>> David: Welcome back to CS50, and welcome now that you are officially enrolled. This is the end of week one. So the enrollment numbers are in and we thought we would share some statistics, as we like to do in this course; being computer scientists, we tend to gather lots of data. Rather than show it to you though first in chart form, I thought I would show it to you in CS50 program style. So I wrote a little program called "chart" that, based on some data I happened to hardcode into the program, shows us their numbers for the past several years. You at this point don't see what I'm seeing because I haven't hit this button, but now you'll actually see that I've brought up a terminal window. So I have so-called SSH'd into the cloud.CS50.net. I have connected to the course's central server from my own laptop and via dot slash chart am I about to run a little program that depicts as best we can with what with generally call ASCII art -- it's really all you can do in a terminal window like this -- our numbers from the past few years. So there we were 2007, 2008, 2009, and bam. So this is you. We are honestly so happy to have you all in the course this semester. It actually seems, based on a quick glance, that about 225 people are still in bed today. But that's okay. This will be our last Friday lecture ever; back on Mondays and Wednesdays hereafter. But this honestly really gratifying for us, for the staff. Because we have, as you've hopefully realized, made a concerted effort over the past several years to really reach out to students on this campus who might not otherwise have considered this as a field of exploration, just a one semester course, or even ultimately a concentration or minor. So it is my promise to you and it is the huge staff's promise to you that we will absolutely get you through this course and you will have a good time doing so. Just to give you another several fun facts -- and next week, once we've looked at your Problem Set "Zero Submissions," which, if you haven't filled it out yet, you'll see asks a few demographic questions, a few geek-type questions so we can get a sense of the students. We have this breakdown in the class right now. So historically, the course is a lot of sophomores who, like me perhaps, are realizing that they finally have time to explore beyond their own interests. But it's a pretty good breakdown. So if you've been thinking you're, like, the only senior here who's taking this course: not at all, there's about a hundred of you, there's about a hundred juniors, there's a couple hundred sophomores and about a couple hundred freshman. So it's a really nice demographic. We also have graduate students from the Graduate School of Design, GSAS. We have 90 extension school students who are taking the course via distance education, so we have a huge group that will be joining us at the 2010 CS50 fair and the those photos you saw a moment ago depicted 2009's. We're also happy to say we're not quite at 50% yet, but the proportion of women in CS50 is now up to 38%, which is its highest level in 21 years. So welcome, ladies, to CS50. So we left off last time with looking at a bit of coding and teasing you with the upcoming problem set. So some support structure that's in view for the coming week. So rather than assign you yet to sections -- which we will do starting this weekend or Monday, based on the uptake in enrollment, we're actually going to rework the schedule we had in mind, so we will announce via email now this we have your official Harvard email addresses on file -- we'll announce via email in the next couple days how to officially section for a specific comfort level and such, but for this first week, so that we actually have a support structure in place, we'll have what we call "supersections." So these are open to students of all comfort levels. There are three different ones on this Sunday, this Monday, this Tuesday. Check the website under "sections" for the times and locations. And one of them will be filmed, too, so that if you can't actually make any of the times not to worry, that video will go online sometime Tuesday in plenty of time for Friday's pset deadline. And we also have starting this Sunday, lead by one of the course's teaching fellows, what we call "walkthroughs," so this is kind of programming lexicon. The idea of a "code walkthrough" refers to the process of walking through your code verbally or visually with or without other people. What we do in these walkthroughs for CS50 is really walk you through the week's problem set. This is targeted at the so-called standard edition, which we expect most students to do. The hacker editions -- we don't offer specific walkthroughs since we assume that that crowd generally is ready to dive into the PDF alone. But for the majority of folks, know that this resource exists. I think it's hugely helpful to show up having read the PDF minimally so you actually get as much out of this experience as possible. But it's really a chance, especially for those less comfortable, to be set off on a very specific path. So you don't pick up a document that has a whole lot of Greek, or what looks like Greek to you and wonder "Where do I even begin?" I mean, we'll get you started. And that's what these will be for on a weekly basis for each of the remaining problem sets. So that is this Sunday at 7:00 p.m. Check the website under "problem sets" for its location. All right. So today is about writing some programs and empowering you to write your own starting this coming week when Pset One goes out via the website tonight by 7:00 p.m. So how to write a program. It's really a three-step process. You open what we call the "text editor," the specific one we used on Wednesday was called Nano, which is similar to Notepad or TextEdit -- totally simple, kind of dumbed down but in a useful way so that you can just focus on writing code and not learning some new interface. The only interesting commands recall were pretty much CTRL+X for Save and Quit and CTRL+O for just Save. You'll see in sections and in some tutorials online that we'll point you toward that there's other key strokes as well that will save you time. And for those of you who want to pick up a more sophisticated text editor, we will point you in the direction soon of tools called Vim, or Vi, Emacs. And then there are other client side IDEs we'll also empower you with. So all that's to come. But once you've written a program, "hello world," in a file called hello.c, you Save and Quit. You then run a compiler, in our case called "GCC" -- one of the world's most popular -- and then you can run it with some number of switches, these command line arguments as they're called that somehow influences the behavior of this program. So this commands, number two here -- can someone just quickly translate into the English what it is doing for us? Yeah? >> Compiling the program [inaudible], saving it under the name "hello," in the library -- >> David: Okay, good. So close. Let me tweak a little bit. So GCC is compiling the source code we wrote, which lives in a file called -- which lives in a file -- oh, that's right. Okay, let me correct myself before I correct you. There we go. So this GCC is going to compile the source code that's in the file called hello.c, but rather than get a stupid default name like a.out, I'm using this switch first -o for output and hello, which says actually store the zeroes and ones not in a file called a.out but in a more reasonably named filed called "hello." And now someone else perhaps, why did I include this -l switch followed by "cs50" at the tail end? >> That lets the compiler know that you want to use some actual compiled code from that library. >> David: Okay, good. So that is a flag that tells the compiler that I want to use or link into my own program code that someone else wrote that lives somewhere else on the system whose moniker is CS50. And we briefly saw or mention a couple of others: there's -lm if you want to use the math library which has functions like sin and cosine and round and other such things that you may want to use over time, but we'll point those out as needed; there's -lncurses we saw briefly, which is a very simple graphic library that did that funkiness toward the end of Wednesday; and there's a whole bunch of others. But the take away for now is that if you don't clue -lcs50, you get some mention -- some error message -- about "undefined symbol," and that should be your clue that, "Oh it's undefined in that I haven't told the compiler that I want to link in these zeros and ones." And then finally, this number three command does what? >> Just runs it. >> David: Just runs it. "dot slash hello" runs the program what do we often see if you omit -- little sanity check -- the "dot slash" ? >> An error. >> David: An error message of some sort like "file not found" or "commands not found." And that's because hello.c is something I just wrote -- it's not something I downloaded or bought and installed via double-clicking or anything like that -- because I wrote it, compiled it in my current directory, I have to be ever-so emphatic to the computer that it's actually right here. And "." signifies my current working directory, the folder that I am currently in. All right, so let's actually write something a little more interesting than "hello world." So among your printout from Wednesday, if you have it, you have a file called math1.c. If you don't have this, the programs are short today, so it should be easy enough to follow along visually, but a PDF and the actual source code is available online for these things. So based on initial impressions, what does this program do when you run in it? Yeah? >> It adds, like, x to y -- >> David: Okay, good. It adds x to y and stores it into z. But if someone wants to be a even a little more snarky, what does this program do? >> [ Inaudible ] >> David: Nothing, right? It actually doesn't do anything at the end of the day because I am performing this math. So it's doing something underneath the hood. It's doing something useful for me. It turns out not, but it does evince the fact that we have some basic syntax like mathematics and equal signs and whatnot with which we can now start using for more useful purposes. But let's just quickly point out what this actually does. And actually, could one of the TFs grab the laser point? Oh, here it is from Barry. So this line here declares a variable, just storage space called "x" and it's of type "int," which means an integer has to go in it. The equal sign is really called the "assignment operator." And one of the things neophytes trip over early on is that we'll soon see there's not only an equal sign operator, there's equals equals. And we'll see what that means in a moment, and it's just because they mean different things. And generally in this language called "C" as well as a lot of others, almost all of your lines have to end with semicolons, but not all; just almost all and we'll see the difference. Case in point: there's no semicolon here, there's no semicolon here, there's no semicolon here. So really, the rule of thumb if you think back to Scratch is that any time you write a statement -- something that does something in one line of code -- you generally need the semicolon there. But you'll get used to the syntax before long. Then I do the same thing on line two and I declare something called "y." I assign it a value of 2. I then create a third variable called "z," add those two digits together, store the sum. But at the end of the day, this program does in effect nothing because I'm not printing the answer, I'm not saving the answer, I'm not doing anything with the answer. And so when I run this program, nothing all that interesting happens. So let's go ahead and compile this gcc math1.c. And for time's sake, I'm not going to bother changing the name all of the time, at least for now. It compiles okay. The program is called a.out. So I run this, Enter, and therein lies the nothing. So let's actually do something a little more interesting. Let's look at a version two of this file. And for reference, incidentally, in case you ever forget what the point of some exercise was, I'll almost always comment the code up top with a quick sentence or two that reminds you what this program does. So here's one that slightly more interesting. And now in a sentence, what does this one actually do? >> Print the answer. >> David: Prints the answer, right? So that's the marginal improvement here and we've seen this syntax before. Last time we used printf generally to print a static string, like a hardcoded string, like "David," just for example's sake. But remember that we did introduce a function -- a little utility you can use -- to ask the user for some text, get it back, and put it in a variable because what's nice about printf -- and this is what the "f" implies, format strings -- I can embed inside my double quotes special strings like "%d" for digits, "%s" for strings, and there's a few others that we'll see over time. And that's really a placeholder for the comma-separated list of values that I put after those quotes. So it's a useful way of not quite knowing in advance what you want to put in a string, but being able to create strings, phrases, sentences, dynamically. And that's useful because clearly I don't need to know in advance what the answer is going to be, what that string is actually going to be. So just to reinforce this, I could run gcc math2.c but I'm getting a little tired of this a.out convention and recall that there's this utility called "make" that right now doesn't really improve much, other than give it a better name. But we'll soon see when the commands you need to type become longer and more complicated, they just become annoying to type and annoying to remember so make generally automates this process for us. The only difference is I don't type "make math2.c" I just type math2. Make then assumes I'm in a file called make math2.c and goes and finds it. Now notice the command -- this is not an error message -- make is first showing me the commands that it is executing on my behalf. So really, once we start writing more interesting programs, you would have to type out long annoying commands like that to just compile more sophisticated programs. And here we already see a hint that make is going to simplify all of that for us. In fact, as a little helper, notice what it's sort of automatically including for me: What's this thing here? >> CS50. >> David: Yeah, so that's the CS50 library. So just in case I happen to use the CS50 library, we've configured the cloud in such a way that make just always provides you with access to it. So that's useful. Always provides you with access to the math library because that's useful, too, so you don't always have to remember that. And then there's some other flags, and we won't spend too much time on these here. But just so you've been teased with them, "-ggdb" is a flag that's going to enable what are going to be called "debugging symbols." We'll see this in a couple of weeks. But for the next week or two when you're writing programs, at least for the first time, generally if you're trying to debug them like you might have been trying to troubleshoot Scratch, you're probably going to reason through it by looking through the your code -- top to bottom, maybe engage a staff member for help -- but your friend will also be printf. So don't underestimate the value for the next week or two of just inserting printf statements into your code temporarily just to print out what the value of some variable is, or some expression is, so that you can just do a sanity check. And then you can delete it once you're sure your code is working right. So printf itself is primitive but useful debugging tool. This thing here hints at more sophisticated approaches we'll soon take. Of this detail here, -std=C99 this programming language called C has been around for some time and it's evolved over time. In 1999 they added some nice features to it that make it a lot more pleasurable to actually code in; they eliminated some of the headaches. So we are actually using the C99 version of C, which really means nothing useful today other than to realize we are using that version. So if you're coming from prior background, your code might work a little differently on a different system if you don't use those flags. And now pedagogically, all these things, -W, -W, -W, these are essentially telling GCC to be really nit-picky. This is telling GC to yell at why you as often as possible, even about the smallest things to really push you to write the best, the most secure, the most correct code possible. So if you omit flags like those, sometimes your code will compile fine, but then you actually compile it with make or with these so-called flags and you'll be yelled at a whole lot more, even though you thought your code was working and this is actually a good thing. And we'll demonstrate this over time. But the point for now is just to run math2, which I just did. And I get an answer of 3, but it seems to be garbled with my prompt. Why is this "3" running right into my Malan user name there? >> [ Inaudible ] >> David: Yeah, so I didn't have my "backslash n." So if I open this file, notice I just did "%d." There's no backslash n -- that would have forced the cursor on to the next row. So that's all; just a minor little detail. All right, so let's take things up slightly to a more interesting one. Let's go into the third version of this and then start doing something with these constructs. So now I'm actually doing some math, but here's some nuances that we're going to start to trip over. And this one will be particularly germane to a portion of Problem Set 1, at least in Problem Set 1. So what am I doing here? Well -- and I'll fix this blue next time -- I'm first telling the compiler I need access to the standard io library because printf is declared there. I'm saying "here comes my main function; here comes the guts of my program." And here, too, it's just a little baby program in that I'm hardcoding the expression 17 divided by 13. And I'm storing the answer in a variable called "answer" that's of type float. Now, a float is floating point value. So unlike an int, this is the type of number that can have numbers after a decimal place. And that makes sense because this is not going to be a whole number, right? What's 17 divided by 3 is roughly -- one point something, so one point dot, dot, dot, right? So why is this relevant though? Why is this even interesting? Well, let me compile this. This is math3, so make math3, Enter. Now I'm going to run math3. My program or this computer seems to be broken. Seems to think the answer is 1.00. Why is that? Here's that source code again. >> [ Inaudible ] >> David: Yeah. So that's some good intuition. We saw last time that there is this remainder operation. So hopefully there is indeed a way to fix this, but it looks as though the division operator, the single slash is division but -- and here's a curiosity about many programming languages -- because 17 is an integer and because 13 is an integer, why do I say that? There's no decimal point; there's no point zero; there's no floating point value, it's just a hardcoded integer. The result is that when you divide an int by an int, the answer no matter what is going to be an int. So even if the correct mathematical answer is 1.4 or whatever, when you divide an int by an int, you only have room in that variable, in the response for an actual integer. So what happens? Everything from the decimal point over gets chopped off. It doesn't round for you. It rounds down maybe, but it doesn't round properly as you would think. It just throws the decimal point away and that's because, again, these are ints and the answer intuitively should be a floating point value, but I need to be more specific. Now as an aside, turns out you can do more interesting formatting with printf, and this is useful even for ASCII art purposes. This time I'm not just saying "%f" I'm actually saying % -- what -- %.2f. Now what does this mean? Well, you can kind of infer. If I go back to that code from a moment ago, and I just rerun math3, notice how many places printed after the decimal point -- two? So it turns out with printf you can actually control those kinds of aesthetics as well. And when that becomes relevant in a problem set, we'll point you at the appropriate documentation. So let's fix this. That was version three. Let me go ahead and fix this problem. Well, if intuitively the problem is the result of dividing an int by an int, surely a solution is: "Don't do that," right? Instead divide an int by a floating point value. And I can fix this just by changing one of those values to a floating point. Now as an aside, I'll admit this is a completely useless program, much like the first couple of ones we did because why would you write a program just to solve this? You could use a calculator or any number of other tools but we'll get there. But here I'm doing the exact same thing except my number here in the bottom in the denominator is 13.0. So now when I compile this fourth version with make math4 and then run math4, I indeed get 1.31. And there's probably more digits after the decimal place, but because of my formatting string, I only see a couple of them. And that's probably useful if you're actually trying to format things in a nice way. Let's look at the fifth and final version of this. It turns out that in a lot of languages, C included, you the programmer knowing a bit about how the computer works and the language works, can exercise more fine-grained control. You don't need this hack of just, like, manually adding a decimal point just to fix that problem. You can compel the compiler to treat some value as a different type of value, at least if it makes intuitive sense that that should be possible. So here what I'm doing is 17 divided by 13, but because of this parenthetical, (float), because of that parenthetical -- that has nothing to do with math; this is a programming language thing -- that is a casting operation. So what that means is the compiler is actually going to first "cast" so to speak 13 from whatever it is to a float -- to a floating point value -- and then perform the division for us. So that more rigorously fixes the problem. Now why is this useful? Well, we'll talk before long about cryptography. And cryptography involves scrambling information, converting what you a human can read into sort of nonsense that hopefully a bad guy cannot read. But we know already from week zero that computers ultimately represent all information with numbers, and if they want to represent letters inside memory, well what do they do or what do they use? They want to represent letters and not just numbers. >> [ Inaudible ] >> David: So yeah, not binary per se but ASCII, right? You just need to come up with a convention that maps the numbers that are very easy for a computer to store. You have to come up with a convention that maps numbers to letters. And the thing we've seen thus far is called "ASCII." Now ASCII involves characters. We know from Wednesday if -- briefly -- that there's this thing called a "char" or "char," depending on how you want to pronounce it, which is just a single character but where there's also an int. But if we know that 65 is the int that maps to the capital letter "A," we've already seen verbally that you can convert letters to numbers and numbers to letters, and so here's the syntax with which we'll soon be doing that. If you want to convert a number like 65 to the letter A, you just have tell the computer "cast that int to a char." If you want to do the opposite process, you simply "cast to an int from a char." So this is a teaser of functionality to come. Now as for all these data sizes, let's close one outstanding question. Here is a program that's a little useful in that it's just a little cheat sheet for me. I've declared up top four variables: a char called "c," a double called "d," a float called "f," and an int called "i." And those are four of the data types we've discussed thus far. And I don't quite remember from reading or from class how big these things are, well, it turns out -- and this is sometimes useful, later on more likely than now -- but C has a size of operator that takes an argument in parenthesis and it will tell you how much space is used to store that particular data type. So I'm printing out line by line a char will take out some number of bytes; a double, some number of bytes; a float; and an int. So it's pretty much Copy and Paste. And the only thing that's differing is the name of the type and the name of the variable I'm using. So let's go ahead and make sizeof. Let's go ahead and run sizeof. And we should confirm some of the stuff we started talking about the other day. So a char is one byte, which is bits -- how many? >> Eight bits. >> David: So eight bits. So that's pretty easy now. A float is 4 bytes, as is an int. And an int is interesting because with 4 bytes, you get 32 bits. And so what's the biggest possible number you can represent, give or take, with 32 bits? >> 4 billion. >> David: So 4 billion. Or if you want to tolerate negative numbers, you've got to sacrifice something. So it's like negative 2 billion to positive 2 billion. So this is kind of relevant. So 2 billion, 4 billion -- these are big numbers, but there's a lot of "billions of things" in the world, right? There's billions of atoms. There's billions probably of web pages these days. And yet if a computer can only count up to 2 billion or maybe 4 billion, I mean, what do you then do? Well, this is actually a problem. And this is a little different from what happened ten or so years ago, but the so-called Y2K problem was essentially the result of programmers not really having the foresight to realize, "Maybe we shouldn't use so few bits or so few digits to represent a year because eventually this will be a problem." Now in fairness, that particular problem kind of happened because so many companies ended up running so much code for many more years than the programmers actually thought they would be running it, but the idea is still the same. So it turns out there's a solution to this: If you need more precision, more digits after the decimal point than a float allows, what do you go for instead? >> A double. >> David: A double. And a double is 64 bits. And now this is getting pretty big. This is 2 to the 64, and that's a pretty big number. But in society today, and we'll talk a bit about security topics and such throughout the course, for cryptography -- for encrypting things like your credit card information and bank accounts -- you don't use 32 bits, you don't use 64 bits, you generally use 1024 bits, 4,048 bits. I mean, these are huge, huge, numbers that humans are now using to protect their data. But it all kind of boils down to these basics of storage. [ Phone ringing ] Sorry, I'm getting a call. Not anymore. All right. So any questions? So a bit of uninteresting math, a bit of focus on sizes of types, but any questions on syntax or concepts thus far before we now put this to the test? Yeah? >> Is there a data type for representing 1,024 bits or -- >> David: Good question. Is there a data type? Is there a key word like int or char double with which you can represent a 1024-bit value? Short answer: no, at least not in C. You can construct such constructs in other languages and in theory even C. But out of the box, you generally just get these so-called "primitives." And actually, it's worth noting an int -- 4 billion -- we didn't even solve that problem. So what data type can we use to actually get more bits of precision than an int? Anyone know what it's called? So might have been seen long and that might be correct on some servers, but very, very often the data type called "long" is actually 4 bytes. So in fact, if you want a super long number -- let me go ahead and reopen this program -- you could declare long. So let me try this, long l, and then let me do a little Copy Paste here and say a long is actually the size of l. So let me quit that program; recompile. And here's a little trick -- and again, we promised to point out little tricks of the trade -- if I know I want to execute the last command I typed that started with an m, bangm will actually figure out what that command was and redo it for me so I don't have to figure it out, or you can go back in time in a terminal window. So I'm hitting the up arrow right now. Now I'm hitting the down arrow. So you can scroll back through your history, which is also useful for time's sake. So let me go ahead and rerun sizeof and hit Enter. Well, this is pretty useless, right? A long, at least on this server, which is a Linux system, they're the same size. So it turns out whoever thought of this was either being funny or just not creative that day. If you really want a longer number, it's called a "long long." It's called that ll. Let's do a little Copy Paste down here so I can print out its size. And if I recompile -- and nevermind that I'm going pretty fast; I'm doing the exact same thing as before -- hit Enter, now we have 8 bytes. So 8 is actually a pretty huge number. And this is very much relevant. Toward the end of the semester, we'll talk about database design. And one or two of your problem sets will actually use an actual database called MySQL, which is very popular -- Facebook uses it, all sorts of companies use it. And when you start to store lots and lots of data, you really do need this ability to count to pretty high numbers. And thankfully with 64-bit values can we do so, but sure enough will we run out of space, even with those types of types. So hopefully we will not make the same mistakes twice. All right, so here is a perhaps familiar if underwhelming formula. What does this thing represent? >> How to get Celsius from Fahrenheit. >> David: Yes. So this is how to get Celsius from Fahrenheit. So if you know a temperature F in Fahrenheit, you can output Celsius. This is, like, sort of classic Computer Science 101-type question. It's nice, though, only in that it will give us an opportunity to fill in the blank. So here's a blank. If you have a piece of scrap paper with you, suppose that you've started your program as follows. Notice I've made one change. I was being a little lazy on Wednesday in the interest of simplifying the code as much as possible. But it turns out that as we'll see that functions absolutely take arguments, right? Printf takes arguments inside a parenthesis. Main, though, at least now does not take any arguments. So on Wednesday I just put open parenthesis, closed parenthesis. But it's the really correct way to specify that this function takes no arguments is to actually write this key word "void." So I'll now start to get into that habit, even though it's a bit of distracting detail, it's just consistent with the expectations that the compiler really has. So let me challenge you with this: inside of these curly braces where I have put a comment with slash slash -- a "comment" means nothing here gets compiled, it's just for the human to read. Programmers often write TODO with no space, all caps like this which means "I have to do something here." Go ahead and implement with the person next to you a program that takes as input from the user an integer called F and prints out the answer of the Celsius equivalent. So input is an int called F, print out to the screen or your piece of paper the value of C. Odds are you only need two, maybe three lines of code for this, but the goal ultimately will be try it on your own. Compare after 30 or 60 seconds with the person next to you and see if before I reveal the answer we can't get everyone on to the exact same page. [ Music ] >> David: We'll let it loop once more. [ Music ] >> David: Called what? >> [ Inaudible ] >> David: All right. So if you haven't already, just glance at the person next to you, or say hello if you don't know them. And let's just see how many pieces of the puzzle you got right. So there were a couple of hints embedded in here. A few of you were probably wondering, "Well, how do I actually get the int from the user?" Well, remember from Wednesday we introduced CS50's library. And we've only just begun using it, but it has just a bunch of very useful functions like GetInt, GetString, GetDouble, GetFloat, GetLongLong. And so as those names imply, you can just cull these functions with no arguments and you'll get back that data type based on its name. So I could -- and the hint here is that looks like you probably do want to use CS50's library because I've included the so-called header file for it. Stdio.h, meanwhile, I included in advance why? >> [ Inaudible ] >> David: So you need it for printf, right, if you actually want to print out the value and not just throw it away. So this part is the cookie cutter stuff. Let me go ahead and just to be a little anal add void there. But we'll explain in the week to come exactly why and when you do things like that. And what do you think? Toward the bottom here, printf? So you might have chosen a different sentence or whatnot, but that's fine. So temperature in Fahrenheit maybe with a space, just to get the aesthetics to look a little interesting. Then you declare a float called f and then assign it -- let me scroll up for the folks in front -- that give return value of GetFloat. Yea or nay? Most folks at least have something along those lines. That's okay. All right. So not a problem. So what is this actually doing? Well, again, recall that GetFloat is a function. It's defined in CS50's library; its sole purpose in life is to ask the user for a floating point value and return it. And it's up to me to put that return value in a variable. Think of it as a black box. I say, "Get me a float." It hands me a float. I need to now put this float somewhere, and I'll put it in a variable called f that you can call it whatever you'd like. And now I have to do the mathematics. So here I'm declaring a variable called c, and I'm pretty much translating the formula from the slide using the characters on my keyboard to a floating point value. But there's one potential gotcha here -- and this is where you have to be kind of piecing together the little clues along the way -- what have I done that's interesting here that had I not, I would have had a mathematical error? >> [ Inaudible ] >> David: Let's go over here. I think everyone over here seems to know and -- yeah? >> You changed to 99.0. >> David: Yeah, so I very deliberately changed this 9 to a 9.0 so that my math would actually be floating point math involving real numbers and not just integers. If I left it as just 9, odds are I would very often get what answer? >> Zero. >> David: Right, I would get zero. Just take a look: if this is 9, 5 divided by 9 is always going to be 0 point something, and if you thus have two integers and you're rounding down, which is what happens when you do integral math we're using this operator, I'm going to get zero times whatever. So my answer is always going to be zero and therefore almost always going to be wrong. Yeah? >> But isn't f already a floating point? So why isn't this [inaudible]? >> David: Excellent question. So isn't f already a float? That's true, but especially because of my parenthesization over here, because I'm saying, "Do f minus 32, but then multiply it by the division on the left." Just as in grade school when you're doing division and multiplication, you do it from left to right in terms of order of operations. The 5 is going to get divided by 9 first. The answer is always going to be zero. So yes, f is a float, but that solution is too late; we need to fix the problem sooner. >> So how do I switch the parenthesis? Do I have to put that first? >> David: So, yes, you could. If we did that, if we moved f minus 32 over to the left, that would give me a floating point answer because f is a float. Then I'd be multiplying a float by 5, so that's a float times an int. That's okay. That's going to give me a float. And then I divide by an int -- that's okay because so long as you have a float involved at some point early on, you're okay. The problem only arises if you have an int divided by an int. And that operation is being performed before others. You'll run into errors. Yeah? >> It only works with division? Like, it doesn't matter, like, you have minus 32 even though -- >> David: F minus 32? No. So that's not as big a deal. It's really the multiplication and in this case, division that the problem arises. Yeah? >> Instead of putting 9.0, can you just put "float" in parenthesis? >> David: So I could. Absolutely. So that's a good application of the alternative I proposed. I could have just done this, and the only reason I didn't here is just because now I look at this, and now it's just getting confusing for me -- even for someone who's been programming for a while. Just too much parenthesis for my taste. So I went with the other approach. But absolutely could you do that. Yeah? >> Well, you talked last week about a lot of these. Why are you, like, writing out code? Because didn't you say you could do things like just %f? >> David: %f -- good question. So when we've talked about "printf" whose purpose in life is to take some input and then print it out to the screen, printf supports what are called "format strings." They're just placeholders. But this is a different context. Here I actually need to tell the computer, "Give me some bytes in ram in which to store a value, and that value's going to be a floating point value." >> So for anything that's not printf, you have to write out code? >> David: At some point in time, I'm going to have to have declared the variable as a float before I can then hand it to printf as the insertion value for that format strength. So both of these stories involve floating point values, but only in this case am I actually allocating memory. Other questions? All right, so let's actually run this thing. Glancing at the bottom, this is pretty arbitrary, but I chose to format my string as follows: so at the bottom here I'm printing out %.1f, which quick sanity check means print just one digit after the decimal place. Then I'm going to print a capital F just to be aesthetically interesting equals another %.1fc. So if I scroll now to the right, I should see a comma after the closed quote and then what two values? >> [ Inaudible ] >> David: F, c because I want to tell printf, "Use these values in those placeholders, these values in those format strings." So let's go ahead and compile this. So I'm going to go ahead and run make on f2c, which is the name I gave to this particular program. Now I'm going to run f2c. And now temperature in Fahrenheit -- all right, let's go ahead and pick an easy one like 212, Enter, and indeed equals 100 in Celsius. Let's do another one that I know, 32, and that equals zero. And presumably if we do this again and again, we'd get back some similarly correct answers. Okay. So any questions? Yeah? >> For the printf, do you use the printf for that? Could you also use GetString [inaudible]? >> David: Good question and short answer: no. So can you use GetString to print the answer? No. So we deliberately, in CS50's library, named these functions consistent with their behavior. So when you have a function called GetString, that means it's going to get a string from the user -- prompt the user for a string -- whereas printf is literally going to print it, not to paper, but to the screen. So it's very much the name of functions that denote or connote their behavior. All right. So let's go ahead and introduce a couple other capabilities so that we can finally start writing programs that maybe print out charts or interact with the user, play games, or the like. Well, most of this stuff is actually pretty similar to Scratch. So it turns out in C, you can absolutely represent the idea of a condition, a branch, a fork in the road. The syntax actually looks reminiscent to Scratch, where you have a puzzle piece reminiscent of this shape, but you have to say "if" followed by a space, followed by in parenthesis, the Boolean expression that you want to check -- more on those in a moment. The curly braces are then the C's way of kind of making a puzzle piece that looks like this so you can put stuff inside. So the open curly brace followed by the closed curly brace means everything inside of these curly braces should get executed, but only if that first condition is actually true. You can stack these things in C. So if you want to do if and then rather -- let me tweak this just so simplify -- if you want to stack these things and do this in one case or that in the other, can you stack them like this? And notice, unlike Scratch where some of you might have realized it starts to get a little ugly, you have an "if else" and then you have another here and another one and things start to move and move and move like this, it gets very messy. With C you can just line everything up on the left here because it's just text. So if we have a third, we can just introduce it like this and so things start to line up a lot more nicely. As an aside, if you ever just have one line of code that you want to execute, one puzzle piece in Scratch terminology, you actually don't need the curly braces; you only need the curly braces if you have two or more lines of code that you want to execute if that condition is true. But for now, it's probably simpler just always use the curly braces just to get into the habit. Yeah? >> You said you'd make a space between if and the parenthesis; does that actually matter? >> David: No. Okay, so you caught me in a small white lie for pedagogical sake. So the question is: Do you have to have this space between the if and the parenthesis? So short technical answer is no. As a matter of style, the chorus would staunchly preach yes, for the sake of readability. So this is a topic that will be threaded throughout the course. Thus far and in Scratch will pretty much focus on the idea of correctness: Does your code work as we asked it to and as you intended it to? But the two others axis, per the syllabus that we'll explore in great detail in the course and also these are the axis along with which we'll evaluate your submissions are design, in other words how well implemented is this? Did you just Copy and Paste 50 times when you could have just used a loop that cycles 50 times? So that would be a matter of good versus bad design. And there's this third axis called "style," which is really a more subjective aesthetic sense. So you will see in textbooks, in programs I write, in programs the teaching fellows and course assistants write, very different approaches to style, for instance -- and this is a good canonical example -- a lot of people, especially those who write C, actually put their curly braces on this first line and just intuitively someone unfamiliar proposed why this might be better. Because there's probably no right answer here, but why might this approach be better? Yeah? >> It seems more [inaudible]. >> David: Yeah, it's just practical, right? This takes up three fewer lines. And when I'm starting to write lots of lines of code, you know, it's frankly kind of useful to be able to see more on the screen at once without having to scroll. So I would argue as a matter of practice in my own life and certainly in a teaching capacity, frankly, I find this much more readable. And it's also much more similarly structured to Scratch. But realize that with these decisions, it's going to be a matter of style. And so what you'll be pointed to in Problem Sets One PDF is something we call the CS50 Style Guide. You'll see highlighted in green good ways of doing things; you'll see things highlighted in yellow ways you can do things -- just make sure you're doing it because you know what you're doing and you like the way you're doing it; and things in red like this, which I see surprisingly often because none of us teach this and yet we see submissions like this: indenting like this really helps no one as you see in red up top. So you can do some crazy things because at the end of the day, the computer really doesn't care. The compiler is going to ignore all of this so-called "pretty printing" -- all of this sort of indentation, all of this white space -- that's really for the human's benefits, both yours, your colleagues, the teaching staff, and the like. And so you'll learn over time both by seeing and by doing that there are generally some good ways, some okay ways, and some bad ways of actually writing code. But that's a principle we'll practice over time. Why don't we go ahead and take a five-minute break? All right. So let's actually write a program with this stuff. So among your printouts are a couple of files one called condition1.c. I'm going to change over to my terminal window. I'm going to use Nano to open conditions1.c. And actually, I'm going to cheat. I'm going to use my own special program that will color code things for me in class, but the idea is the same; it's a text editor. And now let's take a look at what this program actually does. So I've removed the comments, the things that start with slash slash from the slides just so you have an opportunity engage more intellectually rather than just reading the answers off the screen. Your copies realize have comments that document everything that's going on. So here's my code here. I'm first saying printf. I'd like an integer please, a colon, and a space just for aesthetic reasons. Then I'm declaring a variable called n, it's of type int. And I'm using the so-called "assignment operator," a single equals sign to store in n what? >> The int. >> David: The int. So to store in n whatever GetInt returns. Now what does it mean to cull GetInt? Well, as we'll eventually show you the source code, the code we wrote for GetInt itself. But for now assume that GetInt just makes the cursor blink or at least stay steady -- it depends on your computer and operating system and such. But suppose that -- think for now that GetInt just makes the cursor blink or wait for the user to type in an "int" and then hit Enter. So that's what it means to get an int. If you instead use GetString, same thing: blinking cursor, the function is just going to wait for the user to type a word, a sentence or whatever, and then hit Enter. And we'll see if you try to mess with our functions by providing a string when we want an int, or providing an int when we want a string, you may very well get yelled at and the user will have to retry. So we've embedded some error checking, if you will, into our implementations. Now at this point in the story, I've got a variable called n. I've stored it in int. What am I now doing? Well, here is one of these conditions, these branches. We've used them in Scratch. If n is greater than zero, I decided I would say, "You picked a positive number, backslash n," so put the cursor on the next line, else if n was not less than zero, I say, "You picked a negative number, backslash n." And notice because I have just one line of code inside of each of these branches, what have I clearly omitted? >> [ Inaudible ] >> David: The curly braces. So I actually don't need the curly braces because I only have a single line of code. But if I did have two lines of code or more, I would in fact need to put those back. Why omit them? It's just a little more compact, as the gentleman there said. It just frees up space on the screen for more content and that may very well be a reasonable decision. All right, so there's a bug. The astute or the mathematicians will realize that what will happen here? >> [ Inaudible ] >> David: Right. So zero is supposed to be neither positive nor negative, and here I am just simplifying and saying it's actually going to be negative. All right, so we can fix this, right? We've seen this branching construct in Scratch, we've seen it a moment ago on the slide, and see, we just need to use not an else, not just an if but an else if. And so here do we see we can check for equality with zero. And here as promised is that other operator -- looks a little weird, but because assignment is already using the equal sign to assign one value on the right to a variable on the left. Well, the world had to come up with another symbol that looked as similar as possible just for people's sanity, so they went with equals equals. So this is the equality operator, whereas the single equal sign is the assignment operator. So now we have three conditions -- three forks in the road -- and this program is in fact correct, at least hopefully. Let's go ahead and make conditions2, and hit Enter. All right, that's good. So now I'm going to go ahead and run conditions2. And now notice as promised, I'm using a Mac here so my cursor is not actually blinking, but the cursor is waiting there for me. Nothing is happening until I actually type in let's say, "David." Okay, obviously that's not an int. I culled int and as promised, it's going to yell at me by saying "retry." And it will just do this ad nauseam until I actually give it an int or if I realize, "Wow, I really screwed up this program. I can't give it what it wants," know that when you're writing code and the problems that will remind of this, if you absolutely have to kill your program, you don't have to close the window, reboot crazy stuff like that, generally you can hit CTRL+C and it will just abort the program right where it is, in case you ever get trapped in some awkward situation. But let's actually play this game properly this time. So I'd like an integer please. One, two, three, Enter. You picked a positive number. Let's now do negative one, two, three. You picked a negative number. And let's run in one more time zero. You picked zero. So that's good. So this program in fact seems to be doing something helpful finally. So now let's take a look at how else we could approach this. Well, it turns out that if you want to check two conditions and you only care that one of them is true or the other one is true. You might want to say in the real world, if you go to a movie theater for this R-rated movie, "Are you 18 and over or are you with a parent?" So if you would want to do this condition or this one, you don't want to break those conditions up because you want to let those people in or that family in either way if either of those conditions is true so you can or them together. In Scratch, the block you may have used for this idea literally says "or" for or; in C, two vertical bars. And if you've never used those, they're usually above your Return key. You might have to hold the Shift key or something like that, but they're standard keys. And it's double bars -- no spaces in between them. We'll eventually see that that single bar means something different. So double bar means if this condition or this one -- and maybe even both -- are true, go down this road and execute that code. If you want to make sure both conditions are true and they both have to be true for any code to be executed, use ampersand ampersand. And this conjures up the idea of and. And in Scratch did you probably see the key word "and" on one of the blocks. So let's see how we might use this. There is file now called nonswitch.c among your printouts. Let me scroll down and take a look at what we can now do. Our program can get a little more interesting, a little more judgmental based on our input. So at the very top, I've coded up the same thing as before: "Give me an integer between one and ten," or rather, "give me an integer between one and ten" -- a little different this time. Then I called GetInt, which is going to handle the difficult users for me. If they type in bogus characters, it's going to yell at them and make them retry, and eventually I'm going to get handed back an int, which I'm storing in n. Well, if I actually want to judge this number based on its magnitude, well, I can say now, "If n is greater than or equal to one." So on your keyboard, you don't have a greater than symbol with a minus sign right underneath, even though you might have that in Microsoft Word or the like, but that's fine. In C and most programming languages, if you need greater than or equal to, use greater than and then right next to it with no space put equal to, and that conjures up the same idea. So if n is greater than or equal to 1 and n is less than or equal to 3, let's just judge this thing a small number arbitrarily. Else if n is greater than 4 and n is less than 6 -- let's call it medium -- else if n is greater than or equal to 7, less than or equal to 10 -- let's call it "big" -- and if the user typed in zero or negative 10 or 20 or whatever, let's just use the all-inclusive else block and just say, "You picked an invalid number." So at this point, now the code's getting a little more interesting, but it's also getting a little bloated. It's kind of growing in size. Are there syntactic alternatives to implementing this same idea? In Scratch you may have realized that, "I could implement my program this way with these puzzle pieces, but it kind of feels like I could use these puzzle pieces instead" -- that's absolutely the case in programming. Even though you'll see a whole bunch of constructs today and even throughout the course, you will find that there's often multiple ways to implement something, and it will be up to us to guide you toward better design and making in giving two different options the better choice as time passes. So turns out C supports what's called a switch, a switching construct. This thing's nice because rather than do "if" and "and and" or "or or" and all of this, you can instead enumerate things a little more cleanly, albeit apparently at the expense of more white space. So the top of this program's the same. "Give me an integer between 1 and 10." I get the int and store it in n. The switch statement takes inside its parenthesis an int or a char or some primitive type. So for now assume it's got to be an int or a char. And then what I get to do inside the curly braces is literally line by line enumerate the cases that I want to apply to the following code. So this code is identical functionally to the last implementation we saw, nonswitch.c, but I'm just ever-more emphatically saying, "In case 1," that is when n equals 1 or when case 2 applies -- when n equals 2 or when n equals 3 do what? I go ahead and print out a small number. But I now have to use "break." Break is another key word. You might have used something similar in Scratch, maybe Stop or something like that to kind of stop what you were doing inside a loop or some construct. I have to break because otherwise the idea of a switch is that it's going to keep falling through. And once one of these things applies, it's just going to start executing code until you tell it to break. Now at the very bottom, should we see a default case. When you're all out of specific cases and you want to handle everything else, you literally say "default:" And here I could end the program with break, but it's kind of unnecessary because once I'm at the bottom of the curly braces, that's it. There's nothing more that might get executed anyway. Which one is better? Honestly, this one looks a little ugly. You have to kind of scroll down to see it. But when you start writing programs, especially when we get to web-based stuff where you want to check the user's input -- is it valid, is it an email address, and all these different scenarios -- it's actually often useful to be able to just enumerate them or rattle them off using this switching construct instead. All right. Well, we saw loops in Scratch. Let's see how we can now start using them like I did for that little chart of enrollment. So here is a for loop. In C and in many languages, PHP and JavaScript are pretty much going to look the same to us later this semester, you implement the idea of looping with any of three constructs: one's called a for loop, as we're about to see; one's called a while loop; and one's called a do while loop. Scratch essentially had the same ideas, but they were call repeat and forever and a few other options. So same ideas, just different jargons, slightly different implementations. So what does this program do? Well, main first declares a loop that starts here. And then there's three parts to the parenthesis after the key word "for." The semicolon separates each of the parts. So this thing on the left is part one, part two, part three. The general structure that we're looking at can be summarized as this, if this helps paint a nice mental picture. The first thing is what we're going to call "initializations." This is code that's got to be executed before anything else happens. It's how you can initialize a variable to like zero for counting's sake or something like that. "Condition," this thing in the middle between the semicolons, is going to be checked every iteration of the loop. And as soon as this condition or these conditions evaluate to false, the whole loop terminates. So unlike Scratch where you pretty much had to say "repeat" ten times or whatever, or forever where it's just "forever" with for loops, can you actually specify a finite number of iterations -- and as I learned 15 years ago, finite is important. So finite number of times can you specify with a condition, as we'll see in a moment. And then finally, updates. It's not a good thing if you're just looping and checking some condition, but never actually changing the state of the world. If you're not updating some variable by incrementing it or decrementing it -- if you're not changing anything, presumably the conditions are never going to evaluate to false or the opposite, so you're just going to have an infinite loop, which might be your goal, but odds are it's not. So how might we use this in practice? Probably the most common approach to using a for loop is just to iterate from i equals zero up to some value. And in this case, it's very reasonable to use a variable called "i" even though that conveys very little information if the whole point is to be an index, just from zero to one to two, to three, to four, or even downward depending on your goal. So this declares an integer, a variable of type int called I, and initializes it to zero. This checks "Is i less than or equal to one hundred? If so, proceed to loop." I proceed to loop. I print Percent complete. And this looks a little messy, but notice what's embedded in there is some familiar stuff. %d means -- >> [ Inaudible ] >> David: Yep, so one or more digits. "%%" means percent. So just as we had to escape things with backslashes in an awkward way, same deal with percent in this context. If you want a literal percent, it's %% and then backslash n. So this program, if you run it based on intuition or little cheat sheets in front of you, what is this program ultimately going to do for me? >> It's going to count [inaudible] from zero. >> David: Yeah, it's going to count from zero up to one hundred percent. It's going to be my sort of simple implementation of a progress bar. So let's go ahead and try this. So I'm going to run progress1. And again, it's kind of a weak implementation. And we won't wait here one hundred seconds for it to finish, but we're using the loop, we're updating a variable, and we're formatting it in a nice way. And so at the end of the day, a hundred lines later, it should get to one hundred percent. And because there's nothing else in the code at that point, the program should just quit naturally in a good way. Yeah? >> Is there a way to get that first percent complete to stay in the same place naturally? >> David: So absolutely. Can you get the percent to stay in the same place? Because notice there's going to be eventually a problem. You go from one, which is this wide; then it goes to ten and eventually it's going to go to one hundred. So if you're really being anal, things are not going to line up in a perfect column. It turns out that you can. You can specify numbers before d just as you can specify numbers before f. And if you don't put a point but just put a number, this specifies the width of space that will be used by the number you're inserting there. And for Problem Set One, we'll defer to some online documentation for the specifics. But short answer: yes. And it boils down to modifying the format string with just a simple number. So you can do some neat things. >> Is sleep [inaudible]? >> David: Very good question. So sleep -- as the name implies -- simply puts the program to sleep for a second. In this case because I'm saying sleep for a value of one, where does that come from? Well, I actually unintentionally glossed over that detail. At the top of this program notice I had to whip out another header file because sleep is not defined in CS50's library, it's not declared in the standard io library, it's apparently defined in the uni standard library -- unistd.h. Well, how in the world did I know that? Well, as you'll see in Problem Set One -- to be clear, unless you walk out of here uncomfortable here today -- realize that we'll very much hold your hand for this first problem set through these various steps. It turns out on a Linux system there's this command called "man" for manual page. And you can look up documentation for various functions. So if I type "man sleep," this is going to give me the user's manual for a program called sleep, but there's a gotcha and the problem set it makes clear, notice that it says at top left sleep one. Turns out this user's manual, just like a typical book, has multiple sections or chapters and Chapter One is generally about programs. So it turns out there's a program called sleep, just like there's a program called Nano, a program called GCC -- that is not what I want. I want the function, which is a little tool, a line of code I can include in my own programs and generally those tools live in sections two or three of the manual. So if I specify the number three, now I'm in the right place. Again, pset one will walk you through this and you'll get familiar with this stuff, even though it looks a little arcane at first glance. But long story short, if I want to use a function called sleep, the reason I, the programmer, knew to use that library -- that header at the top -- because it told me to in this little synopsis. And I read the documentation, did what it said, and that's how I got my program to compile. And you'll do exactly that with some handholding in Problem Sets One. So let's do make this slightly sexier. So I'm going to wave my hands at what one of these things here does, fflush(stdout) here, but I decided this is kind of a weak implementation. A progress bar is not supposed to print one hundred lines just to update its status; generally we like to see a little animation. So let me go ahead and compile progress2 instead and this time run this one. It turns out that you can keep the cursor on the same line and update the same line of code again and again by not using backslash n but instead by using the more retro backslash r, which doesn't move the cursor down as we said; it instead moves the back to the beginning, much like a typewriter would cycle back the beginning. So here I'm culling printf in a loop again and again, but I'm literally overwriting the previous thing that I wrote. And because I'm writing out a string that's the same length -- my strings aren't getting shorter -- it's creating this illusion of some animation. But really, the computer's just so fast I'm drawing the same string with just a slightly different number again and again after going to sleep one second at a time. Yeah? >> So is there a slash letter command for printf they could just like type [inaudible] you know what I mean? >> David: Good question. Is there a command to printf? Not that's as easily said as done. You could absolutely implement something more interesting and something even more animated like we saw on Wednesday or even earlier today, but it takes a little more than just a format string. All right, so let's take a look at one last thing here, one last version of progress. So in addition to for loops like this, know that there are while loops. And when do you use one or the other? At the end of the day, you can implement the exact same program using a while loop that you can using a for loop, it's just your code is going to look slightly different. And odds are if a week hence, two weeks hence just for fun you decide to reimplement your Scratch project or some tiny piece of it, it wouldn't be surprising -- or shouldn't be -- if you end of implementing the same game or animation or whatever using a completely different set of puzzle pieces. Same deal we'd see here. So with the while loop, you have a condition very similar to the if blocks and the else if blocks that we've seen. This is a condition that's checked again and again every time you cycle around. But notice unlike a for loop, if you want to declare a variable or increment or decrement to variable, you've got to do that yourself. You've got to do it above this chunk of code, you've got to do it inside this chunk of code. The burden is put on you. You don't get the nice little feature of a for loop. So we can see this in progress3.c. This is the exact same program that I had in progress2.c. It's the fancier version that's actually using backslash r to move things to the start of the line. Again, for today let me ignore what fflush means. It solves a slight bug if we don't use it at all, but more on that in the future when you talk about files and creating files. But notice what I have to do here. Because the for loop hands me placeholders in between those semicolons for variables and such, now I don't have those with while loops. I got to roll this one myself. So I have up here at the top of my program a variable called i of type int, and I have to initialize it up here to zero. Now I say while i is less than or equal to 100, I write my code, I sleep for a second. But here, as we saw in week zero with the shoe example putting on socks, I have to increment this variable explicitly myself. Now instinctively, prefer the for loop or the while loop? >> For. >> David: Yeah, I'd probably vote for for. It just feels a little cleaner, but it's going to depend. And you will see over time as you've seen with Scratch that there's going to be different ways to implement these various goals. Now there's this last type of loop. So with this type of loop, things get a little bit reversed. So the do while construct is not as useful as the other two. I probably whip out a do while loop very rarely, but very often when programming games or any program that takes user input and has to check that user input and yell at the user if they're messing with you or aren't providing what's expected. Now what do I mean by that? The difference with the do while loop, as the syntax kind of suggests, is that this construct is going to do something no matter what. It doesn't check a condition. It does something, and then what does it do? >> [ Inaudible ] >> David: Then it checks the condition. And if the condition is true, then it goes back and does it again. If it's false, it just breaks there. So conceptually the key difference here, besides the syntax looking slightly different, it just means that if you want a chunk of code to execute no matter what initially, you can use the do while loop; if you want to check a condition first, you can use the while loop. So let's see this in practice. I'm going to open up a program called positive1.c. I'm going to scroll down to the juicy part here. It, too, is pretty short, but take a look at what this one does. Here, too, gets a little ugly and this is why I tend not to like this construct, at least in C, but sometimes it's necessary or it's the simplest way to achieve this goal. I declare a variable called n. I'm not giving it a value yet, so I had better be careful. One of the details we'll see over time, especially as we discuss security: failing to initialize your variables to values you know about is very bad practice in general because if you forget, if you're writing a program that's not 6 lines but 600, leaving things in an unknown state is just asking for trouble because it's these kinds of things that bad guys try to take advantage of by putting data there that you didn't expect. But for now, let's see if it's okay. Logically looks like I'm safe because I know what I'm doing here. So int n just gives me four bytes for an int, but it doesn't put anything there yet. So let's put something there. Do the following: Print. I demand that you give me a positive integer. Okay, I was a little angry when I wrote this. So next I cull the CS50 function called GetInt. And what do I do with its value? I put it in n. So here's where I'm pushing back. I know this is okay because I'm not using n until I myself put something there. So it was a little risky but safe in the end because I didn't do anything else with it. Now what do I do? At this point in the story, I now check while n is less than 1, what do I do? This again and again. So it feels a little backward mentally perhaps, but this is saying, "do this block of code as long as n is less than 1." So the take away is that if the user actually gives me two or three or four or whatever, this is this expression "is n less than 1" is going to evaluate to false if it's actually two or three or four or whatever. So this do while loop immediately breaks out at the point of that check. Now if I am difficult with the user and I compile make positive1, and I then run positive1. And again I say "David," well, it's going to make me retry. Then I type negative1, zero, maybe negative zero. Still didn't work. One -- thanks for the one. And so now it actually spits that out for me. So what else can we do with this version? Well, let's take a look at this variant, positive2.c. So it's a little different. But notice now I'm getting a little fancier. And you might have started doing these kinds of things in Scratch as your programs got more sophisticated. Here I'm declaring another data type altogether. There's this notion of a Boolean value named after Mr. Bool, which is just a notion of true or false. This doesn't actually exist in C itself. We put it there via the CS50 library. We'll pull back that layer before long. But other languages, Java, C++, and the like all come with Bool. This is a true or false value. Because I was taught good style, I'm giving that variable a name that conjures up the idea of its role, which is thankful or not. I initialize it to false. Now what do I do? I print out -- and this is only wrapping because of the big font -- I print out, "I demand that you give me a positive integer." I then do this. If GetInt's return value is greater than zero, what do, in plain English? >> [ Inaudible ] >> David: I change thankful to true. Now notice couple interesting things -- GetInt returns a value. Apparently in this program, I don't actually care what it is, I only care that it is greater than zero, so it suffices. It's totally legit to cull a function, get back a value, do nothing with it other than compare it to another value. So you don't have to use the assignment operator. You don't have to declare a special variable for it if you don't care about its actual value. So I said thankful to true. Now down here I can use that other piece of syntax we just saw. I want to keep doing this while I am not thankful for the user's number. So in other words, if thankful is still false at this point, it means this condition did not work out very well, and so I'm going to do this block of code again. Now this version is arguably a little better in that it's just a little more clear. It's a little more readable because I'm using a Boolean value that tells me, the programmer, this is true or this is false. Well, let's clean this up slightly. Turns out with a Boolean expression, you don't have use the equality operator equals equals, you can just say what you mean. And this starts to make our code more readable, more elegant, just a little more compact. So same code up here -- thankful is initialized to false. I do print this. I check the return value of GetInt is greater than zero. I then assign thankful true, if so, but notice this little trick: I'm going to keep doing this while I am bang thankful -- bang exclamation point means "not," so this is shorthand, sort of clever elegant notation for "while I'm not thankful, keep doing this." And so you can begin to express -- even though the language is a bit arcane -- your ideas in the same way that you might actually speak them. So allow me to put this up on the screen now, which you're now qualified to understand. [ Laughter ] I'm very sorry -- we're turning you into the people who do understand these. Problem Set One will be posted on the course's website tonight by 7:00 p.m. It will very clearly walk you through the week's challenges. We will see you next week. ==== Transcribed by Automatic Sync Technologies ====