1 00:00:00,000 --> 00:00:00,994 2 00:00:00,994 --> 00:00:03,976 [MUSIC PLAYING] 3 00:00:03,976 --> 00:01:23,496 4 00:01:23,496 --> 00:01:27,907 DAVID MALAN: All right, this is CS50, and this is a very exciting day, 5 00:01:27,907 --> 00:01:29,990 because today we're going to learn a new language. 6 00:01:29,990 --> 00:01:33,020 And that's not something that you can say happens to you every day. 7 00:01:33,020 --> 00:01:35,810 And this language is going to look a little something like this. 8 00:01:35,810 --> 00:01:37,220 Today, we introduce C-- 9 00:01:37,220 --> 00:01:41,690 a very traditional, a very old language that's purely text-based, 10 00:01:41,690 --> 00:01:45,230 but it can do everything that you can do in Scratch and even more, 11 00:01:45,230 --> 00:01:47,810 but without the user friendliness that we're now 12 00:01:47,810 --> 00:01:49,370 used to over the past few days. 13 00:01:49,370 --> 00:01:52,490 However, even though this might look quite cryptic to you at first glance, 14 00:01:52,490 --> 00:01:55,280 even though there's some English or English-like words in there, 15 00:01:55,280 --> 00:01:58,200 rest assured that within a few days, certainly within a few weeks, 16 00:01:58,200 --> 00:02:00,658 you'll be able to understand every character on the screen, 17 00:02:00,658 --> 00:02:02,520 every line of code, and much more. 18 00:02:02,520 --> 00:02:06,157 But I dare say that any course like this can be a little daunting, especially 19 00:02:06,157 --> 00:02:07,490 if you have no prior experience. 20 00:02:07,490 --> 00:02:10,759 But recall from last week, that is, indeed, the norm, the common case. 21 00:02:10,759 --> 00:02:13,490 2/3 of CS50 students-- perhaps yourself among them-- 22 00:02:13,490 --> 00:02:16,250 have never taken a CS course before. 23 00:02:16,250 --> 00:02:21,462 So what looks like this today, realize, will feel exactly like this ultimately. 24 00:02:21,462 --> 00:02:24,170 Indeed, even though the code is going to look different-- whoops. 25 00:02:24,170 --> 00:02:25,670 Even though the code is going to look different, 26 00:02:25,670 --> 00:02:27,830 the ideas today are going to be absolutely 27 00:02:27,830 --> 00:02:30,410 the same as this past week in Scratch. 28 00:02:30,410 --> 00:02:33,500 We'll look at functions and conditions and Boolean expressions, loops, 29 00:02:33,500 --> 00:02:35,390 and other features along the way. 30 00:02:35,390 --> 00:02:37,800 But I'm perhaps reminded of this wonderful hack from MIT 31 00:02:37,800 --> 00:02:42,350 back in 1991, an expression that MIT is that getting an education from MIT 32 00:02:42,350 --> 00:02:44,630 is like taking a drink from a fire hose. 33 00:02:44,630 --> 00:02:46,910 And in the spirit of MIT hacks, as they're called, 34 00:02:46,910 --> 00:02:51,140 some students wired up an actual fire hose to an actual water fountain 35 00:02:51,140 --> 00:02:53,480 with a sign on the wall that says exactly that. 36 00:02:53,480 --> 00:02:56,240 And this is the kind of course, as with many introductory courses, 37 00:02:56,240 --> 00:02:58,990 where it feels like you're really getting hit in the face with way 38 00:02:58,990 --> 00:03:04,010 more information, way more ideas than you can possibly take down all at once. 39 00:03:04,010 --> 00:03:09,652 But realize that you'll be able to absorb all the more material over time. 40 00:03:09,652 --> 00:03:11,360 And the goal of the class, ultimately, is 41 00:03:11,360 --> 00:03:14,240 to present you with as many concepts and practical skills 42 00:03:14,240 --> 00:03:16,040 as might prove useful later on. 43 00:03:16,040 --> 00:03:20,960 And so realize by end of semester will this feel much less like this 44 00:03:20,960 --> 00:03:24,630 and much more like something you have succeeded at. 45 00:03:24,630 --> 00:03:27,880 So without further ado, let's go about introducing this language called C. 46 00:03:27,880 --> 00:03:30,380 So on the left here, recall that this was maybe the simplest 47 00:03:30,380 --> 00:03:31,910 program we could write in Scratch. 48 00:03:31,910 --> 00:03:35,330 And all this program did was compel a cat, or any sprite, 49 00:03:35,330 --> 00:03:36,760 to say hello on the screen. 50 00:03:36,760 --> 00:03:38,960 Today, to achieve that same result, we're 51 00:03:38,960 --> 00:03:42,650 going to start writing code that looks like this, using a keyboard only-- 52 00:03:42,650 --> 00:03:44,690 fewer graphical user controls. 53 00:03:44,690 --> 00:03:47,910 But let's see why the left is actually equivalent to the right. 54 00:03:47,910 --> 00:03:50,390 So let's break it down into, say, this single puzzle piece. 55 00:03:50,390 --> 00:03:53,330 This, of course, did what to the-- 56 00:03:53,330 --> 00:03:55,815 this represented what in the context of a Scratch program? 57 00:03:55,815 --> 00:03:57,440 What was the role of this puzzle piece? 58 00:03:57,440 --> 00:03:58,700 AUDIENCE: Like starting things. 59 00:03:58,700 --> 00:03:59,850 DAVID MALAN: Yeah, for starting things. 60 00:03:59,850 --> 00:04:01,892 So for the main part of your program to kick off, 61 00:04:01,892 --> 00:04:05,600 you have to attach it to this one green flag clicked puzzle piece. 62 00:04:05,600 --> 00:04:08,693 And we're going to see in C that it's not nearly as straightforward. 63 00:04:08,693 --> 00:04:11,360 But it's something that you can just kind of copy/paste for now. 64 00:04:11,360 --> 00:04:15,040 And within a few days will this make more sense character by character. 65 00:04:15,040 --> 00:04:17,720 Int main void and then this open curly braces, 66 00:04:17,720 --> 00:04:20,029 it's called followed, by this closed curly brace 67 00:04:20,029 --> 00:04:22,940 suggests that all of the code that we're going to write today onward 68 00:04:22,940 --> 00:04:26,240 is going to go between those two curly braces as opposed 69 00:04:26,240 --> 00:04:28,770 to underneath a puzzle piece like this. 70 00:04:28,770 --> 00:04:31,785 So even though this won't make perfect sense today or for a few days, 71 00:04:31,785 --> 00:04:34,160 realize that it is functionally equivalent to just saying 72 00:04:34,160 --> 00:04:38,070 when the green flag is clicked, here is the main part of my program. 73 00:04:38,070 --> 00:04:40,197 Now, what might a program actually do for you? 74 00:04:40,197 --> 00:04:43,280 Well, you might have something like say "hello world" in Scratch that just 75 00:04:43,280 --> 00:04:45,030 literally prints that on the screen. 76 00:04:45,030 --> 00:04:48,260 So let's consider how you would implement this in C, C 77 00:04:48,260 --> 00:04:50,930 being a text-based or keyboard-based language. 78 00:04:50,930 --> 00:04:55,490 Well, there isn't a verb or a function called say in C. Instead, 79 00:04:55,490 --> 00:04:57,410 it's called print, or not quite print. 80 00:04:57,410 --> 00:05:00,680 It's actually called printf, where the f stands for formatted 81 00:05:00,680 --> 00:05:03,860 so that you can print formatted text, as we'll soon see. 82 00:05:03,860 --> 00:05:07,400 Then, you go ahead and put, next to printf, two parentheses-- an 83 00:05:07,400 --> 00:05:09,830 open parenthesis and a close parenthesis. 84 00:05:09,830 --> 00:05:14,180 And that's kind of reminiscent of this oval shape in which we were previously 85 00:05:14,180 --> 00:05:15,770 putting input into in the first place. 86 00:05:15,770 --> 00:05:19,210 And the input we provided last week was to just say, hello world. 87 00:05:19,210 --> 00:05:21,770 So literally, in C, you're going to write "hello world" 88 00:05:21,770 --> 00:05:24,200 in between those two parentheses. 89 00:05:24,200 --> 00:05:25,850 But C is a little more nit-picky. 90 00:05:25,850 --> 00:05:28,850 You can't just start writing words in between parentheses. 91 00:05:28,850 --> 00:05:32,870 Anytime you have characters or words or sentences or phrases, 92 00:05:32,870 --> 00:05:36,290 you need to actually encapsulate that text with double quotes, 93 00:05:36,290 --> 00:05:37,090 as in this case. 94 00:05:37,090 --> 00:05:40,340 So you just have to surround whatever it is you want to say or print 95 00:05:40,340 --> 00:05:41,540 with double quotes here. 96 00:05:41,540 --> 00:05:44,480 And the last thing with C that's so easy to forget early on, 97 00:05:44,480 --> 00:05:47,520 as you undoubtedly will, is that you need to finish your thought. 98 00:05:47,520 --> 00:05:51,000 So just like in an English essay, you typically end a sentence with a period, 99 00:05:51,000 --> 00:05:52,850 so in C do you finish your thought. 100 00:05:52,850 --> 00:05:55,730 But not with a period, but with a semicolon, generally 101 00:05:55,730 --> 00:05:57,560 at the end of a line of code. 102 00:05:57,560 --> 00:06:00,882 But we'll see which types of lines of code require this. 103 00:06:00,882 --> 00:06:02,840 So on the left, we have an idea from last week. 104 00:06:02,840 --> 00:06:06,930 On the right, we have an idea from this week, as we'll soon see on my computer, 105 00:06:06,930 --> 00:06:08,930 but they are functionally equivalent. 106 00:06:08,930 --> 00:06:10,440 They do the same thing. 107 00:06:10,440 --> 00:06:13,940 So how do we go about, then, getting from this Scratch program 108 00:06:13,940 --> 00:06:15,540 to this Scratch program? 109 00:06:15,540 --> 00:06:18,770 Let's go ahead and point out one last thing. 110 00:06:18,770 --> 00:06:20,840 We need one last line of code, which I just 111 00:06:20,840 --> 00:06:24,090 popped up on the screen, which is to include stdio.h. 112 00:06:24,090 --> 00:06:25,320 Well, what does that mean? 113 00:06:25,320 --> 00:06:28,010 It turns out that Scratch is super user friendly. 114 00:06:28,010 --> 00:06:30,600 You've got all of those colorful categories of puzzle pieces 115 00:06:30,600 --> 00:06:32,670 on the left, and they're just available to you 116 00:06:32,670 --> 00:06:35,220 right from the moment you start using Scratch. 117 00:06:35,220 --> 00:06:38,910 In C, when you want to use some function-- or some puzzle piece, 118 00:06:38,910 --> 00:06:39,790 if you will-- 119 00:06:39,790 --> 00:06:42,240 you have to typically tell the computer in advance 120 00:06:42,240 --> 00:06:47,110 where that function is implemented, where it was saved. 121 00:06:47,110 --> 00:06:50,340 And this is going to be the admittedly cryptic syntax for saying, 122 00:06:50,340 --> 00:06:52,880 hey, computer, look in a file that we're going 123 00:06:52,880 --> 00:06:56,640 to start calling stdio.h, whatever that means, 124 00:06:56,640 --> 00:06:58,933 in order to access this function. 125 00:06:58,933 --> 00:07:00,350 So, again, that's a huge mouthful. 126 00:07:00,350 --> 00:07:02,400 That's the first of the fire hoses today. 127 00:07:02,400 --> 00:07:04,620 But the important line of code for today's purposes 128 00:07:04,620 --> 00:07:07,470 really is going to be this one down in the middle. 129 00:07:07,470 --> 00:07:11,040 So how, then, do I go about writing my very first program in C, 130 00:07:11,040 --> 00:07:15,210 just as last week, we wrote our very first program in Scratch? 131 00:07:15,210 --> 00:07:18,540 Well, consider that the first thing we did in Scratch 132 00:07:18,540 --> 00:07:22,950 was to open up a program, a tool-- scratch.mit.edu. 133 00:07:22,950 --> 00:07:25,530 You can program, actually, on your own Mac, on your own PC, 134 00:07:25,530 --> 00:07:27,510 no matter what operating system you're running. 135 00:07:27,510 --> 00:07:30,630 But frankly, it tends to be really annoying and very prone 136 00:07:30,630 --> 00:07:32,640 to technical support headaches if all of us 137 00:07:32,640 --> 00:07:36,900 try to install requisite software on all of our individual Macs and PCs. 138 00:07:36,900 --> 00:07:39,420 Invariably, all of us have different versions of things, 139 00:07:39,420 --> 00:07:41,500 and our computers don't quite function the same. 140 00:07:41,500 --> 00:07:44,440 So in the earliest weeks of CS50, we use a cloud-based tool-- 141 00:07:44,440 --> 00:07:48,270 CS50 Sandbox, which lives at sandbox.cs50.io. 142 00:07:48,270 --> 00:07:51,360 And you'll use this for your first problem set this coming week. 143 00:07:51,360 --> 00:07:54,280 This is a programming environment similar in spirit to Scratch, 144 00:07:54,280 --> 00:07:55,530 but that does not use Scratch. 145 00:07:55,530 --> 00:07:57,000 It doesn't use puzzle pieces. 146 00:07:57,000 --> 00:07:59,730 It instead uses C, this text-based language 147 00:07:59,730 --> 00:08:01,530 that we're starting to see now. 148 00:08:01,530 --> 00:08:04,410 So there's two main parts to this programming environment. 149 00:08:04,410 --> 00:08:07,350 On the top here, it's just going to be where I write my actual code. 150 00:08:07,350 --> 00:08:09,250 Literally, in a moment, I'm going to click that plus, 151 00:08:09,250 --> 00:08:10,708 and I'm going to create a new file. 152 00:08:10,708 --> 00:08:13,390 And I'm going to start writing code in that file and save it. 153 00:08:13,390 --> 00:08:16,038 And then, in the bottom half of this programming environment 154 00:08:16,038 --> 00:08:18,330 is what we're going to start calling a terminal window. 155 00:08:18,330 --> 00:08:20,880 A terminal window is sort of an old-school interface 156 00:08:20,880 --> 00:08:24,780 via which you can run commands by literally typing them at a prompt 157 00:08:24,780 --> 00:08:25,980 and then hitting Enter. 158 00:08:25,980 --> 00:08:27,330 So unlike in Scratch-- 159 00:08:27,330 --> 00:08:29,700 and frankly, unlike in Mac OS and Windows these days-- 160 00:08:29,700 --> 00:08:32,610 where you point and click and drag and so forth, interacting 161 00:08:32,610 --> 00:08:35,460 with a graphical user interface, a lot of our programming 162 00:08:35,460 --> 00:08:38,620 early on is going to involve typing commands. 163 00:08:38,620 --> 00:08:40,380 So let's make this more real. 164 00:08:40,380 --> 00:08:44,580 The goal at hand, again, is to, quite simply, implement a program in C 165 00:08:44,580 --> 00:08:47,580 that says hello to the world, which is functionally going to be 166 00:08:47,580 --> 00:08:49,950 similar to the Scratch program at left. 167 00:08:49,950 --> 00:08:53,295 But we now need to implement it using the language at right. 168 00:08:53,295 --> 00:08:55,170 So in this programming environment, I'm going 169 00:08:55,170 --> 00:08:59,610 to go ahead and click this plus sign up top for new file or tab. 170 00:08:59,610 --> 00:09:03,090 By convention, I'm going to go ahead and name my file something like hello.c. 171 00:09:03,090 --> 00:09:05,550 Hello just because I want this program to say hello, 172 00:09:05,550 --> 00:09:07,170 but I could call it anything I want. 173 00:09:07,170 --> 00:09:10,920 And dot c because the convention, in this programming language C, 174 00:09:10,920 --> 00:09:14,640 is to name your files that contain your code with literally 175 00:09:14,640 --> 00:09:18,740 dot c, much like you have dot doc or dot x for Microsoft Word, 176 00:09:18,740 --> 00:09:22,342 dot gif for graphical files, and the like. 177 00:09:22,342 --> 00:09:24,300 So I'm going to go ahead and click Create File. 178 00:09:24,300 --> 00:09:27,750 And you'll see now that I have a blinking prompt on line 1-- 179 00:09:27,750 --> 00:09:31,530 it's going to automatically number my lines for me-- in a tab called hello.c. 180 00:09:31,530 --> 00:09:33,000 This is where I can write code. 181 00:09:33,000 --> 00:09:37,210 Now, even though the code I'm about to write is, frankly, pretty cryptic-- 182 00:09:37,210 --> 00:09:41,400 include standard.io, int main void. 183 00:09:41,400 --> 00:09:44,220 And then in here, I'm going to do printf, quote, unquote, 184 00:09:44,220 --> 00:09:46,650 "hello world" semicolon. 185 00:09:46,650 --> 00:09:50,008 I have just written my first program in C. 186 00:09:50,008 --> 00:09:52,050 So I'm going to go ahead and zoom in at top left. 187 00:09:52,050 --> 00:09:54,120 It's six lines of code total. 188 00:09:54,120 --> 00:09:57,720 And you'll see that I have include stdio.h, whatever that means, 189 00:09:57,720 --> 00:09:59,850 int main void, whatever that means. 190 00:09:59,850 --> 00:10:02,610 And then, really, the essence of this program is on line 5-- 191 00:10:02,610 --> 00:10:07,050 print, or printf for formatting, "hello world." 192 00:10:07,050 --> 00:10:10,050 So recall that int main void is similar in spirit to the 193 00:10:10,050 --> 00:10:11,580 when green flag clicked. 194 00:10:11,580 --> 00:10:13,980 And printf is similar to the say block. 195 00:10:13,980 --> 00:10:16,350 And this top line of code, we just need it, 196 00:10:16,350 --> 00:10:19,320 because the computer is not going to understand printf 197 00:10:19,320 --> 00:10:22,630 unless I tell it to include that file. 198 00:10:22,630 --> 00:10:26,850 All right, so now I claim I've written some code. 199 00:10:26,850 --> 00:10:28,110 How do I go about running it? 200 00:10:28,110 --> 00:10:32,390 Well, how do you run a program on your Mac or PC? 201 00:10:32,390 --> 00:10:34,590 What do you typically do? 202 00:10:34,590 --> 00:10:36,180 You double-click it, right? 203 00:10:36,180 --> 00:10:39,730 Unfortunately, there doesn't seem to be anything obvious to double-click here. 204 00:10:39,730 --> 00:10:41,370 In fact, there's no icon on my screen. 205 00:10:41,370 --> 00:10:44,100 And in fact, there's no program, per se, yet. 206 00:10:44,100 --> 00:10:47,760 Because computers, recall from last week, don't understand English. 207 00:10:47,760 --> 00:10:49,740 They don't technically understand C, per. 208 00:10:49,740 --> 00:10:52,440 Se what is the language that computers speak and understand? 209 00:10:52,440 --> 00:10:53,235 AUDIENCE: Binary. 210 00:10:53,235 --> 00:10:55,110 DAVID MALAN: Yeah, so binary, zeros and ones. 211 00:10:55,110 --> 00:10:56,943 And yet, this clearly is not zeros and ones. 212 00:10:56,943 --> 00:11:00,030 And frankly, none of us would have a good time if coding involved, 213 00:11:00,030 --> 00:11:03,240 these days, literally writing zeros and ones, which, in some sense, 214 00:11:03,240 --> 00:11:06,450 it did involve way back in the day. 215 00:11:06,450 --> 00:11:09,510 But nowadays, it turns out there's a solution to this problem. 216 00:11:09,510 --> 00:11:12,660 This, as cryptic as it looks to most of us in this room, 217 00:11:12,660 --> 00:11:15,540 at least you can imagine eventually getting comfortable, 218 00:11:15,540 --> 00:11:18,700 probably, with this syntax, once you learn the rules and the syntax 219 00:11:18,700 --> 00:11:19,530 and so forth. 220 00:11:19,530 --> 00:11:22,260 But we need to convert it somehow to zeros and ones. 221 00:11:22,260 --> 00:11:25,110 And how to do that is perhaps not obvious. 222 00:11:25,110 --> 00:11:31,110 So it turns out if we want to convert code like this to zeros and ones 223 00:11:31,110 --> 00:11:34,770 that the computer understands, there needs to be some intermediate step. 224 00:11:34,770 --> 00:11:38,370 I actually need, on my Mac or PC or this cloud-based environment, 225 00:11:38,370 --> 00:11:43,200 a program that is going to take as input my source code, which 226 00:11:43,200 --> 00:11:45,650 is that language called C, and is going to produce 227 00:11:45,650 --> 00:11:48,000 as output what's called machine code. 228 00:11:48,000 --> 00:11:53,400 So source code is something like C or Python or Java or C++ and maybe other 229 00:11:53,400 --> 00:11:54,660 languages you've heard about. 230 00:11:54,660 --> 00:11:58,170 It's English-like syntax in which you write programs. 231 00:11:58,170 --> 00:12:02,760 Machine code is the zeros and ones that every computer actually understands. 232 00:12:02,760 --> 00:12:05,970 So to get from source code to machine code, 233 00:12:05,970 --> 00:12:08,773 there needs to be some kind of algorithm or, more specifically, 234 00:12:08,773 --> 00:12:10,690 a piece of software that does that conversion. 235 00:12:10,690 --> 00:12:14,230 And that piece of software is what we're going to start calling a compiler. 236 00:12:14,230 --> 00:12:17,790 So we're going to write code literally by just typing commands at a keyboard. 237 00:12:17,790 --> 00:12:20,160 We're going to save those commands in a file, 238 00:12:20,160 --> 00:12:21,900 just like you saved your code in Scratch. 239 00:12:21,900 --> 00:12:24,990 But before I can run my program and do the equivalent of double-clicking 240 00:12:24,990 --> 00:12:28,200 on it, I need to run it through a compiler 241 00:12:28,200 --> 00:12:30,640 and produce output, which is zeros and ones. 242 00:12:30,640 --> 00:12:33,000 So how do I go about doing that? 243 00:12:33,000 --> 00:12:35,640 This is the first of the more esoteric commands, 244 00:12:35,640 --> 00:12:38,880 but it turns out it's relatively straightforward to do. 245 00:12:38,880 --> 00:12:40,680 At the top of my programming environment-- 246 00:12:40,680 --> 00:12:43,380 again, I have my code here at top left. 247 00:12:43,380 --> 00:12:45,780 And if I scroll down to the bottom, I have this, again, 248 00:12:45,780 --> 00:12:47,322 so-called terminal window. 249 00:12:47,322 --> 00:12:49,530 And the dollar sign is just a weird human convention. 250 00:12:49,530 --> 00:12:51,930 The dollar sign just means type something here. 251 00:12:51,930 --> 00:12:54,540 That's your so-called prompt, or your shell. 252 00:12:54,540 --> 00:12:59,700 But the blinking cursor is just inviting me to type a command at this prompt. 253 00:12:59,700 --> 00:13:04,740 The first command I'm going to type is what's called Clang for C language. 254 00:13:04,740 --> 00:13:09,210 Clang is the name of a program that exists to compile code. 255 00:13:09,210 --> 00:13:10,650 Someone else wrote this. 256 00:13:10,650 --> 00:13:14,100 Someone else online built this program called Clang-- a whole group of people, 257 00:13:14,100 --> 00:13:14,640 in fact. 258 00:13:14,640 --> 00:13:18,210 Made it freely available for me and you to download onto your own Macs or PCs 259 00:13:18,210 --> 00:13:19,990 or this sandbox environment. 260 00:13:19,990 --> 00:13:23,110 And we can use Clang to convert source code to machine code. 261 00:13:23,110 --> 00:13:26,940 So I'm going to go ahead and run Clang hello.c. 262 00:13:26,940 --> 00:13:29,860 I've not hit Enter yet, but the moment I hit Enter, 263 00:13:29,860 --> 00:13:31,360 we're going to see something happen. 264 00:13:31,360 --> 00:13:33,720 Let me go up to this little folder icon up here, 265 00:13:33,720 --> 00:13:37,020 and you can actually see all of the files in my current sandbox, 266 00:13:37,020 --> 00:13:38,710 so to speak, my programming environment. 267 00:13:38,710 --> 00:13:41,752 There's, of course, only one, because the only file I've created thus far 268 00:13:41,752 --> 00:13:43,170 is called hello.c. 269 00:13:43,170 --> 00:13:45,720 But notice what happens the moment I hit Enter, 270 00:13:45,720 --> 00:13:47,940 after having typed out Clang hello.c. 271 00:13:47,940 --> 00:13:50,610 272 00:13:50,610 --> 00:13:54,150 So clearly something else exists now, and it's 273 00:13:54,150 --> 00:13:56,490 a really stupid name and very cryptic. 274 00:13:56,490 --> 00:14:02,520 It's a.out, but you can perhaps guess what's inside of that new file. 275 00:14:02,520 --> 00:14:03,842 What might be inside of it? 276 00:14:03,842 --> 00:14:04,800 AUDIENCE: Machine code. 277 00:14:04,800 --> 00:14:06,133 DAVID MALAN: Yeah, machine code. 278 00:14:06,133 --> 00:14:09,540 So it stands for assembly output, but that just means machine code. 279 00:14:09,540 --> 00:14:13,110 So inside of this file are a whole bunch of zeros and ones 280 00:14:13,110 --> 00:14:16,437 that correspond to this code, but in binary, 281 00:14:16,437 --> 00:14:18,270 in the language the computer can understand. 282 00:14:18,270 --> 00:14:20,640 So literally what I just did was this-- 283 00:14:20,640 --> 00:14:24,450 I took as input code that looks like this, written in C. 284 00:14:24,450 --> 00:14:28,148 I ran it as input into the compiler and produced this output, zeros and ones. 285 00:14:28,148 --> 00:14:29,940 And those zeros and ones were automatically 286 00:14:29,940 --> 00:14:35,113 saved for me inside of a file that, by human convention, is called a.out. 287 00:14:35,113 --> 00:14:37,530 All right, but someone proposed earlier, to run a program, 288 00:14:37,530 --> 00:14:40,088 typically, on your Mac and PC, you just double-click it. 289 00:14:40,088 --> 00:14:41,880 But there's really nothing to double-click. 290 00:14:41,880 --> 00:14:44,940 And in fact, if I double-click on this, it's going to look really weird, 291 00:14:44,940 --> 00:14:46,380 and the computer's not going to understand it. 292 00:14:46,380 --> 00:14:48,930 Because it's zeros and ones that aren't meant to be clicked. 293 00:14:48,930 --> 00:14:52,598 They're meant to be executed at this command prompt. 294 00:14:52,598 --> 00:14:53,890 So let me go ahead and do this. 295 00:14:53,890 --> 00:14:54,807 This, too, is cryptic. 296 00:14:54,807 --> 00:14:58,740 But I'm going to go ahead and do ./a.out. 297 00:14:58,740 --> 00:15:02,190 And this, weird as this may look at first glance, 298 00:15:02,190 --> 00:15:07,890 is how I tell the computer, run the program a.out in my current directory. 299 00:15:07,890 --> 00:15:11,010 So that period that I typed first just means it's literally right here, 300 00:15:11,010 --> 00:15:13,260 in my current folder, as though you're double-clicking 301 00:15:13,260 --> 00:15:14,730 on it on your Mac or PC. 302 00:15:14,730 --> 00:15:19,650 And /a.out means look in this directory, and run the program in the file called 303 00:15:19,650 --> 00:15:20,860 a.out. 304 00:15:20,860 --> 00:15:23,150 So let me go ahead and hit Enter. 305 00:15:23,150 --> 00:15:25,980 And voila, hello world. 306 00:15:25,980 --> 00:15:29,610 So you were very impressed last week, as I recall, when I made the cat say, 307 00:15:29,610 --> 00:15:30,580 hello world. 308 00:15:30,580 --> 00:15:32,510 Here, we seem less than underwhelmed. 309 00:15:32,510 --> 00:15:36,360 But hello world is now my program in C that's done exactly the same thing. 310 00:15:36,360 --> 00:15:39,870 But admittedly, it looks a little stupid at the moment. 311 00:15:39,870 --> 00:15:40,950 It looks a little buggy. 312 00:15:40,950 --> 00:15:44,373 What rubs you the wrong way, even if you've never programmed before? 313 00:15:44,373 --> 00:15:45,290 AUDIENCE: Dollar sign. 314 00:15:45,290 --> 00:15:46,748 DAVID MALAN: Yeah, the dollar sign. 315 00:15:46,748 --> 00:15:48,660 I didn't mean to say hello world dollar sign, 316 00:15:48,660 --> 00:15:50,868 but that dollar sign is just like an artifact, right? 317 00:15:50,868 --> 00:15:52,482 What is the dollar sign again? 318 00:15:52,482 --> 00:15:53,190 AUDIENCE: Prompt. 319 00:15:53,190 --> 00:15:54,150 DAVID MALAN: It's just that prompt. 320 00:15:54,150 --> 00:15:57,270 It's waiting for another command, and that's why my cursor is blinking there. 321 00:15:57,270 --> 00:15:58,603 But it just looks stupid, right? 322 00:15:58,603 --> 00:16:01,538 We could argue that this was my intent, but frankly, I'd be lying. 323 00:16:01,538 --> 00:16:03,330 That doesn't quite do what I want it to do. 324 00:16:03,330 --> 00:16:05,380 And this is because, unlike Scratch-- 325 00:16:05,380 --> 00:16:06,930 which, again, is more user friendly-- 326 00:16:06,930 --> 00:16:12,220 C, and many languages like it, literally will only do what you tell them to do. 327 00:16:12,220 --> 00:16:16,972 At no point did I tell the computer to move the cursor to a new line. 328 00:16:16,972 --> 00:16:18,180 I didn't finish that thought. 329 00:16:18,180 --> 00:16:20,340 I said, hello, comma, world, and that's it. 330 00:16:20,340 --> 00:16:23,650 I never sent a command to the computer to actually move that cursor, 331 00:16:23,650 --> 00:16:24,660 but I can. 332 00:16:24,660 --> 00:16:26,830 So let me go back up to my code here. 333 00:16:26,830 --> 00:16:30,300 And it turns out that in C, if you tell the computer 334 00:16:30,300 --> 00:16:33,240 to print hello, comma, world, that is literally all it's 335 00:16:33,240 --> 00:16:34,620 going to print for you. 336 00:16:34,620 --> 00:16:36,810 If you want to print a new line, you need 337 00:16:36,810 --> 00:16:40,950 to use a special command, a special character called a new line character, 338 00:16:40,950 --> 00:16:43,650 which is represented by backslash n. 339 00:16:43,650 --> 00:16:44,672 Now, why is that? 340 00:16:44,672 --> 00:16:46,380 Well, it's really because even though you 341 00:16:46,380 --> 00:16:49,590 might be inclined to hit Enter like this and just hit 342 00:16:49,590 --> 00:16:51,900 Enter like you would hope the computer would do, 343 00:16:51,900 --> 00:16:54,210 even if you've never programmed before, this probably 344 00:16:54,210 --> 00:16:55,950 should start to rub you in the wrong way. 345 00:16:55,950 --> 00:16:57,270 It just looks a little weird. 346 00:16:57,270 --> 00:16:59,460 It looks a little messy, that one line is up here 347 00:16:59,460 --> 00:17:00,930 and the second line is down here. 348 00:17:00,930 --> 00:17:03,180 So what humans decided years ago is let's 349 00:17:03,180 --> 00:17:06,750 just have a simple instruction, backslash n, 350 00:17:06,750 --> 00:17:10,170 that tells the computer to move that new line down. 351 00:17:10,170 --> 00:17:11,670 So let me go ahead and zoom out now. 352 00:17:11,670 --> 00:17:14,010 In the sandbox, it automatically saves like Google Docs, 353 00:17:14,010 --> 00:17:16,589 so you don't have to go to File, Save or anything like that. 354 00:17:16,589 --> 00:17:23,440 If I go ahead now and rerun this program ./a.out Enter, it's not yet fixed. 355 00:17:23,440 --> 00:17:25,319 Let me go ahead and zoom in. 356 00:17:25,319 --> 00:17:27,210 Notice that the symptom is still there. 357 00:17:27,210 --> 00:17:28,260 Why? 358 00:17:28,260 --> 00:17:31,050 What mistake have I already made? 359 00:17:31,050 --> 00:17:32,700 Yeah, I didn't recompile it. 360 00:17:32,700 --> 00:17:36,120 So again, the computer is going to start taking you very, very literally 361 00:17:36,120 --> 00:17:38,580 now that you're programming it to do things. 362 00:17:38,580 --> 00:17:41,340 And if you want to run the new version of your code, 363 00:17:41,340 --> 00:17:44,880 you are literally going to have to do something like Clang 364 00:17:44,880 --> 00:17:48,360 and then hello.c, Enter. 365 00:17:48,360 --> 00:17:49,810 And nothing seems to happen. 366 00:17:49,810 --> 00:17:52,552 And frankly, and ironically, when you don't see any output, 367 00:17:52,552 --> 00:17:53,760 that usually is a good thing. 368 00:17:53,760 --> 00:17:56,340 When you do see output, it's usually a list of, like, five mistakes 369 00:17:56,340 --> 00:17:58,560 that you made or error messages that we'll soon see. 370 00:17:58,560 --> 00:18:00,120 But we still have a.out. 371 00:18:00,120 --> 00:18:02,200 It's just a newer version thereof. 372 00:18:02,200 --> 00:18:06,930 So if I go ahead and zoom in now and do this-- ./a.out, Enter-- 373 00:18:06,930 --> 00:18:10,070 now I have a more impressive version of hello world. 374 00:18:10,070 --> 00:18:12,450 I've just cleaned it up a little bit. 375 00:18:12,450 --> 00:18:14,190 All right, let me pause for just a moment 376 00:18:14,190 --> 00:18:18,490 and see if there are any questions on these mechanics thus far. 377 00:18:18,490 --> 00:18:19,066 Yeah? 378 00:18:19,066 --> 00:18:20,440 AUDIENCE: Why is line 2 empty? 379 00:18:20,440 --> 00:18:21,940 DAVID MALAN: Say it a little louder. 380 00:18:21,940 --> 00:18:23,640 AUDIENCE: Why is line 2 empty? 381 00:18:23,640 --> 00:18:24,330 DAVID MALAN: Why is line 2 empty? 382 00:18:24,330 --> 00:18:25,540 Oh, really good question. 383 00:18:25,540 --> 00:18:29,678 So line 2 is empty just because I have decided stylistically 384 00:18:29,678 --> 00:18:30,720 it looks a little better. 385 00:18:30,720 --> 00:18:32,553 Much like in an English essay, you might hit 386 00:18:32,553 --> 00:18:34,500 Enter, Enter to just separate your paragraphs, 387 00:18:34,500 --> 00:18:36,810 so will programmers often separate their code, just 388 00:18:36,810 --> 00:18:39,300 to make it a little easier to digest so it doesn't 389 00:18:39,300 --> 00:18:41,610 look like just one big blob of code. 390 00:18:41,610 --> 00:18:44,680 But it's not necessary, and I could omit it. 391 00:18:44,680 --> 00:18:46,880 Other questions? 392 00:18:46,880 --> 00:18:49,036 Yeah? 393 00:18:49,036 --> 00:18:51,940 AUDIENCE: Can you rename a.out so that you have more than one 394 00:18:51,940 --> 00:18:52,898 file in your directory? 395 00:18:52,898 --> 00:18:54,315 DAVID MALAN: Really good question. 396 00:18:54,315 --> 00:18:57,750 Can you rename a.out so that you can have more than one file or program 397 00:18:57,750 --> 00:18:58,740 in the same directory? 398 00:18:58,740 --> 00:18:59,430 Absolutely. 399 00:18:59,430 --> 00:19:00,990 So let me do that right now. 400 00:19:00,990 --> 00:19:04,350 It turns out that when you run commands on a computer like Clang, 401 00:19:04,350 --> 00:19:08,100 you don't have to only say the name of the program and the name of the file. 402 00:19:08,100 --> 00:19:10,380 You can add additional options, otherwise known 403 00:19:10,380 --> 00:19:12,180 as command-line arguments. 404 00:19:12,180 --> 00:19:14,280 And here, too, it's a little arcane. 405 00:19:14,280 --> 00:19:19,020 You have to know what's possible in order to type these things out. 406 00:19:19,020 --> 00:19:20,640 But it turns out that with Clang-- 407 00:19:20,640 --> 00:19:22,740 and if you read the documentation, you would see-- 408 00:19:22,740 --> 00:19:25,920 you can actually say -o for output. 409 00:19:25,920 --> 00:19:28,140 And then you can specify any name that you 410 00:19:28,140 --> 00:19:31,860 want for the file in which your machine code is going to be saved. 411 00:19:31,860 --> 00:19:33,000 So notice what happens now. 412 00:19:33,000 --> 00:19:35,550 When I hit Enter now, watch the top left-hand corner, 413 00:19:35,550 --> 00:19:37,710 where I have a.out and hello.c. 414 00:19:37,710 --> 00:19:40,930 I now have hello, as well. 415 00:19:40,930 --> 00:19:45,210 And so now I can go ahead and say ./hello instead of a.out, 416 00:19:45,210 --> 00:19:48,137 and the result will now be the same. 417 00:19:48,137 --> 00:19:50,970 And let me take this as an opportunity to point out one other thing. 418 00:19:50,970 --> 00:19:53,570 Even though we see this graphical interface over here, 419 00:19:53,570 --> 00:19:55,320 this is just convenient, because you and I 420 00:19:55,320 --> 00:19:59,310 are generally familiar with that interface from our own Macs and PCs. 421 00:19:59,310 --> 00:20:04,590 But I can do everything via this command prompt that I can do via my mouse. 422 00:20:04,590 --> 00:20:07,350 In fact, in this programming environment, 423 00:20:07,350 --> 00:20:10,200 I can type a command called ls for list. 424 00:20:10,200 --> 00:20:13,800 It's shorthand notation, because years ago, humans decided, well, 425 00:20:13,800 --> 00:20:17,830 why type L-I-S-T if we can just type ls, which sounds kind of the same. 426 00:20:17,830 --> 00:20:22,320 And thus was born the ls command, which quite simply displays 427 00:20:22,320 --> 00:20:26,340 a list of all the files in that current folder or directory. 428 00:20:26,340 --> 00:20:30,570 And we see the same thing-- a.out, hello, and hello.c. 429 00:20:30,570 --> 00:20:33,720 And you can perhaps infer or guess, what does the asterisk 430 00:20:33,720 --> 00:20:36,060 mean after a.out and hello, perhaps? 431 00:20:36,060 --> 00:20:37,033 AUDIENCE: Executable. 432 00:20:37,033 --> 00:20:38,950 DAVID MALAN: It's executable, which just means 433 00:20:38,950 --> 00:20:42,660 there's machine code in there that can be run by the computer, 434 00:20:42,660 --> 00:20:45,773 whereas hello.c does not have that asterisk or star after it, 435 00:20:45,773 --> 00:20:47,190 which just means it's source code. 436 00:20:47,190 --> 00:20:50,340 So you can even visually distinguish source code from machine code 437 00:20:50,340 --> 00:20:51,600 from machine code. 438 00:20:51,600 --> 00:20:54,630 Now, suppose that I don't want a.out to exist anymore, 439 00:20:54,630 --> 00:20:56,130 because it looks like a stupid name. 440 00:20:56,130 --> 00:20:58,230 I'm never going to remember what the program is. 441 00:20:58,230 --> 00:21:02,520 Well, you can type other commands, like rm, for remove, a.out. 442 00:21:02,520 --> 00:21:03,660 And then hit Enter. 443 00:21:03,660 --> 00:21:04,980 And it's a little arcane. 444 00:21:04,980 --> 00:21:07,540 It says remove regular file a.out. 445 00:21:07,540 --> 00:21:10,890 Notice the prompt is now blinking after that question mark. 446 00:21:10,890 --> 00:21:15,060 I can go ahead and type Y for yes or yes for yes. 447 00:21:15,060 --> 00:21:17,010 Notice that nothing seems to have happened. 448 00:21:17,010 --> 00:21:20,730 But how can I check what files now exist in this folder? 449 00:21:20,730 --> 00:21:24,790 Yeah, so just ls again, and now I'm down to those two files. 450 00:21:24,790 --> 00:21:27,450 So it turns out there's other commands, too, that we can type. 451 00:21:27,450 --> 00:21:34,140 And there's commands like ls and rm. 452 00:21:34,140 --> 00:21:36,690 There's mkdir for make directory. 453 00:21:36,690 --> 00:21:38,683 There's rmdir for remove directory. 454 00:21:38,683 --> 00:21:41,100 And anytime you have to know or use one of these commands, 455 00:21:41,100 --> 00:21:43,080 we'll make sure to tell you in the problem set. 456 00:21:43,080 --> 00:21:46,320 But realize anything you can do with your mouse 457 00:21:46,320 --> 00:21:50,610 and that graphical user interface, can you also do at this command line. 458 00:21:50,610 --> 00:21:53,640 All right, so let's take things up a slight notch 459 00:21:53,640 --> 00:21:55,950 and do something that's a little more interesting, 460 00:21:55,950 --> 00:21:58,350 going back to the side by side here. 461 00:21:58,350 --> 00:22:02,000 So thus far, all we've done is print out hello world. 462 00:22:02,000 --> 00:22:04,620 But recall, last week, the second program we wrote 463 00:22:04,620 --> 00:22:06,450 was a little more dynamic and interactive. 464 00:22:06,450 --> 00:22:10,200 What did we do last week as our second program in Scratch, if you recall? 465 00:22:10,200 --> 00:22:12,400 AUDIENCE: It prompted the user for their name. 466 00:22:12,400 --> 00:22:14,692 DAVID MALAN: Yeah, it prompted the user for their name. 467 00:22:14,692 --> 00:22:17,550 And then we said hello, David, or hello, Brian, or whoever 468 00:22:17,550 --> 00:22:19,133 was actually running the program. 469 00:22:19,133 --> 00:22:21,300 So that program looked a little something like this. 470 00:22:21,300 --> 00:22:25,590 These two lines of code were attached to a when green flag clicked last week. 471 00:22:25,590 --> 00:22:28,170 This blue block here at top was a function, 472 00:22:28,170 --> 00:22:32,940 and that function returned an argument, returned a response. 473 00:22:32,940 --> 00:22:35,170 It returned the answer that the user had typed in. 474 00:22:35,170 --> 00:22:38,130 And that was useful, because we then used the user's answer 475 00:22:38,130 --> 00:22:42,600 to join it together, or concatenate left and right, with the word hello. 476 00:22:42,600 --> 00:22:45,160 And then we said the result of that. 477 00:22:45,160 --> 00:22:46,255 So how do we do this in C? 478 00:22:46,255 --> 00:22:48,630 Well, this is where things are going to escalate quickly. 479 00:22:48,630 --> 00:22:51,570 But again, it's all going to follow certain rules and patterns that 480 00:22:51,570 --> 00:22:54,190 are going to get more and more familiar over time. 481 00:22:54,190 --> 00:22:57,990 In C, at least in the CS50 Sandbox, the closest equivalent 482 00:22:57,990 --> 00:23:03,810 to the ask function in Scratch is going to be a C function called get_string. 483 00:23:03,810 --> 00:23:06,180 A string is just a programmer's expression 484 00:23:06,180 --> 00:23:09,750 for a word or phrase or a sentence. 485 00:23:09,750 --> 00:23:14,470 So text as opposed to numbers or some other piece of data. 486 00:23:14,470 --> 00:23:19,680 So get_string is the closest analog to the ask function there. 487 00:23:19,680 --> 00:23:22,830 In between the parentheses, which imply here's 488 00:23:22,830 --> 00:23:24,840 where you can provide some input, I can go ahead 489 00:23:24,840 --> 00:23:27,673 and provide the prompt that the user is going to see on the screen-- 490 00:23:27,673 --> 00:23:30,217 for instance, what's your name, quote unquote. 491 00:23:30,217 --> 00:23:31,050 Now, why the quotes? 492 00:23:31,050 --> 00:23:34,050 I just claimed earlier that anytime you pass a string-- 493 00:23:34,050 --> 00:23:36,450 a word, a phrase, alphabetical characters-- 494 00:23:36,450 --> 00:23:38,460 you have to surround them with double quotes 495 00:23:38,460 --> 00:23:40,380 on the left and double quotes on the right. 496 00:23:40,380 --> 00:23:44,994 And to be clear, why did I have this weird incantation here, backslash n? 497 00:23:44,994 --> 00:23:45,786 AUDIENCE: New line. 498 00:23:45,786 --> 00:23:47,970 DAVID MALAN: Yeah, it just moves the cursor to the new line. 499 00:23:47,970 --> 00:23:48,540 Why? 500 00:23:48,540 --> 00:23:50,207 Just because it looks a little prettier. 501 00:23:50,207 --> 00:23:51,000 I don't have to. 502 00:23:51,000 --> 00:23:54,370 And indeed, a moment ago, my own computer prompted me to say yes or no, 503 00:23:54,370 --> 00:23:56,780 and it did not move the cursor to the next line. 504 00:23:56,780 --> 00:23:59,470 That's because that programmer decided not to bother doing that. 505 00:23:59,470 --> 00:24:02,120 But I'll go ahead and keep things clean by doing this. 506 00:24:02,120 --> 00:24:07,150 Now, once I ask the user for their name by way of this get_string function, 507 00:24:07,150 --> 00:24:08,680 I need to do something with it. 508 00:24:08,680 --> 00:24:12,220 And in C, the way you do this is you literally 509 00:24:12,220 --> 00:24:15,837 give yourself a variable, which is a piece of storage for a value. 510 00:24:15,837 --> 00:24:18,670 And I'm going to go ahead and call it answer, just like Scratch did. 511 00:24:18,670 --> 00:24:21,040 But in C, I can call this anything I want. 512 00:24:21,040 --> 00:24:22,565 I could call it xyz. 513 00:24:22,565 --> 00:24:25,690 None of those are very descriptive, so I'm going to call it answer instead. 514 00:24:25,690 --> 00:24:27,100 You can use any word. 515 00:24:27,100 --> 00:24:28,990 But C is a little different. 516 00:24:28,990 --> 00:24:34,480 C is old school, and you have to be super explicit as to what type of value 517 00:24:34,480 --> 00:24:37,630 you are getting and, therefore, storing in the variable. 518 00:24:37,630 --> 00:24:40,040 So to the left of the name of the variable, 519 00:24:40,040 --> 00:24:43,810 I have to tell the computer the type of value I need to store 520 00:24:43,810 --> 00:24:45,010 is going to be a string. 521 00:24:45,010 --> 00:24:49,180 And we're going to see in a moment, there's other types of values. 522 00:24:49,180 --> 00:24:53,860 There's numbers and more, but for now, we're just going to store a string. 523 00:24:53,860 --> 00:24:56,760 And there's one thing missing from this line of code. 524 00:24:56,760 --> 00:24:57,700 AUDIENCE: Semicolon. 525 00:24:57,700 --> 00:24:58,600 DAVID MALAN: Semicolon, right? 526 00:24:58,600 --> 00:25:00,392 End of thought, and that was a big thought, 527 00:25:00,392 --> 00:25:02,200 but a semicolon finishes this thought. 528 00:25:02,200 --> 00:25:04,700 Now, this equals sign is a little different from algebra, 529 00:25:04,700 --> 00:25:07,750 if you think back to your math days, where you might say x equals y. 530 00:25:07,750 --> 00:25:11,440 When x equals y, that means, literally, x is the same thing as y. 531 00:25:11,440 --> 00:25:14,740 But here, the equals sign in programming languages 532 00:25:14,740 --> 00:25:17,990 typically is the kind of a motion from right to left. 533 00:25:17,990 --> 00:25:20,560 This equal sign doesn't technically mean equal. 534 00:25:20,560 --> 00:25:24,070 It means assign, or the assignment operator. 535 00:25:24,070 --> 00:25:27,200 Move from the right something to the left. 536 00:25:27,200 --> 00:25:31,600 So if this get_string function, just like the ask function, 537 00:25:31,600 --> 00:25:35,140 asks the user for their name and hands back a value, 538 00:25:35,140 --> 00:25:37,930 you want to put that name into a variable 539 00:25:37,930 --> 00:25:40,192 called answer, from right to left. 540 00:25:40,192 --> 00:25:42,650 So even though we-- just as we wrote it from right to left, 541 00:25:42,650 --> 00:25:45,710 so do you think about it executing from right to left. 542 00:25:45,710 --> 00:25:48,310 So at this point in the story, we now have 543 00:25:48,310 --> 00:25:52,960 somewhere in the computer's memory, in a so-called variable, the user's answer 544 00:25:52,960 --> 00:25:54,130 to their name. 545 00:25:54,130 --> 00:25:55,540 What do I want to do with it? 546 00:25:55,540 --> 00:25:58,093 Well, in C, there isn't a join function, so we're 547 00:25:58,093 --> 00:26:00,010 going to have to do this a little differently. 548 00:26:00,010 --> 00:26:03,613 But there kind of is a say function, and what was that say function called? 549 00:26:03,613 --> 00:26:04,340 AUDIENCE: Printf. 550 00:26:04,340 --> 00:26:05,173 DAVID MALAN: Printf. 551 00:26:05,173 --> 00:26:08,440 So printf is the go-to function any time you want to print or say something 552 00:26:08,440 --> 00:26:09,320 on the screen. 553 00:26:09,320 --> 00:26:10,993 So I'm going to go ahead and use printf. 554 00:26:10,993 --> 00:26:13,660 And I'm going to use parentheses, because parentheses mean, here 555 00:26:13,660 --> 00:26:18,670 come my inputs, otherwise known as arguments or parameters in programming. 556 00:26:18,670 --> 00:26:21,100 But these are synonymous for our purposes. 557 00:26:21,100 --> 00:26:23,350 And now this is a little non-obvious, right? 558 00:26:23,350 --> 00:26:29,180 Because I don't want to just put, quote unquote, hello, comma, answer. 559 00:26:29,180 --> 00:26:29,680 Why? 560 00:26:29,680 --> 00:26:34,480 Why would it be incorrect to do quote unquote, hello, comma, answer? 561 00:26:34,480 --> 00:26:35,155 What's that? 562 00:26:35,155 --> 00:26:36,400 AUDIENCE: It will just print out answer. 563 00:26:36,400 --> 00:26:39,323 DAVID MALAN: Right, it will literally say hello, comma, answer, right? 564 00:26:39,323 --> 00:26:40,490 And that's not what we want. 565 00:26:40,490 --> 00:26:41,530 We don't want to say "hello answer." 566 00:26:41,530 --> 00:26:43,450 We want to say, hello, David or hello, Brian, 567 00:26:43,450 --> 00:26:45,280 or whoever is playing this program. 568 00:26:45,280 --> 00:26:49,900 So I somehow do need to join the word hello with the user's input. 569 00:26:49,900 --> 00:26:53,335 And the way to do this in printf is a little different from Scratch. 570 00:26:53,335 --> 00:26:55,550 You use what's called a placeholder. 571 00:26:55,550 --> 00:26:57,550 So you literally write the sentence or phrase 572 00:26:57,550 --> 00:27:00,220 that you want to say or print to the screen, 573 00:27:00,220 --> 00:27:03,340 but wherever you don't yet know the value in advance, 574 00:27:03,340 --> 00:27:08,570 you put a placeholder using a percent sign and then an s denoting string. 575 00:27:08,570 --> 00:27:11,320 And this is because, of course, if I'm writing this program today, 576 00:27:11,320 --> 00:27:13,840 I have no idea who's going to run it tomorrow. 577 00:27:13,840 --> 00:27:15,910 So I want to dynamically put a placeholder 578 00:27:15,910 --> 00:27:19,400 so that if someone plays this program tomorrow or the next day, 579 00:27:19,400 --> 00:27:21,070 their name gets dynamically inserted. 580 00:27:21,070 --> 00:27:23,410 I, of course, don't know their name today. 581 00:27:23,410 --> 00:27:26,350 So quote unquote, hello, comma, percent s. 582 00:27:26,350 --> 00:27:30,130 And that percent s is just a placeholder for whatever I want to plug in there. 583 00:27:30,130 --> 00:27:32,590 Backslash n, of course, just means new line. 584 00:27:32,590 --> 00:27:35,590 So the only new thing here is this percent s. 585 00:27:35,590 --> 00:27:39,490 Now, it turns out that functions in C, just like in Scratch, 586 00:27:39,490 --> 00:27:40,990 can take no arguments. 587 00:27:40,990 --> 00:27:42,550 Or they can take one arguments. 588 00:27:42,550 --> 00:27:44,650 Or they can take two or more arguments. 589 00:27:44,650 --> 00:27:49,310 And if they take two or more, you just separate them with commas. 590 00:27:49,310 --> 00:27:50,450 So the way printf works-- 591 00:27:50,450 --> 00:27:53,200 and you would only know this, again, by being taught it or reading 592 00:27:53,200 --> 00:27:55,720 the documentation-- is that you can, yes, 593 00:27:55,720 --> 00:27:59,560 provide just a single string as its input-- 594 00:27:59,560 --> 00:28:00,910 quote unquote, something. 595 00:28:00,910 --> 00:28:03,010 But if you have some placeholders in there, 596 00:28:03,010 --> 00:28:06,520 you can tell the computer what to plug in by adding a comma 597 00:28:06,520 --> 00:28:10,570 and then the name of the value or variable that you want to plug in. 598 00:28:10,570 --> 00:28:14,120 So now, these two lines of code are equivalent to these here. 599 00:28:14,120 --> 00:28:15,870 But again, even though at first glance, it 600 00:28:15,870 --> 00:28:17,620 might look especially cryptic, if you just 601 00:28:17,620 --> 00:28:19,480 break it down to the individual components 602 00:28:19,480 --> 00:28:23,020 from right to left and then from outside to inside, 603 00:28:23,020 --> 00:28:28,150 you can generally infer even what new code that you've never seen before 604 00:28:28,150 --> 00:28:29,860 is doing. 605 00:28:29,860 --> 00:28:33,880 Any questions on these two lines of Scratch or C? 606 00:28:33,880 --> 00:28:34,594 Yeah? 607 00:28:34,594 --> 00:28:36,570 AUDIENCE: Can you add [INAUDIBLE]? 608 00:28:36,570 --> 00:28:40,220 609 00:28:40,220 --> 00:28:41,220 DAVID MALAN: Absolutely. 610 00:28:41,220 --> 00:28:42,450 Can you add other variables? 611 00:28:42,450 --> 00:28:46,290 If I had more variables in this program, thanks to more lines of code, 612 00:28:46,290 --> 00:28:49,740 I could just do comma, something else, comma, something else, comma. 613 00:28:49,740 --> 00:28:52,620 And I could just have one placeholder in that quoted 614 00:28:52,620 --> 00:28:56,340 expression for all of those variables that I want to plug in. 615 00:28:56,340 --> 00:28:57,670 And they go from left to right. 616 00:28:57,670 --> 00:29:00,510 So if I had two percent s's here, the first one 617 00:29:00,510 --> 00:29:01,890 would come after the first comma. 618 00:29:01,890 --> 00:29:04,481 The second one would come after the second comma. 619 00:29:04,481 --> 00:29:06,485 AUDIENCE: So you need a percent s [INAUDIBLE]?? 620 00:29:06,485 --> 00:29:07,360 DAVID MALAN: Correct. 621 00:29:07,360 --> 00:29:10,962 You need a percent s for any placeholder you want to plug in if it's a string. 622 00:29:10,962 --> 00:29:13,420 And we're going to see other placeholders in just a moment. 623 00:29:13,420 --> 00:29:14,720 Good question. 624 00:29:14,720 --> 00:29:16,464 Other questions? 625 00:29:16,464 --> 00:29:17,230 No? 626 00:29:17,230 --> 00:29:18,440 Oh, yeah, in back. 627 00:29:18,440 --> 00:29:20,705 AUDIENCE: Is there another way to concatenate strings? 628 00:29:20,705 --> 00:29:23,080 DAVID MALAN: Is there another way to concatenate strings? 629 00:29:23,080 --> 00:29:26,533 Short answer-- yes, many ways, none of them easy. 630 00:29:26,533 --> 00:29:29,200 So we'll build up to that, actually, in a couple of weeks' time. 631 00:29:29,200 --> 00:29:33,290 Printf, for now, is by far the easiest way to do it. 632 00:29:33,290 --> 00:29:34,175 Other questions? 633 00:29:34,175 --> 00:29:36,550 And if I ever miss your hand, there's just lots of glare. 634 00:29:36,550 --> 00:29:37,510 Do just call out. 635 00:29:37,510 --> 00:29:38,200 Over here. 636 00:29:38,200 --> 00:29:40,550 OK, all three of you. 637 00:29:40,550 --> 00:29:41,571 Over here on the right. 638 00:29:41,571 --> 00:29:43,890 AUDIENCE: [INAUDIBLE]. 639 00:29:43,890 --> 00:29:44,640 DAVID MALAN: Sure. 640 00:29:44,640 --> 00:29:45,420 What is a string? 641 00:29:45,420 --> 00:29:50,530 A string is a sequence of zero or more characters in double quotes. 642 00:29:50,530 --> 00:29:54,060 So put another way, it's a word, a phrase, a sentence, a paragraph-- zero 643 00:29:54,060 --> 00:29:58,883 or more characters, alphabetical letters, in double quotes. 644 00:29:58,883 --> 00:29:59,550 Other questions? 645 00:29:59,550 --> 00:30:01,100 Yeah? 646 00:30:01,100 --> 00:30:07,083 AUDIENCE: What would happen if your backslash n was outside the quotations. 647 00:30:07,083 --> 00:30:08,500 DAVID MALAN: Really good question. 648 00:30:08,500 --> 00:30:11,270 What would happen if your backslash n is outside the quotations? 649 00:30:11,270 --> 00:30:12,210 Well, let me go ahead and do this. 650 00:30:12,210 --> 00:30:14,210 And frankly, this is the right instinct to have. 651 00:30:14,210 --> 00:30:17,250 Any time, moving forward, you have those same instinctive questions, 652 00:30:17,250 --> 00:30:17,880 just try it. 653 00:30:17,880 --> 00:30:19,770 You can do no harm to the computer. 654 00:30:19,770 --> 00:30:22,170 So let me go ahead and just accidentally, if you will, 655 00:30:22,170 --> 00:30:24,510 put the backslash n outside of the quotes, 656 00:30:24,510 --> 00:30:25,978 is what I think your question is. 657 00:30:25,978 --> 00:30:27,520 All right, so let's see what happens. 658 00:30:27,520 --> 00:30:29,490 So I'm going to go ahead now and run Clang. 659 00:30:29,490 --> 00:30:31,470 I know how to make a customized name now, 660 00:30:31,470 --> 00:30:34,380 so I'm going to adopt that convention. -o hello. 661 00:30:34,380 --> 00:30:36,720 And now I'm going to go ahead and say hello.c, 662 00:30:36,720 --> 00:30:38,940 which I think is going to be broken. 663 00:30:38,940 --> 00:30:41,910 And indeed, something, indeed, has broken here. 664 00:30:41,910 --> 00:30:43,420 Let's see what the error is. 665 00:30:43,420 --> 00:30:48,210 So it's a little arcane, too, but hello.c, colon 5, colon 26. 666 00:30:48,210 --> 00:30:49,240 What's going on there? 667 00:30:49,240 --> 00:30:50,370 Well, let me zoom out. 668 00:30:50,370 --> 00:30:53,110 Anytime you make a mistake in your code like this, 669 00:30:53,110 --> 00:30:57,870 Clang is going to try to help you figure out where that mistake or that bug is. 670 00:30:57,870 --> 00:31:02,760 So hello.c colon five means look on line 5 for your mistake. 671 00:31:02,760 --> 00:31:07,930 Then, see, it says error-- expected close parentheses right around here. 672 00:31:07,930 --> 00:31:11,500 So it's a little weird, because no, I don't want a close parentheses, 673 00:31:11,500 --> 00:31:12,000 I think. 674 00:31:12,000 --> 00:31:13,170 I want the new line. 675 00:31:13,170 --> 00:31:16,080 So it's not perfectly able to tell you, hey, 676 00:31:16,080 --> 00:31:18,450 that backslash n should be inside of the quotes. 677 00:31:18,450 --> 00:31:21,780 But it can at least help you hone in on where the mistake is. 678 00:31:21,780 --> 00:31:24,000 So it's somewhere around there, at which point 679 00:31:24,000 --> 00:31:26,850 your own memory or your own googling should kick in to figure out, 680 00:31:26,850 --> 00:31:29,717 oh, that's got to be inside of the quotes. 681 00:31:29,717 --> 00:31:30,300 Good question. 682 00:31:30,300 --> 00:31:31,883 Was there a third question back there? 683 00:31:31,883 --> 00:31:32,430 Yeah? 684 00:31:32,430 --> 00:31:32,930 No? 685 00:31:32,930 --> 00:31:33,480 OK. 686 00:31:33,480 --> 00:31:37,860 All right, so let's go ahead now and transition to a few other features 687 00:31:37,860 --> 00:31:39,360 that we can do, as well-- 688 00:31:39,360 --> 00:31:42,630 namely, implementing the same program that I just had. 689 00:31:42,630 --> 00:31:45,600 Let me go ahead and close this file and create a new one called, 690 00:31:45,600 --> 00:31:49,173 say, string.c, because I'm now experimenting with strings. 691 00:31:49,173 --> 00:31:50,590 And I'm going to start as before-- 692 00:31:50,590 --> 00:31:55,260 include stdio.h int main void. 693 00:31:55,260 --> 00:32:01,470 And then I'm going to go ahead here and say string answer get get_string, 694 00:32:01,470 --> 00:32:07,020 quote unquote, what's your name, question mark, backslash n, semicolon. 695 00:32:07,020 --> 00:32:09,448 And as an aside, everything I type on the keyboard 696 00:32:09,448 --> 00:32:11,490 today we will post on the course's website after. 697 00:32:11,490 --> 00:32:15,010 So no need to type down every little character if you'd prefer not. 698 00:32:15,010 --> 00:32:18,448 And then I'm going to go ahead and say printf, quote unquote, hello answer. 699 00:32:18,448 --> 00:32:20,490 Not answer, because we claimed that that was bad. 700 00:32:20,490 --> 00:32:22,440 That would literally say answer. 701 00:32:22,440 --> 00:32:24,750 I want to do a placeholder, percent s. 702 00:32:24,750 --> 00:32:29,920 And now backslash n, comma, answer, semicolon. 703 00:32:29,920 --> 00:32:32,910 So I think I have transcribed the code from the slide 704 00:32:32,910 --> 00:32:37,920 into my programming environment now in a file called string.c. 705 00:32:37,920 --> 00:32:39,300 So let me go ahead and zoom out. 706 00:32:39,300 --> 00:32:41,790 And if I want to compile this program, convert it 707 00:32:41,790 --> 00:32:46,795 from source code to machine code, what command can I type down here? 708 00:32:46,795 --> 00:32:47,295 So Clang. 709 00:32:47,295 --> 00:32:50,150 710 00:32:50,150 --> 00:32:51,210 So string.c. 711 00:32:51,210 --> 00:32:53,590 But that's going to give me a program, by default, called 712 00:32:53,590 --> 00:32:56,030 a.out, which is just very non-helpful. 713 00:32:56,030 --> 00:32:58,670 So let me go ahead and say -o string, just so 714 00:32:58,670 --> 00:33:00,230 that my program is called string. 715 00:33:00,230 --> 00:33:02,090 But I could call it anything I want. 716 00:33:02,090 --> 00:33:04,975 I could call it program two, if I prefer. 717 00:33:04,975 --> 00:33:06,350 So let me go ahead and hit Enter. 718 00:33:06,350 --> 00:33:10,220 And oh my god, there are more errors than there are lines 719 00:33:10,220 --> 00:33:12,320 of code, which is a little worrisome. 720 00:33:12,320 --> 00:33:15,530 And this tier two is where you should take some comfort that that just means 721 00:33:15,530 --> 00:33:17,113 the computer's gotten confused, right? 722 00:33:17,113 --> 00:33:20,480 You're not that bad at programming that you generate more errors than lines 723 00:33:20,480 --> 00:33:21,860 of code you've written yourself. 724 00:33:21,860 --> 00:33:25,370 It's just that the computer got really confused at some point, 725 00:33:25,370 --> 00:33:28,670 and it kind of starts tripping over itself, so to speak, conceptually. 726 00:33:28,670 --> 00:33:31,910 It doesn't know where the error is, so it starts misinterpreting correct code 727 00:33:31,910 --> 00:33:33,020 as incorrect code. 728 00:33:33,020 --> 00:33:38,100 So the place to start is always with the very first error message. 729 00:33:38,100 --> 00:33:41,450 So you'll notice that I already scrolled all the way up to the command 730 00:33:41,450 --> 00:33:44,570 that I typed, which was right here, as I've highlighted. 731 00:33:44,570 --> 00:33:47,270 Focus on the first error you see, and maybe the others 732 00:33:47,270 --> 00:33:50,985 are just phantom errors, confusion that arose instead. 733 00:33:50,985 --> 00:33:53,360 So let me go ahead and zoom in on this part of the screen 734 00:33:53,360 --> 00:33:55,700 and see if we can't diagnose this issue. 735 00:33:55,700 --> 00:33:59,420 The command I ran was Clang -o string string.c. 736 00:33:59,420 --> 00:34:02,480 That just means my input is my source code in string.c. 737 00:34:02,480 --> 00:34:06,500 I want my output to be machine code in a file called string. 738 00:34:06,500 --> 00:34:09,409 All right, string.c line 5 is where the error begins, 739 00:34:09,409 --> 00:34:11,540 so that seems to be a familiar location. 740 00:34:11,540 --> 00:34:13,820 Use of undeclared identifier string. 741 00:34:13,820 --> 00:34:19,960 Did you mean-- anticipation-- stdin? 742 00:34:19,960 --> 00:34:21,280 No, I didn't. 743 00:34:21,280 --> 00:34:22,600 I meant string in this case. 744 00:34:22,600 --> 00:34:25,159 So here, too, the computer's gotten confused, 745 00:34:25,159 --> 00:34:28,179 and even it's green helpful message is actually not helpful. 746 00:34:28,179 --> 00:34:29,679 No, I want a string. 747 00:34:29,679 --> 00:34:31,270 I don't want standard n. 748 00:34:31,270 --> 00:34:34,060 But the reason for this is that technically, 749 00:34:34,060 --> 00:34:37,420 at least this point in the story, there is no such thing as a string, 750 00:34:37,420 --> 00:34:41,699 S-T-R-I-N-G in C. That's actually a training wheel of sorts that 751 00:34:41,699 --> 00:34:44,949 we're going to use for just a couple of weeks until, to your question earlier, 752 00:34:44,949 --> 00:34:48,340 we're going to show what's really going on underneath the hood of the computer, 753 00:34:48,340 --> 00:34:51,130 so to speak, when it comes to implementing a string. 754 00:34:51,130 --> 00:34:56,620 So string is something that the CS50 course provides to you 755 00:34:56,620 --> 00:35:01,570 in a file called CS50.h. 756 00:35:01,570 --> 00:35:06,355 So just as there's a file called standard I/O-- 757 00:35:06,355 --> 00:35:10,330 where I/O just means input/output, like printing and getting input. 758 00:35:10,330 --> 00:35:16,060 Just as there's a file called stdio.h, in which printf was invented, 759 00:35:16,060 --> 00:35:19,420 all of these other functions that I might use in this program, 760 00:35:19,420 --> 00:35:25,000 like get_string, happen to be stored in a file called CS50.h. 761 00:35:25,000 --> 00:35:28,150 So my problem arose a moment ago when compiling this code, 762 00:35:28,150 --> 00:35:30,640 because the computer had no idea what a string is. 763 00:35:30,640 --> 00:35:34,870 And it has no idea-- we'll see what the function get_string is. 764 00:35:34,870 --> 00:35:37,570 So let me go ahead and recompile this now. 765 00:35:37,570 --> 00:35:46,130 I'm going to go ahead and do Clang -o string string.c and zoom in. 766 00:35:46,130 --> 00:35:46,630 Here we go. 767 00:35:46,630 --> 00:35:47,820 Enter. 768 00:35:47,820 --> 00:35:49,930 OK, progress. 769 00:35:49,930 --> 00:35:51,100 Still a bug. 770 00:35:51,100 --> 00:35:53,230 There's still a mistake, because red can't possibly 771 00:35:53,230 --> 00:35:54,850 mean anything good in this context. 772 00:35:54,850 --> 00:35:56,590 And indeed, it's an error. 773 00:35:56,590 --> 00:35:58,940 But it's many fewer errors. 774 00:35:58,940 --> 00:36:02,080 So there's the last piece of commands that we need to introduce now. 775 00:36:02,080 --> 00:36:04,240 Notice what the error message is saying. 776 00:36:04,240 --> 00:36:07,450 So after I run Clang -o string string.c, there's 777 00:36:07,450 --> 00:36:09,490 still a problem in my function main. 778 00:36:09,490 --> 00:36:11,170 What is the problem? 779 00:36:11,170 --> 00:36:13,480 Undefined reference to get_string. 780 00:36:13,480 --> 00:36:18,490 So it turns out that when using the CS50 library, you have to do two things. 781 00:36:18,490 --> 00:36:21,100 In your source code, you have to tell the computer 782 00:36:21,100 --> 00:36:23,800 to include this file CS50.h, where, again, 783 00:36:23,800 --> 00:36:26,860 functions like get_string and the word string 784 00:36:26,860 --> 00:36:28,870 are actually implemented for you. 785 00:36:28,870 --> 00:36:32,170 But when compiling your code, you need to, somewhat redundantly 786 00:36:32,170 --> 00:36:37,060 but for different reasons, tell the computer to add all of the code 787 00:36:37,060 --> 00:36:40,600 that the CS50 staff wrote to implement get_string and string 788 00:36:40,600 --> 00:36:44,110 and other functions like this. 789 00:36:44,110 --> 00:36:50,530 I'm going to go ahead and write Clang -o string string.c, just like before, 790 00:36:50,530 --> 00:36:54,400 but I need to tell the computer this special instruction 791 00:36:54,400 --> 00:36:56,410 to link it with CS50. 792 00:36:56,410 --> 00:36:59,320 And this will make more sense in just a couple of weeks' time. 793 00:36:59,320 --> 00:37:02,620 But this is just a -l for link and CS50. 794 00:37:02,620 --> 00:37:04,720 And all this tells the computer is this-- 795 00:37:04,720 --> 00:37:10,550 the zeros and ones for my actual program are going to come from string.c right 796 00:37:10,550 --> 00:37:11,050 here. 797 00:37:11,050 --> 00:37:12,400 This is my source code. 798 00:37:12,400 --> 00:37:16,780 But CS50 staff, years ago, also wrote code in C in order 799 00:37:16,780 --> 00:37:19,420 to give you functions like get_string, in order 800 00:37:19,420 --> 00:37:22,390 to give you variables like strings. 801 00:37:22,390 --> 00:37:27,070 The zeros and ones from the CS50 library are stored elsewhere in the cloud. 802 00:37:27,070 --> 00:37:29,920 They need to be linked in together with yours. 803 00:37:29,920 --> 00:37:34,000 So just as your code is in this file, our code is in that file. 804 00:37:34,000 --> 00:37:37,330 And so by telling the computer to include it in your source code 805 00:37:37,330 --> 00:37:40,980 and to link it in this command is just the arcane way of saying, 806 00:37:40,980 --> 00:37:46,930 combine my code with CS50's code into one program that I can actually run. 807 00:37:46,930 --> 00:37:49,180 Now, all of this, frankly is very quickly 808 00:37:49,180 --> 00:37:53,170 becoming very overwhelming, I think, and very unnecessarily complicated. 809 00:37:53,170 --> 00:37:56,200 So there is a better way than this. 810 00:37:56,200 --> 00:38:00,310 It turns out, moving forward, if you would like to compile your code, 811 00:38:00,310 --> 00:38:01,720 you don't have to remember -o. 812 00:38:01,720 --> 00:38:03,935 You don't have to remember -l CS50. 813 00:38:03,935 --> 00:38:07,060 You don't have to remember any of those commands, hopefully just the ideas. 814 00:38:07,060 --> 00:38:12,130 You can instead say, make me a program called string, and be done with it. 815 00:38:12,130 --> 00:38:15,970 All this white output is just automatically generated for you 816 00:38:15,970 --> 00:38:18,610 when you tell the computer, make my program. 817 00:38:18,610 --> 00:38:24,130 And the program make will figure out what command-line arguments to use, 818 00:38:24,130 --> 00:38:26,800 what name to give the file, what libraries 819 00:38:26,800 --> 00:38:29,650 or code that other people have written to link in. 820 00:38:29,650 --> 00:38:32,500 So henceforth, when you want to compile your program, 821 00:38:32,500 --> 00:38:36,460 literally just say make and the name of the program. 822 00:38:36,460 --> 00:38:38,680 But it's not make string.c. 823 00:38:38,680 --> 00:38:41,260 It's make and the name of the program. 824 00:38:41,260 --> 00:38:43,180 Make, this other program, will figure out 825 00:38:43,180 --> 00:38:46,630 that you mean something called string.c. 826 00:38:46,630 --> 00:38:48,910 And I can rewind and do this for hello, too. 827 00:38:48,910 --> 00:38:50,770 Make hello. 828 00:38:50,770 --> 00:38:53,150 Oh, I never fixed the problem from before. 829 00:38:53,150 --> 00:38:56,660 So let me go into hello.c by opening that file. 830 00:38:56,660 --> 00:38:59,740 Let me fix this for posterity. 831 00:38:59,740 --> 00:39:02,110 Save this file, or let the file auto save. 832 00:39:02,110 --> 00:39:03,310 Now do make hello. 833 00:39:03,310 --> 00:39:06,100 And viola, it's done the same thing for me now. 834 00:39:06,100 --> 00:39:06,820 Yeah? 835 00:39:06,820 --> 00:39:09,543 AUDIENCE: Is make like a standard thing [INAUDIBLE].. 836 00:39:09,543 --> 00:39:10,960 DAVID MALAN: Really good question. 837 00:39:10,960 --> 00:39:13,300 Is make a standard thing or CS50 specific? 838 00:39:13,300 --> 00:39:16,280 It is not a CS50 specific thing. 839 00:39:16,280 --> 00:39:19,460 It is a standard tool that exists on Macs and PCs and computers 840 00:39:19,460 --> 00:39:21,410 generally running Unix or Linux. 841 00:39:21,410 --> 00:39:24,020 And indeed, the sandbox tool that we're using 842 00:39:24,020 --> 00:39:26,480 is itself a computer in the cloud, even though it just 843 00:39:26,480 --> 00:39:30,960 has these two windows, tabs up top and the terminal window down below. 844 00:39:30,960 --> 00:39:32,960 When you log in to CS50 Sandbox, you have access 845 00:39:32,960 --> 00:39:36,620 to your own server in the cloud running an operating system called Linux. 846 00:39:36,620 --> 00:39:41,600 And Clang and make and other tools we'll see, like ls and rm, 847 00:39:41,600 --> 00:39:43,700 all exist in that operating system. 848 00:39:43,700 --> 00:39:46,580 They're not at all CS50 specific. 849 00:39:46,580 --> 00:39:47,768 Yeah? 850 00:39:47,768 --> 00:39:51,235 AUDIENCE: With that, so would hello be machine code, not [INAUDIBLE]?? 851 00:39:51,235 --> 00:39:52,110 DAVID MALAN: Correct. 852 00:39:52,110 --> 00:39:53,520 Hello is the machine code. 853 00:39:53,520 --> 00:39:55,756 Hello.c is the source code. 854 00:39:55,756 --> 00:39:57,244 AUDIENCE: So [INAUDIBLE]? 855 00:39:57,244 --> 00:40:00,915 856 00:40:00,915 --> 00:40:01,790 DAVID MALAN: Correct. 857 00:40:01,790 --> 00:40:06,110 Make is a smart program designed to make our lives easier, no pun intended, 858 00:40:06,110 --> 00:40:11,210 whereby if you do make hello, it will look for a file called hello.c. 859 00:40:11,210 --> 00:40:14,450 And if it finds it, it will create the program called hello 860 00:40:14,450 --> 00:40:16,630 from source code to machine code, respectively. 861 00:40:16,630 --> 00:40:17,267 Yeah? 862 00:40:17,267 --> 00:40:18,698 AUDIENCE: [INAUDIBLE]. 863 00:40:18,698 --> 00:40:22,498 864 00:40:22,498 --> 00:40:23,540 DAVID MALAN: Not exactly. 865 00:40:23,540 --> 00:40:27,770 So make is a program that comes with an operating system called Linux, 866 00:40:27,770 --> 00:40:29,150 and it also comes with Mac OS. 867 00:40:29,150 --> 00:40:31,160 And these days, it also comes with Windows. 868 00:40:31,160 --> 00:40:34,040 It is a program that you can run by typing its name, 869 00:40:34,040 --> 00:40:37,147 not that you run by double-clicking an icon. 870 00:40:37,147 --> 00:40:37,730 Good question. 871 00:40:37,730 --> 00:40:38,882 Yeah? 872 00:40:38,882 --> 00:40:39,854 AUDIENCE: [INAUDIBLE]? 873 00:40:39,854 --> 00:40:43,755 874 00:40:43,755 --> 00:40:44,880 DAVID MALAN: Good question. 875 00:40:44,880 --> 00:40:46,610 So does that mean make is stored on your computer 876 00:40:46,610 --> 00:40:47,930 or in the cloud-based computer? 877 00:40:47,930 --> 00:40:49,350 In the cloud-based computer. 878 00:40:49,350 --> 00:40:52,100 So at this point in the semester, and for the first several weeks, 879 00:40:52,100 --> 00:40:55,310 everything we do will be in the cloud in a standardized environment 880 00:40:55,310 --> 00:40:58,670 called CS50 Sandbox and, soon, something called CS50 Lab. 881 00:40:58,670 --> 00:41:02,780 But it's designed to be representative of a standard Linux computer 882 00:41:02,780 --> 00:41:04,210 and also a Mac or PC. 883 00:41:04,210 --> 00:41:05,960 But the software tends to differ somewhat, 884 00:41:05,960 --> 00:41:09,470 so we standardize on Linux, which is a very popular operating system 885 00:41:09,470 --> 00:41:12,140 in the software development world. 886 00:41:12,140 --> 00:41:15,265 All right, so let's take a look at a couple of other equivalencies and then 887 00:41:15,265 --> 00:41:18,015 comparisons and start to write more interesting programs than ones 888 00:41:18,015 --> 00:41:19,220 that just say hello world. 889 00:41:19,220 --> 00:41:22,400 So here, again, is a summary of how you technically 890 00:41:22,400 --> 00:41:25,070 should convert your source code to machine code 891 00:41:25,070 --> 00:41:28,580 by using a program called Clang with a command-line argument, 892 00:41:28,580 --> 00:41:33,322 a special parameter, -o hello, to name the file something else. 893 00:41:33,322 --> 00:41:35,780 And honestly, no one's ever going to remember this command. 894 00:41:35,780 --> 00:41:37,905 And even if you do, it's just very tedious to type. 895 00:41:37,905 --> 00:41:40,250 That's why programs like make exist, which 896 00:41:40,250 --> 00:41:42,142 just automate that exact same process. 897 00:41:42,142 --> 00:41:43,850 But they are still doing the same thing-- 898 00:41:43,850 --> 00:41:46,700 compiling your source code into machine code. 899 00:41:46,700 --> 00:41:48,500 And to run the program thereafter, you say 900 00:41:48,500 --> 00:41:50,920 dot, which just refers to your current folder, 901 00:41:50,920 --> 00:41:54,140 because we'll see that you can have multiple folders on a server, and hello 902 00:41:54,140 --> 00:41:55,510 is the name of the program. 903 00:41:55,510 --> 00:41:58,760 All right, let's take a look at a couple of other types of features of Scratch 904 00:41:58,760 --> 00:42:00,510 and see what it's going to look like in C, 905 00:42:00,510 --> 00:42:04,560 and then we'll start to implement some programs in C more manually. 906 00:42:04,560 --> 00:42:07,130 So consider this example here, which was an example 907 00:42:07,130 --> 00:42:11,450 of what type of feature in Scratch? 908 00:42:11,450 --> 00:42:13,300 This did what for us? 909 00:42:13,300 --> 00:42:14,260 AUDIENCE: Variable. 910 00:42:14,260 --> 00:42:16,000 DAVID MALAN: So this was an example of a variable. 911 00:42:16,000 --> 00:42:18,167 And that variable, in this case, was called counter. 912 00:42:18,167 --> 00:42:21,130 And we initialized it to-- that is, we set it equal to-- zero. 913 00:42:21,130 --> 00:42:24,220 In C, on the right-hand side, if we want to achieve this same result 914 00:42:24,220 --> 00:42:27,190 today onward, you're literally going to say the name of the variable, 915 00:42:27,190 --> 00:42:30,490 like counter, but you can call it anything you want, equals zero. 916 00:42:30,490 --> 00:42:33,198 Because recall that the equal sign is the assignment operator. 917 00:42:33,198 --> 00:42:34,990 So whatever is on the right is going to get 918 00:42:34,990 --> 00:42:37,210 copied into whatever is on the left. 919 00:42:37,210 --> 00:42:41,200 However, that's not quite sufficient, because when you declare a variable 920 00:42:41,200 --> 00:42:44,230 and you say, hey, computer, I need some storage for some value, 921 00:42:44,230 --> 00:42:47,950 you have to tell the computer what the type of that variable is. 922 00:42:47,950 --> 00:42:52,000 We've seen strings are variables that store multiple words. 923 00:42:52,000 --> 00:42:55,000 But in this case, we want to store a number. 924 00:42:55,000 --> 00:42:58,390 And in C, that type of number is called an int or an integer, 925 00:42:58,390 --> 00:43:00,070 but I-N-T for short. 926 00:43:00,070 --> 00:43:02,147 There's one thing missing from this line of code. 927 00:43:02,147 --> 00:43:02,980 AUDIENCE: Semicolon. 928 00:43:02,980 --> 00:43:03,610 DAVID MALAN: Semicolon. 929 00:43:03,610 --> 00:43:04,840 Just finishes the thought. 930 00:43:04,840 --> 00:43:05,830 So what does this do? 931 00:43:05,830 --> 00:43:10,270 Hey, computer, give me a variable whose type is integer, or int. 932 00:43:10,270 --> 00:43:15,280 Call that variable counter, and store the value zero in that variable 933 00:43:15,280 --> 00:43:19,970 by default. So it turns out that we can do other such operations on variables. 934 00:43:19,970 --> 00:43:23,460 For instance, here we have the incrementation feature of Scratch. 935 00:43:23,460 --> 00:43:27,080 Change the counter by one by adding 1 to the variable. 936 00:43:27,080 --> 00:43:28,510 So how do we do this in C? 937 00:43:28,510 --> 00:43:30,800 In C, you would do something like this. 938 00:43:30,800 --> 00:43:35,110 And this is a little paradoxical if you're coming at this from algebra, 939 00:43:35,110 --> 00:43:38,110 because how could counter possibly be equal to counter plus 1? 940 00:43:38,110 --> 00:43:39,560 But it's not equality. 941 00:43:39,560 --> 00:43:41,780 This is assignment from right to left. 942 00:43:41,780 --> 00:43:43,780 So on the left-hand side, you're saying counter. 943 00:43:43,780 --> 00:43:45,190 That's the name of your variable. 944 00:43:45,190 --> 00:43:47,500 On the right-hand side, you're saying counter plus 1, 945 00:43:47,500 --> 00:43:49,390 whatever that arithmetic answer is. 946 00:43:49,390 --> 00:43:53,260 And you're copying counter plus 1 into counter. 947 00:43:53,260 --> 00:43:56,420 I'm still missing something here, which is that semicolon. 948 00:43:56,420 --> 00:44:00,580 But I do not need to say int in this example. 949 00:44:00,580 --> 00:44:05,200 At this point in the story, it is assumed that counter exists 950 00:44:05,200 --> 00:44:08,020 and that I've used a line of code like the previous one 951 00:44:08,020 --> 00:44:10,270 somewhere else in my program. 952 00:44:10,270 --> 00:44:13,330 Because that tells the computer once, give me a variable called counter, 953 00:44:13,330 --> 00:44:14,950 and let me store ints in it. 954 00:44:14,950 --> 00:44:17,110 This line of code assumes that counter exists, 955 00:44:17,110 --> 00:44:20,410 and so we do not specify the word int again. 956 00:44:20,410 --> 00:44:22,060 You specify it just once. 957 00:44:22,060 --> 00:44:24,040 Now, we need the semicolon, as I proposed. 958 00:44:24,040 --> 00:44:26,680 But frankly, this is such a common operation in programming, 959 00:44:26,680 --> 00:44:28,930 as we'll see, to just increment a variable. 960 00:44:28,930 --> 00:44:31,280 Turns out there's other ways to do this. 961 00:44:31,280 --> 00:44:33,520 You can, instead, equivalently say this-- 962 00:44:33,520 --> 00:44:36,250 counter plus equals 1 semicolon. 963 00:44:36,250 --> 00:44:37,800 It is literally the same thing. 964 00:44:37,800 --> 00:44:39,550 And if that's too many keystrokes for you, 965 00:44:39,550 --> 00:44:42,910 you can literally just say counter plus plus semicolon, 966 00:44:42,910 --> 00:44:44,500 and that, too, does the same thing. 967 00:44:44,500 --> 00:44:47,650 This is what's known in programming as syntactic sugar. 968 00:44:47,650 --> 00:44:51,110 It doesn't add any functionality that you couldn't do some other way. 969 00:44:51,110 --> 00:44:53,800 But it does it in a prettier, often more succinct way. 970 00:44:53,800 --> 00:44:56,680 And it's just more common to write lines of code like this. 971 00:44:56,680 --> 00:44:58,430 All right, let's consider another example. 972 00:44:58,430 --> 00:45:01,750 This was called what in Scratch? 973 00:45:01,750 --> 00:45:03,980 Yeah, a condition, a decision that you have to make. 974 00:45:03,980 --> 00:45:06,310 So if something is true, then do this. 975 00:45:06,310 --> 00:45:08,720 In C, we might convert it as follows. 976 00:45:08,720 --> 00:45:11,260 If x less than y in parentheses-- 977 00:45:11,260 --> 00:45:15,300 which isn't quite the angled shape that we have here in green, but in C, 978 00:45:15,300 --> 00:45:16,780 you use parentheses here. 979 00:45:16,780 --> 00:45:20,380 So if x is less than y, open paren, close paren, 980 00:45:20,380 --> 00:45:21,970 then go ahead and do the following. 981 00:45:21,970 --> 00:45:25,720 And just as this yellow or orange puzzle piece kind of looks like it's 982 00:45:25,720 --> 00:45:29,920 hugging the purple puzzle piece, so does this open curly brace 983 00:45:29,920 --> 00:45:32,830 and this close curly brace, so to speak, is kind of there 984 00:45:32,830 --> 00:45:36,050 ready to hug or encapsulate one or more lines of code. 985 00:45:36,050 --> 00:45:37,090 What's the line of code? 986 00:45:37,090 --> 00:45:42,640 It might be something like this-- printf x is less than y backslash n. 987 00:45:42,640 --> 00:45:47,080 So, again, new syntax, but we've seen the curly braces before 988 00:45:47,080 --> 00:45:48,490 in the context of main. 989 00:45:48,490 --> 00:45:52,280 And we've seen parentheses before in the context of inputs. 990 00:45:52,280 --> 00:45:54,520 So this is just kind of a pattern that we'll 991 00:45:54,520 --> 00:45:58,530 start to follow in C whenever we want to do something conditionally. 992 00:45:58,530 --> 00:46:01,000 OK, in Scratch, we saw something like this-- 993 00:46:01,000 --> 00:46:04,300 if x is less than y, then say x is less than y. 994 00:46:04,300 --> 00:46:06,730 Else, conclude that x is not less than y. 995 00:46:06,730 --> 00:46:11,380 In C, it almost looks the same, but you set yourself up with an else block 996 00:46:11,380 --> 00:46:15,010 with two sets of curly braces, sort of two characters ready to hug 997 00:46:15,010 --> 00:46:16,600 the lines of code in between them. 998 00:46:16,600 --> 00:46:19,660 And we can just plug in now, literally, the translations to printf 999 00:46:19,660 --> 00:46:25,060 by saying printf x is less than y or printf x is not less than y. 1000 00:46:25,060 --> 00:46:28,450 Now, notice, there's only two semicolons in this example. 1001 00:46:28,450 --> 00:46:33,430 You generally do not end things like conditions with semicolons. 1002 00:46:33,430 --> 00:46:37,690 You end functions or lines involving functions with semicolons. 1003 00:46:37,690 --> 00:46:39,850 And that's not a hard, fast rule, but you 1004 00:46:39,850 --> 00:46:42,490 don't want lines of code-- you don't want semicolons 1005 00:46:42,490 --> 00:46:43,870 after every line of code. 1006 00:46:43,870 --> 00:46:45,855 You generally want it after some action. 1007 00:46:45,855 --> 00:46:48,730 And you'll start to notice this pattern, even though it's perhaps not 1008 00:46:48,730 --> 00:46:50,560 obvious at first. 1009 00:46:50,560 --> 00:46:52,260 All right, how about this one? 1010 00:46:52,260 --> 00:46:55,090 If, else if, else if. 1011 00:46:55,090 --> 00:46:58,900 Now, notice we're just kind of reusing the if-else if block and then another 1012 00:46:58,900 --> 00:47:00,250 if block down here. 1013 00:47:00,250 --> 00:47:02,500 Turns out in C, it's almost a little easier. 1014 00:47:02,500 --> 00:47:04,120 You can literally just say this-- 1015 00:47:04,120 --> 00:47:07,060 if x is less than y, do this with curly braces. 1016 00:47:07,060 --> 00:47:10,220 Else, if x is greater than y, do this in curly braces. 1017 00:47:10,220 --> 00:47:14,160 Else, if x equals equals y, do this in curly braces. 1018 00:47:14,160 --> 00:47:16,050 And what do you want to do in each case? 1019 00:47:16,050 --> 00:47:20,560 Different printf's based on the say messages that we want to display. 1020 00:47:20,560 --> 00:47:23,220 But there's one curiosity here. 1021 00:47:23,220 --> 00:47:26,550 Almost looks like a typo. 1022 00:47:26,550 --> 00:47:28,278 Yeah, the double equal sign. 1023 00:47:28,278 --> 00:47:29,070 But it's not a bug. 1024 00:47:29,070 --> 00:47:29,940 It's not a mistake. 1025 00:47:29,940 --> 00:47:35,070 Why am I perhaps using double equals here instead of a single equal sign, 1026 00:47:35,070 --> 00:47:36,990 like in Scratch? 1027 00:47:36,990 --> 00:47:37,980 Let me go over here. 1028 00:47:37,980 --> 00:47:38,687 Yeah? 1029 00:47:38,687 --> 00:47:42,335 AUDIENCE: [INAUDIBLE]. 1030 00:47:42,335 --> 00:47:43,210 DAVID MALAN: Exactly. 1031 00:47:43,210 --> 00:47:46,420 I said earlier that the single equals sign is used for assignment from right 1032 00:47:46,420 --> 00:47:47,140 to left. 1033 00:47:47,140 --> 00:47:49,120 And honestly, this is just kind of a human situation, where 1034 00:47:49,120 --> 00:47:50,590 we painted ourselves into a corner. 1035 00:47:50,590 --> 00:47:53,050 We already use the equals sign for assignment. 1036 00:47:53,050 --> 00:47:56,570 Then, presumably, some human realized, oh, shoot, how do we ask the question, 1037 00:47:56,570 --> 00:47:57,808 is this equal to that? 1038 00:47:57,808 --> 00:47:59,350 Well, we've already used that symbol. 1039 00:47:59,350 --> 00:48:01,510 So humans, decades ago, decided, all right, 1040 00:48:01,510 --> 00:48:05,200 we'll solve that problem by just using two equals signs back to back. 1041 00:48:05,200 --> 00:48:07,690 So this is the so-called equality operator. 1042 00:48:07,690 --> 00:48:09,633 A single equals sign is just the assignment. 1043 00:48:09,633 --> 00:48:12,550 This is, hands down, one of the most common mistakes to make early on, 1044 00:48:12,550 --> 00:48:15,730 especially if you use Scratch or other languages beforehand. 1045 00:48:15,730 --> 00:48:18,880 And you just get to develop the muscle memory over time. 1046 00:48:18,880 --> 00:48:22,030 Once you make that mistake a few times, it'll go away. 1047 00:48:22,030 --> 00:48:24,010 All right, but it turns out that this program, 1048 00:48:24,010 --> 00:48:26,530 while arguably correct-- or this code, while correct, 1049 00:48:26,530 --> 00:48:30,340 in that it's going to do this or this or that-- and I do think those 1050 00:48:30,340 --> 00:48:31,960 are the three possible situations. 1051 00:48:31,960 --> 00:48:37,090 If you've got two integers, x and y, x is either less than y, greater than y, 1052 00:48:37,090 --> 00:48:38,530 or equal to y. 1053 00:48:38,530 --> 00:48:42,490 But one of these questions technically doesn't need to be asked. 1054 00:48:42,490 --> 00:48:45,400 There's technically three Boolean expressions here, right-- 1055 00:48:45,400 --> 00:48:49,098 x less than y, x greater than y, x equals equals y. 1056 00:48:49,098 --> 00:48:50,890 A Boolean expression, recall, is a question 1057 00:48:50,890 --> 00:48:56,170 that it has a yes/no answer or a true/false answer or a 1/0 answer. 1058 00:48:56,170 --> 00:48:59,560 But I don't need to ask three questions here, do I? 1059 00:48:59,560 --> 00:49:00,920 I think I saw your hand. 1060 00:49:00,920 --> 00:49:01,654 Why not? 1061 00:49:01,654 --> 00:49:05,920 AUDIENCE: Well, because if x is less than [INAUDIBLE].. 1062 00:49:05,920 --> 00:49:09,975 1063 00:49:09,975 --> 00:49:10,850 DAVID MALAN: Exactly. 1064 00:49:10,850 --> 00:49:14,570 This third question, this Boolean expression, does x equal equal y, 1065 00:49:14,570 --> 00:49:16,700 goes without saying logically. 1066 00:49:16,700 --> 00:49:19,655 Because if x is not less than and it's not greater than, 1067 00:49:19,655 --> 00:49:22,280 if it's just [INAUDIBLE] the only other scenario I can think of 1068 00:49:22,280 --> 00:49:24,020 is that it equals y. 1069 00:49:24,020 --> 00:49:28,550 So we can actually simplify both the Scratch code and the C code 1070 00:49:28,550 --> 00:49:31,978 by just having this else condition down below, as well. 1071 00:49:31,978 --> 00:49:33,770 So we'll talk, over the next several weeks, 1072 00:49:33,770 --> 00:49:36,230 about different qualities of code. 1073 00:49:36,230 --> 00:49:38,480 Correctness, like does it do what it's supposed to do, 1074 00:49:38,480 --> 00:49:42,770 but also the quality of design, like did you write this code as efficiently as 1075 00:49:42,770 --> 00:49:45,530 possible, as quickly as possible, in a way that 1076 00:49:45,530 --> 00:49:49,160 uses the least amount of memory and the least amount of CPU, 1077 00:49:49,160 --> 00:49:50,420 the brains of the computer? 1078 00:49:50,420 --> 00:49:54,047 And this is just an allusion to that kind of capability. 1079 00:49:54,047 --> 00:49:55,880 All right, just a couple of more comparisons 1080 00:49:55,880 --> 00:49:58,070 before we go back to writing some code. 1081 00:49:58,070 --> 00:49:59,397 How about something like this? 1082 00:49:59,397 --> 00:50:02,480 In Scratch, we, of course, called this a loop-- a cycle that happens again 1083 00:50:02,480 --> 00:50:03,740 and again and again. 1084 00:50:03,740 --> 00:50:08,120 And a loop like this can be implemented in C not quite in the same way, 1085 00:50:08,120 --> 00:50:09,080 but like this. 1086 00:50:09,080 --> 00:50:11,480 It turns out the closest word to the word 1087 00:50:11,480 --> 00:50:14,820 forever in Scratch is the word while. 1088 00:50:14,820 --> 00:50:17,900 It kind of suggests the idea of doing something again and again. 1089 00:50:17,900 --> 00:50:20,330 This was the word that humans chose years ago. 1090 00:50:20,330 --> 00:50:22,280 But you don't just say while. 1091 00:50:22,280 --> 00:50:26,090 You have to say not only what you want to do forever, 1092 00:50:26,090 --> 00:50:29,910 but you need to answer a Boolean expression. 1093 00:50:29,910 --> 00:50:32,540 So in C, if you want to implement a loop, 1094 00:50:32,540 --> 00:50:36,090 you need to literally be able to say while something is true. 1095 00:50:36,090 --> 00:50:40,850 You need to ask a question to which the answer is yes or true or one. 1096 00:50:40,850 --> 00:50:42,980 All of those are equivalent to a programmer. 1097 00:50:42,980 --> 00:50:46,130 So what's an example of an expression, a Boolean expression, 1098 00:50:46,130 --> 00:50:49,990 that is always true, if my goal is to do something forever? 1099 00:50:49,990 --> 00:50:51,173 AUDIENCE: Five equals five. 1100 00:50:51,173 --> 00:50:53,340 DAVID MALAN: Is five equal equal to five, all right. 1101 00:50:53,340 --> 00:50:55,220 I could do is four equal equal to four. 1102 00:50:55,220 --> 00:50:56,930 I could do is two greater than one. 1103 00:50:56,930 --> 00:50:59,030 I could do is one less than two. 1104 00:50:59,030 --> 00:51:01,640 I could come up with an infinite number of Boolean expressions 1105 00:51:01,640 --> 00:51:03,800 that just logically are always true. 1106 00:51:03,800 --> 00:51:07,070 But the simplest way is just to say literally true. 1107 00:51:07,070 --> 00:51:09,050 So it's a little hackish, but this is perhaps 1108 00:51:09,050 --> 00:51:12,440 the simplest question you can ask, because true, by definition, 1109 00:51:12,440 --> 00:51:16,520 it turns out, is always true, just as false is always false. 1110 00:51:16,520 --> 00:51:19,310 And so I can literally just say while true in order 1111 00:51:19,310 --> 00:51:24,008 to induce a infinite loop, so to speak, that does something forever. 1112 00:51:24,008 --> 00:51:26,300 All right, let's try another type of looping construct. 1113 00:51:26,300 --> 00:51:28,192 This was a loop that did something 50 times. 1114 00:51:28,192 --> 00:51:30,275 This one, now we have to get a little more clever, 1115 00:51:30,275 --> 00:51:32,360 and we have to kind of wire things up. 1116 00:51:32,360 --> 00:51:35,120 So if I want to do something 50 times, here's one way. 1117 00:51:35,120 --> 00:51:37,850 Why don't I give myself a variable and call it counter. 1118 00:51:37,850 --> 00:51:40,760 But I could call it anything I want and initialize it to zero. 1119 00:51:40,760 --> 00:51:42,980 Then, let me go ahead-- you know what? 1120 00:51:42,980 --> 00:51:44,510 Counter is actually pretty verbose. 1121 00:51:44,510 --> 00:51:46,490 Most programmers, when they're just counting, 1122 00:51:46,490 --> 00:51:49,557 they, by convention, just use the letter i, i for integer. 1123 00:51:49,557 --> 00:51:51,140 But you can call it anything you want. 1124 00:51:51,140 --> 00:51:53,810 So I'm going to call it int i equals zero. 1125 00:51:53,810 --> 00:51:56,990 Then I'm going to go ahead and do the following. 1126 00:51:56,990 --> 00:51:59,840 While the following expression is true, let me just 1127 00:51:59,840 --> 00:52:01,790 ask a question again and again. 1128 00:52:01,790 --> 00:52:06,170 While i is less than 50, let me go ahead and say, hello world. 1129 00:52:06,170 --> 00:52:09,300 So I can just print out, hello world. 1130 00:52:09,300 --> 00:52:12,260 But I'm not quite done sort of building this logic. 1131 00:52:12,260 --> 00:52:14,330 I've initialized a variable to zero. 1132 00:52:14,330 --> 00:52:18,380 I'm going to, again and again, ask the question, is i less than 50? 1133 00:52:18,380 --> 00:52:21,530 But for this to work out logically, what other piece of logic 1134 00:52:21,530 --> 00:52:24,360 do I need to add to the code? 1135 00:52:24,360 --> 00:52:25,916 Yeah? 1136 00:52:25,916 --> 00:52:27,810 AUDIENCE: You have to increment i by one. 1137 00:52:27,810 --> 00:52:29,530 DAVID MALAN: Yeah, I have to increment i, right? 1138 00:52:29,530 --> 00:52:30,770 So even if you don't recall-- 1139 00:52:30,770 --> 00:52:33,130 and that's fine-- the syntax for doing that, you do 1140 00:52:33,130 --> 00:52:35,090 need a line of code like this. 1141 00:52:35,090 --> 00:52:38,710 So that, logically, you're going to do the following-- set i equal to zero, 1142 00:52:38,710 --> 00:52:41,120 and then do the following while i is less than 50. 1143 00:52:41,120 --> 00:52:42,430 Well, is i less than 50? 1144 00:52:42,430 --> 00:52:45,200 Obviously, because 0 is less than 50. 1145 00:52:45,200 --> 00:52:46,660 So you print out, hello world. 1146 00:52:46,660 --> 00:52:48,820 And then, as you propose, we need to increment i. 1147 00:52:48,820 --> 00:52:51,290 So now i equals i plus 1. 1148 00:52:51,290 --> 00:52:53,980 So at this point in the story, i equals 1. 1149 00:52:53,980 --> 00:52:57,430 And now the way the code works, much like our pseudo code last week, 1150 00:52:57,430 --> 00:53:00,220 is you sort of implicitly go back to this line. 1151 00:53:00,220 --> 00:53:04,010 Last week, in pseudocode, I literally said, go back to line 3. 1152 00:53:04,010 --> 00:53:09,460 Here, it happens automatically by nature of how C interprets these lines of code 1153 00:53:09,460 --> 00:53:10,720 in these curly braces. 1154 00:53:10,720 --> 00:53:12,980 And I can actually simplify this as follows. 1155 00:53:12,980 --> 00:53:14,568 I can say i plus plus. 1156 00:53:14,568 --> 00:53:17,110 Now, it's not quite as pretty as Scratch, where you just say, 1157 00:53:17,110 --> 00:53:18,760 repeat the following 50 times. 1158 00:53:18,760 --> 00:53:22,630 But using the principles of last week now translated to C, 1159 00:53:22,630 --> 00:53:24,760 you can kind of wire together your own logic that 1160 00:53:24,760 --> 00:53:27,610 does something any number of times. 1161 00:53:27,610 --> 00:53:30,430 And there's one other way to do this, just so you've seen it here. 1162 00:53:30,430 --> 00:53:33,850 It turns out that a more common way to do something a fixed number of times 1163 00:53:33,850 --> 00:53:36,430 is using a different preposition-- the word for. 1164 00:53:36,430 --> 00:53:38,710 And a for loop looks like this. 1165 00:53:38,710 --> 00:53:43,180 A for loop does something, like print out hello world, again and again, 1166 00:53:43,180 --> 00:53:44,740 but it's even more mechanical. 1167 00:53:44,740 --> 00:53:48,580 But it automates into one line of code the exact same logic 1168 00:53:48,580 --> 00:53:50,020 we just implemented. 1169 00:53:50,020 --> 00:53:52,362 After the word for, you can put parentheses. 1170 00:53:52,362 --> 00:53:54,070 And then inside of those parentheses, you 1171 00:53:54,070 --> 00:53:56,740 can say something like, give me a variable called counter 1172 00:53:56,740 --> 00:53:58,180 and initialize it to zero. 1173 00:53:58,180 --> 00:53:59,410 Or that's a little wordy. 1174 00:53:59,410 --> 00:54:00,760 Let's just use i. 1175 00:54:00,760 --> 00:54:04,540 So that is identical, logically, to what we did a moment ago. 1176 00:54:04,540 --> 00:54:09,190 But the for loop actually takes one, two, three inputs inside 1177 00:54:09,190 --> 00:54:10,000 of its parentheses. 1178 00:54:10,000 --> 00:54:12,520 It's a little funky in terms of its syntax. 1179 00:54:12,520 --> 00:54:15,790 The second input to the for loop is the Boolean expression 1180 00:54:15,790 --> 00:54:20,380 you want to ask again and again and again, so is i less than 50? 1181 00:54:20,380 --> 00:54:22,900 And the last thing that you can do in a for loop 1182 00:54:22,900 --> 00:54:27,410 is this third input, where you can do your update of one or more variables. 1183 00:54:27,410 --> 00:54:32,830 So if I do i equals i plus 1 or, more succinctly, i plus equals 1, 1184 00:54:32,830 --> 00:54:36,700 or even more so tersely, i plus plus, I have now 1185 00:54:36,700 --> 00:54:40,210 whittled down to just four lines of code what I previously 1186 00:54:40,210 --> 00:54:42,440 did in a few more lines of code. 1187 00:54:42,440 --> 00:54:43,660 These are both correct. 1188 00:54:43,660 --> 00:54:45,800 They both do exactly the same thing. 1189 00:54:45,800 --> 00:54:49,580 And even though the for loop is a little non-obvious-- because this is step one, 1190 00:54:49,580 --> 00:54:52,090 this is step two, this is step three, then 1191 00:54:52,090 --> 00:54:54,265 in increments-- it achieves the same result. 1192 00:54:54,265 --> 00:54:56,890 And you'll play with this over time in the next couple of weeks 1193 00:54:56,890 --> 00:54:58,510 when doing something again and again. 1194 00:54:58,510 --> 00:55:02,830 But it's just a more succinct way of achieving that same goal. 1195 00:55:02,830 --> 00:55:06,940 Any questions, then, on while loops or for loops here? 1196 00:55:06,940 --> 00:55:09,990 1197 00:55:09,990 --> 00:55:15,180 All right, so let's look at one final set of definitions. 1198 00:55:15,180 --> 00:55:18,510 It turns out that in C, we have a whole list of data types 1199 00:55:18,510 --> 00:55:20,210 besides just strings and besides ints. 1200 00:55:20,210 --> 00:55:22,260 And we'll see these and use these over time. 1201 00:55:22,260 --> 00:55:26,320 You can have a bool, so to speak, which is literally the value true or false. 1202 00:55:26,320 --> 00:55:29,620 And we use that implicitly earlier when I just said while true. 1203 00:55:29,620 --> 00:55:34,140 You can have a char, or character, which is a single character, not two or more 1204 00:55:34,140 --> 00:55:34,920 or a phrase. 1205 00:55:34,920 --> 00:55:39,390 It's just like the letter Y or N if you're asking the question yes or no. 1206 00:55:39,390 --> 00:55:42,720 You can have an int, of course, which is an integer, a string, which 1207 00:55:42,720 --> 00:55:44,940 is one or more characters inside of double quotes. 1208 00:55:44,940 --> 00:55:47,670 So it's bigger than an individual char, typically. 1209 00:55:47,670 --> 00:55:49,650 And then there's a few other data types-- 1210 00:55:49,650 --> 00:55:50,700 int and long. 1211 00:55:50,700 --> 00:55:52,890 So int is typically a certain size. 1212 00:55:52,890 --> 00:55:55,260 You can only count so high with an int. 1213 00:55:55,260 --> 00:55:58,110 Typically, you can count as high as 4 billion with an int, 1214 00:55:58,110 --> 00:56:00,610 and that's not big enough for certain applications. 1215 00:56:00,610 --> 00:56:03,330 Today's biggest companies like Facebook and Microsoft and Google 1216 00:56:03,330 --> 00:56:06,240 have many more pieces of data than 4 billion. 1217 00:56:06,240 --> 00:56:10,030 So there exist things called long, which actually use more bits. 1218 00:56:10,030 --> 00:56:12,640 They're wider values, so they can count even higher. 1219 00:56:12,640 --> 00:56:14,940 A float is a floating point value, which is 1220 00:56:14,940 --> 00:56:18,390 a fancy way of saying a real number, something that has a decimal point. 1221 00:56:18,390 --> 00:56:23,130 And a double is just a real number that can have even more digits 1222 00:56:23,130 --> 00:56:24,790 after the decimal point. 1223 00:56:24,790 --> 00:56:26,370 So we'll see those before long. 1224 00:56:26,370 --> 00:56:28,950 Well, what other features does the CS50 the library provide? 1225 00:56:28,950 --> 00:56:31,320 It gives you not only the function get_string, 1226 00:56:31,320 --> 00:56:35,567 we'll see a few others like get_int or get_float or get_double or get_char. 1227 00:56:35,567 --> 00:56:37,650 These are all functions that will prompt the human 1228 00:56:37,650 --> 00:56:42,360 with the blinking prompt for certain values that they might want to provide. 1229 00:56:42,360 --> 00:56:44,540 And then for placeholders, let's round this out. 1230 00:56:44,540 --> 00:56:48,090 Printf, recall, had a placeholder for percent s for a string. 1231 00:56:48,090 --> 00:56:50,580 Turns out there's a few other placeholders, as well. 1232 00:56:50,580 --> 00:56:53,520 If you want to plug in an int, we're going to start using percent i. 1233 00:56:53,520 --> 00:56:55,920 If you want to plug in a float-- that is, a real number-- 1234 00:56:55,920 --> 00:56:57,350 you're going to use percent f. 1235 00:56:57,350 --> 00:57:00,390 And there's a couple of other format codes, as well. 1236 00:57:00,390 --> 00:57:02,430 But we've seen just one of those thus far. 1237 00:57:02,430 --> 00:57:05,010 And then in terms of arithmetic operations, 1238 00:57:05,010 --> 00:57:07,290 you can do a lot of mathematics very simply. 1239 00:57:07,290 --> 00:57:09,540 And we'll do just a couple of examples, literally just 1240 00:57:09,540 --> 00:57:13,320 by using the characters that you might be inclined to type on the screen. 1241 00:57:13,320 --> 00:57:18,603 So, in short, suppose that we want to go ahead and write one program of our own. 1242 00:57:18,603 --> 00:57:21,270 We can use any number of these functions-- get_int and get_float 1243 00:57:21,270 --> 00:57:22,240 and get_more. 1244 00:57:22,240 --> 00:57:24,990 But before that, let's go ahead and take a five-minute break here, 1245 00:57:24,990 --> 00:57:26,865 because that was quite the fire hose, indeed. 1246 00:57:26,865 --> 00:57:30,570 Cookies await in the lobby outside, and we'll resume in five minutes. 1247 00:57:30,570 --> 00:57:36,420 So we are back, and now we begin focusing not just on comparisons 1248 00:57:36,420 --> 00:57:39,090 of C with Scratch, but on actually writing 1249 00:57:39,090 --> 00:57:42,960 some code from Scratch but in C. And the goal at hand 1250 00:57:42,960 --> 00:57:46,050 really is to begin to develop the muscle memory via which 1251 00:57:46,050 --> 00:57:49,860 you can start with literally empty files and start to fill it 1252 00:57:49,860 --> 00:57:54,090 with C implementations of your ideas. 1253 00:57:54,090 --> 00:57:57,660 So rest assured that all of the examples we're about to do live 1254 00:57:57,660 --> 00:57:59,670 are already pre-baked online, so you'll be 1255 00:57:59,670 --> 00:58:02,580 able to download all of these examples from the course's website. 1256 00:58:02,580 --> 00:58:05,632 In Brian's super section will you be able to explore them in more detail. 1257 00:58:05,632 --> 00:58:07,590 And later this week will you have opportunities 1258 00:58:07,590 --> 00:58:11,020 hands-on to work on these same types of programs, as well. 1259 00:58:11,020 --> 00:58:16,140 For now, the overarching goal is exposure and concepts and the beginning 1260 00:58:16,140 --> 00:58:18,270 of developing that muscle memory. 1261 00:58:18,270 --> 00:58:21,947 So with that said, let me go ahead and create a new file called int.c, 1262 00:58:21,947 --> 00:58:24,780 the purpose of which is going to be to get an integer from the user, 1263 00:58:24,780 --> 00:58:28,530 much like a bit ago I got a string from the user. 1264 00:58:28,530 --> 00:58:30,630 I'm going to go ahead and, as before, I'm 1265 00:58:30,630 --> 00:58:32,410 going to include some familiar files. 1266 00:58:32,410 --> 00:58:35,012 So I'm going to go ahead and include preemptively CS50.h 1267 00:58:35,012 --> 00:58:37,830 so that have I access to strings and get_string 1268 00:58:37,830 --> 00:58:40,800 and get_int and get_float and other features, as well. 1269 00:58:40,800 --> 00:58:43,890 I'm going to include stdio.h so that I have access to printf 1270 00:58:43,890 --> 00:58:45,780 so I can actually see what we're doing. 1271 00:58:45,780 --> 00:58:48,600 Then I'm going to do this, which again, for today's purposes 1272 00:58:48,600 --> 00:58:51,150 and for a couple of weeks, is just kind of copy/paste. 1273 00:58:51,150 --> 00:58:54,090 This is the equivalent of when green flag clicked, 1274 00:58:54,090 --> 00:58:57,240 but we'll explain, in a couple of weeks, exactly why you're writing int 1275 00:58:57,240 --> 00:58:59,235 and why you're writing void. 1276 00:58:59,235 --> 00:59:01,110 In here, I'm going to do something like this. 1277 00:59:01,110 --> 00:59:03,360 This time, I want to get not a string but an int. 1278 00:59:03,360 --> 00:59:08,320 So let's do in age get get_int, what's your age? 1279 00:59:08,320 --> 00:59:10,860 Now, to be fair, I can probably type that pretty quickly, 1280 00:59:10,860 --> 00:59:13,650 because I have the muscle memory already for programming in C. 1281 00:59:13,650 --> 00:59:16,150 But if we look at it real methodically for a moment, 1282 00:59:16,150 --> 00:59:19,540 this is just another function, get_int, from the CS50 library that's 1283 00:59:19,540 --> 00:59:20,800 going to get an integer. 1284 00:59:20,800 --> 00:59:22,550 This is the prompt that the human is going 1285 00:59:22,550 --> 00:59:25,862 to see with their cursor moving to a new line because of the backslash n. 1286 00:59:25,862 --> 00:59:27,570 And whatever they type in is going to get 1287 00:59:27,570 --> 00:59:31,350 copied from right to left into a variable called age, the type of which, 1288 00:59:31,350 --> 00:59:34,140 so to speak, is int, or integer. 1289 00:59:34,140 --> 00:59:37,717 Now let me go ahead and compute, like, how many days old this person is. 1290 00:59:37,717 --> 00:59:40,050 So if I want to do that, I could do something like this. 1291 00:59:40,050 --> 00:59:41,490 Well, give me an integer. 1292 00:59:41,490 --> 00:59:42,780 Call it days. 1293 00:59:42,780 --> 00:59:45,602 And then just do age times 365. 1294 00:59:45,602 --> 00:59:47,310 I proposed a bit ago that there's a bunch 1295 00:59:47,310 --> 00:59:49,830 of arithmetic operators like plus and minus 1296 00:59:49,830 --> 00:59:53,850 and multiplication and subtraction and even the remainder operator. 1297 00:59:53,850 --> 00:59:58,680 So this line, 7, just says multiply age by 365. 1298 00:59:58,680 --> 01:00:02,800 Copy that value, from right to left, into a new variable called days. 1299 01:00:02,800 --> 01:00:04,800 And now I can go ahead and print this if I want. 1300 01:00:04,800 --> 01:00:09,090 So printf something like, you are at least percent-- 1301 01:00:09,090 --> 01:00:13,620 not s, because it's not a string, but percent i because it's an integer now-- 1302 01:00:13,620 --> 01:00:15,900 days old, backslash n. 1303 01:00:15,900 --> 01:00:18,190 But again, this is a placeholder, so I'm not done yet. 1304 01:00:18,190 --> 01:00:23,580 What do I need to put inside of these parentheses also on line 8? 1305 01:00:23,580 --> 01:00:27,990 Yeah, so comma, days, if that's the value that I want to plug in. 1306 01:00:27,990 --> 01:00:29,377 And I'm missing one more thing. 1307 01:00:29,377 --> 01:00:30,210 AUDIENCE: Semicolon. 1308 01:00:30,210 --> 01:00:32,127 DAVID MALAN: Semicolon at the end of the line. 1309 01:00:32,127 --> 01:00:33,503 Now, hopefully, I got this right. 1310 01:00:33,503 --> 01:00:35,670 But odds are the first time you write your programs, 1311 01:00:35,670 --> 01:00:37,150 you're going to see error messages. 1312 01:00:37,150 --> 01:00:41,040 But let's see, make int is the quickest way now to compile this code. 1313 01:00:41,040 --> 01:00:41,850 Enter. 1314 01:00:41,850 --> 01:00:43,860 All right, the big, long white command is OK. 1315 01:00:43,860 --> 01:00:47,490 So long as you don't see red or yellow or colored output that indicates 1316 01:00:47,490 --> 01:00:49,590 warnings or errors, you should be OK. 1317 01:00:49,590 --> 01:00:53,910 I'm going to clear my screen now so I can just now run this program, ./int. 1318 01:00:53,910 --> 01:00:56,150 And suppose your age is, say, 50. 1319 01:00:56,150 --> 01:01:00,422 Well, you are at least 18,250 days old. 1320 01:01:00,422 --> 01:01:03,630 But let me use this as an opportunity to not just do something correct, which 1321 01:01:03,630 --> 01:01:06,690 I claim this code is, but to just make it better designed. 1322 01:01:06,690 --> 01:01:11,580 It's fine to be storing this value, age, in a variable called age. 1323 01:01:11,580 --> 01:01:13,950 And it's fine to be creating a second variable called 1324 01:01:13,950 --> 01:01:19,300 days, in which my mathematical answer is age times 365. 1325 01:01:19,300 --> 01:01:22,530 But strictly speaking, I don't need that additional line of code. 1326 01:01:22,530 --> 01:01:26,520 I could also just do age times 365 here. 1327 01:01:26,520 --> 01:01:27,660 So C is nice like that. 1328 01:01:27,660 --> 01:01:32,370 You can compose, just like in Scratch, bigger ideas from multiple smaller 1329 01:01:32,370 --> 01:01:33,090 pieces. 1330 01:01:33,090 --> 01:01:35,550 And frankly, if I really want to get crazy, 1331 01:01:35,550 --> 01:01:38,040 notice I can actually highlight that whole function 1332 01:01:38,040 --> 01:01:42,000 call, so to speak, get rid of the age all together, 1333 01:01:42,000 --> 01:01:49,330 and just plug this in here times 365. 1334 01:01:49,330 --> 01:01:53,190 But at this point, we're starting to cross an inflection point. 1335 01:01:53,190 --> 01:01:55,342 Yes, this is correct, because I, strictly speaking, 1336 01:01:55,342 --> 01:01:56,550 don't need a variable, right? 1337 01:01:56,550 --> 01:01:58,020 I can pass-- we saw last week-- 1338 01:01:58,020 --> 01:02:00,870 one function's output as another function's input 1339 01:02:00,870 --> 01:02:02,540 by just nesting them in this way. 1340 01:02:02,540 --> 01:02:05,040 But honestly, now we're at the point where this line of code 1341 01:02:05,040 --> 01:02:08,080 is so relatively long, it's just too hard to read. 1342 01:02:08,080 --> 01:02:10,830 And so this is an example where, for design's sake, you know what? 1343 01:02:10,830 --> 01:02:13,210 The previous version was probably a bit better, 1344 01:02:13,210 --> 01:02:16,950 because I can read the code more top to bottom than left to right. 1345 01:02:16,950 --> 01:02:18,900 But this is a design decision. 1346 01:02:18,900 --> 01:02:21,000 And indeed, you might agree or disagree. 1347 01:02:21,000 --> 01:02:24,420 You might agree or disagree with your teaching fellow, or TF, ultimately. 1348 01:02:24,420 --> 01:02:28,770 These are the kinds of decisions that go into writing good or bad code 1349 01:02:28,770 --> 01:02:30,300 or good or better code. 1350 01:02:30,300 --> 01:02:33,000 Much like in an English essay or in any written language, 1351 01:02:33,000 --> 01:02:36,030 you could argue that one person has written their document better 1352 01:02:36,030 --> 01:02:36,730 than another. 1353 01:02:36,730 --> 01:02:40,140 So we'll begin to appreciate these nuances over time. 1354 01:02:40,140 --> 01:02:41,310 What about float? 1355 01:02:41,310 --> 01:02:45,758 Well, let me go ahead and write another program real quick called float.c. 1356 01:02:45,758 --> 01:02:47,550 And this one is going to use floating point 1357 01:02:47,550 --> 01:02:50,800 values, which again, is just synonymous with real numbers with decimal points. 1358 01:02:50,800 --> 01:02:54,150 Let me go ahead and include CS50.h, include stdio.h. 1359 01:02:54,150 --> 01:02:57,840 1360 01:02:57,840 --> 01:03:02,003 And then int main void and then my open curly braces. 1361 01:03:02,003 --> 01:03:02,920 And now let's do this. 1362 01:03:02,920 --> 01:03:04,680 Let me get the price of something. 1363 01:03:04,680 --> 01:03:10,290 So int price equals get float, what's the price, for instance. 1364 01:03:10,290 --> 01:03:11,450 Semicolon. 1365 01:03:11,450 --> 01:03:13,660 And now let me do something mathematical with this. 1366 01:03:13,660 --> 01:03:18,120 Let me go ahead and say, your total is. 1367 01:03:18,120 --> 01:03:21,330 And now let me just do the total price with tax, for instance. 1368 01:03:21,330 --> 01:03:24,353 In Massachusetts, sales tax is 6.25%. 1369 01:03:24,353 --> 01:03:26,520 So let's just write a little program that does that. 1370 01:03:26,520 --> 01:03:30,540 Your total is-- not percent s, because it's not a string. 1371 01:03:30,540 --> 01:03:33,190 Not percent i, because it's not an integer. 1372 01:03:33,190 --> 01:03:37,990 It should be percent f for float. 1373 01:03:37,990 --> 01:03:39,350 And in fact, I goofed. 1374 01:03:39,350 --> 01:03:41,860 I actually made a mistake here accidentally. 1375 01:03:41,860 --> 01:03:44,997 I don't want to store the price in an int if I'm getting it as a float. 1376 01:03:44,997 --> 01:03:47,080 If I'm getting a real number with a decimal point, 1377 01:03:47,080 --> 01:03:49,310 I probably want to store it as a float, as well. 1378 01:03:49,310 --> 01:03:52,480 So again, different format codes, different placeholders 1379 01:03:52,480 --> 01:03:53,787 for different contexts. 1380 01:03:53,787 --> 01:03:55,120 Now let me go ahead and do this. 1381 01:03:55,120 --> 01:03:56,995 And if I want to plug in the price, I'm going 1382 01:03:56,995 --> 01:04:05,230 to do price times 1.0625, which just mathematically means add 106.25%-- 1383 01:04:05,230 --> 01:04:08,770 or multiply, rather, the price by 106.25% 1384 01:04:08,770 --> 01:04:11,203 so that you actually see the total with tax. 1385 01:04:11,203 --> 01:04:13,120 All right, so let's go ahead and compile this. 1386 01:04:13,120 --> 01:04:14,980 Make float, Enter. 1387 01:04:14,980 --> 01:04:17,320 No error messages, so that's already promising. 1388 01:04:17,320 --> 01:04:18,730 ./float. 1389 01:04:18,730 --> 01:04:19,990 And what's the price? 1390 01:04:19,990 --> 01:04:23,170 How about $100. 1391 01:04:23,170 --> 01:04:25,180 OK, that's a little excessively precise. 1392 01:04:25,180 --> 01:04:29,932 The total price is $106.250000. 1393 01:04:29,932 --> 01:04:33,130 But that's just because the computer, per last week, 1394 01:04:33,130 --> 01:04:35,440 is using some number of bits to store values. 1395 01:04:35,440 --> 01:04:40,120 And the computer happens to be capable of showing this many digits 1396 01:04:40,120 --> 01:04:41,140 after the decimal point. 1397 01:04:41,140 --> 01:04:42,830 But what if you don't want to do that? 1398 01:04:42,830 --> 01:04:46,660 Well, it turns out there's some pretty arcane tricks you can do. 1399 01:04:46,660 --> 01:04:48,910 Instead of doing percent f, I can actually 1400 01:04:48,910 --> 01:04:52,360 do percent dot 2f, which again, you would only 1401 01:04:52,360 --> 01:04:55,570 know from having heard it before looking it up in a book or reference. 1402 01:04:55,570 --> 01:04:59,150 That's going to show me only two digits after the decimal point. 1403 01:04:59,150 --> 01:05:02,560 So if I recompile this code and make float and do ./float, 1404 01:05:02,560 --> 01:05:07,720 now notice if the price is $100, now my total is a little more user friendly-- 1405 01:05:07,720 --> 01:05:09,790 106.25. 1406 01:05:09,790 --> 01:05:11,953 So in short, this is the f in printf. 1407 01:05:11,953 --> 01:05:13,870 Just as you can print something to the screen, 1408 01:05:13,870 --> 01:05:19,380 you can format it as by telling printf to only show so many digits. 1409 01:05:19,380 --> 01:05:20,810 Well, let me try something else. 1410 01:05:20,810 --> 01:05:23,470 Let me go ahead and copy/paste the beginnings of this code, 1411 01:05:23,470 --> 01:05:24,940 just to speed things up. 1412 01:05:24,940 --> 01:05:27,190 So I can implement a program called parity.c. 1413 01:05:27,190 --> 01:05:30,343 So parity is a fancy way of saying is a value even or odd. 1414 01:05:30,343 --> 01:05:32,260 And I've gone ahead and just copied and pasted 1415 01:05:32,260 --> 01:05:35,708 the setup of the code, not the essence of my main function. 1416 01:05:35,708 --> 01:05:38,500 But let's go ahead, in this program, and ask the user for a number. 1417 01:05:38,500 --> 01:05:39,540 We'll call it n. 1418 01:05:39,540 --> 01:05:41,620 And we'll use get_int to get that value. 1419 01:05:41,620 --> 01:05:44,620 And we're just going to say to the human, what's the value of n? 1420 01:05:44,620 --> 01:05:49,540 And I'm just going to say n colon space to just prompt them for some integer. 1421 01:05:49,540 --> 01:05:51,460 Then I'm going to go ahead and ask a question. 1422 01:05:51,460 --> 01:05:55,570 I want to ultimately print out even if the number is even or odd 1423 01:05:55,570 --> 01:05:56,830 if the number is odd. 1424 01:05:56,830 --> 01:06:02,650 So you could imagine doing this the very tedious way, like if n equals equals 1, 1425 01:06:02,650 --> 01:06:06,130 I could go ahead and print out odd. 1426 01:06:06,130 --> 01:06:12,340 And then else if n equals equals 2, I could print out even. 1427 01:06:12,340 --> 01:06:16,190 And then after that, I could support the number three, else if n-- 1428 01:06:16,190 --> 01:06:17,440 I mean, this is stupid, right? 1429 01:06:17,440 --> 01:06:18,880 I could do this forever. 1430 01:06:18,880 --> 01:06:21,632 But it's at least showing a pattern, right? 1431 01:06:21,632 --> 01:06:24,340 One and then three and then five, of course, are going to be odd, 1432 01:06:24,340 --> 01:06:26,990 and two and four and six are going to be even, and so forth. 1433 01:06:26,990 --> 01:06:29,240 Well, it turns out we can compute this mathematically. 1434 01:06:29,240 --> 01:06:30,970 And a very common trick might be this-- 1435 01:06:30,970 --> 01:06:32,500 we can actually do this. 1436 01:06:32,500 --> 01:06:39,070 If n divided by 2 has a remainder of, for instance, 0, 1437 01:06:39,070 --> 01:06:42,850 then I'm going to go ahead and conclude that the number is even. 1438 01:06:42,850 --> 01:06:45,430 So this percent sign is a new construction. 1439 01:06:45,430 --> 01:06:46,090 It's not plus. 1440 01:06:46,090 --> 01:06:47,440 It's not minus. 1441 01:06:47,440 --> 01:06:49,240 It's not multiplication or division. 1442 01:06:49,240 --> 01:06:53,150 This is the remainder operation, or the modulo operation, so to speak. 1443 01:06:53,150 --> 01:06:59,470 And this just means divide n by 2, and if the answer has a remainder of 0, 1444 01:06:59,470 --> 01:07:02,670 you can conclude, by definition of even, that the number is even. 1445 01:07:02,670 --> 01:07:04,100 So I'm going to print that. 1446 01:07:04,100 --> 01:07:08,320 Else-- I could do else if n percent 2 equals equals 1 1447 01:07:08,320 --> 01:07:11,380 and has a remainder of 1, you could imagine saying odd. 1448 01:07:11,380 --> 01:07:15,405 But as you noted earlier, this is not necessary. 1449 01:07:15,405 --> 01:07:18,280 What could I instead do to make the program a little better designed, 1450 01:07:18,280 --> 01:07:19,600 a little more efficient? 1451 01:07:19,600 --> 01:07:20,248 Yeah? 1452 01:07:20,248 --> 01:07:22,440 AUDIENCE: You could just use else and that would be fine. 1453 01:07:22,440 --> 01:07:22,770 DAVID MALAN: Yeah. 1454 01:07:22,770 --> 01:07:24,687 So if we're talking about integers, I can just 1455 01:07:24,687 --> 01:07:28,360 conclude, well, if it's not even, it must be odd, by definition. 1456 01:07:28,360 --> 01:07:30,510 And so here, we can just do even and odd. 1457 01:07:30,510 --> 01:07:33,510 So this program, once run, is going to look like this. 1458 01:07:33,510 --> 01:07:35,400 Make parity. 1459 01:07:35,400 --> 01:07:36,630 Looks like it compiled OK. 1460 01:07:36,630 --> 01:07:38,880 So ./parity is how I run it. 1461 01:07:38,880 --> 01:07:40,290 Let's type the number 50. 1462 01:07:40,290 --> 01:07:40,950 That's even. 1463 01:07:40,950 --> 01:07:42,510 Let's type the number 49. 1464 01:07:42,510 --> 01:07:43,380 That's odd. 1465 01:07:43,380 --> 01:07:44,850 Proof by example. 1466 01:07:44,850 --> 01:07:48,060 This is not very compelling, but I bet this is going to be correct, just 1467 01:07:48,060 --> 01:07:49,480 based on those two examples alone. 1468 01:07:49,480 --> 01:07:49,980 Yeah? 1469 01:07:49,980 --> 01:07:52,938 AUDIENCE: [INAUDIBLE] user did not understand our comment that answer's 1470 01:07:52,938 --> 01:07:54,332 a float or not an integer? 1471 01:07:54,332 --> 01:07:55,790 DAVID MALAN: Sorry, say that again? 1472 01:07:55,790 --> 01:07:58,207 AUDIENCE: What if the user doesn't understand, I'm saying? 1473 01:07:58,207 --> 01:08:02,783 Like I just do something like 1 and 1/2 [INAUDIBLE].. 1474 01:08:02,783 --> 01:08:04,200 DAVID MALAN: Really good question. 1475 01:08:04,200 --> 01:08:06,950 One of the reasons we provide for the first few weeks of the class 1476 01:08:06,950 --> 01:08:10,700 a few functions in the CS50 library like get_string and get_int and get_float 1477 01:08:10,700 --> 01:08:14,960 is that it forces the user to behave as you expect so that your program doesn't 1478 01:08:14,960 --> 01:08:17,149 crash because of unexpected user input. 1479 01:08:17,149 --> 01:08:20,180 So to your point, suppose the user is being a little difficult and says, 1480 01:08:20,180 --> 01:08:22,939 my number is going to be 1.5. 1481 01:08:22,939 --> 01:08:27,854 Get_int is going to prompt them for the same question again and again and again 1482 01:08:27,854 --> 01:08:28,729 until they cooperate. 1483 01:08:28,729 --> 01:08:31,819 If you type in apple, it's going to prompt you again. 1484 01:08:31,819 --> 01:08:34,880 Only once you provide an actual integer will it cooperate. 1485 01:08:34,880 --> 01:08:37,540 So those are among the features you get from the CS50 library, 1486 01:08:37,540 --> 01:08:39,410 just so that we can focus on ideas and not 1487 01:08:39,410 --> 01:08:44,270 on what we would call error checking, or malicious users, in this case. 1488 01:08:44,270 --> 01:08:46,670 All right, so what else can we do once we 1489 01:08:46,670 --> 01:08:49,279 have the ability to express conditions? 1490 01:08:49,279 --> 01:08:52,010 Well, let me go ahead and open one that I brought with me. 1491 01:08:52,010 --> 01:08:54,109 So rather than type all of these from Scratch, 1492 01:08:54,109 --> 01:08:56,618 let me go ahead and open conditions1.c. 1493 01:08:56,618 --> 01:08:58,660 So this is a program that's already been written. 1494 01:08:58,660 --> 01:09:00,920 And it turns out, it's got some other lines in it, 1495 01:09:00,920 --> 01:09:03,643 these grayed-out outlines that begin with slash slash. 1496 01:09:03,643 --> 01:09:05,810 You might not have noticed this, but in Scratch, you 1497 01:09:05,810 --> 01:09:06,979 can have what are called comments. 1498 01:09:06,979 --> 01:09:09,050 They're like little sticky notes that you can add 1499 01:09:09,050 --> 01:09:10,550 that don't do anything functionally. 1500 01:09:10,550 --> 01:09:13,825 It's just like notes to self or notes to your friend or notes to your TF. 1501 01:09:13,825 --> 01:09:15,950 That's what a comment is in a programming language. 1502 01:09:15,950 --> 01:09:19,310 So anything starting with a slash slash is a note to self. 1503 01:09:19,310 --> 01:09:21,873 And it's a reminder to me what this line of code does. 1504 01:09:21,873 --> 01:09:24,040 It's a reminder to your colleagues in the real world 1505 01:09:24,040 --> 01:09:27,380 or your TF in a class to explain to them what this line of code 1506 01:09:27,380 --> 01:09:30,520 is supposed to be doing, even if maybe you have a bug 1507 01:09:30,520 --> 01:09:32,090 and it's not actually doing that. 1508 01:09:32,090 --> 01:09:35,840 So I've begun, in these pre-created examples, to comment my code, 1509 01:09:35,840 --> 01:09:37,580 but the lines are essentially the same. 1510 01:09:37,580 --> 01:09:40,250 Go ahead and give me access to the CS50 library. 1511 01:09:40,250 --> 01:09:43,010 And a library, again, is just a file of code 1512 01:09:43,010 --> 01:09:45,080 that someone else wrote that we're using. 1513 01:09:45,080 --> 01:09:47,960 And give me access to the standard I/O library, which contains 1514 01:09:47,960 --> 01:09:50,430 printf and some other things, as well. 1515 01:09:50,430 --> 01:09:54,170 Notice here, I have x equals get_int in order 1516 01:09:54,170 --> 01:09:56,390 to get one integer from the user called x. 1517 01:09:56,390 --> 01:09:59,840 Now I'm going to ask them for a second integer by just calling it y 1518 01:09:59,840 --> 01:10:01,400 and calling get_int again. 1519 01:10:01,400 --> 01:10:03,840 And now I can do things like compare these values. 1520 01:10:03,840 --> 01:10:07,790 So this is now a complete version of the Scratch-like program 1521 01:10:07,790 --> 01:10:11,450 I pulled up before that allows us to conclude is x less than y, 1522 01:10:11,450 --> 01:10:15,290 greater than y, or, by default, equal to y. 1523 01:10:15,290 --> 01:10:19,080 So the only difference is we saw these lines of code on the screen before. 1524 01:10:19,080 --> 01:10:22,340 Now we see, in context, that, oh, for those lines to work, 1525 01:10:22,340 --> 01:10:25,640 we need to get the integers from the user. 1526 01:10:25,640 --> 01:10:28,520 And we need to have the equivalent of when green flag clicked, 1527 01:10:28,520 --> 01:10:31,115 and we need the equivalent of these includes so that it's 1528 01:10:31,115 --> 01:10:33,575 a complete self-contained program. 1529 01:10:33,575 --> 01:10:35,450 And just to be clear, even though I made this 1530 01:10:35,450 --> 01:10:38,710 in advance, if I wanted to run this program, how could I run it? 1531 01:10:38,710 --> 01:10:41,770 Call conditions.c. 1532 01:10:41,770 --> 01:10:45,030 Yeah, so make conditions first. 1533 01:10:45,030 --> 01:10:45,530 Sorry. 1534 01:10:45,530 --> 01:10:48,140 Oh, this is actually a teachable moment. 1535 01:10:48,140 --> 01:10:49,670 Why did this not work? 1536 01:10:49,670 --> 01:10:54,020 So no rule to make target conditions stop, which is a little emphatic. 1537 01:10:54,020 --> 01:10:55,130 But what does that mean? 1538 01:10:55,130 --> 01:10:58,700 Well, in advance today, what I did was I downloaded into my sandbox 1539 01:10:58,700 --> 01:11:02,630 a folder called src1, S-R-C meaning "source" in programmer speak. 1540 01:11:02,630 --> 01:11:06,140 And I just downloaded this into the sandbox for me. 1541 01:11:06,140 --> 01:11:08,540 Because in that folder are all of the examples 1542 01:11:08,540 --> 01:11:12,050 not only that I wrote in live, but also some others that I brought with me. 1543 01:11:12,050 --> 01:11:15,920 Unfortunately, all of those files are in a folder called src1. 1544 01:11:15,920 --> 01:11:18,920 Now, on your Mac or PC, if you want to open a folder, you do what I did. 1545 01:11:18,920 --> 01:11:22,100 You double-double the icon, and boom, the folder is open. 1546 01:11:22,100 --> 01:11:25,880 But in a terminal window, a text-based environment, you can't do that. 1547 01:11:25,880 --> 01:11:29,840 If I type ls, we'll see all of the files that I've created today-- 1548 01:11:29,840 --> 01:11:32,120 float and hello and int. 1549 01:11:32,120 --> 01:11:34,520 But notice over here, there's a folder. 1550 01:11:34,520 --> 01:11:36,145 And that's what the trailing slash is. 1551 01:11:36,145 --> 01:11:38,270 That's a forward slash that just means, hey, human, 1552 01:11:38,270 --> 01:11:40,250 this is a folder, just so it's obvious. 1553 01:11:40,250 --> 01:11:44,150 Just like the asterisk means here's a machine code that you can run. 1554 01:11:44,150 --> 01:11:47,270 I need to change into that directory, but I can't double-click. 1555 01:11:47,270 --> 01:11:49,700 Nothing's going to happen if I double-click on this text. 1556 01:11:49,700 --> 01:11:53,650 But I can type cd space src1. 1557 01:11:53,650 --> 01:11:55,760 cd means change directory. 1558 01:11:55,760 --> 01:11:57,200 And now I hit Enter. 1559 01:11:57,200 --> 01:11:59,990 And now if I hit ls, notice I see even more files, 1560 01:11:59,990 --> 01:12:03,110 because these are all of the files from the course's website 1561 01:12:03,110 --> 01:12:05,180 that I brought with me today. 1562 01:12:05,180 --> 01:12:08,037 And if you type a command like this, pwd, 1563 01:12:08,037 --> 01:12:10,370 this will reveal even more information about the system, 1564 01:12:10,370 --> 01:12:12,050 but more on this in the weeks to come. 1565 01:12:12,050 --> 01:12:16,160 You're actually inside a src1 folder that's inside of a sandbox folder 1566 01:12:16,160 --> 01:12:17,840 that's inside of a root folder. 1567 01:12:17,840 --> 01:12:21,140 Now, odds are, at some point, you'll get confused as to where you are. 1568 01:12:21,140 --> 01:12:23,150 When in doubt, just type cd. 1569 01:12:23,150 --> 01:12:25,950 That will whisk you away to the default folder where you began, 1570 01:12:25,950 --> 01:12:28,430 no matter where you found yourself to. 1571 01:12:28,430 --> 01:12:30,470 Type ls, and you're back at the beginning. 1572 01:12:30,470 --> 01:12:32,570 So when in doubt, just type cd and Enter, 1573 01:12:32,570 --> 01:12:34,430 and you'll be back at the beginning. 1574 01:12:34,430 --> 01:12:37,610 Well, let me go ahead and open up this program, but run this one first. 1575 01:12:37,610 --> 01:12:40,190 I'm going to go into a program called agree.c. 1576 01:12:40,190 --> 01:12:44,520 I'm going to hide the code for a moment and make agree. 1577 01:12:44,520 --> 01:12:47,360 I did it again, cd src1, Enter. 1578 01:12:47,360 --> 01:12:49,800 Now I can do make agree. 1579 01:12:49,800 --> 01:12:51,500 It seems to have compiled the program. 1580 01:12:51,500 --> 01:12:55,700 And if I do ./agree, this program seems to be asking me a question-- 1581 01:12:55,700 --> 01:12:56,523 do you agree? 1582 01:12:56,523 --> 01:12:58,940 Now, it's not obvious from the program what I should type, 1583 01:12:58,940 --> 01:13:01,220 but my gut tells me, sure, yes. 1584 01:13:01,220 --> 01:13:04,370 So I'm going to go ahead and type y for yes and Enter. 1585 01:13:04,370 --> 01:13:06,050 And it seems to know that I've agreed. 1586 01:13:06,050 --> 01:13:07,490 If I rerun it again-- 1587 01:13:07,490 --> 01:13:11,900 ./agree-- and type n this time, not agreed. 1588 01:13:11,900 --> 01:13:12,650 But you know what? 1589 01:13:12,650 --> 01:13:13,942 It's actually better than that. 1590 01:13:13,942 --> 01:13:18,650 If I do ./agree and maybe do a capital Y, Enter, that also seems to work. 1591 01:13:18,650 --> 01:13:20,130 So how is this happening? 1592 01:13:20,130 --> 01:13:21,770 Well, let me look at the code here. 1593 01:13:21,770 --> 01:13:25,190 The top of the file is almost identical to everything thus far. 1594 01:13:25,190 --> 01:13:27,650 Include those two files, int main void. 1595 01:13:27,650 --> 01:13:30,320 But now I'm using get_char, and I'm storing my answer 1596 01:13:30,320 --> 01:13:33,710 in a variable called c, but I could store it in anything I want. 1597 01:13:33,710 --> 01:13:36,350 And now notice the slightly new syntax. 1598 01:13:36,350 --> 01:13:41,300 What's clearly new about what I'm doing here? 1599 01:13:41,300 --> 01:13:43,910 What symbols jump out? 1600 01:13:43,910 --> 01:13:45,200 Yeah, the vertical bar. 1601 01:13:45,200 --> 01:13:48,020 So this is a way of saying a logical or. 1602 01:13:48,020 --> 01:13:50,630 So in Python and a few other languages these days, you 1603 01:13:50,630 --> 01:13:52,280 might literally write the word "or." 1604 01:13:52,280 --> 01:13:57,500 That doesn't work in C. If you want to ask this question or this question 1605 01:13:57,500 --> 01:14:00,740 and just take either answer as a valid answer, 1606 01:14:00,740 --> 01:14:03,020 you just use two vertical bars, which are typically 1607 01:14:03,020 --> 01:14:05,720 above your Enter key on an American keyboard, at least. 1608 01:14:05,720 --> 01:14:07,760 So two vertical bars means or. 1609 01:14:07,760 --> 01:14:10,640 Two ampersands, it turns out, means and. 1610 01:14:10,640 --> 01:14:13,940 But this is just a way of asking two questions in the same breath 1611 01:14:13,940 --> 01:14:16,800 and accepting either answer as potentially true. 1612 01:14:16,800 --> 01:14:21,650 So if c is capital Y or c is lowercase y, assume that the human has agreed. 1613 01:14:21,650 --> 01:14:26,090 Else, if c equals capital N or lowercase n, assume that they've not agreed. 1614 01:14:26,090 --> 01:14:28,970 And suppose I type in some other letter all together, 1615 01:14:28,970 --> 01:14:32,220 what's the program going to do? 1616 01:14:32,220 --> 01:14:32,720 Say again? 1617 01:14:32,720 --> 01:14:33,740 AUDIENCE: Ask you again. 1618 01:14:33,740 --> 01:14:35,000 DAVID MALAN: It's not going to ask me again, 1619 01:14:35,000 --> 01:14:36,950 because there's no loop here, right? 1620 01:14:36,950 --> 01:14:41,360 There's no evidence of while or for loop. 1621 01:14:41,360 --> 01:14:46,190 And get_char is literally going to get a char, but it doesn't specify what char. 1622 01:14:46,190 --> 01:14:50,900 What happens if I don't type y or n, capital or lowercase? 1623 01:14:50,900 --> 01:14:52,103 It seems nothing. 1624 01:14:52,103 --> 01:14:54,020 Just nothing's going to happen, and that's OK. 1625 01:14:54,020 --> 01:14:56,210 Your program doesn't have to print something. 1626 01:14:56,210 --> 01:15:01,060 And indeed, if I run this again and ./agree x. 1627 01:15:01,060 --> 01:15:02,130 It doesn't do anything. 1628 01:15:02,130 --> 01:15:03,860 So I've neither agreed nor disagreed. 1629 01:15:03,860 --> 01:15:07,910 However, you could imagine writing a loop that somehow forces the human 1630 01:15:07,910 --> 01:15:10,117 to cooperate in some way or another. 1631 01:15:10,117 --> 01:15:12,200 All right, let's do a different example, this time 1632 01:15:12,200 --> 01:15:15,800 based on an idea from last time-- that of abstraction. 1633 01:15:15,800 --> 01:15:18,980 Recall that in Scratch, there was no puzzle piece for coughing, 1634 01:15:18,980 --> 01:15:21,620 to make the cat [COUGHS] on the screen. 1635 01:15:21,620 --> 01:15:25,070 And so we implemented this, really, with our own custom puzzle piece, 1636 01:15:25,070 --> 01:15:25,850 ultimately. 1637 01:15:25,850 --> 01:15:30,080 So let me create a program that's called cough0.c. 1638 01:15:30,080 --> 01:15:33,140 That's a generous definition of inactivity, but OK. 1639 01:15:33,140 --> 01:15:35,960 Let me reload the screen. 1640 01:15:35,960 --> 01:15:38,420 When in doubt in CS50, as in life, reload. 1641 01:15:38,420 --> 01:15:39,920 That will probably fix. 1642 01:15:39,920 --> 01:15:43,248 Unfortunately, with programming and the internet, that sometimes happens. 1643 01:15:43,248 --> 01:15:45,290 So in a moment, what I'm going to go ahead and do 1644 01:15:45,290 --> 01:15:49,730 is translate that idea from Scratch of implementing the notion of coughing. 1645 01:15:49,730 --> 01:15:54,060 But instead of the say block, I'm going to use the printf block, or the printf 1646 01:15:54,060 --> 01:15:54,990 function. 1647 01:15:54,990 --> 01:15:58,700 And then I'm going to go ahead and design this version of code slightly 1648 01:15:58,700 --> 01:16:01,920 better and slightly better each time. 1649 01:16:01,920 --> 01:16:07,010 So I'm going to go ahead and open up a file cough0.c. 1650 01:16:07,010 --> 01:16:11,900 And I'm going to go ahead and include, let's say, stdio.h. 1651 01:16:11,900 --> 01:16:16,180 I'm going to go ahead and do int main void, which again, is just our boiler 1652 01:16:16,180 --> 01:16:18,080 plate or copy/paste for today. 1653 01:16:18,080 --> 01:16:21,080 I'm going to go ahead, then, and say printf, quote unquote, 1654 01:16:21,080 --> 01:16:22,580 cough with a new line. 1655 01:16:22,580 --> 01:16:25,050 And recall, in Scratch I wanted this to happen three times, 1656 01:16:25,050 --> 01:16:27,300 so I'm going to do it like this-- cough, cough, cough. 1657 01:16:27,300 --> 01:16:31,520 All right, I'm going to give myself a terminal window here at the bottom 1658 01:16:31,520 --> 01:16:35,330 so that I can now go ahead and say make cough0, Enter. 1659 01:16:35,330 --> 01:16:39,470 Nothing bad seems to happen. ./cough0 and cough, cough, cough. 1660 01:16:39,470 --> 01:16:42,950 So last week, I claimed that, eh, you can design this better, right? 1661 01:16:42,950 --> 01:16:44,960 Anytime you're copying and pasting, odds are 1662 01:16:44,960 --> 01:16:46,850 you should start to resist that temptation, 1663 01:16:46,850 --> 01:16:49,933 because it's going to lead to messy code, longer code than it needs to be. 1664 01:16:49,933 --> 01:16:52,133 What's the solution to this problem from last week? 1665 01:16:52,133 --> 01:16:52,920 AUDIENCE: A loop. 1666 01:16:52,920 --> 01:16:54,390 DAVID MALAN: Yeah, a loop, a for loop. 1667 01:16:54,390 --> 01:16:55,682 So let me go ahead and do that. 1668 01:16:55,682 --> 01:16:57,693 Let me create another version, cough1.c. 1669 01:16:57,693 --> 01:17:00,360 And I'm going to copy/paste this code, just as a starting point. 1670 01:17:00,360 --> 01:17:02,400 But now I'm going to go ahead and clean it up. 1671 01:17:02,400 --> 01:17:04,960 So I'm going to go ahead and instead do a for loop. 1672 01:17:04,960 --> 01:17:07,460 And I don't quite remember what goes in the parentheses yet, 1673 01:17:07,460 --> 01:17:08,690 but we'll come back to that. 1674 01:17:08,690 --> 01:17:12,530 I do know that what I want to do some number of times is just cough. 1675 01:17:12,530 --> 01:17:15,333 So the only question at hand is, what was the syntax here? 1676 01:17:15,333 --> 01:17:17,250 Well, we can write this in any number of ways, 1677 01:17:17,250 --> 01:17:18,890 and we could even use a while loop. 1678 01:17:18,890 --> 01:17:22,520 But I do recall saying int and then the name of a variable. 1679 01:17:22,520 --> 01:17:24,960 I could say counter, or I could just say i 1680 01:17:24,960 --> 01:17:28,970 to keep it succinct, equals 0 by default. 1681 01:17:28,970 --> 01:17:32,540 I could do this so long as i is less than 3, for instance. 1682 01:17:32,540 --> 01:17:38,070 And then on each iteration, I can say i equals i plus 1 or, more succinctly, 1683 01:17:38,070 --> 01:17:39,710 i plus plus. 1684 01:17:39,710 --> 01:17:41,223 So, again, it's a lot of new syntax. 1685 01:17:41,223 --> 01:17:43,140 And there's semicolons all over the place now. 1686 01:17:43,140 --> 01:17:46,700 But if I go ahead now and do make cough1, 1687 01:17:46,700 --> 01:17:48,410 nothing bad seems to have happened. 1688 01:17:48,410 --> 01:17:51,020 ./cough1, cough, cough, cough. 1689 01:17:51,020 --> 01:17:53,180 It seems to be slightly better designed. 1690 01:17:53,180 --> 01:17:55,460 Unfortunately, there is this paradigm in programming 1691 01:17:55,460 --> 01:18:00,110 where humans, programmers, tend to think or tend to count starting from zero. 1692 01:18:00,110 --> 01:18:02,240 However, if you don't like that, at least early on, 1693 01:18:02,240 --> 01:18:05,210 there's nothing stopping me from initializing i to 1 1694 01:18:05,210 --> 01:18:08,420 and then doing i is less than 4 or, even more explicitly, 1695 01:18:08,420 --> 01:18:10,655 i is less than or equal to 3. 1696 01:18:10,655 --> 01:18:13,280 There's no less than or equal sign on your keyboard, typically, 1697 01:18:13,280 --> 01:18:17,390 so you can mimic it by doing a less than and then an equal sign, two characters. 1698 01:18:17,390 --> 01:18:18,800 This is logically the same. 1699 01:18:18,800 --> 01:18:20,240 Set i equal to 1. 1700 01:18:20,240 --> 01:18:23,450 Then go ahead and print cough, and then make sure to increment it. 1701 01:18:23,450 --> 01:18:26,150 And then make sure it's still less than 3, and 2 is. 1702 01:18:26,150 --> 01:18:28,850 Make sure it's still less than or equal to 3, and it still is. 1703 01:18:28,850 --> 01:18:31,620 So that 2 is, logically, going to have the same effect. 1704 01:18:31,620 --> 01:18:36,590 However, in the interests of convention, this would be the more common approach. 1705 01:18:36,590 --> 01:18:42,768 Do this while i equals 0 and then 1 and then 2, for a total of 3 times. 1706 01:18:42,768 --> 01:18:44,810 All right, but recall what we did last time, too, 1707 01:18:44,810 --> 01:18:47,540 is that if I'm writing a lot of code, for some reason, that 1708 01:18:47,540 --> 01:18:51,800 involves programs coughing, it would be nice to give myself my own custom 1709 01:18:51,800 --> 01:18:52,920 function. 1710 01:18:52,920 --> 01:18:54,450 So let me go ahead and do that. 1711 01:18:54,450 --> 01:18:58,430 Let me go ahead and write my own first brand-new function. 1712 01:18:58,430 --> 01:19:00,570 And I'm going to do this as follows. 1713 01:19:00,570 --> 01:19:04,220 I'm going to go ahead and type void, then the name of the function I want. 1714 01:19:04,220 --> 01:19:07,160 Then I'm going to say void here, for reasons we'll come back to. 1715 01:19:07,160 --> 01:19:10,160 And then I'm going to literally just go ahead and say cough. 1716 01:19:10,160 --> 01:19:14,120 So there are functions we've used today-- printf, get_int, get_string, 1717 01:19:14,120 --> 01:19:18,650 get_float-- none of which we showed you the implementation of, because people, 1718 01:19:18,650 --> 01:19:21,270 years ago, both in the staff and in the real world, 1719 01:19:21,270 --> 01:19:23,000 implemented those functions for us. 1720 01:19:23,000 --> 01:19:26,270 You, too, can implement your own custom functions or, in Scratch, 1721 01:19:26,270 --> 01:19:29,690 those puzzle pieces that we made in those pink blocks. 1722 01:19:29,690 --> 01:19:31,940 So if you want to make your own function whose name is 1723 01:19:31,940 --> 01:19:35,960 cough, whose purpose in life is to say cough on the screen, 1724 01:19:35,960 --> 01:19:37,010 this is the syntax. 1725 01:19:37,010 --> 01:19:40,880 For today's purposes, you say void and void here, but the name of the function 1726 01:19:40,880 --> 01:19:41,690 is important. 1727 01:19:41,690 --> 01:19:43,040 I'll call it cough. 1728 01:19:43,040 --> 01:19:45,000 And then I can use it as follows. 1729 01:19:45,000 --> 01:19:50,750 I can say cough, cough, cough now in order to cough three times. 1730 01:19:50,750 --> 01:19:53,150 Or again, we already decided that was bad design. 1731 01:19:53,150 --> 01:19:57,770 For int i get 0, i less than 3, i plus plus. 1732 01:19:57,770 --> 01:20:00,230 I can now do something like cough. 1733 01:20:00,230 --> 01:20:03,290 And so now, again, out of sight, out of mind. 1734 01:20:03,290 --> 01:20:07,460 I don't need to know or care how the cough function is implemented. 1735 01:20:07,460 --> 01:20:10,850 I can care that my code just tells the computer what to do. 1736 01:20:10,850 --> 01:20:15,260 For i from 0 on up to 3, cough, cough, cough. 1737 01:20:15,260 --> 01:20:16,480 And this is an abstraction. 1738 01:20:16,480 --> 01:20:18,950 I don't care that cough is implemented with printf. 1739 01:20:18,950 --> 01:20:22,070 I just care that there's a function called cough. 1740 01:20:22,070 --> 01:20:25,490 So let me go ahead and run this and see what happens. 1741 01:20:25,490 --> 01:20:28,710 Let me scroll down to the bottom, do make cough1. 1742 01:20:28,710 --> 01:20:29,750 OK, amazing. 1743 01:20:29,750 --> 01:20:30,830 No red errors now. 1744 01:20:30,830 --> 01:20:34,550 So ./cough1, cough, cough, cough. 1745 01:20:34,550 --> 01:20:38,553 But notice that this is a little bad design, I would claim, 1746 01:20:38,553 --> 01:20:39,470 because you know what? 1747 01:20:39,470 --> 01:20:42,890 If you keep writing custom functions up here, up here, up here, 1748 01:20:42,890 --> 01:20:46,145 the main part of your program is going to get pushed pretty far down. 1749 01:20:46,145 --> 01:20:48,770 And it's a human convention to generally have the main function 1750 01:20:48,770 --> 01:20:49,790 at the top of your file. 1751 01:20:49,790 --> 01:20:50,790 Seems pretty reasonable. 1752 01:20:50,790 --> 01:20:53,420 So you open the file, boom, the main function's right there. 1753 01:20:53,420 --> 01:20:54,620 So let's keep it there. 1754 01:20:54,620 --> 01:20:58,448 So let me actually move the cough function down below just so 1755 01:20:58,448 --> 01:21:01,490 that, again, the first thing I see is indeed the main part of my program. 1756 01:21:01,490 --> 01:21:03,020 And wherever cough is, I don't care. 1757 01:21:03,020 --> 01:21:05,090 That was the whole point of implementing it. 1758 01:21:05,090 --> 01:21:08,990 Let me go now to my terminal window and do make cough1. 1759 01:21:08,990 --> 01:21:12,500 Oh my god, some red errors flew by. 1760 01:21:12,500 --> 01:21:14,030 What's wrong here? 1761 01:21:14,030 --> 01:21:19,130 So error, implicit declaration of function cough is invalid in C '99. 1762 01:21:19,130 --> 01:21:22,610 C '99 means the version of C invented in 1999. 1763 01:21:22,610 --> 01:21:23,690 What's going on? 1764 01:21:23,690 --> 01:21:25,100 Implicit declaration? 1765 01:21:25,100 --> 01:21:27,500 So this is where C differs from Scratch again. 1766 01:21:27,500 --> 01:21:29,840 C is old, and it's kind of dumb. 1767 01:21:29,840 --> 01:21:32,840 It only knows what you tell it, and it only 1768 01:21:32,840 --> 01:21:36,290 knows what you tell it in order top to bottom, left to right. 1769 01:21:36,290 --> 01:21:41,480 So in this program right now, I have included stdio.h, as before. 1770 01:21:41,480 --> 01:21:43,700 I've included the beginning of main. 1771 01:21:43,700 --> 01:21:45,480 I've started a for loop. 1772 01:21:45,480 --> 01:21:48,320 And then I'm using a function that's apparently called cough. 1773 01:21:48,320 --> 01:21:52,640 However, where is cough now actually implemented? 1774 01:21:52,640 --> 01:21:54,880 Way down here on line 11 onwards. 1775 01:21:54,880 --> 01:21:56,600 C is not that smart. 1776 01:21:56,600 --> 01:21:59,510 It's not going to presume to look later in your file to see, 1777 01:21:59,510 --> 01:22:02,150 maybe they put the function cough down below. 1778 01:22:02,150 --> 01:22:04,070 It's only going to do what you tell it. 1779 01:22:04,070 --> 01:22:05,503 So there's a fix for this. 1780 01:22:05,503 --> 01:22:07,670 You can either do what I did initially, which is put 1781 01:22:07,670 --> 01:22:09,268 all of your custom functions up top. 1782 01:22:09,268 --> 01:22:11,810 But that's kind of a vicious cycle, because you can't forever 1783 01:22:11,810 --> 01:22:13,107 put the new functions up top. 1784 01:22:13,107 --> 01:22:15,690 Eventually, you're going to run into some kind of constraints. 1785 01:22:15,690 --> 01:22:19,070 And my god, you want the main function, by convention, to be up top. 1786 01:22:19,070 --> 01:22:20,880 So there's another solution here. 1787 01:22:20,880 --> 01:22:23,900 And this is the only time where copy/paste is compelling. 1788 01:22:23,900 --> 01:22:29,210 You literally copy the first line of your function's code on line 11 there. 1789 01:22:29,210 --> 01:22:33,660 And you go ahead and paste it at the top of your file with a semicolon. 1790 01:22:33,660 --> 01:22:38,113 So this is a way of sort of tricking C into, oh, you have seen cough before. 1791 01:22:38,113 --> 01:22:40,530 You haven't seen all of it, but you've seen enough of it-- 1792 01:22:40,530 --> 01:22:41,720 you've seen its name-- 1793 01:22:41,720 --> 01:22:45,870 to now tolerate its appearance in my main function. 1794 01:22:45,870 --> 01:22:49,130 So let me go ahead and recompile this code. 1795 01:22:49,130 --> 01:22:51,770 I'm going to go ahead and run make cough1 enter. 1796 01:22:51,770 --> 01:22:53,510 OK, now it compiled. 1797 01:22:53,510 --> 01:22:59,370 ./cough1, and viola, we're back in business there. 1798 01:22:59,370 --> 01:23:00,740 But let me make one refinement. 1799 01:23:00,740 --> 01:23:05,810 And I'm going to jump ahead to what I called in the online examples cough3.c. 1800 01:23:05,810 --> 01:23:08,600 It turns out your own custom functions can take input. 1801 01:23:08,600 --> 01:23:11,610 This word void means that it takes no input. 1802 01:23:11,610 --> 01:23:15,938 And this word void means it returns no value, like get_int and get_string hand 1803 01:23:15,938 --> 01:23:16,730 you back something. 1804 01:23:16,730 --> 01:23:18,647 That's not applicable now, but we'll come back 1805 01:23:18,647 --> 01:23:20,450 to that in a week or two's time. 1806 01:23:20,450 --> 01:23:24,770 Suppose that you wanted to make the cough function more versatile 1807 01:23:24,770 --> 01:23:28,190 such that it will cough any number of times for you. 1808 01:23:28,190 --> 01:23:29,660 You know what you can do, is this. 1809 01:23:29,660 --> 01:23:34,670 You can change the input to cough function to be some value like n, 1810 01:23:34,670 --> 01:23:38,840 and you can then do something like this-- for int i get 0. 1811 01:23:38,840 --> 01:23:43,730 i is less than n, so not hardcoded anymore. i plus plus. 1812 01:23:43,730 --> 01:23:48,650 And then inside of your curly braces, you can print this cough line. 1813 01:23:48,650 --> 01:23:52,520 So now, notice, cough has been parameterized. 1814 01:23:52,520 --> 01:23:55,430 It now takes input of integer called n, and it 1815 01:23:55,430 --> 01:23:58,220 uses that input, n, just like you could have done 1816 01:23:58,220 --> 01:24:00,740 in Scratch, to do something n times-- 1817 01:24:00,740 --> 01:24:04,010 not once, not three times, but a variable number of times. 1818 01:24:04,010 --> 01:24:06,360 I have to change my first line here. 1819 01:24:06,360 --> 01:24:07,520 This is called a prototype. 1820 01:24:07,520 --> 01:24:09,860 This one-liner is what's called a prototype, 1821 01:24:09,860 --> 01:24:12,140 and it's just copy/paste from your actual function. 1822 01:24:12,140 --> 01:24:13,700 But now notice what I can do. 1823 01:24:13,700 --> 01:24:16,550 My main function, again, is the essence of my program. 1824 01:24:16,550 --> 01:24:19,190 It's a little convoluted right now. 1825 01:24:19,190 --> 01:24:23,150 Wouldn't it be nicer if I could just say cough three times? 1826 01:24:23,150 --> 01:24:28,040 And indeed, now I don't need to know or care how coughing is implemented. 1827 01:24:28,040 --> 01:24:30,950 That's a well-designed program, arguably. 1828 01:24:30,950 --> 01:24:32,300 It's one line of code. 1829 01:24:32,300 --> 01:24:33,137 It's descriptive. 1830 01:24:33,137 --> 01:24:33,720 It says cough. 1831 01:24:33,720 --> 01:24:35,990 It takes an input, which means it costs three times. 1832 01:24:35,990 --> 01:24:38,823 And what's down below in the file, though I could certainly bring it 1833 01:24:38,823 --> 01:24:40,770 back up, is just what a computer scientist 1834 01:24:40,770 --> 01:24:43,250 would call an implementation detail. 1835 01:24:43,250 --> 01:24:45,620 Someone cares how you implement coughing, 1836 01:24:45,620 --> 01:24:48,200 but you don't have to care how you implement coughing. 1837 01:24:48,200 --> 01:24:50,530 You don't have to how we get integers. 1838 01:24:50,530 --> 01:24:52,930 You don't have to care about how you printf. 1839 01:24:52,930 --> 01:24:56,140 You just care that someone else has implemented that functionality 1840 01:24:56,140 --> 01:25:00,280 so you can stand on their shoulders and build more interesting programs that 1841 01:25:00,280 --> 01:25:03,310 are actually interesting to you. 1842 01:25:03,310 --> 01:25:06,235 Let me go ahead and open up an example that builds on this same idea. 1843 01:25:06,235 --> 01:25:08,740 1844 01:25:08,740 --> 01:25:14,030 In, let's see, positive.c, we have this example here, 1845 01:25:14,030 --> 01:25:16,040 which makes this all the more clear. 1846 01:25:16,040 --> 01:25:20,100 So here's a program that uses our two libraries, CS50 in standard I/O. 1847 01:25:20,100 --> 01:25:22,330 It turns out that the CS50 library does not 1848 01:25:22,330 --> 01:25:24,730 come with a function called get_positive_int. 1849 01:25:24,730 --> 01:25:25,772 It comes with get_int. 1850 01:25:25,772 --> 01:25:27,730 And you could imagine programs where you really 1851 01:25:27,730 --> 01:25:31,450 want a positive integer from the human, because negative numbers for a game 1852 01:25:31,450 --> 01:25:33,820 or for some program just would make no sense. 1853 01:25:33,820 --> 01:25:35,380 So how can we implement that? 1854 01:25:35,380 --> 01:25:38,350 Well, it would be nice to create it so that you can simply 1855 01:25:38,350 --> 01:25:40,930 write a two-line program like this where you call 1856 01:25:40,930 --> 01:25:42,820 a function called get_positive_int. 1857 01:25:42,820 --> 01:25:46,720 And if I scroll down, notice there's actually a new feature 1858 01:25:46,720 --> 01:25:49,810 here that we've not seen yet, but it's an interesting example 1859 01:25:49,810 --> 01:25:52,600 of another feature of C. What I've highlighted here 1860 01:25:52,600 --> 01:25:56,350 between lines 15 and 24 is this logic. 1861 01:25:56,350 --> 01:25:58,510 Here's a function called get_positive_int. 1862 01:25:58,510 --> 01:26:01,690 It takes no inputs, so I don't have to pass anything in parentheses. 1863 01:26:01,690 --> 01:26:03,850 I just want to get any old positive int. 1864 01:26:03,850 --> 01:26:06,670 But I do want this function to hand me back something, 1865 01:26:06,670 --> 01:26:09,850 just like get_int handed me back a value that I could put in a variable, 1866 01:26:09,850 --> 01:26:11,170 just like get_string does. 1867 01:26:11,170 --> 01:26:13,030 So this is not void. 1868 01:26:13,030 --> 01:26:13,990 This is int. 1869 01:26:13,990 --> 01:26:17,290 So this word to the left of a function is the type of its output. 1870 01:26:17,290 --> 01:26:20,920 This word in parentheses is the type of its input, if any. 1871 01:26:20,920 --> 01:26:24,640 And if there is nothing, you just say void in either or both place. 1872 01:26:24,640 --> 01:26:26,190 Now, here's a curiosity-- 1873 01:26:26,190 --> 01:26:30,280 on line 17, we've not seen this before, but this is just a hint to the computer 1874 01:26:30,280 --> 01:26:32,425 saying give me a variable called n. 1875 01:26:32,425 --> 01:26:34,300 I'm not sure what I'm going to put in it yet. 1876 01:26:34,300 --> 01:26:36,580 So you literally just say int n semicolon. 1877 01:26:36,580 --> 01:26:38,405 You don't need to assign it anything yet. 1878 01:26:38,405 --> 01:26:40,030 It has what we'll call a garbage value. 1879 01:26:40,030 --> 01:26:42,322 You have no idea what's in it, but that doesn't matter. 1880 01:26:42,322 --> 01:26:43,730 You'll put something in it later. 1881 01:26:43,730 --> 01:26:45,820 Then there's this loop, which we haven't seen yet, 1882 01:26:45,820 --> 01:26:47,800 but in C, it's called a do-while loop. 1883 01:26:47,800 --> 01:26:52,120 It literally says do the following while this Boolean expression is true. 1884 01:26:52,120 --> 01:26:53,320 So what do I want to do? 1885 01:26:53,320 --> 01:26:55,330 I want to get an int from the user, prompting 1886 01:26:55,330 --> 01:26:58,540 the human for a positive integer, and store it in n. 1887 01:26:58,540 --> 01:27:03,010 However, I want to keep doing this while n is less than 1. 1888 01:27:03,010 --> 01:27:06,370 Because if the human types in 0 or negative 1 or negative 50 1889 01:27:06,370 --> 01:27:12,040 or anything non-positive, I do want to prompt them again and again and again. 1890 01:27:12,040 --> 01:27:14,530 So a do-while loop is kind of neat, because it 1891 01:27:14,530 --> 01:27:17,090 will do this first thing at least once. 1892 01:27:17,090 --> 01:27:20,200 Then it will check the condition and potentially do it again 1893 01:27:20,200 --> 01:27:22,450 if the human has not cooperated. 1894 01:27:22,450 --> 01:27:25,900 A while loop, if you think back, actually checked the condition first. 1895 01:27:25,900 --> 01:27:29,590 It was while some Boolean expression is true, do the following. 1896 01:27:29,590 --> 01:27:34,210 This one gives you one such iteration, one pass for free, 1897 01:27:34,210 --> 01:27:35,767 and then it checks the condition. 1898 01:27:35,767 --> 01:27:37,600 So it's just a different way of programming, 1899 01:27:37,600 --> 01:27:40,090 but we could do everything we've done thus far using 1900 01:27:40,090 --> 01:27:46,550 while loops or even for loops, as well. 1901 01:27:46,550 --> 01:27:50,080 All right, well let's go ahead now and make this a little more user friendly. 1902 01:27:50,080 --> 01:27:54,790 Let me go ahead and pull up some examples here of some screens that 1903 01:27:54,790 --> 01:27:56,060 might look familiar. 1904 01:27:56,060 --> 01:27:58,488 So if I go ahead and open up, for instance, 1905 01:27:58,488 --> 01:28:00,280 this slide here, you might recall this game 1906 01:28:00,280 --> 01:28:04,000 from yesteryear, Super Mario Brothers 1, from the very original Nintendo. 1907 01:28:04,000 --> 01:28:07,510 And there's some screens in that game that look a little something like this. 1908 01:28:07,510 --> 01:28:09,100 For instance, these are little bricks in the air 1909 01:28:09,100 --> 01:28:11,200 that if Mario or Luigi hits their head up against, 1910 01:28:11,200 --> 01:28:13,450 like a coin or something else pops out. 1911 01:28:13,450 --> 01:28:16,810 But this is kind of a nice idea, because it lends itself to actually doing 1912 01:28:16,810 --> 01:28:18,535 something a little programmatically. 1913 01:28:18,535 --> 01:28:21,160 For instance, how might I go about writing a program that quite 1914 01:28:21,160 --> 01:28:23,800 simply prints out four question marks? 1915 01:28:23,800 --> 01:28:26,920 Well, let me go ahead and open up, for instance, in code, 1916 01:28:26,920 --> 01:28:30,100 an example called mario0.c. 1917 01:28:30,100 --> 01:28:33,087 And I claim that this could be one way of implementing this program. 1918 01:28:33,087 --> 01:28:35,170 It's very simple, and it really doesn't do justice 1919 01:28:35,170 --> 01:28:39,400 to the other graphics on the screen, but it does implement that one idea. 1920 01:28:39,400 --> 01:28:41,800 And indeed, somewhere in the code for Mario, 1921 01:28:41,800 --> 01:28:43,600 there was probably some line of code that 1922 01:28:43,600 --> 01:28:47,950 told the console game to print question mark, question mark, question 1923 01:28:47,950 --> 01:28:48,970 mark, question mark. 1924 01:28:48,970 --> 01:28:51,760 In C, we could certainly do this with four question marks. 1925 01:28:51,760 --> 01:28:55,048 Or how else could we do something that many times? 1926 01:28:55,048 --> 01:28:55,840 AUDIENCE: For loop. 1927 01:28:55,840 --> 01:28:57,465 DAVID MALAN: Something like a for loop. 1928 01:28:57,465 --> 01:29:00,310 So let me go ahead and jump ahead a couple of iterations 1929 01:29:00,310 --> 01:29:05,200 to an example I'll call mario2.c, which just does all of this. 1930 01:29:05,200 --> 01:29:08,500 So this is actually pretty involved, but notice what it's doing. 1931 01:29:08,500 --> 01:29:12,010 In main, I'm saying, hey, give me an integer called n. 1932 01:29:12,010 --> 01:29:14,630 Do the following while n is less than 1. 1933 01:29:14,630 --> 01:29:18,820 So this is just a way of asking, what is the width of the blocks 1934 01:29:18,820 --> 01:29:20,140 that you want to print? 1935 01:29:20,140 --> 01:29:24,190 Then, once I have that answer, I can go ahead and, just as before, 1936 01:29:24,190 --> 01:29:28,940 print that many question marks n times, one at a time. 1937 01:29:28,940 --> 01:29:32,080 And at the very end, I'll print just a new line. 1938 01:29:32,080 --> 01:29:35,470 So in short, if you want to create a program, albeit in text, 1939 01:29:35,470 --> 01:29:37,760 that does something like this, and I make mario2-- 1940 01:29:37,760 --> 01:29:38,410 whoops. 1941 01:29:38,410 --> 01:29:43,510 And I make mario2, Enter, and type ./mario2, 1942 01:29:43,510 --> 01:29:46,510 I can do a width of four and get four question marks. 1943 01:29:46,510 --> 01:29:49,730 Or I can do 50 and get many more on the screen, all 1944 01:29:49,730 --> 01:29:51,480 by just using these basic building blocks. 1945 01:29:51,480 --> 01:29:54,660 But notice, because of that do-while loop, if I don't cooperate 1946 01:29:54,660 --> 01:29:58,110 and I do something like 0 or negative 1 or negative 50, 1947 01:29:58,110 --> 01:30:02,160 I just keep getting prompted again and again, because n is less than 1. 1948 01:30:02,160 --> 01:30:05,130 That's the kind of logic that you can impose there. 1949 01:30:05,130 --> 01:30:10,018 But let's go ahead and skip ahead, say, to something like this in Mario, 1950 01:30:10,018 --> 01:30:12,060 where you have a whole lot of bricks underground. 1951 01:30:12,060 --> 01:30:16,000 And this time, it's not just a column or a row of bricks. 1952 01:30:16,000 --> 01:30:17,755 This time, it's kind of two dimensions. 1953 01:30:17,755 --> 01:30:20,130 Well, this is kind of interesting, because now how do you 1954 01:30:20,130 --> 01:30:23,200 go about printing block, block, block, block, block, block, block, block, 1955 01:30:23,200 --> 01:30:25,158 block, block, block, block, and actually making 1956 01:30:25,158 --> 01:30:26,700 a two-dimensional structure instead? 1957 01:30:26,700 --> 01:30:30,090 Well, there's nothing stopping us in C, as in Scratch, 1958 01:30:30,090 --> 01:30:33,540 from doing something, for instance, with loops. 1959 01:30:33,540 --> 01:30:35,650 So let me show this example here. 1960 01:30:35,650 --> 01:30:38,070 So suppose that with these first lines of code, 1961 01:30:38,070 --> 01:30:41,938 I've asked the user for the size of this block. 1962 01:30:41,938 --> 01:30:44,730 So I want to create something that's square-like like this-- block, 1963 01:30:44,730 --> 01:30:47,710 block, block, block, block, block, block, block, block, and so forth. 1964 01:30:47,710 --> 01:30:51,270 Well, I can go ahead and prompt them for an int again and again 1965 01:30:51,270 --> 01:30:53,500 and again until I know that size. 1966 01:30:53,500 --> 01:30:54,930 And then notice this. 1967 01:30:54,930 --> 01:30:58,770 This is starting to escalate again, but consider the logic. 1968 01:30:58,770 --> 01:31:02,520 This now is for int i get 0, i less than n, i plus plus. 1969 01:31:02,520 --> 01:31:04,500 So do the following n times, right? 1970 01:31:04,500 --> 01:31:08,220 This is a very cryptic, C-like way of saying, do the following n times. 1971 01:31:08,220 --> 01:31:10,170 What about line 16? 1972 01:31:10,170 --> 01:31:13,740 What is line 16 saying? 1973 01:31:13,740 --> 01:31:16,710 Even though it's using a different variable. 1974 01:31:16,710 --> 01:31:18,869 I'm using j just because instead of i. 1975 01:31:18,869 --> 01:31:19,744 AUDIENCE: Same thing. 1976 01:31:19,744 --> 01:31:20,786 Do the following n times. 1977 01:31:20,786 --> 01:31:24,180 DAVID MALAN: Yeah, it says the exact same thing-- do the following n times. 1978 01:31:24,180 --> 01:31:26,880 However, it's counting using j instead of i, 1979 01:31:26,880 --> 01:31:30,100 just so that my math doesn't kind of commingle incorrectly. 1980 01:31:30,100 --> 01:31:32,580 So if you think about what this Mario block is, 1981 01:31:32,580 --> 01:31:35,318 this is like printing rows and columns. 1982 01:31:35,318 --> 01:31:37,860 Kind of like an old school typewriter that's got to move from 1983 01:31:37,860 --> 01:31:41,250 left to right and then top to bottom, top to bottom, left to right, 1984 01:31:41,250 --> 01:31:44,610 and so forth just to print different blocks on different lines. 1985 01:31:44,610 --> 01:31:47,010 So the effect here-- if I open up mario8-- 1986 01:31:47,010 --> 01:31:48,730 might be this, make-- oops. 1987 01:31:48,730 --> 01:31:53,193 Let me go ahead and make mario8, ./mario8. 1988 01:31:53,193 --> 01:31:54,360 What's the size going to be? 1989 01:31:54,360 --> 01:31:55,680 Well, maybe three. 1990 01:31:55,680 --> 01:32:00,030 And now I've printed out three rows and three columns. 1991 01:32:00,030 --> 01:32:03,930 These essentially represent each of my rows. 1992 01:32:03,930 --> 01:32:05,830 I'm counting from i up to-- 1993 01:32:05,830 --> 01:32:07,450 oh. 1994 01:32:07,450 --> 01:32:10,980 I'm teaching myself now only, OK. 1995 01:32:10,980 --> 01:32:11,760 Let's rewind. 1996 01:32:11,760 --> 01:32:13,950 Here is what was amazing me a moment ago. 1997 01:32:13,950 --> 01:32:16,770 When I was running what's the size of this program, 1998 01:32:16,770 --> 01:32:19,140 I saw a three-by-three grid of blocks. 1999 01:32:19,140 --> 01:32:21,450 And if I run it again, maybe with 10, I now 2000 01:32:21,450 --> 01:32:24,003 see an even bigger grid of 10-by-10 bricks. 2001 01:32:24,003 --> 01:32:26,670 It's a little taller than it is wide, because the hash marks are 2002 01:32:26,670 --> 01:32:27,960 taller than they are wide. 2003 01:32:27,960 --> 01:32:30,390 And you'll see that now this program is dynamic. 2004 01:32:30,390 --> 01:32:31,950 So how is that working? 2005 01:32:31,950 --> 01:32:33,950 Well, if I actually look at the code here, 2006 01:32:33,950 --> 01:32:36,750 notice that, effectively, what line 14 is doing 2007 01:32:36,750 --> 01:32:39,030 is it's doing one row at a time. 2008 01:32:39,030 --> 01:32:43,170 It's giving me n rows, and each of those rows I'm thinking of this is i at 0, 2009 01:32:43,170 --> 01:32:46,020 i1, i2, and so forth. 2010 01:32:46,020 --> 01:32:50,650 Meanwhile, within each row, I'm using this inner loop, 2011 01:32:50,650 --> 01:32:54,900 which is deliberately nested inside, to kind of do each of the characters 2012 01:32:54,900 --> 01:32:55,990 from left to right. 2013 01:32:55,990 --> 01:32:58,680 So within each row, I want hash, hash, hash, hash. 2014 01:32:58,680 --> 01:33:00,750 Within each row-- hash, hash, hash, hash. 2015 01:33:00,750 --> 01:33:03,670 So it's like implementing this two-dimensional process. 2016 01:33:03,670 --> 01:33:06,900 But again, using the same fundamental ideas. 2017 01:33:06,900 --> 01:33:11,370 Just a for loop that's very carefully counting from zero on up 2018 01:33:11,370 --> 01:33:16,032 to some value to do something again and again and again. 2019 01:33:16,032 --> 01:33:18,240 And so if you think about really any of today's games 2020 01:33:18,240 --> 01:33:21,150 or graphics or programs, anytime you see redundancy, 2021 01:33:21,150 --> 01:33:24,600 whether it's this in two dimensions-- maybe it's this vertically in one 2022 01:33:24,600 --> 01:33:26,712 dimension or this horizontally in another. 2023 01:33:26,712 --> 01:33:29,670 Odds are, there's just some repetition that's happening again and again 2024 01:33:29,670 --> 01:33:33,510 and again that can be reduced in C or in Scratch or some other language 2025 01:33:33,510 --> 01:33:36,780 to ultimately just lines of code. 2026 01:33:36,780 --> 01:33:39,270 And indeed, this is an allusion to one of the first things 2027 01:33:39,270 --> 01:33:41,760 you'll do for the first problem set, problem set 1. 2028 01:33:41,760 --> 01:33:45,180 You'll use CS50 Lab, which is identical to CS50 Sandbox, which 2029 01:33:45,180 --> 01:33:48,090 I've been using thus far, but which adds instructions, 2030 01:33:48,090 --> 01:33:52,170 the actual problems to solve, alongside of your sandbox. 2031 01:33:52,170 --> 01:33:55,470 But before we tease you with that, let's just 2032 01:33:55,470 --> 01:34:00,720 consider now that there are a bunch of little assumptions I've been making. 2033 01:34:00,720 --> 01:34:03,060 Like thus far, all of the mistakes in my code 2034 01:34:03,060 --> 01:34:06,990 have been my own-- some intentional, but several unintentional, as well, today. 2035 01:34:06,990 --> 01:34:10,560 But it turns out that computers themselves do have limitations. 2036 01:34:10,560 --> 01:34:12,810 Inside of your Mac or PC is generally stuff like this. 2037 01:34:12,810 --> 01:34:14,372 This is called memory, or RAM. 2038 01:34:14,372 --> 01:34:16,080 And you don't typically see it unless you 2039 01:34:16,080 --> 01:34:18,900 remove the cover from your phone or your laptop or desktop. 2040 01:34:18,900 --> 01:34:22,680 RAM is where all of your programs are stored while they're running. 2041 01:34:22,680 --> 01:34:26,190 RAM is where all of your programs-- where all of your files are 2042 01:34:26,190 --> 01:34:27,540 stored while they're open. 2043 01:34:27,540 --> 01:34:30,930 It's what your computer uses to do multiple things at once 2044 01:34:30,930 --> 01:34:32,440 and keep things in memory. 2045 01:34:32,440 --> 01:34:35,430 However, it is, by nature of hardware, finite. 2046 01:34:35,430 --> 01:34:38,610 You have maybe one gigabyte, one billion bytes, of memory. 2047 01:34:38,610 --> 01:34:41,400 Maybe you have four gigabytes, or four billion bytes, of memory. 2048 01:34:41,400 --> 01:34:44,280 You have fixed amount of memory in your computer, 2049 01:34:44,280 --> 01:34:48,040 which means there is some fundamental limitation on what your computer can 2050 01:34:48,040 --> 01:34:48,540 do. 2051 01:34:48,540 --> 01:34:52,350 It cannot necessarily count to infinity, because how could it count to infinity 2052 01:34:52,350 --> 01:34:57,020 if it can't store all possible numbers using a finite amount of space? 2053 01:34:57,020 --> 01:34:59,370 Indeed, there are some limits of computation 2054 01:34:59,370 --> 01:35:01,230 that we've only just begun to see. 2055 01:35:01,230 --> 01:35:02,890 In fact, let me go ahead and do this. 2056 01:35:02,890 --> 01:35:06,445 Let me write a program that I'm going to go ahead and call float.c. 2057 01:35:06,445 --> 01:35:09,570 And this is just going to be a program that gets a couple of floating point 2058 01:35:09,570 --> 01:35:11,980 values from the user. 2059 01:35:11,980 --> 01:35:15,000 Let me go ahead and include the CS50 library. 2060 01:35:15,000 --> 01:35:19,420 Let's go ahead and include stdio.h, int main void, as before. 2061 01:35:19,420 --> 01:35:22,488 And all I want to do here with this program is get a couple of floats. 2062 01:35:22,488 --> 01:35:23,280 So give me a float. 2063 01:35:23,280 --> 01:35:24,420 We'll call it x. 2064 01:35:24,420 --> 01:35:26,808 Get_float, and I'll prompt the human for x. 2065 01:35:26,808 --> 01:35:28,350 Then let me go ahead and get another. 2066 01:35:28,350 --> 01:35:29,370 I'll call it y. 2067 01:35:29,370 --> 01:35:31,380 Get_float, quote unquote y. 2068 01:35:31,380 --> 01:35:34,110 And recall that a float is just a number that 2069 01:35:34,110 --> 01:35:36,475 has a decimal point in it, a so-called real number. 2070 01:35:36,475 --> 01:35:38,100 Now let's just do some simple division. 2071 01:35:38,100 --> 01:35:40,990 I claim that computers can do addition, subtraction, and so forth. 2072 01:35:40,990 --> 01:35:41,920 So let's do that. 2073 01:35:41,920 --> 01:35:46,410 Let's just tell it that x divided by y is going to equal the following-- 2074 01:35:46,410 --> 01:35:52,150 percent f backslash n x divided by y semicolon. 2075 01:35:52,150 --> 01:35:55,110 So that's just sort of a very simplistic calculator 2076 01:35:55,110 --> 01:35:57,510 that I've implemented that only supports division. 2077 01:35:57,510 --> 01:36:04,170 Let me go ahead and compile this by going and typing make floats. 2078 01:36:04,170 --> 01:36:05,820 And you'll see that it did compile. 2079 01:36:05,820 --> 01:36:07,980 So floats with dot slash. 2080 01:36:07,980 --> 01:36:09,570 x is going to be, say, 1. 2081 01:36:09,570 --> 01:36:10,960 y is going to be 10. 2082 01:36:10,960 --> 01:36:12,120 OK, viola. 2083 01:36:12,120 --> 01:36:15,501 x divided by y equals 0.10000. 2084 01:36:15,501 --> 01:36:16,440 That's pretty nice. 2085 01:36:16,440 --> 01:36:19,570 And recall, if you don't want to see all those zeros, you can just say, 2086 01:36:19,570 --> 01:36:23,160 show me one decimal point by adding 0.1. 2087 01:36:23,160 --> 01:36:25,950 Recompile and then rerun it. 2088 01:36:25,950 --> 01:36:27,790 And now do 1, 10. 2089 01:36:27,790 --> 01:36:29,820 OK, so now it's 1/10. 2090 01:36:29,820 --> 01:36:30,930 Or is it? 2091 01:36:30,930 --> 01:36:33,660 Now that I have this ability to look past the decimal point, 2092 01:36:33,660 --> 01:36:36,900 why don't I look not a few places or one place. 2093 01:36:36,900 --> 01:36:40,440 Let me go ahead and look maybe 10 places after the decimal point. 2094 01:36:40,440 --> 01:36:48,210 Let me rerun this as make floats, ./floats, 1, 10. 2095 01:36:48,210 --> 01:36:49,920 Interesting. 2096 01:36:49,920 --> 01:36:51,627 All right, that seems a little strange. 2097 01:36:51,627 --> 01:36:52,710 Maybe it was just a fluke. 2098 01:36:52,710 --> 01:36:54,043 Let's look out a little further. 2099 01:36:54,043 --> 01:36:56,080 Let's look 50 decimal places out. 2100 01:36:56,080 --> 01:36:57,887 Let's go ahead and recompile this. 2101 01:36:57,887 --> 01:36:59,970 And it turns out, there's some keyboard shortcuts. 2102 01:36:59,970 --> 01:37:02,100 I'm now hitting up and down on my keyboard, which 2103 01:37:02,100 --> 01:37:04,302 will scroll through your entire history of commands 2104 01:37:04,302 --> 01:37:06,010 so you don't have to remember everything. 2105 01:37:06,010 --> 01:37:08,130 So to save time, I'm now just going up and down. 2106 01:37:08,130 --> 01:37:11,850 Let me go ahead and do ./floats now, 1, 10. 2107 01:37:11,850 --> 01:37:14,820 Oh my god, division is a lie. 2108 01:37:14,820 --> 01:37:18,660 So when your grade school teachers or whatnot taught you that 1 divided by 10 2109 01:37:18,660 --> 01:37:24,690 is 1/10, or 0.10000 infinitely, apparently that's not true. 2110 01:37:24,690 --> 01:37:28,810 According to this computer, 1/10 is actually this value. 2111 01:37:28,810 --> 01:37:31,500 So how do we reconcile that? 2112 01:37:31,500 --> 01:37:36,180 Who is right, grade school math or computers? 2113 01:37:36,180 --> 01:37:39,150 And what might explain? 2114 01:37:39,150 --> 01:37:40,860 Any thoughts? 2115 01:37:40,860 --> 01:37:41,850 Yeah? 2116 01:37:41,850 --> 01:37:45,550 AUDIENCE: It only stores so much so then half of that, 2117 01:37:45,550 --> 01:37:47,300 you don't know what's going on over there. 2118 01:37:47,300 --> 01:37:48,800 DAVID MALAN: Yeah, that's a good way of putting it. 2119 01:37:48,800 --> 01:37:51,200 Computers can only store so much, so after a certain point, 2120 01:37:51,200 --> 01:37:52,908 you don't know what's going on out there. 2121 01:37:52,908 --> 01:37:53,480 I like that. 2122 01:37:53,480 --> 01:37:54,710 Because that's indeed true. 2123 01:37:54,710 --> 01:37:57,120 If you only have a finite amount of hardware, 2124 01:37:57,120 --> 01:38:00,830 like a finite amount of memory, at some point, the computer has to decide, 2125 01:38:00,830 --> 01:38:02,780 I can count no higher than this value. 2126 01:38:02,780 --> 01:38:06,890 Or I can store no more than this many numbers after the decimal point. 2127 01:38:06,890 --> 01:38:09,290 You might be using 32 bits, which a float is. 2128 01:38:09,290 --> 01:38:12,470 You could use more bits, like a double, as I described it earlier, 2129 01:38:12,470 --> 01:38:14,720 literally uses twice as many bits, 64 bits. 2130 01:38:14,720 --> 01:38:19,580 So that means we could get farther out before we see that imprecision. 2131 01:38:19,580 --> 01:38:20,870 But you will see it. 2132 01:38:20,870 --> 01:38:24,440 Computers are, indeed, not perfect in this sense. 2133 01:38:24,440 --> 01:38:26,780 They can only store a finite amount of information. 2134 01:38:26,780 --> 01:38:31,190 And so in that sense, the computer is storing the closest possible match 2135 01:38:31,190 --> 01:38:34,190 for 1 divided by 10 that it can. 2136 01:38:34,190 --> 01:38:38,090 Because you can't possibly store an infinite number of numbers 100% 2137 01:38:38,090 --> 01:38:42,080 precisely using a finite amount of information. 2138 01:38:42,080 --> 01:38:44,060 And we see this in another context, too. 2139 01:38:44,060 --> 01:38:48,530 Let me go ahead and write one other program here called overflow.c. 2140 01:38:48,530 --> 01:38:50,990 And we'll see the same issue in another context. 2141 01:38:50,990 --> 01:38:54,350 Let me go ahead and include stdio.h. 2142 01:38:54,350 --> 01:38:57,410 Let me go ahead and do int main void. 2143 01:38:57,410 --> 01:39:01,190 Let me go ahead and do for int i gets one. 2144 01:39:01,190 --> 01:39:07,478 I'm going to go ahead and just say no condition and do i times equals 2. 2145 01:39:07,478 --> 01:39:09,020 And let me go ahead and just do this. 2146 01:39:09,020 --> 01:39:11,840 Print out the value of i. 2147 01:39:11,840 --> 01:39:15,440 So I'm doing the super quickly, but I just have written a program here 2148 01:39:15,440 --> 01:39:17,510 that's going to start counting at zero. 2149 01:39:17,510 --> 01:39:19,430 It's going to multiply i. 2150 01:39:19,430 --> 01:39:22,562 Star equals just means times two again and again. 2151 01:39:22,562 --> 01:39:25,520 And it's going to do this forever, because I literally and deliberately 2152 01:39:25,520 --> 01:39:27,380 didn't ask a Boolean expression here. 2153 01:39:27,380 --> 01:39:29,352 I could actually just say something like true, 2154 01:39:29,352 --> 01:39:30,810 but I can also just leave it blank. 2155 01:39:30,810 --> 01:39:32,310 So this just means do this forever. 2156 01:39:32,310 --> 01:39:33,590 It's an infinite loop. 2157 01:39:33,590 --> 01:39:36,950 Well, let me go ahead and this is going to fly past the screen here. 2158 01:39:36,950 --> 01:39:40,190 So I'm going to also sleep for one second in between. 2159 01:39:40,190 --> 01:39:43,010 And indeed, there's a function in C called sleep. 2160 01:39:43,010 --> 01:39:45,230 But to use it, you actually have to include 2161 01:39:45,230 --> 01:39:50,092 another file called unistandard.h. 2162 01:39:50,092 --> 01:39:52,550 You would only know this from looking in the documentation, 2163 01:39:52,550 --> 01:39:55,820 but it's a handy function that lets me sleep one second at a time. 2164 01:39:55,820 --> 01:39:57,920 Let me go ahead and make overflow. 2165 01:39:57,920 --> 01:39:58,650 No errors. 2166 01:39:58,650 --> 01:40:00,650 Let me increase the size of my screen. 2167 01:40:00,650 --> 01:40:02,600 And let me go ahead and run overflow. 2168 01:40:02,600 --> 01:40:06,530 And we'll see that every one second, it prints out a value starting at one, 2169 01:40:06,530 --> 01:40:08,780 and then it doubles it, and then it doubles it, 2170 01:40:08,780 --> 01:40:10,760 and then it doubles it again. 2171 01:40:10,760 --> 01:40:13,220 So you might recall some of these values from last week, 2172 01:40:13,220 --> 01:40:16,620 where I proposed that were 1,024 pages in a phone book, 2173 01:40:16,620 --> 01:40:18,893 and then it just got smaller and smaller and smaller. 2174 01:40:18,893 --> 01:40:20,310 Now we're just doing the opposite. 2175 01:40:20,310 --> 01:40:22,970 We're doubling by two, by two, by two. 2176 01:40:22,970 --> 01:40:26,090 We're just past a million now, 2 million, 4 million, 8 million, 2177 01:40:26,090 --> 01:40:27,077 16 million. 2178 01:40:27,077 --> 01:40:28,160 So we're getting up there. 2179 01:40:28,160 --> 01:40:30,770 So it looks like integers are pretty big. 2180 01:40:30,770 --> 01:40:35,720 They're indeed using 32 bits in a computer that apparently-- 2181 01:40:35,720 --> 01:40:38,150 what just happened? 2182 01:40:38,150 --> 01:40:39,170 Another lie. 2183 01:40:39,170 --> 01:40:44,360 If you just multiply some integer by two forever, it eventually becomes zero, 2184 01:40:44,360 --> 01:40:46,310 it would seem. 2185 01:40:46,310 --> 01:40:48,153 That, too, is not right. 2186 01:40:48,153 --> 01:40:49,070 But what has happened? 2187 01:40:49,070 --> 01:40:51,770 And there's kind of an illusion to it, both in my program's name 2188 01:40:51,770 --> 01:40:53,240 and in the red error. 2189 01:40:53,240 --> 01:40:56,750 Well, at some point, you only have so many bits 2190 01:40:56,750 --> 01:40:59,840 after which if you keep incrementing, incrementing, incrementing, 2191 01:40:59,840 --> 01:41:02,600 you don't have enough bits to sort of carry the one, so to speak, 2192 01:41:02,600 --> 01:41:04,580 and remember the even bigger value. 2193 01:41:04,580 --> 01:41:08,000 After all, if we go back to some of our discussion last week to discuss now 2194 01:41:08,000 --> 01:41:12,240 what's called floating point imprecision or now integer overflow, 2195 01:41:12,240 --> 01:41:14,720 which means floats can only be so precise 2196 01:41:14,720 --> 01:41:16,830 and integers can only be so big. 2197 01:41:16,830 --> 01:41:18,670 What you have is the following scenario. 2198 01:41:18,670 --> 01:41:21,253 123 in decimal, in our human world-- 2199 01:41:21,253 --> 01:41:23,170 of course, you can just keep adding one to it. 2200 01:41:23,170 --> 01:41:26,630 And as soon as you hit nine, it rolls over to zero. 2201 01:41:26,630 --> 01:41:29,240 You then carry the one, and you have 130. 2202 01:41:29,240 --> 01:41:30,380 That works great. 2203 01:41:30,380 --> 01:41:36,050 But of course, even in decimal, if you're at 999 using only three digits 2204 01:41:36,050 --> 01:41:39,440 and you try to add one more, you carry the one, you carry the one, 2205 01:41:39,440 --> 01:41:41,000 you lose the one. 2206 01:41:41,000 --> 01:41:41,840 Sorry. 2207 01:41:41,840 --> 01:41:43,110 What happens next? 2208 01:41:43,110 --> 01:41:47,030 This becomes 1, 0, 0, 0. 2209 01:41:47,030 --> 01:41:50,420 But if you only have three digits, you lose that initial one, 2210 01:41:50,420 --> 01:41:51,890 and you're left with just zero. 2211 01:41:51,890 --> 01:41:53,150 Same thing happens in binary. 2212 01:41:53,150 --> 01:41:54,690 Now if you context switch-- 2213 01:41:54,690 --> 01:41:58,860 and this is, in binary, what number? 2214 01:41:58,860 --> 01:42:01,580 This is the fours place, twos place, ones. 2215 01:42:01,580 --> 01:42:02,420 So it's seven. 2216 01:42:02,420 --> 01:42:04,280 4 plus 2 plus 1, this is 7. 2217 01:42:04,280 --> 01:42:06,230 So of course, if you add 1 to 7, you'd like 2218 01:42:06,230 --> 01:42:10,010 to get 8, which would give you 1, 0, 0. 2219 01:42:10,010 --> 01:42:13,370 But if you only have three bits, three digits, 2220 01:42:13,370 --> 01:42:15,740 you're going to overflow, so to speak. 2221 01:42:15,740 --> 01:42:19,400 You're going to lose the carried one so that the value you're actually storing 2222 01:42:19,400 --> 01:42:20,600 is just zero. 2223 01:42:20,600 --> 01:42:23,600 That's why if I count high enough with an integer in a program, 2224 01:42:23,600 --> 01:42:28,010 once I hit the billions, eventually that one has gotten carried too far. 2225 01:42:28,010 --> 01:42:30,620 It's only 32 bits large. 2226 01:42:30,620 --> 01:42:33,530 We can't fit a number even bigger than that. 2227 01:42:33,530 --> 01:42:35,240 That's what's called integer overflow. 2228 01:42:35,240 --> 01:42:38,340 And if you ever heard of the Y2K problem, 2229 01:42:38,340 --> 01:42:43,340 this was a horrible, very simple problem that humans created for themselves 2230 01:42:43,340 --> 01:42:46,960 back in the day when computers were invented in the mid 1900s, really. 2231 01:42:46,960 --> 01:42:50,410 Humans decided to save space, very reasonable, because space was expensive 2232 01:42:50,410 --> 01:42:51,260 early on. 2233 01:42:51,260 --> 01:42:58,452 So instead of storing the year as 1999 or 1970 for 1970, what did they do? 2234 01:42:58,452 --> 01:43:00,160 Yeah, they just stored two digits, right? 2235 01:43:00,160 --> 01:43:01,480 Like oh my god, we're not going to be using 2236 01:43:01,480 --> 01:43:03,190 these computers 50 years from now. 2237 01:43:03,190 --> 01:43:04,570 Let's just store two digits. 2238 01:43:04,570 --> 01:43:06,573 Unfortunately, that was not the case. 2239 01:43:06,573 --> 01:43:09,490 And there was a lot of code out there and a lot of computers out there 2240 01:43:09,490 --> 01:43:12,040 that were still running in 1999. 2241 01:43:12,040 --> 01:43:17,080 But if you're only storing two digits and you plus plus one value 2242 01:43:17,080 --> 01:43:20,020 to the year, what you'd like to be 2000 was 2243 01:43:20,020 --> 01:43:25,120 misinterpreted in lots of systems as 1900, at which point stuff broke. 2244 01:43:25,120 --> 01:43:27,580 And the world spent millions of dollars, presumably, 2245 01:43:27,580 --> 01:43:30,160 having programmers start using more memory 2246 01:43:30,160 --> 01:43:32,650 to fix this problem in anticipation of what was called 2247 01:43:32,650 --> 01:43:35,860 Y2K to get ahead of this problem. 2248 01:43:35,860 --> 01:43:38,890 And in the end, the world did not end in 1999, which was great. 2249 01:43:38,890 --> 01:43:40,930 But it was a very real and a very expensive 2250 01:43:40,930 --> 01:43:43,570 problem because of that lack of foresight. 2251 01:43:43,570 --> 01:43:46,400 It turns out that there's other examples of this, as well. 2252 01:43:46,400 --> 01:43:50,980 So this one, as an example, will just about end on Boeing 787. 2253 01:43:50,980 --> 01:43:53,737 So Boeing has not been getting great press recently. 2254 01:43:53,737 --> 01:43:55,570 And even a few years ago, did they have what 2255 01:43:55,570 --> 01:43:58,150 appeared to be a very straightforward software bug. 2256 01:43:58,150 --> 01:44:01,300 Pictured here is a model 787 airplane. 2257 01:44:01,300 --> 01:44:04,210 And the article from The New York Times explained as follows-- 2258 01:44:04,210 --> 01:44:09,130 "A model 787 airplane that has been powered continuously for 248 days 2259 01:44:09,130 --> 01:44:12,070 can lose all alternating current, electrical power, 2260 01:44:12,070 --> 01:44:14,380 due to the generator control units simultaneously 2261 01:44:14,380 --> 01:44:15,940 going into failsafe mode. 2262 01:44:15,940 --> 01:44:17,920 This condition is caused by a software counter 2263 01:44:17,920 --> 01:44:20,920 internal to the counters that will overflow 2264 01:44:20,920 --> 01:44:24,550 after 248 days of continuous power. 2265 01:44:24,550 --> 01:44:26,920 Boeing, according to the statement, is in the process 2266 01:44:26,920 --> 01:44:30,550 of developing a software upgrade that will remedy the safe condition." 2267 01:44:30,550 --> 01:44:31,578 So what does this mean? 2268 01:44:31,578 --> 01:44:33,370 Well, if you actually dig into the numbers, 2269 01:44:33,370 --> 01:44:41,560 248 days is roughly the value of 2 raised to the 32nd power, 2270 01:44:41,560 --> 01:44:44,467 give or take, in 1/100 of a second. 2271 01:44:44,467 --> 01:44:47,050 Which is to say that Boeing, in some crucial piece of hardware 2272 01:44:47,050 --> 01:44:51,640 in their 787 actual airplanes, were using integers 2273 01:44:51,640 --> 01:44:56,140 that were counting so high that after the 248th day of the airplane being 2274 01:44:56,140 --> 01:44:59,230 powered on would actually overflow, the result of which 2275 01:44:59,230 --> 01:45:01,900 is that the power in the plane could cut off entirely. 2276 01:45:01,900 --> 01:45:05,140 And so the solution, if you read through all the technical speak and jargon 2277 01:45:05,140 --> 01:45:09,970 there, is they literally had to reboot their planes every 248 days 2278 01:45:09,970 --> 01:45:13,270 in order to reset that variable back to zero. 2279 01:45:13,270 --> 01:45:16,870 This happens even today in the real world with issues like that. 2280 01:45:16,870 --> 01:45:19,540 And so you'll begin to notice these trends anytime people talk 2281 01:45:19,540 --> 01:45:21,760 about hardware mistakes or software mistakes. 2282 01:45:21,760 --> 01:45:24,700 Quite honestly, can you typically reduce them to problems 2283 01:45:24,700 --> 01:45:26,690 you yourselves have run into. 2284 01:45:26,690 --> 01:45:30,310 And let me go ahead and tease just a couple of things, a couple of features 2285 01:45:30,310 --> 01:45:31,390 now ahead. 2286 01:45:31,390 --> 01:45:34,450 It turns out that now that we have the ability to write code, 2287 01:45:34,450 --> 01:45:37,630 our programs, of course, can do any number of things, saying or printing 2288 01:45:37,630 --> 01:45:38,657 things on the screen. 2289 01:45:38,657 --> 01:45:40,990 We, of course, might do something like this in a program 2290 01:45:40,990 --> 01:45:43,900 we might call figlet, which actually comes with some systems. 2291 01:45:43,900 --> 01:45:46,630 And I can say something like, this is CS50, 2292 01:45:46,630 --> 01:45:49,540 and actually print it out in what's called ASCII art using characters 2293 01:45:49,540 --> 01:45:51,707 on the screen that kind of sort of look like letters 2294 01:45:51,707 --> 01:45:55,520 and create fairly beautiful, if old school, art on the screen. 2295 01:45:55,520 --> 01:45:58,210 Of course, if you write code and you understand 2296 01:45:58,210 --> 01:46:01,450 not only how numbers and letters are represented, but also sounds, 2297 01:46:01,450 --> 01:46:04,270 per our chat last week, you can do even more powerful things, 2298 01:46:04,270 --> 01:46:08,900 such as this note, which we will literally end on today. 2299 01:46:08,900 --> 01:46:10,217 SPEAKER 2: This is CS50. 2300 01:46:10,217 --> 01:46:11,550 DAVID MALAN: That's it for CS50. 2301 01:46:11,550 --> 01:46:13,210 We will see you next week. 2302 01:46:13,210 --> 01:46:15,060 [APPLAUSE]