Placeholder Image

字幕列表 影片播放

  • [MUSIC PLAYING]

  • DAVID J. MALAN: All right.

  • This is CS50 and this is the start of week two.

  • And you'll recall that over the past couple of weeks,

  • we've been building up.

  • First initially from Scratch, the graphical programming language

  • that we then, just last week, translated to the equivalent program NC.

  • And of course, there's a lot more syntax now.

  • It's entirely text but the ideas, recall, were fundamentally the same.

  • The catch is that computers don't understand this.

  • They only understand what language?

  • AUDIENCE: [INAUDIBLE]

  • DAVID J. MALAN: zeros and ones or binary.

  • And so there's a requisite step in order for us to get from this code to binary.

  • And what was that step or that program or process called?

  • AUDIENCE: [INAUDIBLE]

  • DAVID J. MALAN: Yeah, so compiling.

  • And of course, recall as you've now experimented

  • with this past week that to compile a program,

  • you can use clang for C, language.

  • And you can just say clang and then the name of the file

  • that you want to compile.

  • And that outputs by default a pretty oddly named program.

  • Just a dot out.

  • Which stands for assembler output.

  • More on that in just a moment.

  • But recall too that you can override that default behavior.

  • And you can actually say, Output instead a program

  • called, hello instead of just a dot out.

  • But you can go one step further, and you actually use Make.

  • And Make it self is not a compiler, it's a build utility.

  • But in layman's terms, what does it do for us?

  • AUDIENCE: [INAUDIBLE]

  • DAVID J. MALAN: compiles it.

  • And it essentially figures out all of those otherwise cryptic

  • looking command line arguments.

  • Like dash-o something, and so forth.

  • So that the program is built just the way

  • we want it without our having to remember

  • those seemingly magical incantations.

  • And though that only works for programs as simple as this.

  • In fact, some of you with the most recent problems that

  • might have encountered compilation errors that we actually

  • did not encounter deliberately in class because Make was helping us out.

  • In fact, as soon as you enhance a program

  • to actually take user input using CS50's library by including CS50 dot H,

  • some of you might have realized that all of a sudden the sandbox,

  • and more generally Clang, didn't know what get_string was.

  • And frankly, Clang might not even known what a string was.

  • And that's because those two are features of CS50's library

  • that you have to teach Clang about.

  • But it's not enough to teach Clang what they look like, as by including CS50.h.

  • Turns out there's a missing step that Make helps us solve

  • but that you too can just solve manually if you want.

  • And by that I mean this, instead of compiling a program with just Clang,

  • hello.c.

  • When you want to use CS50's library, you actually

  • need to add this additional command line argument.

  • Specifically at the end, can't go in the beginning like dash-O.

  • And dash-L stands for link.

  • And this is a way of telling Clang, by the way when compiling my program,

  • please link in CS50's zeros and ones that we the staff

  • wrote some weeks ago and installed in the sandbox for you.

  • So you've got your zeros and ones and then

  • you've got our zeros and ones so to speak.

  • And dash-LCS50 says to link them together.

  • So if you were getting some kind of undefined reference error to get_string

  • or you didn't--

  • you weren't able to compile a program that just used any of the get functions

  • from CS50's library.

  • Odds are, this simple change dash-LCS50 would have fixed.

  • But of course, this isn't interesting stuff to remember, let alone

  • remembering how to use dash-0 as well, at which point

  • the command gets really tedious to type.

  • So here comes, Make again.

  • Make automates all of this for us.

  • And in fact, if you henceforth start running Make and then

  • pay closer attention to the fairly long line of output that it outputs,

  • you'll actually see mention of dash-LCS50,

  • you'll see mention of even dash-LM, which stands for math.

  • So if you're using round, for instance, you

  • might have discovered that round two also

  • doesn't work out of the box unless you use Make itself

  • or this more nuanced approach.

  • So this is all to say that compiling is a bit of a white lie.

  • Like, yes you've been compiling and you've been going from source code

  • to machine code.

  • But it turns out that there's been a number of other steps happening

  • for you that we're going to just slap some labels on today.

  • At the end of the day, we're just breaking the abstraction.

  • So compiling is this abstraction from source code to machine code.

  • Let's just kind of zoom in briefly to appreciate

  • what it is that's going on in hopes that it makes the code we're

  • compiling a little more understandable.

  • So step one of four, when it comes to actually compiling a program

  • is called Pre-processing.

  • So recall that this program we just looked at had a couple of

  • includes at the top of the file.

  • These are generally known as pre-processor directives.

  • Not a particularly interesting term but they're

  • demarcated by the hash at the start of these lines.

  • That's a signal to Clang that these things should be handled first.

  • Preprocessed.

  • Process before everything else.

  • And in fact, the reason for this we did discuss last week, inside of CS50.h

  • is what, for instance?

  • AUDIENCE: [INAUDIBLE]

  • DAVID J. MALAN: Specifically, the declaration of get strings.

  • So there's some lines of code, the prototype if you recall,

  • that one line of code that teaches Clang what the inputs to get_string are

  • and what the outputs are.

  • The return type and the arguments, so to speak.

  • And so when you have include CS50.h at the top of the file, what

  • is happening when you first run Clang during this so-called pre-processing

  • step, is Clang looks on the hard drive for the file literally called CS50.h.

  • It grabs its contents and essentially finds and replaces this line here.

  • So somewhere in CS50.h is a line like this yellow one here

  • that says get_string, is a function that returns a string.

  • And it takes as input, the so-called argument, a string

  • that we'll call prompt.

  • Meanwhile, with include standard I/O. What's the point of including that?

  • What is declared inside of that file presumably?

  • Yeah?

  • AUDIENCE: It's the standard inputs and outputs.

  • DAVID J. MALAN: Standard inputs and outputs.

  • And more specifically, what example there of?

  • What function?

  • AUDIENCE: [INAUDIBLE]

  • DAVID J. MALAN: So printf.

  • The other function we keep using.

  • So inside of standard io.h, somewhere on the sandbox's hard drive

  • is similarly a line of code that frankly looks a little more cryptic

  • but we'll come back to this sort of thing

  • down the road, that says print if is a function.

  • Happens to return on int, but more on that another time.

  • Happens to take a char* format.

  • But more on that another time.

  • Indeed, this is one of the reasons we hide

  • this detail early on because there's some syntax that's

  • just a distraction for now.

  • But that's all that's going on.

  • The sharp include sign is just finding and replacing the contents.

  • Plus dot, dot, dot, a bunch of other things in those files as well.

  • So when we say pre-processing, we just mean

  • that that's getting substituted in so you don't have to copy and paste

  • this sort of thing manually yourself.

  • So "compiling" is a word that actually has a well-defined meaning.

  • Once you've preprocessed your code, and your code looks essentially like this,

  • unbeknownst to you, then comes the actual compilation step.

  • And this code here gets turned into this code here.

  • Now this is scary-looking, and this is the sort of thing

  • that if you take a class like CS61 at Harvard,

  • or, more generally, systems programming, so to speak,

  • you might see something like this.

  • This is x86 64-bit assembly instructions.

  • And the only thing interesting about that claim for the moment

  • is that assembly--

  • I kind of alluded to that earlier-- assembler output, a.out.

  • There's actually a relationship here, but long story short, these

  • are the lower level instructions that only the CPU,

  • the brain inside your computer, actually understands.

  • Your CPU does not understand C. It doesn't understand Python or C++

  • or Java or any language with which you might be familiar.

  • It only understands this cryptic-looking thing.

  • But frankly, from the looks of it, you might glean that probably not so much

  • fun to program in this.

  • I mean, arguably, it's not that much fun to program yet in C,

  • So this looks even more cryptic.

  • But that's OK.

  • C and lots of languages are just these abstractions

  • on top of the lower level stuff that the CPUs do actually

  • understand so that we don't have to worry about it as much.

  • But if we highlight a few terms, here you'll see some familiar things.

  • So main is mentioned in this so-called assembly code.

  • You see mention of get string and printf,

  • so we're not losing information.

  • It's just being presented in really a different language, assembly language.

  • Now you can glean, perhaps, from some of the names of these instructions,

  • this is what Intel Inside means.

  • When Intel or any brand of CPU understands instructions,

  • it means things like pushing and moving and subtracting and calling.

  • These are all low level verbs, functions,

  • if you will, but at the level of the CPU.

  • But for more on that, you can take entire courses.

  • But just to take the hood off of this for today,

  • this is a step that's been happening for us magically unbeknownst

  • to us, thanks to Clang.

  • So assembling-- now that you've got this cryptic-looking code that we will never

  • see again-- we'll never need to output again--

  • what do you do with it?

  • Well, you said earlier that computers only understand zeros and ones,

  • so the third step is actually to convert this assembly language to actual zeros

  • and ones that now look like this.

  • So the assembling step happening, unbeknownst to you,

  • every time you run Clang or, in turn, run

  • make, we're getting zeros and ones out of the assembly code,

  • and we're getting the assembly code out of your C-code.

  • But here's the fourth and final step.

  • Recall that we need to link in other people's zeros and ones.

  • If you're using printf you didn't write that.

  • Someone else created those zeros and ones, the patterns

  • that the computer understands.

  • You didn't create get string.

  • We did, so you need access to those zeros and ones

  • so that your program can use them as well.

  • So linking, essentially, does this.

  • If you've written a program-- for instance, hello.c--

  • and it happens to use a couple of other libraries,

  • files that other people wrote of useful code

  • for you, like cs50.c, which does exist somewhere,

  • and even stdio.c, which does exist somewhere,

  • or technically, Standard IO is such a big library,

  • they actually put printf in a file specifically called printf.c.

  • But somewhere in the sandbox's hard drive, in all of our Macs and PCs,

  • if they support compiling, are, for instance, files like these.

  • But we've got to convert this to zeros and ones, this, and this,

  • and then somehow combine them.

  • So pictorially, this just looks a bit like this.

  • And this is all happening automatically by Clang.

  • Hello.c, the code you wrote, gets compiled

  • to assembly, which then gets assembled into zeros and ones, so-called machine

  • code or object code.

  • Cs50.c-- we did this for you before the semester started.

  • Printf was done way before any of us started decades

  • ago and looks like this.

  • These are three separate files, though, so the linking step literally

  • means, link all of these things together, and combine the zeros

  • and ones from, like, three, at least, separate files,

  • and just combine them in such a way that now

  • the CPU knows how to use not just your code but printf and get string

  • and so forth.

  • So last week, we introduced compiling as an abstraction,

  • if you will, and this is all that we've really meant this whole time.

  • But now that we've seen what's going on underneath the hood,

  • and we can stipulate that my CPU that looks physically

  • like this, albeit smaller in a laptop or desktop,

  • knows how to deal with all of that.

  • So any questions on these four steps--

  • pre-processing, compiling, assembling, linking?

  • But generally, now, we can just call them compiling, as most people do.

  • Any questions?

  • Yeah.

  • AUDIENCE: How does the CPU know that [INAUDIBLE] is there?

  • Is that [INAUDIBLE]?

  • DAVID J. MALAN: Not in the pre-processing step,

  • so the question is, how does the computer

  • know that printf is the only function that's there?

  • Essentially, when you're linking in code,

  • only the requisite zeros and ones are typically linked in.

  • Sometimes you get more than you actually need, if it's a big library,

  • but that's OK, too.

  • Those zeros and ones are just never used by the CPU.

  • Good question.

  • Other questions?

  • OK, all right.

  • So now that we know this is possible, let's start

  • to build our way back up, because everyone here

  • probably knows now that when writing in C, which

  • is kind of up here conceptually, like, it

  • is not without its hurdles and problems and bugs and mistakes.

  • So let's introduce a few techniques and tools with which you can henceforth,

  • starting this week and beyond, trying to troubleshoot those problems yourself

  • rather than just trying to read through the cryptic-looking error messages

  • or reach out for help to another human.

  • Let's see if software can actually answer some of these questions for you.

  • So let me go ahead and do this.

  • Let me go ahead and open up a sandbox here,

  • and I'm going to go ahead and create a new file called

  • buggy0.c in which I will, this time, deliberately introduce a bug.

  • I'm going to go ahead and create my function called

  • main, which, again, is the default, like when green flag is clicked.

  • And I'm going to go ahead and say, printf, quote, unquote,

  • "Hello world/m."

  • All right.

  • Looks pretty good.

  • I'm going to go ahead and compile buggy0, Enter,

  • and of course, I get a bunch of error messages here.

  • Let me zoom in on them.

  • Fortunately, I only have two, but remember, you have to, have to,

  • have to always scroll up to look at the first,

  • because there might just be an annoying cascading effect from one earlier

  • bug to the later.

  • So buggy0.c, line 5, is what this means, character 5, so like 5 spaces in,

  • implicitly declaring library function printf with dot, dot, dot.

  • So you're going to start to see this pretty often if you make

  • this particular mistake or oversight.

  • Implicitly declaring something means you forgot

  • to teach Clang that something exists.

  • And you probably know from experience, perhaps now, what the solution is.

  • What's the first mistake I made here?

  • AUDIENCE: [INAUDIBLE].

  • DAVID J. MALAN: Yeah, I didn't include the header file,

  • so to speak, for the library.

  • I'm missing, at the top of the file, include stdio.h,

  • in which printf is defined.

  • But let's propose that you're not quite sure how to get to that point,

  • and how can we get, actually, some help with this?

  • Let me actually increase the size of my terminal

  • here, and recall that just a moment ago, I ran makebuggy0,

  • which yielded the errors that I saw.

  • It turns out that installed in the sandbox

  • is a command that we, the staff, wrote called help50.

  • And this is just a program we wrote that takes as input any error

  • messages that your code or some program has outputted.

  • We kind of look for familiar words and phrases,

  • just like a TF would in office hours, and if we recognize some error message,

  • we're going to try to provide, either rhetorically or explicitly,

  • some advice on how to handle.

  • So if I go ahead and run this command now, notice there's a bit more output.

  • I see exactly the same output in white and green and red as before,

  • but down below is some yellow, which comes specifically from help50.

  • And if I go ahead and zoom in on this, you'll

  • see that the line of output that we recognized

  • is this one, that same one I verbally drew attention

  • to before-- buggy0.c, line 5, error, implicitly declaring library function

  • printf, and so forth.

  • So here, without the background highlighting, but still in yellow,

  • is our advice or a question a TF or CA might ask you in office hours.

  • Well, did you forget to include stdio.h in which printf

  • is declared atop your file?

  • And hopefully, our questions, rhetorical or otherwise, are correct,

  • and that will get you further along.

  • So let's go ahead and try that advice.

  • So include stdio.h.

  • Now let me go ahead and go back down here.

  • And if you don't like clutter, you can type "clear,"

  • or hit Control+L in the terminal window to keep cleaning it like I do.

  • If you want to go ahead now and run makebuggy0, Enter, fewer errors,

  • so that's progress, and not the same.

  • So this one's, perhaps, a little easier.

  • Reading the line, what line of code is buggy here?

  • AUDIENCE: Forgot the semicolon.

  • DAVID J. MALAN: Yeah, so this is now still on line 5, it turns out,

  • but for a different reason.

  • I seem to be missing a semi-colon.

  • But I could similarly ask help50 for help with that

  • and hope that it recognizes my error.

  • So this, too, should start being your first instinct.

  • If on first glance, you don't really understand

  • what an error message is doing, even though you've

  • scrolled to the very first one, like literally ask this program for help

  • by rerunning the exact same command you just

  • ran, but prefix it with help50 and a space,

  • and that will run help50 for you.

  • Any questions on that process?

  • All right, let's take a look at one other program,

  • for instance, that, this time, has a different error involved in it.

  • So how about-- let me go ahead and whip up a quick program here.

  • I'll call this buggy2.c for consistency with some of the samples

  • we have online for you later.

  • And in this example, I'm going to go ahead and write the correct thing

  • at first, stdio.h, and then I'm going to have int main void, which

  • just gets my whole program started.

  • And then I'm going to have a loop, and recall for--

  • [CLEARS THROAT] excuse me-- Mario or some other program,

  • you might have done something like int i get 0, i is less than or equal to--

  • let's do this 10 times, and then i++.

  • And all I want to do in this program is print out that value of i, as I can do,

  • with the %i placeholder-- so a simple program.

  • Just want it to count from 0 to 10.

  • So let's go ahead and run buggy2, or rather, I want to--

  • let's not print up--

  • rewind.

  • Let's go ahead and just print out a hash symbol

  • and not spoil the solution this way.

  • So here, I go ahead and print out buggy2.

  • My goal is now I will stipulate to print out just 10 hash symbols, one per line,

  • which is what I want to do here.

  • And now I'm going to go ahead and run ./buggy2, and I should see, hopefully,

  • 10 hashes.

  • And I kind of spoiled this a little bit, but what do I instead see?

  • Yeah, I think I see more than I expect.

  • And we can kind of zoom in here and double check, so 1, 2, 3, 4, 5, 6, 7,

  • 8, 9, 10, ooh, 11.

  • 11.

  • Now some of your eyes might already be darting to what the solution should be,

  • but let's just propose that it's not obvious.

  • And if it is actually not obvious, all the better, so how might

  • you go about diagnosing this kind of problem, short of just

  • reaching out and asking a human for help.

  • This is not a problem that help50 can help with,

  • because it's not an error message.

  • Your program is working.

  • It's just not outputting what you wanted it to work,

  • but it's not an error message from the compiler with which help50 can help.

  • So you want to kind of get eyes into what your program is doing,

  • and you want to understand, why are you printing 11 when you really

  • are setting this up from 0 to 10?

  • Well, one of the most common techniques in C or any language,

  • honestly, is to use printf for just other purposes-- diagnostic purposes.

  • For instance, there's not much going on in this program,

  • but I'd argue that it would be interesting for me to know,

  • and therefore understand my program, by just,

  • let's print out this value of i on each iteration,

  • as by doing the line of code that I earlier did,

  • and just say something literally like, i is %i.

  • I'm going to remove this ultimately, because it's

  • going to make my program look a little silly,

  • but it's going to help me understand what's going on.

  • Let me go ahead and recompile buggy2, ./bugg2, and this time,

  • I see a lot more output.

  • But if I zoom in, now it's kind of--

  • now the computer is essentially helping me understand what's going on.

  • When i is 0, here's one of them.

  • When i is 1, here's another.

  • I is 2, 3, 4, 5, 6, 7, 8, 9, and that looks good.

  • But if we scroll a little further, it feels a little problematic

  • that i can also be 10.

  • So what's logically the bug in this program?

  • AUDIENCE: [INAUDIBLE].

  • DAVID J. MALAN: Yeah.

  • I use less than or equal to, because I kind of confuse the paradigm.

  • Like programmers tend to start counting at zero,

  • apparently, but I want to do this 10 times, and in the human world,

  • if I want to do something 10 times, I might count up to and including 10.

  • But you can't have it both ways.

  • You can't start at zero and end at 10 if you

  • want to do something exactly 10 times.

  • So there's a couple of possibilities here.

  • How might we fix this?

  • Yeah, so we could certainly change it to less than.

  • What's another correct approach?

  • Yeah, so we could leave this alone and just start counting at one,

  • and if you're not actually printing the values in your actual program,

  • that might be perfectly reasonable, too.

  • It's just not conventional.

  • Get comfortable with, quickly, just counting from zero, because that's just

  • what most everyone does these days.

  • But the technique here is just use printf.

  • Like, when in doubt, literally use printf on this line, on this line,

  • on this line.

  • Anywhere something is interesting maybe going on in your program,

  • just use it to print out the strings that are in your variables,

  • print out the integers that are in your variables, or anything else.

  • And it allows you to kind of see, so to speak,

  • what's going on inside of your program, printf.

  • One last tool-- so it's not uncommon, when writing code,

  • to maybe get a little sloppy early on, especially when you're not

  • quite familiar with the patterns.

  • And for instance, if I go ahead and do this

  • by deleting a whole bunch of whitespace, even after fixing this mistake

  • by going from zero to 10, is this program now correct,

  • if the goal is to print 10 hashes?

  • Yeah, I heard yes.

  • Why is it correct?

  • In what sense?

  • Yeah, exactly.

  • It still works.

  • It prints out the 10 hashes, one per line,

  • but it's poorly written in the sense of style.

  • So recall that we tend to evaluate, and the world

  • tends to think about code in at least three ways.

  • One, the correctness-- does it do what it's supposed to do,

  • like print 10 hashes?

  • And yes, it does, because all I did was delete whitespace.

  • I didn't actually change or break the code after making that fix.

  • Two is design, like how thoughtful, how well-written is the code?

  • And frankly, it's kind of hard to write this in too many ways,

  • because it's so few lines.

  • But you'll see over time, as your programs grow,

  • the teaching fellows and staff can provide you with feedback

  • on the design of your code.

  • But style is relatively easy.

  • And I've been teaching it mostly by way of example, if you will,

  • because I've been very methodically indenting my code

  • and making sure everything looks very pretty, or at least pretty

  • to a trained eye.

  • But this, let's just stipulate, is not pretty.

  • Like, left aligning everything still works, not incorrect,

  • but it's poorly styled.

  • And what would be an argument for not writing code

  • like this and, instead, writing code the way

  • I did a moment ago, albeit after fixing the bug?

  • Yeah.

  • AUDIENCE: It'll help you identify each little subroutine that

  • goes through the thing, so you know this section is here.

  • DAVID J. MALAN: Yeah.

  • AUDIENCE: [INAUDIBLE] next one, so you know where everything is.

  • DAVID J. MALAN: Exactly.

  • Let me summarize this.

  • It allows you to see, more visually, what

  • are the individual subroutines or blocks of code doing

  • that are associated with each other?

  • Scratch is colorful, and it has shapes, like the hugging shape

  • that a lot of the control blocks make, to make

  • clear visually to the programmer that this block encompasses others,

  • and, therefore, this repeats block or this forever block

  • is doing these things again and again and again.

  • That's the role that these curly braces serve, and indentation

  • in this and in other contexts just helps it

  • become more obvious to the programmer what is inside of what

  • and what is happening where.

  • So this is just better written, because you

  • can see that the code inside of main is everything that's indented here.

  • The code that's inside the for loop is everything that's indented here.

  • So it's just for us human readers, teaching fellows

  • in the case of a course, or colleagues in the case of the real world.

  • But suppose that you don't quite see these patterns too readily initially.

  • That, too, is fine.

  • CS50 has on its website what we call a style guide.

  • It's just a summary of what your code should

  • look like when using certain features of C-- loops,

  • conditions, variables, functions, and so forth.

  • And it's linked on the course's website.

  • But there's also a tool that you can use when

  • writing your code that'll help you clean it up and make it consistent,

  • not just for the sake of making it consistent with the style guide,

  • but just making your own code more readable.

  • So for instance, if I go ahead and run a command called

  • style50 on this program, buggy2.c, and then hit Enter,

  • I'm going to see some output that's colorful.

  • I see my own code in white, and then I see, anywhere

  • I should have indented, green spaces that

  • are sort of encouraging me to put space, space, space, space here.

  • Put space, space, space, space here.

  • Put eight spaces here, four spaces here, and so forth,

  • and then it's reminding me I should add comments as well.

  • This is a short program-- doesn't necessarily

  • need a lot of commenting to explain what's going on.

  • But just one //, like we saw last week to explain,

  • maybe at the top of the file or top the block of the code,

  • would make style50 happy as well.

  • So let's do that.

  • Let me go ahead and take its advice and actually indent this with Tab,

  • this with Tab, this with Tab, this with Tab, and this once more.

  • And you'll notice that on your keyboard, even though you're hitting Tab,

  • it's actually converting it for you, which is very common to four spaces,

  • so you don't have to hit the spacebar four times.

  • Just get into the habit of using Tab.

  • And let me go ahead and write a comment here.

  • "Print 10 hashes."

  • This way, my colleagues, my teaching fellow, myself in a week

  • don't have to read my own code again and figure out what it's doing.

  • I can read the comments alone per the //.

  • If I run style50 again, now it looks good.

  • It's in accordance with the style guide, and it's just more prettily written,

  • so pretty printed would be a term of art in programming

  • when your code looks good and isn't just correct.

  • Any questions then?

  • Yeah.

  • AUDIENCE: I tried using [INAUDIBLE] this past week

  • and it said I needed a new program.

  • DAVID J. MALAN: That's--

  • it wasn't enabled for the first week of the class.

  • It's enabled as of right now and henceforth.

  • Other questions?

  • No.

  • All right, so just to recap then, three tools to have in the proverbial toolbox

  • now are help50 anytime you see an error message that you don't understand,

  • whether it's with make or Clang or, perhaps, something else.

  • Printf-- when you've got a logical program--

  • a bug in your program, and it's just not working the way it's supposed to

  • or the way the problem set tells you it should, and then style50

  • when you want to make sure that, does my code look right in terms of style,

  • and is it as readable as possible?

  • And honestly, you'll find us at office hours and the like

  • often encouraging you, hey, before we answer this question,

  • can you please run style50 on your code?

  • Can you please clean up your code, because it just makes our lives, too,

  • as other humans so much easier when we can understand what's

  • going on without having to visually figure out what parentheses and curly

  • braces line up.

  • And so do get into that habit, because it

  • will save you time from having to waste time parsing things visually yourself.

  • All right.

  • So there's not just CPUs in computers.

  • CPUs are the brains, central processing unit,

  • and that's why we keep emphasizing the instructions that computers understand.

  • There's also this, which we saw last time, too.

  • This is an example of what type of hardware?

  • AUDIENCE: RAM.

  • DAVID J. MALAN: RAM, or Random Access Memory.

  • This is the type of memory that laptops, desktops, servers

  • have that is used whenever you run a program or open a file.

  • There's another type of memory called hard drives or solid state drives,

  • which you're probably familiar as a consumer,

  • and that's just where your files are stored permanently.

  • Your battery can die.

  • You can pull the plug from your laptop or desktop,

  • and any files saved on a hard drive are persistent.

  • They stay there because of the technology

  • being used to implement that.

  • But RAM is more ephemeral.

  • RAM is powered only by electricity.

  • It's only used when the power is on or the battery is charged,

  • and it's where your files and programs live effectively when

  • you double click on them and open them.

  • So when you double click on something like Microsoft Word,

  • it is copied from your hard drive long term into this type of memory,

  • because this type of memory, though smaller in capacity--

  • you don't have as many bytes of it--

  • but it is much, much, much, much faster.

  • Similarly, when you open a document, or you go to a web page,

  • the contents of the file you're seeing are stored in this type of hardware,

  • because even though you don't have terribly many bytes of it,

  • it's just much, much, much, much faster.

  • And so this will be thematic in computer science and in hardware.

  • You sort of have lots of cheap, slow stuff,

  • like hard disk space, relatively speaking, and you have a little less

  • of the more expensive but faster stuff like RAM.

  • And you have just one, usually, CPU, which is the really fast thing that

  • can do a billion things per second.

  • But it, too, is more expensive.

  • So there's four visible chips on this thing, if you will.

  • And we won't get into the details of how these things work, but let's

  • just zoom in on this one black chip here and focus on it

  • as being representative as some amount of memory.

  • Maybe it's one megabyte, one million bytes.

  • Maybe it's even one gigabyte these days, one billion bytes.

  • But this is to say that this chip can be thought of as just having

  • a bunch of bytes in it.

  • This is not to scale.

  • You have many more bytes than these, but let

  • me propose that you just think of each of these squares

  • here as representing one byte.

  • So the very first byte of memory I have access to is here.

  • Next one is here, and so forth.

  • And the fact that they wrap around is just an artist rendition.

  • These things you can think of just virtually as going

  • left to right, not in any kind of grid, but physically, they look like this.

  • So when you actually create a variable in a program like C,

  • like you need a char.

  • A char tends to be one byte or eight bits,

  • and so that means when you have a variable of type char in a C program,

  • it goes, literally, physically in one of these boxes,

  • inside of your computer's RAM.

  • So for instance, it might take up this much space at top left.

  • If you have a bigger type of data, so you

  • have an integer, which tends to be four bytes or 32 bits,

  • you might need more than one square, so the computer might give you access

  • to four squares instead.

  • And you have 32 bits spanning that region of memory.

  • But honestly, I chose those boxes arbitrarily.

  • They could be anywhere in that chip or in any of the other chips.

  • It's up to the computer to just remember where they are for you.

  • You don't need to remember that, per se.

  • But if we think about this grid, it turns out

  • this is actually very valuable that we have chunks of memory--

  • bytes, if you will--

  • that are back to back to back to back.

  • And in fact, there's a word for this technique.

  • This is contiguous memory--

  • back to back to back to back to back.

  • And in general, in programming, this is referred to as an array.

  • You might recall from Scratch, if you use this feature,

  • it actually has things called lists, which

  • are exactly that-- lists of values, lists of words, lists of strings.

  • An array is just a contiguous chunk of memory, such

  • that you can store something here, something here, something here,

  • something here, and so forth.

  • So it turns out an array, this super simple primitive,

  • is actually incredibly powerful.

  • Just being able to store things in my computer's memory

  • back to back to back to back enables so many possibilities, both design-wise,

  • like how well I can write my code, and also how fast I can make my code run.

  • So let me go ahead and take out an example.

  • Let me go ahead and open up, for instance, a new file in a sandbox,

  • and we'll call this score0.

  • So let me go ahead and close this one, create a new file called scores0.c.

  • And in this file, let's go ahead and write a relatively simple program.

  • Let me go ahead and, as usual, give myself access

  • to some helpful functions-- cs50.h and stdio.h.

  • And no need to copy all this down verbatim, if you don't like.

  • Everything will have or is already on the course's website.

  • Let me start my program as usual with int main void.

  • And then let me write a program, as this program's name implies,

  • that, like, asks the user for three scores on recent problem sets,

  • quizzes, whatever, and then kind of creates a very simple chart of them,

  • like a bar chart to kind of help me visualize how well

  • or how poorly I did on something.

  • So if I want to get an integer, no surprise,

  • we can use the get int function, and I can just

  • ask the user for their first score.

  • But I should probably do something with this score,

  • and on the left hand side of this, what do I typically put?

  • Yeah.

  • So int-- sure, score 1 equals this, and then my semi-colon.

  • So you might not have had many occasions to use ints just yet,

  • but get int is in the cs50 library.

  • This is the so-called prompt that the human

  • sees, and let me actually fix my space, because I

  • want the human to see the space after the colon.

  • But that's just an aesthetic detail.

  • And then when I get back this value, its return value--

  • just like Aaron, last week, handed me a piece of paper,

  • so does get int hand me a virtual piece of paper with a number

  • that I'm going to store in a variable called Score 1.

  • And now just to be clear, what has just happened effectively is this.

  • The moment you create a variable of type int, which is four bytes,

  • literally, this is what Clang or, more generally,

  • the computer has done for you.

  • That int that the human typed in is stored literally

  • in four contiguous bytes back to back to back, maybe here, maybe here,

  • but together.

  • So that's all that's going on when you're actually using C.

  • So let me go back into my code here, and now I

  • want to-- it's not interesting to plot one score.

  • So let's go ahead and do another.

  • So int Score 2, get int, get int, and I'll ask the user for score 2,

  • semi-colon, and then let's get one more, Score 3, get int, call it Score 3,

  • semi-colon.

  • All right, so now let me go ahead and generate a bar,

  • like a bar chart of this.

  • I'm going to use what we'll call ASCII art.

  • ASCII, of course, is just text, recall--

  • very simple text in a computer.

  • And I can kind of make a bar chart pretty simply by just printing out

  • like a bunch of hashes horizontally, so a short bar

  • will represent a small number, and a long bar will represent a big number.

  • So let me go ahead and say to the user, all right, here's your Score 1.

  • I'm going to go ahead, then, and say, for int i get 0.

  • I is less than Score 1, i++.

  • And now if I scroll down and give myself a bit of room here,

  • let me go ahead and implement just a simple print.

  • So go ahead and print out a hash, and then when you're all done with that,

  • print out a new line at the end of that loop.

  • And let's just pause there.

  • Just to recap, I've asked the human for three scores.

  • I'm only doing something with one of them at the moment, so in fact,

  • just as a quick check, let me delete those so as to not get ahead of myself.

  • Let me do make score 0.

  • Cross my fingers.

  • OK, no errors.

  • Now let me go ahead and do ./score0, and your first score on a pset this year

  • out of 100 has been?

  • OK, 100.

  • And good job.

  • So it's a really long bar, and if we count those up,

  • hopefully, there's actually 100 bars.

  • And if we run it again and say, eh, it didn't go so well.

  • I got a 50.

  • That's half as big a bar.

  • So it seems like we're on our way correctness-wise.

  • So now let me go ahead and get the other scores.

  • Well, I had them here a moment ago.

  • So let me go ahead and just, well, copy, paste, and change this to two,

  • change this to three, change this to three, this to three.

  • All right, I know how to print bars clearly, so let me go ahead

  • and do this, and then do this, and then fix the indentation.

  • I don't want to say Score 1 everywhere.

  • I want to say a Score 2, Score 2.

  • I mean you're probably being rubbed the wrong way that this

  • is both tedious and sloppy, and why?

  • What am I doing poorly now design-wise?

  • AUDIENCE: Copying and pasting code.

  • DAVID J. MALAN: Like copy-pasting almost always bad, right?

  • There's redundancy here, but that's fine.

  • Let's prioritize correctness, at least, for now.

  • So let me go ahead and make Score 0.

  • All right, no mistakes-- ./score0.

  • And then Tab it.

  • Let me go ahead now and run--

  • OK, we got 100 the first time.

  • We got 50 the--

  • oh, that's a bug.

  • What did I do there?

  • See, this is what happens when you copy-paste.

  • So let's fix this.

  • That should say Score 2, so Control+C will quit a program.

  • Make score 0 will recreate it. ./0, Enter--

  • all right, here we go.

  • 100, 50.

  • Let's split the difference--

  • 75.

  • All right, so this is a simple bar chart horizontally drawn

  • of each of my three scores, where this is 100, this is 50, and this is 75.

  • But there's opportunities for improvement here.

  • So one, it rubbed some folks the wrong way

  • already that we were literally copying and pasting code.

  • So where is one opportunity for improvement here?

  • What should I do instead of copying and pasting that code again and again?

  • What ingredient can you bring?

  • OK, so we can use a loop and actually just do the same thing three times.

  • So let's try that.

  • Let me go ahead and do this.

  • So let's go ahead and delete the copy-paste I did,

  • and let me go ahead and say, OK, well, for int i get zero, i less than 3, i++.

  • Let me create a bracket.

  • I can highlight multiple lines and hit Tab,

  • and they'll all indent for me, which is convenient.

  • And can I do this now, for instance?

  • Say it a little louder.

  • AUDIENCE: If you [INAUDIBLE] to a specific [INAUDIBLE]..

  • DAVID J. MALAN: Yeah, I'm a little worried.

  • As you're noting here, we're using on line 13 here the same variable, so mm.

  • So it's good instincts, but I feel like the fact

  • that this program, unlike last week, we're

  • now collecting multiple pieces of data.

  • Loops are breaking down for us.

  • Yeah.

  • AUDIENCE: [INAUDIBLE] function [INAUDIBLE] takes in--

  • like you can have it [INAUDIBLE].

  • DAVID J. MALAN: OK.

  • AUDIENCE: So like an input of how many scores you wanted to enter.

  • DAVID J. MALAN: OK.

  • AUDIENCE: And then [INAUDIBLE].

  • DAVID J. MALAN: Yeah, we can implement another

  • function that factors out some of this functionality.

  • Any other thoughts?

  • AUDIENCE: Store your scores in an array.

  • DAVID J. MALAN: OK, so we could also store our scores in an array.

  • So let's do these in order then, in fact.

  • So loops are wonderful when you want to do something again and again

  • and again, but the whole purpose of a function,

  • fundamentally, is to factor out common functionality.

  • And there might still be a loop in the solution,

  • but the real fundamental problem with what I was doing a moment ago

  • was I was copying and pasting functionality--

  • shouldn't need to do that, because in both C and Scratch,

  • we had the ability to make our own functions.

  • So let's do that.

  • Let me undo my loop changes here, just to get us

  • back to where we were a moment ago.

  • And let me go ahead and, instead, clean this up a little bit.

  • Let me go ahead and create a new function

  • down here that I'm going to call, say, Chart, just

  • to create a chart for myself.

  • And it's going to take as input a score, but I could call this anything I want.

  • It's void as its return type, because I don't need it to hand me something

  • back.

  • Like I'm not getting a string from the user.

  • I'm just printing a char.

  • It's a so-called side effect or output.

  • Now I'm going to go ahead and do my loop here for int i get 0.

  • I is less than--

  • how many hashes do I want to print if I'm being passed in the user score?

  • Like, is this 3 here?

  • AUDIENCE: The score.

  • DAVID J. MALAN: The score, so if I'm being

  • handed a number that's 0 to 100, that's what I want to iterate over.

  • If my goal here, ultimately--

  • let me finish this thought-- i++ is [? 2 ?] inside this loop print out one

  • hash per point in 1's total score.

  • And just to keep things clean, I'm going to go ahead and put

  • a new line at the very end of this.

  • But I think now, I factored out a good amount of the redundancy.

  • It's not everything, but I've at least now

  • given myself a function called Chart.

  • So up here, it looks like I can kind of remove this loop, which

  • is what I factored out.

  • That's almost identical, except the variable name was hardcoded.

  • And I think I could now do chart like this,

  • and then I maybe could do a little copy-paste, if that's OK, like if maybe

  • I can get away with just doing this, and then say 2, and then say 3,

  • and then say 3, and then say 2.

  • So it's still copy-paste, but it's less.

  • And it looks better.

  • It literally fits on the screen, so it's progress-- not perfect, but progress.

  • Better design, but not perfect.

  • So is this going to compile?

  • I'm going to have errors why?

  • AUDIENCE: Essentially, it's [INAUDIBLE] the program [INAUDIBLE]..

  • DAVID J. MALAN: OK.

  • Yeah.

  • AUDIENCE: We need to declare a [INAUDIBLE]..

  • DAVID J. MALAN: OK, good.

  • So let me induce the actual error, just so we know what problem we're solving.

  • Let me go ahead and sort of innocently go ahead

  • and compile Score 0 hoping all is well, but of course,

  • it's not because of a familiar error up here.

  • So notice, implicit declaration of function chart is invalid in C99.

  • So again, implicit declaration of function

  • just tends to mean Clang does not know what you're talking about.

  • And you could run help50, and it would probably

  • provide you with similar advice.

  • But the gist of this is that chart is not a C function.

  • It doesn't come with C. I wrote it.

  • I just wrote it a little too late.

  • So one solution that we didn't used last week

  • would be, OK, well, if you don't know what chart is, let me just

  • go put it where you'll know about it.

  • And now run make score 0.

  • OK, problem solved.

  • So that fixes it, but we fixed it in a different way last week.

  • And why might we want to stick with last week's approach

  • and not just copy-paste my function and put it

  • at the top instead of the bottom?

  • AUDIENCE: [INAUDIBLE].

  • DAVID J. MALAN: Yeah, I mean it's kind of a minor concern at the moment,

  • because this is a pretty short program.

  • But I'm pushing the main part of my program, literally called Main,

  • farther and farther down.

  • And the whole point of reading code is to understand what it's doing.

  • So if I open this file, and I have to scroll, scroll, scroll, scroll, scroll,

  • just looking for the main function, it's just bad style.

  • It's just kind of nice, and it's a good human convention.

  • Put the main code, the main function, when green flag clicks equivalent,

  • at the very top.

  • So C does offer us a solution here.

  • You just have to provide it with a little hint.

  • Let me go ahead and cut this from here, put it back down at the bottom here,

  • and then go ahead and copy-paste only or retype only the value--

  • whoops-- the value of that first line, which is its so-called prototype.

  • Give Clang enough information so that it knows what arguments the function

  • takes, what its return type is, and what its name is, semi-colon,

  • and that's the so-called declaration or--

  • and then implement it with the curly braces and all the logic down below.

  • So let's go ahead and run this.

  • And if I scroll up here, we'll see-- whoops.

  • We'll see make score 0.

  • All right, now we're on our way, score 0.

  • Enter.

  • Score 1 is 100, 50, 75, and now we seem to have some good functionality.

  • But there's still an opportunity, I dare say, for improvement.

  • And I think the fundamental problem is that I'm still

  • copy-pasting the little stuff, but I think

  • the fundamental problem is that I don't have the expressiveness to store

  • multiple values, unless I, in advance, as the programmer,

  • give them all unique names, because if I use the same variable for everything,

  • I couldn't collect all three variables at the top,

  • and then iterate over all three at the bottom, if I only have one variable.

  • So I do need three variables, but this doesn't scale very well.

  • And who knows?

  • If I want to take in five scores, 10 scores, or more scores,

  • then I'm really copying and pasting excessively.

  • So it turns out, indeed, the answer is an array.

  • So an array, at the end of the day, is just

  • a side effect of storing stuff in memory back to back to back to back.

  • But what's powerful about this reality of memory is the following.

  • I can go ahead here and in, say, a new and more improved

  • version of this program, do this.

  • Let me go ahead and open this one, which I wrote in advance, called scores2.c.

  • And in scores2.c, notice we have the following code.

  • In my main function, I've got a new feature and a new bit of syntax.

  • This line here that I've highlighted says, hey, Clang,

  • give me a variable called Scores of type integer,

  • but please give me three of them.

  • So the new syntax are your square brackets,

  • and inside of which is the number of variables you want of that type.

  • And you don't have to give them unique names.

  • You literally call them collectively, Scores,

  • and in English, I deliberately chose a plural to connote as much.

  • This is an array of values, not a single value.

  • What can I do next?

  • Well, here's my for loop for int i get zero i is less than 3 i++,

  • and now I've solved that earlier problem that was proposed.

  • Well, just put it in a loop.

  • Now I can, because now my variables are not called Score 1, Score 2, Score 3,

  • which I literally had to hard code.

  • They're just called Scores, and now that they're called Scores,

  • and I have this square bracket notation, notice what I can do.

  • I can get an int, and I can say, give me score%i, and plug in i plus 1.

  • I didn't want to say "zero," because humans

  • don't count from zero in general.

  • So this is counting from one, two, and three, but the computer is doing this.

  • So Scores is a variable.

  • Bracket, i, close bracket says store the i-th value there.

  • So i-th is just non-English.

  • That means go to bracket 0, bracket 1, bracket 2.

  • So what this effectively means is on the first iteration of the loop, when

  • i equals 0, this looks like this, effectively.

  • When i then becomes 1 on the next iteration, then you're doing this.

  • When i becomes 2 on the final iteration, it looks like this.

  • When i becomes 3, well, 3 is not less than 3,

  • and so it doesn't execute again.

  • So by using i inside of these square brackets, am I indexing into an array?

  • To index into an array means go to a specific location,

  • the so-called i-th location, but you start counting at zero.

  • Just to make this more real, then, if you go back

  • to this picture of your computer's memory,

  • this might, therefore, be bracket i, bracket 1--

  • bracket 0, bracket 1, bracket 2, bracket 3, bracket 4, bracket 50, or wherever.

  • You can now, using square brackets, get at any of these blocks of memory

  • to store values for you.

  • Any questions on what we've just done?

  • All right, then on the flip side, we can do the exact same thing.

  • Now when I print my scores, I can similarly iterate from 0 to 3,

  • and then print out the scores by passing to chart

  • the same value, the i-th score.

  • Again, the only new syntax here is variable name, square bracket,

  • and then a number, like 0, 1, 2, or a variable like i,

  • and then my chart function down here is exactly the same.

  • It has no idea an array is even involved, because I'm just

  • passing in one score at a time.

  • Now it turns out there's still one bad design decision in this program.

  • There's still some redundancy, something that I keep typing again

  • and again and again.

  • Do any values jump out at you as repeated?

  • AUDIENCE: The for loop.

  • DAVID J. MALAN: The for loop.

  • OK, so I've got the for loop in multiple places.

  • Sure.

  • And what other value seems to be in multiple places?

  • It's subtle.

  • Total number.

  • Yeah, 3.

  • Three is in a few places.

  • It's up here.

  • It's when I declare the array and ask myself for three scores.

  • It's here when I'm iterating.

  • It's not here, because this is a different iteration.

  • That's just for the hashes.

  • So in, ironically, three places, have I written 3.

  • So what does this mean?

  • Well, suppose next year you take more tests or whatever,

  • and you need more scores.

  • You open up your program, and all right, now I've got five scores and five--

  • whoops, typo already-- five, like this kind of pattern

  • where you're typing the same thing again and again.

  • And now the onus is on me, the programmer,

  • to remember to change the same [? damn ?] value in multiple places--

  • bad, bad, bad design.

  • You're going to miss one of those values.

  • Your program's going to get more complex.

  • You're going to leave one at 3 and change the other to 5,

  • and logical errors are eventually going to happen.

  • So how do we solve this?

  • The function's not the solution here, because it's not functionality.

  • It's just a value.

  • Well, we could use a variable, but a certain type of variable.

  • These numbers here-- 5, 5, 5 or 3, 3, 3--

  • are what humans generally refer to as magic numbers.

  • Like they're numbers, but they're kind of magical,

  • because you just arbitrarily hardcoded them in random places.

  • But a better convention would be, often as a global variable, to do this--

  • int, let's call it "count," equals 3.

  • So declare a variable of type int that is the number of things

  • you want, and then type that variable name all throughout your code

  • so that later on, if you ever want to change this program,

  • you change it-- whoops-- in one place, and you're

  • done after recompiling the program.

  • And actually, I should do a little better than this.

  • It turns out that if you know you have a variable that you're never going

  • to change, because it's not supposed to change--

  • it's supposed to be a constant value--

  • C also has a special keyword called const, where before the data type,

  • you say, const int, and then the name and then the value, and this way,

  • the compiler, Clang, will make sure that you, the human,

  • don't screw up and accidentally try to change the count anywhere else.

  • There's one other thing notable.

  • I also capitalize this whole thing for some reason--

  • human convention.

  • Anytime you capitalize all of the letters in a variable name,

  • the convention is that that means it's global.

  • That means it's defined way up top, and you can use it anywhere, therefore,

  • because it's outside all curly braces.

  • But it's meant to imply and remind you that this is special.

  • It's not just a so-called local variable inside

  • of a function or inside of a loop or the like.

  • Any questions on that?

  • Yeah.

  • AUDIENCE: What is [INAUDIBLE]?

  • Why do you have i plus 1?

  • DAVID J. MALAN: Oh, why do I have i plus 1?

  • Let me run this program real quick.

  • Why do I have i plus 1 in this line here, is the question.

  • So let me go ahead and run make scores 2--

  • whoops-- in my directory.

  • Make scores 2 ./scores2, Enter.

  • I wanted just the human to see Score 1 and Score 2 and Score 3.

  • I didn't want him or her to see Score 0, Score 1, Score 2, because it just looks

  • lame to the human.

  • The computer needs to think in terms of zeros.

  • My humans and my users do not, so just an aesthetic.

  • Other questions.

  • Yeah.

  • AUDIENCE: [INAUDIBLE].

  • DAVID J. MALAN: Ah, really good question.

  • And I actually thought about this last night

  • when trying to craft this example.

  • Why don't I just combine these two for loops,

  • because they're clearly iterating an identical number of times?

  • Was this a hand or just a stretch?

  • No, stretch.

  • So this is actually deliberate.

  • If I combine these, what would change logically in my program?

  • Yeah.

  • AUDIENCE: After every [INAUDIBLE] input, you would [INAUDIBLE]..

  • DAVID J. MALAN: Yeah, so after every human input of a score,

  • I would see that user's chart, the row of hashes.

  • Then I'd ask them for another value.

  • They'd see the chart, another value, and they'd see the chart.

  • And that's fine, if that is the design you want.

  • Totally acceptable.

  • Totally correct.

  • I wanted mine to look a little more traditional with all of the bars

  • together, so I effectively had to postpone printing the hashes.

  • And that's why I did have a little bit of redundancy

  • by getting the user's input here and then iterating again

  • to actually print the user's output as a chart, so just a design decision.

  • Good question.

  • Other questions?

  • All right, so what does this look like?

  • Actually, you know what?

  • I can probably do a little better.

  • Let me open up one final example involving scores and this thing

  • called an array.

  • In Scores 4 here, let me go ahead and do this.

  • Now I've changed my chart function to do a little bit more,

  • and you might recall from week 0 and 1, we had the call function,

  • and we kept enhancing it to do more and more,

  • like putting more and more logic into it.

  • Notice this.

  • Chart function now takes a second argument, which is kind of interesting.

  • It takes one argument, which is a number,

  • and then the next argument is an array of scores.

  • So long story short, if you want to have a function that

  • takes as input an array, you don't have to know

  • in advance how big that array is.

  • You should not, in fact, put a number in between the square brackets

  • in this context.

  • But the thing is you do need to know, at some point,

  • how many items are in the array.

  • If you've programmed in Java, took AP CS, Java just gives you .length,

  • if you recall that feature of objects.

  • C does not have this.

  • Arrays do not have an inherent length associated with them.

  • You have to tell everyone who uses your array how long it is.

  • So even though you don't do that syntactically here,

  • you literally just say, I expect an argument called scores that

  • is an array per the square brackets.

  • You have to pass and almost always a second variable

  • that is literally called whatever you want,

  • but is the number of things in that array,

  • because if the goal of this function is just

  • to iterate over the number of scores that are passed in,

  • and then iterate over the number of points in that score

  • in order to print out the hashes, you need to know this count.

  • So what does this function do, just to be clear?

  • This iterates over the total number of scores from 0 to count,

  • which is probably 3 or 5 or whatever.

  • This loop here, using J, which is just a convention,

  • instead iterates from 0 to whatever that i-th score is.

  • So this is what's convenient.

  • Now I've passed in the array, and I can still get at individual values

  • just by using i, because I'm on my i-th iteration here.

  • So you might recall this from Mario, for instance, or any other example

  • in which you had nested loops--

  • just very conventional to use i on the outside, j on the inside.

  • But again, the only point here is that you can, indeed, pass around arrays,

  • even as arguments, which we'll see why that's useful before long.

  • Any questions?

  • OK, so this was a lot, but we can do so much more still with arrays.

  • It gets even more and more cool.

  • In fact, we'll see, in just a bit, how arrays have actually

  • been with us since last week.

  • We just didn't quite realize it under the hood, but let's go ahead

  • and take a breather, five minutes.

  • We'll come back and dive in.

  • All right.

  • So I know that was a bit of a cliffhanger.

  • Where else could arrays have actually been?

  • But, of course, this is how we might depict it pictorially.

  • We called it an array, and it turns out that last week, when

  • we introduced strings, strings, sequences of characters,

  • are literally just an array by another name.

  • A string is an array of chars, and chars, of course, is another data type.

  • Now what are the actual implications of this,

  • both in terms of representation, like how a computer's representing

  • information, and then fundamentally, programmatically,

  • what can we do when we know all of our data

  • is so back to back to back or so proximal to one another?

  • Well, it turns out that we can apply this logic in a few different ways.

  • Let me go ahead and open up, for instance,

  • an example here called String 0.

  • So in our code for today, in our Source 2 folder,

  • let me go ahead and open up String 0, and this example looks like this.

  • Notice that we first, on line 9, get a string from the user.

  • Just say, input, please.

  • We store that value in a string, s, and then we say, here comes the output.

  • And notice what I'm doing in the following line.

  • I'm iterating over i from 0 to strlen, whatever that is.

  • And then in line 13, I'm printing a character one at a time.

  • But notice the syntax I'm using, which we didn't use last week.

  • If you have a string called s, you can index into a string

  • just like it's an array, because it, indeed, is underneath the hood.

  • So s bracket i, where i starts at 0 and goes

  • up to whatever this value is is just a way of getting character 0, then

  • character 1, then character 2, then character 3,

  • and so the end result is actually going to look like this.

  • Let me go ahead and do, make string--

  • whoops-- make string 0.

  • Oops.

  • Not in the directory.

  • Make string 0, ./string0, Enter, and I'll type in, say, Zamyla,

  • and the output now is Z-A-M-Y-L-A. It's a little messy,

  • because I don't have a new line here, so let me actually-- let's clean that up,

  • because this is unnecessarily sloppy.

  • So let me go ahead and print out a new line.

  • Let me recompile with make string 0, dot--

  • whoops-- ./string0.

  • Input shall be Zamyla, Enter, and now Z-A-M-Y-L-A.

  • So why is that happening?

  • Well, if I scroll down on this code, it seems that I am,

  • via this printf line here, just getting the i-th character of the name in s,

  • and then printing out one character at a time per the %c,

  • followed by a new line.

  • So you might guess, what is this function here doing?

  • Strlen-- slightly abbreviated, but you can, perhaps, glean what it means.

  • Yeah, so it's actually string length.

  • So it turns out there is a function that comes

  • with C called strlen, and humans back in the day

  • and to this day like to type as few characters when possible.

  • And so strlen is string length, and the way you use it is you

  • just need one more header file.

  • So there's another library, the so-called string

  • library that gives you string-related functions

  • beyond what CS50's library provides.

  • And so if you include string.h, that gives you access

  • to another function called strlen, that if you pass it,

  • a variable containing a string, it will pass you back

  • as a return value the total number of characters.

  • So I typed in Z-A-M-Y-L-A, and so that should be returning to me six,

  • thereby printing out the six characters in Zamyla's name.

  • Yeah.

  • AUDIENCE: [INAUDIBLE].

  • DAVID J. MALAN: Uh-huh.

  • AUDIENCE: [INAUDIBLE] useful to get the individual digits [INAUDIBLE]..

  • DAVID J. MALAN: Really good question.

  • In the credit problem of the problem set, would this have been useful?

  • Yes, absolutely.

  • But recall that in the credit pset, we encourage you to actually

  • take in the number as a long, so as an integral value, which

  • thereby necessitated arithmetic.

  • But yes, if you had, instead, in a problem involving credit card

  • numbers, gotten the human's input as a long string of characters

  • and not as an actual number like an int or a long,

  • then, yes, you could actually get at those individual characters,

  • which probably would have made things even easier but deliberate.

  • Yeah.

  • AUDIENCE: [INAUDIBLE].

  • DAVID J. MALAN: Really good question.

  • If we're defining string in CS50, are we redefining it in string?

  • No.

  • So string, even though it's named string.h,

  • doesn't actually define something called a string.

  • It just has string-related functions.

  • More on that soon.

  • Yeah.

  • AUDIENCE: [INAUDIBLE] individual values [INAUDIBLE]??

  • DAVID J. MALAN: Ah, really good question.

  • Could you edit the individual values?

  • So short answer, yes.

  • We could absolutely change values, and we'll soon do that in another context.

  • Other questions?

  • All right, so turns out this is correct, if my goal is

  • to print out all of the characters in Zamyla's name,

  • but it's not the best design.

  • And this one's a little subtle, but this is, again, what we mean by design.

  • And to a question that came up during the break,

  • did we expect everyone to be writing good style and good design last week?

  • No.

  • Up until today, like we've introduced the notion of correctness

  • in both Scratch and in C last week, but now we're

  • introducing these other axes of quality of code

  • like design, how well-designed it is, and how pretty

  • does it look in the context of style.

  • So expectations are here on out meant to be aligned with those characteristics,

  • but not in the past.

  • So there's a slight inefficiency here.

  • So on the first iteration of this loop, I first initialize i to 0,

  • and then I check if i less than the length of the string, which hopefully,

  • it is, if it's Zamyla, which is longer than 0.

  • Then I print the i-th character.

  • Then I increment i.

  • Then I check this condition.

  • Then I print the i-th character.

  • Then I increment i.

  • Then I check this condition and so forth.

  • We looped through loops last week, and you've used them, perhaps,

  • by now in problems.

  • What question am I redundantly asking seemingly unnecessarily?

  • I have to check a condition again and again,

  • because i is getting incremented.

  • But there's another other question that I

  • don't need to keep asking again just to get the same answer.

  • AUDIENCE: What is the length [? of the string? ?]

  • DAVID J. MALAN: Yeah, there's this function call

  • in my loop of strlen s, which is fine.

  • This is correct.

  • I'm checking the length of the string, but once I type in Zamyla,

  • her name is not changing in length.

  • I'm incrementing i, so I'm moving in the string, if you will.

  • But the string itself, Z-A-M-Y-L-A, is not changing.

  • So why am I asking the computer, again and again, get me the strlen of s,

  • get me the strlen of s, get me the strlen of s.

  • So I can actually fix this.

  • I can improve the design, because that must take some amount of time.

  • Maybe it's fast, but it's still a non-zero amount of time.

  • So you know what I could do?

  • I could do something like this-- int n get string length of s.

  • And now just do this.

  • This would be better design, because now I'm only asking the question once

  • of the function.

  • I'm remembering or caching, if you will, the answer, and then

  • I'm just using a variable.

  • And just comparing variables is just faster

  • than comparing a variable against a function, which has to be called,

  • which has to return a value, which you can then compare.

  • But honestly, it doesn't have to be this verbose.

  • We can actually be a little elegant about this.

  • If you're using a loop, a secret feature of loops

  • is that you can have commas after declaring variables.

  • And you can actually do this and make this even more elegant, if you will,

  • or more confusing-looking, depending on your perspective.

  • But this now does the same thing but declares n inside of the loop,

  • just like I'm declaring i, and it's just a little tighter.

  • It's one fewer lines of code.

  • Any questions, then?

  • AUDIENCE: [INAUDIBLE].

  • DAVID J. MALAN: Good question.

  • In the way I've just done it cannot reuse this outside of the curly braces.

  • The scope of i and n exists only in this context right now.

  • The other way, yes.

  • I could have used it elsewhere.

  • AUDIENCE: What if you [INAUDIBLE] other loops, and you also had [INAUDIBLE]??

  • DAVID J. MALAN: Absolutely.

  • AUDIENCE: Using different letters of the alphabet,

  • you could just use n and not be [INAUDIBLE]..

  • DAVID J. MALAN: Correct.

  • If I want to use the length of s again, absolutely.

  • I can declare the variable, as I did earlier, outside of the loop,

  • so as to reuse it.

  • That's totally fine.

  • Yes.

  • And even i-- i exists only inside of this loop, so if I have another loop,

  • I can reuse i, and it's a different i, because these variables only

  • exist inside the for loop in which they're declared.

  • So it turns out that these strings don't have anything in them

  • other than character after character after character.

  • And in fact, let me go ahead here and draw

  • a picture of what's actually going on underneath the hood of the computer

  • here.

  • So when I type in Zamyla's name, I'm, of course,

  • doing something like Z-A-M-Y-L-A. But where is that actually going?

  • Well, we know now that inside of your computer is RAM or memory,

  • and you can think of it like a grid.

  • And honestly, I can think of this whole screen

  • as just being in a different orientation, a grid of memory.

  • So for instance, maybe we can divide it into rows and columns like this, not

  • necessarily to scale, and there's more rows and columns.

  • So on the screen here, I'm just dividing things

  • into the individual bytes of memory that we saw a moment ago.

  • And so, indeed, underneath the hood of the computer is this layout of memory.

  • The compiler has somehow figured out or the program has somehow figured out

  • where to put the z and where the a and the m and the y and the l and the a,

  • but the key is that they're all contiguous, back to back to back.

  • But the catch is if I'm typing other words into my program or scores

  • into my program or any data into my program,

  • it's going to end up elsewhere in the computer's memory.

  • So how do you know where Zamyla begins and where

  • Zamyla ends, so to speak, in memory?

  • Well, the variable, called s, essentially is here.

  • There's some remembrance in the computer of where s begins.

  • But there's no obvious way to know where Zamyla ends,

  • unless we ourselves tell the computer.

  • So unbeknownst to us, any time a computer is storing a string like

  • Z-A-M-Y-L-A, it turns out that it's not using one, two, three, four, five,

  • six characters.

  • It's actually using seven secretly.

  • It's actually putting a special character

  • of all zeros in the very last bytes.

  • Every byte is eight bits, so it's putting secretly eight zeros there,

  • or we can actually draw this more conventionally as /0.

  • It's what's called the null character, and it just means all zeros.

  • So the length of the string, Zamyla, is six,

  • but how many bytes does it apparently take up, just to be clear?

  • So it actually takes up seven.

  • And this is kind of a secret implementation detail

  • that we don't really have to care about, but eventually, we will,

  • because if we want to implement certain functionality,

  • we're going to need to know what is actually going on.

  • So for instance, let me go ahead and do this.

  • Let me go ahead and create a program called strlen itself.

  • So this is not a function but a program called strlen.c.

  • Let me go ahead and include the CS50 library at the top.

  • Let me go ahead and include stdio.h.

  • Let me go ahead and type out main void, so all this is same as always.

  • And then let me go ahead and prompt the user for, say, his or her name,

  • like so.

  • And then you know what?

  • Let me actually, this time, not just print their name out,

  • because we've done that ad nauseam.

  • Let's just count the number of letters in his or her name.

  • So how could we do that?

  • Well, we could just do this-- int n get strlen of s, and then say,

  • printf "The length of your name is %i."

  • And then we can plug in n, because that's

  • the number we stored the length in.

  • But to use strlen, I have to include what header file?

  • String.h, which is the new one, so string.h.

  • And now if I type this all correctly, make strlen, make strlen, good.

  • ./strlen-- let's try it--

  • Zamyla.

  • Enter.

  • OK, the length of her name is six.

  • But what is strlen doing?

  • Well, strlen is just an abstraction for us that someone else wrote,

  • and it's wonderfully convenient, but you know, we don't strictly need it.

  • I can actually do this myself.

  • If I understand what the computer is doing,

  • I can implement this same functionality myself as follows.

  • I can declare a variable called n and initialize it to 0,

  • and then you know what?

  • I'm going to go ahead and do this.

  • While s bracket n does not equal all zeros,

  • but you don't write all zeros like this.

  • You literally do this--

  • that /0 to which I referred earlier in single quotes.

  • That just means all zeros in the bytes.

  • And now I can go ahead and do n++.

  • If I'm familiar with what this means, remember,

  • that this is just n equals n plus 1, but it's just a little more compact to say,

  • n++.

  • And then I can print out the name of your n--

  • the name of your n--

  • the name of-- the length of your name is %i, plugging in n.

  • So why does this work?

  • It's a little funky-looking, but this is just

  • demonstrating an understanding of what's going on

  • underneath the proverbial hood.

  • If n is initialized to zero, and I look at s bracket n,

  • well, that's like looking at s bracket 0.

  • And if the string, s, is Zamyla, what is s bracket 0?

  • Z. And then it does not equal /0.

  • It equals z, obviously.

  • So we increment n.

  • So now n is 1.

  • Now n is 1.

  • So what is s bracket 1 in Zamyla's name?

  • A and so forth, and we get to Z-A-M-Y-L-A, then all zeros,

  • the so-called null character, or /0.

  • That, of course, does equal /0, so the loop stops,

  • thereby leaving the total count or value of n at what it previously was,

  • which was 6.

  • So that's it.

  • Like all underneath the hood, all we have

  • is memory laid out like this, top to bottom, left to right,

  • and yet all of the functionality we've been using for a week now

  • and henceforth just boils down to some relatively simple primitives,

  • and if you understand those primitives, you

  • can do anything you want using the computer, both computationally

  • code-wise, but also memory-wise.

  • We can actually see, in fact, some of the stuff we looked at two weeks ago as

  • follows.

  • Let me go ahead and open up an example called ASCII 0.

  • Recall that ASCII is the mapping between letters and numbers in a computer.

  • And notice what this program's going to do.

  • Make-- let me go into this folder.

  • Make ascii0, ./ascii0, Enter.

  • The string shall be, let's say, Zamyla, Enter.

  • Well, it turns out that if you actually look up

  • the ASCII code for Zamyla's name, z is 90, lowercase a is 97, m is 109,

  • and so forth.

  • There are those characters, and actually, we

  • can play the same game we did last week.

  • If I do this again on "hi," there's your 72, and there's your 73.

  • Where is this coming from?

  • Well, now that I know how to manipulate individual strings,

  • notice what I can do.

  • I can get a string from the user, just as we always have.

  • I can iterate over the length of that string, albeit inefficiently

  • using strlen here.

  • And then notice this new feature today.

  • I can now convert one data type to another, because a char,

  • a character is just eight bits, but presented in the context of characters.

  • Bytes is also just eight bits that you could treat as an integer, a number.

  • It's totally context-sensitive.

  • If you use Photoshop, it's a graphic.

  • If you use a text program, it's a message and so forth.

  • So you can encode--

  • change the context.

  • So notice here, s bracket i is, of course, the i-th character of Zamyla's

  • name, so Z or A or M or whatever.

  • But I can convert that i-th character to an integer doing what's called casting.

  • You can literally, in parentheses, specify the data type

  • you want to convert one data type to, and then

  • store it in exactly that data type.

  • So s bracket i-- convert it to a number.

  • Then store it in an actual number variable, so I can print out its value.

  • So c-- this is show me the character.

  • Show me the letter as by plugging in the character, and then the letter--

  • sorry, the character and the number that I've just converted it to.

  • And you don't actually even have to be explicit.

  • This is called explicit casting.

  • Technically, we can do this implicitly, too.

  • And the computer knows that numbers are characters,

  • and characters are a number.

  • You don't have to be so pedantic and even do

  • the explicit casting in parentheses.

  • You can just do it implicitly with data types, and honestly, at this point,

  • I don't even need the variable.

  • I can get rid of this, and down here, I can literally just

  • print the same thing twice, but tell printf

  • to print the first in the context of a character

  • and the second in the context of an int, just treating the exact same bits

  • differently.

  • That's implicit casting.

  • And it just demonstrates what we did in week 0

  • when we claimed that letters are numbers,

  • and numbers can also be colors, and colors can be images, and so forth.

  • Is this a question?

  • AUDIENCE: Would've been useful for credit.

  • DAVID J. MALAN: Also, yes.

  • It all comes back to credit.

  • Yeah.

  • Indeed.

  • Other questions?

  • No.

  • All right, so what else can we actually do with this appreciation?

  • So super simple feature that all of us surely take for granted,

  • if we even use it anymore these days.

  • Google Docs, Microsoft Word, and such can automatically

  • capitalize words for you these days.

  • I mean your phone can do it nowadays.

  • They just sort of AutoCorrect your messages.

  • Well, how is that actually working?

  • Well, once you know that a string is just a bunch of characters

  • back to back to back, and you know that these characters have numbers

  • representing them, and like capital A is 65, and lowercase A is 97, apparently,

  • and so forth, we can leverage these patterns.

  • If I go ahead and open up this other example

  • here called Capitalize 0, notice what this program is

  • going to do for me first by running it.

  • Make capitalize 0 ./capitalize0.

  • Let me go ahead and type in Zamyla's name just as before, but now

  • it's all capital.

  • So this is a little extreme.

  • Hopefully, your phone is not capitalizing every letter,

  • but you can imagine it capitalizing just the first, if you wanted it.

  • So how does this work?

  • Well, let me go ahead and open up this example here.

  • And so what we did--

  • so here, I'm getting a string from the user, just as we always do.

  • Then I'm saying, after, just to kind of format the output nicely.

  • Here, I'm doing a loop pretty efficiently from i equals 0 up

  • to the length of the string.

  • And now notice this neat application of logic.

  • It's a little cryptic, certainly, at first glance.

  • But whoops.

  • And now it's gone.

  • And what am I doing exactly with these lines of code?

  • Well, with every iteration of this loop, I'm asking the question,

  • is the i-th character of s, so the current character,

  • is it greater than or equal to lowercase A, and is it less than

  • or equal to lowercase Z?

  • Put another way, how do you say that more colloquially in English?

  • Is it lowercase, literally.

  • But this is the more programmatic way of expressing, is it lowercase?

  • All right, if it is, go ahead and do this.

  • Now this is a little funky, but print out a character, specifically

  • the i-th character, but subtract from that lowercase letter whatever

  • the difference is between little A and big A. Now where did that come from?

  • So it turns out--

  • OK, capital A is 65.

  • Lowercase A is 97.

  • So the difference between those is 32.

  • And that's true for B, so capital B is 66, and lowercase B is 98.

  • Still 32, and it repeats for the whole alphabet.

  • So I could just do this.

  • If I know that lowercase letters have bigger numbers, like 97, 98,

  • and I know that lowercase numbers have lower letters, like 65, 66,

  • I can just literally subtract off 32 from my lowercase letters.

  • As you point out, it's a lowercase letter.

  • Subtract 32, and that gives us what result?

  • The capitalized version.

  • It uppercases things for us.

  • But honestly, this feels a little hackish that, like, OK, yes,

  • I can do the math correctly, but you know what?

  • It's better practice, generally, to abstract this away.

  • Don't get into the weeds of counting how many characters are away

  • from each other.

  • Math is cheap and easy in the computer.

  • Let it do the math for you by subtracting whatever the value of A

  • is, of capital A is from the value of lowercase A. Or we could just write 32.

  • Otherwise, go ahead and just print the character unchanged.

  • So in this case, the A-M-Y-L-A in Zamyla's name got uppercased,

  • and everything else, the Z, got left alone,

  • just by understanding what's going on with how the computer's represented.

  • But honestly, God, I don't want to keep writing code like this.

  • Like, I'm never going to get this.

  • I'm new to programming, perhaps.

  • I'm never going to get this sort of sequence of all the cryptic symbols

  • together, and that's OK, because we can actually implement this same program

  • a little more easily, thanks to functions

  • and abstractions that others have written for us.

  • So in this program, turns out I can simplify

  • the questions I'm asking by literally calling a function that says, is lower.

  • And there's another one called, is upper,

  • and there's bunches of others that just literally are called,

  • is something or other.

  • So is lower takes an argument like the i-th character of s,

  • and it just returns a bull-- true or false.

  • How is it implemented?

  • Well, honestly, if we looked at the code that someone else wrote decades ago

  • for is upper, odds are-- or is lower--

  • odds are he or she wrote code that looks almost like this.

  • But we don't need to worry about that level of detail.

  • We can just use his or her function, but how do we do that?

  • Turns out that this function-- and you would only know this

  • by having been told or Googling or reading a reference--

  • is in a library called ctype.h.

  • And you need the header file called ctype.h in order to use it.

  • And we'll almost always point you to references and documentation

  • to explain that to you.

  • Toupper is another feature, right?

  • This math-- like, my god.

  • I just want to uppercase a letter.

  • I don't want to really keep thinking about how far apart uppercase letters

  • are from lowercase.

  • Turns out that in the C type library, there's

  • another function called toupper that literally does the exact same thing

  • in the previous program we wrote.

  • And so that, too, is OK.

  • But you know what?

  • This feels a little verbose.

  • It would be nice if I could really tighten this program up.

  • So how those toupper work?

  • Well, it turns out some of you might be familiar with CS50 Reference

  • Online, our web-based app that we have that

  • helps you navigate available functions in C.

  • Turns out that all of the data for that application

  • comes from an older command line program that comes in Linux

  • and comes in the sandbox called Man for manual.

  • And anytime you type "man" at the command prompt, and then the name

  • of a function you're interested in, if it exists,

  • it will tell you a little something about it.

  • So if I go to toupper, man toupper, I get slightly cryptic documentation

  • here.

  • But notice, toupper and some other functions

  • convert uppercase or lowercase.

  • That's the summary.

  • Notice that in the synopsis, the man page, so to speak,

  • is telling me what header file I have to include.

  • Notice that under Synopsis, it's also telling me

  • what the signature or prototype is of the function.

  • In other words, the documentation in Man, the Linux programmer's manual,

  • is very terse.

  • So it's not going to hold your hand in this black and white format.

  • It's just going to convey, well, implicitly,

  • you better put this on top of your file.

  • And by the way, this is how you use the function.

  • It takes an argument called C, returns a value of type int.

  • Why is it int?

  • Let me wave my hands at that.

  • It effectively returns a character for our purposes today.

  • And if we scroll down, OK, description.

  • Ugh, I don't really want to read all of this, but OK, here we go.

  • If c is a lowercase letter, toupper returns its uppercase equivalent,

  • if an uppercase representation exists in the current locale.

  • That just means if it's punctuation, it's not going to do anything.

  • Otherwise, it returns C, And that's kind of the key detail.

  • If I pass it lowercase A, it's going to give me capital A,

  • but if I pass it capital A, what's it going to give me?

  • AUDIENCE: Capital A.

  • DAVID J. MALAN: Also, capital A. It returns the original character, c.

  • That's the only detail I cared about.

  • When in doubt, read the manual.

  • And it might be a little cryptic, and this

  • is why CS50 Reference takes somewhat cryptic documentation

  • and tries to simplify it into more human-friendly terms.

  • But at the end of the day, these are the authoritative answers.

  • And if I or one of the staff don't know, we literally

  • pull up the Man page or CS50 Reference to answer these kinds of questions.

  • Now what's the implication?

  • I don't need any of this.

  • I can literally get rid of the condition and just let

  • toupper do all of the legwork, and now my program

  • is so much more compact than the previous versions were,

  • because I've read the documentation.

  • I know what the function does, and I can let toupper uppercase something

  • or just pass it through unchanged.

  • We can better design, because we're writing fewer lines of code that

  • are just as clear, and so we can now actually tighten things up.

  • Any questions on this particular approach?

  • All right.

  • So we're getting very low level.

  • Now let's make these things more useful, because clearly, other people

  • have solved some of these problems for us,

  • as by having these functions and the C type library and the string library.

  • What more is there?

  • Well, recall that every time we run Clang, or even run make,

  • we're typing multiple words at the command prompt.

  • You're typing make hello or make Mario, a second word,

  • or you're typing clang-o, hello, hello.c,

  • like lots of words at the prompt.

  • Well, it turns out that all this time, you're using, indeed,

  • command line arguments.

  • But in C, you can write programs that also accept words and numbers when

  • the user runs the program.

  • Think back, after all.

  • When you ran Mario, you did ./mario, Enter.

  • You couldn't type any more words at the prompt.

  • When you did credit, you did ./credit, Enter.

  • No more words at the prompt.

  • You used get string or get long to get more input, but not

  • at the command line.

  • And it turns out that we can, relatively simply, in C,

  • but it's a little cryptic at first glance.

  • Let me go ahead and--

  • let me go ahead and, here, pull up this signature here, which looks like this.

  • This is the function that we're all used to by now for writing a main function.

  • And up until now, we've said void.

  • Main doesn't take any inputs, and indeed, it just runs.

  • But it turns out if you change your existing programs or future programs,

  • not to say void, but to say, int argc, string argv,

  • it's a little cryptic at first glance.

  • But what's a recognizable symbol now?

  • Yeah, there's brackets here.

  • So it turns out that every time you write a program,

  • if you don't just say void, you actually enable this feature

  • by writing int argc, string argv.

  • You can actually tell Clang, you know what?

  • I want this program to accept one or more words or numbers after the name

  • of the program, so I can do ./hellodavid, or ./hellozamyla.

  • I don't have to wait for the program to be running to use string.

  • And just as with the earlier example, where you were able to chart an array,

  • main is defined as taking an array, called argv historical reasons--

  • argument vector.

  • Vector means array.

  • Argument vector, bracket, closed bracket just means this is--

  • this contains one or more words, each of which is a string.

  • Argc is argument count, so this is the variable

  • that main gets access to that tells it how many arguments,

  • how many strings are actually in argv.

  • So how can we use this in a useful way?

  • Well, let me go ahead here and open up the sandbox.

  • And let me go ahead and create a new file called, say, argv0, argv0.c--

  • again, argument vector, just list or array of arguments.

  • And let me go ahead and, as usual, include cs50.h, include stdio.h,

  • and then int main not void, but int argc, string argv--

  • argv-- open bracket, closed bracket.

  • And even if that doesn't come naturally at first, it will eventually.

  • And I'm going to do this.

  • If the number of arguments passed in equals 2,

  • then I'm going to go ahead and do this-- printf, hello %s, comma,

  • and here in the past, I've typed a variable name.

  • And I now actually have access to a variable.

  • Go ahead and do argv bracket 1.

  • Else, if the user does not type, apparently, two words,

  • let me go ahead and just by default, say, hello world, as we always have.

  • Now why-- what is this doing, and how is it doing it?

  • Well, let's quickly run it.

  • So make-- whoops.

  • Make argv0, ./argv0, Enter, Hello World.

  • But if I do Hello--

  • or dot-- the program would be better named

  • if we called it Hello, but Zamyla, Enter.

  • Hello Zamyla.

  • If I change it to David, now I have access to David.

  • If I had David Malan, no.

  • It doesn't support that.

  • So what's going on?

  • If you change main in any program write to take

  • these two arguments, argc and argv of type string int

  • and then an array of strings, argc tells you how many words

  • were typed at the prompt.

  • So if the human typed two words, I presume

  • the first word is the name of the program, dot slash argv0,

  • the second word is presumably my name, if he or she is actually

  • providing their name at the prompt.

  • And so I print out argv bracket 1.

  • Not 0 because that's the name of the program, but argv bracket 1.

  • Else, down here, if the human doesn't provide just Zamyla, or just David,

  • or just one word more generally, I just print the default, "Hello world."

  • But what's neat about this now is notice that argv is an array of strings.

  • What is a string?

  • It's an array of characters.

  • And so let's enter just one last piece of syntax that gets kind of powerful

  • here.

  • Let me go ahead and do this.

  • Let me go ahead and, in a new file here, argv 1 dot c.

  • Let me go ahead and paste this in.

  • Close this.

  • Let me go ahead and do this.

  • Rather than do this logical checking, let me do this, for--

  • let's say for int, i get 0.

  • i is less than argc--

  • i++.

  • Let's go ahead and, one per line, print out every word

  • that the human just typed, just to reinforce

  • that this is indeed what's going on.

  • So argv bracket 0, save.

  • Make argv 1, enter.

  • And now let's go ahead and run this program--

  • dot slash, argv 1, David Malan.

  • OK, you see all three words.

  • If we change it to Zamyla, we see just those two words.

  • If we change it to Zamyla Chan, we see those three words.

  • So we clearly have access to all of the words in the array,

  • but let's take this one step further.

  • Rather than just print out every word in a string, let's go ahead and do this.

  • For intj get 0.

  • n equals the string length of the current argument, like this--

  • j is less than n, j++--

  • oops, oops, oops-- j++.

  • Now let me go ahead and print out not the full string, but let me do-- oops,

  • oops-- let me go ahead and print out this--

  • not a string, but a character, n bracket i bracket j, like this.

  • All right.

  • So what's going on?

  • One, this outer loop, and let's comment it, iterate over strings in argv.

  • This inner loop, iterate over chars in argv bracket i.

  • So the outer loop iterates over all of the strings in argv.

  • And the inner loop, using a different variable, starting at 0,

  • iterates over all of the characters in the ith

  • argument, which itself is a string.

  • So we can call string length on it.

  • And then we do this up until n, which is the length of that string.

  • And then we print out each character.

  • So just to be clear-- when I run arv1 and correct it, at first glance,

  • why it's implicitly declaring library function sterling, what's almost always

  • the solution when you do this wrong?

  • AUDIENCE: [INAUDIBLE]

  • DAVID J. MALAN: Yeah.

  • So I forgot this, so include string.h and help50 would

  • help with that as well.

  • Let's recompile with make argv1.

  • All right.

  • When I run argv1, of, say, Zamyla Chan, what am I going to see?

  • AUDIENCE: [INAUDIBLE]

  • DAVID J. MALAN: Yeah.

  • Is that the right intuition?

  • AUDIENCE: [INAUDIBLE]

  • DAVID J. MALAN: I'm going to see Zamyla Chan, but--

  • AUDIENCE: [INAUDIBLE]

  • DAVID J. MALAN: One character on each line, including the program's name.

  • So in fact, let me scroll this up so it's a little bigger.

  • Enter.

  • OK, it's a little stupid, the program, but it does confirm that using arrays

  • do I have access not only to the words, but I can kind of

  • have the second dimension.

  • And within each word, I can get at each character within.

  • And we do this, again, just by using not just single square brackets,

  • but double.

  • And again, just break this down into the first principles.

  • What is this first bracket?

  • This is the ith argument, the ith string in the array.

  • And then if you take it further, with bracket j,

  • that gives you the j character inside of this.

  • Now, who cares about any of this kind of functionality?

  • Well, let me scroll back and propose one application here.

  • So recall that CS is really just problem solving.

  • But suppose the problem that you want to solve

  • is to actually pass a secret message in class

  • or send someone a secret for whatever reason.

  • Well, the input to that problem is generally

  • called plain test, a message you want to send to that other person.

  • You ideally want ciphertext to emerge from it,

  • which is enciphered and scrambled, somehow encrypted information

  • so that anyone in the room, like the teacher, can't just grab the note

  • and read what you're sending to your secret crush or love across the room,

  • or in any other context as well.

  • But the problem is that if the message you want to send, say,

  • is our old friend Hi!, with an exclamation point,

  • you can encode it in certain contexts as just 72, 73, 33.

  • And I daresay most classes on campus if you wrote on a piece of paper 72,

  • 73, 33, passed it through the room, and whatever professor intercepts it,

  • they're not going to know what you're saying anyway.

  • But this is not a good system.

  • This is not a cryptosystem.

  • Why?

  • It's not secure.

  • [INAUDIBLE]

  • [INTERPOSING VOICES]

  • DAVID J. MALAN: Yeah.

  • Anyone has access to this, right, so long

  • as you attend like week 1 or 0 of CS50, or you just

  • have general familiarity with Ascii.

  • Like this is just a code.

  • I mean Ascii is a system that maps letters to numbers.

  • And anyone else who knows this code obviously

  • knows what your message is, because it's not a unique secret

  • to you and the recipient.

  • So that's probably not the best idea.

  • Well, you can be a little more sophisticated.

  • And this is back-- actually, a photograph

  • from World War I of a message that was sent from Germany to Mexico

  • that was encoded in a very similar way.

  • It wasn't using Ascii.

  • The numbers, as you can perhaps glean from the photo,

  • are actually much larger.

  • But in this system, in a militaristic context, there was a code book.

  • So similar in spirit to Ascii, where you have

  • a column of numbers and a column of letters to which they correspond,

  • a codebook more generally has like numbers, and then maybe

  • even letters or whole words that they correspond to,

  • sometimes thousands of them, like literally a really big book of codes.

  • And so long as only, in this context the Germans and the recipients,

  • the Mexicans, had access to that same book,

  • only they could encrypt and decrypt, or rather encode and decode information.

  • Of course, in this very specific context--

  • you can read more about this in historical texts--

  • this was intercepted.

  • This message, seemingly innocuous, though definitely

  • suspicious looking with all these numbers,

  • so therefore not innocuous, the British, in this case actually, intercepted it.

  • And thanks to a lot of efforts and cryptanalysis,

  • the Bletchley Park style code breaking, albeit further back,

  • were they able to figure out what those numbers represented in words

  • and actually decode the message.

  • And in fact, here's a photograph of some of the words

  • that were translated from one to the other.

  • But more on that in any online or textual references.

  • Turns out in this poem too there was a similar code, right?

  • So apropos of being in Boston here, you might recall this one.

  • "Listen my children, and you shall hear of the midnight ride of Paul Revere.

  • On the 18th of April in '75, hardly a man

  • is now alive who remembers that famous day and year.

  • He said to his friend, if the British march by land or sea

  • from the town tonight night, hang a lantern

  • aloft in the belfry arch of the North Church tower as a signal light,

  • one if by land, and two if by sea.

  • And I on the opposite shore will be ready to ride and spread

  • the alarm through every Middlesex village and farm for the country folk

  • to be up and to arm."

  • So it turns out some of that is not actually factually correct,

  • but the one if by land and the two if by sea code were

  • sort of an example of a one-time code.

  • Because if the revolutionaries in the American Revolution kind of

  • decided secretly among themselves literally that-- we will put up one

  • light at the top of a church if the British are coming by land.

  • And we will instead use two if the British are instead coming by sea.

  • Like that is a code.

  • And you could write it down in a book, unless you have a code book.

  • But of course, as soon as someone figures out that pattern,

  • it's compromised.

  • And so code books tend not to be the most robust mechanisms

  • for encoding information.

  • Instead, it's better to use something more algorithmic.

  • And wonderfully, in computer science is this black box

  • to-- we keep saying, the home of algorithms.

  • And in general, encryption is a problem with inputs and outputs,

  • but we just need one more input.

  • The input is what's generally called the key, or a secret.

  • And a secret might just be a number.

  • So for instance, if I wanted my secret to be 1,

  • because we'll keep the example simple, but it could really be any number.

  • And indeed, we saw with the photograph a moment ago,

  • the Germans used much larger than this, albeit in the context of codes.

  • Suppose that you now want to send a more private message to someone

  • across the room in a class that, I love you.

  • How do you go about encoding that in a way that isn't just using Ascii

  • and isn't just using some simple code book?

  • Well, let me propose that now that we understand how strings are represented,

  • right-- we're about to make love really, really lame and geeky--

  • so now that you know how to express strings computationally,

  • well, let's just start representing "I love you" in Ascii.

  • So I is 73.

  • L is 76.

  • O-V-E Y-O-U. That's just Ascii.

  • Should not send it this way, because anyone

  • who knows Ascii is going to know what you're saying.

  • But what if I enciphered this message, I performed an algorithm on it?

  • And at its simplest, an algorithm can just

  • be math-- simple arithmetic, as we've seen.

  • So you know, let me just use my secret key of 1.

  • And let me make sure that my crush knows that I am using a secret value of 1.

  • So he or she also knows to expect that value.

  • And before I send my message, I'm going to add 1 to every letter.

  • So 73 becomes 74.

  • 76 becomes 77.

  • 80, 87, 70, 90, 80, 86.

  • Now this could just be sent in the clear.

  • But then, I could actually send it as a textual message.

  • So let's convert it back to Ascii.

  • 74 is now J. 77 is now M. 80 is now P. And you can perhaps see the pattern.

  • This message was, I love you.

  • And now, all of the letters are off by one, I think.

  • I became J. L became M. O became P, and so forth.

  • So now the claim would be, cryptographically, I'm

  • going to send this message across the room.

  • And now no one who has a code book is going to be able to solve this.

  • I can't just steal the book and decode it,

  • because now the key is only up here, so to speak.

  • It's just the number 1 that he or she and I

  • had to agree upon in advance that we would

  • use for sending our secret messages.

  • So if someone captures this message, teacher in the room or whoever,

  • how would they even go about decoding this or decrypting it?

  • Are there any techniques available to them?

  • I daresay we can kind of chip away at this love note.

  • AUDIENCE: [INAUDIBLE]

  • DAVID J. MALAN: What's that?

  • Guess and check.

  • OK, we could try all--

  • there still kind of some spacing.

  • So you know honestly, we could do like kind of a cryptanalysis of it,

  • a frequency attack.

  • Like, I can't think of too many words in English

  • that have a single letter in them.

  • So what does J probably represent?

  • [INTERPOSING VOICES]

  • DAVID J. MALAN: I, probably.

  • Maybe A, but probably I. And there's not too many other options.

  • So we've attacked one part of the message already.

  • I see a commonality.

  • There's two what in here?

  • Two P. And I don't necessarily know that that maps to O, but I do

  • know it's the same character.

  • So if I kind of continue this thoughtful process or this trial and error,

  • and I figure out, oh, what if that's an O?

  • And then that's an O. And then wait a minute.

  • They're passing from one to another.

  • Maybe this says, I love you.

  • Like you actually can, with some probability,

  • decrypt a message by doing this kind of analysis on it.

  • It's at least more secure than the code book,

  • because you're not compromised if the book itself is stolen.

  • And you can change the key every time, so long as you

  • and the recipient actually agree on something.

  • But at least we now have this mechanism in place.

  • So with just the understanding of what you can do with strings,

  • can you actually now do really interesting domain-specific things

  • to them?

  • And in fact, back in the day, Caesar, back in militaristic times literally

  • used a cipher quite like this.

  • And frankly, when you're the first one to use these ciphers,

  • they actually are kind of secure, even if they're relatively simple.

  • But hopefully, not just using a key of 1, maybe 2, or 13, or 25,

  • or something larger.

  • But this is an example of a substitution cipher,

  • or a rotational cipher where everything's kind of rotating--

  • A's becoming B, B's becoming C. Or you can kind of

  • rotate it even further than that.

  • Well, let's take a look at one last example here

  • of just one other final primitive of a feature

  • today, before we then go back high level to bring everything together.

  • It turns out that printing out error messages

  • is not the only way to signal that something has gone wrong.

  • There's a new keyword, a new use of an old keyword in this example,

  • that's actually a convention for signaling errors.

  • So this is an example called exit.c.

  • It apparently wants the human to do what, if you infer from the code?

  • AUDIENCE: Exit [INAUDIBLE].

  • DAVID J. MALAN: Yes.

  • Say again?

  • AUDIENCE: [INAUDIBLE]

  • DAVID J. MALAN: Well, it wants the-- well, what

  • does it what the human to do implicitly, based on the printf's here?

  • How should I run this program?

  • Yeah?

  • AUDIENCE: [INAUDIBLE] just apply [INAUDIBLE]..

  • DAVID J. MALAN: Yeah.

  • So for whatever reason, this program implicitly

  • wants me to write exactly two words at the prompt.

  • Because if I don't, it's going to yell at me, missing command line argument.

  • And then it's going to return 1, whatever that is.

  • Otherwise, it's going to say, Hello, such and such.

  • So if I actually run this program--

  • let me go back over here and do make exit--

  • oops-- in my directory, make exit.

  • OK, dot slash exit, enter, I'm missing a command line argument.

  • All right, let me put Zamyla's name.

  • Oh, Hello Zamyla.

  • Let me put Zamyla Chan.

  • Nope, missing command line argument.

  • It just wants the one, so in this case here.

  • I'm seeing visually the error message, but it turns out

  • the computer is also signaling to me what the so-called exit code is.

  • So long story short, we've already seen examples last week of how

  • you can have a function return a value.

  • And we saw how [? Erin ?] came up on stage,

  • and she returned to me a piece of paper with a string on it.

  • But it turns out that main is a little special.

  • If main returns a value like 1 or 0, you can actually see that,

  • albeit in a kind of a non-obvious way.

  • If I run exit, and I run it correctly with Zamyla as the name,

  • if I then type echo, dollar sign, question mark, of all things,

  • enter, I will then see exactly what main returned with, which in this case is 0.

  • Now, let me try and be uncooperative.

  • If I actually run just dot slash exit, with no word,

  • I see, missing command line argument.

  • But if I do the same cryptic command, echo, dollar sign, question mark,

  • I see that main exited with 1.

  • Now, why is this useful?

  • Well, as we start to write more complicated programs,

  • it's going to be a convention to exit from main by returning

  • a non-zero value, if anything goes wrong.

  • 0 happens to mean everything went well.

  • And in fact, in all of the programs we've

  • written thus far, if you don't mention return anything,

  • main automatically for you returns 0.

  • And it has been all this time.

  • It's just a feature, so you don't have to bother typing it yourself.

  • But what's nice about this, or what's real about this,

  • is if on your Mac or PC, if you've ever gotten an annoying error message that

  • says, error negative 29, system error has occurred, or something freezes,

  • but you very often see numbers on the screen, maybe.

  • Like those error codes actually tend to map to these kinds of values.

  • So when a human is writing software and something goes wrong

  • and an error happens, they typically return a value like this.

  • And the computer has access to it.

  • And this isn't all that useful for the human running the program.

  • But as your programs get more complex, we'll

  • see that this is actually quite useful as a way of signaling

  • that something indeed went wrong.

  • Whew.

  • OK, that's a lot of syntax wrapped in some loving context.

  • Any questions before we look at one final domain?

  • No?

  • All right.

  • So it turns out that we can answer the "who cares" question in yet another way

  • too.

  • It turns out-- let me go ahead and open up an example of our array again here--

  • that arrays can actually now be used to solve problems more algorithmically.

  • And this is where life gets more interesting.

  • Like we were so incredibly in the weeds today.

  • And as we move forward in the class, we're

  • not going to spend so much time on syntax,

  • and dollar signs, and question marks, and square brackets, and the like.

  • That's not the interesting part.

  • The interesting part is when we now have these fundamental building

  • blocks, like an array, with which we can solve problems.

  • So it turns out that an array, you know, you

  • can kind of think of it as a series of lockers,

  • a series of lockers that might look like this, inside of which

  • are values-- strings, or numbers, or chars, or whatnot.

  • But the lockers is an apt metaphor because a computer, unlike us humans,

  • can only see and do one thing at a time.

  • It can open one locker and look inside, but it can't kind of

  • take a step back, like we humans can, and look at all of the lockers,

  • even if all of the doors are open.

  • So it has to be a more deliberate act than that.

  • So what are the actual implications?

  • Well, all this time--

  • we had that phone book example in the first week,

  • and the efficiency of that algorithm, of finding Mike Smith in this phone book,

  • all assumed what feature of this phone book?

  • AUDIENCE: That it's ordered alphabetically.

  • DAVID J. MALAN: That it was ordered alphabetically.

  • And that was a huge plus, because then I could go to the middle,

  • and I could go to the middle of the middle, and so forth.

  • And that was an algorithmic possibility.

  • On our phones, if you pull up your contacts,

  • you've got a list of first names, or last names, all alphabetically sorted.

  • That is because, guess what data structure or layout

  • your phone probably uses to store your contacts?

  • It's an array of some sort, right?

  • It's just a list.

  • And it might be displayed vertically, instead of horizontally,

  • as I've been drawing it today.

  • But it's just values that are back, to back, to back, to back, to back,

  • that are actually sorted.

  • But how did they actually get into that sorted order?

  • And how do you actually find values?

  • Well, let's consider what this problem is actually

  • like for a computer, as follows.

  • Let me go ahead here.

  • Would a volunteer mind joining us up here?

  • I can throw in a free stress ball.

  • OK, someone from the back?

  • OK, come on up here.

  • Come on.

  • What's your name?

  • ERIC: Eric.

  • DAVID J. MALAN: Aaron.

  • All right.

  • So Aaron's going to come on up.

  • And--

  • ERIC: Eric.

  • DAVID J. MALAN: I'm sorry?

  • Oh, Eric.

  • Nice to meet you.

  • All right.

  • Come on over here.

  • So Eric, now normally, I would ask you to find the number 23.

  • But seeing is that's a little easy, can you go ahead and just find us

  • the number 50 behind these doors, or really these yellow lockers?

  • 8?

  • Nope.

  • 42?

  • Nope.

  • OK.

  • Pretty good.

  • That's three, three out of seven.

  • How did you get it so quickly?

  • ERIC: I guessed.

  • DAVID J. MALAN: OK, so he guessed.

  • Is that the best algorithm that Eric could have used here?

  • ERIC: Probably not.

  • DAVID J. MALAN: Well, I don't know.

  • Yes?

  • No?

  • AUDIENCE: Yeah.

  • DAVID J. MALAN: Why?

  • Why yes?

  • AUDIENCE: [INAUDIBLE]

  • DAVID J. MALAN: He has no other information.

  • So yes, like that was the best you can do.

  • But let me give you a little more information.

  • You can stay here.

  • And let me go ahead and reload the screen here.

  • And let me go ahead and pull up a different set of doors.

  • And now suppose that, much like the phone book, and much like the phones

  • are sorted, now these doors are sorted.

  • And find us the number 50.

  • All right.

  • So good.

  • What did you do that time?

  • AUDIENCE: Well, [INAUDIBLE].

  • It was 50 is 116.

  • So I just--

  • DAVID J. MALAN: Right.

  • So you jumped to the middle, initially, and then to the right half.

  • And then technically-- so we're technically off by 1, right?

  • Because like binary search would have gone to the middle of the--

  • that's OK, but very well done to Eric.

  • Here, let me at least reinforce this with a stress ball.

  • So thank you.

  • Very well done.

  • So with that additional information, as you know,

  • Eric was able to do better because the information was sorted on the screen.

  • But he only had one insight to a locker at a time,

  • because only by revealing what's inside can he actually see it.

  • So this seems to suggest that once you do

  • have this additional information in Eric's example, in your phone example,

  • in the phone book example, you open up possibilities for much much, much more

  • efficient algorithms.

  • But to get there, we've kind of been deferring this whole time in class

  • how you actually sort these elements.

  • And if you wouldn't mind-- and this way, we'll hopefully end on a more energized

  • note here because I know we've been in the weeds for a while--

  • can we get like eight volunteers?

  • OK, so 1, 2, 3, 4-- how about 5, 6, 7, 8, come on down.

  • Oh, I'm sorry.

  • Did I completely overlook the front row?

  • OK.

  • All right, next time.

  • Next time.

  • Come on down.

  • Oh, and Colton, do you mind meeting them over there instead?

  • All right.

  • Come on up.

  • What's your name?

  • [? CAHMY: ?] [? Cahmy. ?]

  • DAVID J. MALAN: [? Cahmy? ?] David.

  • Right over there.

  • What's your name?

  • MATT: Matt.

  • DAVID J. MALAN: Matt?

  • David.

  • [? JUHE: ?] [? Juhe. ?]

  • DAVID J. MALAN: [? Juhe? ?] David.

  • MAX: Max.

  • DAVID J. MALAN: Max, nice to meet you.

  • JAMES: James.

  • DAVID J. MALAN: James, nice to see you.

  • Here, I'll get more chairs.

  • What's your name?

  • ,PEYTON: Peyton.

  • DAVID J. MALAN: Peyton?

  • David.

  • And two more.

  • Actually can what have you come down to this end here?

  • What's your name.

  • ANDREA: Andrea.

  • DAVID J. MALAN: Andrea, nice to see you.

  • And your name?

  • [? PICCO: ?] [? Picco. ?]

  • DAVID J. MALAN: [? Picco, ?] David.

  • Nice to see you.

  • OK, Colton has a T-shirt for each of you, very Harvard-esque here.

  • And each of these shirts, as you're about to see, has a number on it.

  • And that number is--

  • well, go ahead put them on, if you wouldn't mind.

  • OK, thank you so much.

  • So I daresay we've arranged our humans much like the lockers in an array.

  • Like we have humans back, to back, to back, to back.

  • But this is actually both a blessing and a constraint,

  • because we only have eight chairs.

  • So there's really not much room here, so we're confined to just this space here.

  • And I see we have a 4, 8, 5, 2, 3, 1, 6, 7.

  • So this is great.

  • Like they are unsorted.

  • By definition, it's pretty random.

  • So that's great.

  • So let's just start off like this.

  • Sort yourselves from 1 to 8, please.

  • OK.

  • All right.

  • Well, what algorithm was that?

  • [LAUGHTER]

  • AUDIENCE: Look around, figure it out.

  • DAVID J. MALAN: Look around, figure it out.

  • OK, well--

  • MATT: Human ingenuity.

  • DAVID J. MALAN: Human ingenuity?

  • Very well done.

  • So can we-- well, what was like a thought

  • going through any of your minds?

  • MATT: Find a chair and sit down.

  • DAVID J. MALAN: Find the chair--

  • find the right chair.

  • So go to a location.

  • Good.

  • So like an index location, right?

  • Arrays have indices, so to spea--

  • 0, 1, 2, all the way up to 7.

  • And even though our shirts are numbered from 1 to 8,

  • you can think in terms of 0 to 7.

  • So that was good.

  • Anyone else?

  • Other thoughts?

  • [? CAHMY: ?] I mean, this is something we implicitly think of,

  • but no one told us that it was ordered right to left.

  • Like we could have done it left to right.

  • DAVID J. MALAN: OK.

  • Absolutely.

  • Could have gone from right to left, instead of left to right.

  • But at least we all agreed on this convention

  • too, so that was in your mind.

  • OK.

  • So good.

  • So we got this sorted.

  • Go ahead and re-randomize yourself, if you could.

  • And what algorithm was this?

  • Just random awkwardness?

  • OK, so that's fine.

  • So it looks pretty random.

  • That will do.

  • Let's see if we can now reduce the process of sorting

  • to something a little more algorithmic so that, one, we can be sure

  • we're correct and not just kind of get lucky that everyone kind of figured it

  • out and no one was left out, and two, then

  • start to think about how efficient it is, right?

  • Because if we've been gaining so much efficiency for the phone book,

  • for our contacts, for [? error ?] coming up,

  • we really should have been asking the whole time,

  • sure, you save time with binary search and divide and conquer,

  • but how much did it cost you to get to a point

  • where you can use binary search and divide and conquer?

  • Because sorting, if it's super, super, super expensive and time-consuming

  • maybe it's a net negative.

  • And you might as well just search the whole list,

  • rather than ever sort anything.

  • All right.

  • So let's see here.

  • 6 and 5, I don't like this.

  • Why?

  • AUDIENCE: [INAUDIBLE]

  • DAVID J. MALAN: 6 is supposed to come after 5.

  • And so, can we fix this, please?

  • All right.

  • And then let's see.

  • OK, 6 and 1-- ugh, don't really like this.

  • Yeah, can we fix this?

  • Very nice.

  • 6 and 3, OK, you really got the short end of the stick here.

  • So 6 and 3, could we fix this?

  • And 6-- yeah, OK.

  • Ooh, OK, 6 and 7-- good.

  • All right, so that's pretty good.

  • 7 and 8, nice.

  • 8 and 4, sorry.

  • Could we switch here?

  • All right.

  • And then 8 and 2?

  • OK, could we switch here?

  • OK.

  • And let me ask you a somewhat rhetorical question.

  • OK, am I done?

  • OK, no.

  • Obviously not, but I did fix some problems, right?

  • I fixed some transpositions, numbers being out of order.

  • And in fact, I-- what's your name again?

  • [? CAHMY: ?] [? Cahmy. ?]

  • DAVID J. MALAN: [? Cahmy, ?] kind of bubbled to the right here, if you will.

  • Like you were kind of farther down, and now you're over here.

  • And like the smaller numbers, kind of-- yeah 1.

  • Like, my god, like he kind of bubbled his way this way.

  • So things are percolating, in some sense.

  • And that's a good thing.

  • And so you know what?

  • Let Me try to fix some remaining problems.

  • So 1 and 5-- good.

  • Oh 3 and 5, could you switch?

  • 5 and 6, OK.

  • 6 and 7?

  • 7 and 4, could you switch?

  • OK.

  • And 7 and 2, could you switch?

  • And now, I don't have to speak with [? Cahmy ?] again,

  • because we know you're in the right place.

  • So I actually don't have to do quite as much work

  • this time, which is kind of nice.

  • But am I done?

  • No, obviously not.

  • But what's the pattern now?

  • Like what's the fundamental primitive?

  • If I just compare pairwise humans and numbers,

  • I can slightly improve the situation each time

  • by just swapping them, swapping them.

  • And each time now--

  • I'm sorry, [? Picco ?] is in number 7's place.

  • I don't have to talk to him anymore, because he's now bubbled

  • his way all the way up to the top.

  • So even though I'm doing the same thing again and again,

  • and looping again and again isn't always the best thing,

  • so long as you're looping fewer and fewer times, I will eventually stop,

  • it would seem.

  • Because 6 is going to eventually go in the right place, and then 5,

  • and then 4, and so forth.

  • So if we can just finish this algorithm.

  • Good.

  • Not good.

  • OK, 6 and 2, not good.

  • If you could swap?

  • OK, and what's your name again?

  • PEYTON: Peyton.

  • DAVID J. MALAN: Peyton is now in the right place.

  • I have even less work now ahead of me.

  • So if I can just continue this process--

  • 1 and 3, 3 and 5, 4 and 5, OK, and then 2 and 5.

  • And then, what's your name again?

  • MATT: Matt.

  • DAVID J. MALAN: Matt is now in the right place.

  • Even less work.

  • We're almost there.

  • 1 and 3, 3 and 4, 4 and 2, if you could swap.

  • OK, almost done.

  • And 1 and 3, 3 and 2, if you could swap.

  • Nice.

  • So this is interesting.

  • It would seem that-- you know, in the first place,

  • I kind of compared seven pairs of people.

  • And then the next time I went through, I compared how many pairs of people

  • maximally?

  • AUDIENCE: [INAUDIBLE]

  • DAVID J. MALAN: Just six, right?

  • Because we were able to leave [? Cahmy ?] out.

  • And then we were able to leave [? Picco ?] out, and then Peyton.

  • And so the number of comparisons I was doing was getting fewer and fewer.

  • So that feels pretty good.

  • But you know what?

  • Before We even analyze that, can you just randomize yourselves again?

  • Any human algorithm is fine.

  • Let's try one other approach, because this feels kind of non-obvious, right?

  • I was fixing things, but I had to keep fixing things again and again.

  • Let me try to take a bigger bite out of the problem

  • this time by just selecting the smallest person.

  • OK, so your name again is?

  • [? JUHE: ?] [? Juhe. ?]

  • DAVID J. MALAN: [? Juhe, ?] number 2-- that's a pretty small number,

  • so I'm going to remember that in sort of a mental variable.

  • 4?

  • No, you're too big.

  • Too big.

  • Oh, what was your name again?

  • JAMES: James.

  • DAVID J. MALAN: James.

  • James is a 1.

  • That's pretty nice.

  • Let me keep checking.

  • OK, James, in my mental variable is the smallest number.

  • I know I want him at the beginning.

  • So if you wouldn't mind coming with me.

  • And I'm sorry, we don't have room for you anymore.

  • If you could just-- oh, you know what?

  • Could you all just shuffle down?

  • Well, hm, I don't know if I like that.

  • That's a lot of work, right?

  • Moving all these values, let's not do that.

  • Let's not do that.

  • Number 2, could you mind just going where--

  • where--

  • JAMES: It's James.

  • DAVID J. MALAN: --James was?

  • OK, so I've kind of made the problem a little worse in that,

  • now, number 2 is farther away from the goal.

  • But I could have gotten lucky, and maybe she was number 7 or 8.

  • And so let me just claim that, on average, just evicting the person

  • is going to kind of be a wash and average out.

  • But now James is in the right place.

  • Done.

  • Now I have a problem that's of size 7.

  • So let me select the next smallest person.

  • 4 is the next smallest, not 8, not 5, not 7-- ooh, 2.

  • Not 3, 6.

  • OK, so you're back in the game.

  • All right, come on back.

  • And can we evict number 4?

  • And on this algorithm, if you will, I just

  • interpretively select the smallest person.

  • I'm not comparing everyone in quite the same way and swapping them pairwise,

  • I'm doing some of more macroscopic swaps.

  • So now I'm going to look for the next smallest, which is 3.

  • If you wouldn't mind popping around here?

  • [? Cahmy, ?] we have to, unfortunately, evict you,

  • but that works out to our favor.

  • Let me look for the next smallest, which is 4.

  • OK, you're back in.

  • Come on down.

  • Swap with 5.

  • OK, now I'm looking for 5.

  • Hey, 5, there you are.

  • OK.

  • So go here.

  • OK, looking for 6.

  • Oh, 6, a little bit of a shuffle.

  • OK.

  • And now looking for 7.

  • Oh, 7, if you could go here.

  • But notice, I'm not going back.

  • And this is what's important.

  • Like my steps are getting shorter and shorter.

  • My remaining steps are getting shorter and shorter.

  • And now we've actually sorted all of these humans.

  • So two fundamentally different ways, but they're both comparative in nature,

  • because I'm comparing these characters again,

  • and again, and again, and swapping them if they're out of order.

  • Or at a higher level, going through and swapping them again,

  • and again, and again.

  • But how many steps am I taking each time?

  • Even though I was doing fewer and fewer and I wasn't doubling back,

  • the first time, I was doing like n minus 1 comparisons.

  • And then I went back here.

  • And in the first algorithm, I kind of stopped going as far.

  • In the second algorithm, I just didn't go back as far.

  • So it was just kind of a different way of thinking of the problem.

  • But then I did what?

  • Like seven comparisons?

  • Then six, then five, then four, then three, then two, then one.

  • It's getting smaller, but how many comparisons is that total?

  • I've got like n people, n being a number.

  • AUDIENCE: [INAUDIBLE]

  • DAVID J. MALAN: Is not as bad as factorial.

  • We'd be here all day long.

  • But it is big.

  • It is big.

  • Let's go-- a round of applause, if we could, for our volunteers.

  • You can keep the shirts, if you'd like, as a souvenir.

  • [APPLAUSE]

  • Thank you, very much.

  • Let me see if we can't just kind of quantify that-- thank you, so much--

  • and see how we actually got to that point.

  • If I go ahead and pull up not our lockers, but our answers here,

  • let me propose that what we just did was essentially two algorithms.

  • One has the name bubble.

  • And I was kind of deliberately kind of shoehorning the word in there.

  • Bubble sort is just that comparative sort, pair by pair,

  • fixing tiny little mistakes.

  • But we needed to do it again, and again, and again.

  • So those steps kind of add up, but we can express them as pseudocode.

  • So in pseudocode-- and you can write this any number of ways--

  • I might just do the following.

  • Just keep doing the following, until there's no remaining swaps--

  • from i from 0 to n -2, which is just n is the total number of humans.

  • n -2 is go up from that person to this person,

  • because I want to compare him or her against the person next to them.

  • So I don't want to accidentally do this.

  • That's why it's n -2 at the end here.

  • Then I want to go ahead and, if the ith and the ith +1 elements are out

  • of order, swap them.

  • So that's why I was asking our human volunteers to exchange places.

  • And then just keep doing that, until there's no one left to swap.

  • And by definition, everyone is in order.

  • Meanwhile, the second algorithm has the conventional name of selection sort.

  • Selection sort is literally just that, where you actually

  • select the smallest person, or number of interest to you, intuitively,

  • again and again.

  • And the number keeps getting bigger, but you

  • start ignoring the people who you've already put into place.

  • So the problem, similarly, is getting smaller and smaller.

  • Just like in bubble sort, it was getting more and more sorted.

  • The pseudocode for selection sort might look like this.

  • For i from 0 to n -1, so that's 0 in an array.

  • And this is n -1.

  • Just keep looking for the smallest element between those two chairs,

  • and then pull that person out.

  • And then just evict whoever's there-- swap them,

  • but not necessarily adjacently, just as far away as is necessary.

  • And in this way, I keep turning my back on more and more people

  • because they are then in place.

  • So two different framings of the problem,

  • but it turns out they're actually both the same number of steps, give or take.

  • It turns out they're roughly the same number of steps,

  • even though it's a different way of thinking about it.

  • Because if I think about bubble sort, the first iteration, for instance,

  • what just-- actually, well, let's consider selection sort even.

  • In selection sort, how many comparisons did I have to do?

  • Well, once I found my smallest element, I

  • had to compare them against everyone else.

  • So that's n -1 comparisons the first time.

  • So n -1 on the board.

  • Then I can ignore them, because they're behind me now.

  • So now I have how many comparisons left out of n people?

  • n -2, because I subtracted one.

  • Then again, n -3, then n -4, all the way down to just one person remaining.

  • So I'll express that sort of generally, mathematically, like this.

  • So n -1 plus n -2 plus whatever plus one final comparison, whatever that is.

  • It turns out that if you actually read the back of the math

  • book or your physics textbooks where they have those little cheat

  • sheets as to what these recurrences are, turns out that n -1 plus n -2 plus n -3

  • and so forth can be expressed more succinctly

  • as literally just n times n -1 divided by 2.

  • And if you don't recall that, that's OK.

  • I always look these things up as well.

  • But that's true-- fact.

  • So what does that equal out to?

  • Well, it's like n squared minus n, if you just multiply it out.

  • And then if you divide the two, then it's

  • n squared divided by 2 minus n over 2.

  • So that's the total number of steps.

  • And I could actually plug this in.

  • We could plug in 8, do the math, and get the total number of comparisons

  • that I was verbally kind of rattling off.

  • So is that a big deal?

  • Hm, it feels like it's on the order of n squared.

  • And indeed, a computer scientist, when assessing

  • the efficiency of an algorithm, tends not to care too much

  • about the precise values.

  • All we're going to care about it's the biggest term.

  • What's the value in the formula that you come up

  • with that just dominates the other terms, so to speak,

  • that has the biggest effect, especially as n is getting larger and larger?

  • Now, why is this?

  • Well, let's just do sort of proof by example, if you will.

  • If this is the expression, technically, but I

  • claim that, ugh, it's close enough to say

  • on the order of, big O of n squared, so to speak, let's use an example.

  • If there's a million people on stage, and not just eight,

  • that math works out to be like a million squared

  • divided by 2 steps minus a million divided by 2, total.

  • So what does that actually work out to be?

  • Well, that's 500 billion minus 500,000.

  • And what does that work out to be?

  • Well, that's 499 billion, 999 million, 500,000.

  • That feels pretty darn close to like n squared.

  • I mean, that's a drop in the bucket to subtract 500,000 from 500 billion.

  • So you know what?

  • Eh, it's on the order of n squared.

  • It's not precise, but it's in that general order of magnitude,

  • so to speak.

  • And so this symbol, this capital 0, is literally a symbol

  • used in computer science and in programming

  • to just kind of describe with a wave of the hand,

  • but some good intuition and algorithm, how fast or slow your algorithm is.

  • And it turns out there's different ways to evaluate algorithms

  • with just different similar formulas.

  • n squared happens to be how much time both bubble sort and selection

  • sort take.

  • If I literally count up all of the work we

  • were doing on stage with our volunteers, it

  • would be roughly n squared, 8 squared, or 64 steps, give or take,

  • for all of those humans.

  • And that would be notably off.

  • There's a good amount of rounding error there.

  • But if we had a million volunteers on stage,

  • then the rounding error would be pretty negligible.

  • But we've actually seen some of these other orders of magnitude,

  • so to speak, before.

  • For instance, when we counted someone, or we searched for Mike Smith one page

  • at a time, we called that a linear algorithm.

  • And that was big O of n.

  • So it's on the order of n steps.

  • It's 1,000.

  • Maybe it's 999.

  • Whatever.

  • It's on the order of n steps.

  • The [? twosies ?] approach was twice as fast, recall-- two pages at a time.

  • But you know what?

  • That's still linear, right?

  • Like two pages at a time?

  • Let me just wait till next year when my CPU is twice

  • as fast, because Intel and companies keep speeding up computers.

  • The algorithm is fundamentally the same.

  • And indeed, if you think back to the picture we drew,

  • the shapes of those curves were indeed the same.

  • That first algorithm, finding Mike one page at a time looked like this.

  • Second algorithm finding him looked like this.

  • Only the third algorithm, the divide and conquer, splitting the phone book

  • was a fundamentally different shape.

  • And so even though we didn't use this fancy phrasing a couple of weeks

  • ago, these first algorithms, one page at a time, two pages at a time, eh,

  • they're on the order of n.

  • Technically, yes, n versus n divided by 2,

  • but we only care about the dominating factor, the variable n.

  • We can throw away everything in the denominator,

  • and we can throw away everything that's smaller than the biggest term, which

  • in this case is just n.

  • And I alluded to this two weeks ago--

  • logarithmic.

  • Well, it turns out that any time you divide something again, and again,

  • and again, you're leveraging a logarithmic type function,

  • log base 2 technically.

  • But on the order of log base n is a common one as well.

  • The beautiful algorithms are these--

  • literally, one step, or technically constant number of steps.

  • For instance, like what's an algorithm that might be constant time?

  • Open phone book.

  • OK, one step.

  • Doesn't really matter how many pages there are,

  • I'm just going to open the phone book.

  • And that doesn't vary by number of pages.

  • That might be a constant time algorithm, for instance.

  • So those are the lowest you can go.

  • And then there's somewhere even in between here

  • that we might aspire to with certain other algorithms.

  • So in fact, let's just see if-- just a moment--

  • let's just see if we can do this a little more succinctly.

  • Let's go ahead and use arrays in just one final way, using merge sorts.

  • So it turns out, using an array, we can actually

  • do something pretty powerfully, so long as we allow ourselves

  • a couple of arrays.

  • So again, when we just add sorting with bubble sort and selection sort,

  • we had just one array.

  • We had eight chairs for our eight people.

  • But if I actually allowed myself like 16 chairs, or even more,

  • and I allowed these folks to move a bit more,

  • I could actually do even better than that using arrays.

  • So here's some random numbers that we'll just do visually, without any humans.

  • And they're in an array, back, to back, to back, to back.

  • But if I allow myself a second array, I'm

  • going to be able to shuffle these things around and not just compare them,

  • because it was those comparisons and all of my footsteps in front of them

  • that really started to take a lot of time.

  • So here's my array.

  • You know what?

  • Just like the phone book-- that phone book example got us pretty far

  • in the first week--

  • let me do half of the problem at a time and then kind of combine my answer.

  • So here's an array--

  • 4, 2, 7, 5, 6, 8, 3, 1-- randomly sorted.

  • Let me go ahead and sort just half of this,

  • just like I searched for Mike initially in just half of the phone book.

  • So 4, 2, 7, 5-- not sorted.

  • But you know what?

  • This feels like too big of a problem, still.

  • Let me sort just the left half of the left half.

  • OK, now it's a smaller problem.

  • You know what?

  • 4 and 2, still out of order.

  • Let me just divide this list of two into two tiny arrays, each of size 1.

  • So here's a mini-array of size 1, and then another one of like size

  • 7, but they're back to back, so whatever.

  • But this array of size 1, is it sorted?

  • AUDIENCE: No.

  • DAVID J. MALAN: I'm sorry?

  • AUDIENCE: No.

  • DAVID J. MALAN: No?

  • If this array has just one element and that element is 4--

  • AUDIENCE: There's only one thing you can do.

  • DAVID J. MALAN: Yes, then it is sorted, by definition.

  • All right, so done.

  • Making some progress.

  • Now, let me kind of mentally rewind.

  • Let me sort the right half of that array.

  • So now I have another array of size 1.

  • Is this array sorted?

  • Yeah, kind of stupidly.

  • We don't really seem to be doing anything.

  • We're just making claims.

  • But yes, this is sorted.

  • But now, this was the original half.

  • And this half is sorted.

  • This half is sorted.

  • What if I now just kind of merge these sorted halves?

  • I've got two lists of size 1--

  • 4 and 2.

  • And now if I have extra storage space, if I had like extra benches,

  • I could do this a little better.

  • don't I go ahead and merge these two as follows?

  • 2 will go there.

  • 4 will go there.

  • So now I've taken two sorted lists and made one bigger, more sorted list

  • by just merging them together, leveraging some additional space.

  • Now, let me mentally rewind.

  • How did I get to 4 and 2?

  • Well, I started with the left half, then the left half of the left half.

  • Let me now do the right half of the left half, if you will.

  • All right, let me divide this again.

  • 7, list of size 1, is it sorted?

  • Yes, trivially.

  • 5, is it sorted?

  • Yes.

  • 7 and 5, let's go ahead and merge them together.

  • 5 is, of course, going to go here.

  • 7, of course, is going to go here.

  • OK.

  • Now where do we go?

  • We originally sorted the left half.

  • Let's go sort the right-- oh, right.

  • Sorry.

  • Now, we have the left half.

  • And the right half of the left half are sorted.

  • Let's go ahead and merge these.

  • We have two lists now of size 2--

  • 2, 4 and 5, 7, both of which are sorted.

  • If I now merge 2, 4 and 5, 7, which element should come first

  • in the new longer list, obviously?

  • 2.

  • And then 4, then 5, and then 7.

  • That wasn't much of anything.

  • But OK, we're just using a little more space in our array.

  • Now what comes next?

  • Now, let's do the right half.

  • Again, we started by taking the whole problem, doing the left half,

  • the left half of the left half, the left half of the left half of the left half.

  • And now we're going back in time, if you will.

  • So let's divide this into two halves, now the left half into two

  • halves still.

  • 6 is sorted.

  • 8 is sorted.

  • Now I have to merge them--

  • 6, 8.

  • What comes next?

  • Right half-- 3 and 1.

  • Well, left half is sorted, right half is sorted--

  • 1 and 3.

  • All right, now how do I merge these?

  • 6, 8, 1, 3, which element should obviously come first?

  • 1, then 3, then 6, then 8.

  • And then lastly, I have two lists of size four.

  • Let me give myself a little more space, one more array.

  • Now let me go ahead and put 1, and 2, and 3, and 4, and 5,

  • and 6, and 7, and 8.

  • What just happened?

  • Because it actually happened a lot faster, even though we were doing this

  • all verbally.

  • Well notice, how many times did each number change locations?

  • Literally three, right?

  • Like one, two, three, right?

  • It moved from the original array, to the secondary array, to the tertiary array,

  • to the fourth array, whatever that's called.

  • And then it was ultimately in place.

  • So each number had to move one, two, three spots.

  • And then how many numbers are there?

  • AUDIENCE: [INAUDIBLE]

  • DAVID J. MALAN: Well, they were already in the original array.

  • So how many times do they have to move?

  • Just one, two, three.

  • So how many total numbers are there, just to be clear?

  • There's eight.

  • So 8 times 3.

  • So let's generalize this.

  • If there's n numbers, and each time we moved

  • the numbers we did like half of them, than half, then half, well,

  • how many times can you divide 8 by 2?

  • 8 goes to 4.

  • 4 goes to 2.

  • 2 goes to 1.

  • And that's why we bottomed out at one element, lists of size 1.

  • So it turns out whenever you divide something by half, by half, by half,

  • what is that function or formula?

  • Not power, that's bad.

  • That's the other direction.

  • AUDIENCE: [INAUDIBLE]

  • DAVID J. MALAN: It's a logarithm.

  • So again, logarithm is just a mathematical description

  • for any function that you keep dividing something again, and again, and again.

  • In half, in half, in half, in third, in third, in third, whatever it is,

  • it just means division by the same proportional amounts again,

  • and again, and again.

  • And so if we move the numbers three times, or more generally log

  • of n times, which again just means you divided n things again,

  • and again, and again, you just call that log n.

  • And there's n numbers, so n numbers moved

  • log n times, the total arithmetic here in question

  • is one of those other values on our little cheat sheet, which

  • looked like this.

  • In our other cheat sheet, recall that we had formulas that looked like this,

  • not just n squared and n, and log n, and 1, we have this one in the middle--

  • n times log n.

  • So again, we're kind of jumping around here.

  • But again, each number moves log n places.

  • There's n total numbers.

  • So n times log n is just, by definition, n log n.

  • But why is this sorted this way?

  • Well log n, recall from week 0 with the phone book example,

  • the green curve is definitely smaller than n. n was the straight lines,

  • log n was the green curved one.

  • So this indeed belongs in between, because this is n times n.

  • This is n.

  • This is n times something smaller than n.

  • So what's the actual implication?

  • Well, if we were to run these algorithms side by side

  • and actually compare them with something like this--

  • let me go ahead and compare these algorithms using this demo here--

  • if I go ahead and hit play, we'll see that the bars in this chart

  • are actually horizontal.

  • And the small bars represent small numbers,

  • large bars represent long numbers.

  • And then each of these is going to run a different algorithm-- selection

  • sort on the left, bubble sort in the middle,

  • merge sort, as we'll now call it, on the right.

  • And here's how long each of them take to sort those values.

  • Bubble's still going.

  • Selection's still going.

  • And so that's the appreciable difference, albeit with a small demo,

  • between n squared and something like log n.

  • And so what have we done here?

  • We've really, really, really got into the weeds of what arrays can actually

  • do for us and what the relationships are with strings, because all of it

  • kind of reduces to just things being back, to back, to back, to back.

  • But now that we kind of come back, and we'll

  • continue along this trajectory next time to be

  • able to talk at a much higher level about what's actually going on.

  • And we can now take this even further, by applying

  • other sort of forms of media to these same kinds of questions.

  • And we'll conclude it's about 60 seconds long.

  • These bars are vertical, instead of horizontal.

  • And what you'll see here is a visualization

  • of various sorting algorithms, among them selection sort, bubble

  • sort, and merge sort, and a whole assortment of others, each of which

  • has even a different sound to it because of the speed

  • and the pattern by which it actually operates.

  • So let's take a quick look.

  • [VIDEO PLAYBACK]

  • [MUSIC PLAYING]

  • This is bubble sort.

  • And you can see how the larger elements are indeed bubbling up to the top.

  • [?

  • And you can kind of hear the ?] periodicity,

  • or the cycle that it's going in.

  • And there's less, and less, and less, and less work to do, until almost--

  • This is selection sort now.

  • So it starts off random, but we keep selecting the smallest human

  • or, in this case, the shortest bar.

  • And you'll see here the bars correlate with frequency, clearly.

  • So it's getting higher and higher and taller and taller.

  • This is merge sort now which, recall, does things in halves,

  • and then halves of halves, and then merges those halves.

  • So we just did all the left work, almost all the right work.

  • That one's very gratifying.

  • [LAUGHS]

  • This is something called [? nom ?] sort, which is improving things.

  • Not quite perfectly, but it's always making forward progress,

  • and then kind of doubling back and cleaning things up.

  • [END PLAYBACK]

  • Whew.

  • That was a lot.

  • Let's call it a day.

  • I'll stick around for one-on-one questions.

  • We'll see you next time.

  • [APPLAUSE]

[MUSIC PLAYING]

字幕與單字

單字即點即查 點擊單字可以查詢單字解釋

B1 中級

數組和排序算法--計算機科學導論--哈佛的CS50(2018)。 (Arrays and Sorting Algorithms - Intro to Computer Science - Harvard's CS50 (2018))

  • 0 1
    林宜悉 發佈於 2021 年 01 月 14 日
影片單字