[MUSIC PLAYING] DAVID MALAN: All right. Welcome back. This is CS50, and this is Week One, Continued. So one of the reasons we've been passing around technologies like Google Glass is that they come with something known as an API, an Application Programming Interface. And what this means is that with the right files and with the right documentation, you can actually write software for even devices like these. And so what we have in mind toward semesters end is, if a project involving, say, Google Glass might appeal, we'll see what we can do in terms of hooking you up with some loaner hardware as well as the publicly-accessible API so that you can actually start creating software that runs on that same Google Glass. Another device that we've been playing with of late that we thought might be fun at semester's end is this little thing here. It's called Leap Motion, and what you're about to see is technically an advertisement for the device, but it does speak to what this particular device is capable of. And it, too, comes with an API via which you can write software to control your own computer in a manner quite like this one-minute film here. [VIDEO PLAYBACK] [END VIDEO PLAYBACK] So right now, this device happens to be implemented as a little USB connector that you can plug into your computer, but I wouldn't be surprised if before long we have these kinds of technologies in the next batch of PCs and Macs so that you can, indeed, interact with it in a manner like that. In fact, what I thought I'd do, too, is I pulled up a little demonstration program that comes with this software. So I've put the little sensor in front of my laptop. And as you can see, it already realizes that my hand is there controlling it. And all this application does is swimmingly little things like this. But you can see that, indeed, I have five fingers there. If we can get it to do all 10, you can imagine a neat piano application or the like. So if you'd like to come up after class today and play with that as well, you are welcome to. So more on that toward semester's end. So a couple of administrative announcements. One, do section by this Friday at noon at cs60.net/section. That URL is on the course's homepage as well. In the meantime, though, supersections will debut this Sunday. Supersections are a one-time thing, because it takes us some time to work out who's in which section and where. So this coming Sunday, there'll be one section for those less comfortable, one section for those more comfortable. And those of you somewhere in between are welcome to go to either or both or neither. Both of these will be filmed. They'll be in a larger auditorium than a section normally would be in. But the goal here is to equip you with some comfort with problem set one, with C, with the CS50 appliance, this weekend, even before you find out your formal section assignment. So you'll meet your TF and your smaller group of sectionmates in about a week's time. Office hours, meanwhile, have been going on. Do take advantage of them tonight or tomorrow night if you would like. Problem set 0 is due on Friday. This is a day later than the regularly-scheduled Thursday. But with problem set 1, you'll see that it includes some warm-up exercises with which you yourself can extend your Thursday deadline to Friday. Problem set 1, meanwhile, will debut on the course's website this coming Friday, if you'd like to curl up with it as I did once upon a time late Friday night in your room. So cs50.net/appliance is the place where you can get the CS50 appliance that we started using on Monday. We'll use it a bit more today. But rest assured that the problem set 1 specification will walk you through precisely the steps you need to get that up and running. So don't worry about doing that before Pset 1 if you'd rather not. All right. So we looked on Monday at source code, but in the context of a new programming language, namely C. And C, unlike Scratch, is not graphical. It's not puzzle pieces. It's more English-like syntax. And there's a couple of steps involved in actually writing and running a program in C, because besides source code like this, you need something called a compiler. And in layman's terms, what does a compiler do for us? Yeah. STUDENT: It converts the code that you write to 0s and 1s. DAVID MALAN: Good. So it converts the code that we write to 0s and 1s. It converts so-called source code to object code, the latter of which looks a little something like this. And it's your CPU, the brains inside of your computer, that because of the people who created those computers, know what those sequences of 0s and 1s mean. Maybe it means print. Maybe it means addition. Maybe it means subtraction. Maybe it means display a graphic. There are predefined patterns of bits that the world has decided mean certain things. But for the most part in this course, we'll work at a higher level, and we'll take for granted that there exist things like compilers that can make our source code function in the way we intend. So the program we wrote first last week and then began to port, so to speak, to C this past Monday, was this. When green flag clicked, say hello. This was, of course, written in Scratch. And I claimed that the equivalent program in C looked a little something like this. So what I thought we'd do at first is, let's tease apart what looks, at first glance, admittedly, as fairly arcane syntax, but you'll start to notice patterns quite quickly. What we'll also do today is provide you with a mental model for some canonical, some standard constructs in programming. And then we'll actually get our hands dirty with some examples as well. So for those of you more comfortable, realize that this week and then next week may very well be a bit of review. But especially when the hacker edition of problem set 1 goes out on the course's website on Friday, I do think you'll find that even as you fill in some blanks over the next week or two, you'll begin to get ever more challenged and encounter new and newer things. So let's tease this program apart a few lines at a time. At the very top, we have what's technically called a preprocessor directive. This is just a line of code that says to include the contents of a file, called standard I/N, standard input-- or, sorry, standard I/O, standard input/output, .h, inside of my own program. So in other words, if I wrote this program with a simple text editor like gedit, the simpler equivalent of something like Microsoft Word, that instruction, #include stdio.h, is just going to tell the compiler, grab the contents of that other file, stdio.h, and paste them right here. Now, why do I care? What did we claim is inside of this file called stdio.h, which is stored somewhere on my hard drive, or in this case, somewhere in the CS50 appliance? Someone else put it there for me. But what's in it? Yeah, so it's a declaration of a function called printf. So printf recalls the function that displays words and characters and numbers on the screen at my bidding. But I didn't write it. CS50 didn't write it. Someone years ago wrote it, and they essentially gave us the recipe for it in a file called stdio.h. So that first line just gives me access to functions that someone else wrote years ago, among which are printf. Now, the next line I'm going to wave my hand at, at least until next week. But for now, know that int main(void) is essentially the equivalent of this yellow puzzle piece when green flag clicked. The world, years ago, decided that if you're writing a program in the language called C, you start your program with a line that looks like that. In just about a week's time, it'll make sense what int is, what void is. But for now, just think of it as this yellow puzzle piece. Now next, we have a curly brace followed by another close curly brace, so to speak. And we'll see these throughout programs in C, as well as JavaScript and PHP. And these just encapsulate related lines of code. The open curly brace essentially says, here comes some code. And the closed curly brace, which is angled in the other direction, just means, that's it for the relevant code. So the juicy line in this first program is the last, printf, quote-unquote, hello world. And I called the thing between quotes what last time? So it's a string. And a string is just the techie term for a sequence of characters, a word, a phrase. Even a single letter could be double quoted. But it's a sequence of zero or more characters. Backslash-n, though, looks a bit strange. But it simply meant something simple to the computer. What's backslash-n? New line. So that's just the special sequence of characters that the world has decided means put a line break right there, because the compiler will actually get confused, usually, if you, very understandably, but incorrectly, just start hitting Enter to put new lines in your code. You need to be a little more explicit with backslash-n. And we'll see there's a few other such patterns for special characters. For instance, if you wanted to let your mind wander to a corner case, suppose that I wanted to print a double quote on the screen for whatever reason, that would seem to be a little problematic, right? Because if I put a double quote in the middle of "hello, world," for whatever reason, why does that seem potentially problematic? It breaks the string. The compiler is just a program. A program like a compiler is just going to read your code top to bottom, left to right. And if sees three double quotes instead of two, it's not going to know if you mean that the thing to the left should be the string, or the thing to the right, or the whole thing. It's ambiguous, and so what a typical compiler would do is just freak out, and give you some error message, and make you deal with the problem. So given that backslash-n means a new line, what would your instincts now start to be if you wanted to include something anomalous like a double quote inside of this otherwise-quoted string? Backslash-double quote. And so we'll see this kind of pattern too. If you want to do something a little strange, you'll find that the solutions often follow a pattern, and the backslash denotes an escape sequence. And it just means something special that we need to represent in a different way. As for how do you represent a backslash, well, we'll come back to that. But the answer, too, is actually a bit obvious. So let's now introduce some other programming constructs that you saw in Scratch. You've probably taken for granted already if you've already dived into problem set 0. But let's now introduce the syntax in C for these otherwise fairly intuitive ideas, at least some of them. So this notion of a condition or a branch, whereas previously we represented it with code that looked like this on the left in Scratch-- if x is less than y, then say so-- instead now in C-- let me hone in on the simplest case-- we're simply going to say, if, open parenthesis, something is true-- a Boolean expression is going to go where I have said condition-- close parenthesis, then do what's inside of those curly braces. So here, too, the curly braces are kind of like Scratch's U-shaped puzzle pieces. Do what's inside these curly braces. In this case, slash slash. And notice this is a forward slash, not a backslash. Forward slash, forward slash, for those who've programmed before, just means-- it's just a comment. A comment is not a line of code, per se. It's a line of English that you, the human, have written to yourself to perhaps remind you to do something, to explain to yourself, to explain to someone else, what your code is doing. It's just a descriptive comment. Now, of course, we can have a two-way fork in the road just by doing this, a three-way fork in the road by doing this, and if you continue this pattern, you can have four-way, five-way, six-way forks in the road if you need to handle, indeed, that many conditions. And then notice the parallelism here-- if (condition), else if (condition), and the only one that's a little strange is the last, which is just that else. But again, this is identical, conceptually, to what we've done already, even though the syntax will take a little bit getting used to. Now, in this example, there are some other strange syntax. We see printf again, open parenthesis, and close parenthesis. And inside of there is a quoted string. The parentheses, in the context of printf, go on the left and right of what? What do we describe that quoted string as more generally? So it's an argument. Any time you have a function, like printf, and then an open paren and a close paren and something inside of it, whether it's a string, or an integer, or anything else, the thing in between those parentheses is called an argument. And an argument just influences the function's behavior. In this case, it's pretty clear how. x < y is what's being passed in, so to speak, as an argument. And printf is going to print exactly that. Because surely, the person years ago who implemented printf had no idea what we human successors were going to use printf for. So that's why arguments exist, to influence behavior after a function's been written. Now, Boolean expression. We've seen these before in Scratch. It turns out in C you can also "or" them together, so to speak. Two vertical bars means that this block of code, this do this, will execute if the first condition is true or the second condition is true. And even though you might not have done this in Scratch, you could indeed do this in Scratch, And you can also express yourself differently-- if the first condition and the second condition are true, then do what's inside of the curly braces. And just as an aside, the reason it's a double ampersand and a double vertical bar, we'll see eventually that a single vertical bar and a single ampersand actually have different meaning in C. So for now, that duplication of symbols is intentional. So let's introduce, briefly, this other bit of syntax. This doesn't quite carry over to Scratch, but I claim that I can implement the notion of an if else, if else, if else, if else statement using something called a switch statement. And the only reason this really exists is to just give you, the programmer, a slightly different way of solving some problem, even though logically it doesn't give you any new capabilities. By that I mean this. When you say switch, and then a space, and then a pair of parentheses, inside of which goes an expression-- and this might be a little non-obvious at first, but this is not an argument, technically, because switch is not a function. So for now, just assume that we're using parentheses in different places for different reasons. So switch on expression means I can put a variable inside of those parentheses where it says expression. And then if that variable-- suppose it's called x, and it's just an integer-- I can then enumerate in my slide here something like this. If x is my variable, and I want to do something if x equals 1, I can do that. If I instead want to do something if x is 2, I can do that. Else, if I want to do something else entirely, I can have a default case in which case I do this other thing. So in that sense, it's equivalent to an if x equals equals 1, else if else, but I mention this now just because we'll see it again. But for now, just know that it exists. All right. So these last couple are a little more complex at first glance, but they do something fairly straightforward. A for loop in C is a chunk of code that just does something again and again and again. And the only annoying thing about it is that is that it's a little cryptic to express yourself in this cyclical pattern, but the world standardized on the following way. When you use a for loop, you've got a pair of parentheses again. And notice the two semicolons in there. Those two semicolons separate three different expressions inside of the parentheses. One is the so-called initializations. One is the so-called condition. And one is the so-called updates. Looked at in the abstract, this is completely non-obvious, so let's look at a concrete example. In Scratch we had a repeat block. And this block said repeat 10 times, say "hello, world." Let me claim for now, and we'll come back to this, and this, too, will get more familiar to you before long, the equivalent C code could be said to be this-- a for statement and a space, a pair of parentheses, notice the semicolons in there, which separate three distinct things, the initialization, the condition, and the update. And take a guess what the first is doing. Int i = 0. In rough layman's terms, what is that doing for us, probably? So yeah. It's declaring a variable called i, and it's giving it what value? 0. So it's creating a variable called i, storing the value 0 in it. That's the so-called initialization. All right, now I claimed before that the middle thing, i < 10, is the condition. So what is doing? Well, what the for loop does when a program with a for loop is run, is every time the computer runs through this loop, top to bottom, top to bottom, just like you guys did when counting yourselves and sitting down, again and again and again, the computer is going to check that condition. And if i is less than 10, it'll do it again. If i is less than 10, it'll do it again. If i is less than ten, it'll do it again. So that seems to suggest that hopefully i is changing. Otherwise, we'd have an infinite loop. And indeed, i is changing, because the last thing after the semicolon there is the somewhat cryptic syntax of i++. But those of you who've done this before, that just means quite simply what? STUDENTS: [INTERPOSING VOICES]. DAVID MALAN: Add 1 to i. Increment i. So we saw a Scratch puzzle piece for that, actually. It didn't look like i++, but that just means, quite simply, increment the value i by 1 every time you do this. So literally, you start by initializing i to 0. You then check your condition. Is 0 less than 10? Yes. We go through the loop. The next thing I claim the computer's going to do is it's going to increment i. So i is now 1. It checks the condition. Is 1 less than 10? Of course. So does it again. Then it increments i++ to 2. Is 2 less than 10? Yes. And again and again and again. And eventually, because of the plus-plussing, we get to i equals 10. Is 10 less than 10? Well, obviously not. And that's the point at which the for loop just stops. And if you have more code on the screen down below, the computer proceeds to run that code instead. So again, even though this is going to look and feel a little strange at first, certainly for those of you who have never programmed before, it literally reduces conceptually to what's otherwise a very straightforward puzzle piece in Scratch. All right, I promised that there'd be other analogs in Scratch. There's this one too. And we saw this briefly last time. But remember the forever block in Scratch? It just does something forever? I claimed that you could implement this in this way. And you can actually implement this in a bunch of different ways. But the while loop is just a different way in C of expressing yourself. At the end of the day, you can't do anything with a while loop that you can't with a for loop. So they're at the end of the day functionally the same. But it allows you to express yourself a little differently in the following way. With the while loop, it's what's in parentheses that's checked again and again and again. And as soon as that expression is false, then the loop stops executing, and the computer proceeds to run whatever other code you have in your file. But what's interesting here is that I literally typed true. And true is a type of Boolean value, a true or false value. So could true ever become false if I've literally hard-coded it into my program? So no. It's a little strange that I did this. But true is true. There's no plus-plussing. There's no use of variables in here. So because I hard-coded while true, this loop is always going to evaluate again and again and again. So how many times is hello world going to print on the screen? Forever. An infinite number of times until the battery dies or some other external event happens. So this is probably not the best program to write, because if the user can never quit your program, it's probably not what you intended. But sometimes, programs should have an infinite loop. For instance, if your computer has a clock on it, it certainly would be nice if your clock it does keep updating itself forever, albeit once a second or once a minute or something like that. So even infinite loops do have their place. All right. Lastly, this one. And this one is a little bit different functionally, and we'll come back to this probably in Pset 1. But there's another type of loop called a do while loop. And the only difference here between a do while loop and, say, a while loop, is that the condition is checked not before you execute the code, but after you execute the code. So at the top for the while loop, whereas the do while checks it at the bottom. And this just means that the while loop will typically execute more times or fewer times than a while loop? Potentially more times, because a do while loop is clearly saying do this, only after which point you check if the condition inside of the parentheses is true. So we'll see this again probably in Pset 1. If you ever want to do something at least once and then maybe some more times, this is a good construct to use. But a while loop, by contrast, will check its condition first. And that's it for loops in C, do while, while, and for loops. And again, they map pretty nicely back to Scratch, except this one doesn't quite have the same analog in Scratch. Well, how about, now, variables? So this is how I declared a variable syntactically the other day. I had an int, which I claimed is an integer. I then had a variable called counter, and then a semicolon. So what is this line of code doing? This is, quite simply, declaring a variable-- that is, asking the computer, give me some memory, give me some bits-- in which I can store what? An int. And the semicolon just means end of line of code. Now, the second line is probably pretty guessable. What is counter = 0; doing? It's assigning 0 to counter. And so this is the other thing that's a little annoying versus, say, algebra. Whereas in algebra, the equal sign means equals, here in C, the equal sign means assignment. So it means put what's on the right into what's on the left. And we'll see another symbol, equals equals, when we want to actually test for quality, somewhat annoyingly. But this is a little inefficient. It's kind of annoying that I have to declare a variable and then give it a value. So C actually lets us simplify this and just do it all at once. You can declare the variable on the left. You can still do the assignment on the right by putting that equal sign in the middle. So at the end of the day, these two are equivalent, but this one, frankly, is probably the better habit to get into just because it's a little less code, it's a little easier to read, and it just tightens up your code, so to speak. Any questions thus far on the loops, on variables, on conditions, on Booleans, either technically or conceptually? All right. So now this next one gets a little more interesting. And this is the example I put up last time that just maps a Scratch example over to C. So a function. In layman's terms, what's a function? Got to be bolder with your answer. What's a function? STUDENT: Does something. DAVID MALAN: What's that? STUDENT: Does something. DAVID MALAN: Does something. OK. We'll start there. So a function does something. So it's a piece of code that's essentially implemented elsewhere that indeed does something. Now, what's interesting about a function is that it can take input, and it can produce output. And let's actually take a look at this. So the man behind the curtain was deliberate a moment ago. Here we have a table. But suppose that this actually represents a big box. So this is a so-called black box. And in general, in design, in computer science, black boxes just refer to pieces of functionality that someone has implemented, and you don't necessarily know or care how it's implemented underneath the hood. You just care that this black box, which we'll now start calling a function, does something. So, for instance, if this black box on the stage here represents printf, a function, I know from previous examples that printf takes one or more arguments, and the first of those arguments should be a string, like "hello, world." Well, if I am the person writing the program, and I want to use printf, I, for instance, might take a piece of blank paper here and a black marker and write on it-- I misspelled "world"-- H-E-L-L-O. So I'll take my black marker and I'll write, as big and legibly as I can on this piece of paper, "hello, world," And now I claim this is my argument. This is a string represented with a piece of white paper. And my input now to the function printf is going to be this. So I am calling printf, passing that argument as input to it. And now, I don't know how the person who wrote printf did it years ago, but I do know from its documentation that its purpose in life is to print what I provide to it as input. And so, even though this implementation is unbeknownst to me underneath the hood, now I see, oh, it is done. It has printed something on the screen. And now control of the program, if there were more lines of code, would have now returned to me. And so the fact that Colton-- bless his heart, is hiding here under a table in front of all of you-- is deliberate in that I don't know and I don't care how printf is implemented. I just know, again, from its documentation, what it does and how I am supposed to use it. Now, recall that printf could get a little more sophisticated. Again, we're just talking about the equivalent of Scratch's Say block. But I also did this last time. I wanted to make my hello program a little more dynamic and not just hard code something like "world," and definitely not hard code something arbitrary like D-A-V-I-D into the program. I wanted to ask the user for his or her name, and then do something with that string that they provide. So there's something a little different here. printf, a moment ago, did, indeed, do something, but it didn't return anything to me. Right? Colton did not hand me anything back, no piece of paper. There was just a side effect. My providing "hello, world" as an argument to Colton resulted in the side effect of a word, some words, appearing on the screen. getstring, though, is a little different. getstring is also a function, but it returns some value. It doesn't just have an aesthetic side effect. It actually gives me, the person calling or using the function, something back. So in this case, getstring is called with getstring open paren, close paren. Does getstring, therefore, take any arguments or input? No, it seems not. Its purpose in life is just to get a string. It needs no more detail than that. So let me go ahead and pretend that, again, this black box is not printf, but getstring, and let me, the person writing this program, call or use getstring by just writing G-E-T-S-T-R-I-N-G, open paren, close paren, getstring. Now, I have no idea how the CS50 staff implemented getstring, but I know that if I wait long enough, it will do its thing underneath the hood, maybe using some variables, maybe using some conditions, maybe using some loops, maybe using some functions, maybe using-- just trying to stall-- maybe using some other programming features. But if I wait long enough-- in reality, in the computer, this happens super fast-- if I wait long enough, this function getstring is going to get a string from the user, who is presumably typing it out on their keyboard, and then, when you getstring is done getting those characters from the user and storing them into a string, that function, getstring, is going to have ready for me some output which I am going to retrieve by way of the assignment operator. And if I go, indeed, into the output here, Obosi has generously participated, without knowing this in advance, by writing his name onto this variable, which is representing a string. Now, the assignment operator means, even though this might feel a little redundant, I actually do need to make my own copy of this. Because on the left hand side-- whoops!-- notice that I essentially have string name on the left hand side. So I'm also going to make my own copy of this. And this is a bit of a white lie, because we'll see in a week or two's time that strings are not actually what they appear to be. But for now, here is the return value. Here is my own copy of it after using the assignment operator. And now, what do I want to do next? We now have the second of two lines of code. So I now want to call printf. Let's pretend now that the black box is back again to being printf and not getstring. Printf this time is going to take how many arguments? So look, it's like two. There's two commas in there, but one of those commas, it's inside of the quotes. So the first argument is literally going to be this. H-E-L-L-O, comma, percent s, backslash-n. And now I'm providing not one argument, but two arguments to printf. And what's printf supposed to do with these two inputs after I pass them in as arguments? It's supposed to take the second of them, which I called name, so the second piece of paper I wrote out a moment ago is called name. It's going to plug of the value inside of that variable into the placeholder, %s, so that, again, in just a moment's time, we will see a side effect of having called printf, whereby now we see not "hello, world," but "hello, Obosi." So a big round of applause to both of our volunteers, only one of whom knew this would be happening. All right. So, perhaps, simple as that was, certainly, if you're already familiar with such, hopefully you will never forget that particular visual of how functions work. So there's more than just getstring. Inside of the CS50 library, there's a whole bunch of functions, all of which are capitalized just to make clear that we wrote these functions. Typically, in C, almost every other function you'll use is lowercase. But we deliberately use capital letters just to make clear that these are training wheels of sorts that we'll use for just a few weeks that simplify the process of getting input from the user. The CS50 library does not do anything that you yourselves could not do by just using C code from an oldschool textbook. But, again, we use them as training wheels of sorts for just a couple of weeks so that we can get rid of the complexity that you'll soon understand yourself of doing something as relatively straightforward as getting input from a user. So know that you'll have access to GetChar, GetDouble-- double. What's-- and then GetFloat. What's a float? Let's start there. STUDENT: [INAUDIBLE]. DAVID MALAN: Yeah. It's a number with a decimal point. So whereas an int is an integer, which is just a number with 0 through 9, some number of repetitions thereof, a float is something with a decimal point. And a double, meanwhile, is also a number with a decimal point, but more numbers after the decimal point, potentially. So we'll get back to this before long. But typically, each of these types of data, each of these types of variables that a library like ours can return to you, use different numbers of bits to store information. Typically, a Char, which just means one character, uses 8 bits. And that's actually consistent with our byte of volunteers last week who came up and represented one Ascii character at a time. So a Char is 8 bits. A float happens to be 32 bits, typically. And a double, as you might guess, is actually 64 bits, which is just more, which means you can have bigger numbers or more precision. But again, more on that another time. GetLongLong, meanwhile, though stupidly named, is really just a integer that's twice as big, twice as long, potentially, as a regular integer, 64 bits instead of 32. And GetString we've been using. But it turns out, in the CS50 library, which is implemented, as we'll see, in the form of the two files, one of which is called cs50.h, has two other data types in it. Booleans do not exist in C. You can simulate them by just using 0s and 1s throughout your programs. But we in the CS50 library have created the symbols "true" and "false" to represent 1 and 0 so you don't have to hard code something literally like 1 and 0. But we'll see those again. String, too, does not exist. And that's why I mentioned it's a bit of a white lie for now. But we'll peel back that layer before long. But for now, a string is a sequence of characters. Meanwhile, in C, you indeed have different data types. Notice these are lowercase. So the functions you saw a moment ago are functions written by CS50 that will return to you a value that falls into one of these categories. A couple cheat sheets just to plant the seed here. printf doesn't just take %s as placeholders. It takes %d for decimal integers, or %i would work as well. %f is floating point values. %c is for a char, if you want to just plug one character into a preformatted string like we've been doing, you can use %c. And then, somewhat annoyingly, %lld is for a long, long decimal integer, which just means if you need a really big number and you're using something called a long long, which we'll come back to in a pset, you can use %lld to tell printf, plug in a really big integer here by way of its second or some other argument. And lastly, I promised that there's a few other escape sequences that printf supports. We've seen backslash-n. Backslash-r you may see. It's sort of an old-school thing. If you ever used a real typewriter years ago and you pulled on the crank which not only rotated the wheel to move the lineup, it also moved the whole thing all the way back over to the left, well, backslash-r just essentially moves your cursor back to the start of the line without moving it down. But again, more on that, perhaps, in the future. Backslash-quote, backslash-double quote, backslash-backslash is the solution to the tiny little riddle I alluded to earlier. And backslash-0 is actually quite interesting. But we'll come back to that before long. So let me go into, now, the CS50 appliance, and let's actually do a quick warm up with one of the examples we did already and then move on to something a little more complex. So if I open up my program called gedit-- this is my graphical editor. And I can do that-- let me close that window there-- by way of this icon down here, gedit, in the bottom-left corner next to the menu. I'm going to go ahead and advance, and save this example into, say, John Harvard's folder. John Harvard's folder is just his home directory where all of his files live by default. And I'm going to save this as a file called hello-0.c. And I've chosen this name just so it lines up with the sample code on the course's website and in the YouTube videos online. So now I'm going to begin to write my first program. Let me zoom in for legibility. And I'm going to go ahead and say int main void, which is just like that yellow puzzle piece that starts a program. I have gotten into the habit over the years of opening my curly brace, then also closing it and then going back to where I want to put my code, just because it helps me keep everything balanced, especially as my program gets long. And now, in here, I'm going to go ahead and say, printf, quote unquote, hello world, backslash-n, close quote, close parenthesis, semicolon. So I'm just repeating everything we've been taking for granted thus far. Now I'm going to zoom out. And this terminal window down here, what am I allowed to do in this black and white window? What can I use it for? So this is where I run commands and where I can compile things. And I'm going to keep it simple. I'm going to use a program called Make, which isn't technically a compiler. The compiler's called Clang, but we'll come back to that in a week or two's time. For now, I'm just going to type make hello-0, But those of you who were comparing in your minds what I just typed to what I should have typed may know already that I did something wrong here. Now, there's clearly some errors. Before I even look at what they are, any thoughts as to what I did wrong? STUDENTS: [INTERPOSING VOICES]. DAVID MALAN: Yeah. I'm missing the library's header file. Any of these .h files are called header files, and they collectively belong to things called libraries. Libraries are just chunks of code that other people wrote. So the standard [? i ?] library is a collection of files containing code that other people wrote. So I'm missing that. So why am I getting an error? Well, let me scroll back up in my terminal window here. And unfortunately, in C, as in a lot of programming languages, especially if it's all new to you, the error messages are precise, but they're also quite cryptic. And the error here, in red, is "implicitly declaring library function printf with type," and then it scrolls to the next line, "int const char * , ..." It just gets really overwhelming quickly. But what you should begin to do, if, again, new to all of this, is just to begin to look for keywords. Clearly, I might not understand half of the words I'm seeing just yet. You will, though, in a week's time. But I see printf. And that should begin, before long, to jog your memory, all right, printf. Something's wrong with printf. Did I spell it wrong? No, it doesn't look like-- oh. I can't use it unless I teach the compiler that it exists. And so, again, go with your instincts, even if you don't actually understand the actual error messages. And indeed, the solution here is to just include it at the top of the file like that, resaving my file with Control-S or the File menu. And if I now go back down here, I'm going to clear this. Control-L is just a nice way to clear the screen. And then I'm going to type "make hello 0" Enter, and now I still see a cryptic sequence of symbols, but we'll come back to that. That's what Make is doing for you. It's automating the process of taking a fairly annoying command involving Clang, the actual compiler. But the fact that I got no errors means that this thing should work. So I'm now going to do-- let me zoom in again-- ./hello-0 Enter, and indeed, I see "hello, world." So let's now enhance this ever so slightly just to replicate the steps we intended. I'm going to rename this with Save As to hello1.c. And now I'm going to declare a variable called name, so string name, and I'm going to put in it the value of quote-unquote D-A-V-I-D close-quote semicolon. And now I'm going to replace "world" with what placeholder for a string? %s. And now, how many arguments should printf take this time? So two. So I go outside of the quotes. I type "name" after a comma. But I've done something else wrong this time. But let's assume that I didn't realize that yet. Let me go up here. And notice, too, I'm getting a little bored of typing "make hello 0" all the time, "make" and all this. So, it turns out, in Linus you can often hit the Up arrow on your keyboard, and you can actually scroll through all of the commands that I've executed previous to just now. So if I do that, Up, Up, there's make hello 0. I don't want that. I just want to change that to hello 1 this time, Enter. Eventually, that will save you some time. All right. Unfortunately, there's is an error. So let me scroll up. This looks like I really butchered this program. I mean, my god, it's two lines of code, and its 10 lines of errors. But look at the top one first. Use of undeclared identifier string. Did I mean standard i n? No I didn't. I meant string. But where is the string variable type declared, dd we say? So it's in the CS50 the library. So it doesn't suffice, in these first couple of weeks, just to use what C gives us. I'm also going to go up here, and I could put it above or below, but I'll just keep it alphabetical to keep things orderly. I'm going to include cs50.h, which is pre-installed for you on the CS50 appliance. And it's open source, so even people on the internet can use it on their own computers. But it comes with the CS50 appliance. So now let me go back and recompile this with make hello 1. Damn it. Still another error. Let me scroll up to the first, though. This one's a little complex. Multi-character character constant. That's not helping me. But notice, Clang is at least a little bit decent, whereby with a little green caret symbol, it's saying here is where I screwed up. Why is it pointing, with that little green arrow, to the single quote next to my name? So this is one of the things you just get used to, especially if you've been programming in Python, or JavaScript, or other languages where this detail doesn't matter. In C, it does matter. If you are declaring a string, which is a sequence of 0 or more characters, you actually must use double quotes. So I actually need to change this back to open quote, close quote, with double quotes. Single quotes do have their place, but only when you're using individual chars, but more on that another time. For now, the double quotes are necessary. So now, let me go back to my terminal window, make hello 1. And who's confident? Is this program now going to compile correctly? OK. So three of us think this. All right. Enter. And it actually did. So there's no errors this time, even though this program's gotten a bit more complex. If I now do dot slash hello 1, Enter, it's going to say "hello, David." But let's do the third iteration of this, where the program is truly dynamic. Let me go ahead and change the file name, just for consistency with the files you'll have available to you afterward online. Enter. And now I'm going to go in and not store "David" hard coded here. What could I do to very simply improve this program? I could call getstring. It might be a little non-obvious what's about to happen, so I'm going to actually add another line, printf, and say name, colon, close quote, just to give the user a prompt on the screen. And now I'm going to go here, and I'm going to use my keyboard shortcut. I'm going to go Up, Up, and change hello 1 to hello 2, Enter. And thankfully, I'm making progress. And now I'm going to go up to dot slash hello and change that to 2, Enter. And now my program-- I'll zoom in-- is getting a little prettier. Name is going to be, let's say Rob this time, Enter, hello, Rob. We can do it again. Name, Lauren, Enter. Name, Joseph, Enter. Name, let's try to be difficult, Enter. Eh. It's not really a bug. So it's just a little ugly. So maybe we could solve this in the future, not now. But how would you instinctively go about addressing that particular challenge? It just looks stupid. How do you avoid things looking stupid? So we could do, OK, I heard a couple of things, a condition and a loop. We could use, one, a condition, to check what is the length of the string the user gave us? And if it's 0, it's just quote unquote, they just hit Enter, then maybe I should yell at them and prompt them again. But how do a prompt them again? Well, I also heard loop, and I could do that again and again and again prompting the user for the same thing. Well, let's do one other example using a different function in the CS50 library. Let me close this file. Let me create a new one. And I'll call it adder.c, just because it's easy to do simple arithmetic, even though this will be completely underwhelming with what you could do with any modern computer. But let me go ahead now and-- I learned my lesson last time-- include cs50.h, include stdio.h, int main void, which, for now, I'll just take on blind faith, but we'll assume that will understand what that means before long. And I'm going to say something like "give me an int." And now, how do I get an int? I want to ultimately declare a variable called x of type int and store in it an integer from the user. So that was a mouthful. But if someone wants to propose, how do I declare an integer called x? Int x. So it really is that simple. Give me an int. Call it x. Now I use the assignment operator. And how do I store from the left a value of the user? I don't want to call getstring, obviously, but rather getint. Any arguments? No. So it's open paren, close paren immediately, and then a semicolon ends the line. Now let me do this again. Give me another int. This time I'll do int, let's call it y, equals getint. And now let me do something super-simple like some math. So printf, the sum of %d is the placeholder for an int. And %d, period, backslash-n. All right. So that's not actually math. But if I want to say the sum of this value plus this value equals this other value, how many arguments into total should I be giving printf, ultimately? So four, right? This string and then the three values. So x is the first I want to be plugged in first to the %d. y is going to be the next. And now I kind of want to say z, but z doesn't exist. But that's not a big deal. Because what would you do instinctively, especially if you had a graphing calculator, what do you type? How about x plus y? So it's not an actual variable. It's just the sum of two other variables. And that's perfectly legitimate. C certainly understands simple arithmetic like this. Semicolon, save. Now let me go down here and type make adder, Enter. No error, so that's progress too. Type adder. And another keyboard shortcut, if you start to get bored with all the commands-- if you start typing a command, like dot slash ad, and that's where your boredom kicks in, you can usually hit Tab to have the computer finish the rest of the phrase for you if it's not ambiguous what should come after ad. So let me go ahead now and you click Enter. Give me an int, 1, 2, and thankfully, it's 3. But as always, testing programs shouldn't reduce to just trying it once. Let me try a corner case, like negative 1, give me 1, and that one checks out as well. And I probably want to do some more rigorous testing, but I'm pretty comfortable with where that's at. Well, now let's try another program that this time uses a bit of other syntax. Let me create a new file. I'll call this conditions0.c to line up with some sample code online. And let me go ahead and do include cs50.h, include stdio.h, in main void-- OK. There we go. We have our standard boilerplate. And this time I'm going to say printf, "I'd like an int, please," just to make the prompt a little more friendly. And now I want to get an int from the user. I'm going to call it n this time, just because n sounds like number. getint, and now, what do I want to do with it? Well, if n is-- and I'll zoom in-- if n is greater than 0, I want to do the following-- printf "You picked a positive number." Else, I'm going to type printf "You picked a negative number." All right. So this program, even though I did it fast, looks right syntactically. Let me try this. Make condition 0. Seems to run. Condition 0, enter. Let's give it an int of 50. I picked a positive number. Let's try it again. Condition 0. Negative 50. I picked a negative number. But now, let me pick what we'll keep calling a corner case, which is more an interesting case that you think might give you some trouble, 0. Now, I'm pretty sure this is one of those corner cases where zero is neither positive nor negative, so my program, though in syntactically correct-- it compiles, it runs-- is not logically correct. So what's the simple fix here if I want to detect, if I want to handle n equals 0 separately? So if n equals 0, then I want to say something like printf "You picked 0." Let me try this now. Let me go back here, clear my window, and recompile. Hm. One error generate. But I do you want to check if n equals 0. So again, another stupid thing to get used to, equal sign is the assignment operator. So this is actually mistake in that, technically, even though the compiler protected me from myself, we'd technically be copying 0 into n, which is not what I want. I want to test for equality with equals equals. And so that now might be my better solution. Let me actually resave this as, say, conditions1, to be new and improved. So now if I recompile this, it would make conditions-- whoops-- make conditions1 dot slash conditions1, Enter, "I'd like an int, please." I'm going to go ahead and type 50. It's still good. Negative 50, still good. 0, and it, indeed, detected that I picked 0. So what more can I now do with this? Well, we can certainly do increasingly complex things. But what I'd like to propose is that we end on this note here. If we pull up this, you'll see, perhaps, a favorite cartoon of yours up until today you might never have understood. And that's about the quality of laughter you should get with CS jokes. So that's about right. But more compellingly, I thought I'd give us a little teaser for Monday. So we've started using integers. We've referred to floats. We've even referred to doubles, which, again, give you numbers after decimal points. But it turns out that floats and doubles, and, really, computers, fundamentally, cannot express some values precisely. We know from math classes that you can have any number of numbers after the decimal point. And you can even put a vertical bar to say these go on forever. Unfortunately, you can't really do that in a computer. And so corner cases arise. For instance, suppose you're doing something financial. You're doing mathematics with percentages, and with dollars and cents. And those cents don't necessarily line up. Well, it turns out that fractions of pennies can start to add up when modeled with a computer system in such a way that clever humans can take advantage. And those of you who haven't seen, I'd like to give you a 30-second teaser of a wonderful film known as Office Space, which will paint a picture of a problem we shall tackle first thing on Monday. If we could raise the volume a little bit, I give you 30 seconds of Office Space. [VIDEO PLAYBACK] -I mean, you, you haven't been showing up and you get to keep your job. -Actually, I'm being promoted. -I could program a virus that'd rip that place off big time. -Well, how does it work? -Every time there's a bank transaction where interest is computed, and there are thousands a day, the computer ends up with these fractions of a cent. -But I'm not going to do anything illegal. -Illegal? Samir, this is America. -We have to swear to God. -If nobody knows about this but us, all right? No family members, no girlfriends, nobody. -Of course. -Agreed. -Don't worry, man. I won't tell anyone either. [END VIDEO PLAYBACK] DAVID MALAN: So this, then, is CS50, that was Office Space, and it will all make sense on Monday. See you then. NARRATOR: At the next CS50, Rob adjusts to being off the Harvard meal plan.