1 00:00:00,000 --> 00:00:03,493 [INTRIGUING MUSIC] 2 00:00:03,493 --> 00:01:01,377 3 00:01:01,377 --> 00:01:06,220 DAVID MALAN: All right, so this is CS50. 4 00:01:06,220 --> 00:01:09,310 And this is week 1, zero index, so to speak. 5 00:01:09,310 --> 00:01:12,890 And it's not every day that you can say that you've learned a new language, 6 00:01:12,890 --> 00:01:14,260 but today is that day. 7 00:01:14,260 --> 00:01:18,010 Today, we explore a more traditional and older language called C. 8 00:01:18,010 --> 00:01:22,450 And rest assured that even if what you're about to see-- no pun intended-- 9 00:01:22,450 --> 00:01:25,420 looks very cryptic, very unusual, particularly if you're 10 00:01:25,420 --> 00:01:28,967 among those less comfortable, cling to the ideas from last week, 11 00:01:28,967 --> 00:01:32,050 week zero, wherein we talked about some of those fundamentals of functions 12 00:01:32,050 --> 00:01:35,230 and loops and conditionals, all of which are coming back today. 13 00:01:35,230 --> 00:01:37,815 Indeed, whereas last week, and with problem set 0, 14 00:01:37,815 --> 00:01:39,940 we focused on learning how to program with Scratch, 15 00:01:39,940 --> 00:01:44,770 which, again, you might have played with as a younger student days back. 16 00:01:44,770 --> 00:01:46,870 Today, we focus on C instead. 17 00:01:46,870 --> 00:01:50,260 But along the way, we're going to focus, as always, frankly, 18 00:01:50,260 --> 00:01:51,850 on learning how to solve problems. 19 00:01:51,850 --> 00:01:54,820 But among the goals for today and really on an entire class like this 20 00:01:54,820 --> 00:01:58,610 is just to give you week after week all the more tools for your toolkit, 21 00:01:58,610 --> 00:02:00,680 so to speak, via which to do exactly that. 22 00:02:00,680 --> 00:02:03,860 So for instance today, we'll learn how to solve problems all the more 23 00:02:03,860 --> 00:02:06,420 so with functions, as per last week. 24 00:02:06,420 --> 00:02:07,910 We'll do the same with variables. 25 00:02:07,910 --> 00:02:10,789 We'll do the same with conditionals, with loops, and with more. 26 00:02:10,789 --> 00:02:13,190 But we'll also learn at the end of today's class 27 00:02:13,190 --> 00:02:14,970 really how not to solve problems. 28 00:02:14,970 --> 00:02:18,410 It turns out as powerful as Macs, PCs, cell phones are nowadays, 29 00:02:18,410 --> 00:02:21,890 there's actually certain things that they can't do very well 30 00:02:21,890 --> 00:02:24,650 and information they can't represent very well. 31 00:02:24,650 --> 00:02:28,760 And that actually leads to a lot of real-world problems, both past 32 00:02:28,760 --> 00:02:29,940 and surely future. 33 00:02:29,940 --> 00:02:33,540 So more on what we're not going to be able to do with programming before 34 00:02:33,540 --> 00:02:34,040 long. 35 00:02:34,040 --> 00:02:36,600 But beyond that, let's come back to this picture here. 36 00:02:36,600 --> 00:02:38,900 So this was the very first program that I wrote, 37 00:02:38,900 --> 00:02:40,880 that you wrote presumably in some form. 38 00:02:40,880 --> 00:02:43,400 And all it does is say "Hello, world." 39 00:02:43,400 --> 00:02:47,660 But as promised, today, this puzzle piece, or these puzzle pieces together, 40 00:02:47,660 --> 00:02:50,880 are going to very quickly start to look more like this. 41 00:02:50,880 --> 00:02:54,295 And I've deliberately color coded it in a way so that the text on the screen 42 00:02:54,295 --> 00:02:55,920 now kind of resembles the puzzle piece. 43 00:02:55,920 --> 00:02:59,540 So if I go back, notice that we had this, when green flag clicked puzzle 44 00:02:59,540 --> 00:03:02,780 piece, mostly in yellow with the green flag, that sort of kicks off 45 00:03:02,780 --> 00:03:04,550 the whole process once you actually click 46 00:03:04,550 --> 00:03:07,640 the button at top right of Scratch's user interface. 47 00:03:07,640 --> 00:03:11,990 And then there's the purple block which actually is the verb, the action, 48 00:03:11,990 --> 00:03:13,620 the function that does something. 49 00:03:13,620 --> 00:03:16,820 So if I bring us back over to what we're about to see today, 50 00:03:16,820 --> 00:03:20,477 there's going to be some boilerplate, so to speak, some orange text here 51 00:03:20,477 --> 00:03:23,060 on the screen that for now you just type and take for granted, 52 00:03:23,060 --> 00:03:25,430 like you need to write your code like that. 53 00:03:25,430 --> 00:03:27,435 But more interesting is going to be the purple. 54 00:03:27,435 --> 00:03:29,810 And we're going to see today that the function previously 55 00:03:29,810 --> 00:03:34,430 called "say" in Scratch is now called "printf" in this language called C. 56 00:03:34,430 --> 00:03:37,520 But in white here, you'll see similar text to our white oval 57 00:03:37,520 --> 00:03:40,550 last week, whereby that's where user input, like your input 58 00:03:40,550 --> 00:03:42,277 as the programmer, can actually go. 59 00:03:42,277 --> 00:03:43,610 So there's a lot of distraction. 60 00:03:43,610 --> 00:03:44,930 And honestly, it's these kinds of things that 61 00:03:44,930 --> 00:03:47,180 tend to distract and get frustrating early on when 62 00:03:47,180 --> 00:03:48,780 learning to code for the first time. 63 00:03:48,780 --> 00:03:52,170 But the ideas, most importantly, are going to be the same. 64 00:03:52,170 --> 00:03:54,060 So how are we going to go about using this. 65 00:03:54,060 --> 00:03:55,910 Well, it turns out, like last week, you're 66 00:03:55,910 --> 00:03:58,190 going to start writing something called source code. 67 00:03:58,190 --> 00:04:01,280 So code as we know it, quote, unquote, is more technically called 68 00:04:01,280 --> 00:04:02,060 "source code." 69 00:04:02,060 --> 00:04:04,460 That's what you and I as humans actually write. 70 00:04:04,460 --> 00:04:07,350 And indeed it might look a little something like we just saw. 71 00:04:07,350 --> 00:04:11,090 But unfortunately, computers only speak this, binary-- 72 00:04:11,090 --> 00:04:15,660 zeros and ones-- more properly known as machine code, in other words, 73 00:04:15,660 --> 00:04:19,550 those same patterns of zeros and ones last week, someone guessed, 74 00:04:19,550 --> 00:04:23,090 print out "hello, world" on the screen because one of those patterns 75 00:04:23,090 --> 00:04:27,570 is an H. Another pattern is an E, an L, and L, and an O, and so forth. 76 00:04:27,570 --> 00:04:31,880 And then other patterns of those zeros and ones are commands or instructions 77 00:04:31,880 --> 00:04:37,280 to the computer that literally say, show H-E-L-L-O comma "world" on the screen. 78 00:04:37,280 --> 00:04:40,520 But machine code would not be nearly as much fun 79 00:04:40,520 --> 00:04:43,070 to write if it were indeed in zeros and ones. 80 00:04:43,070 --> 00:04:45,080 Entirely for us, ideally, you and I are going 81 00:04:45,080 --> 00:04:49,100 to write source code, which conceptually is sort of up here, high level. 82 00:04:49,100 --> 00:04:52,790 But we're going to need a program to convert it to the lower-level machine 83 00:04:52,790 --> 00:04:56,240 code so that we don't spend our lives actually having to read and write 84 00:04:56,240 --> 00:04:59,000 zeros and ones, which back in the day, kind of in yesteryear, 85 00:04:59,000 --> 00:05:01,160 you kind of did with things called punch cards 86 00:05:01,160 --> 00:05:03,050 and holes on physical sheets of paper. 87 00:05:03,050 --> 00:05:06,440 We're beyond that because after years and years of innovation, 88 00:05:06,440 --> 00:05:09,462 folks have given us higher-level languages instead. 89 00:05:09,462 --> 00:05:11,420 So here's what we're going to need to do today. 90 00:05:11,420 --> 00:05:14,900 If at the end of the day you and I are writing source code 91 00:05:14,900 --> 00:05:18,260 but we want machine code as output, we need something 92 00:05:18,260 --> 00:05:21,900 in the middle that's going to convert that source code to machine code. 93 00:05:21,900 --> 00:05:23,900 You and I are not going to have to learn or talk 94 00:05:23,900 --> 00:05:25,672 about really any more zeros and ones. 95 00:05:25,672 --> 00:05:28,880 And the type of program we're going to start using today and introduce you to 96 00:05:28,880 --> 00:05:30,080 is called a compiler. 97 00:05:30,080 --> 00:05:34,130 So a compiler is a program that translates one language to another. 98 00:05:34,130 --> 00:05:35,720 And it can be any two languages. 99 00:05:35,720 --> 00:05:39,770 But today, and often, we'll talk about it in the context of source code 100 00:05:39,770 --> 00:05:40,890 to machine code. 101 00:05:40,890 --> 00:05:45,325 So this is Apple or Google or Microsoft or folks from other companies 102 00:05:45,325 --> 00:05:48,200 or even volunteers who have written software that do this conversion. 103 00:05:48,200 --> 00:05:51,230 You and I are essentially going to download a free compiler 104 00:05:51,230 --> 00:05:55,040 and use it to actually get our computer to understand the source 105 00:05:55,040 --> 00:05:58,595 code that you and I write in these higher-level languages. 106 00:05:58,595 --> 00:05:59,970 So where are we going to do that? 107 00:05:59,970 --> 00:06:01,845 Well, we could actually give you instructions 108 00:06:01,845 --> 00:06:05,340 and you could download the appropriate free open-source software 109 00:06:05,340 --> 00:06:06,607 onto your own Mac or PC. 110 00:06:06,607 --> 00:06:09,690 The reality is that creates so many technical support headaches because we 111 00:06:09,690 --> 00:06:11,280 all have slightly different computers. 112 00:06:11,280 --> 00:06:14,640 We all have slightly different versions of Windows or macOS or Linux 113 00:06:14,640 --> 00:06:15,840 or other operating systems. 114 00:06:15,840 --> 00:06:19,260 And that, too, tends to be a distraction at the beginning of any course 115 00:06:19,260 --> 00:06:20,730 like this or learning programming. 116 00:06:20,730 --> 00:06:22,680 So we're going to use the cloud instead. 117 00:06:22,680 --> 00:06:28,530 We're going to use a URL of the form https://cs50.dev. 118 00:06:28,530 --> 00:06:32,040 And what this will do for you is put inside of your browser window 119 00:06:32,040 --> 00:06:36,390 absolutely everything you need for the course, but it's going to use software, 120 00:06:36,390 --> 00:06:39,810 software called Visual Studio code, otherwise known as VS Code, 121 00:06:39,810 --> 00:06:41,730 that's actually free itself. 122 00:06:41,730 --> 00:06:43,200 It's very popular in industry. 123 00:06:43,200 --> 00:06:45,420 It's what "real" programmers use every day. 124 00:06:45,420 --> 00:06:47,560 But it's a cloud-based version thereof. 125 00:06:47,560 --> 00:06:50,250 And so everything will just work for you out of the box. 126 00:06:50,250 --> 00:06:52,530 But toward the end of CS50, the goal is going 127 00:06:52,530 --> 00:06:55,200 to be to get you off of CS50's infrastructure, 128 00:06:55,200 --> 00:06:59,040 to get you to download this freely available software onto your own Mac 129 00:06:59,040 --> 00:07:02,170 or PC if you so choose so that those training wheels, so to speak, 130 00:07:02,170 --> 00:07:02,840 can come off. 131 00:07:02,840 --> 00:07:05,170 And then even if you never take another class again, 132 00:07:05,170 --> 00:07:07,780 you don't need any class's infrastructure moving forward. 133 00:07:07,780 --> 00:07:10,960 You'll have everything you want and need on your own Mac or PC. 134 00:07:10,960 --> 00:07:13,250 But for now, it'll save us a bit of time. 135 00:07:13,250 --> 00:07:16,750 So in just a bit, I'm going to go to that URL myself on my computer. 136 00:07:16,750 --> 00:07:19,552 And I and you will see a user interface that 137 00:07:19,552 --> 00:07:21,010 looks a little something like this. 138 00:07:21,010 --> 00:07:23,170 The colors might be different based on your settings. 139 00:07:23,170 --> 00:07:24,800 Fonts might be different, and so forth. 140 00:07:24,800 --> 00:07:27,590 But in general, it consists of a few different regions. 141 00:07:27,590 --> 00:07:31,750 So over here at the top is where we are going to start writing code today. 142 00:07:31,750 --> 00:07:34,930 So it's a tabbed interface like any number of programs nowadays. 143 00:07:34,930 --> 00:07:38,058 And this is that same C code we saw a moment ago. 144 00:07:38,058 --> 00:07:40,600 So this is where, in a moment, I'm going to start to type it. 145 00:07:40,600 --> 00:07:43,330 Over here at the bottom is what we're going to call 146 00:07:43,330 --> 00:07:45,438 a terminal window, or a console. 147 00:07:45,438 --> 00:07:47,980 And the terminal window is where we're going to type commands 148 00:07:47,980 --> 00:07:50,500 for compiling our code, for running our code. 149 00:07:50,500 --> 00:07:54,860 And we'll see today a contrast between a graphical-user interface, 150 00:07:54,860 --> 00:07:57,370 or GUI, which has menus and icons and things 151 00:07:57,370 --> 00:08:01,270 you click and are very familiar with, versus a command-line interface, 152 00:08:01,270 --> 00:08:02,200 or CLI. 153 00:08:02,200 --> 00:08:04,270 And so we're using both of these together. 154 00:08:04,270 --> 00:08:08,007 And command-line interface just means, down here, you only use your keyboard. 155 00:08:08,007 --> 00:08:10,340 You can click, click, click if you want with your mouse. 156 00:08:10,340 --> 00:08:13,423 It's not going to generally do much because a command-line interface takes 157 00:08:13,423 --> 00:08:14,540 commands at the keyboard. 158 00:08:14,540 --> 00:08:16,840 So in a weird sense, it's going to feel like taking 159 00:08:16,840 --> 00:08:20,620 a step backwards from the Macs, the PCs, the iPhones, and Android phones we all 160 00:08:20,620 --> 00:08:22,660 have, which are very graphical. 161 00:08:22,660 --> 00:08:26,120 But it turns out, once you become a "computer" person or a programmer, 162 00:08:26,120 --> 00:08:29,680 you can be a lot more productive, a lot more efficient, I dare say, 163 00:08:29,680 --> 00:08:31,990 by learning to harness the command-line interface 164 00:08:31,990 --> 00:08:35,169 and using both types of interfaces for what each is good at. 165 00:08:35,169 --> 00:08:36,730 So more on that in just a bit. 166 00:08:36,730 --> 00:08:41,289 Over here at left, you're going to see soon a folder interface like Mac OS 167 00:08:41,289 --> 00:08:45,010 or Windows where any of the files or folders we create in CS50 168 00:08:45,010 --> 00:08:46,310 are going to end up, as well. 169 00:08:46,310 --> 00:08:47,990 So it gives you the best of both worlds. 170 00:08:47,990 --> 00:08:51,310 You can point and click on the left, or you can type commands at the bottom, 171 00:08:51,310 --> 00:08:52,420 as we'll soon see. 172 00:08:52,420 --> 00:08:54,670 And then along here is the so-called activity bar, 173 00:08:54,670 --> 00:08:58,500 where there's just VS Code-specific features but also CS50-specific 174 00:08:58,500 --> 00:08:59,000 features. 175 00:08:59,000 --> 00:09:01,420 And if you're in your own version of CS50.dev, 176 00:09:01,420 --> 00:09:03,580 you click through in the dot dot dot menu 177 00:09:03,580 --> 00:09:05,320 or zoom out so you can see everything. 178 00:09:05,320 --> 00:09:08,530 You'll see CS50's own rubber duck, virtually speaking, 179 00:09:08,530 --> 00:09:10,870 that will be there throughout the course to answer 180 00:09:10,870 --> 00:09:13,460 any and all of your questions, as well. 181 00:09:13,460 --> 00:09:15,190 So more on that soon, too. 182 00:09:15,190 --> 00:09:18,040 So here's the code that I propose that we write first, 183 00:09:18,040 --> 00:09:21,800 just like we wrote our very first Scratch program to say "hello, world." 184 00:09:21,800 --> 00:09:23,650 So let's go ahead and do exactly this. 185 00:09:23,650 --> 00:09:25,870 I'm going to switch over to this screen here, 186 00:09:25,870 --> 00:09:29,980 where I've already logged into CS50.dev on my computer. 187 00:09:29,980 --> 00:09:33,760 And just to keep the focus on the code, I've hidden the activity bar. 188 00:09:33,760 --> 00:09:36,140 I've hidden the File Explorer, so to speak. 189 00:09:36,140 --> 00:09:39,740 So you're seeing here the area where all of my tabs are about to go 190 00:09:39,740 --> 00:09:42,490 and the terminal window, where all of my commands are going to go. 191 00:09:42,490 --> 00:09:44,710 But I've just simplified the UI to keep our focus 192 00:09:44,710 --> 00:09:46,910 on the interesting parts for now. 193 00:09:46,910 --> 00:09:53,140 So how do I go about actually writing and compiling and running some code? 194 00:09:53,140 --> 00:09:55,690 Well, the teaser is going to be these three steps. 195 00:09:55,690 --> 00:09:58,510 One of these is a command called, aptly, Code. 196 00:09:58,510 --> 00:10:02,260 And Code is just going to let me to open or create a new file, 197 00:10:02,260 --> 00:10:03,930 like a file called "hello.c." 198 00:10:03,930 --> 00:10:06,960 Make is going to be, for now, my compiler that 199 00:10:06,960 --> 00:10:11,280 allows me to make the program, that is convert source code into machine 200 00:10:11,280 --> 00:10:13,710 code, so from C to zeros and ones. 201 00:10:13,710 --> 00:10:15,570 And then weirdly, but we'll soon see why, 202 00:10:15,570 --> 00:10:19,810 ./hello is going to be the command to run my actual code, 203 00:10:19,810 --> 00:10:23,760 so the textual equivalent of like double-clicking on a Mac or a PC icon 204 00:10:23,760 --> 00:10:25,890 or tapping an icon on your phone. 205 00:10:25,890 --> 00:10:26,670 So that's it. 206 00:10:26,670 --> 00:10:30,810 These three commands are going to allow me to write, to compile, and to run 207 00:10:30,810 --> 00:10:32,070 code ultimately. 208 00:10:32,070 --> 00:10:33,340 So let's go ahead and do that. 209 00:10:33,340 --> 00:10:35,170 I'm back in my VS Code interface. 210 00:10:35,170 --> 00:10:39,000 I'm going to go ahead and run "code hello.c." 211 00:10:39,000 --> 00:10:40,900 And notice a couple of details here. 212 00:10:40,900 --> 00:10:44,790 So one, there's this weird dollar sign, which has nothing to do with currency, 213 00:10:44,790 --> 00:10:48,000 but it's just a common convention in the programming world 214 00:10:48,000 --> 00:10:50,520 to represent your prompt. 215 00:10:50,520 --> 00:10:53,190 So if a TF, if I ever say, go to your prompt, 216 00:10:53,190 --> 00:10:55,170 we really mean, go to your terminal window. 217 00:10:55,170 --> 00:10:56,100 Go to the dollar sign. 218 00:10:56,100 --> 00:10:58,285 And the dollar sign is where you type the command. 219 00:10:58,285 --> 00:11:01,160 Sometimes it's a different symbol, but a dollar sign is conventional. 220 00:11:01,160 --> 00:11:03,950 Now that I've typed "code" space "hello.c," 221 00:11:03,950 --> 00:11:05,450 I'm going to go ahead and hit Enter. 222 00:11:05,450 --> 00:11:07,158 And maybe not surprisingly, this gives me 223 00:11:07,158 --> 00:11:10,850 a brand new tab, a new file if you will, called "hello.c." 224 00:11:10,850 --> 00:11:15,290 And just like Word documents have their own file extension, like DOC, DOCX, 225 00:11:15,290 --> 00:11:22,050 and Excel files have .XLSX and PDFs have .PDF and GIFs have .GIF and so forth, 226 00:11:22,050 --> 00:11:26,780 so do C files have a file extension by convention that is .C. 227 00:11:26,780 --> 00:11:28,350 Now, a couple of minor points. 228 00:11:28,350 --> 00:11:30,710 Notice that, by convention, I'm almost always 229 00:11:30,710 --> 00:11:32,630 going to name my files in lowercase. 230 00:11:32,630 --> 00:11:36,440 By convention, I'm never going to use spaces in my file names. 231 00:11:36,440 --> 00:11:39,080 And my file extension, too, is going to be lowercase. 232 00:11:39,080 --> 00:11:41,840 Long story short, accidentally hitting the spacebar 233 00:11:41,840 --> 00:11:44,180 or using file names with spaces just tends 234 00:11:44,180 --> 00:11:47,130 to make life harder when you're in a command-line environment. 235 00:11:47,130 --> 00:11:49,530 So just beware silly, stupid things like that. 236 00:11:49,530 --> 00:11:51,410 So all lowercase, no spaces for now. 237 00:11:51,410 --> 00:11:54,380 So my cursor is literally blinking because the program 238 00:11:54,380 --> 00:11:55,825 wants me to write some code. 239 00:11:55,825 --> 00:11:57,200 I'm going to do this from memory. 240 00:11:57,200 --> 00:12:00,607 It'll take you presumably some time to acquire the same instincts. 241 00:12:00,607 --> 00:12:02,940 But I'm going to go ahead and type this first line here, 242 00:12:02,940 --> 00:12:06,390 pronounced "include standard io.h"-- 243 00:12:06,390 --> 00:12:07,590 more on that soon-- 244 00:12:07,590 --> 00:12:11,190 int main(void), with some parentheses thrown in. 245 00:12:11,190 --> 00:12:13,740 Notice what's about to happen here is a little interesting. 246 00:12:13,740 --> 00:12:15,750 In the code I want to type, I want what we'll 247 00:12:15,750 --> 00:12:18,210 call curly braces, the sort of squiggles that you 248 00:12:18,210 --> 00:12:20,460 don't use often in English, at least, but are there 249 00:12:20,460 --> 00:12:21,750 on your keyboard somewhere. 250 00:12:21,750 --> 00:12:25,350 But notice what VS Code does, and a lot of programming environments, 251 00:12:25,350 --> 00:12:27,480 is it finishes part of my thought. 252 00:12:27,480 --> 00:12:30,330 So I'm only going to type a left curly brace, 253 00:12:30,330 --> 00:12:32,950 but notice I actually get two of them. 254 00:12:32,950 --> 00:12:36,820 And if I hit Enter, notice that not only does it scooch one down a bit, 255 00:12:36,820 --> 00:12:40,350 it also indents my cursor because, just like with pseudocode last week, 256 00:12:40,350 --> 00:12:43,320 whenever you're doing something logically that should only 257 00:12:43,320 --> 00:12:45,930 happen if the thing above it happens, similarly 258 00:12:45,930 --> 00:12:48,900 is indentation going to be a thing when we actually write code. 259 00:12:48,900 --> 00:12:51,870 So VS Code and programs like it just try to save us 260 00:12:51,870 --> 00:12:54,450 keystrokes so I don't have to waste time hitting the spacebar 261 00:12:54,450 --> 00:12:57,900 or hitting Tab or wasting my human time like that. 262 00:12:57,900 --> 00:13:00,180 All right, so with that said, I'm going to go ahead 263 00:13:00,180 --> 00:13:02,430 and type the last of these lines, "printf," 264 00:13:02,430 --> 00:13:05,860 where the F is going to mean "formatted," and then a parentheses. 265 00:13:05,860 --> 00:13:07,290 And notice it gave me two. 266 00:13:07,290 --> 00:13:08,910 It gave me the second one for free. 267 00:13:08,910 --> 00:13:10,270 Sometimes it will get confused. 268 00:13:10,270 --> 00:13:13,560 And you can certainly override this, delete it, and start over. 269 00:13:13,560 --> 00:13:16,680 And now, unlike Scratch, in C, It turns out 270 00:13:16,680 --> 00:13:18,870 I'm going to need to use double quotes anytime 271 00:13:18,870 --> 00:13:22,860 I'm using an English word or phrase or any human language for that matter. 272 00:13:22,860 --> 00:13:25,050 "Hello" comma "world." 273 00:13:25,050 --> 00:13:29,310 And then at the very end of my line, much like English uses periods, 274 00:13:29,310 --> 00:13:32,160 I'm going to use a semicolon in C. 275 00:13:32,160 --> 00:13:35,340 So that's a lot of talking, but it's not much coding. 276 00:13:35,340 --> 00:13:37,290 It's technically six lines of code. 277 00:13:37,290 --> 00:13:40,600 But honestly, the only interesting one intellectually, as we'll soon see, 278 00:13:40,600 --> 00:13:41,670 is really line 5. 279 00:13:41,670 --> 00:13:44,580 Like, that is the equivalent of that, say, block. 280 00:13:44,580 --> 00:13:46,500 Now here's where I'll cross my fingers, hoping 281 00:13:46,500 --> 00:13:48,750 that I didn't make any typographical errors. 282 00:13:48,750 --> 00:13:50,700 It's going to automatically save for me. 283 00:13:50,700 --> 00:13:53,790 And I'm going to go back to my terminal window where now I'm 284 00:13:53,790 --> 00:13:56,670 going to do that second command, "make" space "hello." 285 00:13:56,670 --> 00:14:00,180 Common mistake-- you do not say "make hello.c," because you 286 00:14:00,180 --> 00:14:01,350 already made that file. 287 00:14:01,350 --> 00:14:04,950 You say "make hello," which is the name of the program that in this case I do 288 00:14:04,950 --> 00:14:06,600 want to create. 289 00:14:06,600 --> 00:14:07,830 And Make is smart. 290 00:14:07,830 --> 00:14:09,550 It's going to look in my folder. 291 00:14:09,550 --> 00:14:12,060 And if it sees a file called "hello.c," it's 292 00:14:12,060 --> 00:14:14,910 going to convert that source code to machine code 293 00:14:14,910 --> 00:14:18,510 and save the results in a simpler shorter-named file just called 294 00:14:18,510 --> 00:14:20,650 "hello," like an icon on your desktop. 295 00:14:20,650 --> 00:14:22,650 Now, hopefully nothing will happen. 296 00:14:22,650 --> 00:14:25,560 And that is a good thing, quite paradoxically. 297 00:14:25,560 --> 00:14:28,350 If you do anything wrong when programming, odds are you're 298 00:14:28,350 --> 00:14:31,738 going to see one or many more lines of error sort of yelling 299 00:14:31,738 --> 00:14:33,030 at you that you made a mistake. 300 00:14:33,030 --> 00:14:35,950 Seeing nothing happen is actually a good sign. 301 00:14:35,950 --> 00:14:40,470 So the last command, to run my code, recall our three steps here. 302 00:14:40,470 --> 00:14:46,260 We've written code to create the file, Make to compile the file from source 303 00:14:46,260 --> 00:14:47,140 code to machine code. 304 00:14:47,140 --> 00:14:49,320 So lastly is "./hello." 305 00:14:49,320 --> 00:14:53,130 So this now is the equivalent of my double-clicking on a Mac or PC 306 00:14:53,130 --> 00:14:55,650 or single tapping on a phone. 307 00:14:55,650 --> 00:14:57,360 Enter. 308 00:14:57,360 --> 00:14:58,893 [SIGHS] So close! 309 00:14:58,893 --> 00:15:00,060 All right, it's pretty good. 310 00:15:00,060 --> 00:15:02,970 I got the H-E-L-L-O comma space "world." 311 00:15:02,970 --> 00:15:05,770 But there's something a little stupid about my output. 312 00:15:05,770 --> 00:15:09,565 What might rub some of you aesthetically the wrong way? 313 00:15:09,565 --> 00:15:10,065 Yeah? 314 00:15:10,065 --> 00:15:11,460 STUDENT: The dollar sign. 315 00:15:11,460 --> 00:15:14,430 DAVID MALAN: Yeah, so the dollar sign looks like I was like, "hello, 316 00:15:14,430 --> 00:15:16,390 world" dollar sign in my output. 317 00:15:16,390 --> 00:15:21,100 But no, that's just kind of a remnant of my prompt starting with a dollar sign. 318 00:15:21,100 --> 00:15:23,767 And this is a little nitpicky, but this just doesn't feel right, 319 00:15:23,767 --> 00:15:24,558 doesn't look right. 320 00:15:24,558 --> 00:15:25,600 It's not quite correct. 321 00:15:25,600 --> 00:15:27,030 So how can I go about fixing this? 322 00:15:27,030 --> 00:15:29,100 Well, here's where, at least initially, it's 323 00:15:29,100 --> 00:15:33,660 going to take some introduction to just new syntax in C to fix this. 324 00:15:33,660 --> 00:15:35,850 The simplest instinct might be to do this. 325 00:15:35,850 --> 00:15:37,590 Well, let me just hit Enter like that. 326 00:15:37,590 --> 00:15:40,095 But this should soon, if not already, rub you 327 00:15:40,095 --> 00:15:41,970 the wrong way because in general, we're going 328 00:15:41,970 --> 00:15:44,550 to see that programming in C and in Python 329 00:15:44,550 --> 00:15:46,920 and other languages tends to be line-based. 330 00:15:46,920 --> 00:15:49,763 Like, you should really start and finish your thought on one line. 331 00:15:49,763 --> 00:15:51,930 So if you're in the habit of hitting Enter like this 332 00:15:51,930 --> 00:15:54,360 and finishing your thought on the next line, 333 00:15:54,360 --> 00:15:57,250 generally programming languages don't like that. 334 00:15:57,250 --> 00:16:00,030 So this is, in fact, not going to do what we expect. 335 00:16:00,030 --> 00:16:02,390 And just to show you as much, I'm going to do this. 336 00:16:02,390 --> 00:16:04,430 Let me go back to my terminal window here. 337 00:16:04,430 --> 00:16:07,670 I'm going to rerun "make hello" after making that change. 338 00:16:07,670 --> 00:16:08,380 Enter. 339 00:16:08,380 --> 00:16:11,830 And there we have it, like the first of our erroneous outputs. 340 00:16:11,830 --> 00:16:12,940 And it's yelling at me. 341 00:16:12,940 --> 00:16:15,075 It's missing a terminating character. 342 00:16:15,075 --> 00:16:17,950 And there's some red in here, some green, drawing my attention to it. 343 00:16:17,950 --> 00:16:20,598 Sometimes these error messages will be straightforward. 344 00:16:20,598 --> 00:16:23,390 Sometimes you're going to rack your brain a bit to figure them out. 345 00:16:23,390 --> 00:16:24,970 But for now I've kind of spoiled it. 346 00:16:24,970 --> 00:16:27,200 Obviously Enter is not the right solution. 347 00:16:27,200 --> 00:16:30,200 So let me clear my terminal window just to hide that error. 348 00:16:30,200 --> 00:16:32,050 Let me delete this. 349 00:16:32,050 --> 00:16:36,850 And let me propose now that I add this incantation here. 350 00:16:36,850 --> 00:16:39,610 So backslash n, it turns out, is going to be 351 00:16:39,610 --> 00:16:43,000 the sort of magical way of ensuring that you actually get 352 00:16:43,000 --> 00:16:45,830 a new line at the end of your output. 353 00:16:45,830 --> 00:16:49,930 So let me go ahead now and rerun "make hello," because I've changed my code. 354 00:16:49,930 --> 00:16:55,390 I need to now reconvert, recompile the source code to new machine. 355 00:16:55,390 --> 00:16:56,290 "./hello." 356 00:16:56,290 --> 00:17:00,580 And now, there is the canonical "hello, world" program 357 00:17:00,580 --> 00:17:03,330 that I hoped to write in the first place. 358 00:17:03,330 --> 00:17:05,863 So for now, don't worry about the include. 359 00:17:05,863 --> 00:17:07,280 Don't worry about the standard io. 360 00:17:07,280 --> 00:17:10,369 Don't worry about int or main or void or the curly braces. 361 00:17:10,369 --> 00:17:12,508 Focus primarily on line 5 here. 362 00:17:12,508 --> 00:17:14,300 And over the course of today and next week, 363 00:17:14,300 --> 00:17:16,520 we'll start to tease apart the other characters 364 00:17:16,520 --> 00:17:18,680 that, for now, you should take at face value. 365 00:17:18,680 --> 00:17:22,200 Questions, though, on any of the steps we've just done? 366 00:17:22,200 --> 00:17:22,700 Yeah? 367 00:17:22,700 --> 00:17:27,580 STUDENT: Why is the backslash n inside the apostrophes? 368 00:17:27,580 --> 00:17:31,940 DAVID MALAN: Sure, why is the backslash n inside of the quotation marks, 369 00:17:31,940 --> 00:17:32,570 if you will? 370 00:17:32,570 --> 00:17:35,350 So short answer is that's just where it needs 371 00:17:35,350 --> 00:17:40,600 to be because inside of the quotes is the input that you want printf 372 00:17:40,600 --> 00:17:42,320 to output to the screen. 373 00:17:42,320 --> 00:17:46,030 So if you want printf, this function, to output a new line, 374 00:17:46,030 --> 00:17:50,470 it must be included in the quoted text that you give it. 375 00:17:50,470 --> 00:17:53,555 STUDENT: So the backslash n [INAUDIBLE]. 376 00:17:53,555 --> 00:17:54,430 DAVID MALAN: Exactly. 377 00:17:54,430 --> 00:17:58,840 Backslash n is a special pattern that "printf no" means, OK, I should 378 00:17:58,840 --> 00:18:01,060 move the cursor to the next line. 379 00:18:01,060 --> 00:18:02,330 Good question. 380 00:18:02,330 --> 00:18:04,010 Other questions on any of these steps? 381 00:18:04,010 --> 00:18:04,510 Yeah? 382 00:18:04,510 --> 00:18:05,562 STUDENT: [INAUDIBLE] 383 00:18:05,562 --> 00:18:06,770 DAVID MALAN: A good question. 384 00:18:06,770 --> 00:18:10,120 So what if you actually want to print backslash n? 385 00:18:10,120 --> 00:18:12,140 Things get a little tricky there. 386 00:18:12,140 --> 00:18:15,920 Let me go ahead and propose that we do this. 387 00:18:15,920 --> 00:18:18,490 So it turns out-- and this is often the case in programming-- 388 00:18:18,490 --> 00:18:20,890 when you want a literal character to appear, 389 00:18:20,890 --> 00:18:23,347 you actually put another backslash in front of it. 390 00:18:23,347 --> 00:18:25,430 But this is not going to be something we do often. 391 00:18:25,430 --> 00:18:27,340 But there is in fact a solution to that. 392 00:18:27,340 --> 00:18:30,145 But let me propose that beyond that now we compare it 393 00:18:30,145 --> 00:18:31,520 against what we've actually done. 394 00:18:31,520 --> 00:18:35,260 So here is the first Scratch program we wrote with the green flag there. 395 00:18:35,260 --> 00:18:37,690 Here, recall, is the mental model that I proposed 396 00:18:37,690 --> 00:18:41,950 we have for almost everything we do whereby functions are just 397 00:18:41,950 --> 00:18:45,820 an implementation, say, in code of algorithms, step-by-step instructions 398 00:18:45,820 --> 00:18:47,150 for solving problems. 399 00:18:47,150 --> 00:18:49,300 The inputs to functions, recall from last week, 400 00:18:49,300 --> 00:18:52,330 are called arguments, or in some contexts parameters. 401 00:18:52,330 --> 00:18:55,130 And sometimes functions can have side effects. 402 00:18:55,130 --> 00:18:58,280 Like last time with Scratch, there was the speech bubble 403 00:18:58,280 --> 00:19:00,440 that magically appeared next to the cat's mouth 404 00:19:00,440 --> 00:19:02,930 as a sort of side effect of using the Say block. 405 00:19:02,930 --> 00:19:07,310 So just like this then, we had the white oval as input. 406 00:19:07,310 --> 00:19:09,590 The Say block was the function last week. 407 00:19:09,590 --> 00:19:11,790 And then we had this here, side effect. 408 00:19:11,790 --> 00:19:14,550 Well, how do we compare these things left to right? 409 00:19:14,550 --> 00:19:16,010 Well, here's the Say block at left. 410 00:19:16,010 --> 00:19:17,990 Let's compare now to the C code at right. 411 00:19:17,990 --> 00:19:22,400 Notice a couple of things to adapt from Scratch to C. Print 412 00:19:22,400 --> 00:19:23,970 is almost the name of the function. 413 00:19:23,970 --> 00:19:26,780 It is technically "printf," for reasons we'll eventually see. 414 00:19:26,780 --> 00:19:32,210 Notice the parentheses in C are kind of evocative of the oval in Scratch. 415 00:19:32,210 --> 00:19:36,140 And that's probably why MIT chose an oval, because a lot of languages 416 00:19:36,140 --> 00:19:37,850 use parentheses in this way. 417 00:19:37,850 --> 00:19:42,050 You still write "hello, world" just as we did last week in Scratch. 418 00:19:42,050 --> 00:19:45,800 But per our demo thus far, you do need the double quotes-- 419 00:19:45,800 --> 00:19:49,220 and double quotes, not single quotes-- double quotes on the left and right. 420 00:19:49,220 --> 00:19:52,580 And in order to get that new line, you need the backslash n. 421 00:19:52,580 --> 00:19:54,630 And one more thing is missing. 422 00:19:54,630 --> 00:19:55,130 Yeah? 423 00:19:55,130 --> 00:19:55,460 STUDENT: Semicolon. 424 00:19:55,460 --> 00:19:57,920 DAVID MALAN: The semicolon to finish your thought. 425 00:19:57,920 --> 00:20:00,020 So all of these sort of stupid things now 426 00:20:00,020 --> 00:20:03,395 that honestly you will forget initially if you've never programmed before, 427 00:20:03,395 --> 00:20:05,270 but you'll soon-- within days, within weeks-- 428 00:20:05,270 --> 00:20:08,330 develop the muscle memory where all of that stuff just jumps off, 429 00:20:08,330 --> 00:20:10,700 jumps off the page right at you. 430 00:20:10,700 --> 00:20:14,420 All right, so this backslash n is generally known, 431 00:20:14,420 --> 00:20:16,920 just so you know, as an escape sequence. 432 00:20:16,920 --> 00:20:20,420 And so backslash n allows us to specify a character that 433 00:20:20,420 --> 00:20:21,890 might otherwise be hard to type. 434 00:20:21,890 --> 00:20:26,150 But let's tease apart some of the other things atop that function already. 435 00:20:26,150 --> 00:20:28,880 So include stdio.h. 436 00:20:28,880 --> 00:20:33,290 It turns out that in C, a lot of the functionality that 437 00:20:33,290 --> 00:20:36,900 comes with the language is tucked away in separate files. 438 00:20:36,900 --> 00:20:40,650 So if you want to use certain functions, you have to tell the compiler, 439 00:20:40,650 --> 00:20:43,430 hey, I want to do some standard input and output. 440 00:20:43,430 --> 00:20:45,680 Like, I want to print some things on the screen. 441 00:20:45,680 --> 00:20:48,980 And that's because, for now, you can think of printf 442 00:20:48,980 --> 00:20:52,340 as living in this file, stdio.h. 443 00:20:52,340 --> 00:20:53,870 That's a bit of a white lie for now. 444 00:20:53,870 --> 00:20:57,890 But in stdio.h is essentially a declaration for printf 445 00:20:57,890 --> 00:21:01,820 that will teach the compiler how to print things to the screen. 446 00:21:01,820 --> 00:21:05,090 So "hash include" here simply tells the compiler 447 00:21:05,090 --> 00:21:07,790 before it does anything else essentially go ahead and find 448 00:21:07,790 --> 00:21:10,700 on the local hard drive a file called stdio.h 449 00:21:10,700 --> 00:21:14,330 and copy/paste it there so I know now about printf. 450 00:21:14,330 --> 00:21:19,673 So this thing, this .h file, is what we'll technically call a header file. 451 00:21:19,673 --> 00:21:21,590 And if you've ever heard this word, especially 452 00:21:21,590 --> 00:21:24,800 if you have programmed before, it represents essentially what 453 00:21:24,800 --> 00:21:26,390 we'll start calling a library. 454 00:21:26,390 --> 00:21:29,330 So a library in the world of programming is just code 455 00:21:29,330 --> 00:21:31,740 that someone else wrote that you can use. 456 00:21:31,740 --> 00:21:33,968 It's usually free and open source, which means 457 00:21:33,968 --> 00:21:36,260 you can literally see the code that someone else wrote, 458 00:21:36,260 --> 00:21:37,670 or sometimes you pay for it. 459 00:21:37,670 --> 00:21:40,370 Sometimes it's closed source, which maybe Microsoft wrote it. 460 00:21:40,370 --> 00:21:43,850 They won't show you the code, but they will let you use the zeros and ones. 461 00:21:43,850 --> 00:21:46,670 So libraries are super useful because honestly 462 00:21:46,670 --> 00:21:49,700 even I don't really know how printf works. 463 00:21:49,700 --> 00:21:52,340 I've taken for granted for 25 years that if I use printf, 464 00:21:52,340 --> 00:21:53,780 stuff prints on the screen. 465 00:21:53,780 --> 00:21:56,330 But someone smarter than me had to actually write 466 00:21:56,330 --> 00:22:00,860 the code in C that figures out how to get the H, the E, the L-L-O, and so 467 00:22:00,860 --> 00:22:05,320 forth onto the Mac screen, the PC screen, the phone screen, or somewhere 468 00:22:05,320 --> 00:22:05,820 else. 469 00:22:05,820 --> 00:22:08,510 So libraries allow us to stand on each other's shoulders 470 00:22:08,510 --> 00:22:10,910 and so that someone else can do the hard work, 471 00:22:10,910 --> 00:22:14,550 and we can now solve problems that are more interesting to us, 472 00:22:14,550 --> 00:22:18,060 not the basic commodity stuff that everyone might want in their code. 473 00:22:18,060 --> 00:22:20,480 So again, library is code that someone else wrote. 474 00:22:20,480 --> 00:22:23,540 A header file in C is just a file ending in ".h" 475 00:22:23,540 --> 00:22:25,440 that gives you access to the same. 476 00:22:25,440 --> 00:22:28,040 And so for instance, if you to learn more about these, 477 00:22:28,040 --> 00:22:31,410 there are, what are called in the world of programming, manual pages. 478 00:22:31,410 --> 00:22:37,190 And these are textual files, like a documentation of sorts, 479 00:22:37,190 --> 00:22:39,860 via which you can just learn how a function works 480 00:22:39,860 --> 00:22:42,830 or how you can use its inputs or arguments. 481 00:22:42,830 --> 00:22:45,660 The reality is they're written for folks who aren't in CS50. 482 00:22:45,660 --> 00:22:48,410 They're written for folks who aren't just learning how to program. 483 00:22:48,410 --> 00:22:51,330 They're written for and by folks who have been programming for years. 484 00:22:51,330 --> 00:22:53,510 And so frankly, they're a little hard to understand. 485 00:22:53,510 --> 00:22:58,690 And so CS50 has its own version thereof at this URL, manual.cs50.io, 486 00:22:58,690 --> 00:23:03,260 where you'll see not only the official documentation for C, the language, 487 00:23:03,260 --> 00:23:07,360 but also staff-written simplifications in layperson's terms 488 00:23:07,360 --> 00:23:10,720 what all of the various popular functions are, what their inputs, 489 00:23:10,720 --> 00:23:12,130 and what their outputs are. 490 00:23:12,130 --> 00:23:17,990 So for instance, under stdio.h, you can actually go to that website. 491 00:23:17,990 --> 00:23:21,970 You can go to a URL like this, where stdio.h is in there. 492 00:23:21,970 --> 00:23:24,348 And you can actually see the documentation therefore. 493 00:23:24,348 --> 00:23:25,640 So let me go ahead and do this. 494 00:23:25,640 --> 00:23:27,640 I'm going to go ahead in my browser here, 495 00:23:27,640 --> 00:23:31,240 I'm going to go to manual.cs50.io. 496 00:23:31,240 --> 00:23:33,880 And let me go ahead here and select those functions 497 00:23:33,880 --> 00:23:36,220 that are frequently used in CS50. 498 00:23:36,220 --> 00:23:39,820 And under stdio.h, you'll see a bunch of functions, 499 00:23:39,820 --> 00:23:42,730 only one of which we've even discussed called printf. 500 00:23:42,730 --> 00:23:44,560 I'm going to click on printf there. 501 00:23:44,560 --> 00:23:46,573 And you'll see an interface that at first glance 502 00:23:46,573 --> 00:23:48,490 might be a little overwhelming, but it's going 503 00:23:48,490 --> 00:23:50,300 to start to look more and more familiar. 504 00:23:50,300 --> 00:23:54,620 So first of all, you'll see that if you want to use printf under Synopsis, 505 00:23:54,620 --> 00:23:56,690 you need to include this header file. 506 00:23:56,690 --> 00:23:59,960 Like, you literally copy and paste that line into your own code. 507 00:23:59,960 --> 00:24:03,440 You'll also see this, which for now is a bit arcane, 508 00:24:03,440 --> 00:24:07,890 but this is kind of a hint as to what the function is going to look like. 509 00:24:07,890 --> 00:24:09,043 But more on that soon. 510 00:24:09,043 --> 00:24:11,460 But more importantly, you can read a description about it. 511 00:24:11,460 --> 00:24:14,390 And because these descriptions, when you're in less comfortable mode, 512 00:24:14,390 --> 00:24:17,432 are written by me and the course's teaching fellows, teaching assistants, 513 00:24:17,432 --> 00:24:20,970 and course assistants, you'll find them to be much more in layperson's terms. 514 00:24:20,970 --> 00:24:23,340 And so long story short, rely on this site 515 00:24:23,340 --> 00:24:25,580 once you want to learn how to use some function 516 00:24:25,580 --> 00:24:27,960 and also what other functions exist. 517 00:24:27,960 --> 00:24:29,970 In fact, if I go back to the main page here, 518 00:24:29,970 --> 00:24:33,890 you'll see that there are all of these functions like are frequently 519 00:24:33,890 --> 00:24:35,000 used in CS50. 520 00:24:35,000 --> 00:24:37,190 And there's hundreds more that come with C. 521 00:24:37,190 --> 00:24:40,340 But learning a programming language is not about learning all of those 522 00:24:40,340 --> 00:24:45,020 but rather just getting a sense of where you find answers to questions when 523 00:24:45,020 --> 00:24:47,760 you do want to try something new. 524 00:24:47,760 --> 00:24:50,330 But what is important to know for CS50 today 525 00:24:50,330 --> 00:24:55,600 is that we have our own header file called cs50.h which has functions 526 00:24:55,600 --> 00:24:57,910 that we have written just to make life easier 527 00:24:57,910 --> 00:24:59,675 in the first few weeks of the class. 528 00:24:59,675 --> 00:25:02,050 These are training wheels that we'll eventually take off. 529 00:25:02,050 --> 00:25:04,270 But it turns out in C, especially if you've 530 00:25:04,270 --> 00:25:07,120 programmed before, it's actually really hard and annoying just 531 00:25:07,120 --> 00:25:11,900 to get input from users, to get them to type a word or a number or something 532 00:25:11,900 --> 00:25:12,400 else. 533 00:25:12,400 --> 00:25:15,850 Like, C does not make this easy, in part because it's one of the earliest 534 00:25:15,850 --> 00:25:17,800 languages that wasn't zeros and ones. 535 00:25:17,800 --> 00:25:20,050 So you have to do a lot of the heavy lifting yourself. 536 00:25:20,050 --> 00:25:23,200 But we'll put on these training wheels today and for a few weeks 537 00:25:23,200 --> 00:25:28,150 so that we can focus really on the intellectually interesting ideas of C 538 00:25:28,150 --> 00:25:30,970 and programming without getting bogged down in certain weeds 539 00:25:30,970 --> 00:25:33,160 that we will come back to before long. 540 00:25:33,160 --> 00:25:36,820 So for instance, CS50's own documentation is there at that URL. 541 00:25:36,820 --> 00:25:40,550 But within the library are these functions, 542 00:25:40,550 --> 00:25:44,440 a function called get_string to get a string of text. 543 00:25:44,440 --> 00:25:47,330 "String" is a synonym for just text in a programming language. 544 00:25:47,330 --> 00:25:50,170 So get_string will prompt the human for a string of text. 545 00:25:50,170 --> 00:25:52,660 Get_int is shorthand for "get integer," if you 546 00:25:52,660 --> 00:25:54,890 want to get a number from the user. 547 00:25:54,890 --> 00:25:58,550 Get_float is a little more arcane-- get a floating point number, 548 00:25:58,550 --> 00:26:00,780 like a real number with a decimal point in it. 549 00:26:00,780 --> 00:26:03,690 And dot, dot, dot, there are others, as well. 550 00:26:03,690 --> 00:26:08,180 So this is to say within CS50, we've got some user-friendly functions via which 551 00:26:08,180 --> 00:26:09,563 we can actually get some input. 552 00:26:09,563 --> 00:26:12,230 And let's go ahead and use one of these, for instance get_string 553 00:26:12,230 --> 00:26:15,950 because recall that last week our second program in Scratch 554 00:26:15,950 --> 00:26:18,920 was this one here, where we didn't just say "hello, world." 555 00:26:18,920 --> 00:26:21,110 We said "hello, David," or "hello, Carter," 556 00:26:21,110 --> 00:26:24,590 "hello, Julia," whoever it was typing their name in. 557 00:26:24,590 --> 00:26:28,910 But to do that, we needed this Ask block in Scratch. 558 00:26:28,910 --> 00:26:30,470 And then we used the Say block. 559 00:26:30,470 --> 00:26:34,050 And then we used the Join block to make all of this work. 560 00:26:34,050 --> 00:26:36,352 So let's translate this program now into C 561 00:26:36,352 --> 00:26:39,560 because it's a little more interesting and representative of the kind of code 562 00:26:39,560 --> 00:26:40,670 we'll start to write. 563 00:26:40,670 --> 00:26:42,950 But we need a slightly different mental model. 564 00:26:42,950 --> 00:26:47,450 Still have a function here, which is the implementation in code of an algorithm. 565 00:26:47,450 --> 00:26:49,910 We still have some inputs called arguments. 566 00:26:49,910 --> 00:26:53,330 But previously, I said that the Say block and, in turn, 567 00:26:53,330 --> 00:26:56,870 printf have side effects, which is just something visually, typically, 568 00:26:56,870 --> 00:26:58,340 that happens on the screen. 569 00:26:58,340 --> 00:27:02,900 Other functions actually have, what we called last week, return values. 570 00:27:02,900 --> 00:27:08,540 And this is kind of analogous to a function maybe doing something for you, 571 00:27:08,540 --> 00:27:11,990 writing down the answer on a slip of paper, and then handing you, 572 00:27:11,990 --> 00:27:14,180 the programmer, the slip of paper to do whatever 573 00:27:14,180 --> 00:27:16,430 you want with it without just broadcasting it 574 00:27:16,430 --> 00:27:19,190 to the world with, like, a speech bubble on the screen. 575 00:27:19,190 --> 00:27:22,610 So a return value is germane for a program like this 576 00:27:22,610 --> 00:27:26,960 because recall when we used the Ask block and I typed in my name, 577 00:27:26,960 --> 00:27:30,650 where did my name end up initially? 578 00:27:30,650 --> 00:27:32,217 It didn't go on the screen yet. 579 00:27:32,217 --> 00:27:33,050 Where did it end up? 580 00:27:33,050 --> 00:27:33,967 STUDENT: In an answer. 581 00:27:33,967 --> 00:27:35,900 DAVID MALAN: In an "answer" puzzle piece. 582 00:27:35,900 --> 00:27:39,320 And that special oval puzzle piece I claimed at the time 583 00:27:39,320 --> 00:27:43,250 represents a return value, so the metaphorical piece of paper 584 00:27:43,250 --> 00:27:46,410 that the answer is written down on so that I can then use it later. 585 00:27:46,410 --> 00:27:48,740 So that's what we want to get to now in C, 586 00:27:48,740 --> 00:27:51,832 a return value that I can then do anything I want, 587 00:27:51,832 --> 00:27:54,290 whether it's print it to the screen, change it in some way, 588 00:27:54,290 --> 00:27:56,430 save it in a database, or anything else. 589 00:27:56,430 --> 00:27:58,670 So here, for instance, is what we did with Scratch, 590 00:27:58,670 --> 00:28:02,510 the input to the Say block-- or the Ask block was "what's your name," quote, 591 00:28:02,510 --> 00:28:03,140 unquote. 592 00:28:03,140 --> 00:28:05,120 The function, of course, is the Ask function. 593 00:28:05,120 --> 00:28:07,310 And the return value was "answer." 594 00:28:07,310 --> 00:28:10,880 If we now consider how we might translate this to C, 595 00:28:10,880 --> 00:28:12,770 it's going to look a little weird at first. 596 00:28:12,770 --> 00:28:15,680 But it's going to follow a pattern today, next week, the week 597 00:28:15,680 --> 00:28:18,090 after any time we do code like this. 598 00:28:18,090 --> 00:28:23,480 So get_string, I claim, is going to be the most analogous function in C 599 00:28:23,480 --> 00:28:24,650 to the Ask block. 600 00:28:24,650 --> 00:28:28,400 And to be clear, this is a CS50-specific thing, training wheels of sorts. 601 00:28:28,400 --> 00:28:31,520 But we'll show you in a few weeks what this function is doing and how you 602 00:28:31,520 --> 00:28:35,750 cannot use it moving forward once you're comfortable with the language itself. 603 00:28:35,750 --> 00:28:37,820 Notice I've put parentheses, left and right, 604 00:28:37,820 --> 00:28:39,950 as sort of a placeholder for user input. 605 00:28:39,950 --> 00:28:43,118 And that user input is going to be "what's your name?" 606 00:28:43,118 --> 00:28:45,410 But I can't just put "what's your name" in parentheses. 607 00:28:45,410 --> 00:28:47,327 What do I minimally need to add in there, too? 608 00:28:47,327 --> 00:28:48,020 STUDENT: Quotes. 609 00:28:48,020 --> 00:28:50,353 DAVID MALAN: Yeah, so the double quotes, left and right. 610 00:28:50,353 --> 00:28:52,250 So let me go ahead and add those in. 611 00:28:52,250 --> 00:28:55,040 I left a space here, not for a new line. 612 00:28:55,040 --> 00:28:56,990 I could move the cursor to the next line. 613 00:28:56,990 --> 00:29:00,440 But I minimally at least want to move the cursor at least one space over 614 00:29:00,440 --> 00:29:03,140 just so it looks pretty, so that when I'm prompted for my name, 615 00:29:03,140 --> 00:29:05,810 there's a space between the question and my answer. 616 00:29:05,810 --> 00:29:07,280 But it could also be backslash n. 617 00:29:07,280 --> 00:29:09,830 That's just an aesthetic choice on my part. 618 00:29:09,830 --> 00:29:14,037 But what do I do with the answer that comes back from get_string? 619 00:29:14,037 --> 00:29:16,370 This is where the text is going to look different today. 620 00:29:16,370 --> 00:29:21,770 In C, you start to use an equals sign from left to right respectively. 621 00:29:21,770 --> 00:29:26,540 And on the left, you put the name of the variable in which you 622 00:29:26,540 --> 00:29:29,730 want to store that return value. 623 00:29:29,730 --> 00:29:32,030 So a return value is kind of a conceptual thing. 624 00:29:32,030 --> 00:29:33,900 You can do with it what you want. 625 00:29:33,900 --> 00:29:36,590 And if I want to store it longer term in a variable, 626 00:29:36,590 --> 00:29:40,580 like x or y or z in math class, I can just give it a name here-- x 627 00:29:40,580 --> 00:29:45,410 or y or z or, more reasonably, "answer," or any other English word. 628 00:29:45,410 --> 00:29:49,850 No spaces, generally lowercase, same heuristics as before, but this means 629 00:29:49,850 --> 00:29:53,010 now, ask the user, what's their name? 630 00:29:53,010 --> 00:29:55,620 Whatever they type in, go ahead and store it from right 631 00:29:55,620 --> 00:29:58,470 to left in this variable called "answer." 632 00:29:58,470 --> 00:29:59,880 But C's not done with us yet. 633 00:29:59,880 --> 00:30:02,130 If you've learned Python or certain other languages, 634 00:30:02,130 --> 00:30:04,470 you'd kind of be done writing code at this point. 635 00:30:04,470 --> 00:30:09,840 In C, though, you additionally have to tell the compiler what type of variable 636 00:30:09,840 --> 00:30:11,080 you want to use. 637 00:30:11,080 --> 00:30:13,590 So if it's a string of text, you say "string." 638 00:30:13,590 --> 00:30:17,668 If it's an integer, a number, you say "int," as we might have seen before. 639 00:30:17,668 --> 00:30:18,960 So it's a little more pedantic. 640 00:30:18,960 --> 00:30:22,320 It's more annoying, frankly, the more onus on you and me, the programmers. 641 00:30:22,320 --> 00:30:24,120 But this just helps the compiler know how 642 00:30:24,120 --> 00:30:26,260 to store it in the computer's memory. 643 00:30:26,260 --> 00:30:29,838 And I'm so close to being done with this line of code, but what's missing? 644 00:30:29,838 --> 00:30:30,630 STUDENT: Semicolon. 645 00:30:30,630 --> 00:30:31,713 DAVID MALAN: So semicolon. 646 00:30:31,713 --> 00:30:34,980 And mark my words, if you've never programmed before, sometime this week, 647 00:30:34,980 --> 00:30:37,290 this semester, you will forget a semicolon. 648 00:30:37,290 --> 00:30:38,678 You will raise your hand. 649 00:30:38,678 --> 00:30:41,970 You'll get frustrated because you can't understand why your code's not working. 650 00:30:41,970 --> 00:30:44,370 You will run into stupid issues like that. 651 00:30:44,370 --> 00:30:46,385 But do take faith that they are stupid issues. 652 00:30:46,385 --> 00:30:49,260 It doesn't mean it's not clicking for you or you're not a programmer. 653 00:30:49,260 --> 00:30:53,020 It just takes time to see these things if it's a new language to you. 654 00:30:53,020 --> 00:30:54,960 So there now is my semicolon. 655 00:30:54,960 --> 00:30:58,110 All right, let's go ahead then and do something 656 00:30:58,110 --> 00:31:02,100 with that return value using the second of the big puzzle pieces in Scratch. 657 00:31:02,100 --> 00:31:06,720 So when I wanted to say, "hello, David," or whatever the human's name is, 658 00:31:06,720 --> 00:31:09,850 I kind of stacked my puzzle pieces like this. 659 00:31:09,850 --> 00:31:13,350 This is actually similar to Python and maybe some other languages some of you 660 00:31:13,350 --> 00:31:13,980 have learned. 661 00:31:13,980 --> 00:31:15,990 But C is a little bit different. 662 00:31:15,990 --> 00:31:21,750 And the closest analog to this Scratch solution is going to look like this. 663 00:31:21,750 --> 00:31:25,080 I still use printf because printf is the equivalent of Say. 664 00:31:25,080 --> 00:31:32,022 Inside of my parentheses, I'm going to go ahead and say, weirdly, "hello, %s." 665 00:31:32,022 --> 00:31:35,580 So there's no real analog in C of Join. 666 00:31:35,580 --> 00:31:41,970 Instead, there's a way to specially format text using printf, hence the F 667 00:31:41,970 --> 00:31:42,900 in "printf." 668 00:31:42,900 --> 00:31:45,630 And what you do in printf is you type whatever English word 669 00:31:45,630 --> 00:31:47,280 or human words that you want. 670 00:31:47,280 --> 00:31:50,110 You then use %s a placeholder. 671 00:31:50,110 --> 00:31:54,450 If you want a string of text to be added to your own text, 672 00:31:54,450 --> 00:31:55,935 you literally write "%s." 673 00:31:55,935 --> 00:31:59,640 And let me anticipate a question from the crowd-- how do you print out %s? 674 00:31:59,640 --> 00:32:03,690 There's a solution to that, too, if you literally ever want to print out %s. 675 00:32:03,690 --> 00:32:07,390 But it's deliberately a weird choice of characters 676 00:32:07,390 --> 00:32:10,140 so that the probability that we ever need to type this ourselves 677 00:32:10,140 --> 00:32:12,870 is just low that no one really worries too much about it. 678 00:32:12,870 --> 00:32:14,550 All right, but that's not quite enough. 679 00:32:14,550 --> 00:32:19,890 In addition to saying "hello", comma, space, placeholder %s-- 680 00:32:19,890 --> 00:32:23,880 and just for vocabulary sake, that's a format code. 681 00:32:23,880 --> 00:32:26,250 Again, "format" being the F in printf. 682 00:32:26,250 --> 00:32:29,010 I still need my double quotes around the whole thing. 683 00:32:29,010 --> 00:32:31,290 In this case, to match my previous program, 684 00:32:31,290 --> 00:32:33,270 I am going to go ahead and add the backslash n 685 00:32:33,270 --> 00:32:35,910 to move the cursor to the next line. 686 00:32:35,910 --> 00:32:39,840 And now I've left a crazy amount of room here, but that's deliberate. 687 00:32:39,840 --> 00:32:42,240 Does anyone have an instinct for what I'm probably 688 00:32:42,240 --> 00:32:47,180 going to want to add after the quotes but still inside of the parentheses? 689 00:32:47,180 --> 00:32:48,310 STUDENT: The answer. 690 00:32:48,310 --> 00:32:49,840 DAVID MALAN: So answer itself. 691 00:32:49,840 --> 00:32:54,010 I need to somehow tell printf with a second input, 692 00:32:54,010 --> 00:32:58,870 otherwise known as an argument, what I want to substitute for that %s. 693 00:32:58,870 --> 00:33:02,650 And so I put a comma and then the name of the variable 694 00:33:02,650 --> 00:33:06,028 that I want printf to figure out how to plug in here. 695 00:33:06,028 --> 00:33:09,070 So honestly it's a little annoying, and this is kind of a dated approach. 696 00:33:09,070 --> 00:33:11,620 Newer, more modern languages, like we'll see later 697 00:33:11,620 --> 00:33:13,630 in the course, Python and JavaScript, actually 698 00:33:13,630 --> 00:33:15,950 have much more user-friendly ways of doing it. 699 00:33:15,950 --> 00:33:19,390 But once you wrap your mind around the heuristics, the rules here, 700 00:33:19,390 --> 00:33:23,470 it's just formatting a string by plugging in whatever you want 701 00:33:23,470 --> 00:33:26,470 into this format string, so to speak. 702 00:33:26,470 --> 00:33:28,810 And again, the comma here is important. 703 00:33:28,810 --> 00:33:33,220 This signifies that it takes one input at left and a second input at right. 704 00:33:33,220 --> 00:33:34,420 But notice this comma. 705 00:33:34,420 --> 00:33:35,950 There's technically two commas. 706 00:33:35,950 --> 00:33:40,480 But I'm not claiming that this function takes three inputs. 707 00:33:40,480 --> 00:33:41,680 Why? 708 00:33:41,680 --> 00:33:43,975 This comma I'm pointing out doesn't mean the same. 709 00:33:43,975 --> 00:33:46,690 STUDENT: It's because that comma's part of the quotation marks 710 00:33:46,690 --> 00:33:48,070 and it's been part of the string. 711 00:33:48,070 --> 00:33:48,700 DAVID MALAN: Exactly. 712 00:33:48,700 --> 00:33:51,867 This comma that I'm pointing to is part of the quotation marks and therefore 713 00:33:51,867 --> 00:33:53,910 part of my string of English text. 714 00:33:53,910 --> 00:33:55,400 So this is just English grammar. 715 00:33:55,400 --> 00:33:57,140 This is sort of C syntax. 716 00:33:57,140 --> 00:33:59,810 And again, these are the sort of annoying little details 717 00:33:59,810 --> 00:34:03,795 that we're using the same symbol for different things, but context matters. 718 00:34:03,795 --> 00:34:06,170 So just stare at your code, look carefully left to right, 719 00:34:06,170 --> 00:34:10,080 and generally the answer will pop out, no pun intended. 720 00:34:10,080 --> 00:34:13,244 OK, questions now on this syntax before we actually write it and run it? 721 00:34:13,244 --> 00:34:13,744 Yeah? 722 00:34:13,744 --> 00:34:18,290 STUDENT: Why is the backslash n not after the answer? 723 00:34:18,290 --> 00:34:20,940 DAVID MALAN: Why is the backslash n not after the answer? 724 00:34:20,940 --> 00:34:24,230 So the way functions work, including printf, 725 00:34:24,230 --> 00:34:28,310 is that you pass to them one argument inside of the parentheses. 726 00:34:28,310 --> 00:34:32,690 And then if you have a second argument, you put it after this comma here. 727 00:34:32,690 --> 00:34:36,920 But the way printf works is that its first argument is always a string 728 00:34:36,920 --> 00:34:39,330 that you want to be formatted for you. 729 00:34:39,330 --> 00:34:43,340 So anything you want printed on the screen has to go in those quotes. 730 00:34:43,340 --> 00:34:45,560 And you can perhaps extrapolate from this. 731 00:34:45,560 --> 00:34:50,389 If I actually wanted to say multiple things in this sentence, so "hello," 732 00:34:50,389 --> 00:34:55,670 maybe first name, last name, I could actually do "hello" comma, %s, space, 733 00:34:55,670 --> 00:34:59,960 %s, if I had two variables, one called First Name, one called Last Name. 734 00:34:59,960 --> 00:35:04,890 But then I would need another comma for a third input to the function. 735 00:35:04,890 --> 00:35:07,790 And so it's very general purpose in that sense. 736 00:35:07,790 --> 00:35:08,720 Questions? 737 00:35:08,720 --> 00:35:09,702 Yeah? 738 00:35:09,702 --> 00:35:15,370 STUDENT: Can you abstract this further by [INAUDIBLE] the "hello" [INAUDIBLE]?? 739 00:35:15,370 --> 00:35:19,870 DAVID MALAN: OK, so can you abstract away the format string itself, "hello," 740 00:35:19,870 --> 00:35:20,560 comma answer? 741 00:35:20,560 --> 00:35:23,770 Short answer, yes, but not nearly as easily in C 742 00:35:23,770 --> 00:35:25,280 as you can in other languages. 743 00:35:25,280 --> 00:35:26,920 So that's why we're keeping it simple for now. 744 00:35:26,920 --> 00:35:29,200 But you're going to love something like Python or JavaScript, 745 00:35:29,200 --> 00:35:31,090 where a lot of this complexity goes away. 746 00:35:31,090 --> 00:35:34,300 But you'll see also in Python and JavaScript and other languages, 747 00:35:34,300 --> 00:35:37,610 they still are inspired by syntax like this. 748 00:35:37,610 --> 00:35:41,350 So just understanding it now will be useful for multiple languages 749 00:35:41,350 --> 00:35:42,670 down the line. 750 00:35:42,670 --> 00:35:45,190 All right, so let's actually do something with this code 751 00:35:45,190 --> 00:35:48,670 rather than just talk about what it might be doing for us. 752 00:35:48,670 --> 00:35:52,400 Let me go over to, for instance, VS Code again. 753 00:35:52,400 --> 00:35:56,920 And I'm going to go ahead now and remove this middle line of printf. 754 00:35:56,920 --> 00:35:59,337 I'm still in my same file called "hello.c." 755 00:35:59,337 --> 00:36:02,170 I'm going to clear my terminal window just to eliminate distraction. 756 00:36:02,170 --> 00:36:04,097 And to do that, I can literally type "clear." 757 00:36:04,097 --> 00:36:05,680 But this is just for aesthetic's sake. 758 00:36:05,680 --> 00:36:07,240 That's not functionally that useful. 759 00:36:07,240 --> 00:36:10,363 Or you can hit Control L to achieve the same on your keyboard. 760 00:36:10,363 --> 00:36:13,030 But I'm going to go back to line 5 here, where I previously just 761 00:36:13,030 --> 00:36:14,990 said "hello, world." 762 00:36:14,990 --> 00:36:17,390 And I'm going to do this instead. 763 00:36:17,390 --> 00:36:20,330 I'm going to give myself a variable called string. 764 00:36:20,330 --> 00:36:22,760 Sorry, I'm going to give myself a variable called 765 00:36:22,760 --> 00:36:25,280 answer, the type of which is string. 766 00:36:25,280 --> 00:36:28,220 I'm going to set it equal to whatever the return 767 00:36:28,220 --> 00:36:33,290 value is of get_string, asking an English question, "what's your name?" 768 00:36:33,290 --> 00:36:36,290 with just a single space just to move the cursor over, 769 00:36:36,290 --> 00:36:38,430 followed by a semicolon. 770 00:36:38,430 --> 00:36:41,300 Then I'm going to go ahead and say printf, quote, 771 00:36:41,300 --> 00:36:48,680 unquote, "hello, placeholder, backslash n," 772 00:36:48,680 --> 00:36:50,900 comma, and then what goes here again? 773 00:36:50,900 --> 00:36:51,680 STUDENT: Answer. 774 00:36:51,680 --> 00:36:53,420 DAVID MALAN: This is where answer goes. 775 00:36:53,420 --> 00:36:56,430 And then I just need a semicolon on the right of that. 776 00:36:56,430 --> 00:36:58,042 But I think now that I'm done. 777 00:36:58,042 --> 00:36:59,750 But let me point out a couple of details. 778 00:36:59,750 --> 00:37:01,940 This got very colorful, very pretty quickly. 779 00:37:01,940 --> 00:37:05,610 And it's not like the black and white code I had on the screen a moment ago. 780 00:37:05,610 --> 00:37:10,160 This is because what programs like VS Code do for us is it "pretty" prints, 781 00:37:10,160 --> 00:37:13,980 or rather it syntax highlights our code for us. 782 00:37:13,980 --> 00:37:17,060 So syntax highlighting means just add some colors to the code 783 00:37:17,060 --> 00:37:19,080 so that different ideas pop out. 784 00:37:19,080 --> 00:37:22,760 So you'll notice, for instance, that printf here, get_string here 785 00:37:22,760 --> 00:37:26,210 are in purple because they represent functions, just like the Say block. 786 00:37:26,210 --> 00:37:28,460 Here, "what's your name?", quote, unquote, in VS Code 787 00:37:28,460 --> 00:37:29,990 is a light blue instead of white. 788 00:37:29,990 --> 00:37:33,230 But it's still going to be consistent if I use strings of text elsewhere, 789 00:37:33,230 --> 00:37:33,810 as well. 790 00:37:33,810 --> 00:37:35,453 So I didn't type anything special. 791 00:37:35,453 --> 00:37:37,370 This isn't like Microsoft Word or Google Docs, 792 00:37:37,370 --> 00:37:39,578 where I'm highlighting and changing colors of things. 793 00:37:39,578 --> 00:37:41,180 This is all happening automatically. 794 00:37:41,180 --> 00:37:44,060 But it's just unicode text. 795 00:37:44,060 --> 00:37:46,340 It's just being interpreted automatically 796 00:37:46,340 --> 00:37:51,080 and having these colors applied so that things pop out more usefully visually. 797 00:37:51,080 --> 00:37:52,985 Now, I've unfortunately made a mistake. 798 00:37:52,985 --> 00:37:55,610 But I'm going to deliberately induce this one because you, too, 799 00:37:55,610 --> 00:37:57,130 will probably make this mistake. 800 00:37:57,130 --> 00:37:58,880 I'm going to go ahead and run "make hello" 801 00:37:58,880 --> 00:38:00,380 again, because I've changed my code. 802 00:38:00,380 --> 00:38:03,740 So I have to regenerate the machine code from the new source code. 803 00:38:03,740 --> 00:38:06,950 But unfortunately, when I hit Enter now, my God, 804 00:38:06,950 --> 00:38:08,790 the errors don't even fit on the screen. 805 00:38:08,790 --> 00:38:09,990 So let me make this bigger. 806 00:38:09,990 --> 00:38:12,157 I'm going to click the little caret symbol here just 807 00:38:12,157 --> 00:38:14,360 to make my terminal bigger for just a moment. 808 00:38:14,360 --> 00:38:17,090 And you'll see that there's more lines of errors 809 00:38:17,090 --> 00:38:19,370 than there are of code that I actually wrote, 810 00:38:19,370 --> 00:38:22,730 often which is written pretty arcanely, again, for programmers who've 811 00:38:22,730 --> 00:38:24,830 been writing code for 10, 20 years. 812 00:38:24,830 --> 00:38:27,210 But there are some details that pop out. 813 00:38:27,210 --> 00:38:30,620 So notice the problem is definitely with hello.c. 814 00:38:30,620 --> 00:38:36,180 So great, it is my fault. This syntax here means that line 5 is the problem. 815 00:38:36,180 --> 00:38:38,810 And this next 5 means character 5. 816 00:38:38,810 --> 00:38:42,860 So you can literally triangulate your bug, your mistake by going to line 5 817 00:38:42,860 --> 00:38:45,440 and then over five, and it's somewhere in that area. 818 00:38:45,440 --> 00:38:49,280 Specifically, "the area is use of undeclared identifier string. 819 00:38:49,280 --> 00:38:51,320 Did you mean standard in?" 820 00:38:51,320 --> 00:38:52,460 I don't think I did. 821 00:38:52,460 --> 00:38:56,120 Like, I do want string, and then there's some other complexity here. 822 00:38:56,120 --> 00:39:00,860 But what's important here is not the specifics of this error but really 823 00:39:00,860 --> 00:39:04,010 the implication that it doesn't recognize the word 824 00:39:04,010 --> 00:39:06,590 "string" or "get_string." 825 00:39:06,590 --> 00:39:08,355 Now, why might this be? 826 00:39:08,355 --> 00:39:08,855 Yeah? 827 00:39:08,855 --> 00:39:14,195 STUDENT: You said that in order to [INAUDIBLE] 828 00:39:14,195 --> 00:39:15,070 DAVID MALAN: Exactly. 829 00:39:15,070 --> 00:39:17,740 Because we are using get_string, which I claimed 830 00:39:17,740 --> 00:39:19,930 is a CS50 thing that we'll use for a few weeks, 831 00:39:19,930 --> 00:39:22,910 C does not know about it out of the box, so to speak. 832 00:39:22,910 --> 00:39:26,080 I have to teach the compiler that get_string exists, 833 00:39:26,080 --> 00:39:29,620 just like I taught the compiler that printf exists by including 834 00:39:29,620 --> 00:39:31,010 the appropriate header file. 835 00:39:31,010 --> 00:39:35,200 And in this case, quite simply, it's called includeCS50.h. 836 00:39:35,200 --> 00:39:38,890 That now teaches the compiler, oh, someone else 837 00:39:38,890 --> 00:39:42,220 wrote this function already, get_string, and with it this type of variable 838 00:39:42,220 --> 00:39:43,190 called "string." 839 00:39:43,190 --> 00:39:45,430 So now if I go back to my terminal window 840 00:39:45,430 --> 00:39:49,510 and rerun the exact same command, "make hello"-- maybe crossing my fingers-- 841 00:39:49,510 --> 00:39:52,060 now nothing in fact goes wrong because the compiler 842 00:39:52,060 --> 00:39:55,210 has been brought up to speed with all of the functionality it needs. 843 00:39:55,210 --> 00:39:59,410 And now if I do ./hello, Enter, there it is, what's my name? 844 00:39:59,410 --> 00:40:01,330 And notice the cursor is one space over just 845 00:40:01,330 --> 00:40:03,550 because I thought that looked prettier than having the cursor right 846 00:40:03,550 --> 00:40:05,110 next to the question mark. 847 00:40:05,110 --> 00:40:07,840 D-A-V-I-D as my input, and Enter. 848 00:40:07,840 --> 00:40:11,890 And "hello, David." 849 00:40:11,890 --> 00:40:16,780 Questions on any of this code thus far? 850 00:40:16,780 --> 00:40:18,630 Questions? 851 00:40:18,630 --> 00:40:20,800 Any of the code. 852 00:40:20,800 --> 00:40:21,370 No? 853 00:40:21,370 --> 00:40:25,630 All right, so let's introduce some other functionality into the mix. 854 00:40:25,630 --> 00:40:28,570 It turns out that there are other types of data, 855 00:40:28,570 --> 00:40:31,270 other types of variables in the world, not just strings 856 00:40:31,270 --> 00:40:33,790 but indeed, per before, we have things called 857 00:40:33,790 --> 00:40:38,260 integers, "int" for short, floating point values, "float" for short, 858 00:40:38,260 --> 00:40:39,590 and a few others as well. 859 00:40:39,590 --> 00:40:41,530 So rather than only focus on string, let's 860 00:40:41,530 --> 00:40:43,330 get a little more interesting with numbers 861 00:40:43,330 --> 00:40:46,660 here and see what we can do with something like integers, again 862 00:40:46,660 --> 00:40:51,130 "int" for short, by taking a look at not get_string, as before, but now 863 00:40:51,130 --> 00:40:52,630 how about get_int. 864 00:40:52,630 --> 00:40:56,110 And for this, I'm going to give us a few other tools in our toolkit, 865 00:40:56,110 --> 00:40:59,986 those format codes to which I alluded earlier, like %s, 866 00:40:59,986 --> 00:41:01,640 fortunately are pretty straightforward. 867 00:41:01,640 --> 00:41:04,930 And here is a list of most of the popular format codes 868 00:41:04,930 --> 00:41:07,510 that you might ever care about with printf. 869 00:41:07,510 --> 00:41:10,180 In particular, we saw %s for string. 870 00:41:10,180 --> 00:41:13,060 And you can perhaps guess which one we're going to use for integers. 871 00:41:13,060 --> 00:41:13,932 STUDENT: %i. 872 00:41:13,932 --> 00:41:16,640 DAVID MALAN: Yeah, so %i is what we're going to use for integers. 873 00:41:16,640 --> 00:41:17,710 And this is the kind of thing that you can 874 00:41:17,710 --> 00:41:20,420 consult in the manual pages or a slide like this. 875 00:41:20,420 --> 00:41:22,850 There's only a few of them that you might frequently use. 876 00:41:22,850 --> 00:41:26,480 But let's go ahead and use integers in a more interesting context, not 877 00:41:26,480 --> 00:41:27,440 just using functions. 878 00:41:27,440 --> 00:41:29,510 But let's revisit this idea of conditionals. 879 00:41:29,510 --> 00:41:32,750 And conditionals in Scratch were like these proverbial forks in the road. 880 00:41:32,750 --> 00:41:36,420 Like, do you want to do this thing or this thing or this other thing? 881 00:41:36,420 --> 00:41:38,750 It's a way of making decisions in a program, which 882 00:41:38,750 --> 00:41:42,170 is going to be super useful and pretty much omnipresent in any problems 883 00:41:42,170 --> 00:41:43,320 that we try to solve. 884 00:41:43,320 --> 00:41:45,290 So let me give you a few more building blocks 885 00:41:45,290 --> 00:41:48,140 in C by doing the side-by-side comparison again. 886 00:41:48,140 --> 00:41:53,750 So here in Scratch is how we might say if two variables, x and y, 887 00:41:53,750 --> 00:41:57,110 one is less than the other, then go ahead and say, quote, unquote, 888 00:41:57,110 --> 00:41:58,250 "x is less than y." 889 00:41:58,250 --> 00:41:59,730 So kind of a stupid program. 890 00:41:59,730 --> 00:42:02,300 But just to show you the basic syntax for Scratch, 891 00:42:02,300 --> 00:42:07,160 this is how you would ask the question, if x is less than y, then say this. 892 00:42:07,160 --> 00:42:08,570 So Say is the function. 893 00:42:08,570 --> 00:42:09,920 "If" is the conditional. 894 00:42:09,920 --> 00:42:14,307 And the green thing here we called, what? 895 00:42:14,307 --> 00:42:15,140 What did we call it? 896 00:42:15,140 --> 00:42:15,560 Yeah? 897 00:42:15,560 --> 00:42:16,040 STUDENT: A Boolean. 898 00:42:16,040 --> 00:42:18,000 DAVID MALAN: A Boolean or a Boolean expression, 899 00:42:18,000 --> 00:42:20,167 which is just a fancy way of saying a question whose 900 00:42:20,167 --> 00:42:25,580 answer is true or false, yes or no, 1 or 0, however you want to think about it. 901 00:42:25,580 --> 00:42:28,560 In C, the code is going to look like this. 902 00:42:28,560 --> 00:42:32,480 So it'll take a little bit of habit, a little bit of muscle memory to develop. 903 00:42:32,480 --> 00:42:35,880 But you're going to say "if," then in parentheses, 904 00:42:35,880 --> 00:42:39,530 you're going to say "x less than y," assuming x and y are variables. 905 00:42:39,530 --> 00:42:41,690 You're then going to use these curly braces. 906 00:42:41,690 --> 00:42:45,110 And then if you want to say, quote, unquote, "x is less than y" 907 00:42:45,110 --> 00:42:50,140 in C, what function should we use here presumably? 908 00:42:50,140 --> 00:42:51,430 So printf. 909 00:42:51,430 --> 00:42:54,803 So printf, quote, unquote, "x is less than y." 910 00:42:54,803 --> 00:42:57,220 So it's a bit of a mouthful, but again notice the pattern. 911 00:42:57,220 --> 00:42:58,750 Name of the function is printf. 912 00:42:58,750 --> 00:43:02,320 In the parentheses, left and right, is the argument to printf, 913 00:43:02,320 --> 00:43:04,750 which is, quote, unquote, "x is less than y." 914 00:43:04,750 --> 00:43:07,730 And again, just for aesthetics, to move the cursor to the next line, 915 00:43:07,730 --> 00:43:10,522 which you don't have to worry about in Scratch because everything's 916 00:43:10,522 --> 00:43:14,000 in speech bubbles, we're adding a backslash n, as well. 917 00:43:14,000 --> 00:43:16,390 So notice that these curly braces, as they're 918 00:43:16,390 --> 00:43:18,850 called, much like the orange puzzle piece here, 919 00:43:18,850 --> 00:43:21,520 are kind of hugging the code like this. 920 00:43:21,520 --> 00:43:24,760 And I'll note that technically speaking in C, 921 00:43:24,760 --> 00:43:28,990 If you only have one line of code inside of your conditional, 922 00:43:28,990 --> 00:43:31,360 you can actually omit the curly braces altogether. 923 00:43:31,360 --> 00:43:34,190 And the code will still work if you have one single line of code. 924 00:43:34,190 --> 00:43:34,690 Why? 925 00:43:34,690 --> 00:43:36,190 Just saves people some keystrokes. 926 00:43:36,190 --> 00:43:38,470 If you have two lines, three lines, or more in there, 927 00:43:38,470 --> 00:43:39,670 you need the curly braces. 928 00:43:39,670 --> 00:43:41,920 But I'll always draw it with the curly braces in class 929 00:43:41,920 --> 00:43:44,980 so it resembles Scratch as closely as possible. 930 00:43:44,980 --> 00:43:47,230 As an aside to some of you who have programmed before, 931 00:43:47,230 --> 00:43:49,340 you might be cringing now because like you really 932 00:43:49,340 --> 00:43:52,610 like your curly brace to be over here instead of here, that, 933 00:43:52,610 --> 00:43:53,900 too, is a stylistic choice. 934 00:43:53,900 --> 00:43:55,790 And we'll talk, too, about this in the class. 935 00:43:55,790 --> 00:43:58,910 Aesthetically, stylistically there are certain decisions we can make. 936 00:43:58,910 --> 00:44:03,530 But generally in a class, in a company, you as a student or an employee 937 00:44:03,530 --> 00:44:07,890 would simply standardize on one set of rules, so to speak. 938 00:44:07,890 --> 00:44:12,200 So we'll use these rules for formatting our code in class consistently. 939 00:44:12,200 --> 00:44:16,792 All right, any questions on this snippet of C code? 940 00:44:16,792 --> 00:44:18,250 All right, a couple of others then. 941 00:44:18,250 --> 00:44:21,420 So here is how, in Scratch, we might have a two-way fork in the road. 942 00:44:21,420 --> 00:44:26,340 If x is less than y, say x is less than y, else say x is not less than y. 943 00:44:26,340 --> 00:44:28,870 In C, It's going to look pretty much the same. 944 00:44:28,870 --> 00:44:32,697 But notice I'm adding an "else" keyword here with another set of curly braces. 945 00:44:32,697 --> 00:44:34,530 I'm going to have a couple of more printf's. 946 00:44:34,530 --> 00:44:37,600 But in C, even though it's clearly keyboard based, 947 00:44:37,600 --> 00:44:41,500 it's just text, no more puzzle pieces, it's kind of the same shape, 948 00:44:41,500 --> 00:44:44,440 so to speak, and it's definitely the same idea. 949 00:44:44,440 --> 00:44:46,150 So it's following a pattern. 950 00:44:46,150 --> 00:44:49,990 What about a three-way fork in the road, if x is less than y, 951 00:44:49,990 --> 00:44:53,160 then say x is less than y, else if x is greater 952 00:44:53,160 --> 00:45:01,012 than y, say x is greater than y, else if x equals y, then say x is equal to y. 953 00:45:01,012 --> 00:45:02,970 Well, you can probably see where this is going. 954 00:45:02,970 --> 00:45:06,070 On the right-hand side, it looks almost the same. 955 00:45:06,070 --> 00:45:09,360 In fact, if I add in the printf's, it's really almost the same, 956 00:45:09,360 --> 00:45:10,620 at least logically. 957 00:45:10,620 --> 00:45:16,320 But there is at least one curiosity, seemingly a typo 958 00:45:16,320 --> 00:45:17,765 but it's not this time. 959 00:45:17,765 --> 00:45:18,265 Yeah? 960 00:45:18,265 --> 00:45:19,390 STUDENT: The double equals. 961 00:45:19,390 --> 00:45:23,860 DAVID MALAN: Yeah, the double equal signs does not match Scratch, 962 00:45:23,860 --> 00:45:28,150 but it's not in fact a bug or a mistake in C. Anyone 963 00:45:28,150 --> 00:45:33,610 have an intuition for why I did use two equal signs instead of one here? 964 00:45:33,610 --> 00:45:34,571 Yeah? 965 00:45:34,571 --> 00:45:37,460 STUDENT: Because otherwise it could be mistaken for a variable. 966 00:45:37,460 --> 00:45:38,335 DAVID MALAN: Exactly. 967 00:45:38,335 --> 00:45:41,180 Well, otherwise it would be mistaken for a variable, specifically 968 00:45:41,180 --> 00:45:42,990 assignment of a variable. 969 00:45:42,990 --> 00:45:47,270 So recall that in previous code, when we used the get_string function, 970 00:45:47,270 --> 00:45:52,465 we used an equals sign to assign, from right to left, the value of a variable. 971 00:45:52,465 --> 00:45:53,840 And that's a reasonable decision. 972 00:45:53,840 --> 00:45:56,007 "Equal" kind of means that the two should ultimately 973 00:45:56,007 --> 00:45:59,660 be equal even though you think about it from going right to left. 974 00:45:59,660 --> 00:46:03,180 Unfortunately, the authors of C kind of [? painted ?] themselves into a corner. 975 00:46:03,180 --> 00:46:05,900 And presumably, decades ago when they realized, oh, shoot, 976 00:46:05,900 --> 00:46:07,910 we've already used a single equal sign, how 977 00:46:07,910 --> 00:46:12,320 do we represent equality of two values, the answer they came up with was, 978 00:46:12,320 --> 00:46:14,450 all right, we'll just use two instead. 979 00:46:14,450 --> 00:46:16,058 And thus was born this decision. 980 00:46:16,058 --> 00:46:16,850 Is it the best one? 981 00:46:16,850 --> 00:46:17,690 Who knows? 982 00:46:17,690 --> 00:46:20,450 Crazy enough, in other languages, like JavaScript, 983 00:46:20,450 --> 00:46:23,810 you have not just one, but two, but also three equal signs 984 00:46:23,810 --> 00:46:25,770 in a row to solve yet another problem. 985 00:46:25,770 --> 00:46:29,100 So reasonable people will disagree as to how good or bad these decisions are. 986 00:46:29,100 --> 00:46:32,930 But in C, this is what you must do. 987 00:46:32,930 --> 00:46:38,430 But there's a bad design decision here, too. 988 00:46:38,430 --> 00:46:40,560 It's still correct, the code, left and right. 989 00:46:40,560 --> 00:46:45,210 But I bet I could critique the quality of the design of both the Scratch code 990 00:46:45,210 --> 00:46:47,910 and the C code for reasons, what? 991 00:46:47,910 --> 00:46:51,788 STUDENT: Do we have to do else if x equals [INAUDIBLE]?? 992 00:46:51,788 --> 00:46:53,580 DAVID MALAN: OK, no, really good intuition. 993 00:46:53,580 --> 00:46:57,030 Do we have to ask this third question, "else if x equals y?" 994 00:46:57,030 --> 00:46:59,610 So short answer, no, logically, right? 995 00:46:59,610 --> 00:47:05,130 Just based on arithmetic, either x is less than y or x is greater than y 996 00:47:05,130 --> 00:47:08,220 or, what's the only other possible answer? 997 00:47:08,220 --> 00:47:10,080 They must be equal, logically. 998 00:47:10,080 --> 00:47:13,140 So technically, you're just kind of wasting the computer's time 999 00:47:13,140 --> 00:47:15,270 by asking this question because it already knows, 1000 00:47:15,270 --> 00:47:16,353 at that point, the answer. 1001 00:47:16,353 --> 00:47:18,780 And you're wasting your time as the programmer bothering 1002 00:47:18,780 --> 00:47:20,700 to type out more code or more puzzle pieces 1003 00:47:20,700 --> 00:47:24,010 than you need because logically one stems from the other. 1004 00:47:24,010 --> 00:47:28,080 So I can tighten this up, get rid of the "else, if," just use an "else." 1005 00:47:28,080 --> 00:47:31,110 And I can do the same thing over here in C, thereby avoiding 1006 00:47:31,110 --> 00:47:33,870 the double equal sign altogether, but not because it's wrong 1007 00:47:33,870 --> 00:47:38,340 but because you're wasting time, because now you're potentially asking only two 1008 00:47:38,340 --> 00:47:43,050 questions, two Boolean expressions, instead of 50% more by asking 1009 00:47:43,050 --> 00:47:46,200 a total of three questions at most. 1010 00:47:46,200 --> 00:47:52,900 Other questions then on this kind of code, logically or otherwise? 1011 00:47:52,900 --> 00:47:53,400 No? 1012 00:47:53,400 --> 00:47:58,450 All right, so if we have these puzzle pieces, so to speak, at our disposal, 1013 00:47:58,450 --> 00:48:00,753 how can we go about actually using these? 1014 00:48:00,753 --> 00:48:03,420 Well, suppose that we actually want to do something with values. 1015 00:48:03,420 --> 00:48:06,190 Let's introduce variables in C, as well. 1016 00:48:06,190 --> 00:48:08,197 We saw an example using a string a moment ago. 1017 00:48:08,197 --> 00:48:10,030 But what about with something like integers? 1018 00:48:10,030 --> 00:48:11,947 Well, you might not have used this in Scratch. 1019 00:48:11,947 --> 00:48:13,830 But here's the orange puzzle piece in Scratch 1020 00:48:13,830 --> 00:48:17,100 via which you can create a variable called counter to count things. 1021 00:48:17,100 --> 00:48:19,638 And you can set it equal to some value like 0. 1022 00:48:19,638 --> 00:48:21,930 Now, you can perhaps guess where we're going with this. 1023 00:48:21,930 --> 00:48:27,540 If I want in C a variable called counter and I want to set it equal to 0, 1024 00:48:27,540 --> 00:48:30,210 I use a single equal sign because logically you 1025 00:48:30,210 --> 00:48:32,340 read it from right to left, or technically it's 1026 00:48:32,340 --> 00:48:34,050 executed from right to left. 1027 00:48:34,050 --> 00:48:37,128 But that's not enough in C. What's missing from the screen? 1028 00:48:37,128 --> 00:48:37,920 STUDENT: Data type. 1029 00:48:37,920 --> 00:48:38,760 DAVID MALAN: I need a what? 1030 00:48:38,760 --> 00:48:39,570 STUDENT: You need a data type. 1031 00:48:39,570 --> 00:48:40,860 DAVID MALAN: So we need a data type. 1032 00:48:40,860 --> 00:48:43,110 And if it's going to be an integer, indeed I'm going to use int. 1033 00:48:43,110 --> 00:48:44,943 And now the other mistake I keep making is-- 1034 00:48:44,943 --> 00:48:45,735 STUDENT: Semicolon. 1035 00:48:45,735 --> 00:48:48,070 DAVID MALAN: So a semicolon at the end of the line. 1036 00:48:48,070 --> 00:48:50,153 So it's a little more verbose than some languages. 1037 00:48:50,153 --> 00:48:52,180 But if you read it left to right, this is 1038 00:48:52,180 --> 00:48:56,600 how you tell C to give you a variable called counter of type int 1039 00:48:56,600 --> 00:49:00,010 and initialize it to a value of 0. 1040 00:49:00,010 --> 00:49:00,850 That's all. 1041 00:49:00,850 --> 00:49:04,750 All right, how about, in Scratch, if you want to change that variable by 1, 1042 00:49:04,750 --> 00:49:05,860 by adding 1 to it? 1043 00:49:05,860 --> 00:49:07,280 In Scratch, it's super simple. 1044 00:49:07,280 --> 00:49:09,430 You just change it by 1 or even negative 1 1045 00:49:09,430 --> 00:49:11,830 if you want to go up or down respectively. 1046 00:49:11,830 --> 00:49:14,590 In C, it turns out you have a few different ways to do this. 1047 00:49:14,590 --> 00:49:18,140 And this looks like it's not mathematically possible, 1048 00:49:18,140 --> 00:49:21,820 but that's because equals is assignment, recall. 1049 00:49:21,820 --> 00:49:27,130 So this line of code is not saying that counter equals counter plus 1, 1050 00:49:27,130 --> 00:49:30,160 because that's just not possible using typical numbers. 1051 00:49:30,160 --> 00:49:33,290 But this means take counter's value, add 1 to it, 1052 00:49:33,290 --> 00:49:36,080 and assign it back to the counter variable. 1053 00:49:36,080 --> 00:49:38,450 So it's like incrementing counter in this way. 1054 00:49:38,450 --> 00:49:41,380 But this is such a common thing in C and in programming 1055 00:49:41,380 --> 00:49:43,990 to increase or decrease the values of variables, 1056 00:49:43,990 --> 00:49:46,090 there's a more succinct syntax. 1057 00:49:46,090 --> 00:49:48,460 This is identical. 1058 00:49:48,460 --> 00:49:51,167 And it might take you a little practice to get used to it, 1059 00:49:51,167 --> 00:49:52,750 but it just saves you some keystrokes. 1060 00:49:52,750 --> 00:49:56,050 But it similarly adds 1, or whatever number you use there. 1061 00:49:56,050 --> 00:49:58,720 And this is such a common operation in C especially 1062 00:49:58,720 --> 00:50:02,590 that there's an even tighter way of executing the same idea. 1063 00:50:02,590 --> 00:50:08,240 And you can literally just say counter++ and then semicolon in this case. 1064 00:50:08,240 --> 00:50:09,760 All three are exactly the same. 1065 00:50:09,760 --> 00:50:11,170 All three are perfectly correct. 1066 00:50:11,170 --> 00:50:13,545 But you'll learn over time that typing less on the screen 1067 00:50:13,545 --> 00:50:15,860 is probably going to save you some time. 1068 00:50:15,860 --> 00:50:19,660 Meanwhile, if we wanted to do the opposite and do something like minus 1 1069 00:50:19,660 --> 00:50:24,610 in Scratch, we could similarly do minus minus in C. Or we could do-- 1070 00:50:24,610 --> 00:50:28,450 yeah, we could do minus minus in C here at right. 1071 00:50:28,450 --> 00:50:31,480 All right, so just some additional building blocks, translating 1072 00:50:31,480 --> 00:50:36,790 from scratch to C. Why don't we go ahead and try using this perhaps 1073 00:50:36,790 --> 00:50:38,260 in the following way? 1074 00:50:38,260 --> 00:50:40,750 Let me go ahead and go back to VS Code. 1075 00:50:40,750 --> 00:50:45,910 And let me propose that we do something like this. 1076 00:50:45,910 --> 00:50:48,550 In VS Code, I'm going to go ahead and clear my terminal window. 1077 00:50:48,550 --> 00:50:50,650 I'm going to close "hello.c" by just clicking 1078 00:50:50,650 --> 00:50:54,220 the X. I'm going to go ahead and create a new file called "compare.c" 1079 00:50:54,220 --> 00:50:56,410 because the purpose in life of this program 1080 00:50:56,410 --> 00:50:58,942 is going to be to compare integers on the screen. 1081 00:50:58,942 --> 00:51:00,400 This time I'm not going to mess up. 1082 00:51:00,400 --> 00:51:04,480 I'm going to preemptively include CS50.h. 1083 00:51:04,480 --> 00:51:07,630 I'm going to preemptively include stdio.h. 1084 00:51:07,630 --> 00:51:13,690 And here, too, is a very common mistake in learning C. It is not "studio.h." 1085 00:51:13,690 --> 00:51:16,690 So when you email us asking why "studio.h" is not working, 1086 00:51:16,690 --> 00:51:18,190 that's because that is not the word. 1087 00:51:18,190 --> 00:51:22,420 It is "standard io.h," meaning standard input and output, 1088 00:51:22,420 --> 00:51:24,370 stuff involving the screen and the keyboard. 1089 00:51:24,370 --> 00:51:27,370 Then I'm going to go ahead and, just as before, int main(void), 1090 00:51:27,370 --> 00:51:29,830 but we'll come back to that eventually as to what it means. 1091 00:51:29,830 --> 00:51:35,050 And now inside of "main," which is just where the main part of my program goes, 1092 00:51:35,050 --> 00:51:39,310 again you can think of this as being analogous to "when green flag clicked." 1093 00:51:39,310 --> 00:51:40,870 This just kicks everything off. 1094 00:51:40,870 --> 00:51:42,680 I'm going to go ahead and do two things. 1095 00:51:42,680 --> 00:51:45,100 I'm going to go ahead and get an integer called x, 1096 00:51:45,100 --> 00:51:47,080 and I'm going to prompt the user for that int 1097 00:51:47,080 --> 00:51:50,770 and just say something like, "what's x?", space. 1098 00:51:50,770 --> 00:51:55,540 Then I'm going to do int y equals get_int, quote, unquote, "what's y?", 1099 00:51:55,540 --> 00:51:56,410 space. 1100 00:51:56,410 --> 00:52:00,830 And then let's just do something simple like, if x is less than y, 1101 00:52:00,830 --> 00:52:03,520 then go ahead and print out, quote, unquote, 1102 00:52:03,520 --> 00:52:08,740 "x is less than y backslash n," semicolon. 1103 00:52:08,740 --> 00:52:10,610 So it's not a very deep program. 1104 00:52:10,610 --> 00:52:13,610 It's just going to do what most any human brain could do pretty quickly. 1105 00:52:13,610 --> 00:52:17,080 But it's at least demonstrating how we might use now 1106 00:52:17,080 --> 00:52:19,480 something like a conditional in code. 1107 00:52:19,480 --> 00:52:21,490 So let me go ahead and re-- 1108 00:52:21,490 --> 00:52:25,750 let me compile this code for the first time, make compare, enter. 1109 00:52:25,750 --> 00:52:31,150 Nothing bad happens, which is good. "./compare" is how I run the program. 1110 00:52:31,150 --> 00:52:33,820 And just to tease this apart, dot, as we'll soon see, 1111 00:52:33,820 --> 00:52:36,770 essentially means that the file is in your current folder. 1112 00:52:36,770 --> 00:52:38,620 So dot means in your current folder. 1113 00:52:38,620 --> 00:52:41,440 And we'll eventually see that dot dot means your parent 1114 00:52:41,440 --> 00:52:43,780 folder, like the one that contains wherever 1115 00:52:43,780 --> 00:52:45,820 I am on my computer's hard drive. 1116 00:52:45,820 --> 00:52:47,050 All right. ./compare. 1117 00:52:47,050 --> 00:52:48,264 What's x? 1118 00:52:48,264 --> 00:52:49,210 1. 1119 00:52:49,210 --> 00:52:50,470 2 for y. 1120 00:52:50,470 --> 00:52:54,217 And hopefully it should say that x is less than y. 1121 00:52:54,217 --> 00:52:55,300 So pretty straightforward. 1122 00:52:55,300 --> 00:52:56,290 Proof by example. 1123 00:52:56,290 --> 00:52:58,480 And hopefully this would work in other cases, too. 1124 00:52:58,480 --> 00:53:04,960 But if I flip that around and I rerun it, ./compare, and I do 2 and 1, 1125 00:53:04,960 --> 00:53:06,432 nothing's going to happen. 1126 00:53:06,432 --> 00:53:08,140 But you would expect that because there's 1127 00:53:08,140 --> 00:53:11,860 only one Boolean expression deciding whether or not 1128 00:53:11,860 --> 00:53:13,880 I should actually type this out. 1129 00:53:13,880 --> 00:53:15,160 So what's going on? 1130 00:53:15,160 --> 00:53:17,140 Well, if this helps you, you might find it 1131 00:53:17,140 --> 00:53:20,830 useful to think about the logic of any program, be it in Scratch or C, 1132 00:53:20,830 --> 00:53:22,600 as kind of a flowchart of sorts. 1133 00:53:22,600 --> 00:53:24,910 And we'll put up a few of these over time just in case 1134 00:53:24,910 --> 00:53:26,690 you're a particularly visual thinker. 1135 00:53:26,690 --> 00:53:28,780 And this represents what it is I just did. 1136 00:53:28,780 --> 00:53:32,470 So here in this picture is where the program starts conceptually. 1137 00:53:32,470 --> 00:53:35,860 And any time you see a diamond, think of that as a Boolean expression, 1138 00:53:35,860 --> 00:53:37,330 a question that's being asked. 1139 00:53:37,330 --> 00:53:39,940 And the question being asked is, is x less than y? 1140 00:53:39,940 --> 00:53:44,600 That has two possible answers, true or false, yes or no respectively. 1141 00:53:44,600 --> 00:53:48,400 So let me propose, per the arrow, that if the answer is true, then print out, 1142 00:53:48,400 --> 00:53:52,480 per this rectangle, "x is less than y," just quote, unquote, and then stop. 1143 00:53:52,480 --> 00:53:53,680 That's it for the program. 1144 00:53:53,680 --> 00:53:56,800 But logically, if x is not less than y, that 1145 00:53:56,800 --> 00:54:00,310 is that question's answer is false, we'll just skip right to the end 1146 00:54:00,310 --> 00:54:01,210 and stop. 1147 00:54:01,210 --> 00:54:03,493 So this is a control-flow diagram. 1148 00:54:03,493 --> 00:54:05,410 It's just a pictorial way that you could write 1149 00:54:05,410 --> 00:54:09,490 on a piece of paper that just represents what it is the program is doing. 1150 00:54:09,490 --> 00:54:12,520 And this gets a little more interesting if now we 1151 00:54:12,520 --> 00:54:14,260 do something else with the code. 1152 00:54:14,260 --> 00:54:20,620 For instance, instead of just concluding that it's less than 1 or the other, 1153 00:54:20,620 --> 00:54:22,330 let's go back to the code here. 1154 00:54:22,330 --> 00:54:24,028 Let me clear my terminal window. 1155 00:54:24,028 --> 00:54:25,070 And let me add an "else." 1156 00:54:25,070 --> 00:54:29,950 So else, go ahead and print out "x"-- 1157 00:54:29,950 --> 00:54:34,240 I don't think I want to say this-- "greater than y." 1158 00:54:34,240 --> 00:54:35,480 It's not quite right. 1159 00:54:35,480 --> 00:54:38,208 What would be reasonable to say here? 1160 00:54:38,208 --> 00:54:39,500 STUDENT: "x is not less than y. 1161 00:54:39,500 --> 00:54:43,850 DAVID MALAN: Yeah, subtle, but "x is not less than y" because it could be equal. 1162 00:54:43,850 --> 00:54:48,990 We don't know if we're only checking two scenarios here. 1163 00:54:48,990 --> 00:54:53,030 So if I recompile this, make compare, ./compare. 1164 00:54:53,030 --> 00:54:55,970 Now if I do 1, comma 2, I still get the same answer. 1165 00:54:55,970 --> 00:55:01,532 If I rerun ./compare 2, comma 1, I now get the opposite answer. 1166 00:55:01,532 --> 00:55:02,990 It's not as good as might be ideal. 1167 00:55:02,990 --> 00:55:05,750 It'd be nice to know if it's equal to or greater than. 1168 00:55:05,750 --> 00:55:08,330 But at least that's all of the code that we have here. 1169 00:55:08,330 --> 00:55:10,430 And just to now paint a picture, if I go back 1170 00:55:10,430 --> 00:55:13,340 to my control-flow diagram, my flow chart here, 1171 00:55:13,340 --> 00:55:15,800 this is what it looked like before logically. 1172 00:55:15,800 --> 00:55:21,600 Now that I've added in a second branch, so to speak, 1173 00:55:21,600 --> 00:55:26,420 now, if the answer is false, I first print out x is not less than y, 1174 00:55:26,420 --> 00:55:28,370 and then I stop the program. 1175 00:55:28,370 --> 00:55:31,297 So same idea, but the decision tree, if you will, 1176 00:55:31,297 --> 00:55:34,130 if you've taken a 10 or the like, is getting a little bit bigger now 1177 00:55:34,130 --> 00:55:34,672 conceptually. 1178 00:55:34,672 --> 00:55:36,755 All right, what if we do something more than this? 1179 00:55:36,755 --> 00:55:38,700 Let's actually have that third condition. 1180 00:55:38,700 --> 00:55:40,973 Let me go back into my code here. 1181 00:55:40,973 --> 00:55:43,890 I'm going to hide the terminal window just to make room for more code. 1182 00:55:43,890 --> 00:55:47,730 And I'm going to say, "else if x is greater 1183 00:55:47,730 --> 00:55:51,720 than y," then go ahead and say not "x is not less than y," 1184 00:55:51,720 --> 00:55:55,710 but rather "x is greater than y." 1185 00:55:55,710 --> 00:55:59,950 And then down here, I'll do an "else if x equals equals y," 1186 00:55:59,950 --> 00:56:06,540 then I can go ahead and say printf, "x is equal to y backslash n," 1187 00:56:06,540 --> 00:56:07,990 close quote. 1188 00:56:07,990 --> 00:56:11,160 All right, so now if I run it-- let me open my terminal window again. 1189 00:56:11,160 --> 00:56:13,380 Let me rerun make compare. 1190 00:56:13,380 --> 00:56:15,570 Let me rerun ./compare. 1191 00:56:15,570 --> 00:56:17,400 1 and 2 are the same. 1192 00:56:17,400 --> 00:56:18,600 Let me rerun it. 1193 00:56:18,600 --> 00:56:20,730 2 and 1 are the same. 1194 00:56:20,730 --> 00:56:22,470 Let me rerun it a third time. 1195 00:56:22,470 --> 00:56:26,130 1 and 1 are now in fact equal. 1196 00:56:26,130 --> 00:56:28,080 So this works correctly. 1197 00:56:28,080 --> 00:56:31,920 But why did I make a point of using these "else if"s? 1198 00:56:31,920 --> 00:56:36,660 Put another way, couldn't I just make my life a little simpler 1199 00:56:36,660 --> 00:56:39,180 and just say, if this, then that? 1200 00:56:39,180 --> 00:56:40,200 If this, then that. 1201 00:56:40,200 --> 00:56:41,640 If this, then that. 1202 00:56:41,640 --> 00:56:43,290 Just ask all three questions. 1203 00:56:43,290 --> 00:56:44,340 Keep the code simple. 1204 00:56:44,340 --> 00:56:47,010 Don't bother with these else's. 1205 00:56:47,010 --> 00:56:48,715 Would this work for me? 1206 00:56:48,715 --> 00:56:49,215 Yeah? 1207 00:56:49,215 --> 00:56:52,312 STUDENT: It just seems like [INAUDIBLE] the program 1208 00:56:52,312 --> 00:56:53,520 doesn't have to run the rest. 1209 00:56:53,520 --> 00:56:56,980 DAVID MALAN: Yeah, so it saves a little bit of time because in this case, 1210 00:56:56,980 --> 00:57:00,840 just like in English, this is like asking three separate questions. 1211 00:57:00,840 --> 00:57:05,190 And it's not harnessing any information from previous questions 1212 00:57:05,190 --> 00:57:08,950 in order to decide whether you should bother asking that other question. 1213 00:57:08,950 --> 00:57:11,610 In other words, if x is less than y-- and you already 1214 00:57:11,610 --> 00:57:14,460 figured that out because it's 1 and 2 respectively-- you're 1215 00:57:14,460 --> 00:57:15,420 going to print this. 1216 00:57:15,420 --> 00:57:17,967 Why would you waste time asking this question when 1217 00:57:17,967 --> 00:57:19,050 it's not going to be true? 1218 00:57:19,050 --> 00:57:21,133 Why would you waste time asking this question when 1219 00:57:21,133 --> 00:57:22,240 it's not going to be true? 1220 00:57:22,240 --> 00:57:24,115 And so the point I wanted to make here, which 1221 00:57:24,115 --> 00:57:27,300 is that if we visualize that particular design, 1222 00:57:27,300 --> 00:57:30,000 what the flow chart looks like is actually this. 1223 00:57:30,000 --> 00:57:31,320 And let me zoom in at the top. 1224 00:57:31,320 --> 00:57:34,500 If you ask the question "is x less than y," well, 1225 00:57:34,500 --> 00:57:37,502 you're going to go ahead and say, x less than y. 1226 00:57:37,502 --> 00:57:39,210 Then if you go down to the next question, 1227 00:57:39,210 --> 00:57:41,490 you're still going to ask is x greater than y. 1228 00:57:41,490 --> 00:57:45,060 And then below that, you're still going to ask is x equal equal to y? 1229 00:57:45,060 --> 00:57:50,730 So no matter what x and y are, you're asking one, two, three questions all 1230 00:57:50,730 --> 00:57:51,580 of the time. 1231 00:57:51,580 --> 00:57:54,840 But if we actually go in and do what we did the first time, 1232 00:57:54,840 --> 00:57:59,700 where if I go back to my code and I undo this edit and add back the "else if"s-- 1233 00:57:59,700 --> 00:58:01,990 and now let me go back to the flow chart, 1234 00:58:01,990 --> 00:58:05,440 which I claim is bad because it's one, two, three questions, one 1235 00:58:05,440 --> 00:58:09,630 or two of which might not be necessary-- now if I visualize what I just did, 1236 00:58:09,630 --> 00:58:12,480 the flow chart gets a little more complicated looking, 1237 00:58:12,480 --> 00:58:15,430 but it's going to be better designed, more efficient. 1238 00:58:15,430 --> 00:58:15,930 Why? 1239 00:58:15,930 --> 00:58:19,320 Well, because if I start at the top here, I ask one question, 1240 00:58:19,320 --> 00:58:20,460 is x less than y. 1241 00:58:20,460 --> 00:58:22,050 If the answer is true, OK. 1242 00:58:22,050 --> 00:58:23,220 I say x less than y. 1243 00:58:23,220 --> 00:58:25,680 And then, boom, I sort of cheat and go all the way 1244 00:58:25,680 --> 00:58:29,400 to the end of the program and stop, having asked only one question. 1245 00:58:29,400 --> 00:58:33,600 If, though, x is not less than y, OK, fine, I'll ask you a second question. 1246 00:58:33,600 --> 00:58:37,680 But if the answer is true, boom, I print out x is greater than y, 1247 00:58:37,680 --> 00:58:38,730 and then I stop. 1248 00:58:38,730 --> 00:58:42,000 And only in a perverse case where x actually 1249 00:58:42,000 --> 00:58:46,410 equals y, which I'm going to claim is very unlikely or infrequent, 1250 00:58:46,410 --> 00:58:51,420 only then am I going to ask one, two, three questions to figure out whether 1251 00:58:51,420 --> 00:58:53,950 or not to print something at all. 1252 00:58:53,950 --> 00:58:56,557 So this is what we mean by distinguishing between correctness 1253 00:58:56,557 --> 00:58:58,140 of code-- because it's still correct-- 1254 00:58:58,140 --> 00:59:01,050 but this version is better designed because hopefully you're 1255 00:59:01,050 --> 00:59:04,980 going to go down this branch or this branch rather than the longest one 1256 00:59:04,980 --> 00:59:06,390 frequently. 1257 00:59:06,390 --> 00:59:13,660 Any questions now about this code or this visualization thereof? 1258 00:59:13,660 --> 00:59:14,230 Yeah? 1259 00:59:14,230 --> 00:59:17,597 STUDENT: I don't know if [INAUDIBLE] 1260 00:59:17,597 --> 00:59:19,332 1261 00:59:19,332 --> 00:59:20,540 DAVID MALAN: A perfect segue. 1262 00:59:20,540 --> 00:59:23,153 Why did I bother, though, even asking this question? 1263 00:59:23,153 --> 00:59:25,070 Don't need to because when I hit this button-- 1264 00:59:25,070 --> 00:59:27,440 hopefully I have the right slide in place-- 1265 00:59:27,440 --> 00:59:30,287 this would be even better than that design. 1266 00:59:30,287 --> 00:59:31,620 So thank you for teeing that up. 1267 00:59:31,620 --> 00:59:32,662 This is the same picture. 1268 00:59:32,662 --> 00:59:35,630 It sort of got bigger because there's fewer nodes, 1269 00:59:35,630 --> 00:59:37,100 fewer shapes in the picture. 1270 00:59:37,100 --> 00:59:40,400 Notice that if x less than y, boom, we say as much, and we stop. 1271 00:59:40,400 --> 00:59:43,910 If x is not less than y but it's greater than y, boom, we stop. 1272 00:59:43,910 --> 00:59:46,820 Or if it's not greater than, we immediately 1273 00:59:46,820 --> 00:59:49,580 conclude x indeed is equal to y. 1274 00:59:49,580 --> 00:59:50,900 And again, we stop. 1275 00:59:50,900 --> 00:59:54,680 So this picture is about as efficient and as 1276 00:59:54,680 --> 00:59:57,200 well designed as we can make our logic. 1277 00:59:57,200 --> 00:59:59,640 That's about as good as we can solve this problem. 1278 00:59:59,640 --> 01:00:02,690 So if I go back to my code now to make my C code 1279 01:00:02,690 --> 01:00:06,830 match that, the only thing I need to do is stop wasting the computer's time. 1280 01:00:06,830 --> 01:00:08,540 Don't ask that third question. 1281 01:00:08,540 --> 01:00:12,290 Just logically, mathematically conclude that of course it's 1282 01:00:12,290 --> 01:00:16,455 going to be equal at that point in the story. 1283 01:00:16,455 --> 01:00:18,080 All right, any other questions on this? 1284 01:00:18,080 --> 01:00:21,340 STUDENT: [INAUDIBLE] 1285 01:00:21,340 --> 01:00:23,906 DAVID MALAN: Sorry, a little louder? 1286 01:00:23,906 --> 01:00:26,702 STUDENT: [INAUDIBLE] 1287 01:00:26,702 --> 01:00:28,353 1288 01:00:28,353 --> 01:00:29,770 DAVID MALAN: Really good question. 1289 01:00:29,770 --> 01:00:31,728 What if I put in something that's not a number? 1290 01:00:31,728 --> 01:00:35,910 So here, too, is where the CS50 library and the implementation of get_int 1291 01:00:35,910 --> 01:00:36,990 will be your friend. 1292 01:00:36,990 --> 01:00:41,400 So for instance, if I run ./compare and I want to compare cats and dogs, 1293 01:00:41,400 --> 01:00:43,905 I could type in "cats," Enter. 1294 01:00:43,905 --> 01:00:45,780 It's just going to prompt me again and again. 1295 01:00:45,780 --> 01:00:47,738 It's not going to let me type in "dogs" either. 1296 01:00:47,738 --> 01:00:49,740 It's going to force me to give it an integer. 1297 01:00:49,740 --> 01:00:51,880 C does not do that by default. 1298 01:00:51,880 --> 01:00:55,110 And in fact, as we'll soon see over the course of CS50, 1299 01:00:55,110 --> 01:00:57,660 C is actually a very dangerous language at the end of the day 1300 01:00:57,660 --> 01:01:00,660 because it just trusts that the human is doing what it wants. 1301 01:01:00,660 --> 01:01:04,890 And as such, a lot of today's software that is hacked in some ways, 1302 01:01:04,890 --> 01:01:07,800 if it's using C or another language called C++, 1303 01:01:07,800 --> 01:01:11,190 are actually very vulnerable to certain types of hacking, 1304 01:01:11,190 --> 01:01:14,880 whereas other languages that we'll get to in the class are less so for reasons 1305 01:01:14,880 --> 01:01:17,170 like this. 1306 01:01:17,170 --> 01:01:21,440 All right, so besides this, let's consider just one other data type. 1307 01:01:21,440 --> 01:01:21,940 how about. 1308 01:01:21,940 --> 01:01:26,710 So besides strings, besides chars, there's some others on this list here. 1309 01:01:26,710 --> 01:01:29,110 Sorry, besides strings, besides integers, 1310 01:01:29,110 --> 01:01:33,410 there's this other data type here in C known as a char for a single character. 1311 01:01:33,410 --> 01:01:35,050 So here, let me just tease this apart. 1312 01:01:35,050 --> 01:01:37,690 A string is indeed a string of text. 1313 01:01:37,690 --> 01:01:40,540 It is zero or more characters together. 1314 01:01:40,540 --> 01:01:45,130 A char is always precisely one character. 1315 01:01:45,130 --> 01:01:48,520 Not all languages bother distinguishing between a single character 1316 01:01:48,520 --> 01:01:49,660 and a string of characters. 1317 01:01:49,660 --> 01:01:53,140 But in C, a string is typically multiple characters, 1318 01:01:53,140 --> 01:01:54,640 but technically can be zero. 1319 01:01:54,640 --> 01:01:56,350 Coincidentally, it could be one. 1320 01:01:56,350 --> 01:01:58,210 But it's capable of being more. 1321 01:01:58,210 --> 01:02:02,290 But a char is literally, as the word implies, a single character. 1322 01:02:02,290 --> 01:02:05,050 All right, given that, notice that in the CS50 library, 1323 01:02:05,050 --> 01:02:08,388 besides get_string, besides get_int, we also have get_char, 1324 01:02:08,388 --> 01:02:10,930 so another handy function for just getting a single character 1325 01:02:10,930 --> 01:02:11,770 from the user. 1326 01:02:11,770 --> 01:02:14,603 Now, why would it be useful to get a single character from the user? 1327 01:02:14,603 --> 01:02:16,312 Well, what if you're just doing something 1328 01:02:16,312 --> 01:02:19,310 that you and I do pretty frequently when you install new software 1329 01:02:19,310 --> 01:02:20,750 or fill out some form? 1330 01:02:20,750 --> 01:02:23,370 You agree to some form of terms and conditions. 1331 01:02:23,370 --> 01:02:25,650 So in fact, let me go back over to VS Code here. 1332 01:02:25,650 --> 01:02:29,540 And let me propose that I create a new program called agree.c, 1333 01:02:29,540 --> 01:02:32,420 so something akin to asking for the user's agreement. 1334 01:02:32,420 --> 01:02:35,698 So in VS Code, I'm going to type "code agree.c." 1335 01:02:35,698 --> 01:02:37,490 And I'm going to do some quick boilerplate. 1336 01:02:37,490 --> 01:02:43,280 So include CS50.h, include stdio.h, int main(void). 1337 01:02:43,280 --> 01:02:46,820 And then inside of main, which is like the "green flag clicked," 1338 01:02:46,820 --> 01:02:47,960 I'm going to do this. 1339 01:02:47,960 --> 01:02:51,290 Go ahead and get a character from the user, 1340 01:02:51,290 --> 01:02:54,500 and ask them something simple like, "Do you agree?," 1341 01:02:54,500 --> 01:02:56,490 expecting a yes/no response. 1342 01:02:56,490 --> 01:03:00,778 But at the beginning of this line, I need to put the return value somewhere. 1343 01:03:00,778 --> 01:03:02,570 So I'm going to put it in a variable called 1344 01:03:02,570 --> 01:03:06,200 C. And in programming, if you're just getting a single value, 1345 01:03:06,200 --> 01:03:11,645 it's OK sometimes to use X and Y or C when you're using-- 1346 01:03:11,645 --> 01:03:15,470 in larger programs, you'll benefit from using actual words like "answer," 1347 01:03:15,470 --> 01:03:16,820 like we did from the get go. 1348 01:03:16,820 --> 01:03:18,870 But C has to be a specific type. 1349 01:03:18,870 --> 01:03:21,020 So I'm going to literally say "char," and then 1350 01:03:21,020 --> 01:03:23,180 I'm going to finish my thought with a semicolon. 1351 01:03:23,180 --> 01:03:26,030 And here's now how I could check if the user agrees or not. 1352 01:03:26,030 --> 01:03:27,480 I could do something like this. 1353 01:03:27,480 --> 01:03:31,580 If the value of C equals equals, quote, unquote, 1354 01:03:31,580 --> 01:03:38,240 lowercase 'y,' then go ahead and print out "Agreed backslash n." 1355 01:03:38,240 --> 01:03:44,420 Else if the variable C has a value equal to lowercase 'n', let's go ahead 1356 01:03:44,420 --> 01:03:48,440 and print out, say, "Not agreed," as though I'm agreeing or not to some 1357 01:03:48,440 --> 01:03:49,670 terms and conditions. 1358 01:03:49,670 --> 01:03:51,590 But notice these are not typos. 1359 01:03:51,590 --> 01:03:56,400 What did I do ever so subtly different from last time I used text? 1360 01:03:56,400 --> 01:03:56,900 Yeah? 1361 01:03:56,900 --> 01:03:58,983 STUDENT: Single quotes instead of double quotes. 1362 01:03:58,983 --> 01:04:01,150 DAVID MALAN: Single quotes instead of double quotes. 1363 01:04:01,150 --> 01:04:02,150 So here's the heuristic. 1364 01:04:02,150 --> 01:04:04,860 When using strings, which are generally multiple characters, 1365 01:04:04,860 --> 01:04:06,240 have to use double quotes. 1366 01:04:06,240 --> 01:04:09,900 When using a single character, you should use single quotes 1367 01:04:09,900 --> 01:04:11,320 around the single character. 1368 01:04:11,320 --> 01:04:13,770 So let me go ahead now and, make agree. 1369 01:04:13,770 --> 01:04:16,890 Nothing went wrong, which is good. ./agree, Enter, 1370 01:04:16,890 --> 01:04:19,080 and let me go ahead and type in y for yes. 1371 01:04:19,080 --> 01:04:20,350 It seems to work. 1372 01:04:20,350 --> 01:04:24,480 Let me run it again. ./agree. n for no, and it seems to work. 1373 01:04:24,480 --> 01:04:27,600 And just if I type in something random like question mark, I don't know, 1374 01:04:27,600 --> 01:04:28,590 it doesn't crash. 1375 01:04:28,590 --> 01:04:32,830 It just ignores me because I only had two Boolean expressions there. 1376 01:04:32,830 --> 01:04:35,610 But notice that it's actually a little buggy arguably. 1377 01:04:35,610 --> 01:04:38,550 Let me run it again. ./agree, Enter. 1378 01:04:38,550 --> 01:04:41,760 How about capital Y because, like, my Caps Lock is down. 1379 01:04:41,760 --> 01:04:43,050 OK, it just ignores me. 1380 01:04:43,050 --> 01:04:46,020 Let me do it again. ./agree, capital N because my-- oops-- 1381 01:04:46,020 --> 01:04:48,540 because my Caps Lock is down. 1382 01:04:48,540 --> 01:04:49,590 OK, it just ignores me. 1383 01:04:49,590 --> 01:04:52,590 But this should make sense because I'm literally checking for lowercase. 1384 01:04:52,590 --> 01:04:55,990 So how could I fix this? 1385 01:04:55,990 --> 01:05:00,347 How could I fix this without just changing lowercase to uppercase, 1386 01:05:00,347 --> 01:05:02,680 because that would then break it in the other direction? 1387 01:05:02,680 --> 01:05:03,220 Yeah? 1388 01:05:03,220 --> 01:05:06,510 STUDENT: [INAUDIBLE] 1389 01:05:06,510 --> 01:05:09,698 1390 01:05:09,698 --> 01:05:12,490 DAVID MALAN: Yeah, let's just add another branch here, so to speak. 1391 01:05:12,490 --> 01:05:18,090 So if variable C equals equals capital Y, then I can go ahead here 1392 01:05:18,090 --> 01:05:20,280 and say printf agreed. 1393 01:05:20,280 --> 01:05:23,160 And then let me close my terminal to make more room. 1394 01:05:23,160 --> 01:05:27,690 Otherwise, down here, else if C equals equals capital N, 1395 01:05:27,690 --> 01:05:31,050 let's go ahead and again say printf not agreed. 1396 01:05:31,050 --> 01:05:33,600 And I claim that this would actually now work. 1397 01:05:33,600 --> 01:05:36,180 It's a four-way fork in the road, but I'm at least 1398 01:05:36,180 --> 01:05:40,500 checking for lowercase, uppercase, lowercase, uppercase for y and n 1399 01:05:40,500 --> 01:05:41,580 respectively. 1400 01:05:41,580 --> 01:05:44,910 I claim that this is correct, but this too, 1401 01:05:44,910 --> 01:05:47,490 even if you've never programmed before, should start today 1402 01:05:47,490 --> 01:05:49,290 to rub you the wrong way. 1403 01:05:49,290 --> 01:05:51,420 Like, we can do better. 1404 01:05:51,420 --> 01:05:53,790 This isn't the best design. 1405 01:05:53,790 --> 01:05:54,570 Why might that be? 1406 01:05:54,570 --> 01:05:55,490 Yeah? 1407 01:05:55,490 --> 01:06:00,735 STUDENT: Could you change the character c to be uppercase, like before you even 1408 01:06:00,735 --> 01:06:01,235 [INAUDIBLE]? 1409 01:06:01,235 --> 01:06:02,420 DAVID MALAN: Ah, clever. 1410 01:06:02,420 --> 01:06:07,790 So could we change the variable c to just be forced to uppercase 1411 01:06:07,790 --> 01:06:09,320 or maybe forced to lowercase? 1412 01:06:09,320 --> 01:06:12,650 No matter what the human types, we just do that ourselves so that way 1413 01:06:12,650 --> 01:06:15,380 we can just simplify this again to two possible scenarios. 1414 01:06:15,380 --> 01:06:17,930 I love that, but we haven't seen any functions yet 1415 01:06:17,930 --> 01:06:20,570 in C that would let me change things to uppercase or lowercase. 1416 01:06:20,570 --> 01:06:22,795 So we'll get there, but a good instinct and correct. 1417 01:06:22,795 --> 01:06:23,420 Other thoughts? 1418 01:06:23,420 --> 01:06:24,620 STUDENT: Use "or." 1419 01:06:24,620 --> 01:06:28,550 DAVID MALAN: So we could use "or" in some sense, like a logical "or." 1420 01:06:28,550 --> 01:06:32,760 What I don't like about this, to be clear, is that it's repeating itself. 1421 01:06:32,760 --> 01:06:35,510 And there's this principle in programming, and in life in general, 1422 01:06:35,510 --> 01:06:37,940 like, don't repeat yourself unnecessarily. 1423 01:06:37,940 --> 01:06:41,930 And by that I mean I literally have the same line 10 as 14. 1424 01:06:41,930 --> 01:06:44,760 I have the same line 18 as 22. 1425 01:06:44,760 --> 01:06:48,920 And if anything, one, I literally wasted twice as much time as I needed to. 1426 01:06:48,920 --> 01:06:51,200 Put another way, per our discussion of Scratch, 1427 01:06:51,200 --> 01:06:53,510 what if I go in and just change something like, 1428 01:06:53,510 --> 01:06:55,610 I want to be more excited, like "Agreed!"? 1429 01:06:55,610 --> 01:06:57,818 Well, I might forget to change it in the other place. 1430 01:06:57,818 --> 01:07:00,527 And let's just claim for today's purposes that that looks stupid, 1431 01:07:00,527 --> 01:07:02,580 it's a bug, because I want them to be consistent. 1432 01:07:02,580 --> 01:07:06,090 So don't invite situations where you might change something 1433 01:07:06,090 --> 01:07:07,650 in one place but not another. 1434 01:07:07,650 --> 01:07:10,030 Just only write it in one place total. 1435 01:07:10,030 --> 01:07:12,280 So I like this idea of "or"-ing things together. 1436 01:07:12,280 --> 01:07:14,580 So let me go ahead and delete what I just did. 1437 01:07:14,580 --> 01:07:18,240 And just to be clear, too, while this is on the screen, when you highlight code 1438 01:07:18,240 --> 01:07:21,630 in VS Code based on how we've configured it, these dots just show you 1439 01:07:21,630 --> 01:07:25,230 how much I've indented because in C, stylistically, the convention 1440 01:07:25,230 --> 01:07:29,710 is generally to indent four spaces and maybe four more spaces. 1441 01:07:29,710 --> 01:07:32,100 So those dots just help you count without having 1442 01:07:32,100 --> 01:07:34,560 to manually eyeball things yourself. 1443 01:07:34,560 --> 01:07:36,180 But let me delete those lines. 1444 01:07:36,180 --> 01:07:38,250 Let me delete these lines. 1445 01:07:38,250 --> 01:07:40,090 And this is going to look a little weird, 1446 01:07:40,090 --> 01:07:43,590 but the way you can "or" two thoughts together, so to 1447 01:07:43,590 --> 01:07:46,950 speak, like "or" them together, is you don't say "or," 1448 01:07:46,950 --> 01:07:50,610 but you use two vertical bars, which syntactically 1449 01:07:50,610 --> 01:07:53,070 means the English word "or." 1450 01:07:53,070 --> 01:07:55,650 And you can just ask the other question, if C equals, 1451 01:07:55,650 --> 01:07:57,330 quote, unquote, capital 'Y.' 1452 01:07:57,330 --> 01:08:02,340 And then down here, I can say or C equals equals capital 'N.' 1453 01:08:02,340 --> 01:08:05,170 So it adds a little more code to each of those lines, 1454 01:08:05,170 --> 01:08:09,450 but it doesn't add redundancy, because I've not duplicated my printf. 1455 01:08:09,450 --> 01:08:12,570 I've not added more curly braces unnecessarily. 1456 01:08:12,570 --> 01:08:17,040 Now as an aside, there's the opposite of "or", logically is the word "and." 1457 01:08:17,040 --> 01:08:19,740 Just so you've seen it, I could do this. 1458 01:08:19,740 --> 01:08:24,430 "&&" in C is how you express that the thing on the left must be true 1459 01:08:24,430 --> 01:08:26,319 and the thing on the right must be true. 1460 01:08:26,319 --> 01:08:30,045 But why would this make no sense in this context of line 8? 1461 01:08:30,045 --> 01:08:31,920 STUDENT: It can't be uppercase and lowercase. 1462 01:08:31,920 --> 01:08:33,753 DAVID MALAN: Yeah, at least to my knowledge, 1463 01:08:33,753 --> 01:08:36,300 a character can't be both lowercase and uppercase. 1464 01:08:36,300 --> 01:08:37,720 That just makes no logical sense. 1465 01:08:37,720 --> 01:08:41,250 So indeed "or" is what we want in this case. 1466 01:08:41,250 --> 01:08:43,286 Other questions? 1467 01:08:43,286 --> 01:08:49,245 STUDENT: In CS50.h, is there a way to directly compare strings [INAUDIBLE]?? 1468 01:08:49,245 --> 01:08:50,370 DAVID MALAN: Good question. 1469 01:08:50,370 --> 01:08:53,310 Via CS50.h, is there a way to compare strings. 1470 01:08:53,310 --> 01:08:54,270 Short answer, no. 1471 01:08:54,270 --> 01:08:56,100 But C is going to give us that capability. 1472 01:08:56,100 --> 01:08:59,439 And in fact, next week, among the things we'll do is actually compare strings. 1473 01:08:59,439 --> 01:09:01,439 And if you've programmed before, you'll see in C 1474 01:09:01,439 --> 01:09:04,533 that it actually doesn't work the way that you might expect. 1475 01:09:04,533 --> 01:09:06,450 But that's a problem, too, that we will solve. 1476 01:09:06,450 --> 01:09:08,040 But that transcends CS50. 1477 01:09:08,040 --> 01:09:15,370 That's a question for C. Other questions on this kind of logic? 1478 01:09:15,370 --> 01:09:18,790 Just to make this real then, anytime you click one of those EULAs 1479 01:09:18,790 --> 01:09:22,000 or terms and conditions on a form in a piece of software, 1480 01:09:22,000 --> 01:09:24,850 odds are there is code as simple as this underneath the hood. 1481 01:09:24,850 --> 01:09:25,760 Maybe it's graphical. 1482 01:09:25,760 --> 01:09:27,760 Maybe it's checking for you clicking this button 1483 01:09:27,760 --> 01:09:29,052 or maybe hitting the Enter key. 1484 01:09:29,052 --> 01:09:31,479 But underneath the hood is presumably some kind 1485 01:09:31,479 --> 01:09:35,740 of conditional checking for those kinds of outputs. 1486 01:09:35,740 --> 01:09:37,600 All right, how about another building block 1487 01:09:37,600 --> 01:09:39,558 from last time, which we'll now translate to C, 1488 01:09:39,558 --> 01:09:41,720 namely loops, things that happen again and again? 1489 01:09:41,720 --> 01:09:43,640 And these, too, are everywhere in code. 1490 01:09:43,640 --> 01:09:47,710 So in Scratch, here's how we might meow three times, super simple. 1491 01:09:47,710 --> 01:09:49,430 In C, it's going to look a little weird. 1492 01:09:49,430 --> 01:09:52,810 But you will get used to this over time if you've never programmed before. 1493 01:09:52,810 --> 01:09:55,540 It looks like a mouthful, OK. 1494 01:09:55,540 --> 01:09:57,940 But let's tease it apart line by line. 1495 01:09:57,940 --> 01:10:01,360 And you'll see that you won't have that reaction frequently because it's all 1496 01:10:01,360 --> 01:10:03,500 going to start to look very similar to itself. 1497 01:10:03,500 --> 01:10:04,900 But what are we doing here? 1498 01:10:04,900 --> 01:10:09,400 In C, you don't have the luxury of these cute and fun puzzle pieces 1499 01:10:09,400 --> 01:10:12,430 that just do the work for you, repeat three times. 1500 01:10:12,430 --> 01:10:16,250 In fact, in C and programming in general, sometimes 1501 01:10:16,250 --> 01:10:18,870 the work is on us to actually figure out, OK, 1502 01:10:18,870 --> 01:10:21,830 how can I use functions, variables, conditionals, and loops 1503 01:10:21,830 --> 01:10:25,580 and implement some idea like repetition, like looping? 1504 01:10:25,580 --> 01:10:27,680 And in C, here's how this might work. 1505 01:10:27,680 --> 01:10:31,850 How can I go about doing something like printing "meow" three times? 1506 01:10:31,850 --> 01:10:33,620 Well, I know about variables now. 1507 01:10:33,620 --> 01:10:35,270 We're about to see loops. 1508 01:10:35,270 --> 01:10:39,110 And I've seen how I can update variables by plussing or minusing 1509 01:10:39,110 --> 01:10:40,280 some value to them. 1510 01:10:40,280 --> 01:10:41,850 Let's combine those ideas. 1511 01:10:41,850 --> 01:10:46,375 So first, I'm doing what with this highlighted line in English? 1512 01:10:46,375 --> 01:10:49,250 If a friend cared to ask you, like, 'what is this line of code doing' 1513 01:10:49,250 --> 01:10:51,012 later today, what would you say? 1514 01:10:51,012 --> 01:10:54,250 STUDENT: It's creating a variable called "counter" and setting it equal to 3. 1515 01:10:54,250 --> 01:10:56,750 DAVID MALAN: Good, it's creating a variable called "counter" 1516 01:10:56,750 --> 01:10:58,400 and setting it equal to 3. 1517 01:10:58,400 --> 01:11:01,040 I'll use slightly new jargon. 1518 01:11:01,040 --> 01:11:04,157 I'm defining a variable, would be the term of our "called counter" 1519 01:11:04,157 --> 01:11:05,240 and setting it equal to 3. 1520 01:11:05,240 --> 01:11:07,152 So I'll use my hand to represent the counter. 1521 01:11:07,152 --> 01:11:08,360 And that's all a variable is. 1522 01:11:08,360 --> 01:11:11,870 It's like storage in some case that I'm representing information, using 1523 01:11:11,870 --> 01:11:14,480 my hand in this case or the computer's memory here. 1524 01:11:14,480 --> 01:11:17,575 Now what happens when using a loop in C? 1525 01:11:17,575 --> 01:11:20,700 There's different types of loops, one of which is called a for loop-- oop-- 1526 01:11:20,700 --> 01:11:22,790 one of which is called a while loop-- spoiler. 1527 01:11:22,790 --> 01:11:24,770 A while loop works like this. 1528 01:11:24,770 --> 01:11:28,910 Inside of parentheses is a Boolean expression just like inside 1529 01:11:28,910 --> 01:11:30,770 of a conditional that asks a question. 1530 01:11:30,770 --> 01:11:33,330 But this time the question is going to determine, 1531 01:11:33,330 --> 01:11:37,080 do you keep going through the loop again and again and again? 1532 01:11:37,080 --> 01:11:38,810 So it's not a one-time thing potentially. 1533 01:11:38,810 --> 01:11:41,210 It is checked again and again and again to decide 1534 01:11:41,210 --> 01:11:44,810 when it is time to stop looping, to stop cycling. 1535 01:11:44,810 --> 01:11:46,970 All right, so it's asking this question first. 1536 01:11:46,970 --> 01:11:49,713 Is counter greater than 0? 1537 01:11:49,713 --> 01:11:52,880 OK, obviously the answer is true because I'm still holding up three fingers. 1538 01:11:52,880 --> 01:11:54,140 So what happens? 1539 01:11:54,140 --> 01:11:58,070 C goes inside of the curly braces per the indentation 1540 01:11:58,070 --> 01:12:02,340 and executes printf of "meow," which prints out a "meow" on the screen. 1541 01:12:02,340 --> 01:12:04,640 The next line of code executes, which, recall, 1542 01:12:04,640 --> 01:12:07,250 is the same as just subtracting 1 from counter. 1543 01:12:07,250 --> 01:12:10,790 So I think I take down one finger, so I'm left with two. 1544 01:12:10,790 --> 01:12:12,035 And what happens next? 1545 01:12:12,035 --> 01:12:13,910 Well, this you just kind of have to memorize. 1546 01:12:13,910 --> 01:12:16,580 Once you get to the end of the inside of a loop, 1547 01:12:16,580 --> 01:12:19,460 you go back to the beginning of a loop here 1548 01:12:19,460 --> 01:12:22,770 and ask the same question, the same Boolean expression. 1549 01:12:22,770 --> 01:12:24,680 So is 2 greater than 0? 1550 01:12:24,680 --> 01:12:25,700 OK, obviously so. 1551 01:12:25,700 --> 01:12:27,890 So you go into it, you print a "meow." 1552 01:12:27,890 --> 01:12:31,400 You go into it and decrement counter further by one. 1553 01:12:31,400 --> 01:12:33,470 So now my hand is holding up one. 1554 01:12:33,470 --> 01:12:35,900 Now we wrap back around to the Boolean expression. 1555 01:12:35,900 --> 01:12:37,790 Is 1 greater than 0? 1556 01:12:37,790 --> 01:12:38,480 Obviously. 1557 01:12:38,480 --> 01:12:40,340 We print out a third "meow." 1558 01:12:40,340 --> 01:12:43,850 We then decrement counter again, and my hand goes to zero. 1559 01:12:43,850 --> 01:12:45,680 We go back around once more. 1560 01:12:45,680 --> 01:12:47,600 Is 0 greater than 0? 1561 01:12:47,600 --> 01:12:48,350 No. 1562 01:12:48,350 --> 01:12:49,970 And now the program just terminates. 1563 01:12:49,970 --> 01:12:51,980 Or if there were more code here, it would just 1564 01:12:51,980 --> 01:12:56,240 jump outside of the curly braces and keep going lower on the screen. 1565 01:12:56,240 --> 01:12:57,810 So that's all that's happening. 1566 01:12:57,810 --> 01:13:00,740 And so this is what MIT has the luxury of doing with pictures. 1567 01:13:00,740 --> 01:13:03,440 But at MIT, someone probably essentially wrote 1568 01:13:03,440 --> 01:13:09,030 code that looks like this to give us the illusion, the abstraction of this. 1569 01:13:09,030 --> 01:13:12,710 So what we're learning today is how they invented these puzzle pieces 1570 01:13:12,710 --> 01:13:17,370 by just using lower-level plumbing, if you will, like this here. 1571 01:13:17,370 --> 01:13:17,870 Yeah? 1572 01:13:17,870 --> 01:13:21,900 STUDENT: What would happen if you created the variable "counter" 1573 01:13:21,900 --> 01:13:23,330 inside of the curly braces? 1574 01:13:23,330 --> 01:13:24,830 DAVID MALAN: A really good question. 1575 01:13:24,830 --> 01:13:28,430 What would happen if you created the variable inside of the curly braces? 1576 01:13:28,430 --> 01:13:30,650 Short answer, it just wouldn't work in C, 1577 01:13:30,650 --> 01:13:33,560 because if I were to try with my slide here, 1578 01:13:33,560 --> 01:13:39,650 for instance, to move this line of code here down inside of this, for instance, 1579 01:13:39,650 --> 01:13:44,700 now the very top line is trying to use counter before it even exists. 1580 01:13:44,700 --> 01:13:46,160 So C is very literal it. 1581 01:13:46,160 --> 01:13:48,000 Reads top to bottom, left to right. 1582 01:13:48,000 --> 01:13:50,870 And if it hasn't seen you define or create a variable yet, 1583 01:13:50,870 --> 01:13:55,550 you're going to get some scary error message on the screen instead. 1584 01:13:55,550 --> 01:13:59,010 All right, other questions on this here code? 1585 01:13:59,010 --> 01:13:59,510 No? 1586 01:13:59,510 --> 01:14:03,110 All right, so if we want to then maybe tighten this up a bit, 1587 01:14:03,110 --> 01:14:05,130 let me propose that we could do this instead. 1588 01:14:05,130 --> 01:14:07,850 So besides this version of the code, let me just 1589 01:14:07,850 --> 01:14:10,070 do something more canonical, more conventional. 1590 01:14:10,070 --> 01:14:13,280 So you're totally fine with using a variable like counter . 1591 01:14:13,280 --> 01:14:15,500 It's what Scratch uses by default. It's very verbose. 1592 01:14:15,500 --> 01:14:16,520 It does what it says. 1593 01:14:16,520 --> 01:14:18,410 Frankly, once you get comfy with programming, 1594 01:14:18,410 --> 01:14:20,480 like most typical programmers, whenever they 1595 01:14:20,480 --> 01:14:24,210 have a single integer in a program whose sole purpose in life is to count, 1596 01:14:24,210 --> 01:14:27,810 they'll just use "i" for integer just like I used "c" for character. 1597 01:14:27,810 --> 01:14:29,820 When you have larger programs, you don't want 1598 01:14:29,820 --> 01:14:35,070 to start using A and B and C and D and E and F and so forth for your variables 1599 01:14:35,070 --> 01:14:36,880 because nothing's going to make any sense. 1600 01:14:36,880 --> 01:14:40,980 But when you're doing something super simple like counting with an integer, 1601 01:14:40,980 --> 01:14:44,670 using a short-named variable is totally stylistically reasonable. 1602 01:14:44,670 --> 01:14:48,195 But I can tighten this up further, not just renaming counter to i. 1603 01:14:48,195 --> 01:14:50,580 What else can I do, if you recall? 1604 01:14:50,580 --> 01:14:51,300 Over here? 1605 01:14:51,300 --> 01:14:52,800 STUDENT: [INAUDIBLE] 1606 01:14:52,800 --> 01:14:53,550 DAVID MALAN: Sure. 1607 01:14:53,550 --> 01:14:55,150 STUDENT: A for loop? 1608 01:14:55,150 --> 01:14:56,400 DAVID MALAN: Oh, OK, for loop. 1609 01:14:56,400 --> 01:14:57,442 Yes, that was my spoiler. 1610 01:14:57,442 --> 01:15:00,300 But while in a while loop, I can tighten this up slightly more. 1611 01:15:00,300 --> 01:15:01,460 Over here? 1612 01:15:01,460 --> 01:15:03,660 STUDENT: Instead of i equals i minus 1. 1613 01:15:03,660 --> 01:15:06,420 DAVID MALAN: Yeah, instead of i equals i minus 1, 1614 01:15:06,420 --> 01:15:08,310 I can actually tighten this up this way. 1615 01:15:08,310 --> 01:15:10,143 And we didn't see the minus before, but it's 1616 01:15:10,143 --> 01:15:15,120 the same idea-- i minus equals 1, or even more succinctly, i minus minus. 1617 01:15:15,120 --> 01:15:18,210 So when you get comfortable with programming, any of these approaches 1618 01:15:18,210 --> 01:15:19,230 are correct. 1619 01:15:19,230 --> 01:15:21,875 This would be more conventional at this point. 1620 01:15:21,875 --> 01:15:24,000 So if you want to write code like most other people 1621 01:15:24,000 --> 01:15:28,410 write code, adopt ultimately these kinds of conventions. 1622 01:15:28,410 --> 01:15:31,170 All right, so that just does the exact same thing, though. 1623 01:15:31,170 --> 01:15:33,780 But let's now put this into practice. 1624 01:15:33,780 --> 01:15:36,460 Let me go back to VS Code here. 1625 01:15:36,460 --> 01:15:40,590 Let me go ahead and clear my terminal and close agree.c from before. 1626 01:15:40,590 --> 01:15:43,200 And let me go ahead and create a file called "meow." 1627 01:15:43,200 --> 01:15:45,540 So code meow.c. 1628 01:15:45,540 --> 01:15:47,530 And let me do this the sort of wrong way. 1629 01:15:47,530 --> 01:15:49,320 Let me include stdio.h. 1630 01:15:49,320 --> 01:15:52,860 at the top, int main(void) thereafter. 1631 01:15:52,860 --> 01:15:56,282 Inside of there, let me do printf "meow." 1632 01:15:56,282 --> 01:15:57,240 And then you know what? 1633 01:15:57,240 --> 01:15:58,020 I don't want to keep typing that. 1634 01:15:58,020 --> 01:16:00,460 Let me just go ahead and copy/paste two more times. 1635 01:16:00,460 --> 01:16:04,140 So I claim this is correct, make meow. 1636 01:16:04,140 --> 01:16:05,520 ./meow, done. 1637 01:16:05,520 --> 01:16:07,980 I've got code that prints "meow" three times. 1638 01:16:07,980 --> 01:16:11,790 But this, again, should already rub you the wrong way. 1639 01:16:11,790 --> 01:16:13,290 Why? 1640 01:16:13,290 --> 01:16:14,040 Yeah? 1641 01:16:14,040 --> 01:16:15,267 STUDENT: There's duplication. 1642 01:16:15,267 --> 01:16:16,350 DAVID MALAN: Because what? 1643 01:16:16,350 --> 01:16:17,030 STUDENT: There's duplication. 1644 01:16:17,030 --> 01:16:18,690 DAVID MALAN: Because I have duplication. 1645 01:16:18,690 --> 01:16:20,250 I mean, I literally copied and pasted it. 1646 01:16:20,250 --> 01:16:21,510 And that's kind of a good rule of thumb. 1647 01:16:21,510 --> 01:16:24,690 If you, in the future, start finding yourself copying and pasting code 1648 01:16:24,690 --> 01:16:27,570 within the same program, you're probably doing something wrong. 1649 01:16:27,570 --> 01:16:30,100 There's a better way to design it even if it's correct. 1650 01:16:30,100 --> 01:16:32,513 So this is clearly a candidate for a loop. 1651 01:16:32,513 --> 01:16:34,180 So let me go ahead and actually do that. 1652 01:16:34,180 --> 01:16:37,380 Let me just go ahead and remove all of this duplication. 1653 01:16:37,380 --> 01:16:42,630 Let me give myself a variable called i, set it equal to 3. 1654 01:16:42,630 --> 01:16:44,580 Let me go ahead and give myself a while loop 1655 01:16:44,580 --> 01:16:47,550 and check that i is greater than 0. 1656 01:16:47,550 --> 01:16:50,640 Inside of this loop, let me print out just "meow" once. 1657 01:16:50,640 --> 01:16:54,060 But I'll reuse that code again and again because here I'm 1658 01:16:54,060 --> 01:16:56,100 going to do i minus minus. 1659 01:16:56,100 --> 01:16:59,820 So that's the exact same code, the tight version of it that we saw a moment ago. 1660 01:16:59,820 --> 01:17:04,900 Let me go ahead and "make meow" again, ./meow, and it still works. 1661 01:17:04,900 --> 01:17:06,270 Why is this version better? 1662 01:17:06,270 --> 01:17:10,320 Because if you want the cat to meow five times, you change it in one place. 1663 01:17:10,320 --> 01:17:15,630 If you want to make the cat a dog, you change the meow to a woof in one place, 1664 01:17:15,630 --> 01:17:18,210 albeit changing the file name eventually, but changing it 1665 01:17:18,210 --> 01:17:22,950 in one place, not worrying about changing it again and again and again. 1666 01:17:22,950 --> 01:17:25,810 But there are other ways to do this. 1667 01:17:25,810 --> 01:17:30,300 For instance, let me propose that. 1668 01:17:30,300 --> 01:17:34,540 And actually, let's see, let me propose that instead of just doing it this way, 1669 01:17:34,540 --> 01:17:36,870 just to be clear-- 1670 01:17:36,870 --> 01:17:39,660 yeah, let's go ahead and propose that instead of doing this, 1671 01:17:39,660 --> 01:17:41,670 we can actually count in different directions. 1672 01:17:41,670 --> 01:17:44,820 I'm kind of forcing this idea of starting at 3, going down to 0. 1673 01:17:44,820 --> 01:17:47,610 But when normal humans in this room, if you ever count something, 1674 01:17:47,610 --> 01:17:49,530 you probably do 1, 2, 3, and done. 1675 01:17:49,530 --> 01:17:51,640 Like, that's how we would count in the real world. 1676 01:17:51,640 --> 01:17:54,480 Well, we can do that, too, here code-wise. 1677 01:17:54,480 --> 01:17:56,670 We could initialize i to 1. 1678 01:17:56,670 --> 01:18:00,870 We could check that i is less than or equal to 3. 1679 01:18:00,870 --> 01:18:03,000 And we've not seen this syntax before, but there's 1680 01:18:03,000 --> 01:18:06,060 no easy way on a typical keyboard to type a less than or equal sign 1681 01:18:06,060 --> 01:18:07,020 like in a math book. 1682 01:18:07,020 --> 01:18:11,100 So we use two characters, a less-than sign and then an equal sign 1683 01:18:11,100 --> 01:18:11,940 back to back. 1684 01:18:11,940 --> 01:18:13,620 And that means less than or equal to. 1685 01:18:13,620 --> 01:18:18,030 And this is the same idea so long as I plus plus i inside of it 1686 01:18:18,030 --> 01:18:22,080 because that'll start at 1, then 2, but it won't stop then. 1687 01:18:22,080 --> 01:18:25,440 It will go up to until i is equal to 3. 1688 01:18:25,440 --> 01:18:29,500 Once i becomes 4, then that Boolean expression isn't going to be true. 1689 01:18:29,500 --> 01:18:32,430 So it stops after three "meow"s total. 1690 01:18:32,430 --> 01:18:34,710 But there's another way, too, and this is probably 1691 01:18:34,710 --> 01:18:37,560 the most conventional and the way you should do it 1692 01:18:37,560 --> 01:18:39,360 even though it's just as correct. 1693 01:18:39,360 --> 01:18:43,030 In CS, if you've seen already last week, we almost always start counting from 0. 1694 01:18:43,030 --> 01:18:43,530 Why? 1695 01:18:43,530 --> 01:18:46,380 Just because, so we're not wasting a pattern of bits. 1696 01:18:46,380 --> 01:18:49,480 So generally when you start writing code that counts, 1697 01:18:49,480 --> 01:18:52,770 you should, quote, unquote, "almost always" start at 0, 1698 01:18:52,770 --> 01:18:56,070 count up to but not through the total you 1699 01:18:56,070 --> 01:18:59,200 care about so you don't get one extra by accident. 1700 01:18:59,200 --> 01:19:01,710 And so this would be the most conventional way 1701 01:19:01,710 --> 01:19:04,090 of doing what we just described. 1702 01:19:04,090 --> 01:19:05,130 But they're all correct. 1703 01:19:05,130 --> 01:19:07,620 You can make an argument that all of them are equally good. 1704 01:19:07,620 --> 01:19:10,740 This is what most people, quote, unquote, "would do." 1705 01:19:10,740 --> 01:19:15,255 OK, other questions on this here syntax or logic? 1706 01:19:15,255 --> 01:19:18,440 1707 01:19:18,440 --> 01:19:19,220 No? 1708 01:19:19,220 --> 01:19:21,530 All right, how about-- 1709 01:19:21,530 --> 01:19:23,120 we got some cookies on the horizon. 1710 01:19:23,120 --> 01:19:26,240 But before we get there, let's meow a few more times, if we may. 1711 01:19:26,240 --> 01:19:31,373 So how about doing a little bit differently versus the while loop. 1712 01:19:31,373 --> 01:19:32,790 And I think we heard it over here. 1713 01:19:32,790 --> 01:19:35,850 Turns out there's another type of loop altogether. 1714 01:19:35,850 --> 01:19:37,850 So this one here. 1715 01:19:37,850 --> 01:19:40,940 And this one, if you can believe it, is probably even more conventional 1716 01:19:40,940 --> 01:19:41,940 than the other way. 1717 01:19:41,940 --> 01:19:43,940 And this is going to be thematic in programming. 1718 01:19:43,940 --> 01:19:46,463 There's rarely one way, one right way to do things. 1719 01:19:46,463 --> 01:19:49,130 You're going to have bunches of different tools in your toolkit. 1720 01:19:49,130 --> 01:19:52,213 And your code might look different from someone else's because each of you 1721 01:19:52,213 --> 01:19:54,470 tends to reach for a different tool in that toolkit. 1722 01:19:54,470 --> 01:19:55,650 And here's another tool-- 1723 01:19:55,650 --> 01:19:57,350 and as you proposed earlier-- 1724 01:19:57,350 --> 01:19:58,370 a for loop. 1725 01:19:58,370 --> 01:20:02,960 A for loop is just another way of achieving the exact same idea 1726 01:20:02,960 --> 01:20:04,800 using slightly different syntax. 1727 01:20:04,800 --> 01:20:08,360 And it's appealing, frankly in general, because it's a little more succinct. 1728 01:20:08,360 --> 01:20:11,540 It just saves some keystrokes even though you have to memorize 1729 01:20:11,540 --> 01:20:12,980 the order in which it works. 1730 01:20:12,980 --> 01:20:18,628 This code is identical to this code here functionally. 1731 01:20:18,628 --> 01:20:20,670 But aesthetically, of course, it looks different. 1732 01:20:20,670 --> 01:20:21,630 How does it work? 1733 01:20:21,630 --> 01:20:24,330 In a for loop, notice that in the parentheses 1734 01:20:24,330 --> 01:20:26,790 is not a single simple Boolean expression. 1735 01:20:26,790 --> 01:20:28,480 There are three things. 1736 01:20:28,480 --> 01:20:33,060 One, before a semicolon, is a place to initialize a variable 1737 01:20:33,060 --> 01:20:34,710 to do your counting typically. 1738 01:20:34,710 --> 01:20:36,617 Second is the Boolean expression. 1739 01:20:36,617 --> 01:20:37,450 So it's still there. 1740 01:20:37,450 --> 01:20:40,242 It's just surrounded on the left and the right by two other things. 1741 01:20:40,242 --> 01:20:41,610 Lastly is the update. 1742 01:20:41,610 --> 01:20:45,917 What do you want to do at the end of every loop through this block of code? 1743 01:20:45,917 --> 01:20:48,250 So you can probably imagine where we're going with this. 1744 01:20:48,250 --> 01:20:49,300 How does this work? 1745 01:20:49,300 --> 01:20:51,570 The first thing that happens is that a variable 1746 01:20:51,570 --> 01:20:54,360 called i is defined and initialized to the value of 0. 1747 01:20:54,360 --> 01:20:56,400 That happens once and only once. 1748 01:20:56,400 --> 01:20:58,020 Then we check the condition. 1749 01:20:58,020 --> 01:21:00,570 Is 0 less than 3? 1750 01:21:00,570 --> 01:21:01,470 Obviously yes. 1751 01:21:01,470 --> 01:21:03,690 So now we don't do the plus plus yet. 1752 01:21:03,690 --> 01:21:04,810 We go into the loop. 1753 01:21:04,810 --> 01:21:07,352 And this is where the for loop's a little confusing at first. 1754 01:21:07,352 --> 01:21:08,460 We print out "meow." 1755 01:21:08,460 --> 01:21:09,540 Then what happens? 1756 01:21:09,540 --> 01:21:10,480 There's no more lines. 1757 01:21:10,480 --> 01:21:14,740 So we go back to the for loop, and we increment i at that point. 1758 01:21:14,740 --> 01:21:16,200 So now i is 1. 1759 01:21:16,200 --> 01:21:19,290 Then we check the condition. i is less than 3? 1760 01:21:19,290 --> 01:21:20,640 Yes, because 1 is less than 3. 1761 01:21:20,640 --> 01:21:23,040 We go back into the loop and print "meow." 1762 01:21:23,040 --> 01:21:26,250 Now we go back to the plus plus, so i is now 2. 1763 01:21:26,250 --> 01:21:27,390 We check the condition. 1764 01:21:27,390 --> 01:21:28,890 2 is less than 3 obviously. 1765 01:21:28,890 --> 01:21:31,200 So we go back into the loop and print "meow." 1766 01:21:31,200 --> 01:21:34,590 Then we do the increment. i is now 3. 1767 01:21:34,590 --> 01:21:37,380 Is 3 less than 3? 1768 01:21:37,380 --> 01:21:41,070 No, so we exit the loop, and we're done, or we keep 1769 01:21:41,070 --> 01:21:42,960 going down here if there's more code. 1770 01:21:42,960 --> 01:21:45,240 But how many times did I say "meow?" 1771 01:21:45,240 --> 01:21:52,280 1, 2, 3 total, when my hand was 0, 1, and 2. 1772 01:21:52,280 --> 01:21:54,410 Questions on this alternative syntax? 1773 01:21:54,410 --> 01:21:56,540 It takes some getting used to, but most people 1774 01:21:56,540 --> 01:21:58,910 would write loops using a for loop, I would say. 1775 01:21:58,910 --> 01:22:02,150 STUDENT: Could you now in the curly braces, use just one line of code? 1776 01:22:02,150 --> 01:22:02,870 DAVID MALAN: Yes. 1777 01:22:02,870 --> 01:22:05,540 If you really want to be cool and save syntax, 1778 01:22:05,540 --> 01:22:11,390 yes, it is correct and common to eliminate the curly braces if you only 1779 01:22:11,390 --> 01:22:13,400 have one line of code therein. 1780 01:22:13,400 --> 01:22:16,150 We in class will always put the curly braces there 1781 01:22:16,150 --> 01:22:19,400 because this is the kind of thing where, if you get forgetful, you go in later 1782 01:22:19,400 --> 01:22:20,360 and add a second line. 1783 01:22:20,360 --> 01:22:22,360 Like, darn it, like you forgot the curly braces, 1784 01:22:22,360 --> 01:22:24,150 things will not work as expected. 1785 01:22:24,150 --> 01:22:27,950 So in general, use the curly braces, but you do not have to strictly. 1786 01:22:27,950 --> 01:22:30,000 Other questions on 6? 1787 01:22:30,000 --> 01:22:30,500 Yes? 1788 01:22:30,500 --> 01:22:33,665 STUDENT: [INAUDIBLE] 1789 01:22:33,665 --> 01:22:35,290 DAVID MALAN: Can be used without, what? 1790 01:22:35,290 --> 01:22:37,168 STUDENT: [INAUDIBLE] 1791 01:22:37,168 --> 01:22:39,460 DAVID MALAN: Oh, could you do it without the condition? 1792 01:22:39,460 --> 01:22:43,570 Yes, there are very fancy things you can do that we won't focus on today. 1793 01:22:43,570 --> 01:22:48,160 But yes, if you want to get rid of the condition, you could get rid of this 1794 01:22:48,160 --> 01:22:48,820 here. 1795 01:22:48,820 --> 01:22:51,370 And that would actually make the loop go forever, 1796 01:22:51,370 --> 01:22:53,290 which may be a good thing if it's like a clock 1797 01:22:53,290 --> 01:22:57,010 that you want to tick forever, but often not a good thing in code. 1798 01:22:57,010 --> 01:22:58,600 Good question, though. 1799 01:22:58,600 --> 01:23:03,023 All right, so beyond that, let's just go ahead and put this into context. 1800 01:23:03,023 --> 01:23:04,940 Just in case it helps you to think about this, 1801 01:23:04,940 --> 01:23:07,360 this is just another flow chart, if you're 1802 01:23:07,360 --> 01:23:09,520 more of a visual thinker, that represents 1803 01:23:09,520 --> 01:23:11,590 what it is this loop is now doing. 1804 01:23:11,590 --> 01:23:14,630 Previously, all of our arrows went from top to bottom and stopped. 1805 01:23:14,630 --> 01:23:16,960 But now there's an arrow going back, up, and around 1806 01:23:16,960 --> 01:23:18,740 because of this loop, this cycle. 1807 01:23:18,740 --> 01:23:21,550 So when we start this program, we set i equal to 0. 1808 01:23:21,550 --> 01:23:23,920 We then check, is i less than 3? 1809 01:23:23,920 --> 01:23:25,990 Obviously it is, so we print "meow." 1810 01:23:25,990 --> 01:23:29,860 We increment i, and then we go back to that same condition. 1811 01:23:29,860 --> 01:23:31,930 We check the condition. 1812 01:23:31,930 --> 01:23:33,040 We print "meow." 1813 01:23:33,040 --> 01:23:36,190 i plus plus, go back, go back. 1814 01:23:36,190 --> 01:23:40,440 Now, if i equals 3, 3 is not less than 3, so the answer is false. 1815 01:23:40,440 --> 01:23:41,248 And we stop. 1816 01:23:41,248 --> 01:23:43,040 So again, it's just another way of thinking 1817 01:23:43,040 --> 01:23:46,460 about how the code in Scratch, how the code in C 1818 01:23:46,460 --> 01:23:50,660 might alternatively work in each of these contexts. 1819 01:23:50,660 --> 01:23:53,750 But there's this one other puzzle piece in Scratch, 1820 01:23:53,750 --> 01:23:55,700 recall, that's not the repeat block, which 1821 01:23:55,700 --> 01:23:59,210 is for finite numbers of repetitions, but forever. 1822 01:23:59,210 --> 01:24:02,240 And in C, there is a way to do this, but it's a little weird looking. 1823 01:24:02,240 --> 01:24:03,860 There's no forever keyword. 1824 01:24:03,860 --> 01:24:08,300 But you can use the while loop or, as you inferred, 1825 01:24:08,300 --> 01:24:12,000 you can actually use the for loop without a condition in the middle. 1826 01:24:12,000 --> 01:24:14,720 So here, I can actually say this. 1827 01:24:14,720 --> 01:24:17,690 If I want to do something forever, I want 1828 01:24:17,690 --> 01:24:20,600 to make sure that the answer to my question, the Boolean expression, 1829 01:24:20,600 --> 01:24:23,570 is always true, always true, always true, 1830 01:24:23,570 --> 01:24:27,680 the easiest way to achieve that goal is just literally write "true" there 1831 01:24:27,680 --> 01:24:29,670 because true is true no matter what. 1832 01:24:29,670 --> 01:24:31,970 And it's a trick for making the loop forever 1833 01:24:31,970 --> 01:24:33,740 go around and around, as you might if you 1834 01:24:33,740 --> 01:24:36,740 want the cat to live forever and meow incessantly 1835 01:24:36,740 --> 01:24:39,690 or if it is a clock that you want to tick forever or the like. 1836 01:24:39,690 --> 01:24:44,720 So here, for instance, is how we might have a cat meow endlessly, 1837 01:24:44,720 --> 01:24:47,420 using this so-called for loop instead. 1838 01:24:47,420 --> 01:24:50,330 But recall that in Scratch, we also had this ability 1839 01:24:50,330 --> 01:24:52,700 to create some of our own puzzle pieces. 1840 01:24:52,700 --> 01:24:55,700 And this, too, is something that we're going to be able to do here in C. 1841 01:24:55,700 --> 01:24:59,570 And let me propose that we do exactly that 1842 01:24:59,570 --> 01:25:03,090 by introducing the C analog of this. 1843 01:25:03,090 --> 01:25:08,023 So here, for instance, is, in Scratch, our definition 1844 01:25:08,023 --> 01:25:10,190 of a function called meow whose sole purpose in life 1845 01:25:10,190 --> 01:25:12,740 was to just play the sound "meow" until it's done. 1846 01:25:12,740 --> 01:25:15,000 This is going to look a little weird at first. 1847 01:25:15,000 --> 01:25:17,540 But you'll notice some similarities with main. 1848 01:25:17,540 --> 01:25:21,230 So recall this thing I keep typing with main, int main(void), int main(void). 1849 01:25:21,230 --> 01:25:25,080 That's just the "when green flag clicked" equivalent for today. 1850 01:25:25,080 --> 01:25:28,940 But if you want to create your own puzzle piece or your own function in C, 1851 01:25:28,940 --> 01:25:31,190 you, for now, literally do this. 1852 01:25:31,190 --> 01:25:34,760 You say, void, the name of the function you want to create, and then 1853 01:25:34,760 --> 01:25:35,870 void in parentheses. 1854 01:25:35,870 --> 01:25:39,920 And technically what this means is that this function has no return value. 1855 01:25:39,920 --> 01:25:42,800 It doesn't hand you anything back like get_string or get_int. 1856 01:25:42,800 --> 01:25:45,500 And the "void" in parentheses means it takes no inputs. 1857 01:25:45,500 --> 01:25:46,437 It only meows. 1858 01:25:46,437 --> 01:25:48,020 You don't have to tell it how to meow. 1859 01:25:48,020 --> 01:25:49,220 It's just going to meow. 1860 01:25:49,220 --> 01:25:51,740 So no arguments, so to speak. 1861 01:25:51,740 --> 01:25:53,990 This literally just prints out "meow." 1862 01:25:53,990 --> 01:25:56,990 But what this does for me is it abstracts away the idea of meowing. 1863 01:25:56,990 --> 01:25:59,360 I don't need to know how to use printf or that you're 1864 01:25:59,360 --> 01:26:01,370 using printf to make the cat meow. 1865 01:26:01,370 --> 01:26:05,300 I now have a function in life called meow because in Scratch, recall, 1866 01:26:05,300 --> 01:26:06,470 I used it like this. 1867 01:26:06,470 --> 01:26:10,640 When the green flag is clicked, I could repeat three times this new custom 1868 01:26:10,640 --> 01:26:11,450 puzzle piece. 1869 01:26:11,450 --> 01:26:13,940 But in C, I could now do this. 1870 01:26:13,940 --> 01:26:18,920 In my main program, I can use a for loop just like we saw a moment ago, 1871 01:26:18,920 --> 01:26:20,480 copy/pasted from earlier. 1872 01:26:20,480 --> 01:26:25,310 But now I can call my own C function called meow. 1873 01:26:25,310 --> 01:26:28,040 And let me go ahead now and do this. 1874 01:26:28,040 --> 01:26:33,560 If I go over to my C code here, back in VS Code, let me go ahead 1875 01:26:33,560 --> 01:26:35,480 and delete everything inside main. 1876 01:26:35,480 --> 01:26:42,260 Let me go ahead and do for int i equals 0, i is less than 3, i++. 1877 01:26:42,260 --> 01:26:45,980 Inside of my curly braces, let me go ahead and say "meow." 1878 01:26:45,980 --> 01:26:49,460 But I now need this meow function to exist because if I 1879 01:26:49,460 --> 01:26:52,280 do "make meow" again, notice error. 1880 01:26:52,280 --> 01:26:56,660 "Implicit declaration of function meow is invalid in C99"-- 1881 01:26:56,660 --> 01:26:59,970 the 1999 version of C. What does that mean? 1882 01:26:59,970 --> 01:27:02,510 Well, it doesn't know what the meow function is. 1883 01:27:02,510 --> 01:27:04,820 And the meow function is not in CS50.h. 1884 01:27:04,820 --> 01:27:06,710 It's not in stdio.h. 1885 01:27:06,710 --> 01:27:08,070 I have to create it. 1886 01:27:08,070 --> 01:27:12,020 So let me type out or really copy/paste what I had on the screen a moment ago-- 1887 01:27:12,020 --> 01:27:13,370 "void meow meow"-- 1888 01:27:13,370 --> 01:27:20,210 [CHUCKLES] "void meow(void)" printf, quote, unquote, "meow," close quote, 1889 01:27:20,210 --> 01:27:21,440 semicolon. 1890 01:27:21,440 --> 01:27:24,350 But here, too, let me scooch this down a bit 1891 01:27:24,350 --> 01:27:26,010 so you can see all the code at once. 1892 01:27:26,010 --> 01:27:27,620 Let me now do make meow. 1893 01:27:27,620 --> 01:27:30,860 And unfortunately, I still have an error. 1894 01:27:30,860 --> 01:27:36,680 If I scroll up, still on line 7 of meow.c, 1895 01:27:36,680 --> 01:27:42,300 my compiler thinks that meow is invalid, that it does not exist. 1896 01:27:42,300 --> 01:27:44,150 This too is a common mistake. 1897 01:27:44,150 --> 01:27:50,240 And as simple as this code might be in spirit, where did I screw up? 1898 01:27:50,240 --> 01:27:51,655 Yeah, in the middle. 1899 01:27:51,655 --> 01:27:54,530 STUDENT: You need to define the function like above where you use it. 1900 01:27:54,530 --> 01:27:57,238 DAVID MALAN: Yeah, I need to define the function before I use it. 1901 01:27:57,238 --> 01:27:59,120 So again, C is going to take you literally. 1902 01:27:59,120 --> 01:28:03,230 If you try to call meow on line 7, you better not define it on line 11. 1903 01:28:03,230 --> 01:28:05,120 You better define it higher up. 1904 01:28:05,120 --> 01:28:09,290 So the simplest fix is going to be just to do this. 1905 01:28:09,290 --> 01:28:10,610 Let me clear my terminal. 1906 01:28:10,610 --> 01:28:13,970 Let me highlight and just delete the meow function. 1907 01:28:13,970 --> 01:28:15,770 And let me just paste it up here. 1908 01:28:15,770 --> 01:28:18,000 And this will actually solve the problem. 1909 01:28:18,000 --> 01:28:19,950 Make meow now works. 1910 01:28:19,950 --> 01:28:22,550 And if I do ./meow, that, too, works. 1911 01:28:22,550 --> 01:28:26,090 But this isn't really the best solution because if your solution is constantly, 1912 01:28:26,090 --> 01:28:28,798 oh, well, just put it up there, put it up there, put it up there, 1913 01:28:28,798 --> 01:28:30,530 I bet we could contrive a situation where 1914 01:28:30,530 --> 01:28:32,450 one function needs to be above the other, 1915 01:28:32,450 --> 01:28:33,620 but it needs to be above the other. 1916 01:28:33,620 --> 01:28:35,495 And that's just not going to work in general. 1917 01:28:35,495 --> 01:28:40,110 And more importantly, it just pushes main lower and lower and lower 1918 01:28:40,110 --> 01:28:40,712 in your file. 1919 01:28:40,712 --> 01:28:42,420 But the whole point of your main function 1920 01:28:42,420 --> 01:28:43,890 is like, that's the entry point. 1921 01:28:43,890 --> 01:28:46,540 That is what happens when the green flag is clicked. 1922 01:28:46,540 --> 01:28:50,340 And so just in terms of user conventions, it's just useful for main 1923 01:28:50,340 --> 01:28:53,400 to always be at the top of a file because then you can find it fast. 1924 01:28:53,400 --> 01:28:56,910 Your friends can, your TFs can find it quickly if it's at the top. 1925 01:28:56,910 --> 01:29:01,290 So the other solution here would be to leave meow at the bottom 1926 01:29:01,290 --> 01:29:02,880 and leave main at the top. 1927 01:29:02,880 --> 01:29:07,080 But this is the only time, if I may, that copy/paste is OK. 1928 01:29:07,080 --> 01:29:11,560 What I've highlighted here in line 11 is what's called the function's prototype. 1929 01:29:11,560 --> 01:29:16,860 It is enough information to give you the return type, the name of the function, 1930 01:29:16,860 --> 01:29:18,630 and the return value-- 1931 01:29:18,630 --> 01:29:20,820 and any arguments. 1932 01:29:20,820 --> 01:29:25,590 And so if you just copy/paste that one line and end it with a semicolon 1933 01:29:25,590 --> 01:29:29,850 up there, that's enough of a hint to the compiler 1934 01:29:29,850 --> 01:29:32,370 that, OK, it doesn't exist yet, but it will. 1935 01:29:32,370 --> 01:29:34,650 And it will look like that. 1936 01:29:34,650 --> 01:29:37,110 That's the only time it's OK to copy/paste 1937 01:29:37,110 --> 01:29:39,630 the very first line of a function you've written 1938 01:29:39,630 --> 01:29:42,000 to the top of the file with a semicolon so 1939 01:29:42,000 --> 01:29:45,270 that you can make the compiler happy. 1940 01:29:45,270 --> 01:29:51,390 So if I do make meow now, still no errors. ./meow, and it now works. 1941 01:29:51,390 --> 01:29:55,800 But let me add one final feature, coming back to Scratch here. 1942 01:29:55,800 --> 01:29:57,480 And then it's time for a snack. 1943 01:29:57,480 --> 01:30:01,920 So here, recall, was sort of the last fancy thing we did in Scratch, where 1944 01:30:01,920 --> 01:30:04,380 we created not only our own custom puzzle piece, 1945 01:30:04,380 --> 01:30:08,370 but it took an input so that we didn't need to keep using the loop ourself. 1946 01:30:08,370 --> 01:30:11,250 We could just let the meow function be told how many times 1947 01:30:11,250 --> 01:30:12,570 do you want the cat to meow. 1948 01:30:12,570 --> 01:30:16,980 So in C, we don't have to make that many changes except this. 1949 01:30:16,980 --> 01:30:21,670 We change the prototype to take an argument inside of parentheses. 1950 01:30:21,670 --> 01:30:23,190 And this is the syntax for that. 1951 01:30:23,190 --> 01:30:26,850 If you want your own function in C to take one or more arguments, 1952 01:30:26,850 --> 01:30:30,330 you give the arguments a name, n, or whatever you want to call it. 1953 01:30:30,330 --> 01:30:33,060 But you have to tell C what the type of that input is. 1954 01:30:33,060 --> 01:30:34,650 So it's an int n. 1955 01:30:34,650 --> 01:30:36,240 So it knows it's a number. 1956 01:30:36,240 --> 01:30:38,290 And then you can just use n in your program. 1957 01:30:38,290 --> 01:30:41,460 So instead of hard coding, typing manually the number 3, 1958 01:30:41,460 --> 01:30:43,090 I'm just using n here. 1959 01:30:43,090 --> 01:30:46,590 So this is equivalent to what I did with Scratch, by just dragging and dropping 1960 01:30:46,590 --> 01:30:48,720 the n variable there. 1961 01:30:48,720 --> 01:30:51,240 And then "meow" will get printed that many times. 1962 01:30:51,240 --> 01:30:54,780 If I want to then use this-- notice, this is the last version of the cat 1963 01:30:54,780 --> 01:30:58,330 that we did last week-- you just say "meow" this many times. 1964 01:30:58,330 --> 01:31:03,060 So in C, this is where now the code gets very succinct 1965 01:31:03,060 --> 01:31:06,653 because all the main part of the program does is meow three times. 1966 01:31:06,653 --> 01:31:08,070 So this, again, is an abstraction. 1967 01:31:08,070 --> 01:31:11,730 I don't need to know, care, or remember how meow is implemented. 1968 01:31:11,730 --> 01:31:16,230 I just need to know what its return value, its name, and any arguments 1969 01:31:16,230 --> 01:31:17,560 thereto are. 1970 01:31:17,560 --> 01:31:21,600 So if I make this change, I think we can get the cat 1971 01:31:21,600 --> 01:31:23,490 to meow any number of times. 1972 01:31:23,490 --> 01:31:25,920 Let me go back over to my C code here. 1973 01:31:25,920 --> 01:31:31,710 Let me go back into the file and change "void" here to be int n, 1974 01:31:31,710 --> 01:31:33,390 where n just means number. 1975 01:31:33,390 --> 01:31:36,960 I could use i, but n tends to be a quantity instead of a counter. 1976 01:31:36,960 --> 01:31:40,320 I then, inside of this function, am going to do a for loop-- 1977 01:31:40,320 --> 01:31:43,620 for int i get 0; i less than n-- 1978 01:31:43,620 --> 01:31:46,110 instead of 3-- i++. 1979 01:31:46,110 --> 01:31:49,050 And then inside of here, I'll paste that "meow" again. 1980 01:31:49,050 --> 01:31:52,950 I need to change my prototype to be identical, so another copy/paste, 1981 01:31:52,950 --> 01:31:54,240 or just manually edit it. 1982 01:31:54,240 --> 01:31:56,940 But now notice what's cool about main, is 1983 01:31:56,940 --> 01:32:00,090 that now I can meow maybe three times. 1984 01:32:00,090 --> 01:32:04,260 Make meow, Enter, ./meow. 1985 01:32:04,260 --> 01:32:09,870 OK, or if I really want to be cool, I can change this to 30,000 times. 1986 01:32:09,870 --> 01:32:11,940 Go back here, make meow. 1987 01:32:11,940 --> 01:32:16,500 Increase the size of my terminal window for a dramatic pre-break flourish. 1988 01:32:16,500 --> 01:32:18,390 And there are 30-- that was a fast cat. 1989 01:32:18,390 --> 01:32:19,950 There are 30,000 meows. 1990 01:32:19,950 --> 01:32:22,990 I think now let's go ahead and take-- that's a lot-- a 10-minute break. 1991 01:32:22,990 --> 01:32:23,940 We'll see you in 10. 1992 01:32:23,940 --> 01:32:26,400 Cookies are now served outside. 1993 01:32:26,400 --> 01:32:29,490 All right, so we are back. 1994 01:32:29,490 --> 01:32:31,920 And I realize this has been a lot so far, right? 1995 01:32:31,920 --> 01:32:33,630 So there's a lot of new syntax. 1996 01:32:33,630 --> 01:32:36,100 There's a lot of translation of Scratch over to C. 1997 01:32:36,100 --> 01:32:39,790 But among the goals of having spent last week in Scratch 1998 01:32:39,790 --> 01:32:44,830 and having spent problems at 0 in Scratch is that none of today's ideas 1999 01:32:44,830 --> 01:32:46,430 are really all that new. 2000 01:32:46,430 --> 01:32:49,780 It's just a lot of syntax that will get more comfortable and more 2001 01:32:49,780 --> 01:32:52,480 in your muscle memory as time passes. 2002 01:32:52,480 --> 01:32:56,170 Up until now, though, we've focused largely on these side effects, 2003 01:32:56,170 --> 01:32:58,100 like things happening on the screen. 2004 01:32:58,100 --> 01:33:01,450 And that was akin to the speech bubble appearing in the world of Scratch. 2005 01:33:01,450 --> 01:33:05,170 But let's focus for just a bit-- before we then explore things 2006 01:33:05,170 --> 01:33:07,930 we can't do very well in code-- on return 2007 01:33:07,930 --> 01:33:10,870 values instead in C. We've seen them already. 2008 01:33:10,870 --> 01:33:12,880 Like, get_string returns a value. 2009 01:33:12,880 --> 01:33:16,400 Get_int returns a value, a string and an int respectively. 2010 01:33:16,400 --> 01:33:19,000 But what if we want to make our own functions that don't just 2011 01:33:19,000 --> 01:33:21,910 meow and visually have this side effect of meowing on the screen 2012 01:33:21,910 --> 01:33:24,310 but actually hand us back some value? 2013 01:33:24,310 --> 01:33:26,950 Well, I bet we can do this in C, as well. 2014 01:33:26,950 --> 01:33:30,488 Well, let me propose that to go that route-- 2015 01:33:30,488 --> 01:33:31,780 let me go back to VS Code here. 2016 01:33:31,780 --> 01:33:33,940 And let's make our very simple calculator 2017 01:33:33,940 --> 01:33:35,668 that just adds some numbers together. 2018 01:33:35,668 --> 01:33:37,460 But the same calculator, we'll soon see, is 2019 01:33:37,460 --> 01:33:40,790 going to get us into trouble if you don't understand what the computer is 2020 01:33:40,790 --> 01:33:42,770 doing underneath the hood. 2021 01:33:42,770 --> 01:33:47,690 Let me go ahead and run code of, say, calculator.c. 2022 01:33:47,690 --> 01:33:49,910 And in here, let me go ahead and give myself 2023 01:33:49,910 --> 01:33:56,660 access to the CS50 library with CS50.h, the stdio.h library with stdio.h, 2024 01:33:56,660 --> 01:34:01,370 int main(void), which, again, we'll just take for granted today that we have 2025 01:34:01,370 --> 01:34:03,290 to include atop any of these programs. 2026 01:34:03,290 --> 01:34:06,420 And let's just add two numbers together-- super simple calculator. 2027 01:34:06,420 --> 01:34:08,420 So it gives me a variable called x. 2028 01:34:08,420 --> 01:34:10,640 Assign it the return value of get_int. 2029 01:34:10,640 --> 01:34:13,520 And I'll ask the user to give us x. 2030 01:34:13,520 --> 01:34:15,530 Give me another variable called y. 2031 01:34:15,530 --> 01:34:18,470 Assign it the return value of get_int again. 2032 01:34:18,470 --> 01:34:20,900 But this time, ask the user for y. 2033 01:34:20,900 --> 01:34:26,600 And then, lastly, let's just go ahead and print out the value of x plus y. 2034 01:34:26,600 --> 01:34:29,540 But I don't think I can get away with something 2035 01:34:29,540 --> 01:34:33,230 like this, x plus y semicolon, because if I 2036 01:34:33,230 --> 01:34:36,080 do this, based on what we've seen before, 2037 01:34:36,080 --> 01:34:37,790 what's actually going to get printed out? 2038 01:34:37,790 --> 01:34:38,390 STUDENT: x plus y. 2039 01:34:38,390 --> 01:34:40,250 DAVID MALAN: Right, literally like x plus y. 2040 01:34:40,250 --> 01:34:43,700 So I think this is where I need the F in "printf" for formatting. 2041 01:34:43,700 --> 01:34:48,470 What I think I really want to do is print out the value of some placeholder 2042 01:34:48,470 --> 01:34:51,140 because, what do I want to substitute for percent i 2043 01:34:51,140 --> 01:34:55,280 maybe as a second argument to printf intuitively? 2044 01:34:55,280 --> 01:34:56,990 Maybe just x plus y. 2045 01:34:56,990 --> 01:34:59,630 So indeed, I can get away with this because it turns out in C, 2046 01:34:59,630 --> 01:35:03,290 there's a bunch of arithmetic operators, all of the ones that you might expect, 2047 01:35:03,290 --> 01:35:07,010 including addition, subtraction, multiplication, division, 2048 01:35:07,010 --> 01:35:09,570 and even this one, the so-called modulo operator, 2049 01:35:09,570 --> 01:35:12,470 which generally gives us the ability to calculate a remainder when 2050 01:35:12,470 --> 01:35:13,977 you divide one number by another. 2051 01:35:13,977 --> 01:35:15,560 But I'll keep it simple with addition. 2052 01:35:15,560 --> 01:35:20,480 And indeed, with printf, if I want to print out the value of x plus y, 2053 01:35:20,480 --> 01:35:21,480 I can do that. 2054 01:35:21,480 --> 01:35:25,940 But I have to tell printf what kind of value to expect, an integer, 2055 01:35:25,940 --> 01:35:29,010 thus the percent i instead of %s for string. 2056 01:35:29,010 --> 01:35:30,630 And I think this should do the job. 2057 01:35:30,630 --> 01:35:32,090 So let me go back to my terminal. 2058 01:35:32,090 --> 01:35:34,370 Make calculator, Enter. 2059 01:35:34,370 --> 01:35:37,430 All is well so far. ./calculator, and let's keep it simple-- 2060 01:35:37,430 --> 01:35:39,230 1 for x, 2 for y. 2061 01:35:39,230 --> 01:35:42,140 And indeed, I get 3 as the output. 2062 01:35:42,140 --> 01:35:43,170 It's not very dynamic. 2063 01:35:43,170 --> 01:35:46,170 It can't do a subtraction or multiplication or much more. 2064 01:35:46,170 --> 01:35:49,370 But it does at least do those kinds of calculations. 2065 01:35:49,370 --> 01:35:54,085 But let me propose now that we maybe make a reusable addition 2066 01:35:54,085 --> 01:35:56,960 function, right, because addition is something I'm going to do a lot. 2067 01:35:56,960 --> 01:35:59,750 And maybe it should be abstracted away with a function 2068 01:35:59,750 --> 01:36:02,310 just like meowing was abstracted away a moment ago. 2069 01:36:02,310 --> 01:36:05,060 So let me go ahead and instead of doing this, 2070 01:36:05,060 --> 01:36:08,360 let me go ahead and give myself a function called add, 2071 01:36:08,360 --> 01:36:11,870 but instead of last time where I had a meow function, 2072 01:36:11,870 --> 01:36:14,420 I'm obviously going to call this "add" instead. 2073 01:36:14,420 --> 01:36:19,040 And instead of last time, taking in no arguments, 2074 01:36:19,040 --> 01:36:21,600 I think I want add to work a little differently. 2075 01:36:21,600 --> 01:36:24,920 I don't want add necessarily to take an argument yet, 2076 01:36:24,920 --> 01:36:27,320 but I do want add to return some type of value. 2077 01:36:27,320 --> 01:36:31,347 And just intuitively, what type of value should an addition function return? 2078 01:36:31,347 --> 01:36:32,180 STUDENT: An integer. 2079 01:36:32,180 --> 01:36:33,680 DAVID MALAN: An integer, so an int. 2080 01:36:33,680 --> 01:36:37,250 So I'm going to change void, which means the absence of a return value-- 2081 01:36:37,250 --> 01:36:39,860 nothing's coming back-- to literally "int." 2082 01:36:39,860 --> 01:36:43,250 But I'm not going to change the thing inside parentheses yet. 2083 01:36:43,250 --> 01:36:47,090 I'm going to go ahead and copy my prototype up here. 2084 01:36:47,090 --> 01:36:51,590 And I'm going to make this change, return x plus y. 2085 01:36:51,590 --> 01:36:57,438 And then here, instead of printing out x plus y, let's go ahead and do this. 2086 01:36:57,438 --> 01:36:59,480 Let me give myself a third variable just for now. 2087 01:36:59,480 --> 01:37:02,540 z equals the return value of this brand-new 2088 01:37:02,540 --> 01:37:05,660 add function that's going to add x plus y for me. 2089 01:37:05,660 --> 01:37:07,520 And then let me print out the value of z. 2090 01:37:07,520 --> 01:37:10,860 Instead of x plus y, I'm outsourcing now to this add function 2091 01:37:10,860 --> 01:37:14,690 so it will do the addition of x plus y. 2092 01:37:14,690 --> 01:37:19,160 So similar in spirit to meowing, but the return values, I claim, 2093 01:37:19,160 --> 01:37:20,400 are about to create an issue. 2094 01:37:20,400 --> 01:37:22,640 So let me make calculator again. 2095 01:37:22,640 --> 01:37:24,270 And there's definitely some errors. 2096 01:37:24,270 --> 01:37:28,580 So here we have, "use of undeclared identifier x." 2097 01:37:28,580 --> 01:37:30,390 And that's on line 17. 2098 01:37:30,390 --> 01:37:32,300 So that's pretty far down in the file. 2099 01:37:32,300 --> 01:37:37,350 So specifically, my compiler does not like my use of x on line 17. 2100 01:37:37,350 --> 01:37:42,510 But wait a minute, x is clearly defined on line 8. 2101 01:37:42,510 --> 01:37:46,555 What intuitively might explain this issue 2102 01:37:46,555 --> 01:37:48,180 even if you've never programmed before? 2103 01:37:48,180 --> 01:37:48,750 Yeah? 2104 01:37:48,750 --> 01:37:52,245 STUDENT: Well, because x and y are defined in the main function, not 2105 01:37:52,245 --> 01:37:53,277 the add function. 2106 01:37:53,277 --> 01:37:56,110 DAVID MALAN: Yeah, because x and y are defined in the main function, 2107 01:37:56,110 --> 01:37:57,412 not in the add function. 2108 01:37:57,412 --> 01:37:59,620 So the term of art here that we're about to introduce 2109 01:37:59,620 --> 01:38:00,820 is something called "scope." 2110 01:38:00,820 --> 01:38:05,920 So "scope" just refers to the context in which variables exist-- 2111 01:38:05,920 --> 01:38:08,030 the context in which variables exist. 2112 01:38:08,030 --> 01:38:09,580 So by that, I mean this. 2113 01:38:09,580 --> 01:38:11,200 On line 8, I've declared x. 2114 01:38:11,200 --> 01:38:12,595 On line y, I've declared-- 2115 01:38:12,595 --> 01:38:14,830 [CHUCKLES] on line 9, I've declared y. 2116 01:38:14,830 --> 01:38:18,100 But the catch is-- and here's where the curly braces are helpful-- 2117 01:38:18,100 --> 01:38:25,000 those variables only exist in the context of the outer curly braces 2118 01:38:25,000 --> 01:38:26,950 that are nearest to them, like this. 2119 01:38:26,950 --> 01:38:31,690 So I can use x and y on lines 10, 11, 12, and even up to 13, 2120 01:38:31,690 --> 01:38:33,170 but not thereafter. 2121 01:38:33,170 --> 01:38:35,920 So I certainly can't use x down here on line 7. 2122 01:38:35,920 --> 01:38:39,400 But this is a problem, because if add's purpose in life is to add x and y 2123 01:38:39,400 --> 01:38:43,540 but add can't access x plus y, well, we have an issue of scope. 2124 01:38:43,540 --> 01:38:46,840 Like, x and y are not in scope for this add function. 2125 01:38:46,840 --> 01:38:50,650 But that's OK because remember that every function we've seen thus far 2126 01:38:50,650 --> 01:38:53,790 can have maybe a return value or a side effect, 2127 01:38:53,790 --> 01:38:59,220 but it can also take 0 or one or two or more inputs, known as arguments. 2128 01:38:59,220 --> 01:39:00,740 So what if I instead do this? 2129 01:39:00,740 --> 01:39:02,460 Let me clear my terminal window. 2130 01:39:02,460 --> 01:39:05,630 And let me update add to not take nothing 2131 01:39:05,630 --> 01:39:07,550 as input but maybe two integers. 2132 01:39:07,550 --> 01:39:10,130 And I'll call them arbitrarily a and b. 2133 01:39:10,130 --> 01:39:12,920 But I have to tell the compiler what type of arguments 2134 01:39:12,920 --> 01:39:16,040 they are-- two integers, one after the other. 2135 01:39:16,040 --> 01:39:18,720 And now what I can do is this. 2136 01:39:18,720 --> 01:39:21,380 Let me change this up here, too-- int a, int b-- 2137 01:39:21,380 --> 01:39:23,840 just so that the prototype is exactly the same. 2138 01:39:23,840 --> 01:39:27,800 And the only purpose of this prototype is just to avoid the previous error, 2139 01:39:27,800 --> 01:39:30,440 where the compiler didn't realize add was going to exist 2140 01:39:30,440 --> 01:39:32,790 because it came later in the file. 2141 01:39:32,790 --> 01:39:37,580 So here on line 11 now, if I want to add two values, x and y, 2142 01:39:37,580 --> 01:39:39,650 this is now the syntax. 2143 01:39:39,650 --> 01:39:42,530 We saw syntax in Scratch for passing in inputs 2144 01:39:42,530 --> 01:39:44,360 to tell it how many times to meow. 2145 01:39:44,360 --> 01:39:50,160 So this is just telling add what two numbers to add together. 2146 01:39:50,160 --> 01:39:54,787 So now I have to change this to a plus b, for reasons we'll soon see. 2147 01:39:54,787 --> 01:39:56,120 And let me see if this is right. 2148 01:39:56,120 --> 01:39:57,060 Make calculator. 2149 01:39:57,060 --> 01:39:59,000 So far so good. ./calculator. 2150 01:39:59,000 --> 01:40:02,120 Let's do 1 and 2 for x and y respectively. 2151 01:40:02,120 --> 01:40:05,630 And hopefully we should, again, see 3. 2152 01:40:05,630 --> 01:40:07,020 Now, what's going on? 2153 01:40:07,020 --> 01:40:11,990 So here, again, if I zoom in on my add function, this "int" here on the left, 2154 01:40:11,990 --> 01:40:15,476 on line 15, means what about add? 2155 01:40:15,476 --> 01:40:16,700 STUDENT: [INAUDIBLE] 2156 01:40:16,700 --> 01:40:18,980 DAVID MALAN: This means that it has a return value, that it's an int. 2157 01:40:18,980 --> 01:40:21,563 So it's going to hand me back, metaphorically, a slip of paper 2158 01:40:21,563 --> 01:40:24,080 with an answer on it that is of type integer. 2159 01:40:24,080 --> 01:40:25,400 It's not a word, like my name. 2160 01:40:25,400 --> 01:40:26,750 It's a number instead. 2161 01:40:26,750 --> 01:40:33,290 These mentions of int here and here are inside the parentheses, which means 2162 01:40:33,290 --> 01:40:36,390 this function, add, takes two inputs. 2163 01:40:36,390 --> 01:40:37,460 The first is an int. 2164 01:40:37,460 --> 01:40:38,540 The second is an int. 2165 01:40:38,540 --> 01:40:42,930 And just so we have something to call them, I call them a and b respectively. 2166 01:40:42,930 --> 01:40:49,010 So what happens essentially when I call the add function now on line 11, 2167 01:40:49,010 --> 01:40:51,050 I'm kind of passing in x. 2168 01:40:51,050 --> 01:40:52,610 I'm passing in y. 2169 01:40:52,610 --> 01:40:56,210 But the add function is going to think of them as a and b respectively. 2170 01:40:56,210 --> 01:40:57,770 It could call them anything I want. 2171 01:40:57,770 --> 01:41:00,710 I could change this to the word "first" and "second." 2172 01:41:00,710 --> 01:41:03,500 And then I could literally change this to "first + second." 2173 01:41:03,500 --> 01:41:07,220 Those are perfectly acceptable as argument or variable names. 2174 01:41:07,220 --> 01:41:08,210 But who really cares? 2175 01:41:08,210 --> 01:41:12,500 Like, a and b for such a simple function is perfectly reasonable, too. 2176 01:41:12,500 --> 01:41:14,540 Technically, if your mind is going there, 2177 01:41:14,540 --> 01:41:18,365 I could even call them the exact same thing. 2178 01:41:18,365 --> 01:41:21,240 But let me propose for today, certainly don't do that because it just 2179 01:41:21,240 --> 01:41:24,210 confuses things if you've got x's and y's here, x's and y's here, 2180 01:41:24,210 --> 01:41:25,470 but they're clearly different. 2181 01:41:25,470 --> 01:41:26,310 Just don't do that. 2182 01:41:26,310 --> 01:41:29,640 Try to come up with different variables just to keep yourself sane. 2183 01:41:29,640 --> 01:41:33,930 But here, I have a function that takes now two integers, a and b respectively. 2184 01:41:33,930 --> 01:41:37,920 It just returns the sum of them so that I can now store the return 2185 01:41:37,920 --> 01:41:40,680 value of add in a variable called z. 2186 01:41:40,680 --> 01:41:45,180 And then, quite simply, print it out. 2187 01:41:45,180 --> 01:41:47,520 But there's one other thing I can do here. 2188 01:41:47,520 --> 01:41:51,690 Now, if we think about design, even if you've never programmed before, 2189 01:41:51,690 --> 01:41:55,350 do I really need the variable z? 2190 01:41:55,350 --> 01:41:58,890 Because I'm defining it on line 11, and then I'm quickly using it on line 12, 2191 01:41:58,890 --> 01:41:59,672 and that's it? 2192 01:41:59,672 --> 01:42:01,380 Like, sometimes you don't need variables. 2193 01:42:01,380 --> 01:42:03,213 And they might make your code more readable. 2194 01:42:03,213 --> 01:42:06,840 But strictly speaking-- and this is just kind of like substitution in math-- 2195 01:42:06,840 --> 01:42:10,980 if z is the same thing as "add (x, y)," well, let me go ahead 2196 01:42:10,980 --> 01:42:12,870 and just delete line 11 altogether. 2197 01:42:12,870 --> 01:42:14,520 Let me get rid of mention of z. 2198 01:42:14,520 --> 01:42:16,800 You can actually get away with doing this. 2199 01:42:16,800 --> 01:42:20,340 And much like the Join block in Scratch, where I kind of overlaid it 2200 01:42:20,340 --> 01:42:24,390 on the Say block, kind of stacking them, you can stack functions in C, 2201 01:42:24,390 --> 01:42:26,640 or nest them really, kind of mathematically. 2202 01:42:26,640 --> 01:42:28,530 Honestly, it makes it a little harder to read 2203 01:42:28,530 --> 01:42:31,320 because your mind has to dive in conceptually deeper and deeper 2204 01:42:31,320 --> 01:42:33,010 into this second argument. 2205 01:42:33,010 --> 01:42:35,310 But it's perfectly acceptable, too. 2206 01:42:35,310 --> 01:42:38,100 And just to connect the dots to maybe something from high school, 2207 01:42:38,100 --> 01:42:40,890 this is kind of analogous to a function in math class 2208 01:42:40,890 --> 01:42:43,260 being like f of x, where f is some function name, 2209 01:42:43,260 --> 01:42:45,700 x is some arbitrary input to that function. 2210 01:42:45,700 --> 01:42:49,120 And when you start to put functions inside of functions 2211 01:42:49,120 --> 01:42:51,570 so that the output of one becomes the input to the next, 2212 01:42:51,570 --> 01:42:54,313 it's like using this syntax, f of g of x and so forth. 2213 01:42:54,313 --> 01:42:56,230 If you've never seen that before, don't worry. 2214 01:42:56,230 --> 01:42:59,730 But if you have, it's a way to connect some of these dots. 2215 01:42:59,730 --> 01:43:02,880 Any questions, though, on just this idea of now 2216 01:43:02,880 --> 01:43:05,580 having a function that doesn't just have a side effect 2217 01:43:05,580 --> 01:43:10,500 but instead has a return value? 2218 01:43:10,500 --> 01:43:11,790 Yeah, in back? 2219 01:43:11,790 --> 01:43:14,031 STUDENT: In our declaration of main, why did we 2220 01:43:14,031 --> 01:43:16,622 show it as returning an integer instead of void? 2221 01:43:16,622 --> 01:43:19,080 DAVID MALAN: In our definition of main, why did I do, what? 2222 01:43:19,080 --> 01:43:21,445 STUDENT: Why do we show it as returning an integer 2223 01:43:21,445 --> 01:43:22,870 instead of returning as void? 2224 01:43:22,870 --> 01:43:24,820 DAVID MALAN: Oh, a really good question that I was trying 2225 01:43:24,820 --> 01:43:26,195 to sweep under the rug for today. 2226 01:43:26,195 --> 01:43:28,240 But in every one of our programs thus far, 2227 01:43:28,240 --> 01:43:31,330 I have indeed said "int main(void)." 2228 01:43:31,330 --> 01:43:34,940 Technically speaking, whenever you write a program and it finishes running, 2229 01:43:34,940 --> 01:43:37,750 it actually returns a value somewhat secretly. 2230 01:43:37,750 --> 01:43:41,200 It returns the number 0 by convention, which means all is well. 2231 01:43:41,200 --> 01:43:44,420 And it can return any other integer if something goes wrong. 2232 01:43:44,420 --> 01:43:46,960 In fact, on your Mac, PC, or even phone, if you've ever 2233 01:43:46,960 --> 01:43:50,030 gotten like a weird message on the screen, like something went wrong 2234 01:43:50,030 --> 01:43:53,710 and it's like a weird numeric code, like error negative 129, or something 2235 01:43:53,710 --> 01:43:57,340 arbitrary like that, that tends to mean that some program running 2236 01:43:57,340 --> 01:44:01,660 on your Mac, PC, or phone had something go wrong with the main function. 2237 01:44:01,660 --> 01:44:03,608 And that is the number that was returned. 2238 01:44:03,608 --> 01:44:05,650 But that's more than we want to talk about today. 2239 01:44:05,650 --> 01:44:07,060 But we'll come back to this. 2240 01:44:07,060 --> 01:44:08,890 But main always returns a number. 2241 01:44:08,890 --> 01:44:10,930 By default, it is 0. 2242 01:44:10,930 --> 01:44:12,640 More on that soon. 2243 01:44:12,640 --> 01:44:15,790 All right, so with that said, let's actually tease 2244 01:44:15,790 --> 01:44:18,100 apart what it is we've been using underneath the hood 2245 01:44:18,100 --> 01:44:21,743 here a little bit by returning to VS Code's interface itself. 2246 01:44:21,743 --> 01:44:23,660 It turns out that all this time, even though I 2247 01:44:23,660 --> 01:44:27,050 keep alluding to macOS and Windows, which like 99% of us 2248 01:44:27,050 --> 01:44:29,540 are probably running on our laptops or desktops, 2249 01:44:29,540 --> 01:44:32,390 there's actually other very popular operating systems in the world, 2250 01:44:32,390 --> 01:44:33,620 among which is Linux. 2251 01:44:33,620 --> 01:44:36,960 So Linux is a very popular operating system, 2252 01:44:36,960 --> 01:44:39,380 the thing that turns on-- the thing that boots up 2253 01:44:39,380 --> 01:44:40,880 when you first turn on a computer. 2254 01:44:40,880 --> 01:44:44,690 And it's very commonly used for servers nowadays. 2255 01:44:44,690 --> 01:44:48,860 All of CS50's own servers run some version of Linux. 2256 01:44:48,860 --> 01:44:51,080 Those students more comfortable sometimes 2257 01:44:51,080 --> 01:44:54,410 run Linux on their own Macs or PCs even. 2258 01:44:54,410 --> 01:44:56,720 So Linux is a very popular operating system. 2259 01:44:56,720 --> 01:45:00,110 And it's particularly characterized by its textual interface, 2260 01:45:00,110 --> 01:45:03,770 its command-line interface, even though it also comes with graphical ones, 2261 01:45:03,770 --> 01:45:04,410 as well. 2262 01:45:04,410 --> 01:45:07,490 So again, this term we started today with, a graphical user interface 2263 01:45:07,490 --> 01:45:09,230 is a thing with menus and buttons. 2264 01:45:09,230 --> 01:45:11,850 It's literally what you and I use every day on our devices, 2265 01:45:11,850 --> 01:45:13,220 otherwise known as a GUI. 2266 01:45:13,220 --> 01:45:15,440 But today onward, you'll get more comfortable 2267 01:45:15,440 --> 01:45:18,380 with and more practice with this terminal window 2268 01:45:18,380 --> 01:45:22,430 down here, which represents a command-line interface, or CLI. 2269 01:45:22,430 --> 01:45:26,270 And just so you have a mental model of what's going on in the cloud here, 2270 01:45:26,270 --> 01:45:31,460 when you access cs50.dev, you are accessing this version of VS Code 2271 01:45:31,460 --> 01:45:34,290 in the cloud, a piece of software just running in a browser. 2272 01:45:34,290 --> 01:45:36,680 But that piece of software is automatically 2273 01:45:36,680 --> 01:45:41,600 connected to your very own personal server in the cloud, so to speak. 2274 01:45:41,600 --> 01:45:43,860 Technically speaking, it's a "docker container." 2275 01:45:43,860 --> 01:45:47,930 But it means that you have essentially your own mini server in the cloud 2276 01:45:47,930 --> 01:45:50,640 that only you have access to. 2277 01:45:50,640 --> 01:45:55,460 And that server or container is running an operating system called Linux. 2278 01:45:55,460 --> 01:45:58,370 And in fact, every time I've been running a command down here, 2279 01:45:58,370 --> 01:46:02,750 whether it's code or make or ./hello or anything else, 2280 01:46:02,750 --> 01:46:06,740 I've been running commands from here in Sanders Theatre on a server somewhere 2281 01:46:06,740 --> 01:46:10,280 in the cloud, my own Linux container or server. 2282 01:46:10,280 --> 01:46:12,050 And you'll have the same yourself. 2283 01:46:12,050 --> 01:46:14,270 This is the thing that we have pre-configured 2284 01:46:14,270 --> 01:46:18,320 for you by installing the compiler in so many other pieces of software 2285 01:46:18,320 --> 01:46:20,180 you'll soon see in the class. 2286 01:46:20,180 --> 01:46:24,920 But underneath the hood, then, of Linux is a soon-to-be familiar environment 2287 01:46:24,920 --> 01:46:27,530 that allows you to run different types of commands. 2288 01:46:27,530 --> 01:46:29,542 And those commands include things like this. 2289 01:46:29,542 --> 01:46:32,250 And this is something you'll develop muscle memory for over time. 2290 01:46:32,250 --> 01:46:36,710 But I wanted to give you a sense of some of the most popular textual commands 2291 01:46:36,710 --> 01:46:38,690 because we're essentially about to take away 2292 01:46:38,690 --> 01:46:42,740 muscle memory you have from a GUI world and have you type out words that 2293 01:46:42,740 --> 01:46:46,280 represent double-clicking on things, dragging on other things, 2294 01:46:46,280 --> 01:46:48,680 and other such commands that you and I take for granted. 2295 01:46:48,680 --> 01:46:51,830 It'll be a little painful at first in the first days or weeks, 2296 01:46:51,830 --> 01:46:56,150 but it will make you far more productive long term so that even after CS50, 2297 01:46:56,150 --> 01:46:59,390 if you start using your programming skills in some other domain, class, 2298 01:46:59,390 --> 01:47:02,660 or real-world job, you'll just be a lot faster at the keyboard 2299 01:47:02,660 --> 01:47:04,980 and able to do more work more quickly. 2300 01:47:04,980 --> 01:47:08,660 So with that said, let me go back to VS Code over here. 2301 01:47:08,660 --> 01:47:11,360 I'm going to go ahead and open up my File Explorer over here. 2302 01:47:11,360 --> 01:47:14,180 And you'll see at left all of the files that I've 2303 01:47:14,180 --> 01:47:17,210 created thus far in class and all of the programs 2304 01:47:17,210 --> 01:47:19,250 that I've compiled thus far in class. 2305 01:47:19,250 --> 01:47:21,620 I also have this source 1 directory, which 2306 01:47:21,620 --> 01:47:25,070 you can download from the course's website, which has all of today's code 2307 01:47:25,070 --> 01:47:27,740 pre-written in advance, so you don't have to type everything 2308 01:47:27,740 --> 01:47:28,910 that I literally type. 2309 01:47:28,910 --> 01:47:31,560 But all of these files are things that I've created. 2310 01:47:31,560 --> 01:47:34,070 And you'll see that in white are the C files. 2311 01:47:34,070 --> 01:47:38,180 And grayed out are actually the binary files, the machine code 2312 01:47:38,180 --> 01:47:40,160 that I created that I was running. 2313 01:47:40,160 --> 01:47:45,080 So you can click on any of these files in VS Code to open them. 2314 01:47:45,080 --> 01:47:47,330 For instance, here is hello.c. 2315 01:47:47,330 --> 01:47:49,860 And voila, it opens in the text editor. 2316 01:47:49,860 --> 01:47:52,520 But if I try to open "hello," that's not going to work, 2317 01:47:52,520 --> 01:47:53,870 because that's zeros and ones. 2318 01:47:53,870 --> 01:47:57,098 And frankly, the computer could show me all those zeros and ones, 2319 01:47:57,098 --> 01:47:58,640 but it's just not going to be useful. 2320 01:47:58,640 --> 01:48:01,800 And honestly, it's too easy to make one mistake and break the whole thing. 2321 01:48:01,800 --> 01:48:05,690 So instead, VS Code says that it can't display the text, because it's binary 2322 01:48:05,690 --> 01:48:07,860 or maybe unsupported more generally. 2323 01:48:07,860 --> 01:48:12,470 So know that you want to only click on the .c files when writing C code. 2324 01:48:12,470 --> 01:48:14,240 But let me go ahead and do something else. 2325 01:48:14,240 --> 01:48:18,650 Suppose that I decide that, wait a minute, we're nearing the end of class. 2326 01:48:18,650 --> 01:48:23,180 And we're not done yet, but what if I want to change hello.c to goodbye.c 2327 01:48:23,180 --> 01:48:26,990 or if I want to change meow.c to woof.c and turn it into a dog? 2328 01:48:26,990 --> 01:48:28,310 Well, let's actually do that. 2329 01:48:28,310 --> 01:48:32,450 I could go over here and right click or Control click on the file, 2330 01:48:32,450 --> 01:48:33,650 just like on a Mac or PC. 2331 01:48:33,650 --> 01:48:35,520 I can find the Rename option. 2332 01:48:35,520 --> 01:48:37,460 And I can do it all via the GUI. 2333 01:48:37,460 --> 01:48:41,120 But you should get more comfortable using commands like these here. 2334 01:48:41,120 --> 01:48:45,410 And among the commands on this list are "mv" for move, a.k.a. 2335 01:48:45,410 --> 01:48:46,430 rename. 2336 01:48:46,430 --> 01:48:52,430 So for instance, if I want to change meow.c to be woof.c instead, 2337 01:48:52,430 --> 01:48:56,960 I literally type "mv" space, the original file name, space, 2338 01:48:56,960 --> 01:48:58,140 and the new file name. 2339 01:48:58,140 --> 01:49:00,050 So this is very similar to what I've already 2340 01:49:00,050 --> 01:49:03,260 been doing with the code program or the make program. 2341 01:49:03,260 --> 01:49:06,200 I not only type the name of the command but also the thing 2342 01:49:06,200 --> 01:49:08,690 that I want to code or the thing that I want to make. 2343 01:49:08,690 --> 01:49:12,140 In this case, I type the thing that I want to move from old to new. 2344 01:49:12,140 --> 01:49:15,230 Now, if I hit Enter in a moment, watch on the left-hand side, 2345 01:49:15,230 --> 01:49:18,200 meow.c in the GUI should automatically change 2346 01:49:18,200 --> 01:49:23,800 even though I'm doing this all via the command-line keyboard interface. 2347 01:49:23,800 --> 01:49:25,282 And now it becomes woof.c. 2348 01:49:25,282 --> 01:49:26,740 I mean, it's not all that exciting. 2349 01:49:26,740 --> 01:49:29,380 But this is just to say that they are one and the same. 2350 01:49:29,380 --> 01:49:33,260 One is a GUI, one is a CLI, but it's the same exact thing. 2351 01:49:33,260 --> 01:49:35,530 Moreover, let me go ahead and close now the GUI 2352 01:49:35,530 --> 01:49:37,510 at left, the so-called explorer. 2353 01:49:37,510 --> 01:49:41,327 And in my terminal window alone, now I'm kind of out of my element, 2354 01:49:41,327 --> 01:49:43,660 like wait a minute, what was the file I created earlier? 2355 01:49:43,660 --> 01:49:45,550 Well, there's other commands as well. 2356 01:49:45,550 --> 01:49:50,500 On this list is, coincidentally, "ls," which lists 2357 01:49:50,500 --> 01:49:52,940 the file in your current folder. 2358 01:49:52,940 --> 01:49:56,770 And as you might have gleaned here, "mv" for move, "ls" for list, 2359 01:49:56,770 --> 01:49:59,560 CS people like to be succinct, terse, and type 2360 01:49:59,560 --> 01:50:01,150 the minimal number of keystrokes. 2361 01:50:01,150 --> 01:50:04,180 That's why these are all abbreviated commands instead of full words. 2362 01:50:04,180 --> 01:50:07,480 But if I go back to my terminal window and type "ls," voila, 2363 01:50:07,480 --> 01:50:13,540 there is exactly the same contents of my server but displayed textually. 2364 01:50:13,540 --> 01:50:14,920 And there's some heuristics here. 2365 01:50:14,920 --> 01:50:18,040 In green with an asterisk is all of the programs 2366 01:50:18,040 --> 01:50:21,110 that I made with make that are executable. 2367 01:50:21,110 --> 01:50:24,150 So the asterisks just means this is executable with dot-slash. 2368 01:50:24,150 --> 01:50:27,860 Meanwhile, the source 1 directory, which only I have because I downloaded it 2369 01:50:27,860 --> 01:50:31,520 in advance, has a slash to indicate that it's a folder instead of a file. 2370 01:50:31,520 --> 01:50:36,570 But all of these white files ending in .c we created together here today. 2371 01:50:36,570 --> 01:50:42,020 Now, what if I really am embarrassed by my very first program, hello.c? 2372 01:50:42,020 --> 01:50:48,020 Well, I can very destructively go and use the rm command for remove. 2373 01:50:48,020 --> 01:50:52,370 And rm hello.c is going to prompt me, a little cryptically, 2374 01:50:52,370 --> 01:50:54,740 "remove regular file 'hello.c'?" 2375 01:50:54,740 --> 01:51:01,580 And amazingly, this rm program has code just like we wrote earlier for agree.c, 2376 01:51:01,580 --> 01:51:03,560 where I can type 'y' to delete it. 2377 01:51:03,560 --> 01:51:05,060 I can type 'n' not to delete it. 2378 01:51:05,060 --> 01:51:06,180 But let's delete it. 2379 01:51:06,180 --> 01:51:08,210 Let's go ahead and hit y, enter. 2380 01:51:08,210 --> 01:51:09,840 Nothing seems to happen. 2381 01:51:09,840 --> 01:51:11,370 But in general, that's a good thing. 2382 01:51:11,370 --> 01:51:14,170 But if I type "ls" again, notice what is now missing? 2383 01:51:14,170 --> 01:51:15,920 And in fact, the list is a little shorter. 2384 01:51:15,920 --> 01:51:18,110 So it's one line instead of two. 2385 01:51:18,110 --> 01:51:20,370 "hello.c" is now gone. 2386 01:51:20,370 --> 01:51:24,300 Now, if you do that, there are not easy ways to get the file back. 2387 01:51:24,300 --> 01:51:26,750 So don't do that unless you really want to. 2388 01:51:26,750 --> 01:51:29,910 But there are backups maintained of these files, as well. 2389 01:51:29,910 --> 01:51:31,160 Well, what else is there, too? 2390 01:51:31,160 --> 01:51:32,510 Well, there's all of these other commands. 2391 01:51:32,510 --> 01:51:34,052 And you'll experience them over time. 2392 01:51:34,052 --> 01:51:35,540 Like, "cp" is copy. 2393 01:51:35,540 --> 01:51:40,190 "mkdir" is make directory. "rmdir" is remove directory. 2394 01:51:40,190 --> 01:51:43,070 And for instance, let me just show you one folder. 2395 01:51:43,070 --> 01:51:45,770 If I type "ls," there's that source 1 folder 2396 01:51:45,770 --> 01:51:47,510 that I claimed I downloaded in advance. 2397 01:51:47,510 --> 01:51:50,120 If you want to see what's there, you can type "cd" 2398 01:51:50,120 --> 01:51:53,810 for change directory, source 1, enter. 2399 01:51:53,810 --> 01:51:56,970 And voila, notice that your prompt has now changed. 2400 01:51:56,970 --> 01:51:58,310 And let me clear the screen. 2401 01:51:58,310 --> 01:52:03,320 Just as a visual reminder of where you are, you can see before the dollar sign 2402 01:52:03,320 --> 01:52:05,370 now the name of the folder that you're inside of. 2403 01:52:05,370 --> 01:52:08,090 So in Mac or Windows, you'd see obviously a graphical folder. 2404 01:52:08,090 --> 01:52:11,360 Here, you just see a little textual reminder of where you now are. 2405 01:52:11,360 --> 01:52:14,840 And if I type "ls," you'll see that I wrote a crazy number of files 2406 01:52:14,840 --> 01:52:15,770 before class. 2407 01:52:15,770 --> 01:52:18,380 And each of these represents different versions of the files 2408 01:52:18,380 --> 01:52:20,540 that we've been coding here in real time that I usually 2409 01:52:20,540 --> 01:52:22,748 have printouts of just to go through things in series 2410 01:52:22,748 --> 01:52:25,135 so you have copies online, as well. 2411 01:52:25,135 --> 01:52:28,010 So in short, all of these commands, if you've never used them before, 2412 01:52:28,010 --> 01:52:29,780 they will soon become like muscle memory. 2413 01:52:29,780 --> 01:52:31,760 And they do the most basic of operations. 2414 01:52:31,760 --> 01:52:33,927 But there will be other commands that we'll see over 2415 01:52:33,927 --> 01:52:36,470 time that do even much more than that. 2416 01:52:36,470 --> 01:52:39,050 But let's go ahead now and solve some actual problems. 2417 01:52:39,050 --> 01:52:41,990 And it's no coincidence that we keep showing or alluding 2418 01:52:41,990 --> 01:52:44,300 to Super Mario Brothers in some form, an older game 2419 01:52:44,300 --> 01:52:47,660 from the Nintendo Entertainment System, that allows you ultimately 2420 01:52:47,660 --> 01:52:50,720 to have this two-dimensional world, where Mario moves up and down 2421 01:52:50,720 --> 01:52:52,730 and side scrolls from left to right. 2422 01:52:52,730 --> 01:52:55,940 But you'll see we can distill even some aspects of "Mario" 2423 01:52:55,940 --> 01:53:00,260 into some fairly representative programming problems. 2424 01:53:00,260 --> 01:53:02,835 And in fact, let me propose that we consider this screen 2425 01:53:02,835 --> 01:53:04,460 from the original Super Mario Brothers. 2426 01:53:04,460 --> 01:53:09,810 So there's these four blocks in the sky, each with a question mark. 2427 01:53:09,810 --> 01:53:12,800 And if you click on one of these-- or if Mario jumps up 2428 01:53:12,800 --> 01:53:15,800 underneath each of these question marks, he 2429 01:53:15,800 --> 01:53:18,140 gets like a coin or something else that pops out. 2430 01:53:18,140 --> 01:53:22,550 Let's distill this, though, into its essence and consider in C, how can 2431 01:53:22,550 --> 01:53:26,310 we make, not a blue sky yet, not a green grassy hill, and so forth, 2432 01:53:26,310 --> 01:53:28,910 but how can we just make four question marks in a row, 2433 01:53:28,910 --> 01:53:32,790 because I dare say that we do have the building blocks via which to do this. 2434 01:53:32,790 --> 01:53:38,180 Well, the simplest way might be to go over here and run code of mario.c. 2435 01:53:38,180 --> 01:53:42,560 And then in mario.c, let's include some stdio.h so we have printf. 2436 01:53:42,560 --> 01:53:45,200 Let's do int main(void), as we keep doing. 2437 01:53:45,200 --> 01:53:47,960 And inside of main, let's keep it super simple-- 2438 01:53:47,960 --> 01:53:51,360 1, 2, 3, 4, backslash n. 2439 01:53:51,360 --> 01:53:52,880 Doesn't get much simpler than that. 2440 01:53:52,880 --> 01:53:54,838 This is not going to be the prettiest of games. 2441 01:53:54,838 --> 01:54:00,947 But if I make Mario now, ./mario, I get my four question marks in the sky. 2442 01:54:00,947 --> 01:54:02,780 All right, so it's not all that interesting. 2443 01:54:02,780 --> 01:54:07,287 But this is clearly a candidate for what type of programming feature. 2444 01:54:07,287 --> 01:54:08,565 STUDENT: Scratch. 2445 01:54:08,565 --> 01:54:11,690 DAVID MALAN: Not to Scratch, though Scratch would make it more interesting. 2446 01:54:11,690 --> 01:54:12,005 yeah? 2447 01:54:12,005 --> 01:54:12,320 STUDENT: A loop. 2448 01:54:12,320 --> 01:54:14,028 DAVID MALAN: So some kind of loop, right? 2449 01:54:14,028 --> 01:54:15,980 So print the thing out iteratively instead. 2450 01:54:15,980 --> 01:54:16,730 So let me do that. 2451 01:54:16,730 --> 01:54:19,620 Instead of just printing this out all at once, 2452 01:54:19,620 --> 01:54:25,106 let me go ahead and remove this and do for int i gets zero; i less than 4; 2453 01:54:25,106 --> 01:54:26,280 i++. 2454 01:54:26,280 --> 01:54:29,390 And then in here, let me go ahead and print out just one question mark 2455 01:54:29,390 --> 01:54:30,420 instead. 2456 01:54:30,420 --> 01:54:31,800 And now let's run this. 2457 01:54:31,800 --> 01:54:35,210 So "make mario" to recompile it, ./mario. 2458 01:54:35,210 --> 01:54:37,910 And does anyone not want me to hit Enter yet? 2459 01:54:37,910 --> 01:54:38,855 Why? 2460 01:54:38,855 --> 01:54:40,730 STUDENT: Because it's gonna print a new line. 2461 01:54:40,730 --> 01:54:43,860 DAVID MALAN: Yeah, it's going to print out a new line every time. 2462 01:54:43,860 --> 01:54:48,205 So notice it's four question marks, but there each on its own line. 2463 01:54:48,205 --> 01:54:49,580 All right, well, let me fix this. 2464 01:54:49,580 --> 01:54:51,590 It's obviously because of the backslash n. 2465 01:54:51,590 --> 01:54:52,940 So let me remove that. 2466 01:54:52,940 --> 01:54:55,850 Let me rerun make mario, ./mario. 2467 01:54:55,850 --> 01:54:59,960 And it's better in one way but worse in another. 2468 01:54:59,960 --> 01:55:01,910 So wait, but now the dollar sign is doing 2469 01:55:01,910 --> 01:55:03,785 that thing where it's on the same line, which 2470 01:55:03,785 --> 01:55:05,550 just looks stupid if nothing else. 2471 01:55:05,550 --> 01:55:07,830 So how can I fix that? 2472 01:55:07,830 --> 01:55:08,400 Yeah? 2473 01:55:08,400 --> 01:55:11,070 STUDENT: [INAUDIBLE] 2474 01:55:11,070 --> 01:55:14,070 DAVID MALAN: Yeah, so logically, we don't have that many building blocks 2475 01:55:14,070 --> 01:55:14,570 today. 2476 01:55:14,570 --> 01:55:17,200 It's a lot of new syntax, but it's not that many new ideas. 2477 01:55:17,200 --> 01:55:21,330 Let's just use printf to print out literally one and only 2478 01:55:21,330 --> 01:55:24,690 one of these backslash n's, but outside of the loop so 2479 01:55:24,690 --> 01:55:27,750 it happens after all four of those have been printed. 2480 01:55:27,750 --> 01:55:30,510 All right, let me do make mario again, ./mario. 2481 01:55:30,510 --> 01:55:32,680 And OK, now we're back in business. 2482 01:55:32,680 --> 01:55:35,760 So sort of silly syntactical details, but if you 2483 01:55:35,760 --> 01:55:39,750 reduce the problem to its essence, it should hopefully, logically, 2484 01:55:39,750 --> 01:55:41,225 become clear over time. 2485 01:55:41,225 --> 01:55:44,100 All right, well, how about not just something like that but vertical? 2486 01:55:44,100 --> 01:55:45,720 Well, we've done something vertical already. 2487 01:55:45,720 --> 01:55:47,720 And so I can imagine we could change the program 2488 01:55:47,720 --> 01:55:51,540 to very simply print out three bricks instead of four question marks. 2489 01:55:51,540 --> 01:55:53,890 But what if we consider a two-dimensional world? 2490 01:55:53,890 --> 01:55:55,890 And later on in this game if you go underground, 2491 01:55:55,890 --> 01:55:57,720 everything looks like this with lots of bricks. 2492 01:55:57,720 --> 01:55:59,678 And let me propose, for the sake of discussion, 2493 01:55:59,678 --> 01:56:03,947 that this big wall here is like a 3-by-3 grid of bricks. 2494 01:56:03,947 --> 01:56:05,280 So it's not just a single brick. 2495 01:56:05,280 --> 01:56:07,530 It's like three by three, or nine total. 2496 01:56:07,530 --> 01:56:09,450 Now things get interesting. 2497 01:56:09,450 --> 01:56:11,820 And let me go back to mario.c. 2498 01:56:11,820 --> 01:56:15,150 I could take the easy road out and just say, all right, well, 2499 01:56:15,150 --> 01:56:21,270 let's printf, how about 1, 2, 3, backslash n, close quote. 2500 01:56:21,270 --> 01:56:23,490 And then, OK, let me just copy/paste. 2501 01:56:23,490 --> 01:56:26,520 And I'm using hashes instead of the actual bricks. 2502 01:56:26,520 --> 01:56:28,860 But aesthetically, it's pretty close. 2503 01:56:28,860 --> 01:56:33,073 Let me now go ahead and "make mario" again, ./mario. 2504 01:56:33,073 --> 01:56:34,740 And it doesn't quite look like a square. 2505 01:56:34,740 --> 01:56:37,823 But that's just because the hashes are a little taller than they are wide. 2506 01:56:37,823 --> 01:56:40,140 But it is correct, but not well designed. 2507 01:56:40,140 --> 01:56:44,430 So here, too, what would be better designed than just hardcoding, typing 2508 01:56:44,430 --> 01:56:48,280 literally all of these hashes? 2509 01:56:48,280 --> 01:56:49,876 Yeah? 2510 01:56:49,876 --> 01:56:51,540 STUDENT: We could use maybe two loops. 2511 01:56:51,540 --> 01:56:53,040 DAVID MALAN: Interesting, two loops. 2512 01:56:53,040 --> 01:56:56,080 And why two loops instead of one? 2513 01:56:56,080 --> 01:56:57,580 STUDENT: Oh, wait, nevermind. 2514 01:56:57,580 --> 01:57:00,545 Well, I was going to say you could do it one for vertical and one 2515 01:57:00,545 --> 01:57:01,170 for horizontal. 2516 01:57:01,170 --> 01:57:02,280 DAVID MALAN: OK, it's the right instinct. 2517 01:57:02,280 --> 01:57:04,170 So one for vertical, one for horizontal. 2518 01:57:04,170 --> 01:57:06,060 And even though these predate most of us, 2519 01:57:06,060 --> 01:57:08,220 old-school typewriters you might know or might 2520 01:57:08,220 --> 01:57:12,180 recall that if you feed a piece of paper into it, you can print like line, 2521 01:57:12,180 --> 01:57:16,180 then it scrolls, line, then it scrolls, line, then it scrolls. 2522 01:57:16,180 --> 01:57:18,390 This is kind of how the terminal window works, too. 2523 01:57:18,390 --> 01:57:20,970 You can print rows and columns, but you have 2524 01:57:20,970 --> 01:57:24,540 to print one row at a time, one row at a time, one row at a time. 2525 01:57:24,540 --> 01:57:28,810 It's not easy, but it is possible to go backwards and go up and down. 2526 01:57:28,810 --> 01:57:31,960 But just going row by row by row is more typical. 2527 01:57:31,960 --> 01:57:33,010 So how can I do this? 2528 01:57:33,010 --> 01:57:36,370 Well, I could use at least one and maybe even indeed two loops. 2529 01:57:36,370 --> 01:57:39,270 And this is where we're just now composing different ideas 2530 01:57:39,270 --> 01:57:40,990 from today and even last week. 2531 01:57:40,990 --> 01:57:45,900 So let me go ahead and say, for int i gets 0; i less than 3-- 2532 01:57:45,900 --> 01:57:47,370 for a 3-by-3 grid-- 2533 01:57:47,370 --> 01:57:48,810 i++. 2534 01:57:48,810 --> 01:57:51,180 And now let me cheat slightly. 2535 01:57:51,180 --> 01:57:55,790 Let me print out just three of these here, and that's it. 2536 01:57:55,790 --> 01:57:56,790 So I'm kind of cheating. 2537 01:57:56,790 --> 01:58:01,360 I'm printing out rows dynamically, but I'm still printing three columns all 2538 01:58:01,360 --> 01:58:02,170 in one breath. 2539 01:58:02,170 --> 01:58:03,430 But let's see what happens. 2540 01:58:03,430 --> 01:58:07,840 Make mario, ./mario, and it does work. 2541 01:58:07,840 --> 01:58:12,610 But what if you said, no, I want 4 by 4 or 5 by 5 or 6 by 6? 2542 01:58:12,610 --> 01:58:17,590 Now I have to change the 3 to a 6, and I have to add another three hashes here. 2543 01:58:17,590 --> 01:58:20,180 Things get messy if we don't do this mathematically. 2544 01:58:20,180 --> 01:58:22,120 So let me now do this instead. 2545 01:58:22,120 --> 01:58:26,440 Why don't I go ahead and print out every row at a time. 2546 01:58:26,440 --> 01:58:30,340 But for each row, let me use another loop to decide, like, rat-a-tat-tat, 2547 01:58:30,340 --> 01:58:33,010 from left to right, how many do I want to print. 2548 01:58:33,010 --> 01:58:35,890 So to do this, I could do another for loop. 2549 01:58:35,890 --> 01:58:39,050 I could call this variable something different. j is pretty common. 2550 01:58:39,050 --> 01:58:40,480 We start at i, we go to j. 2551 01:58:40,480 --> 01:58:43,720 If you go past k, maybe l, you're probably doing something wrong. 2552 01:58:43,720 --> 01:58:46,990 You don't want nested, nested, nested loops, but two is OK. 2553 01:58:46,990 --> 01:58:52,480 j equals 0; j is less than 3; j++. 2554 01:58:52,480 --> 01:58:57,178 And then here, I can print out a single one of these and no new line. 2555 01:58:57,178 --> 01:58:58,970 I don't want to screw up like I did before. 2556 01:58:58,970 --> 01:59:00,340 So I'll just do one. 2557 01:59:00,340 --> 01:59:03,970 Let me go ahead and do make mario now, ./mario. 2558 01:59:03,970 --> 01:59:06,482 But when I hit Enter, this is not correct yet. 2559 01:59:06,482 --> 01:59:07,690 What's it going to look like? 2560 01:59:07,690 --> 01:59:09,130 STUDENT: A single line? 2561 01:59:09,130 --> 01:59:12,040 DAVID MALAN: A single line of nine hashes, I think, 2562 01:59:12,040 --> 01:59:14,980 because I never used a single backslash n. 2563 01:59:14,980 --> 01:59:16,220 So that looks wrong. 2564 01:59:16,220 --> 01:59:23,620 So between what line number should I insert a printf of backslash n? 2565 01:59:23,620 --> 01:59:25,660 Let me look a little farther back if I can. 2566 01:59:25,660 --> 01:59:26,920 How about over here? 2567 01:59:26,920 --> 01:59:27,520 Yeah? 2568 01:59:27,520 --> 01:59:28,720 STUDENT: 10 and 11. 2569 01:59:28,720 --> 01:59:30,280 DAVID MALAN: Between 10 and 11. 2570 01:59:30,280 --> 01:59:31,580 So I'm going to go in here. 2571 01:59:31,580 --> 01:59:34,930 I'm going to add printf, quote, unquote, "backslash n" semicolon. 2572 01:59:34,930 --> 01:59:37,380 Let me go back and recompile mario-- 2573 01:59:37,380 --> 01:59:38,290 ./mario. 2574 01:59:38,290 --> 01:59:41,320 And crossing fingers-- voila, perfect. 2575 01:59:41,320 --> 01:59:43,210 I printed out now a 3-by-3. 2576 01:59:43,210 --> 01:59:44,440 Now, it's correct. 2577 01:59:44,440 --> 01:59:48,130 It's not, if we want to be really nitpicky, maybe still not 2578 01:59:48,130 --> 01:59:49,240 the best design. 2579 01:59:49,240 --> 01:59:51,310 Where am I perhaps repeating myself? 2580 01:59:51,310 --> 01:59:53,840 2581 01:59:53,840 --> 01:59:54,627 Yeah? 2582 01:59:54,627 --> 01:59:55,770 STUDENT: [INAUDIBLE] 2583 01:59:55,770 --> 01:59:57,770 DAVID MALAN: Yeah, I mean, it's not a huge deal. 2584 01:59:57,770 --> 02:00:00,247 But now I have two, people would call these magic numbers. 2585 02:00:00,247 --> 02:00:02,330 "Magic" in the sense of, where did that come from? 2586 02:00:02,330 --> 02:00:05,100 You just randomly put it in the middle of your code. 2587 02:00:05,100 --> 02:00:06,878 And you also put the same thing here. 2588 02:00:06,878 --> 02:00:10,170 Now I have to make sure I don't screw up and make one change but not the other. 2589 02:00:10,170 --> 02:00:11,837 So it turns out we can factor these out. 2590 02:00:11,837 --> 02:00:15,050 I can actually do something like this, int n equals 3. 2591 02:00:15,050 --> 02:00:17,690 And then I can just change this to n and this 2592 02:00:17,690 --> 02:00:19,730 to n, which is marginally better because now 2593 02:00:19,730 --> 02:00:22,160 I only have to change n in one place if I want 2594 02:00:22,160 --> 02:00:24,113 to make this thing bigger or smaller. 2595 02:00:24,113 --> 02:00:25,530 It's still going to work the same. 2596 02:00:25,530 --> 02:00:27,830 So make mario, ./mario. 2597 02:00:27,830 --> 02:00:28,880 There's our 3-by-3. 2598 02:00:28,880 --> 02:00:35,120 But if I want to make a 5-by-5, let me change the n to 5, rerun make mario, 2599 02:00:35,120 --> 02:00:35,900 ./mario. 2600 02:00:35,900 --> 02:00:38,480 And now it's a bigger grid, 5-by-5. 2601 02:00:38,480 --> 02:00:40,162 But this is a little fragile. 2602 02:00:40,162 --> 02:00:42,620 And it turns out there's another trick we should introduce. 2603 02:00:42,620 --> 02:00:45,590 It turns out that C supports what are called constants, 2604 02:00:45,590 --> 02:00:48,920 whereby if you have a variable that you want to exist because it's useful 2605 02:00:48,920 --> 02:00:50,857 but you don't want to accidentally change it, 2606 02:00:50,857 --> 02:00:53,690 or if you're working with a partner in class or a colleague at work, 2607 02:00:53,690 --> 02:00:57,140 you don't want your partner or colleague to accidentally change 2608 02:00:57,140 --> 02:01:01,250 that value with their own code, you can go into your code and tell C, 2609 02:01:01,250 --> 02:01:05,790 this is actually a constant integer, a const, so to speak. 2610 02:01:05,790 --> 02:01:07,790 And this will just prevent you or someone else 2611 02:01:07,790 --> 02:01:11,430 from doing something stupid by accidentally changing it elsewhere. 2612 02:01:11,430 --> 02:01:14,510 The code is still going to work the same, ./mario, 2613 02:01:14,510 --> 02:01:18,690 but you won't be accidentally able to change it very easily to something 2614 02:01:18,690 --> 02:01:19,190 else. 2615 02:01:19,190 --> 02:01:22,160 And honestly, what we've now done, too, is set ourselves 2616 02:01:22,160 --> 02:01:23,420 up to make this more dynamic. 2617 02:01:23,420 --> 02:01:27,920 Let me go up here, and let me add the CS50 library so that we have access 2618 02:01:27,920 --> 02:01:30,050 to get_int because now we could do something 2619 02:01:30,050 --> 02:01:36,920 fancy like ask the get_int function for the size of this brick wall. 2620 02:01:36,920 --> 02:01:39,150 And then we can use n dynamically. 2621 02:01:39,150 --> 02:01:42,300 So for instance, let me increase the size of my terminal, make mario, 2622 02:01:42,300 --> 02:01:45,140 ./mario, size 3. 2623 02:01:45,140 --> 02:01:47,150 Gives me a 3-by-3. 2624 02:01:47,150 --> 02:01:50,000 ./mario size 5 gives me a 5-by-5. 2625 02:01:50,000 --> 02:01:54,600 ./mario, how about 50, gives me a crazy big one, but it's all dynamic. 2626 02:01:54,600 --> 02:01:56,760 And now I don't have to even change the code. 2627 02:01:56,760 --> 02:01:58,980 It just now works. 2628 02:01:58,980 --> 02:02:01,500 As an aside, if you're wondering how I type so darn fast, 2629 02:02:01,500 --> 02:02:03,900 sometimes it's just because I'm hitting the up arrow. 2630 02:02:03,900 --> 02:02:06,600 It turns out that Linux will remember, if you 2631 02:02:06,600 --> 02:02:08,860 configure it this way, all of your previous commands. 2632 02:02:08,860 --> 02:02:12,480 So if you hit up, up, up, I can go through the past couple of hours 2633 02:02:12,480 --> 02:02:14,820 of commands that I've typed, which is useful sometimes-- 2634 02:02:14,820 --> 02:02:16,950 not for hours of commands but the past few-- 2635 02:02:16,950 --> 02:02:18,810 just to save yourself some keystrokes. 2636 02:02:18,810 --> 02:02:22,110 And another trick in a terminal window is to do this. 2637 02:02:22,110 --> 02:02:28,050 If I do ./ma and I get bored and I don't want to type out "rio," 2638 02:02:28,050 --> 02:02:31,800 I can also just hit Tab, and it will autocomplete based on the characters 2639 02:02:31,800 --> 02:02:32,470 that do match. 2640 02:02:32,470 --> 02:02:36,990 So those kinds of tricks, too, will save you time over time. 2641 02:02:36,990 --> 02:02:38,070 But let's do this. 2642 02:02:38,070 --> 02:02:41,880 It's kind of broken, arguably, if I do this. 2643 02:02:41,880 --> 02:02:44,400 How about "cat?" 2644 02:02:44,400 --> 02:02:45,900 All right, well, that works. 2645 02:02:45,900 --> 02:02:48,480 That prevents me from doing something stupid 2646 02:02:48,480 --> 02:02:51,120 because get_int only accepts integers. 2647 02:02:51,120 --> 02:02:54,000 But it will accept 0, which does nothing. 2648 02:02:54,000 --> 02:02:56,370 It will accept negative 1, which does nothing. 2649 02:02:56,370 --> 02:02:57,600 And that's not bad. 2650 02:02:57,600 --> 02:02:59,040 It's not doing something weird. 2651 02:02:59,040 --> 02:03:01,890 But it would be nice to catch that and force the user 2652 02:03:01,890 --> 02:03:04,410 to give us a positive integer instead so we at least 2653 02:03:04,410 --> 02:03:05,732 see something on the screen. 2654 02:03:05,732 --> 02:03:08,190 So let me go back into my code, and let me propose that now 2655 02:03:08,190 --> 02:03:12,018 that we have the CS50 library, why don't we do something like this? 2656 02:03:12,018 --> 02:03:13,060 I'm going to change this. 2657 02:03:13,060 --> 02:03:14,640 I'm going to get rid of the constant just in case 2658 02:03:14,640 --> 02:03:16,080 the user needs to type it again. 2659 02:03:16,080 --> 02:03:17,250 And what if I do this? 2660 02:03:17,250 --> 02:03:20,070 While n is less than 1-- 2661 02:03:20,070 --> 02:03:23,610 so if it's 0, negative 1, negative 2, or whatever, let's go ahead 2662 02:03:23,610 --> 02:03:28,860 and again ask the user for an int, and ask them for the size again. 2663 02:03:28,860 --> 02:03:33,780 And therefore, only once n is not less than 1 will 2664 02:03:33,780 --> 02:03:36,670 this loop break out and will proceed with the rest of the code. 2665 02:03:36,670 --> 02:03:37,770 So now let me try this. 2666 02:03:37,770 --> 02:03:42,120 Make mario, ./mario 0-- 2667 02:03:42,120 --> 02:03:42,960 didn't like that. 2668 02:03:42,960 --> 02:03:44,370 Negative 1-- didn't like that. 2669 02:03:44,370 --> 02:03:45,810 Negative 2-- didn't like that. 2670 02:03:45,810 --> 02:03:48,640 3-- it did like that. 2671 02:03:48,640 --> 02:03:52,950 So using a loop now, I can ensure that the human is providing me 2672 02:03:52,950 --> 02:03:55,810 with input that I actually want. 2673 02:03:55,810 --> 02:03:57,180 So this is correct. 2674 02:03:57,180 --> 02:04:01,140 But I dare say 6 through 10 could be done better. 2675 02:04:01,140 --> 02:04:06,580 Why is this poorly designed instinctively? 2676 02:04:06,580 --> 02:04:07,080 Yeah? 2677 02:04:07,080 --> 02:04:07,930 STUDENT: There's repetition. 2678 02:04:07,930 --> 02:04:10,600 DAVID MALAN: What's the repetition, to be clear, what lines? 2679 02:04:10,600 --> 02:04:12,145 STUDENT: Lines 6 and 9. 2680 02:04:12,145 --> 02:04:13,240 DAVID MALAN: 6 and 9. 2681 02:04:13,240 --> 02:04:16,400 OK, so they're literally the same, and that's generally not a good thing. 2682 02:04:16,400 --> 02:04:19,390 And maybe I could change this one to remind the user like, hey, 2683 02:04:19,390 --> 02:04:20,688 that's not a positive number. 2684 02:04:20,688 --> 02:04:22,480 So you might want to customize the message. 2685 02:04:22,480 --> 02:04:26,390 But just having copy/paste here for the most part is not a good thing. 2686 02:04:26,390 --> 02:04:29,770 So it turns out-- and there's just one feature of C we wanted to introduce you 2687 02:04:29,770 --> 02:04:33,400 to today-- it turns out there's one other way that would actually help us 2688 02:04:33,400 --> 02:04:37,450 eliminate this redundancy of using get_int twice and particularly asking 2689 02:04:37,450 --> 02:04:39,670 literally the same question-- size-- 2690 02:04:39,670 --> 02:04:40,990 twice in duplicate. 2691 02:04:40,990 --> 02:04:42,937 So I'm actually going to go into my code here, 2692 02:04:42,937 --> 02:04:45,520 and I'm going to delete the loop as we've written it thus far. 2693 02:04:45,520 --> 02:04:47,750 And instead of using a while loop, I'm going 2694 02:04:47,750 --> 02:04:49,750 to introduce instead something that we typically 2695 02:04:49,750 --> 02:04:52,960 call a do while loop, which is a little bit different. 2696 02:04:52,960 --> 02:04:55,360 Indeed, we begin with the keyword "do," and then 2697 02:04:55,360 --> 02:04:57,850 inside of the curly braces, what I'm going to do here 2698 02:04:57,850 --> 02:05:02,690 is that thing I might want to do once and more times thereafter. 2699 02:05:02,690 --> 02:05:08,690 So for instance, I'm going to say n equals get_int quote, unquote, "size." 2700 02:05:08,690 --> 02:05:12,110 And then at the bottom of this block of code, then 2701 02:05:12,110 --> 02:05:15,380 I'm going to use the keyword "while," as well as parentheses as always 2702 02:05:15,380 --> 02:05:16,740 for a Boolean expression. 2703 02:05:16,740 --> 02:05:17,280 And here. 2704 02:05:17,280 --> 02:05:21,500 I'm going to ask the question, do this while n is less than 1. 2705 02:05:21,500 --> 02:05:25,250 But there's one fix I still need to do here because notice on the current line 2706 02:05:25,250 --> 02:05:28,280 8, I actually haven't given n a type. 2707 02:05:28,280 --> 02:05:29,990 I haven't declared n yet. 2708 02:05:29,990 --> 02:05:37,100 But it would not be correct to declare n here, inside of that do block. 2709 02:05:37,100 --> 02:05:39,060 But why might that be? 2710 02:05:39,060 --> 02:05:44,780 Why would it not be a good thing to declare n inside of these curly braces? 2711 02:05:44,780 --> 02:05:47,240 Yeah, so recall that this is an issue of scope. 2712 02:05:47,240 --> 02:05:49,820 Recall that the scope of a variable is generally 2713 02:05:49,820 --> 02:05:53,690 confined to the most recently opened curly braces in which that variable is 2714 02:05:53,690 --> 02:05:54,230 declared. 2715 02:05:54,230 --> 02:05:56,690 And so if I declare this variable on line 8, 2716 02:05:56,690 --> 02:05:58,845 I'm not going to be able to use it on line 10. 2717 02:05:58,845 --> 02:06:01,470 But there is a fix, even though it might look a little strange. 2718 02:06:01,470 --> 02:06:04,020 I'm going to go above my do block here. 2719 02:06:04,020 --> 02:06:06,290 And before I go into this loop, I'm actually 2720 02:06:06,290 --> 02:06:10,183 going to declare n to be an integer, but semicolon, end of thought. 2721 02:06:10,183 --> 02:06:12,350 I'm not going to bother giving it a value, because I 2722 02:06:12,350 --> 02:06:17,000 know logically I'm going to end up giving it a value anyway now on line 9. 2723 02:06:17,000 --> 02:06:19,400 And so what's different about this version of the code 2724 02:06:19,400 --> 02:06:24,200 is that the do while loop ensures that we prompt the user for input at least 2725 02:06:24,200 --> 02:06:24,740 once. 2726 02:06:24,740 --> 02:06:30,140 And then while that input is not what we expect, for instance less than 1, then 2727 02:06:30,140 --> 02:06:32,583 it's going to execute again, again, again. 2728 02:06:32,583 --> 02:06:34,250 And indeed, the semantics are just that. 2729 02:06:34,250 --> 02:06:38,460 Do the following while this Boolean expression is true. 2730 02:06:38,460 --> 02:06:44,180 So if I go ahead now and rerun make mario, compiles OK-- ./mario. 2731 02:06:44,180 --> 02:06:48,140 And now I'll go ahead and input something that's not correct, like 0. 2732 02:06:48,140 --> 02:06:49,340 But I'm prompted again. 2733 02:06:49,340 --> 02:06:52,250 I'll input something like negative 1, and I'm prompted again. 2734 02:06:52,250 --> 02:06:54,920 But if I go ahead and input, for instance, 10, 2735 02:06:54,920 --> 02:07:02,060 now, because that's a positive integer, I indeed get a 10-by-10 grid of bricks. 2736 02:07:02,060 --> 02:07:05,110 And there's one other thing we should introduce here, too, in C, too. 2737 02:07:05,110 --> 02:07:06,022 C supports comments. 2738 02:07:06,022 --> 02:07:07,730 And a couple of you have asked about this 2739 02:07:07,730 --> 02:07:09,740 if you come from other programming languages. 2740 02:07:09,740 --> 02:07:13,070 Suppose I want to remember what it is I just did with this program. 2741 02:07:13,070 --> 02:07:20,120 Let me go in between lines 5 and 6 here and do "// prompt user for positive 2742 02:07:20,120 --> 02:07:20,713 integer." 2743 02:07:20,713 --> 02:07:22,130 This is what's known as a comment. 2744 02:07:22,130 --> 02:07:25,378 And it's grayed out only in the sense that the compiler is not 2745 02:07:25,378 --> 02:07:26,420 going to care about this. 2746 02:07:26,420 --> 02:07:28,295 The computer is not going to care about this. 2747 02:07:28,295 --> 02:07:31,430 This is a note to self, like a sticky note in the context of Scratch. 2748 02:07:31,430 --> 02:07:35,000 And it starts with "//," which essentially tells the compiler ignore 2749 02:07:35,000 --> 02:07:37,490 this, this is for the human, not for the computer. 2750 02:07:37,490 --> 02:07:41,270 But this comment, so to speak, is a way of just reminding yourself, reminding 2751 02:07:41,270 --> 02:07:43,520 your colleague, reminding your TF what it 2752 02:07:43,520 --> 02:07:46,460 is a few lines of code are meant to do. 2753 02:07:46,460 --> 02:07:53,930 And now this comment might be print, and how about n-by-n grid of bricks? 2754 02:07:53,930 --> 02:07:57,890 And what's nice about comments is that theoretically you can get away with, 2755 02:07:57,890 --> 02:08:00,440 or someone else can get away with, just reading this comment 2756 02:08:00,440 --> 02:08:02,787 and then not even have to look at the rest of the code. 2757 02:08:02,787 --> 02:08:05,870 They can look at this comment and not have to look at the rest of the code 2758 02:08:05,870 --> 02:08:09,195 because you've described for them what it's meant to do. 2759 02:08:09,195 --> 02:08:09,695 Yeah? 2760 02:08:09,695 --> 02:08:13,020 STUDENT: I just had a question about the hashtag [INAUDIBLE] 2761 02:08:13,020 --> 02:08:14,790 DAVID MALAN: Sure. 2762 02:08:14,790 --> 02:08:16,440 STUDENT: That's for [INAUDIBLE] 2763 02:08:16,440 --> 02:08:19,080 DAVID MALAN: Correct, the hash sign in Python is a comment, 2764 02:08:19,080 --> 02:08:24,360 is not the same thing in C. In C, hash include means to include the library's 2765 02:08:24,360 --> 02:08:26,320 header files in that way. 2766 02:08:26,320 --> 02:08:28,290 Other questions on these here tricks? 2767 02:08:28,290 --> 02:08:31,060 2768 02:08:31,060 --> 02:08:31,600 No? 2769 02:08:31,600 --> 02:08:37,810 All right, so as promised, what is maybe C not actually good at? 2770 02:08:37,810 --> 02:08:40,840 Well, let me propose that we consider what's 2771 02:08:40,840 --> 02:08:42,280 actually inside of your computer. 2772 02:08:42,280 --> 02:08:45,340 At the end of the day, whether it's a Mac, PC, iPhone, Android, phone, 2773 02:08:45,340 --> 02:08:48,257 or some other computer device, there's something that looks like this. 2774 02:08:48,257 --> 02:08:51,423 And this is memory, otherwise known as RAM, or random access memory, 2775 02:08:51,423 --> 02:08:53,090 for reasons we'll get to in a few weeks. 2776 02:08:53,090 --> 02:08:54,770 But this is where data is stored. 2777 02:08:54,770 --> 02:08:56,570 This is where "hello, world" is stored. 2778 02:08:56,570 --> 02:08:59,200 This is where 1 and 2 and all of those numbers are stored. 2779 02:08:59,200 --> 02:09:03,590 Any data in your program is stored ultimately in the computer's memory. 2780 02:09:03,590 --> 02:09:06,460 And the most important takeaway for today is that all of us 2781 02:09:06,460 --> 02:09:10,090 only have a finite amount of memory in our devices. 2782 02:09:10,090 --> 02:09:12,970 You might have a high-end device which has a lot of memory, 2783 02:09:12,970 --> 02:09:15,970 but it's still finite, which means you can only 2784 02:09:15,970 --> 02:09:17,650 count so high with that device. 2785 02:09:17,650 --> 02:09:20,150 You can only store so many files with that device. 2786 02:09:20,150 --> 02:09:24,730 There are fundamental physical limitations even though mathematically, 2787 02:09:24,730 --> 02:09:27,617 theoretically, we should be able to count toward infinity. 2788 02:09:27,617 --> 02:09:29,200 So what are the implications for this? 2789 02:09:29,200 --> 02:09:30,530 Well, consider this. 2790 02:09:30,530 --> 02:09:34,677 In the world of numbers, as per week 0, if you're only using three digits-- 2791 02:09:34,677 --> 02:09:37,760 and I've grayed out the fourth one just to make the point-- if you're only 2792 02:09:37,760 --> 02:09:43,750 using three digits, we can count from 0 to 1 in decimal, to 2, to3, to 4, 2793 02:09:43,750 --> 02:09:47,030 to 5, to 6, to 7. 2794 02:09:47,030 --> 02:09:50,180 And as soon as you count to 8, you technically, per last week, 2795 02:09:50,180 --> 02:09:51,600 need a fourth bit. 2796 02:09:51,600 --> 02:09:55,970 But if you don't have it, the number 7 might seem 2797 02:09:55,970 --> 02:09:58,770 to be followed by what number instead? 2798 02:09:58,770 --> 02:09:59,450 STUDENT: 0. 2799 02:09:59,450 --> 02:10:00,380 DAVID MALAN: 0. 2800 02:10:00,380 --> 02:10:03,260 The number overflows, so to speak, right? 2801 02:10:03,260 --> 02:10:04,155 You carry the 1. 2802 02:10:04,155 --> 02:10:07,280 But if there's no place to put the 1, because there's no fourth light bulb, 2803 02:10:07,280 --> 02:10:09,740 if there's no fourth transistor, if there's no fourth bit, 2804 02:10:09,740 --> 02:10:14,180 the lower bits, the zeros, are going to be mistaken for the number you 2805 02:10:14,180 --> 02:10:15,080 and I know is 0. 2806 02:10:15,080 --> 02:10:18,410 So integer overflow is a thing in computers 2807 02:10:18,410 --> 02:10:21,560 whereby if you don't have enough memory, if you count high enough, 2808 02:10:21,560 --> 02:10:23,690 the number will wrap around back to 0. 2809 02:10:23,690 --> 02:10:26,210 Or sometimes it will wrap around to a negative number, 2810 02:10:26,210 --> 02:10:30,350 depending on whether the code supports negative and positive numbers and 0 2811 02:10:30,350 --> 02:10:30,950 alike. 2812 02:10:30,950 --> 02:10:33,080 So that has some very real world implications 2813 02:10:33,080 --> 02:10:36,590 in integer overflow that's sort of a fundamental limitation of how 2814 02:10:36,590 --> 02:10:37,850 numbers are typically stored. 2815 02:10:37,850 --> 02:10:39,980 Now, thankfully, we typically don't store things 2816 02:10:39,980 --> 02:10:42,590 based on number of digits but number of bits. 2817 02:10:42,590 --> 02:10:44,270 And a bit is just a 0 or 1. 2818 02:10:44,270 --> 02:10:46,820 And recall from last week that a common unit of measure 2819 02:10:46,820 --> 02:10:51,080 is minimally eight bits, or a byte, but even more commonly is 32. 2820 02:10:51,080 --> 02:10:54,263 So for instance, here are 32 bits, all zeros. 2821 02:10:54,263 --> 02:10:56,180 And if you do out the math, this is the number 2822 02:10:56,180 --> 02:10:58,760 you and I know in decimal is of course 0. 2823 02:10:58,760 --> 02:11:03,410 But if I change all 32 zeros to ones, this is a really big number now. 2824 02:11:03,410 --> 02:11:05,810 If we're only using positive numbers, not negatives, 2825 02:11:05,810 --> 02:11:10,680 what number roughly is this, 32 ones? 2826 02:11:10,680 --> 02:11:15,520 It's roughly 4 billion in total-- roughly 4 billion in total. 2827 02:11:15,520 --> 02:11:16,020 Why? 2828 02:11:16,020 --> 02:11:19,770 Well, if you've got 32 bits, each can be two possible values, 0 or 1, that's 2829 02:11:19,770 --> 02:11:22,260 2 to the 32nd power, which is roughly-- 2830 02:11:22,260 --> 02:11:26,490 I'll stipulate-- roughly 4 billion total. 2831 02:11:26,490 --> 02:11:29,883 The problem is, what if you want to count to 4,000,000,001? 2832 02:11:29,883 --> 02:11:31,050 That's a bit of a white lie. 2833 02:11:31,050 --> 02:11:32,290 It's not precisely that. 2834 02:11:32,290 --> 02:11:34,457 But what if you want to count just higher than that? 2835 02:11:34,457 --> 02:11:36,780 You'd need a 33rd bit because all of the others 2836 02:11:36,780 --> 02:11:40,860 are going to go to 0 at that point, and you might count from 1 to 2 2837 02:11:40,860 --> 02:11:45,690 to 3 to 4 billion back to 0, or worse if you're dealing with negative numbers, 2838 02:11:45,690 --> 02:11:46,300 too. 2839 02:11:46,300 --> 02:11:51,540 So the fact that there are finitely many bits used in computers is a problem. 2840 02:11:51,540 --> 02:11:55,050 And negative numbers do add a complexity because this is specifically 2841 02:11:55,050 --> 02:11:56,460 the 4 billion in question-- 2842 02:11:56,460 --> 02:12:00,300 4,294,968,295. 2843 02:12:00,300 --> 02:12:03,480 That is as high as you can count with 32 bits 2844 02:12:03,480 --> 02:12:05,033 if you don't bother with negatives. 2845 02:12:05,033 --> 02:12:07,200 But if you want negative numbers, you've got to half 2846 02:12:07,200 --> 02:12:10,350 that because you've got to save half of them for negative, half of them 2847 02:12:10,350 --> 02:12:11,770 for positive, give or take. 2848 02:12:11,770 --> 02:12:14,640 And so if you're supporting negative numbers, as you probably 2849 02:12:14,640 --> 02:12:17,850 should for a calculator, for Microsoft Excel, Google Spreadsheets, 2850 02:12:17,850 --> 02:12:21,060 you can only count as high up as 2 billion roughly, 2851 02:12:21,060 --> 02:12:24,640 or negative 2 billion roughly instead. 2852 02:12:24,640 --> 02:12:29,340 So it turns out that when you are using data types in C, 2853 02:12:29,340 --> 02:12:32,760 you have some control over how many bits are actually used. 2854 02:12:32,760 --> 02:12:34,980 And this list is longer than we've covered today, 2855 02:12:34,980 --> 02:12:37,800 but we did talk about integers for a while. 2856 02:12:37,800 --> 02:12:40,680 Those are, by convention nowadays, 32 bits. 2857 02:12:40,680 --> 02:12:44,760 If that's not enough, you can upgrade your variables to longs, which 2858 02:12:44,760 --> 02:12:49,290 tend to be 64 bits instead, which isn't just twice as big as an integer, 2859 02:12:49,290 --> 02:12:52,500 it's actually 64 bits, which is exponentially more. 2860 02:12:52,500 --> 02:12:54,510 It's an unpronounceable number, at least for me. 2861 02:12:54,510 --> 02:12:58,240 That's a crazy big number, but it's available to you. 2862 02:12:58,240 --> 02:13:02,700 Moreover, we can see this if we actually are a little reckless with how 2863 02:13:02,700 --> 02:13:03,428 we're using code. 2864 02:13:03,428 --> 02:13:05,220 And just so you know too, though, there are 2865 02:13:05,220 --> 02:13:07,140 functions even in CS50's library that let 2866 02:13:07,140 --> 02:13:10,930 you use these larger values, get long of course, will get you a long. 2867 02:13:10,930 --> 02:13:16,240 And this one's a little non-obvious, but "%li" is the format code for printf, 2868 02:13:16,240 --> 02:13:20,720 just so you know, for printing a long integer and not just an integer. 2869 02:13:20,720 --> 02:13:22,330 So it's two characters instead of one. 2870 02:13:22,330 --> 02:13:26,860 Suppose, though, we actually want to use code involving some large numbers. 2871 02:13:26,860 --> 02:13:29,208 It turns out that certain bad things can happen. 2872 02:13:29,208 --> 02:13:30,500 So let me go ahead and do this. 2873 02:13:30,500 --> 02:13:32,200 I'm going to go back over to VS Code here, 2874 02:13:32,200 --> 02:13:35,408 and I'm going to modify my calculator to do something that, at glance, should 2875 02:13:35,408 --> 02:13:36,880 be perfectly reasonable. 2876 02:13:36,880 --> 02:13:40,030 Let me go ahead and open up calculator.c, as before. 2877 02:13:40,030 --> 02:13:42,220 And where we left off, we had this add function. 2878 02:13:42,220 --> 02:13:42,970 And you know what? 2879 02:13:42,970 --> 02:13:45,502 I'm going to simplify it back to its very original version. 2880 02:13:45,502 --> 02:13:47,710 I'm going to go ahead and get rid of the add function 2881 02:13:47,710 --> 02:13:50,845 and just distill it to its essence, which is not to add any more. 2882 02:13:50,845 --> 02:13:51,970 But let's just do division. 2883 02:13:51,970 --> 02:13:55,120 I want to print out this time maybe x divided by y. 2884 02:13:55,120 --> 02:13:59,770 So here we go. x divided by y is a nice simple program in my calculator. 2885 02:13:59,770 --> 02:14:03,250 Let me do make calculator again, ./calculator. 2886 02:14:03,250 --> 02:14:07,170 And let's divide something like 1 divided by 3, which should-- 2887 02:14:07,170 --> 02:14:08,860 hm, OK, weird. 2888 02:14:08,860 --> 02:14:13,360 It gave me 0 instead of probably 0.3333333, 2889 02:14:13,360 --> 02:14:16,540 as you might have expected for 1/3. 2890 02:14:16,540 --> 02:14:19,990 So what might the takeaway there be? 2891 02:14:19,990 --> 02:14:22,090 Why am I seeing zero perhaps? 2892 02:14:22,090 --> 02:14:22,600 Yeah? 2893 02:14:22,600 --> 02:14:27,060 STUDENT: If 0's the integer [INAUDIBLE],, then if you want decimals [INAUDIBLE].. 2894 02:14:27,060 --> 02:14:29,178 DAVID MALAN: Yeah, so 0 is an integer. 2895 02:14:29,178 --> 02:14:31,470 And indeed, that's what I'm telling the thing to print. 2896 02:14:31,470 --> 02:14:34,980 And in fact, if we go over to my little cheat sheet here of format codes, 2897 02:14:34,980 --> 02:14:36,525 I'm currently using %i. 2898 02:14:36,525 --> 02:14:41,460 I should actually, when I do division of numbers that might have floating point 2899 02:14:41,460 --> 02:14:43,560 values, a decimal point that floats left to right, 2900 02:14:43,560 --> 02:14:47,698 otherwise known as a real number, I want to use %f for float instead. 2901 02:14:47,698 --> 02:14:49,740 So I'm actually going to go back to my code here. 2902 02:14:49,740 --> 02:14:52,920 And let's try this-- %f instead of %i. 2903 02:14:52,920 --> 02:14:55,560 And let me go ahead and "make calculator." 2904 02:14:55,560 --> 02:14:56,370 Huh, all right. 2905 02:14:56,370 --> 02:14:57,930 Well, this didn't work then. 2906 02:14:57,930 --> 02:15:01,830 "Format specifies type 'double,' but the argument has type 'int.' 2907 02:15:01,830 --> 02:15:05,260 All right, so that, too, is not quite working. 2908 02:15:05,260 --> 02:15:09,150 So I think I actually need to make a change here further. 2909 02:15:09,150 --> 02:15:10,870 Let me actually go ahead and do this. 2910 02:15:10,870 --> 02:15:13,230 It turns out that besides integers, there 2911 02:15:13,230 --> 02:15:15,750 are these things called floats, and also doubles. 2912 02:15:15,750 --> 02:15:19,082 A float uses 32 bits, and a double uses 64 bits. 2913 02:15:19,082 --> 02:15:20,790 And that doesn't necessarily mean you can 2914 02:15:20,790 --> 02:15:22,860 count higher as much as it means you can have 2915 02:15:22,860 --> 02:15:24,820 more numbers after the decimal point. 2916 02:15:24,820 --> 02:15:27,610 So if you want a more precise value, you throw memory at it 2917 02:15:27,610 --> 02:15:30,363 by using a double and 64 bits instead of a float. 2918 02:15:30,363 --> 02:15:32,780 But we'll keep it simple, and let me go ahead and do this. 2919 02:15:32,780 --> 02:15:37,250 Let me just do the math using the type of variable that I should be here. 2920 02:15:37,250 --> 02:15:43,240 Let me do not int, but float z equals x divided by y. 2921 02:15:43,240 --> 02:15:45,730 And now let me go ahead and print out the value of z. 2922 02:15:45,730 --> 02:15:47,605 Strictly speaking, I don't need the variable. 2923 02:15:47,605 --> 02:15:50,830 But I'm trying to be pedantic and actually use a float explicitly 2924 02:15:50,830 --> 02:15:52,900 this time so we see a real number. 2925 02:15:52,900 --> 02:15:57,760 All right, let me go ahead and do make calculator, ./calculator. 2926 02:15:57,760 --> 02:16:00,610 1 divided by 3 equals-- 2927 02:16:00,610 --> 02:16:04,420 damn, now it's just showing me more zeros, which clearly isn't the case. 2928 02:16:04,420 --> 02:16:08,750 Well, this is because of an issue that we'll generally call truncation. 2929 02:16:08,750 --> 02:16:12,320 So truncation is just a term of art that means if you take an integer 2930 02:16:12,320 --> 02:16:15,760 and you divide it by an integer, even if you get a fractional value, 2931 02:16:15,760 --> 02:16:18,880 the fraction just gets thrown away because you're only 2932 02:16:18,880 --> 02:16:21,062 doing integer-based math. 2933 02:16:21,062 --> 02:16:23,020 So if there's anything after the decimal point, 2934 02:16:23,020 --> 02:16:25,280 it just gets truncated, literally discarded. 2935 02:16:25,280 --> 02:16:27,460 So what should 1 divided by 3 be? 2936 02:16:27,460 --> 02:16:31,810 Obviously, 0.33333333-- ad nauseum. 2937 02:16:31,810 --> 02:16:34,670 Fortunately, you throw away everything after the decimal point, 2938 02:16:34,670 --> 02:16:37,000 which leaves you still with just 0. 2939 02:16:37,000 --> 02:16:40,510 And even though I'm seeing more zeros, that's because we threw away all 2940 02:16:40,510 --> 02:16:41,049 of the 3's. 2941 02:16:41,049 --> 02:16:44,200 That is just what happens when you use integers and do 2942 02:16:44,200 --> 02:16:46,090 any kind of division like that. 2943 02:16:46,090 --> 02:16:47,959 But there is a solution. 2944 02:16:47,959 --> 02:16:53,320 We can actually convert, or cast, integers to floating point values. 2945 02:16:53,320 --> 02:16:56,230 So we can tell C, I know this is an integer now. 2946 02:16:56,230 --> 02:16:59,290 But go ahead and treat it as though it has a decimal point, even 2947 02:16:59,290 --> 02:17:01,690 if it's .0 At the end of the number. 2948 02:17:01,690 --> 02:17:06,100 So I can go into this, and I can use parentheses and literally write 2949 02:17:06,100 --> 02:17:07,750 "float" in parentheses. 2950 02:17:07,750 --> 02:17:12,700 And over here for y, I can literally use parentheses and convert y to a float. 2951 02:17:12,700 --> 02:17:15,129 The term of art here is type casting. 2952 02:17:15,129 --> 02:17:19,330 You're converting one type to another effectively, or technically treating 2953 02:17:19,330 --> 02:17:23,080 one type as though it's another even if it doesn't necessarily 2954 02:17:23,080 --> 02:17:24,430 have a mathematical impact. 2955 02:17:24,430 --> 02:17:28,959 But what it means now is that z will be defined 2956 02:17:28,959 --> 02:17:31,219 by dividing one float by another. 2957 02:17:31,219 --> 02:17:33,700 So truncation will not now happen. 2958 02:17:33,700 --> 02:17:36,580 So let me do make calculator, ./calculator. 2959 02:17:36,580 --> 02:17:39,100 And now 1 divided by 3, there it is. 2960 02:17:39,100 --> 02:17:41,480 Now the math is actually correct. 2961 02:17:41,480 --> 02:17:45,770 But my God, we had to jump through hoops just to get this to work. 2962 02:17:45,770 --> 02:17:48,610 So to be clear, the two issues we-- well, the issue we encountered 2963 02:17:48,610 --> 02:17:49,480 was truncation. 2964 02:17:49,480 --> 02:17:52,389 If you divide an int by an int, you will get an int no matter 2965 02:17:52,389 --> 02:17:54,070 what it should be mathematically. 2966 02:17:54,070 --> 02:17:59,020 But if you instead type cast the values, the variables to a floating point 2967 02:17:59,020 --> 02:18:03,610 value, or a double for that matter, then a float divided by a float will give 2968 02:18:03,610 --> 02:18:06,520 you a float and preserve all of those 3's. 2969 02:18:06,520 --> 02:18:10,870 But here's another catch, or at least a limitation potentially with computers. 2970 02:18:10,870 --> 02:18:14,379 What if I go ahead here and do-- 2971 02:18:14,379 --> 02:18:15,559 let me do this. 2972 02:18:15,559 --> 02:18:18,820 Let me show you one trick here, even though the syntax is a bit weird. 2973 02:18:18,820 --> 02:18:25,750 Instead of printing out %f alone, let me print out % dot, 2974 02:18:25,750 --> 02:18:30,080 maybe 5f So this is weird syntax. 2975 02:18:30,080 --> 02:18:32,350 And it's only specific to printf. 2976 02:18:32,350 --> 02:18:36,770 "%.5f" means 'show me five decimal places specifically.' 2977 02:18:36,770 --> 02:18:40,480 So if I do make calculator, ./calculator, 1, 3, voila, 2978 02:18:40,480 --> 02:18:43,010 I get five decimal places. 2979 02:18:43,010 --> 02:18:44,469 If I want six, let's do this. 2980 02:18:44,469 --> 02:18:45,969 I'll change the code to 6. 2981 02:18:45,969 --> 02:18:52,337 Make calculator, ./calculator, 1, 3, and now I get six 3's instead. 2982 02:18:52,337 --> 02:18:54,879 All right, well, wouldn't it be nice to be even more precise? 2983 02:18:54,879 --> 02:18:59,209 Let's give me 20 significant digits after the decimal point. 2984 02:18:59,209 --> 02:19:04,420 So make calculator, ./calculator, 1 divided by 3, and-- woo. 2985 02:19:04,420 --> 02:19:09,481 So your middle school teacher seems to have lied to you at this point. 2986 02:19:09,481 --> 02:19:14,620 1 divided by 3 is apparently not 0.33333 with a line over it, 2987 02:19:14,620 --> 02:19:17,350 or just infinite number of 3's. 2988 02:19:17,350 --> 02:19:19,690 OK, that's not quite the right conclusion, though. 2989 02:19:19,690 --> 02:19:20,230 Oops. 2990 02:19:20,230 --> 02:19:24,820 Why might I be seeing these weird numbers instead 2991 02:19:24,820 --> 02:19:28,200 of just lots of 3's, intuitively? 2992 02:19:28,200 --> 02:19:31,340 2993 02:19:31,340 --> 02:19:32,999 Why this rounding error? 2994 02:19:32,999 --> 02:19:33,499 Yeah? 2995 02:19:33,499 --> 02:19:36,307 STUDENT: The computer just has a [? limited ?] [? memory. ?] So 2996 02:19:36,307 --> 02:19:37,665 there's [INAUDIBLE] 2997 02:19:37,665 --> 02:19:38,540 DAVID MALAN: Exactly. 2998 02:19:38,540 --> 02:19:41,270 The computer only has limited memory, finite memory. 2999 02:19:41,270 --> 02:19:44,840 So it just can't represent every possible number in the universe 3000 02:19:44,840 --> 02:19:48,240 because we know from grade school there are infinitely many of those numbers. 3001 02:19:48,240 --> 02:19:52,520 So what you're essentially seeing is the closest it can actually get. 3002 02:19:52,520 --> 02:19:56,120 It's rounding to the nearest floating point value, if you will. 3003 02:19:56,120 --> 02:19:58,850 And it also relates to how the numbers themselves are represented 3004 02:19:58,850 --> 02:20:00,145 in memory underneath the hood. 3005 02:20:00,145 --> 02:20:01,520 I can do a little better, though. 3006 02:20:01,520 --> 02:20:02,330 Let me zoom out. 3007 02:20:02,330 --> 02:20:06,530 And let me upgrade, so to speak, from 32 bits to 64 bits and use 3008 02:20:06,530 --> 02:20:07,400 doubles instead. 3009 02:20:07,400 --> 02:20:09,410 I can still use %f. 3010 02:20:09,410 --> 02:20:11,030 You don't use %d for double. 3011 02:20:11,030 --> 02:20:14,750 Let me do make calculator again, ./calculator, 1, 3. 3012 02:20:14,750 --> 02:20:17,490 I get more 3's but still some rounding. 3013 02:20:17,490 --> 02:20:21,842 It's more precise, but it's not 100% accurate, 3014 02:20:21,842 --> 02:20:24,050 because that's just not going to be possible in terms 3015 02:20:24,050 --> 02:20:25,320 of the computer's memory. 3016 02:20:25,320 --> 02:20:29,450 So this is a whole other issue known as floating point imprecision, which 3017 02:20:29,450 --> 02:20:31,910 is another type of limitation. 3018 02:20:31,910 --> 02:20:34,640 We saw integer overflow, if integers can only 3019 02:20:34,640 --> 02:20:37,860 count so high before you run out of bits and things wrap around. 3020 02:20:37,860 --> 02:20:40,350 Floating point imprecision means that you can't possibly 3021 02:20:40,350 --> 02:20:43,470 represent the infinite number of real numbers that exist in the universe 3022 02:20:43,470 --> 02:20:46,830 if you only have a finite amount of memory. 3023 02:20:46,830 --> 02:20:49,710 You would need an infinite number of bits, it would seem. 3024 02:20:49,710 --> 02:20:51,902 So these are two issues that actually fundamentally 3025 02:20:51,902 --> 02:20:53,610 can influence the correctness not only of 3026 02:20:53,610 --> 02:20:55,260 your code but code in the real world. 3027 02:20:55,260 --> 02:20:56,820 And case in point, back in my day-- 3028 02:20:56,820 --> 02:20:59,310 I graduated in 1999-- and a lot of the world 3029 02:20:59,310 --> 02:21:01,350 thought the world was going to end around then 3030 02:21:01,350 --> 02:21:06,180 because around the time the years rolled over from 1999 to 2000, 3031 02:21:06,180 --> 02:21:08,850 there was a lot of old software still running in the world. 3032 02:21:08,850 --> 02:21:12,450 And in fact, that old software, reasonably so, 3033 02:21:12,450 --> 02:21:14,740 only used two digits to represent years. 3034 02:21:14,740 --> 02:21:15,240 Why? 3035 02:21:15,240 --> 02:21:17,200 Memory was very expensive early on. 3036 02:21:17,200 --> 02:21:20,910 And if you could use half as much memory to store a year, that was a win. 3037 02:21:20,910 --> 02:21:21,870 That saved you money. 3038 02:21:21,870 --> 02:21:23,310 That saved you memory. 3039 02:21:23,310 --> 02:21:25,350 The problem though, of course, is that a lot 3040 02:21:25,350 --> 02:21:29,970 of old software from the '70s and prior was still running in 1999. 3041 02:21:29,970 --> 02:21:32,970 And unless companies or individuals updated that software, 3042 02:21:32,970 --> 02:21:39,112 1999 might be mistaken for the year 1900 instead of 2000, 3043 02:21:39,112 --> 02:21:41,320 because all of the code just assumed that, of course, 3044 02:21:41,320 --> 02:21:42,850 we're talking about the 1900s. 3045 02:21:42,850 --> 02:21:45,120 This code is not going to be running 50 years later, 3046 02:21:45,120 --> 02:21:46,762 but it was still in that case. 3047 02:21:46,762 --> 02:21:48,720 So people had to scramble, and they essentially 3048 02:21:48,720 --> 02:21:53,310 had to solve this by using more digits, so upgrading from two to four. 3049 02:21:53,310 --> 02:21:55,590 Nowadays, and really since the '70s too, we've 3050 02:21:55,590 --> 02:21:59,190 used 32-bit integers to keep track of time, 3051 02:21:59,190 --> 02:22:03,120 specifically keeping track of the number of seconds 3052 02:22:03,120 --> 02:22:08,400 using an integer from January 1, 1970, the so-called epoch whereby 3053 02:22:08,400 --> 02:22:11,800 that's just an arbitrary date early on where we just started counting time. 3054 02:22:11,800 --> 02:22:14,430 So all of the clocks in your Macs, PCs, and phones pretty much 3055 02:22:14,430 --> 02:22:17,280 just have a single integer that gets updated every second, 3056 02:22:17,280 --> 02:22:20,080 but it's just keeping track not of absolute time per se, 3057 02:22:20,080 --> 02:22:23,460 but how many seconds have passed since January 1, 1970, 3058 02:22:23,460 --> 02:22:25,710 just because that's the date humans chose. 3059 02:22:25,710 --> 02:22:28,650 The problem is you can only count as high as 4 billion, 3060 02:22:28,650 --> 02:22:31,950 give or take, with 32 bits and actually 2 billion, give or take, 3061 02:22:31,950 --> 02:22:34,180 if you support negative numbers, as well. 3062 02:22:34,180 --> 02:22:37,500 And the problem with that is that we're about to trip over the same issue 3063 02:22:37,500 --> 02:22:39,450 again in not too long from now. 3064 02:22:39,450 --> 02:22:45,760 This is the 2038 problem because in the year 2038, on that date, mark my words, 3065 02:22:45,760 --> 02:22:46,830 things could break again. 3066 02:22:46,830 --> 02:22:47,430 Why? 3067 02:22:47,430 --> 02:22:50,820 Because that 32-bit value is going to accidentally wrap 3068 02:22:50,820 --> 02:22:53,873 around back to a 0 or a negative value. 3069 02:22:53,873 --> 02:22:56,290 So we're going to go through the whole darn process again. 3070 02:22:56,290 --> 02:22:59,190 Now, thankfully the solution, as you might expect, is kind of just 3071 02:22:59,190 --> 02:23:01,470 to kick the can even further down the road 3072 02:23:01,470 --> 02:23:07,050 and use 64 bits, which I think will get us another 290 million years of runway. 3073 02:23:07,050 --> 02:23:08,290 It's more than twice. 3074 02:23:08,290 --> 02:23:10,527 So it's not our problem anymore at that point. 3075 02:23:10,527 --> 02:23:12,610 But that's fundamentally going to be the solution. 3076 02:23:12,610 --> 02:23:15,160 But it will still be finite. 3077 02:23:15,160 --> 02:23:18,240 So we're just deferring to our descendants 3078 02:23:18,240 --> 02:23:21,150 to actually deal with the issue some millions of years from now 3079 02:23:21,150 --> 02:23:22,930 if these things are still running. 3080 02:23:22,930 --> 02:23:26,010 So if that does happen, here's the specific date 3081 02:23:26,010 --> 02:23:28,290 that, in 2038, all of a sudden our clocks will still 3082 02:23:28,290 --> 02:23:32,400 think because a negative number will get subtracted to the current epoch time. 3083 02:23:32,400 --> 02:23:35,140 So it will think we're back in 1901. 3084 02:23:35,140 --> 02:23:38,170 So this has had some fun and very real world implications. 3085 02:23:38,170 --> 02:23:41,250 So for instance, this is the game Pac-Man, which you might have played. 3086 02:23:41,250 --> 02:23:44,020 It kind of came out around my day, back in time. 3087 02:23:44,020 --> 02:23:48,950 And if you get to the 256th level, this unfortunately 3088 02:23:48,950 --> 02:23:50,700 is what happens because they didn't really 3089 02:23:50,700 --> 02:23:54,280 expect that players would spend all this much time playing Pac-Man apparently. 3090 02:23:54,280 --> 02:23:56,370 And they didn't really have a condition saying, 3091 02:23:56,370 --> 02:23:59,832 you win if you get to the 255th or 266th level. 3092 02:23:59,832 --> 02:24:02,790 And so what happens here essentially is that the whole screen gets very 3093 02:24:02,790 --> 02:24:06,120 garbled because there's an integer in the original Pac-Man that 3094 02:24:06,120 --> 02:24:11,100 counts to 256, but that's too big, so it wraps back around to 0. 3095 02:24:11,100 --> 02:24:14,700 And it doesn't know when to stop printing fruits on the screen, 3096 02:24:14,700 --> 02:24:16,260 as in this case, to collect. 3097 02:24:16,260 --> 02:24:19,470 Another example of this is actually from the original Donkey Kong 3098 02:24:19,470 --> 02:24:24,420 game, which looks something like this in my day, too, whereby in Donkey Kong, 3099 02:24:24,420 --> 02:24:26,880 there was this mathematical formula, whereby 3100 02:24:26,880 --> 02:24:31,740 the number of seconds you have to solve the game was a function of 10 times 3101 02:24:31,740 --> 02:24:34,500 your current level number plus the number 4. 3102 02:24:34,500 --> 02:24:36,330 That dictated how many seconds you get. 3103 02:24:36,330 --> 02:24:39,480 So of course, the higher the level, you get more and more time 3104 02:24:39,480 --> 02:24:41,130 as the level climbs. 3105 02:24:41,130 --> 02:24:47,580 Unfortunately, once you hit level 22, the math ends up being 10 times 3106 02:24:47,580 --> 02:24:51,690 22 plus 4, which gives you the number 260. 3107 02:24:51,690 --> 02:24:55,290 And they, too, were using 8-bit values, a single byte 3108 02:24:55,290 --> 02:25:00,520 to represent numbers, which means 260 is bigger than 256. 3109 02:25:00,520 --> 02:25:02,520 And the way that math worked out was, well, 3110 02:25:02,520 --> 02:25:08,250 260 minus 256, if it wraps back around, gave people four seconds to solve level 3111 02:25:08,250 --> 02:25:10,440 22, which is just impossible. 3112 02:25:10,440 --> 02:25:12,480 Like, Mario can't even get up a couple of levels 3113 02:25:12,480 --> 02:25:15,040 or so from where he actually was. 3114 02:25:15,040 --> 02:25:17,400 So that, too, was sort of a well-known bug, 3115 02:25:17,400 --> 02:25:20,680 as well, since that works out to be there. 3116 02:25:20,680 --> 02:25:25,260 Lastly, and this one is all the more real, in 2015, 3117 02:25:25,260 --> 02:25:30,150 Boeing 787 was documented as having not a hardware bug but a software bug 3118 02:25:30,150 --> 02:25:31,560 in the following sense. 3119 02:25:31,560 --> 02:25:37,060 "A model 787 airplane that has been powered continuously for 248 days 3120 02:25:37,060 --> 02:25:42,430 can lose all of its power due to the control unit simultaneously going 3121 02:25:42,430 --> 02:25:43,690 into failsafe mode. 3122 02:25:43,690 --> 02:25:48,100 This condition was caused by a software counter that will overflow 3123 02:25:48,100 --> 02:25:51,700 after 248 days of continuous power. 3124 02:25:51,700 --> 02:25:55,720 Boeing at the time was in the process of developing a CPU software upgrade that 3125 02:25:55,720 --> 02:25:57,250 will remedy the unsafe condition." 3126 02:25:57,250 --> 02:25:58,310 And people did the math. 3127 02:25:58,310 --> 02:26:02,440 It turns out that Boeing was probably using an integer that was 32 bits. 3128 02:26:02,440 --> 02:26:06,650 And they were keeping track of time not in seconds but hundredths of seconds, 3129 02:26:06,650 --> 02:26:12,830 because if you do out the math, after a 32-bit value has reached 4 billion-- 3130 02:26:12,830 --> 02:26:18,650 or 2 billion one hundredths of a second, the number wraps around back to 0, 3131 02:26:18,650 --> 02:26:19,840 or negative 2 billion. 3132 02:26:19,840 --> 02:26:23,480 And the implications was literally the plane's power would stop. 3133 02:26:23,480 --> 02:26:26,770 And if you can believe it, if you grew up with Windows, macOS, or whatnot, 3134 02:26:26,770 --> 02:26:29,080 anyone want to conjecture what the solution was 3135 02:26:29,080 --> 02:26:33,550 until Boeing updated their software? 3136 02:26:33,550 --> 02:26:35,295 STUDENT: Turn it off, turn it back on. 3137 02:26:35,295 --> 02:26:37,128 DAVID MALAN: Turn the plane off, and turn it 3138 02:26:37,128 --> 02:26:41,280 back on because that has the effect of resetting its memory and therefore 3139 02:26:41,280 --> 02:26:43,200 all of its variables back to 0. 3140 02:26:43,200 --> 02:26:47,910 So this is ultimately to say as you dive into problem set 1, your first in C, 3141 02:26:47,910 --> 02:26:51,360 you, too, will make quite a few mistakes when it comes to correctness. 3142 02:26:51,360 --> 02:26:54,840 You, too, will encounter opportunities for better design and better style. 3143 02:26:54,840 --> 02:26:57,272 In the real world, there are very much these issues. 3144 02:26:57,272 --> 02:26:59,730 So even if you struggle, know that for better or for worse, 3145 02:26:59,730 --> 02:27:00,900 you're in very good company. 3146 02:27:00,900 --> 02:27:03,567 But some three months from now, you will be in much better shape 3147 02:27:03,567 --> 02:27:06,210 because this was week 1, and this is CS50. 3148 02:27:06,210 --> 02:27:07,710 [APPLAUSE] 3149 02:27:07,710 --> 02:27:11,310 3150 02:27:11,310 --> 02:27:14,360 [INTRIGUING MUSIC] 3151 02:27:14,360 --> 02:27:41,000