DAVID J. MALAN: All right, this is CS50, and this is the start of week two. Thank you. Let us begin here with a phone call. I'm about to dial 617-BUG-CS50. CS50: This is CS50. For Shuttle Boy, press 1. To start over, press 9. DAVID J. MALAN: So he said for Shuttle Boy, press 1. So we're going to press 1. CS50: What is your origin? For quad, press 1. Mather, press 2. Boylston, press 3. Lamont, press 4. Mem Hall, press 5. To start over, press 0. DAVID J. MALAN: We'll press 1 for quad. CS50: Next shuttle leaves this very minute at 1:10 PM, and then at 1:20 PM, 1:30 PM, 1:40 PM. This is CS50. DAVID J. MALAN: So this is CS50's voice. And it's an example of the sorts of final projects, for instance, you can bite off toward the end of the semester. For instance, that shuttleboy.cs50.net exists-- actually a project that I first wrote after taking CS51 back when I was an undergraduate. And the inspiration here was back then, all they had was the printed shuttle bus schedules, and there was no notion of looking things up online. And so I sort of dove in one weekend, poured through the printed schedule, and ported it to a computer program. At the time, the computer program happened to be written in C. And you actually ran it by typing Shuttle Boy at a blinking prompt like we've been doing thus far. But over the years, it's evolved into an instant messaging bot. It's evolved more recently into this website, into an SMS-based tool, as well as into this voice-based tool. And this is to hint at the sorts of things that you can do for yourself by semester's end. For instance, there, the SMS version of Shuttle Boy happens to operate as follows. If, on your cell phone, you send a text message to 41411 and then send the special symbol sboy, for Shuttle Boy, followed by A and B, where A is an origin and B is a destination-- for instance, Boylston Space Quad-- what you should get back within a few seconds is a text message from Shuttle Boy telling you exactly when the next few shuttles are, from that point A going to that point B. And this is a more general example of what's known as using an API. So for instance, this here is just shuttleboy.cs50.net, the actual web-based incarnation of this. But the data that underlines this and other apps that CS50 has developed are all exposed to everyone here in the form of APIs, application programming interfaces. And that's just a fancy way of saying that people like we on the Internet and others have spent some time creating software that you can use in order to grab data from us and then build your own applications on top of that data set. So for instance, this Shuttle Boy API page here, which happens to be in the CS50 manual, essentially documents how you can go about asking CS50 servers for data. For instance, if you're familiar with CSV files, comma separated values, these are just sort of quick and dirty Excel-like files. So you can ask Shuttle Boy for all of the data on all of the houses and their GPS coordinates, and you'll get back, essentially, a spreadsheet like that that you can then read into a program of your own and then generate results, like Shuttle Boy itself happens to be doing. For those more familiar, more modern data representations include JSON, JavaScript Object Notation. Something will come back to you toward the end of the semester. But again, this is just one of several of CS50's own APIs. And the exciting thing is now, these days, Facebook and Twitter and Google and pretty much every popular website out there has some sort of API, which means if you read the documentation on their website, you sign up for an account, you can then start writing software on top of whatever tools or data that company there provides. And so one of our own teaching fellows a couple years back wrote a Mac version of this. So at the link titled Mac here at top left, you can actually download a Mac OS widget that runs on your own Mac to do the same kinds of things. So it's all about building on top of data sets like these. But more on that toward the end of the semester. So let's dive in real quick to a bug, just to kind of get things warmed up today, and think back on some of the things we looked at last week. In particular, let me go ahead and pull up, say, this example here. Buggy1.c, this is available on the course's website if you'd like to download it and poke around yourself. But let's zoom in here at this fairly short program, and just a super-fast recap of some of the basic building blocks that we really are going to just start taking for granted. So the blue stuff, in lines 1 through 9, are just softball questions. So these are just comments. They have no functional meaning. But they're comments in the sense that they're notes that I, the human, made to myself so that in lecture and after lecture, I can actually remember what this program does without having to read through it line by line and recreating history in my mind. Moreover, if I hand this program to someone else like you, it's much clearer to you, because of comments like this, what the program's actually doing, or at least what the program's supposed to be doing. Whether or not it's correct is another matter altogether. Now, in C, with multi-line comments, recall that on line one here is the magic symbol, /*. It means here comes the start of a comment. And nothing else matters until you reach the end terminator, which is */, the opposite. So the fact that I have 80-some odd stars here from left to right is really just an aesthetic detail. It has no functional meaning. Now how about line 11? What does this do in layman's terms? What's that? AUDIENCE: Includes the standard. DAVID J. MALAN: OK, good. So it includes the stdio.h library. So what does that mean? Well, inside that file, stdio.h, are a whole bunch of function declarations-- that is, code that someone else wrote. And a perfect example of a function that's declared in stdio.h is-- which favorite by now? So printf, one of the most common ones to use, certainly early on, from that library is there. If I exclude that line of code, Clang is going to yell at me something about using an undeclared symbol. Something undeclared is probably the keyword, because we haven't informed the compiler what printf looks like unless we include that line. And more down to Earth, really, what that line is saying is open up that file, stdio.h, wherever it is on the server's hard drive, or the appliance's hard drive, and copy-paste it right there into my file, without my having to do that manually. Now, once we get down here to main, before long we'll start teasing apart what int and what void is. But for now, let's look at the three lines within 15 through 17. This here I claim as buggy. Line 7 in my comments says "Should print 10 asterisks but does not." Why does this not print, in fact, 10 such stars? AUDIENCE: [INAUDIBLE]. DAVID J. MALAN: Exactly. So notice that we're starting to count from 0. And this is actually a convention in programming and computer science more generally, starting to count from 0 instead of 1. And this really just derives from the fact that, for instance, when we had eight people up on the stage, when no one was raising their hand, they were all effectively zeros. And so it's just kind of a computer convention so, therefore, to start counting from 0. If that's the lowest number you can represent in binary. So here we've started initializing i to 0. We've set i equal to 0. But then I made this mistake here, saying i is less than or equal to 10. But if you think that through, if I start at 0 and then I go up to 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, I'm actually going to print out 11 stars to the screen, because I've gone up to and equal to 10. So the easy fix here then is what? AUDIENCE: [INAUDIBLE]. DAVID J. MALAN: Just change it to less than. If you really want, you could do this. But in general, that's frowned upon. And so starting to count from 0 is just something you should typically get used to. Now, what about this whole construct in and of itself? This line 15 demarks a for loop. So for is not a function. It's just a statement. It's a looping construct, like we saw in Scratch. And it has three parts. Notice that there is the first part to the left of the semicolon. There's the middle part in between the two semicolons. And then there's the right-hand part to the right of the second semicolon. Now, the first of these does what? AUDIENCE: [INAUDIBLE]. DAVID J. MALAN: Back there? Yeah? AUDIENCE: Initialization. DAVID J. MALAN: Initialization. So what does this mean? We have declared a variable called i. It is of type int, because I've specified int i. And I'm initializing i to the value of 0. So what's this really saying? It's effectively saying to the computer hey, give me enough memory, enough RAM, to fit a number, and then put the number 0 in that chunk of RAM. And as an aside, how big is an int typically, at least inside of the appliance? AUDIENCE: 32 bit. DAVID J. MALAN: 32 bits. So that means give me 32 bits, otherwise known as 4 bytes, and put the value 0 in it, which is pretty easy because it just means set all the bits to 0. So now, the second part here is the condition. And the condition, as the name suggests, is what is checked again and again and again as to whether it's true or false. So this is just saying do the following lines of code-- namely line 16, because that's the only one indented underneath-- so long as i is less than 10. And after each iteration through this loop, do the incrementation, which in this case is i++. Now, it doesn't have to be i++. It could be i--. But if I did this, what's the behavior going to be of this program? AUDIENCE: It's going to be an infinite loop. DAVID J. MALAN: It's going to be some kind of infinite loop, unless we get lucky after negative 2 billion or so. Maybe things will wrap around, just by nature of the finite number of bits that we have allocated for an int. But it's certainly going to iterate far more than 10 and certainly more than 11 times here. And now, just as an aside, realize that i++ and i-- are really just syntactic sugar. It's just shorthand notation for what's a little more explicitly written as follows: i = i + 1. That is identical to i++. It just kind of looks prettier to say i++. It's more succinct, more readable. And so most people do that instead. But this is identical functionally to what we just saw. So in short, the quick fix here is just to say iterate i from 0 all the way up to less than 10. And then we'll indeed get 10 stars. So let's try this. Let me open up the terminal at the bottom. Let me go into the directory that this is in. And I'm going to compile it manually with Clang for now. And I'm going to compile this as buggy1.c, Enter. And now buggy1, why is there no such file or directory called buggy1? AUDIENCE: [INAUDIBLE]. DAVID J. MALAN: Yeah. So it's actually called a.out. So recall if you just run Clang, where Clang is the compiler, and you don't specify the name you want to give to your program, it's going to default to a.out. So indeed if I do ls-- oops. And I didn't--the black-and-white issue some of you faced has been fixed. But let me do this. There we have a.out on the left-hand side there. So we have to run a.out instead of buggy1. So let me go ahead and do this. ./a.out, Enter. And I apparently did not do what? AUDIENCE: Save. DAVID J. MALAN: Save my file. So that is easily solved by hitting Control S, or going to File, Save, like in most programs. Let me go down here, clear the screen, run it again. And there's still a bug. So what is going-- AUDIENCE: You didn't compile. DAVID J. MALAN: Ah, good. I didn't compile it. Like an idiot, I'm looking at the code to see what's wrong. So clang buggy1.c, now a.out. And phew, saved. So it looks a little ugly because there's no new line anywhere in the program. But again, that's just an aesthetic detail. And at least if we count those out, we should now see 10 such stars. Well, what about this second warm-up example? So in buggy2, I claim that this version, too, will print 10 stars, one per line. So this time, I have a newline character, just to make things a little prettier. But instead what I get is this. So let me do clang buggy2.c, Enter. Now it's again called a.out. Enter. I only see one new line, only the very last new line that moves my prompt to the next line. And yet clearly I've been printing *, then a new line, *, then a new line. But what's the bug here? Yeah? AUDIENCE: [INAUDIBLE]. DAVID J. MALAN: Exactly. So unlike some languages, like Python, where indentation actually has functional meaning, in a language like C-- as we'll see, PHP, JavaScript-- the indentation is really just for humans' benefit. So the fact that I've indented line 16 and 17 looks great, but it has no functional meaning here. If I want both lines to execute as part of the for loop, then I must enclose them in curly braces by doing this. You can only cut that corner and omit the curly braces if what's the case? AUDIENCE: Just one line. DAVID J. MALAN: Just one line. So that's just sort of a nice sort of syntax detail so that you don't waste time writing three lines, two of which are curly braces, just to write a single line of code. But if you have two or more lines, we indeed need to do this. So now let me save this. Let me go ahead and re-run Clang. Then let me rerun a.out, and now I get them one per line. Now, a.out again is kind of a dumb name for a program. How can I tell Clang to actually give me a file name that's more user-friendly, like buggy2 itself? A little more clearly? AUDIENCE: [INAUDIBLE]. DAVID J. MALAN: OK, so I can actually take the very user-friendly shortcut and just write make buggy2. I don't specify .c in this case, and hit Enter. And what make does is it compiles buggy2.c for me by asking Clang to do it. Specifically, it calls Clang, it runs Clang using way more command-line arguments or switches than I actually need. In time, we'll come back to what all of these various cryptic hyphenated expressions means. But for now, that's just saving me the trouble of having to remember and having to type out all of those various hyphenated expressions. And the upside of it ultimately is that now I have buggy2. If I want to do this manually, though, I can instead do this-- clang -o buggy2 and then buggy2.c. And that will similarly give me a file called buggy2. So in short, Clang's the compiler. Make is just a user-friendly tool that we'll be using more and more, because it just starts to simplify things for us. And we return 0, lastly. For now, just because, but we'll start teasing that part today and on Wednesday. Any questions on any of this? Yeah? AUDIENCE: [INAUDIBLE] ls in quotes there? DAVID J. MALAN: OK. When I typed ls in quotes, that was me doing some magic behind the scenes to fix a bug. I forgot, like we've been telling many of you on the discussion boards, to do-- we'll do this now--sudo yum -y update appliance50. Whoops, that that's spelled right. So the appliance is like an operating system. It's running this operating system called Fedora. And now because of my slow Internet connection, I've really hosed it. So running sudo yum update, as we tell you to do in the problem set, is essentially like running automatic updates in Mac OS or Windows. And the reason for running this at the very start of the problem set is because when we created the appliance, I messed up, and I accidentally made all of your programs look black on a black screen, which is why you're not seeing them by default. But the latest version of the appliance fixes this. And I'll fix that during break once I have Internet connectivity. So the quotes just hides my mistake, very discreetly, apparently. Other questions? Yes? AUDIENCE: Where does make come from? [INAUDIBLE] DAVID J. MALAN: Good question. Where does make come from? It is a Linux program that has existed for many years, long before CS50. And it comes with an operating system like Fedora. It does not come from the CS50 library. In fact, the only things that come from the CS50 library thus far, that we've seen, are GetString, GetInt, all of those Get functions, and the word string, and to some extent, the word bool. But we'll tease that apart when we dive into the CS50 appliance itself. So yes, one more question here. AUDIENCE: When you said make and then buggy, how does the computer know [INAUDIBLE]? DAVID J. MALAN: Good question. So when you just run make buggy1 or make buggy2, how does make know? So by default, if you type make buggy1, make looks for a file called buggy1.c. And then it executes the appropriate Clang commands, thereby overriding the default output file called a.out. In fact, if we look at what make, what-- let's quit this. If we look at what make was actually doing, make buggy2, it's already up to date. So let me remove the rm command, the program I wrote before. Typing Y-E-S to confirm that I want to remove it. If I now do make, notice that in this very long line, there's this last thing here, -o buggy2. All make is doing is passing that argument, so to speak, to Clang, so that I don't have to type it myself. All right, so a quick couple of administrative announcements. So for sections, which officially began this coming Sunday, you'll always want to bring, if you have one, a laptop. If you don't have a laptop, do reach out to me by dropping me an email. And we'll figure out a workflow. What generally you'll find in section is that they're part conceptual, part hands-on. We'll specifically use the section of questions, part of the week's problem set, to walk through some of the conceptual material from lecture. And that's all in the current problem set. And we'll also dive into some hands-on activities, sometimes of which will be required to be submitted, sometimes of which will not. For instance, this first week, they're meant just as a warm-up exercise. And you'll find that those problems are really just that. They're meant to be fairly small, but not necessarily trivial programs to write, that aren't necessarily exciting in and of themselves but are good opportunities to practice with syntax, with new functions, in the comfort of a section where you have a few of your classmates present as well as your TF. And what we'll do over time is use a tool called CS50 Spaces, whereby instead of just using the CS50 Appliance, you'll instead go to a web page in a browser, where you'll be able to write code in a browser window during section. And then if you opt in, your teaching fellow can then show whatever it is you're typing on your screen in your browser window up at the front of the class, whether anonymously or publicly, so that he or she can then walk through with your classmates what you did well, what you didn't do well. And again, rest assured all of this can be nicely anonymized. But it'll be a nice opportunity for much more interactivity than something like lecture allows. In the meantime, we'll have these things called super sections, which are optional but are open to everyone in the class, so that you can do this more collectively for problem set one. Here's the schedule. This is also posted on the homepage at cs50.net. Notice that there'll be a hacker-specific one tomorrow afternoon. And we will film one today and one tomorrow and post those online within 24 hours. So if you can't make any of these times, not to worry. And again, the schedule is online now at cs50.net. In terms of sectioning itself, you should have gotten an email instructing you to go to the course's homepage to find out your section. If life has changed and you need to change your section, not a problem. Go back to that same URL, cs50.net/section, singular, and you'll fill out the similar form so that you can then give us your preferences. And we will follow up by week's end as to what we can accommodate. Last week, recall that we proposed using CS50 Discuss, the course's discussion tool, in lecture. So we had 40 questions that were asked and answered during lecture. So it seemed to work well, so we'll continue trying to do this. If, during lecture, you don't just feel comfortable raising your hand, not a problem. Go to cs50.net/discuss, post there, and one of our teaching fellows will either answer it electronically or raise their hand on your behalf anonymously to ask, depending on the nature of the question. And in terms of feedback, generally psets will be returned within a week. Because it takes a little while for sections to achieve equilibrium, the first pset, 0 and 1, will be a little bit delayed as things settle down. But stay tuned for that in the weeks to come. All right, so let me put on my serious voice for just a moment. So this is actually an interesting climate to be having this discussion, what with all of the other things going on on campus related thereto. But CS50 has certainly had its history of this particular topic, in as much as every year, this course, for many years, Ad-Boards roughly 3% of the class. This most recent year, 2011, CS50 Ad-Boarded 35 students. This is not, I think, due to lack of clarity. Realize that in the course's syllabus, there is a page of statement explaining where the lines are. That same statement is repeated on every one of the problem sets on page one. So I mention this today really just to make folks mindful of this. And we've tried different things. And what I thought we would do today is just take a moment to actually look at some of past cases that have come up. Rather than keep these as dirty little secrets, actually point out what students have done and how we have detected it and really what the overarching motivation is for even having this conversation. So with that said, the line essentially is this-- per the syllabus, you're welcome, you are encouraged, to talk with classmates. That's the whole purpose of having these collaborative office hours in Annenberg and encouraging people for the final project to work together. But the line is drawn when it comes time to actually write your final solution. Speaking in English, totally fine, speaking in pseudo code, totally fine. Emailing a classmate your pset, letting them look over the screen as the hands continue typing, over the line as well. Do look to the syllabus for the particular lines. But just to paint a picture of how this is unfortunately a reality, realize that there are websites out there that have solutions from this class and many other classes. The fact that you or some 3% of you know that this exists means that we know that this exists. The fact that there are websites like this where you can pay someone to actually do your problem sets-- this was an actual case that came up last year. This is a website called odesk.com. And Tim was the name of the person here who was posting on this website and asked someone to do his pset 7 in this particular case. Well, odesk.com is very Google-able, and we too are very good at Googling. Here, too, there are sites-- and this one's rather atrocious, frankly. [LAUGHTER] DAVID J. MALAN: The funny thing about this site is if you read the About page, they talk about their corporate culture and how customer service is their number-one priority, to make sure that your assignments get turned in on time. But in all seriousness, again, the fact that these sites exist, realize we, too, are cognizant of these kinds of sites. And to give you a sense of what forms this generally takes, we generally don't have great scandals where people are collaborating on any kind of massive scale, but rather it's these late-night moments of weakness, where you have so much to do, it's 4:00 AM, you're exhausted, and you think to yourself, well, let me just take a look at my roommate's or my friend's code or the like. And the manifestations of this unfortunately involve Student A submitting something like this and Student B submitting something like this, which certainly, in a computer science class, is remarkably easy for computer scientists to detect with software. This is another common paradigm, where you've sort of been working alongside of someone, maybe talking in English, just fine, pseudocode. But then it comes time to actually submit, and the psets just get exchanged via email or Dropbox or the like. But in an attempt to make it less apparent that this is what has happened, then this is what's submitted. This, too, does not trip up well-written pieces of software like we have to actually detect these kinds of things. And indeed what we do is run software that compares all of this year's submissions against all of past year's submissions, against everything we found on the Internet, against every job website out there. It's all very automated. And so we do this really in great fairness to the 97% who are really working their asses off in this and in other classes and putting in all of that effort so that the work they ultimately submit is their own. And I can go on for ages. These are just a handful of last year's cases. A few students submitted these files identically for pset 2, pset 3, pset 4, pset 5, pset 6, pset 9. In this case, this was quiz 0 and in last year, where two students submitted identically this sentence among many others, "The request of type--" dot, dot, dot. So even in a class of 600 did we detect this on submitted quizzes. So in short, this--frankly, I hate having this kind of conversation--but this is really a deliberate effort this year to try to drive down that number. Because even though we say these kinds of things every year, I think the reality of having dwelled on it for a few more seconds than usual and actually just pointing out that what might seem like, eh, not such a big deal, at least think back to this particular moment, both in fairness to yourself and to your classmates here. So if you ever have any questions as to where the line is, please just reach out to me personally. But the answer is always, completely stressed at the last minute, cash in a late day. Or if it's a matter of not having any late days, honestly, email me personally. We'll figure something out. Please do not put your time here at Harvard at risk. Now, I thought we should lighten the mood, so I included this as the next slide. [LAUGHTER] DAVID J. MALAN: This website was great. I actually got a little distracted. There's this one. And then this one was amazing. Okay, so think of that kitten late at night when making those decisions. All right, so back to more fun and less serious stuff, like conditions. All right, so we talked briefly about these. This is something that's probably quite familiar from the world of Scratch. And in the world of Scratch, we have this need sometimes to go make forks in the road. Either do this or that or this other thing here. And when we want to do this, we can use, in C now, this if else construct. And then here we have Boolean expressions. For instance, Boolean expressions here, we can OR them together, in the sense that we have this condition OR that condition. We can AND them together, in the sense that we want to check this condition AND that condition. And here we have a switch statement now, which is not so similar syntactically to those kinds of conditions, but it allows us to do the equivalent of if, else if, else if, else if, and the like by simply enumerating them case by case by case by case. So we saw those last time. And then we started touching upon things like loops. We saw one of these just a moment ago. But there are these other looping constructs. For instance, this one here. So while (condition), do this thing again and again. So fundamentally, what seems to be different between this for loop and this while loop here? This for loop and this while loop. Yeah? What's that? AUDIENCE: [INAUDIBLE]. DAVID J. MALAN: Good. So whereas in the for loop condition, there's clearly more syntax. There's this initialization, there's this update. In a while loop, there's just this condition. So it seems that it's a little pared down versus the for loop, which means if we want to have variables and we want to have incrementation, we actually have to do this thing ourselves. So let me go ahead and open up gedit. Let me switch over to the appliance. And let's just do a quick little example that distinguishes one of these from the other. And in the back of my mind here, I should say one thing. I specifically mentioned the name Tim. Tim was actually someone that a student tried to find to do their homework for them. We had no Tim in that particular section. So realize, lest I disclosed a student, it was not a student. It was a random person on the Internet doing things by proxy last year. So we find that, too. So in this case here, let me go ahead and open up a new file. File, New. This gives me a tab here. Let me go ahead and save it as loop.c. Let me go and click Save. And then down here, let's go ahead and start writing #include . Let me zoom in. Now we'll do int main(void). Now let me go ahead and do for (int i = 0; i < oh, 10; i++). And now I'm going to go ahead and do print the star that I did earlier. And then at the end of this program, we're just going to print a new line, just so that my prompt doesn't look all messy. return 0. Seem syntactically correct? So far. So let's see. So let me zoom out, go into my terminal window. And let me go ahead and run loop, because I called this thing loop.c. So make loop. Seems to compile OK. Let me run loop, and now Enter. And it seems to have printed 10 stars. So let's just convert this to a while loop and see what kinds of issues we trip over. So instead of this, let me go in here and say while i is less than 10-- let me get rid of the for loop. OK, so we have a couple of problems already. So the condition is the same, but I'm obviously missing the initialization. I am missing the incrementation. So what should the compiler likely tell me when I try to compile this program? Yeah? AUDIENCE: [INAUDIBLE]. DAVID J. MALAN: Good. So it's going to say something like undeclared--in this case, variable i. And indeed, use of undeclared identifier i. And so this is in contrast with languages like PHP and Python and Ruby, with which some of you might be familiar, where you can just kind of start using variables willy-nilly and not have to worry about declaring them explicitly always. In C and in languages like Java and C++, you have to be super explicit. And if you want a variable called i, you have to tell me what kind of variable it is. So we're going to have to fix this as follows. I'm going to have to go up here and type int i; therefore, I have declared a variable called i. Now, I've skipped one step. I've obviously not initialized it, but let's see if that at least makes Clang stop complaining. So let me remake this program. All right, now it's just complaining for a different reason. "Variable 'i' is uninitialized when used here." All right, so that's pretty explicit. Initialized just means setting it equal to a value. And we've not done that, so let me try equals 0. Now let's try this again and re-run Clang. Compiled this time. And I'm about to run it. But big old infinite loop, because I've done the initialization, I've done the condition, but I've never done any kind of incrementation. So how can I do the incrementation? Well, in a while loop, it feels like I'm going to have to do it inside of the loop, because much like the first week's examples of doing looping constructs, like with the socks and with the self-counting, we had to do something at the very end, like go back to the next line. What if I go ahead and do this i++ here? Let's not even compile this. Catch me already. What's wrong here? AUDIENCE: [INAUDIBLE]. DAVID J. MALAN: So it's definitely not int. It's i. And the curly braces, like before, indentation is not enough. So now I have this construct. So while i is less than 10, print a star, then increment i. And the way a while loop works is that as soon as you hit the bottom of the loop, which in this case looks like line 10, it's going to go back to line 6, at which point the condition will be checked again. And if i is still less than 10, we'll do lines 8 and then 9, then we'll hit 10, and go back to 6, again and again and again and again, so long as i is less than 10. So let's re-run make here. Okay, we've compiled okay. Let me re-run loop. And now it actually seems to work. So pluses and minuses here? Well, so far there's actually not a whole of plo-- so cute. All right, that was an--ah, that was an accident. All right, so let's go back to the for loop. So for loops are nice because they're super explicit. And even though they're a little clunky to write, it's very powerful and it allows you to do multiple things at once. While loops don't seem to have a huge amount of value just yet, because it feels like we just have to do more work. We have to put the initialization up here, the update down here, and we have to remember to do all that. So we'll see in time that while loops actually lend themselves to just different contexts, different data structures like lists and hash tables, things we'll get to mid-semester. But for now, know that there's this third type known as a do- while loop. And we've seen this briefly. And this might be super helpful with pset 1. Any time you want to do something and then check if the user cooperated, and if they didn't, do it again, a do- while loop lends itself to that kind of logic. Because as the ordering from top to bottom here suggests, do literally means do this. And do this again and again, what might that be? Maybe it means calling GetInt or GetString and then checking the value of GetInt or GetString and then yelling at the user if they haven't cooperated by asking them again and again and again. Where you want to do something once, then check some condition. So let's try this. Let me actually change this now to a do-while loop. And I'm going to go ahead and do the following. So do the following. Let's do int i = GetInt(); but let's first tell the user what to do. So a little different this time. "Give me an int". So I'll use printf for that. And now I'm going to go down here, and I'm going to do this while i is, let's say, greater than-- let's see, i is, let's say, less than 0, or i is greater than 10. In other words, I want a number from 1 to 9, just arbitrarily. So I'm using a combined Boolean expression here to make sure that i is less than 0 or greater than 10, in which case I will do this loop here again. So again, do this-- while i is less than 0 or i is greater than 10. So now let's go ahead and do this once we've done that. Let's just do a quick sanity check. printf("Thanks, i is %d", i). So this simple program asks the user for an int, makes sure it's within some range, 1 to 9 inclusive, and then thanks the user by reminding them what they just typed in, just as a little sanity check. But let's see if this works as intended. Let me go head down here and re-run make loop. Hmm. "Use of undeclared identifier 'i'". That's strange. I thought we resolved that. Same symptom but different code. Yeah? AUDIENCE: [INAUDIBLE] inside the two, we have to [INAUDIBLE]. DAVID J. MALAN: Exactly. So this actually leads us to a topic known as scope. It turns out that C, again, it really takes you literally. And if you do something like this where you declare an int and then assign it some value, but you do that inside of a pair of curly braces, what C does is it assumes that you only want those 32 bits known as i to exist within the context of those curly braces, within the context of lines 6 through 9. So i is declared, and it is assigned a value in line 8, but as soon as you get outside of line 9 below the curly brace, i is no longer in scope, so to speak. S-C-O-P-E. It's no longer in the right context. So now there is no i, so it's as though we hadn't even declared it at all. So what's a fix then for something like this, if the reason is that i is declared within the curly braces, which is apparently bad? Here? AUDIENCE: [INAUDIBLE]. DAVID J. MALAN: Yeah. So we can initialize it outside. So let me go ahead and delete the declaration parts whereby I specify the type, and let me do it up here. So in line 5, it now says "Give me an int." Call it i. Notice in line 9, I do not want to do this, because I already have the 32 bits. I don't want to ask the computer for a different 32 bits. I want to use those same 32 bits. And now because i is declared in line 5, it's still legit to use it in line 11 and line 12. So let me try to recompile this and see if Clang stops yelling. make loop. So now it is "implicit declaration of function 'GetInt' is invalid in C99." What is that? Yeah? AUDIENCE: [INAUDIBLE]. DAVID J. MALAN: Yeah. So now that I'm actually using GetInt, this is not something that just comes with C. This comes from CS50. So we need this here. And let me go back to the prompt down here and re-run make. Okay, finally. Now we've resolved that and the other error. Let me now run loop and see what happens. "Give me an int." I'll give it 11. I'll give it -1. I'll give it foo. I'll give it 5. And now it indeed works. But the prompt changed for a reason here. Why did it say retry one of these times but give me an int the other three times? Why is that behavior different? AUDIENCE: Gave it a string. DAVID J. MALAN: Sorry? AUDIENCE: You gave it a string. DAVID J. MALAN: Yeah. So we gave it a string in this third attempt, when I typed foo. Foo is a string. It's obviously not an int. And the way that CS50 has implemented GetInt is that we don't check if something's less than 0 or greater than 10 for you, because how do we know in advance what kind of int you want? But we can minimally check for you, did the user at least type an integer? And if they didn't, we yell at the user by typing "retry" on the screen. So now we have a program that's looping. Okay. Now, which of these is sort of the better construct? So this is where things start to get a little messy, the fact that you have to remember to declare a variable up here if you want to use it inside of some curly braces and outside. But even if this looks a little cryptic at first glance, just again, remember the simple logic. In order to use anything in C, whether it's a function or it's a variable, you have to include it if it's a function in some library, or you need to declare it. But now you need to be extra mindful of the fact that you're declaring it in the right scope. You're not putting it too tightly inside of parentheses. So let me actually roll back. If we go back to our for example from earlier, and I go back to for int, int i = 0; i < 10; i++, and I do printf stars, like this, and then close paren, and now printf i is now-- according to the same logic, what will happen when I try to compile this program? AUDIENCE: Invalid identifier. DAVID J. MALAN: So it's another invalid identifier, undeclared identifier. Now, the reason's a little different. There's obviously no curly braces here, but the same idea, the same story of scope applies. If you have declared a variable like i inside of a for loop, even if you have not explicitly written the curly braces, think of them mentally as still being there, in which case i is only valid inside of the for loop. It is not valid once you get to the next line, which in this case is now 10. So just a few issues of scope and the like. All right, any questions? All right, so this is kind of a trivial little program, printing just little stars. But let's see if you remember this song here. This is an incredibly annoying song the kids would sing on the school bus and the like. But what's nice about it is that it has this cyclicity, whereby it's "99 bottles of beer on the wall, 99 bottles of beer. Take one down, pass it around, 98 bottles of beer on the wall." And then the song repeats the 97, then 96, then 95, then 94, all the way down to 0 if you actually got that far on the bus. So this is a nice program to sort of implement, because my God, if you could just implement this with a few lines of code, you could spit out the entire lyrics to this song quite quickly. But along the way, we can start to now tease apart some of these basic looping constructs and now also introduce functions that we write ourselves, return values that we pass around. But first, why don't we go ahead and take our five-minute break here? And when we get back, we will sing this song. All right, so we are back. And when I say we will now sing this song, I mean programmatically, not verbally. So here we have beer1.c, which is one implementation of this particular song. And just to be clear, for those unfamiliar with what this thing looks like, let me go ahead and make beer1, Enter. Now let me run beer1, and what we'll see--how many bottles of beer will there be? I'll type in 99, like the song says. Enter. And now if we scroll through-- oops--if we scroll through all of this, we'll see that this did indeed sing the whole song. Wait a minute. My scroll bar's a little messed up. Let's use the bigger window. So beer1, 99, there we go. So here we have the whole song, sung much faster by the computer than it could have been by us. So notice, though, the cyclical nature here. It says 99, then 99, then "take one down, pass it around," then 98. And now it repeats again and again. So this is actually a perfect opportunity for some kind of looping construct. Notice that I'm kind of cutting a corner here. Notice that I'm saying "98 bottles of beer on the wall, 97 bottles of beer on the wall," and that was just so that when we get to one bottles of beer, I don't have to worry about the English grammar. But we can also fix this with a little bit of an if condition, perhaps. If this number is singular, go ahead and say "bottle", otherwise if it's plural, say "bottles". But for now, I'm completely cutting that corner. So let's see what we've got here. So we've got some comments at the top. I'm including these two libraries, as we've commonly been. And now let me scroll down to the first actual lines of code. Line 17 kicks off main. Line 21 and 20 has how many bottles of beer will there be? And then I call GetInt. And now I have a bit of a sanity check. So this is a convention that we'll now start adopting to more rigorously check the user's input. Sometimes you just don't want to prompt them again and again and again. If the user screws up and doesn't cooperate, fine. Quit and just don't deal with them. And so that's what I'm doing here. If n is less than 1, I'm just going to yell at the user, "Sorry, that makes no sense." And then I'm going to arbitrarily return 1. So again, this is just a convention to get used to. For now, take it on faith. But up until now, we've always been returning 0, because we've said returning 0 denotes what? AUDIENCE: Success. DAVID J. MALAN: Success, that's all. So now that we're finally starting to think about non-successes-- in other words, corner cases, error conditions-- now I have an infinite supply, or at least four billion possible things that can go wrong in my programs. And I can start assigning them individual numbers. Now, generally it suffices to just return something other than 0. So we're going to simply return 1 for now. But the reason for returning 1 is that as soon as you return 1, guess what happens to the rest of the program? It stops. That's it. So the fact that I'm returning 1 is effectively short-circuiting this program's execution so that nothing below line 27 will continue executing. As soon as main returns, that is it. All right, so if the user does cooperate and we reach line 30 because they typed in a legitimate number, here is my implementation of this song. So I first print out a newline character, just for aesthetics. I now have a for loop. And notice I'm doing things in a bit of a different direction. I don't have to do less than, I don't have to do ++. I can instead say initialize a variable i, set it equal to n, the number the user typed in, then do the following, so long as i is greater than 0, then i-- once you've finished one iteration of this loop. So we can count down using a for loop as well. Now, this is pretty much week one stuff now, with printf. So print "%d bottles of beer on the wall." Print "%d bottles of beer." "Take one down, pass it around." Print "%d bottles of beer on the wall." So it's still %d, but notice that the argument to printf is changing. After the comma, I have i, because I want to say 99. After this comma, I have i, because I want to say 99. After this comma, I have i - 1, because I want to say 98 in this first iteration, and so forth. And now down here, I just have some stupid little remark. And then line 42, I return 0 by convention, signifying that everything is okay. So what if I goofed? What might a common mistake here be? Well, what if I accidentally said well, I do want to count down to 0, I want 0 bottles of beer on the wall? So I say, i is greater than or equal to 0. What's going to be the symptom that I now see if I recompile beer1 and run it? AUDIENCE: Negative. DAVID J. MALAN: Yeah, it's gonna go negative. This is an off-by-one error, an incredibly common mistake to make. Let's actually go back to the terminal window and do it here, so we can see more at a time. Enter, 99 bottles of beer. Close, but we went ever so slightly too far. We sang the song too far down, such that we now hit the negative number. So it doesn't quite work. All right, so we can easily fix that by going back to the way it once was. But what are some opportunities now for improvement? Well, let me open beer2.c and scroll down here and take a look at this version. What's the first thing that jumps out at you as different in this version here? AUDIENCE: [INAUDIBLE]. DAVID J. MALAN: Yeah, so no more i, because it occurred to me you know what, I'm asking the user for n, and then I'm setting i equal to n, and then I'm changing i, but I'm never touching n again. So what the heck was the point of you allocating another 32 bits called i just so that I can have a different variable? So in this case, I sort of recognized that unnecessary design feature. And I'm now going to say while n is greater than 0, go ahead and print the same song, passing an n to printf as the second argument, and n - 1 as the second argument down here. And then on each iteration of this loop, go ahead and just decrement n itself. Now, functionally, this program is going to be identical. If I type in 99, n starts at 99. I decrement, decrement, decrement, decrement. I'm going to get all the way down to "One bottle of beer on the wall, one bottle of beer. Take one down, pass it around. 0 bottles of beer on the wall." The end, because I did get the condition correct. It's greater than 0. I didn't make this mistake. So which is better, version one or version two? So I heard a bunch of murmurings for two. Why two? What's that? AUDIENCE: [INAUDIBLE]. DAVID J. MALAN: Oh, okay. So it won't go below 0, but remember, in version one, the original correct version didn't go below 0 either. So remember that this is the correct version. So let's at least compare the two correct versions. What's an argument in favor of version two being, mmm, better? Yeah? AUDIENCE: It uses less space. DAVID J. MALAN: Okay, so it uses less space, right? Whereas version one used 32 bits for n, and then another 32 bits for i. Version two only uses 32 bits for n, so that seems to be a plus. Other thoughts? Does anyone want to argue in favor of one? Yeah? AUDIENCE: You have to use extra line of code for n--. DAVID J. MALAN: Okay, sure. So that's fair. So this just, at least to me-- I mean, this actually feels a little messier, the fact that I can't sort of encapsulate all of my logic in one beautiful line, the for loop, as the for loop can. Here, I kind of have to tack on this n-- at the end of the loop, because it's logically necessary. But it kind of rubs me the wrong way, just because it seems separate from the logic of up here, even though, again, it's necessary. Other thoughts? Yeah? AUDIENCE: [INAUDIBLE]. DAVID J. MALAN: Yeah. So what if you instead, at the end of the song, wanted to print out again the name of the song? Like "Thanks for playing 99 bottles of beer", or something silly like that? But the point is, you wanted access to the original value. The fact that you've mutated or changed n on every iteration and therefore have destroyed its original value means you just can't do that at the end. Now, arguably, we clearly don't want to do that in this program. So who cares? But that's a very valid point. And to be honest, there's really no one right answer here. They're both equally correct. I could be convinced either way. I will say that, in general, it's a good principle if you asked the user for some value and you stored in a variable like n, just sort of on principle, it's probably good to keep that around. And any data you want to mutate again and again, just give yourself a copy of that variable, just so that you have access to the original. You are spending 32 more bits, but the reality is this computer has, like, two gigabytes of RAM these days, and we're quibbling over 32 bits? Really not such a big deal. And even on this device here, with a half a gig or a gigabyte of RAM, 32 bits versus 64 bits, not such a big deal. Certainly today, it's going to be way overwhelmed by the size of the program itself, which is going to be several hundred kilobytes, if not a few megabytes, these days. So reasonable concerns, no one right answer. But at least those are the thoughts that should start to go through your mind? Because in pset 0, even though we really only expected correctness, or at least disclaiming various bugs that you might have encountered, as we move forward, design is going to be another key aspect, both of writing code and also our evaluating code. And so at least give thought to things like this. And just because something works doesn't mean it's good, doesn't mean it's well-designed. And that's one of the things the teaching fellows and problem sets will help us tease part over time. Well, what about, let's say, this version here? Let me do something a little sexy here in a moment. First let me get rid of this. And now let's fix this grammatical issue. So in this version, I want to fix the grammar so that, rather than just say parenthetical s, like "bottle" or "bottles"-- I don't want to cut that corner-- I also want to dynamically print out the word "bottles" or "bottle", thereby using these %s placeholders today. So I need to conditionally check what is the value of i. And if it's 1, I want to say "bottle", and if it's anything else, I want to say "bottles". So let's try to do this. So if i == 1, then let me go ahead and declare-- I need a string, so let me do string s1, because it's the first string I care about right now. I'm going to say "bottle". And then, let's see, string s2--and I'll explain where I'm going in a moment-- "bottles." So recall that, in this song, we need to be able to print things, two different words potentially. So if we look back here, notice that when we get to this example here, "two bottles of beer on the wall, two bottles of beer, take one down, pass it around", I want this fourth line to now say "one bottle of beer on the wall". So I need to decide, do I want to say "bottles" or "bottle"? So I'm going to arbitrarily say, all right, I'm going to now declare a variable called s1, string one, that's going to get plugged in here and also here, because those words are always identical, just because of the nature of the song. And I'm going to call s2 whatever word I want to eventually appear down here. Now, literally, 99 times out of 100, it's going to be the same in both of those cases, because 3 is plural, 2 is plural, 4 is plural. But in this corner case, where we get to 2 and then 1, or even 1 and then 0, I need this logic. So I have to spend some time in my code getting that right. So if I do this, if i == 1, then set s1 equal to "bottle" and s2 equal to "bottles", because this will be for 1 bottle, and this will be for 0 bottles. And this here, what does this represent? Just to be clear. This is just a comment. So the fact that you can have single-line comments means you can comment your code like this, but another common paradigm, too, is that if you have a super-short phrase that you want to put yourself and it's just more readable to put it right at the end of the line of code, you can absolutely do something like this. So now what if I do this? Else if i is not equal to 1. So bang equals-- exclamation point is known as "bang". So bang = 1. So if i is not equal to 1, what do I instead want to do? Well, the first word I want to be what? So string 1 should be "bottles" for plural bottles, and then this will be plural "bottles" as well, for now. And we'll see if this actually gets us to where we want to go. So now if I scroll down here, notice that I'm plugging in not only i, but s1. I'm plugging in i and s1. And then down here, I'm minus 1, which is the same as before, but s2. In other words, I want the English word to change based on this logic. Now, there's already some problems in this code. What is broken already out of the gate here? Yeah? AUDIENCE: [INAUDIBLE]. DAVID J. MALAN: Exactly. So I've already violated the lesson of scope. So I've declared s1 and s2, but I've done it inside of curly braces, which means yeah, this code will work up until line 42, but as soon as I hit line 43, guess what no longer exists? Well, guess what's no longer in scope--neither s1 or s2. So we have to fix this. So let me delete the declarations. And I'll leave the variable names and delete this here and delete this here. And in what lines should I really declare these things? AUDIENCE: [INAUDIBLE]. DAVID J. MALAN: Yeah, so probably right up here, 33-ish. So string s1 and then string s2. And it turns out, I can do this. If you're declaring two variables of the same type, you can actually just use a comma and do that in C. All right, so now I have two variables-- s1 and s2. I'm assigning them values in these conditions here, or in here. And then I'm using them down below. How well is this now going to work? Well, it's still a little buggy, but let's at least see how far we've gotten. So let me go ahead and make beer3. Is this beer3? Yep, this is beer3. And now let me go ahead and run beer3. 399 99. We can probably skip most of them. And down here, look at that. "One bottle of beer on the wall, one bottle of beer, take one down, pass it around, 0 bottles of beer on the wall." But I'm drawing your attention to only half of the solution. Kind of screwed up here. So it seems that the corner cases arise when i equals what two values? AUDIENCE: 2, 1. DAVID J. MALAN: 2 and 1. It's not 1 and not 1. It's really just these last two stanzas of this song. So what do I instead want to do? So I seem to have caught the case where if i is == to 1, then the first word is "bottle", but the second word is "bottles". But here, I want to change this to be == 2. And if this is the case, what do I want the first word to be? AUDIENCE: "Bottles". DAVID J. MALAN: "Bottles", so for two bottles. And then this word here should be-- AUDIENCE: "Bottle". DAVID J. MALAN: "Bottle", singular. All right, let's zoom out, go back over here, re-run make, re-run beer3, type 99 again. Okay, "Segmentation fault (core dumped)." What have I done wrong? AUDIENCE: You don't have a value [INAUDIBLE]. DAVID J. MALAN: Ah, excellent point. All right, so what's wrong here? So segmentation fault, and we're actually going to see this quite a few times in the future, deliberately. But for now, what does this actually mean? A segmentation fault almost always means that you have somehow tried to access memory, RAM in your computer, that you don't own, that you have not actually asked the operating system for. So in this case, notice what I've done, which is flawed in my logic. I have assigned s1 and s2 a value if i equals 1. I've also done that if i equals 2. But I haven't done it in the infinite number of other possibilities-- in particular, 3 or 4 or dot, dot, dot, 99. So one fix for this could just be let's have an else condition. And let me go in here and say s1 equals-- what should it be here? AUDIENCE: [INAUDIBLE]. DAVID J. MALAN: "Bottles", because in the common case, it's just the same thing. So equals quote, unquote, "bottles." So for plural bottles, and then up here, for plural bottles. Okay, so now let me go back to my terminal window, recompile, re-run it. 99. Whew. And let's do a quick sanity check. Technically, we'd want to read all of these to make sure they're correct, but let's look at least the known culprits. 3 bottles, 2 bottles, 2 bottles, 1 bottle, 1 bottle, 0 bottles. We seem to have at least fixed it for now. But the catch here is that what a god awful mess this is just to solve a stupid one-character grammatical detail. So there's kind of a reason that I cut this corner earlier, because it's just completely annoying to have to write this much code. But it turns out that there's slightly more elegant ways of expressing the exact same thing. And we can do this as follows. Let me leave this on the screen for a moment and introduce something known as a ternary operator. This is kind of a one-liner that's just meant to make our lives a little sexier, as promised. And I'm going to do this as follows. Give me a string called s1, and let me assign it as follows. (i == 1) ? "bottle", otherwise "bottles". String s2 gets (i == 2) ? "bottle", otherwise "bottles". So what then is the difference here? These two lines of code, I argue, can replace this whole mess. So I call it a mess, just because it kind of rubs me the wrong way that it's so many lines of code. Not wrong. It's not bad design. Like, this is perfectly correct and perfectly fine. But coding gets tedious if you have to express yourself so damn specifically again and again and again with a simple scenario like this. So C has some shortcuts, like this. So this essentially is saying declare a string called s1 and assign it either this value or this value if i is ==-- sorry, I should say this more clearly. Declare a variable s1, assign it this value if this is true. Otherwise, assign it this value. So in other words, this is sort of a one-line way of saying if else but doing an assignment along the way. So if i is 1, then go ahead and call this "bottle". And then this else, call it "bottles". Meanwhile, s2, the second word that we need to define, if i equals 2, we'll set s2 to "bottle". Otherwise, set it to "bottles". And what this means now is I can go through this and delete all of those lines of code. And when I say, somewhat ridiculously, that this is now sexier, it's sexier in the sort of stylistic sense. The fact that functionally, this code is actually going to do the exact same thing. And even though it might look a little cryptic at first glance, because we've not seen this construct before, I'd argue that it's ultimately going to be so much more readable and so much easier for we humans to sort of understand, because now you can just read the code all on one line. It's still similar in spirit to an if, where this is the condition and then this is what's inside the if and this is what's inside the else. But we can do this just much more elegantly. And if I now go back to my terminal, having deleted all of those lines and replaced them with just those two, recompile, re-run bottles of beer with 99, notice that my grammar is, in fact, still correct. So again, something to start. 2 bottles of beer, 1 bottle of beer. Looks right. Yeah. So there we have a much more succinct solution. So this, too, as you get more comfortable with C, not necessarily with the first pset or even second, but realize that these constructs can allow us to do things ever more elegantly. Now let's do one other thing here. Let me go ahead and open up return1.c. Now let's start to solve another problem in a way that allows us to write more sophisticated code. So here's a simple little program whose purpose in life is to increment values. And actually, let's take a step back. Let me do this manually. Let me do include and int main(void). And let me call this increment.c. And what do I want to do? I'm going to go ahead and say something like-- will we call the numbers the same-- int x. So int x gets 2; printf x is %d, new line, x. So I'm typing fast, but sort of familiar stuff now. Then I'm going to do x++. Then I'm going to print that same sentence again. And then I'm going to return 0 just to quit the program. All right, so this is a program that increments a number. It's first going to initialize something to 2, and then it's going to increment it and print it again. So let's run increment, incredibly simple program. But suppose now that I want to cube the value, so do something somewhat arbitrary. And I actually want to do x gets the cube of it. So I could use what's called the pow function, but I don't really know where that is yet. So I'm going to do this the old-fashioned way. x times this equals x times x times x. So I'm cubing the value, multiplying it by itself again and again and again, so that we get the power of 3 in this case. So now the numbers I should print should be, as we'll see here--make increment, so it's actually not really increment anymore, but we'll leave the name alone-- 2 and then 8. Now, we have the beginnings of an opportunity for refinement here, whereby this cubing thing of multiplying a number by itself by itself by itself feels like this might just be useful to have as a function, much like someone decided years ago--you know, kind of useful if one of us sits down and writes printf so that the rest of the world can use it, why don't we sit down and write a function called cube that does this cubing for us so we don't have to manually implement the notion of cubing values here? So a simple example, but let's go ahead and use this is as an opportunity to write our own function. So thus far, we've only used main, and we've used other people's functions, but we haven't written our own. So here we go. I'm going to go ahead and write a function called cube. And I'm going to have it take an input. So its input is going to be an integer. And what is it going to do? It's going to declare int output = input times input times input. And then it's going to return that output. And then I have to be specific now. This function is going to return an int. So here then is how you'd write your own functions. You first decide what's the name of your function going to be. And generally, something explanatory is good, so I'll call it cube. Then you have to specify what it's going to return, what's its output going to be. And we don't have that many options yet. Int, char, float, bool, string. For now, I'm going to stick with an int, because I want it to return an integer. Then you have to specify what its inputs, if any, are. And if cube takes an argument, takes something between parentheses, you have to give that argument a name so that you can call it something as you're implementing or writing this function, and you have to give it a type, which in this case is going to be int. So in short, cube is a function that takes an integer as input and returns an integer as output. So what does it do with that input? Well, in line 14, I declare a variable called output, and I assign it the value, input times input times input. And then I return output. So how do I use this then? What do I change these highlighted characters on line 7 to be, do you think? AUDIENCE: [INAUDIBLE]. DAVID J. MALAN: Yeah, so cube of x. So x is a variable, which means it holds some value. Fortunately, it's of type integer. And because x is an int, that means I can pass it into cube. And even though I'm overriding the value of x with the value of cube x, as has been the case thus far, any time you have equal sign and a line of code, the stuff on the right gets executed and then gets assigned to the value on the left. So the order of operations is as we would hope. So does this work? Well, let me go down here. Let me open up my terminal window. Let me do make increment, Enter. "Implicit declaration of function 'cube' is invalid in C99." As an aside, C99 refers to the language C as it was defined in 1999, which was an update over the version from 1989, which is an update over the original. So that's all that means. So what does it mean that "implicit declaration of function 'cube' is invalid?" It's right here. It's right there in line 12. AUDIENCE: [INAUDIBLE]. DAVID J. MALAN: What's that? AUDIENCE: It's not before. DAVID J. MALAN: It's not before. So this is the thing. C is kind of stupid, or C compilers are kind of stupid. They really only do what you tell them to do. And they, in particular, only read your code top to bottom, left to right. So if the compiler, Clang, is reading your code, line 1, it figures out how to do this. Oh, here comes main. Okay, let me go ahead and declare a variable x. Let me print something. Line 7, what the heck is cube? It's not declared in stdio.h. It doesn't come with C. I have no idea what to do. And so Clang just bails and quits with that error message. So we can fix this in a couple of ways. We can teach Clang what cube is by just moving where the declaration is. So I cut and pasted it atop main. Now realize that just because main is no longer first, it's still executed by default. Main is main. It's the default function name. It doesn't matter where it is in a file. But at least now Clang has seen cube before I use it. So let's see if Clang is happier now. Make increment, it did compile this time. Let me run increment. And indeed, it seems to be working. Now, you can come up with scenarios eventually where it's not feasible to put every function above every other function. You'll get stuck in this infinite loop in reality, where this guy wants to be here but this guy needs to be there. So that doesn't always work. So thankfully, C has a more elegant solution. I'm going to put this back where it was, just because I prefer, as a matter of principle, that main always be at the top, because it's just nice to see what this program does by default. And what I'm going to do up here is declare what's called a prototype. I'm going to re-declare my cube function by literally copying and pasting. Actually, that's not literally. So literally copying and pasting line 15 up above line 6. It doesn't matter what line this ends up on. It happens to be on line 4. But it does have to be before main. But notice the difference. Line 4 ends with a semicolon, which means hey, Clang, take my word for it that there exists a function called cube that takes an int and returns an int. But I'm not gonna tell you what it is yet. Just know that I promise to tell you eventually. And indeed, now it's okay that this is down below. So this is generally better, because then at the top of your file, you can just rattle off, rapid-fire, one line each, what the names of your functions are, what their inputs are, what their outputs are. And to be more clear, input generally means argument or parameter, synonymous. Output means return value, what does it hand back to me. So in this case here, cube has been declared at the top, but defined, otherwise known as implemented, at the bottom. So now let's go back here and re-run this. So now let me go ahead and re-run make, re-run increment. And it now seems to be working just fine. So now we can go ahead and factor out something like the beer example into this fourth version. So let me scroll down here. And notice that I kind of took this lesson to heart just now. The fact that I was singing the same stanza again and again and again, the same chorus line in the song, felt like why don't I factor that out into a function? And indeed, this should be one of the motivations. Besides the fact that someone else in the world might want to use a cube function-- that's a good reason to factor something out and write your own custom function-- if there's a chunk of code in your program that just makes conceptual sense, that you kind of want to give it a name-- like in this case, chorus-- then you can similarly write that as a separate function. You don't have to write everything in main if it just feels cleaner to separate it out and give it a name. So in this case here, notice that I have a comment atop this function that just sings about the specified numbers of bottles. Notice here that I don't need to call these things input and output. In fact, this time I just called my input b for bottle. And notice here, void suggests what? That chorus-- AUDIENCE: Doesn't return it. DAVID J. MALAN: Doesn't return a value. And indeed, functions don't have to return values. They can just do something. They can have what are called side effects, which in this case is just a whole bunch of printing on the screen. So notice that this code here, I literally just stole from the previous example. The only difference is instead of using i as my variable, I'm now using b as my variable. So I have b down here, I have b down here, I have b minus 1 down here. But the code is exactly the same. But just to show you now how we can use this, let me go ahead and actually change this to be a for loop. for (int i = n; i > n; i--). So I've stolen that from our previous example. Previously, it's in line 37 that I would have started singing this annoying song. But instead, I'm just going to now call chorus of i. Done. So now in every iteration of this loop, I call this other function, chorus, that I happened to write. It wasn't written by someone else years ago. But chorus, meanwhile, uses printf to print out these four lines. But the fact that I'm calling chorus again and again in a loop means that I'm going to get, at the very end, the exact same song as I have thus far. So in short, now if I look back at my code, even though functionally this is equivalent, notice that it's starting to get even more readable. I don't exactly know how GetInt is implemented. Frankly, I don't know how chorus is implemented. But it doesn't matter to me. I don't care, because now I can sort of, as a human, read this from top to bottom. And because the functions are named according to what they do, my code is increasingly readable. And as our programs get much more complex-- by the semester's end, you'll be writing hundreds of lines of code in languages like PHP and JavaScript and the like-- you'll find that it's so much easier than to keep track of what you've done. And when you start collaborating with friends or partners or colleagues, you'll be able to write much more massive programs by starting to exercise these basic building blocks. So with that said, why don't we call it a day? And we will see you on Wednesday. [APPLAUSE]