1 00:00:00,000 --> 00:00:02,988 [REEL-TO-REEL PLAYER STARTING] 2 00:00:02,988 --> 00:00:05,976 [MUSIC PLAYING] 3 00:00:05,976 --> 00:01:13,350 4 00:01:13,350 --> 00:01:16,090 DAVID J. MALAN: All right, this is CS50. 5 00:01:16,090 --> 00:01:19,090 And this is week 1, wherein we continue programming, 6 00:01:19,090 --> 00:01:22,420 but we do it in a different language because recall last time, we 7 00:01:22,420 --> 00:01:25,060 focused on this graphical language called Scratch. 8 00:01:25,060 --> 00:01:28,360 But we use Scratch, not only because it's sort of fun and accessible, 9 00:01:28,360 --> 00:01:31,750 but because it allows us to explore a lot of these concepts here, 10 00:01:31,750 --> 00:01:35,810 namely functions, and conditionals, Boolean expressions, loops, variables, 11 00:01:35,810 --> 00:01:36,410 and more. 12 00:01:36,410 --> 00:01:41,050 And so, indeed, even if today's syntax, as we transition to this new language 13 00:01:41,050 --> 00:01:44,980 called C, feels a little bit cryptic, maybe a little intimidating at first, 14 00:01:44,980 --> 00:01:48,040 and you don't quite see all of the meaning of the symbols 15 00:01:48,040 --> 00:01:51,310 beyond the syntax itself, realize that the ideas are ultimately 16 00:01:51,310 --> 00:01:52,670 going to be the same. 17 00:01:52,670 --> 00:01:55,870 In fact, as we transition from what was last week-- 18 00:01:55,870 --> 00:02:00,017 a Hello World program that looked a little something like this-- this week, 19 00:02:00,017 --> 00:02:02,350 of course, it's going to now look a little more cryptic. 20 00:02:02,350 --> 00:02:04,350 It's going to look a little something like this. 21 00:02:04,350 --> 00:02:06,370 And now even if you can't quite distinguish 22 00:02:06,370 --> 00:02:08,479 what all of the various symbols mean in this code, 23 00:02:08,479 --> 00:02:10,120 it turns out that at the end of the day, it's 24 00:02:10,120 --> 00:02:11,578 indeed going to do what you expect. 25 00:02:11,578 --> 00:02:14,170 It's just going to say, hello, world on the screen, 26 00:02:14,170 --> 00:02:15,370 just like we did in Scratch. 27 00:02:15,370 --> 00:02:19,610 So let's start to apply some terminology to these tokens first. 28 00:02:19,610 --> 00:02:22,332 So what we're about to see, what we're about to write henceforth, 29 00:02:22,332 --> 00:02:24,040 we're going to start calling source code. 30 00:02:24,040 --> 00:02:27,908 Code that you the human programmer write is just henceforth called source code. 31 00:02:27,908 --> 00:02:29,200 Doesn't matter if it's Scratch. 32 00:02:29,200 --> 00:02:32,370 Doesn't matter if it's C. Doesn't matter if it's Python before long. 33 00:02:32,370 --> 00:02:34,120 Source code is the general term for really 34 00:02:34,120 --> 00:02:37,330 what you and I as human programmers will ultimately write. 35 00:02:37,330 --> 00:02:42,190 Of course, computers don't understand source code, it turns out. 36 00:02:42,190 --> 00:02:46,200 Computers don't understand Scratch and Puzzle Pieces, per se, or C code 37 00:02:46,200 --> 00:02:47,200 like we're about to see. 38 00:02:47,200 --> 00:02:49,870 They only understand this, which we called what last week? 39 00:02:49,870 --> 00:02:50,650 AUDIENCE: Zeros and ones. 40 00:02:50,650 --> 00:02:51,525 DAVID J. MALAN: Yeah. 41 00:02:51,525 --> 00:02:53,080 So this is binary, zeros and ones. 42 00:02:53,080 --> 00:02:56,470 But really, it's just information represented in binary. 43 00:02:56,470 --> 00:03:00,370 And in fact, the technical term now for patterns of zeros and ones 44 00:03:00,370 --> 00:03:04,810 that a computer not only understands how to interpret as letters, or numbers, 45 00:03:04,810 --> 00:03:09,520 or colors, or images, or more, but knows how to execute as well henceforth 46 00:03:09,520 --> 00:03:12,880 is going to be called machine code to contrast it with source code. 47 00:03:12,880 --> 00:03:15,160 So whereas you and I, the humans, write source code, 48 00:03:15,160 --> 00:03:18,860 it's the computer that ultimately only understands machine code. 49 00:03:18,860 --> 00:03:21,940 And even though we won't get into the details of exactly what pattern 50 00:03:21,940 --> 00:03:27,010 of symbols means what, you'll see that in this kind of pattern of zeros 51 00:03:27,010 --> 00:03:28,600 and ones, there's going to be numbers. 52 00:03:28,600 --> 00:03:29,530 There's going to be letters. 53 00:03:29,530 --> 00:03:32,200 But there's also going to be instructions because, indeed, computers 54 00:03:32,200 --> 00:03:35,140 are really good at doing things-- addition, subtraction, moving things 55 00:03:35,140 --> 00:03:36,430 in and out of memory. 56 00:03:36,430 --> 00:03:40,720 And suffice it to say that the Macs, the PCs, the other computers of the world 57 00:03:40,720 --> 00:03:44,740 have just decided as a society what certain patterns of zeros and ones 58 00:03:44,740 --> 00:03:48,220 mean when it comes to operations as well-- so not just data, 59 00:03:48,220 --> 00:03:49,200 but instructions. 60 00:03:49,200 --> 00:03:50,950 But those patterns are not something we're 61 00:03:50,950 --> 00:03:52,575 going to focus on in a class like this. 62 00:03:52,575 --> 00:03:55,450 We're going to focus on the higher level software side of things, 63 00:03:55,450 --> 00:03:58,910 simply assuming that we need to somehow output machine code. 64 00:03:58,910 --> 00:04:02,050 So it turns out, then, that this problem we 65 00:04:02,050 --> 00:04:04,300 have to solve getting from source code to machine code 66 00:04:04,300 --> 00:04:07,120 actually fits into the same paradigm as last time. 67 00:04:07,120 --> 00:04:11,230 But the input in this case is going to be source code on the one hand. 68 00:04:11,230 --> 00:04:13,750 That's what you and I ideally will write so that we 69 00:04:13,750 --> 00:04:15,430 don't have to write zeros and ones. 70 00:04:15,430 --> 00:04:18,140 But we need to somehow output machine code 71 00:04:18,140 --> 00:04:19,990 because that's what your Macs, PCs, phones 72 00:04:19,990 --> 00:04:21,730 are actually going to understand. 73 00:04:21,730 --> 00:04:25,390 Well, it turns out there are special programs in life whose purpose is 74 00:04:25,390 --> 00:04:28,690 to do exactly this conversion-- convert the source code you 75 00:04:28,690 --> 00:04:32,320 and I write to the machine code that our phones and computers understand. 76 00:04:32,320 --> 00:04:36,050 And that type of program is going to be called a compiler. 77 00:04:36,050 --> 00:04:39,400 So indeed today, we'll introduce you to another piece of software. 78 00:04:39,400 --> 00:04:40,810 And these come in many forms. 79 00:04:40,810 --> 00:04:45,580 We'll use a popular one here that allows you to convert source code in C 80 00:04:45,580 --> 00:04:48,805 to machine code in zeros and ones. 81 00:04:48,805 --> 00:04:50,680 Now, you didn't have to do this with Scratch. 82 00:04:50,680 --> 00:04:53,513 In the world of Scratch, it was as simple as clicking the green flag 83 00:04:53,513 --> 00:04:57,280 because essentially MIT did all of the heavy lifting there figuring out 84 00:04:57,280 --> 00:05:00,760 how to convert these graphical puzzle pieces to the underlying machine code. 85 00:05:00,760 --> 00:05:04,420 But now starting today, as we begin to study programming and computer science 86 00:05:04,420 --> 00:05:06,550 proper, now that power moves to you. 87 00:05:06,550 --> 00:05:09,340 And it's up to you now to do that kind of conversion. 88 00:05:09,340 --> 00:05:12,160 But thankfully, the fact that these compilers exist 89 00:05:12,160 --> 00:05:14,320 means that you and I don't have to program 90 00:05:14,320 --> 00:05:17,500 in machine code like our ancestors once upon a time did, 91 00:05:17,500 --> 00:05:19,973 be it virtually or with physical punch cards, 92 00:05:19,973 --> 00:05:21,640 like pieces of paper with holes in them. 93 00:05:21,640 --> 00:05:25,810 You and I get to focus on our keyboard, as such. 94 00:05:25,810 --> 00:05:29,370 But it's not just going to be a matter today of writing code. 95 00:05:29,370 --> 00:05:31,120 It's going to be a matter ultimately today 96 00:05:31,120 --> 00:05:32,930 onward of writing good code as well. 97 00:05:32,930 --> 00:05:35,180 And this is the kind of thing that you don't just learn overnight. 98 00:05:35,180 --> 00:05:35,870 It takes time. 99 00:05:35,870 --> 00:05:36,620 It takes practice. 100 00:05:36,620 --> 00:05:38,650 Just like writing an essay in any subject 101 00:05:38,650 --> 00:05:41,050 might take time, and practice, and iteration over time. 102 00:05:41,050 --> 00:05:44,020 But in a programming class like CS50, we're 103 00:05:44,020 --> 00:05:48,820 going to aspire to evaluate the quality of code along these three axes, 104 00:05:48,820 --> 00:05:49,360 generally. 105 00:05:49,360 --> 00:05:51,040 Is it correct, first and foremost? 106 00:05:51,040 --> 00:05:52,810 Does the code do what it's supposed to do? 107 00:05:52,810 --> 00:05:54,460 After all, if it doesn't, well, what was the point 108 00:05:54,460 --> 00:05:55,835 of writing it in the first place? 109 00:05:55,835 --> 00:05:59,350 So it goes without saying that you want code you write to be correct. 110 00:05:59,350 --> 00:06:00,820 And it's obviously not always. 111 00:06:00,820 --> 00:06:03,340 Again, anytime your Mac, or PC, or phone has crashed, 112 00:06:03,340 --> 00:06:05,560 some human somewhere wrote buggy-- 113 00:06:05,560 --> 00:06:07,030 that is code with mistakes. 114 00:06:07,030 --> 00:06:10,060 But code correctness is going to be the first and foremost goal. 115 00:06:10,060 --> 00:06:13,930 But then there's a more subjective goal see in time, a matter of design. 116 00:06:13,930 --> 00:06:16,030 And we saw a little bit of this last week 117 00:06:16,030 --> 00:06:19,510 when I proposed that we could design even scratch programs better, 118 00:06:19,510 --> 00:06:22,510 maybe by using loops instead of just by copying and pasting 119 00:06:22,510 --> 00:06:24,170 the same blocks again and again. 120 00:06:24,170 --> 00:06:26,080 So design is more subjective. 121 00:06:26,080 --> 00:06:29,830 It's more of a learned art whereby two people might ultimately 122 00:06:29,830 --> 00:06:32,882 disagree as to which version of a program is better designed. 123 00:06:32,882 --> 00:06:35,840 But we'll give you building blocks and principles over the coming weeks 124 00:06:35,840 --> 00:06:37,840 so that you can have a better sense for yourself 125 00:06:37,840 --> 00:06:40,090 if your own code is well designed. 126 00:06:40,090 --> 00:06:41,530 And why is that valuable? 127 00:06:41,530 --> 00:06:44,980 Well, the better designed your code is, often the faster it's going to run, 128 00:06:44,980 --> 00:06:47,438 the more maintainable it's going to be by you or colleagues 129 00:06:47,438 --> 00:06:49,438 if you're working with others in the real world. 130 00:06:49,438 --> 00:06:50,900 So good design is a good thing. 131 00:06:50,900 --> 00:06:54,490 It helps you communicate your ideas, just like in a typical English essay. 132 00:06:54,490 --> 00:06:57,523 And then lastly, we'll talk this week onward about style. 133 00:06:57,523 --> 00:06:59,690 And this is really just the aesthetics of your code. 134 00:06:59,690 --> 00:07:04,720 It turns out that computers often don't care how sloppy your actual code is, 135 00:07:04,720 --> 00:07:08,920 where in the world of code, it turns out that you don't really need 136 00:07:08,920 --> 00:07:10,750 to indent things in a beautiful way. 137 00:07:10,750 --> 00:07:13,150 You don't need to paginate things like might in an essay. 138 00:07:13,150 --> 00:07:16,390 The computer generally does not care, but the human does. 139 00:07:16,390 --> 00:07:17,817 The teaching assistant does. 140 00:07:17,817 --> 00:07:19,900 You will care the next day when you're just trying 141 00:07:19,900 --> 00:07:21,560 to understand what your code does. 142 00:07:21,560 --> 00:07:24,520 So we'll focus lastly on style, the aesthetics of the code 143 00:07:24,520 --> 00:07:25,520 that you're writing. 144 00:07:25,520 --> 00:07:27,280 So where are we going to write code? 145 00:07:27,280 --> 00:07:28,940 Where are we going to compile code? 146 00:07:28,940 --> 00:07:32,770 So for this class, not only with C, but the other languages we use later 147 00:07:32,770 --> 00:07:35,140 in the term, we're going to use a free text 148 00:07:35,140 --> 00:07:39,280 editor that is program called Visual Studio Code, AKA VS Code. 149 00:07:39,280 --> 00:07:43,450 It's super popular nowadays, not just for C, but for C++, and Python, 150 00:07:43,450 --> 00:07:45,970 and Java, and any number of other languages. 151 00:07:45,970 --> 00:07:49,270 It's a text editor in the sense that it lets you edit text. 152 00:07:49,270 --> 00:07:52,150 And that's all code is going to be. 153 00:07:52,150 --> 00:07:54,907 Now, strictly speaking, you could write code on paper/pencil. 154 00:07:54,907 --> 00:07:56,740 In fact, in high school if you took a class, 155 00:07:56,740 --> 00:07:59,532 you might have done that one or more times as an in-class exercise. 156 00:07:59,532 --> 00:08:02,532 You can't run it on paper, of course, but you could write it, certainly. 157 00:08:02,532 --> 00:08:04,570 You could use something like Microsoft Word, 158 00:08:04,570 --> 00:08:07,240 or Notepad.exe, or Text Edit on the Mac. 159 00:08:07,240 --> 00:08:09,340 But none of those programs are really designed 160 00:08:09,340 --> 00:08:12,190 to format the code in the best way for you, 161 00:08:12,190 --> 00:08:15,250 nor are they designed to let you compile and run the code. 162 00:08:15,250 --> 00:08:19,120 So VS Code is going to be a tool via which you can do all that 163 00:08:19,120 --> 00:08:22,240 and more-- write the code, compile the code, run the code. 164 00:08:22,240 --> 00:08:25,630 So that you all don't have to wrestle with stupid technical support 165 00:08:25,630 --> 00:08:29,110 headaches at the beginning of the course by installing this software and that 166 00:08:29,110 --> 00:08:33,070 on your Macs or PCs, we'll use a cloud-based version of VS Code 167 00:08:33,070 --> 00:08:34,780 at code.cs50.io. 168 00:08:34,780 --> 00:08:36,580 And that's going to be the exact same tool. 169 00:08:36,580 --> 00:08:38,860 And the goal, then, is by the end of the semester 170 00:08:38,860 --> 00:08:43,240 to migrate you off of that cloud-based environment to your own Mac and PC 171 00:08:43,240 --> 00:08:46,090 so that even if CS50 is the only CS class you ever take, 172 00:08:46,090 --> 00:08:50,290 you're 100% equipped to continue writing code after the class using 173 00:08:50,290 --> 00:08:54,010 not something that's even CS50-specific, but a de facto industry 174 00:08:54,010 --> 00:08:55,760 standard, at least for some time. 175 00:08:55,760 --> 00:08:59,020 So what's this program VS Code going to look like, be it on your Mac, 176 00:08:59,020 --> 00:09:00,990 PC, or initially in your browser? 177 00:09:00,990 --> 00:09:02,990 It's going to look a little something like this. 178 00:09:02,990 --> 00:09:05,657 And there's going to be several different regions to the screen. 179 00:09:05,657 --> 00:09:07,450 And pictured here is that very same code I 180 00:09:07,450 --> 00:09:10,335 keep proposing as the simplest program you can write in C. 181 00:09:10,335 --> 00:09:12,460 And what are these different regions of the screen? 182 00:09:12,460 --> 00:09:15,440 Well, there's essentially these four here. 183 00:09:15,440 --> 00:09:19,660 So first, highlighted up top is going to be one or more tabs where 184 00:09:19,660 --> 00:09:21,160 you're going to actually write code. 185 00:09:21,160 --> 00:09:23,230 So much like in Google Docs or Microsoft Word, 186 00:09:23,230 --> 00:09:24,940 you can have tabs open with files. 187 00:09:24,940 --> 00:09:28,330 Similarly in VS Code-- or, really, any programming environment-- 188 00:09:28,330 --> 00:09:30,830 you generally nowadays have tabs of some sort. 189 00:09:30,830 --> 00:09:34,480 And this is going to be a tab containing a file, it seems, called hello.c. 190 00:09:34,480 --> 00:09:38,020 And that's going to be the very first file we write in just a moment. 191 00:09:38,020 --> 00:09:40,720 Down here, though, is going to be an interface that many of you 192 00:09:40,720 --> 00:09:41,920 might not know. 193 00:09:41,920 --> 00:09:44,170 This is what's called a terminal window. 194 00:09:44,170 --> 00:09:47,920 And a terminal window provides what's generally called a Command Line 195 00:09:47,920 --> 00:09:49,720 Interface, or CLI. 196 00:09:49,720 --> 00:09:53,680 And this is in contrast with a Graphical User Interface, or GUI. 197 00:09:53,680 --> 00:09:57,760 Now, you and I, every day, are using GUIs on our phones, on our PCs. 198 00:09:57,760 --> 00:10:01,420 And a GUI is literally graphical-- so menus, and buttons, and icons. 199 00:10:01,420 --> 00:10:04,060 And you generally use your finger or a trackpad 200 00:10:04,060 --> 00:10:06,380 or a mouse or something like that to interact with it. 201 00:10:06,380 --> 00:10:08,410 But it turns out that many programmers-- they're 202 00:10:08,410 --> 00:10:11,770 saying most programmers, at least over time, come to prefer, 203 00:10:11,770 --> 00:10:14,620 not a GUI, but a CLI, a Command Line Interface 204 00:10:14,620 --> 00:10:20,650 where you actually do everything somewhat arcanely via keyboard alone. 205 00:10:20,650 --> 00:10:21,250 Why? 206 00:10:21,250 --> 00:10:24,610 Well, it turns out, there's just more features built in to most computers 207 00:10:24,610 --> 00:10:26,260 if you can access them with a keyboard. 208 00:10:26,260 --> 00:10:29,530 It turns out, most of us can type faster than you can point and click. 209 00:10:29,530 --> 00:10:32,330 And so that ends up being an efficiency gain over time. 210 00:10:32,330 --> 00:10:35,140 So in time, will you get comfortable using this terminal 211 00:10:35,140 --> 00:10:39,370 window to do things like compile your code or make your program 212 00:10:39,370 --> 00:10:40,390 as well as run it. 213 00:10:40,390 --> 00:10:43,810 So you won't be in the habit initially of just double clicking icons 214 00:10:43,810 --> 00:10:45,800 like we do in our typical real world. 215 00:10:45,800 --> 00:10:47,890 You'll do it the programmer's way. 216 00:10:47,890 --> 00:10:51,820 But it's not to the exclusion of adding icons, and clickability, and more. 217 00:10:51,820 --> 00:10:53,950 On the left-hand side of VS Code, there's 218 00:10:53,950 --> 00:10:56,920 going to be a somewhat familiar File Explorer, 219 00:10:56,920 --> 00:11:00,040 some kind of hierarchical tree, like on your Mac or PC where you can 220 00:11:00,040 --> 00:11:02,110 see all of the files in your account. 221 00:11:02,110 --> 00:11:04,390 Pictured here, for instance, is just hello.c, 222 00:11:04,390 --> 00:11:06,140 which I'll create myself in a moment. 223 00:11:06,140 --> 00:11:09,343 And then far away on the left is the so-called Activity Bar, 224 00:11:09,343 --> 00:11:12,260 and this is where you just get a lot of traditional menus and buttons. 225 00:11:12,260 --> 00:11:16,250 So VS Code itself gives you both a GUI and a CLI. 226 00:11:16,250 --> 00:11:19,958 But it's within the CLI, the terminal window, the bottom region of the screen 227 00:11:19,958 --> 00:11:22,250 that we're actually going to type most of our commands. 228 00:11:22,250 --> 00:11:25,417 And in general in class, I'm going to hide all of the graphical stuff that's 229 00:11:25,417 --> 00:11:28,380 just not of all that much interest. 230 00:11:28,380 --> 00:11:30,710 So with that said, let me actually change over 231 00:11:30,710 --> 00:11:32,878 to a live version of VS Code. 232 00:11:32,878 --> 00:11:34,670 And I've indeed hidden in the Activity Bar. 233 00:11:34,670 --> 00:11:36,470 I've indeed hidden the File Explorer. 234 00:11:36,470 --> 00:11:39,380 So what I have here for visibility sake is a really big area 235 00:11:39,380 --> 00:11:42,840 for writing code and a really big terminal window at the bottom. 236 00:11:42,840 --> 00:11:45,260 You'll see in the terminal window, there's dollar sign. 237 00:11:45,260 --> 00:11:47,160 And this doesn't mean any form of currency. 238 00:11:47,160 --> 00:11:51,230 This is just the standard symbol that represents type commands here. 239 00:11:51,230 --> 00:11:53,480 So the fact that there's just dollar sign and a cursor 240 00:11:53,480 --> 00:11:55,490 means, eventually, that's where I'm going to type commands. 241 00:11:55,490 --> 00:11:58,020 But first, I'm going to actually create some code. 242 00:11:58,020 --> 00:12:02,900 So how might I program using VS Code-- be it on my Mac, PC, 243 00:12:02,900 --> 00:12:07,160 or in this cloud-based environment that you'll get set up for problem set 1-- 244 00:12:07,160 --> 00:12:08,870 go about writing my first file? 245 00:12:08,870 --> 00:12:10,610 Well, perhaps the easiest way is this. 246 00:12:10,610 --> 00:12:14,090 Literally run the command code and then the name of the file 247 00:12:14,090 --> 00:12:15,200 you want to create. 248 00:12:15,200 --> 00:12:18,838 Notice that I deliberately end the file with .c in lowercase. 249 00:12:18,838 --> 00:12:21,380 Notice that I've deliberately lowercased the whole file name. 250 00:12:21,380 --> 00:12:22,672 And these are just conventions. 251 00:12:22,672 --> 00:12:24,140 You could use a capital H. 252 00:12:24,140 --> 00:12:27,260 You kind of could use a capital C. But just don't do that. 253 00:12:27,260 --> 00:12:30,260 Follow best practices so that it's consistent with what most everyone 254 00:12:30,260 --> 00:12:31,100 else would do. 255 00:12:31,100 --> 00:12:33,770 When I hit Enter, I just get an empty tab, 256 00:12:33,770 --> 00:12:35,540 just like the screenshot a moment ago. 257 00:12:35,540 --> 00:12:40,100 And it's in this tab where I can now write my very first program in C. 258 00:12:40,100 --> 00:12:42,620 Unfortunately, it's not quite as user-friendly as Scratch 259 00:12:42,620 --> 00:12:45,992 where you drag and drop a couple of puzzle pieces and, boom, it's done. 260 00:12:45,992 --> 00:12:47,450 So I'm going to do this for memory. 261 00:12:47,450 --> 00:12:49,970 But this, too, will become familiar to you over time. 262 00:12:49,970 --> 00:12:53,720 I'm going to include something called stdio.h. 263 00:12:53,720 --> 00:12:57,230 I'm going to type int main, void in parentheses. 264 00:12:57,230 --> 00:13:01,190 On a new line, I'm going to insert some curly braces, as we'll call them. 265 00:13:01,190 --> 00:13:03,830 And then I'm going to type printf, and then some 266 00:13:03,830 --> 00:13:09,200 parentheses, and then in quotes, hello, comma, world, then a backslash, then 267 00:13:09,200 --> 00:13:12,800 a lowercase n, then a close quote, and then a semicolon 268 00:13:12,800 --> 00:13:14,280 at the very end of the line. 269 00:13:14,280 --> 00:13:19,010 So all I've done is recreate, just from memory, that very first program. 270 00:13:19,010 --> 00:13:21,710 In a little bit, we'll make clear what most of this does. 271 00:13:21,710 --> 00:13:23,857 But for now, let's just actually run this thing. 272 00:13:23,857 --> 00:13:26,690 And just like I clicked the green flag last week for the first time, 273 00:13:26,690 --> 00:13:29,840 let's actually compile and run this program. 274 00:13:29,840 --> 00:13:33,967 If it were your Mac or PC and Google, or Microsoft, or someone else 275 00:13:33,967 --> 00:13:36,050 had made the software, at this point in the story, 276 00:13:36,050 --> 00:13:37,408 we'd be double clicking an icon. 277 00:13:37,408 --> 00:13:38,450 But we can't do that yet. 278 00:13:38,450 --> 00:13:39,930 This is still source code. 279 00:13:39,930 --> 00:13:42,380 So I'm going to click back down in my terminal window. 280 00:13:42,380 --> 00:13:45,650 Notice I have a second dollar sign below the first, which just 281 00:13:45,650 --> 00:13:47,880 means it's ready for a second command. 282 00:13:47,880 --> 00:13:53,000 And now the command via which to make this an actual program, to compile it 283 00:13:53,000 --> 00:13:56,990 from source code to machine code is, going to be quite simply make 284 00:13:56,990 --> 00:13:59,360 and then the name of the program I want to make. 285 00:13:59,360 --> 00:14:03,710 Slight subtlety-- I'm omitting deliberately .c because the program I 286 00:14:03,710 --> 00:14:05,870 want to make, I just want to call hello. 287 00:14:05,870 --> 00:14:07,400 Don't write make hello.c. 288 00:14:07,400 --> 00:14:08,780 Just write make hello. 289 00:14:08,780 --> 00:14:13,040 And this program make is essentially our compiler. 290 00:14:13,040 --> 00:14:15,560 Technically speaking, it's a program that automates 291 00:14:15,560 --> 00:14:17,580 the compilation of my program for me. 292 00:14:17,580 --> 00:14:20,180 But it is going to see that I've typed the word hello. 293 00:14:20,180 --> 00:14:25,100 It's going to automatically look now for a file on the hard drive called hello.c 294 00:14:25,100 --> 00:14:30,690 and convert it from source code in C to machine code in zeros and ones. 295 00:14:30,690 --> 00:14:37,170 So if I didn't make any typos, Enter, nothing seems to happen. 296 00:14:37,170 --> 00:14:38,210 And that's a good thing. 297 00:14:38,210 --> 00:14:41,862 Almost always, if nothing gets outputted on the screen, you did good. 298 00:14:41,862 --> 00:14:43,070 You didn't make any mistakes. 299 00:14:43,070 --> 00:14:43,880 You didn't get yelled at. 300 00:14:43,880 --> 00:14:45,000 There's no error messages. 301 00:14:45,000 --> 00:14:46,590 So this is actually a good thing. 302 00:14:46,590 --> 00:14:47,942 How do I now run this program? 303 00:14:47,942 --> 00:14:50,150 Well, notice I've got a third dollar sign, which just 304 00:14:50,150 --> 00:14:52,110 means I'm ready for a third command. 305 00:14:52,110 --> 00:14:55,400 And now I'm going to go ahead and run ./hello. 306 00:14:55,400 --> 00:14:58,798 And this is admittedly a little weird that you have to do dot slash. 307 00:14:58,798 --> 00:15:00,590 But for now just take on faith that this is 308 00:15:00,590 --> 00:15:04,610 how you run a program called hello In your current folder, 309 00:15:04,610 --> 00:15:07,730 in your current directory in this cloud-based environment. 310 00:15:07,730 --> 00:15:10,430 All right, crossing my fingers again, hitting Enter. 311 00:15:10,430 --> 00:15:12,110 And voila. 312 00:15:12,110 --> 00:15:15,950 My very first program in C, hello, world. 313 00:15:15,950 --> 00:15:20,480 And now let me go ahead and reveal the File Explorer that I proposed 314 00:15:20,480 --> 00:15:21,292 exists earlier. 315 00:15:21,292 --> 00:15:23,750 I'm just going to use the keyboard shortcut to reveal that. 316 00:15:23,750 --> 00:15:27,000 And generally, I keep it closed because I don't really need to constantly what 317 00:15:27,000 --> 00:15:28,250 files are in my account. 318 00:15:28,250 --> 00:15:31,820 But you'll see now in the File Explorer, similar in spirit to a Mac or PC 319 00:15:31,820 --> 00:15:35,270 but graphically a little different, here's my file, hello.c. 320 00:15:35,270 --> 00:15:37,520 It's highlighted because I have that tab open. 321 00:15:37,520 --> 00:15:40,970 But now there's a second file here called just hello. 322 00:15:40,970 --> 00:15:42,690 That's the name of my program. 323 00:15:42,690 --> 00:15:46,100 So if you were on a Mac or PC, you would ideally double click that thing. 324 00:15:46,100 --> 00:15:48,162 You can't do that in a command line environment. 325 00:15:48,162 --> 00:15:49,370 You have to run it down here. 326 00:15:49,370 --> 00:15:50,453 But that's all we've done. 327 00:15:50,453 --> 00:15:53,750 We've created a file called hello.c, and then my compiler 328 00:15:53,750 --> 00:15:56,240 made the program from that. 329 00:15:56,240 --> 00:16:00,080 Let me pause here and see if there's any questions because that's 330 00:16:00,080 --> 00:16:01,970 a lot of magical phrases. 331 00:16:01,970 --> 00:16:04,450 Yeah? 332 00:16:04,450 --> 00:16:04,950 Yeah. 333 00:16:04,950 --> 00:16:08,390 So if you're currently following along, playing along at home 334 00:16:08,390 --> 00:16:10,890 and you're getting some kind of error message, part of today 335 00:16:10,890 --> 00:16:13,950 will be for me to deliberately induce some of those error messages. 336 00:16:13,950 --> 00:16:17,070 For now let me just propose that if you literally did what I did, 337 00:16:17,070 --> 00:16:19,320 you must have made a typo somewhere. 338 00:16:19,320 --> 00:16:23,790 And notice that it's indeed standard io-- stdio.h. 339 00:16:23,790 --> 00:16:25,890 Maybe you typed studio.h? 340 00:16:25,890 --> 00:16:30,600 OK, super common mistake, I could call you out. 341 00:16:30,600 --> 00:16:32,280 It is not studio.h. 342 00:16:32,280 --> 00:16:34,560 It is stdio.h-- so common. 343 00:16:34,560 --> 00:16:37,658 But this is exactly representative of the kind of stupid headaches 344 00:16:37,658 --> 00:16:40,200 you're going to run into this week, probably for a few weeks, 345 00:16:40,200 --> 00:16:41,730 probably, honestly, for a few years. 346 00:16:41,730 --> 00:16:45,180 But you start to see past these stupid mistakes over time, 347 00:16:45,180 --> 00:16:47,610 and it just gets easier and easier because the computer is 348 00:16:47,610 --> 00:16:49,110 going to be so regimented. 349 00:16:49,110 --> 00:16:50,950 It will only do what you tell it to do. 350 00:16:50,950 --> 00:16:54,223 And if you say because it's verbally sounds like studio.h, 351 00:16:54,223 --> 00:16:55,890 it's not going to know what the file is. 352 00:16:55,890 --> 00:16:58,182 So actually, thank you for tripping over that so early. 353 00:16:58,182 --> 00:16:59,740 That's super common to happen. 354 00:16:59,740 --> 00:17:00,240 Yeah? 355 00:17:00,240 --> 00:17:02,540 AUDIENCE: Why do you have two hello files? 356 00:17:02,540 --> 00:17:03,799 DAVID J. MALAN: Why do I have to hello files? 357 00:17:03,799 --> 00:17:04,400 AUDIENCE: Yes. 358 00:17:04,400 --> 00:17:06,400 DAVID J. MALAN: So why do I have to hello files? 359 00:17:06,400 --> 00:17:09,170 One is the one I created as the human called hello.c, 360 00:17:09,170 --> 00:17:10,520 and it's pictured right here. 361 00:17:10,520 --> 00:17:15,890 But then when I ran make hello, that process compiled my source code 362 00:17:15,890 --> 00:17:17,040 into machine code. 363 00:17:17,040 --> 00:17:20,240 So this second file just called hello is the file that 364 00:17:20,240 --> 00:17:25,700 contains all of those zeros and ones that the server actually understands. 365 00:17:25,700 --> 00:17:27,200 All right, so yeah, question? 366 00:17:27,200 --> 00:17:29,710 AUDIENCE: The access to the hello [INAUDIBLE] 367 00:17:29,710 --> 00:17:31,960 DAVID J. MALAN: If you try clicking on the hello file, 368 00:17:31,960 --> 00:17:34,270 you'll see in this environment the VS Code, 369 00:17:34,270 --> 00:17:36,580 quote/unquote, The file is not displayed in the editor 370 00:17:36,580 --> 00:17:38,230 because it is either binary-- 371 00:17:38,230 --> 00:17:41,437 AKA zeros and ones-- or uses an unsupported text encoding. 372 00:17:41,437 --> 00:17:42,520 In this case, it's binary. 373 00:17:42,520 --> 00:17:43,660 It's zeros and ones. 374 00:17:43,660 --> 00:17:47,680 Now, you could use software to see those zeros and ones. 375 00:17:47,680 --> 00:17:50,320 It won't be intellectually enlightening to most any human. 376 00:17:50,320 --> 00:17:53,165 So VS Code just takes the choice of not showing it to you at all. 377 00:17:53,165 --> 00:17:56,290 So that would be a common mistake too, clicking on a file you don't intend. 378 00:17:56,290 --> 00:18:00,190 But the source code is indeed going to be editable by us. 379 00:18:00,190 --> 00:18:01,900 All right, so I've written this program. 380 00:18:01,900 --> 00:18:04,780 It seems to magically work, at least with some effort 381 00:18:04,780 --> 00:18:06,700 if you get every single keystroke right. 382 00:18:06,700 --> 00:18:08,440 Well, what is it that's going on? 383 00:18:08,440 --> 00:18:09,460 And how is this working? 384 00:18:09,460 --> 00:18:13,180 Well, first of all, notice that even without my highlighting things 385 00:18:13,180 --> 00:18:17,740 or choosing buttons for menus, notice that it's already color coded. 386 00:18:17,740 --> 00:18:20,980 And yet, I wasn't highlighting along the way in Google Docs style, 387 00:18:20,980 --> 00:18:22,510 changing the color, certainly. 388 00:18:22,510 --> 00:18:25,960 Well, it turns out, what VS Code and most programming environments 389 00:18:25,960 --> 00:18:29,600 nowadays do for you automatically is syntax highlighting. 390 00:18:29,600 --> 00:18:33,850 So syntax highlighting is just this feature of typical text editors 391 00:18:33,850 --> 00:18:36,760 nowadays that analyzes the code that you've typed. 392 00:18:36,760 --> 00:18:40,000 And when it notices certain types of keystrokes, 393 00:18:40,000 --> 00:18:43,900 things that represent functions, or conditionals, or loops, or variables-- 394 00:18:43,900 --> 00:18:47,570 a lot of the vocab from last week-- it just highlights it ever so differently 395 00:18:47,570 --> 00:18:48,070 for you. 396 00:18:48,070 --> 00:18:51,430 So main, for instance, which we'll soon see, is in purple here. 397 00:18:51,430 --> 00:18:53,890 Int, and void, and include are in red. 398 00:18:53,890 --> 00:18:55,630 Hello, world is in blue. 399 00:18:55,630 --> 00:18:57,390 My parentheses are in green. 400 00:18:57,390 --> 00:18:59,290 This will totally vary by programmer too. 401 00:18:59,290 --> 00:19:02,995 In fact, if you do want to change these colors for problem set 1 402 00:19:02,995 --> 00:19:04,870 for your own environment, you can poke around 403 00:19:04,870 --> 00:19:07,190 VS Code Settings via the gear icon. 404 00:19:07,190 --> 00:19:09,820 You can change to a different color theme. 405 00:19:09,820 --> 00:19:13,480 Syntax highlighting isn't some specific color scheme like it is in Scratch. 406 00:19:13,480 --> 00:19:16,485 It just generally is to each human their own preference. 407 00:19:16,485 --> 00:19:18,610 But that's all that's happening here is this notion 408 00:19:18,610 --> 00:19:20,830 of syntax highlighting at the moment. 409 00:19:20,830 --> 00:19:25,510 Well, what more is going on in this code before I run it, but rather write it? 410 00:19:25,510 --> 00:19:28,790 Well, it looks a little something like this if I take away all of the colors. 411 00:19:28,790 --> 00:19:30,550 And then just for discussion's sake, let me go ahead 412 00:19:30,550 --> 00:19:32,500 and color it a little more like Scratch. 413 00:19:32,500 --> 00:19:34,690 Recall that our very first Scratch program 414 00:19:34,690 --> 00:19:39,670 that just said hello, world on the screen had a green flag clicked icon-- 415 00:19:39,670 --> 00:19:45,070 puzzle piece, roughly in orange, and then a purple say block beneath it. 416 00:19:45,070 --> 00:19:48,820 So whereas this is the C version, if we run rewind to last week, 417 00:19:48,820 --> 00:19:50,950 this was the same program in Scratch. 418 00:19:50,950 --> 00:19:53,090 But what's happening now is exactly the same. 419 00:19:53,090 --> 00:19:55,060 So if you think back to last week and you've 420 00:19:55,060 --> 00:19:58,600 got some function, like the say function in purple, 421 00:19:58,600 --> 00:20:01,270 that might take one or more arguments, like inputs that 422 00:20:01,270 --> 00:20:03,190 influences what it says on the screen. 423 00:20:03,190 --> 00:20:05,230 And then functions, recall, can sometimes 424 00:20:05,230 --> 00:20:08,480 have side effects, like the speech bubble appears on the screen. 425 00:20:08,480 --> 00:20:11,260 So last week when we used the say block and we 426 00:20:11,260 --> 00:20:13,840 passed in an argument of hello, world at left, 427 00:20:13,840 --> 00:20:17,915 we got this visual side effect on the screen that says now hello, world 428 00:20:17,915 --> 00:20:18,790 in the speech bubble. 429 00:20:18,790 --> 00:20:23,230 And that's exactly what just happened in VS Code but much, much more textually. 430 00:20:23,230 --> 00:20:25,900 And let's look a little closer now at the code itself. 431 00:20:25,900 --> 00:20:29,020 Let me wave my hand at the equivalent of when 432 00:20:29,020 --> 00:20:32,890 green flag clicked part of my code, and let's focus only 433 00:20:32,890 --> 00:20:38,350 on the say block in Scratch and the corresponding function in C. 434 00:20:38,350 --> 00:20:41,770 So if I step through this and I wanted to convert what 435 00:20:41,770 --> 00:20:44,830 we did last week with the say block to C, 436 00:20:44,830 --> 00:20:47,645 I would first use the print function-- although that's actually 437 00:20:47,645 --> 00:20:48,520 a bit of a white lie. 438 00:20:48,520 --> 00:20:50,440 It's actually the printf function. 439 00:20:50,440 --> 00:20:52,030 Printf means formatted. 440 00:20:52,030 --> 00:20:55,360 And it's just a function that allows you to format text on the screen. 441 00:20:55,360 --> 00:20:58,570 There is no say function in C. There's a printf function. 442 00:20:58,570 --> 00:21:02,650 What MIT did down the road years ago was they took what existed historically 443 00:21:02,650 --> 00:21:05,290 as printf, and they simplified it for a broader audience 444 00:21:05,290 --> 00:21:08,050 by just calling it essentially say instead. 445 00:21:08,050 --> 00:21:13,450 But notice that now if I want to convert the Scratch code at left to C code 446 00:21:13,450 --> 00:21:16,250 it right, it's the same shape. 447 00:21:16,250 --> 00:21:18,940 So MIT deliberately used this white oval, 448 00:21:18,940 --> 00:21:23,510 if only because it conjures this idea of having parentheses too. 449 00:21:23,510 --> 00:21:26,770 So on the right, if I want to pass an argument or an input 450 00:21:26,770 --> 00:21:31,240 to the printf function, I use an open parentheses and a close parentheses. 451 00:21:31,240 --> 00:21:33,700 In those parentheses, I then type whatever 452 00:21:33,700 --> 00:21:35,600 it is I want to print on the screen-- 453 00:21:35,600 --> 00:21:37,460 in this case, hello, comma, world. 454 00:21:37,460 --> 00:21:39,310 But notice I've deliberately left some room 455 00:21:39,310 --> 00:21:42,160 because you need some extra keystrokes in the world of C. 456 00:21:42,160 --> 00:21:44,590 Any time you type out some text-- 457 00:21:44,590 --> 00:21:49,150 otherwise known as a string of text, to use computer science jargon-- 458 00:21:49,150 --> 00:21:52,100 you need to quote it, in this case with double quotes. 459 00:21:52,100 --> 00:21:54,520 Double quote at the left, double quote at the right. 460 00:21:54,520 --> 00:21:57,730 And notice too I'm going to include some slightly cryptic symbol 461 00:21:57,730 --> 00:22:01,660 here too-- backslash n, which I also typed and said verbally earlier, 462 00:22:01,660 --> 00:22:05,480 and then one last nuisance at the end of this, which is a semicolon. 463 00:22:05,480 --> 00:22:08,890 So suffice it to say, this is why we start with Scratch. 464 00:22:08,890 --> 00:22:10,960 This, drag and drop, you're good to go. 465 00:22:10,960 --> 00:22:14,680 In a language like C, printf, parentheses, double quotes, the text 466 00:22:14,680 --> 00:22:16,630 you want, backslash n, semicolon at the end. 467 00:22:16,630 --> 00:22:18,970 There's just so much syntactic overhead. 468 00:22:18,970 --> 00:22:21,290 But at the end of the day, it's just a function. 469 00:22:21,290 --> 00:22:25,180 And you'll get used to these nuisances like the parentheses, the quotes, 470 00:22:25,180 --> 00:22:27,130 the semicolon, and the like. 471 00:22:27,130 --> 00:22:31,810 But things can very easily you go wrong, and it's very easy to make mistakes, 472 00:22:31,810 --> 00:22:33,380 even with lines of code like this. 473 00:22:33,380 --> 00:22:34,190 So let me do this. 474 00:22:34,190 --> 00:22:37,070 Let me go back to VS Code where I have the exact same code. 475 00:22:37,070 --> 00:22:40,910 Notice that on line 5 is exactly that line of code. 476 00:22:40,910 --> 00:22:42,910 So this is the equivalent of the say block. 477 00:22:42,910 --> 00:22:46,090 And let's consider what mistakes I may make early on or even now 478 00:22:46,090 --> 00:22:49,930 20 years later after learning this that are quite common in general. 479 00:22:49,930 --> 00:22:52,180 Suppose I forget the semicolon there. 480 00:22:52,180 --> 00:22:53,380 So easy to do. 481 00:22:53,380 --> 00:22:54,910 You will do this eventually. 482 00:22:54,910 --> 00:22:57,970 Let's see what happens now when I go back to my terminal window 483 00:22:57,970 --> 00:22:59,920 and try to compile my code again. 484 00:22:59,920 --> 00:23:02,590 Just to keep things tidy, I'm going to clear my screen. 485 00:23:02,590 --> 00:23:05,170 But that's just for lecture's sake so that we can focus only 486 00:23:05,170 --> 00:23:06,460 on the most recent command. 487 00:23:06,460 --> 00:23:09,940 But I'm going to go ahead now and rerun make hello. 488 00:23:09,940 --> 00:23:13,690 This will ensure that my program is recompiled. 489 00:23:13,690 --> 00:23:14,950 And this is a manual process. 490 00:23:14,950 --> 00:23:16,060 I changed my code. 491 00:23:16,060 --> 00:23:18,670 The zeros and ones on the hard drive have not changed. 492 00:23:18,670 --> 00:23:21,980 I need to recompile it to output the latest machine code. 493 00:23:21,980 --> 00:23:22,580 So here we go. 494 00:23:22,580 --> 00:23:24,830 I'm going to hit Enter, crossing my fingers as before. 495 00:23:24,830 --> 00:23:29,320 But again, I remove the semicolon by accident. 496 00:23:29,320 --> 00:23:29,980 Oh, my god. 497 00:23:29,980 --> 00:23:33,700 There's more lines of errors now than there are of actual code. 498 00:23:33,700 --> 00:23:35,770 And this, too, takes some getting used to. 499 00:23:35,770 --> 00:23:38,590 The programs we're using were not necessarily written 500 00:23:38,590 --> 00:23:40,480 with the least comfortable audience in mind 501 00:23:40,480 --> 00:23:42,760 but, really, professional programmers back in the day. 502 00:23:42,760 --> 00:23:46,000 But through practice, and through experience, and through mistakes, 503 00:23:46,000 --> 00:23:47,750 you'll start to notice patterns here too. 504 00:23:47,750 --> 00:23:49,090 So here's what I typed. 505 00:23:49,090 --> 00:23:51,220 Make hello after the sign prompt. 506 00:23:51,220 --> 00:23:57,010 Now I get yelled at as follows, hello.c, colon, 5, colon, 29. 507 00:23:57,010 --> 00:23:58,420 Well, what's that referring to? 508 00:23:58,420 --> 00:24:03,460 I've screwed up somewhere-- on line 5, on the 29th character on that line. 509 00:24:03,460 --> 00:24:05,740 Generally, the specific character is not that useful 510 00:24:05,740 --> 00:24:07,448 unless you actually want to count it out. 511 00:24:07,448 --> 00:24:08,630 But line 5 is a good clue. 512 00:24:08,630 --> 00:24:09,130 Why? 513 00:24:09,130 --> 00:24:11,660 It means I screwed up somewhere on line 5 here. 514 00:24:11,660 --> 00:24:12,160 All right. 515 00:24:12,160 --> 00:24:13,360 Well, what is the error? 516 00:24:13,360 --> 00:24:16,242 Expected a semicolon after expression. 517 00:24:16,242 --> 00:24:17,950 And this error is actually pretty obvious 518 00:24:17,950 --> 00:24:20,103 now that I see it and I realize, oh, wait a minute. 519 00:24:20,103 --> 00:24:21,520 All right, here's my line of code. 520 00:24:21,520 --> 00:24:26,890 Here in sort of ASCII art, so to speak-- textual text representing graphics-- 521 00:24:26,890 --> 00:24:30,550 it wants me to put in green here the semicolon at the end of that line. 522 00:24:30,550 --> 00:24:32,470 1 error generated, builtin-- 523 00:24:32,470 --> 00:24:33,850 so some esoteric stuff there. 524 00:24:33,850 --> 00:24:36,340 But my program did not compile. 525 00:24:36,340 --> 00:24:39,470 When you see an error like this, it means it did not work. 526 00:24:39,470 --> 00:24:40,360 So what's the fix? 527 00:24:40,360 --> 00:24:45,470 Well, obviously, the fix is to go back up here, put the semicolon there. 528 00:24:45,470 --> 00:24:48,760 And now if I recompile my code with make hello-- 529 00:24:48,760 --> 00:24:52,060 I won't clear my screen just yet just to show you the difference-- now 530 00:24:52,060 --> 00:24:52,990 it just worked. 531 00:24:52,990 --> 00:24:55,550 So we're back in business as before. 532 00:24:55,550 --> 00:24:57,910 All right, let me pause here, though, and ask if there's 533 00:24:57,910 --> 00:25:02,240 any questions about what I just did. 534 00:25:02,240 --> 00:25:04,460 These error messages will become frequent initially. 535 00:25:04,460 --> 00:25:04,960 Yeah? 536 00:25:04,960 --> 00:25:08,848 AUDIENCE: So do you need a semicolon after line or just some of them? 537 00:25:08,848 --> 00:25:10,390 DAVID J. MALAN: Really good question. 538 00:25:10,390 --> 00:25:12,960 Do you need a semicolon after every line or just some? 539 00:25:12,960 --> 00:25:14,022 It turns out, just some. 540 00:25:14,022 --> 00:25:16,980 This is something you'll learn through practice, through demonstrations 541 00:25:16,980 --> 00:25:18,240 and examples today. 542 00:25:18,240 --> 00:25:22,810 Generally, you put a semicolon after a statement, so to speak. 543 00:25:22,810 --> 00:25:25,230 And this is the technical term for this line of code. 544 00:25:25,230 --> 00:25:25,950 It's a statement. 545 00:25:25,950 --> 00:25:29,230 And think of it as it's the code equivalent of an English sentence. 546 00:25:29,230 --> 00:25:32,820 So the semicolon in code is like a period in English 547 00:25:32,820 --> 00:25:34,830 when you're done with that particular thought. 548 00:25:34,830 --> 00:25:37,650 You don't need semicolons for now anywhere else. 549 00:25:37,650 --> 00:25:39,750 And we'll see examples of where else you put them. 550 00:25:39,750 --> 00:25:42,780 But it usually is at the end of a line of code 551 00:25:42,780 --> 00:25:46,980 that isn't purely syntactic like curly braces instead. 552 00:25:46,980 --> 00:25:51,600 Other questions on the mistake I just fixed and created for myself? 553 00:25:51,600 --> 00:25:52,230 Yeah? 554 00:25:52,230 --> 00:25:55,170 AUDIENCE: [INAUDIBLE] 555 00:25:55,170 --> 00:25:56,170 DAVID J. MALAN: Correct. 556 00:25:56,170 --> 00:25:58,950 So line 5 is where the error is most likely. 557 00:25:58,950 --> 00:26:02,250 Character 29 means it's 29 characters that way. 558 00:26:02,250 --> 00:26:04,800 And then it's actually, in this case, giving me a suggestion. 559 00:26:04,800 --> 00:26:07,420 The compiler won't always know how to advise me, 560 00:26:07,420 --> 00:26:09,750 especially if I've made a real mess of my code. 561 00:26:09,750 --> 00:26:13,260 But often, it will do its best to give you the answer like this. 562 00:26:13,260 --> 00:26:14,170 Yeah? 563 00:26:14,170 --> 00:26:16,930 AUDIENCE: How come you first put code hello.c? 564 00:26:16,930 --> 00:26:21,140 DAVID J. MALAN: Ah, so how come I first typed code, space, hello.c, 565 00:26:21,140 --> 00:26:22,940 and now I'm typing make hello? 566 00:26:22,940 --> 00:26:24,180 Two different processes. 567 00:26:24,180 --> 00:26:27,350 So when I typed code, space, hello.c, that 568 00:26:27,350 --> 00:26:31,280 was because I wanted to open VS Code and create a new file called hello.c. 569 00:26:31,280 --> 00:26:34,910 It's like going to File, New in a Mac or PC. 570 00:26:34,910 --> 00:26:38,690 Thereafter, though, once the file exists and is actually open here-- 571 00:26:38,690 --> 00:26:41,900 and it does autosave, you don't need to hit Command-S or Control-S all 572 00:26:41,900 --> 00:26:42,560 the time-- 573 00:26:42,560 --> 00:26:46,110 I can now compile it with make hello again and again. 574 00:26:46,110 --> 00:26:50,570 So theoretically, I should never need to type code, space, hello.c 575 00:26:50,570 --> 00:26:54,020 again unless I want to create a brand-new file called the same thing. 576 00:26:54,020 --> 00:26:57,200 All right, so what about this other piece of syntax here? 577 00:26:57,200 --> 00:26:58,790 Let me clear my terminal window here. 578 00:26:58,790 --> 00:27:01,280 You can also hit Control-L just to throw everything 579 00:27:01,280 --> 00:27:03,380 away just to clean it up aesthetically. 580 00:27:03,380 --> 00:27:06,470 Suppose that I omit whatever this sequence of symbols 581 00:27:06,470 --> 00:27:09,680 is, backslash n, since I'm not really sure at first glance 582 00:27:09,680 --> 00:27:11,460 why that's even there. 583 00:27:11,460 --> 00:27:13,310 Does anyone want to conjecture, especially 584 00:27:13,310 --> 00:27:18,110 if you've never programmed before, what might happen now if I recompile 585 00:27:18,110 --> 00:27:20,450 and rerun this version of the program? 586 00:27:20,450 --> 00:27:25,130 I left the semicolon, but I took away the backslash n. 587 00:27:25,130 --> 00:27:28,390 Any instincts? 588 00:27:28,390 --> 00:27:29,920 All right, well-- yeah? 589 00:27:29,920 --> 00:27:32,470 AUDIENCE: Will the next dollar sign appear 590 00:27:32,470 --> 00:27:34,190 straight after your hello, world? 591 00:27:34,190 --> 00:27:35,190 DAVID J. MALAN: It will. 592 00:27:35,190 --> 00:27:38,740 The next dollar sign will appear right after my hello, world. 593 00:27:38,740 --> 00:27:40,564 But what makes you think that? 594 00:27:40,564 --> 00:27:43,010 AUDIENCE: Because the backslash n creates a new line? 595 00:27:43,010 --> 00:27:44,010 DAVID J. MALAN: Exactly. 596 00:27:44,010 --> 00:27:46,050 Backslash n is actually a special sequence 597 00:27:46,050 --> 00:27:48,060 of symbols that creates a new line. 598 00:27:48,060 --> 00:27:52,710 And so, to your point, if I recompile this program, make hello, Enter-- 599 00:27:52,710 --> 00:27:55,420 no syntax error, so it did compile this time. 600 00:27:55,420 --> 00:27:57,180 So you don't need the backslash n. 601 00:27:57,180 --> 00:27:58,800 You do need the semicolon. 602 00:27:58,800 --> 00:28:02,730 But if you don't have the backslash n, watch what happens when I do ./hello 603 00:28:02,730 --> 00:28:03,510 this time. 604 00:28:03,510 --> 00:28:07,230 Now, indeed, I see hello, comma, world and then a weird dollar sign. 605 00:28:07,230 --> 00:28:08,460 And this is still a prompt. 606 00:28:08,460 --> 00:28:12,270 I can still type commands at it, like clear, and everything gets cleaned up. 607 00:28:12,270 --> 00:28:13,710 But it just looks kind of stupid. 608 00:28:13,710 --> 00:28:18,240 If I run it again here with ./hello, it's just not very user friendly. 609 00:28:18,240 --> 00:28:20,740 It is convention that when you're done running your program, 610 00:28:20,740 --> 00:28:22,950 you should ideally clean things up, move the cursor 611 00:28:22,950 --> 00:28:24,460 to the next line for the user. 612 00:28:24,460 --> 00:28:27,540 And so the backslash n is simply the special symbol, 613 00:28:27,540 --> 00:28:32,640 otherwise known as an escape sequence that C knows 614 00:28:32,640 --> 00:28:34,980 means move the cursor to the next line. 615 00:28:34,980 --> 00:28:39,640 In other languages, Python among them, uses this same symbology as well. 616 00:28:39,640 --> 00:28:44,850 Now, if I go back to the code here and, for instance, 617 00:28:44,850 --> 00:28:47,220 I try to do this differently. 618 00:28:47,220 --> 00:28:49,020 Suppose I don't put the backslash n. 619 00:28:49,020 --> 00:28:52,860 I just hit Enter like a normal person would in Google Docs or Microsoft Word. 620 00:28:52,860 --> 00:28:55,107 Let me go ahead and try compiling this program. 621 00:28:55,107 --> 00:28:56,940 And this, you would hope, would work, right? 622 00:28:56,940 --> 00:29:00,210 You would hope this would print out hello, world and then a blank line 623 00:29:00,210 --> 00:29:02,220 because I move the cursor to the next line. 624 00:29:02,220 --> 00:29:02,790 But no. 625 00:29:02,790 --> 00:29:07,290 If I run make hello now and try to compile that, C does not like this. 626 00:29:07,290 --> 00:29:09,690 Now I get a different error, still on line 5, 627 00:29:09,690 --> 00:29:12,240 this time starting at character 12-- 628 00:29:12,240 --> 00:29:15,810 error, missing terminating double quote character and then 629 00:29:15,810 --> 00:29:17,070 some other esoteric stuff. 630 00:29:17,070 --> 00:29:19,530 And then this does not sound good-- fatal error this time, 631 00:29:19,530 --> 00:29:21,900 too many errors emitted, stopping now. 632 00:29:21,900 --> 00:29:23,470 So I really screwed up here. 633 00:29:23,470 --> 00:29:25,320 So why can't I do this? 634 00:29:25,320 --> 00:29:26,190 Just because. 635 00:29:26,190 --> 00:29:29,730 The humans who designed C decided that if you have a string of text, 636 00:29:29,730 --> 00:29:31,380 it must stay on the same line. 637 00:29:31,380 --> 00:29:32,760 It can get really long. 638 00:29:32,760 --> 00:29:36,150 It can soft wrap-- that is, without you hitting Enter. 639 00:29:36,150 --> 00:29:38,220 But you can't hit Enter to create a new line. 640 00:29:38,220 --> 00:29:42,870 If you deliberately want a new line, you have to indeed use this backslash n 641 00:29:42,870 --> 00:29:43,958 escape character. 642 00:29:43,958 --> 00:29:45,250 So let me go ahead and do this. 643 00:29:45,250 --> 00:29:46,710 Let me put it back. 644 00:29:46,710 --> 00:29:48,720 Let me go back to my terminal window. 645 00:29:48,720 --> 00:29:50,080 I'll clear the screen again. 646 00:29:50,080 --> 00:29:54,090 Let me go ahead now and do make hello to recompile to that version-- ./hello. 647 00:29:54,090 --> 00:29:54,900 And voila. 648 00:29:54,900 --> 00:29:57,780 We're back in business with hello. 649 00:29:57,780 --> 00:30:00,300 All right, so now let's tease apart some other aspects 650 00:30:00,300 --> 00:30:03,870 of this code because there's a lot going on just to get us to say hello, 651 00:30:03,870 --> 00:30:04,920 world on the screen. 652 00:30:04,920 --> 00:30:07,740 For today, we're largely going to ignore this-- int 653 00:30:07,740 --> 00:30:10,145 main(void) and these curly braces here. 654 00:30:10,145 --> 00:30:12,520 We'll come back to that before long as to why it's there. 655 00:30:12,520 --> 00:30:15,870 But for now just think of int main(void) and these curly braces 656 00:30:15,870 --> 00:30:19,180 here as really being the C equivalent of when green flag clicked. 657 00:30:19,180 --> 00:30:19,680 Why? 658 00:30:19,680 --> 00:30:20,638 You just need it there. 659 00:30:20,638 --> 00:30:22,320 That's how you get your program going. 660 00:30:22,320 --> 00:30:25,500 And main is indeed going to be some special function, but more on that 661 00:30:25,500 --> 00:30:26,340 another time. 662 00:30:26,340 --> 00:30:28,950 But why do I have this line of code here? 663 00:30:28,950 --> 00:30:33,990 The correct spelling is indeed stdio.h, S-T-D-I-O dot H. 664 00:30:33,990 --> 00:30:37,500 And they're angled brackets this time, so that's a little new. 665 00:30:37,500 --> 00:30:40,290 There's a hash and then an include keyword. 666 00:30:40,290 --> 00:30:42,123 If you don't know what something is, there's 667 00:30:42,123 --> 00:30:45,165 not really that much harm in just getting rid of it and see what happens. 668 00:30:45,165 --> 00:30:46,360 So let me delete that line. 669 00:30:46,360 --> 00:30:48,910 Let me go back to my terminal window, clear the screen, 670 00:30:48,910 --> 00:30:50,160 and then run make hello again. 671 00:30:50,160 --> 00:30:53,290 And let's try compiling this program now without that first line. 672 00:30:53,290 --> 00:30:53,790 Why? 673 00:30:53,790 --> 00:30:56,340 I don't understand it, so let's see what happens. 674 00:30:56,340 --> 00:30:58,920 All right, here's yet another error, but let's see-- 675 00:30:58,920 --> 00:31:03,480 hello.c, line 5, character 5-- so it's pretty early on-- 676 00:31:03,480 --> 00:31:07,920 error, implicitly declaring library function printf with type int 677 00:31:07,920 --> 00:31:09,150 and then dot, dot, dot. 678 00:31:09,150 --> 00:31:12,630 So implicitly declaring library function printf-- 679 00:31:12,630 --> 00:31:14,490 so this is very cryptic sounding. 680 00:31:14,490 --> 00:31:16,920 You'll get better at understanding phrases like these. 681 00:31:16,920 --> 00:31:22,620 But apparently, I do need the include line for stdio.h. 682 00:31:22,620 --> 00:31:23,820 But why? 683 00:31:23,820 --> 00:31:27,810 Based on this symptom, what might your instinct 684 00:31:27,810 --> 00:31:33,330 be for what that first line of code is doing for us in the first place? 685 00:31:33,330 --> 00:31:35,370 Why intuitively must it be there? 686 00:31:35,370 --> 00:31:37,290 AUDIENCE: It's how the [INAUDIBLE] functions. 687 00:31:37,290 --> 00:31:38,290 DAVID J. MALAN: Exactly. 688 00:31:38,290 --> 00:31:41,350 It's like importing a library so that you can do things like print things 689 00:31:41,350 --> 00:31:42,137 out on the screen. 690 00:31:42,137 --> 00:31:45,220 Now, in Scratch, you didn't have to do this for most of the puzzle pieces. 691 00:31:45,220 --> 00:31:47,950 But you might recall that partway through week 0, 692 00:31:47,950 --> 00:31:51,640 I went to the Extensions button at the bottom left of the Scratch screen, 693 00:31:51,640 --> 00:31:54,340 and I imported some extra puzzle pieces for text 694 00:31:54,340 --> 00:31:59,170 to speech that gave us the creepy humanized voice that actually came out 695 00:31:59,170 --> 00:32:00,100 of the cat's mouth. 696 00:32:00,100 --> 00:32:02,500 Well, that was like adding a library-- 697 00:32:02,500 --> 00:32:04,390 code that someone else wrote. 698 00:32:04,390 --> 00:32:06,550 In that case, it was a third party. 699 00:32:06,550 --> 00:32:08,380 But I gave myself access to it. 700 00:32:08,380 --> 00:32:09,250 Same here. 701 00:32:09,250 --> 00:32:13,900 Turns out that you don't really get printf automatically in C. 702 00:32:13,900 --> 00:32:17,560 You have to include a so-called header file that 703 00:32:17,560 --> 00:32:20,020 declares that function to exist. 704 00:32:20,020 --> 00:32:22,570 Now, the reason for this historically is just efficiency. 705 00:32:22,570 --> 00:32:26,882 Back in the day when computers were really slower and resource constrained, 706 00:32:26,882 --> 00:32:29,590 you don't want to just give yourself access to the entire kitchen 707 00:32:29,590 --> 00:32:30,610 sink of functionality. 708 00:32:30,610 --> 00:32:34,690 You only want to include only the functions you actually care about. 709 00:32:34,690 --> 00:32:39,180 Nowadays, it's a copy/paste step because you almost always 710 00:32:39,180 --> 00:32:40,930 want to print something out on the screen, 711 00:32:40,930 --> 00:32:42,680 at least when writing programs like these. 712 00:32:42,680 --> 00:32:45,760 But these so-called header files contain enough information 713 00:32:45,760 --> 00:32:50,350 about all of the functions in what's called the Standard I/O Library. 714 00:32:50,350 --> 00:32:53,450 And standard I/O just means standard Input and Output. 715 00:32:53,450 --> 00:32:54,700 And that's appropriate, right? 716 00:32:54,700 --> 00:32:57,010 Because printing is pretty basic output. 717 00:32:57,010 --> 00:32:59,920 Turns out, there's other functions for getting input from the human's 718 00:32:59,920 --> 00:33:01,310 keyboard-- more on that in a bit. 719 00:33:01,310 --> 00:33:03,970 But any time you want to print something on the screen in C, 720 00:33:03,970 --> 00:33:07,630 you indeed need to include this header file at the top of your code. 721 00:33:07,630 --> 00:33:11,350 And that's going to essentially inform the compiler, hey, compiler, 722 00:33:11,350 --> 00:33:15,980 I want to use functionality from the Standard I/O Library, 723 00:33:15,980 --> 00:33:18,320 including printf in this case. 724 00:33:18,320 --> 00:33:20,770 And if you omit the header file by accident, 725 00:33:20,770 --> 00:33:24,040 it's just not going to work because it doesn't know what printf is. 726 00:33:24,040 --> 00:33:27,970 It's some unrecognized symbol in that case. 727 00:33:27,970 --> 00:33:34,320 All right, questions, then, about this line of code, this line of code here, 728 00:33:34,320 --> 00:33:37,590 or what these header files are? 729 00:33:37,590 --> 00:33:40,890 All right, you might wonder, well, how do you know what functions exist? 730 00:33:40,890 --> 00:33:43,990 How do you know what files you might indeed want to include? 731 00:33:43,990 --> 00:33:46,620 Well, it turns out that C is a many-year-old language, 732 00:33:46,620 --> 00:33:48,720 and it has ample documentation. 733 00:33:48,720 --> 00:33:52,770 A caveat is that its documentation isn't necessarily all that user friendly. 734 00:33:52,770 --> 00:33:56,370 But what we have for the course is a simplified version 735 00:33:56,370 --> 00:34:01,680 of the official documentation for C at this URL here, manual.cs50.io. 736 00:34:01,680 --> 00:34:04,380 So in the world of C, and other languages too, 737 00:34:04,380 --> 00:34:06,150 there are what are called manual pages. 738 00:34:06,150 --> 00:34:08,820 And these are just text-based documentation 739 00:34:08,820 --> 00:34:11,010 that, honestly, is typically written in a voice 740 00:34:11,010 --> 00:34:14,560 that you have to be an experienced programmer to understand some of it. 741 00:34:14,560 --> 00:34:17,699 So what we've done in this version of the same documentation 742 00:34:17,699 --> 00:34:20,699 is we've imported all of the original official documentation, 743 00:34:20,699 --> 00:34:24,074 but we've added less comfortable translations in English 744 00:34:24,074 --> 00:34:26,699 for a lot of the functionality that you might use in class just 745 00:34:26,699 --> 00:34:27,713 to help onboard you. 746 00:34:27,713 --> 00:34:30,630 So at the end of the day, you don't need this documentation long term. 747 00:34:30,630 --> 00:34:34,320 But just to get started, we'll translate it into terminology 748 00:34:34,320 --> 00:34:36,630 that you might appreciate from a teaching assistant, 749 00:34:36,630 --> 00:34:39,969 for instance, as opposed to the original author of these documents. 750 00:34:39,969 --> 00:34:42,420 And so, for instance, if you were interested in reading up 751 00:34:42,420 --> 00:34:48,330 on what functions exist in the stdio.h file, well, 752 00:34:48,330 --> 00:34:52,830 you could go to a URL like this, or you could search for it at manual.cs50.io. 753 00:34:52,830 --> 00:34:56,350 That would show you a list of all of the available functions in that library, 754 00:34:56,350 --> 00:34:58,350 and print if indeed would be one of them. 755 00:34:58,350 --> 00:35:00,683 And then you could click further on that, reaching a URL 756 00:35:00,683 --> 00:35:03,475 like this that's going to give you all of the documentation for how 757 00:35:03,475 --> 00:35:04,110 to use printf. 758 00:35:04,110 --> 00:35:07,560 It turns out, you can do even more than just printing out hello, world. 759 00:35:07,560 --> 00:35:09,450 And we'll scratch the surface of that today. 760 00:35:09,450 --> 00:35:12,900 But it turns out that the documentation will always 761 00:35:12,900 --> 00:35:16,680 be your authoritative source ultimately for questions like, what can I do, 762 00:35:16,680 --> 00:35:18,160 and how can I do it? 763 00:35:18,160 --> 00:35:23,010 Meanwhile, it turns out that CS50 has its own library 764 00:35:23,010 --> 00:35:25,980 and accessible via header file called cs50.h. 765 00:35:25,980 --> 00:35:28,530 It turns out in C that output is actually 766 00:35:28,530 --> 00:35:30,750 pretty easy, relatively speaking, once you 767 00:35:30,750 --> 00:35:34,110 get used to all the curly braces, parentheses, quote marks, and the like. 768 00:35:34,110 --> 00:35:36,670 But input is a little more difficult. 769 00:35:36,670 --> 00:35:41,100 And if you have programmed before, input's not that hard to do in Python. 770 00:35:41,100 --> 00:35:42,540 It's not that hard to do in Java. 771 00:35:42,540 --> 00:35:46,312 It's more difficult to do in C. And we'll see why in a couple of weeks. 772 00:35:46,312 --> 00:35:48,270 But for the first couple of weeks of the class, 773 00:35:48,270 --> 00:35:50,880 we actually provide you with some training wheels, 774 00:35:50,880 --> 00:35:53,700 of sorts, whereby we have a number of functions 775 00:35:53,700 --> 00:35:56,430 that are declared in this file, cs50.h. 776 00:35:56,430 --> 00:35:59,220 It lives its documentation at a URL like this. 777 00:35:59,220 --> 00:36:01,230 And in a moment, we'll use a few of these. 778 00:36:01,230 --> 00:36:05,040 You'll see that CS50 provides you with some functions like get_char 779 00:36:05,040 --> 00:36:08,580 for get a single character from the user's keyboard, 780 00:36:08,580 --> 00:36:11,790 get_int to get an integer from the user's keyboard, 781 00:36:11,790 --> 00:36:15,450 get_string to get a sequence of text from the user's keyboard, and a bunch 782 00:36:15,450 --> 00:36:16,930 of others as well. 783 00:36:16,930 --> 00:36:19,920 So let's actually use some of these functions, how about, 784 00:36:19,920 --> 00:36:22,410 by revisiting, really, the second program we 785 00:36:22,410 --> 00:36:26,710 wrote in Scratch last time, which adds some input to the output. 786 00:36:26,710 --> 00:36:28,830 So first version of Scratch was just hello, world. 787 00:36:28,830 --> 00:36:31,200 Said the same thing every time you click the green flag. 788 00:36:31,200 --> 00:36:33,180 Version 2, recall, though, did this. 789 00:36:33,180 --> 00:36:35,190 It asked the user, what's your name? 790 00:36:35,190 --> 00:36:40,870 And then that somehow gave it back a return value, we called it. 791 00:36:40,870 --> 00:36:44,100 And we then joined hello and that name to say something a little more 792 00:36:44,100 --> 00:36:46,420 interesting on the screen. 793 00:36:46,420 --> 00:36:48,420 So what did that model look like? 794 00:36:48,420 --> 00:36:49,560 Same thing as before. 795 00:36:49,560 --> 00:36:52,680 We've got a function in the middle where function is like the code 796 00:36:52,680 --> 00:36:54,480 implementation of our algorithm. 797 00:36:54,480 --> 00:36:56,910 That takes in one or more arguments, like what is it you 798 00:36:56,910 --> 00:37:00,000 want to say on the screen ultimately? 799 00:37:00,000 --> 00:37:03,580 And return value, in this case, is going to be actually a value that comes back. 800 00:37:03,580 --> 00:37:07,660 So in the case of getting input, we can consider this ask block again, 801 00:37:07,660 --> 00:37:08,490 like last week. 802 00:37:08,490 --> 00:37:12,420 The input to it is whatever words of English you want to ask the user. 803 00:37:12,420 --> 00:37:14,670 And then it returns a value. 804 00:37:14,670 --> 00:37:17,550 And this was called by default in MIT'S world answer. 805 00:37:17,550 --> 00:37:20,460 But we'll see in C, you can call these return values anything 806 00:37:20,460 --> 00:37:22,300 you want ultimately in variables. 807 00:37:22,300 --> 00:37:24,100 But this is different from a side effect. 808 00:37:24,100 --> 00:37:27,100 A side effect is just something visual often that happens on the screen, 809 00:37:27,100 --> 00:37:28,980 like the speech bubble or hello, world. 810 00:37:28,980 --> 00:37:32,220 A return value is actually a value you get back from a function 811 00:37:32,220 --> 00:37:34,020 that you can use or reuse. 812 00:37:34,020 --> 00:37:38,400 So how do we convert this Scratch block from last week to C code this week? 813 00:37:38,400 --> 00:37:41,340 Well, if you want to ask the user for something like their name, 814 00:37:41,340 --> 00:37:42,580 you can do this. 815 00:37:42,580 --> 00:37:45,600 You use a CS50 function called get_string. 816 00:37:45,600 --> 00:37:49,950 And you use the parentheses to represent here comes the inputs there too. 817 00:37:49,950 --> 00:37:52,967 You can then put the sentence you want to ask the user-- 818 00:37:52,967 --> 00:37:54,300 quote/unquote, what's your name? 819 00:37:54,300 --> 00:37:57,150 But you do indeed need the quotes literally in C. 820 00:37:57,150 --> 00:37:59,220 So I'll go ahead and add those as well. 821 00:37:59,220 --> 00:38:03,720 Subtle, but I've deliberately included a space after the question mark, 822 00:38:03,720 --> 00:38:06,840 but before the double quote, just so that the cursor 823 00:38:06,840 --> 00:38:08,998 moves one step over because, in this case, 824 00:38:08,998 --> 00:38:11,790 we're not going to get a special speech box like we did in Scratch. 825 00:38:11,790 --> 00:38:14,582 It's just going to leave the cursor where it is, so we'll see that, 826 00:38:14,582 --> 00:38:16,980 aesthetically, that just moves the blinking cursor one 827 00:38:16,980 --> 00:38:19,800 space after the sentence on the screen. 828 00:38:19,800 --> 00:38:21,930 All right, but the catch is with Scratch, 829 00:38:21,930 --> 00:38:25,140 we just automatically got back the answer from the user 830 00:38:25,140 --> 00:38:27,180 in a special variable called answer. 831 00:38:27,180 --> 00:38:30,270 In C, you're going to have to be a little more specific. 832 00:38:30,270 --> 00:38:35,780 In C, If you want to get back a return value from a function like get_string, 833 00:38:35,780 --> 00:38:40,420 you have to use an equal sign and then the name of a variable on the left. 834 00:38:40,420 --> 00:38:42,280 The choice of variables is up to you. 835 00:38:42,280 --> 00:38:44,290 I could have called this anything-- x, y, z. 836 00:38:44,290 --> 00:38:47,470 I'm going to more descriptively call it answer for parity with what 837 00:38:47,470 --> 00:38:48,880 MIT did with Scratch. 838 00:38:48,880 --> 00:38:53,090 But notice that this doesn't represent equality, per se. 839 00:38:53,090 --> 00:38:55,640 This is assignment in this case. 840 00:38:55,640 --> 00:38:58,180 So in C, when you use a single equal sign, 841 00:38:58,180 --> 00:39:01,720 that means copy the value on the right over to the value 842 00:39:01,720 --> 00:39:03,590 on the left-- from right to left. 843 00:39:03,590 --> 00:39:05,390 So what does this do for us? 844 00:39:05,390 --> 00:39:08,170 Well, if get_string is a function that prompts the user with, 845 00:39:08,170 --> 00:39:12,160 quote/unquote, what's your name, and it has I claim a return value, 846 00:39:12,160 --> 00:39:14,750 that means it hands me back some value. 847 00:39:14,750 --> 00:39:17,960 But it's up to me in C to do something with that value. 848 00:39:17,960 --> 00:39:21,520 So if I want to copy that value into a variable that I can use and reuse, 849 00:39:21,520 --> 00:39:25,300 I use an equal sign, and I invent on the left-hand side of that equal sign 850 00:39:25,300 --> 00:39:27,340 any variable name I want. 851 00:39:27,340 --> 00:39:28,450 There are certain rules. 852 00:39:28,450 --> 00:39:29,700 There are certain conventions. 853 00:39:29,700 --> 00:39:32,590 But generally if you use a single word with all lowercase, 854 00:39:32,590 --> 00:39:34,570 you're in good shape. 855 00:39:34,570 --> 00:39:37,040 But C's a little more pedantic than that. 856 00:39:37,040 --> 00:39:38,980 And those of you who have programmed before 857 00:39:38,980 --> 00:39:41,410 might not be used to this, for instance, in Python, which 858 00:39:41,410 --> 00:39:43,330 is a world we'll get to in a few weeks. 859 00:39:43,330 --> 00:39:48,670 You also have to tell C what type of value you're storing. 860 00:39:48,670 --> 00:39:54,370 So if I do want a string of text from the user-- so not an integer, not 861 00:39:54,370 --> 00:39:55,270 a single character. 862 00:39:55,270 --> 00:39:58,430 I want a whole string of text, like a phrase, a sentence, a name, 863 00:39:58,430 --> 00:39:59,270 in this case-- 864 00:39:59,270 --> 00:40:04,250 I have to tell C that this variable is of type string. 865 00:40:04,250 --> 00:40:06,267 So it's a little wordy, but you get used to it. 866 00:40:06,267 --> 00:40:07,600 And you just have to be precise. 867 00:40:07,600 --> 00:40:12,760 You're informing the computer what type of value is going in this variable. 868 00:40:12,760 --> 00:40:15,040 All right, it's so close to being correct, 869 00:40:15,040 --> 00:40:19,210 but I have omitted something that's annoyingly important still. 870 00:40:19,210 --> 00:40:20,470 What's missing still? 871 00:40:20,470 --> 00:40:21,070 Yeah? 872 00:40:21,070 --> 00:40:21,970 AUDIENCE: Semicolon? 873 00:40:21,970 --> 00:40:23,178 DAVID J. MALAN: So semicolon. 874 00:40:23,178 --> 00:40:24,230 This is a statement. 875 00:40:24,230 --> 00:40:27,040 This is like a full thought, if you will. 876 00:40:27,040 --> 00:40:31,680 In Code, I do need to end it ultimately with the semicolon at the end there. 877 00:40:31,680 --> 00:40:33,430 All right, so this was more of a mouthful, 878 00:40:33,430 --> 00:40:35,720 but let's try using this in now my code. 879 00:40:35,720 --> 00:40:40,250 Let me go back to VS Code where I have version 0 of my code here. 880 00:40:40,250 --> 00:40:44,560 Let me go ahead and include one other file at the top of hello.c, 881 00:40:44,560 --> 00:40:48,790 namely include cs50.h so that I have access now 882 00:40:48,790 --> 00:40:51,370 to get_string and anything else I might want. 883 00:40:51,370 --> 00:40:56,710 Now let me go ahead and add a line of code here inside of these curly braces. 884 00:40:56,710 --> 00:40:58,390 And let me go ahead and do this-- 885 00:40:58,390 --> 00:41:03,820 string answer equals get_string, quote/unquote, what's your name, 886 00:41:03,820 --> 00:41:04,847 question mark. 887 00:41:04,847 --> 00:41:07,180 I'm going to add an extra space before the double quote. 888 00:41:07,180 --> 00:41:10,430 I'm going to indeed end my thought with a semicolon. 889 00:41:10,430 --> 00:41:14,260 And now let me deliberately make a mistake, just to make a point here. 890 00:41:14,260 --> 00:41:19,840 Let me now try changing hello, world to hello, comma, answer. 891 00:41:19,840 --> 00:41:22,630 Now, perhaps, even though this is some new lines of code, 892 00:41:22,630 --> 00:41:24,520 you can see where I've errored already. 893 00:41:24,520 --> 00:41:26,980 But let me try making this program now. 894 00:41:26,980 --> 00:41:27,970 So far, so good. 895 00:41:27,970 --> 00:41:29,120 So no error messages. 896 00:41:29,120 --> 00:41:30,140 So that's a good thing. 897 00:41:30,140 --> 00:41:34,000 Let me go ahead and run ./hello, and you'll see the prompt. 898 00:41:34,000 --> 00:41:35,650 What's your name, question mark. 899 00:41:35,650 --> 00:41:37,942 And notice, the cursor is indeed one space to the right 900 00:41:37,942 --> 00:41:39,817 just because I thought it would look prettier 901 00:41:39,817 --> 00:41:42,190 to put a little blank space there as opposed to leaving 902 00:41:42,190 --> 00:41:43,600 it right after the question mark. 903 00:41:43,600 --> 00:41:44,530 Let me type my name. 904 00:41:44,530 --> 00:41:48,340 But even if you've never programmed before, I have screwed up here. 905 00:41:48,340 --> 00:41:51,240 What are we going to see on the screen when I hit Enter? 906 00:41:51,240 --> 00:41:52,240 AUDIENCE: Hello, answer. 907 00:41:52,240 --> 00:41:53,115 DAVID J. MALAN: Yeah. 908 00:41:53,115 --> 00:41:54,280 Hello, answer, most likely. 909 00:41:54,280 --> 00:41:54,730 Why? 910 00:41:54,730 --> 00:41:56,855 Because the computer is going to take me literally. 911 00:41:56,855 --> 00:41:59,020 And if I say, quote/unquote, hello, answer. 912 00:41:59,020 --> 00:42:01,750 That is the string of text followed by a new line that's 913 00:42:01,750 --> 00:42:03,260 going to be outputted to the screen. 914 00:42:03,260 --> 00:42:08,530 So we need some way of actually plugging answer into this line of code. 915 00:42:08,530 --> 00:42:10,330 It's not quite as simple as scratch where 916 00:42:10,330 --> 00:42:14,140 you could just grab a second say block and drag and drop the variable there. 917 00:42:14,140 --> 00:42:15,670 We actually need a new syntax. 918 00:42:15,670 --> 00:42:18,250 And it's going to look weird at first, but it is everywhere 919 00:42:18,250 --> 00:42:22,900 in software nowadays, especially in the world of C and certain other languages. 920 00:42:22,900 --> 00:42:27,610 So let me go ahead and propose that I solve it as follows. 921 00:42:27,610 --> 00:42:31,450 Well, back when we did this in Scratch, remember that the most elegant solution 922 00:42:31,450 --> 00:42:32,350 was this here. 923 00:42:32,350 --> 00:42:36,550 We used the say block still, which is going to be analogous to printf today. 924 00:42:36,550 --> 00:42:41,630 But I use the join puzzle piece and Scratch to combine hello, comma, space, 925 00:42:41,630 --> 00:42:43,340 and then the name of the human. 926 00:42:43,340 --> 00:42:45,790 So how do we translate this code to C? 927 00:42:45,790 --> 00:42:47,830 Well, it's going to look a little different now. 928 00:42:47,830 --> 00:42:51,700 I'm going to start with printf with some parentheses and a semicolon 929 00:42:51,700 --> 00:42:53,530 representing the say block. 930 00:42:53,530 --> 00:42:55,240 But how do I now do this joining? 931 00:42:55,240 --> 00:42:58,330 This is where the puzzle pieces don't quite translate perfectly. 932 00:42:58,330 --> 00:43:00,290 This would be the way to do this. 933 00:43:00,290 --> 00:43:03,430 You put hello, comma, and then a placeholder. 934 00:43:03,430 --> 00:43:07,810 So this is what's known as a format code in C, specifically for printf. 935 00:43:07,810 --> 00:43:11,350 And it just means this is a placeholder for a string. 936 00:43:11,350 --> 00:43:12,740 Again, a string is just text. 937 00:43:12,740 --> 00:43:17,120 So this means, hey, computer, print out literally, hello, comma, space, 938 00:43:17,120 --> 00:43:23,200 and then not literally %s. %s is treated specially to mean plug in some value 939 00:43:23,200 --> 00:43:23,903 here. 940 00:43:23,903 --> 00:43:25,570 All right, so what else do I still need? 941 00:43:25,570 --> 00:43:28,030 Well, this is still some text, so I'm still 942 00:43:28,030 --> 00:43:32,460 going to surround the whole thing with double quotes. 943 00:43:32,460 --> 00:43:35,220 I'm still going to include my backslash n just 944 00:43:35,220 --> 00:43:37,870 to keep things tidy and move the cursor to the next line. 945 00:43:37,870 --> 00:43:45,120 So the last step here in C is to somehow join the answer with that word hello. 946 00:43:45,120 --> 00:43:49,980 And the way you do this is with printf, passing it not one argument, which 947 00:43:49,980 --> 00:43:51,000 is what I keep doing. 948 00:43:51,000 --> 00:43:53,820 I keep passing it one string of text, quote/unquote. 949 00:43:53,820 --> 00:43:58,320 I'm going to now add a comma and then the name of the value that I want 950 00:43:58,320 --> 00:44:02,760 printf to go back and plug into that %s. 951 00:44:02,760 --> 00:44:04,410 And printf is just smart about this. 952 00:44:04,410 --> 00:44:09,390 If you have one %s and one additional argument after a comma, it just does-- 953 00:44:09,390 --> 00:44:10,980 from right to left, it plugs it in. 954 00:44:10,980 --> 00:44:16,470 If you have two %s's and two variables after the comma, that's OK too. 955 00:44:16,470 --> 00:44:19,860 If you separate them with commas, it'll plug the first into the first %s 956 00:44:19,860 --> 00:44:22,380 and the second variable into the second %s. 957 00:44:22,380 --> 00:44:24,750 So it's just left to right, order of operations. 958 00:44:24,750 --> 00:44:30,302 It's not as pretty or as simple as this, but this is how it's done in C. 959 00:44:30,302 --> 00:44:32,760 All right, let me pause because this is a lot of symbology. 960 00:44:32,760 --> 00:44:35,080 Any questions on this technique here? 961 00:44:35,080 --> 00:44:35,580 Yeah? 962 00:44:35,580 --> 00:44:39,725 AUDIENCE: Why did you exclude the backslash n in the previous section? 963 00:44:39,725 --> 00:44:41,600 DAVID J. MALAN: Yeah, a really good question. 964 00:44:41,600 --> 00:44:45,550 Why did I exclude the backslash n a moment ago? 965 00:44:45,550 --> 00:44:48,280 Really, just my sense of aesthetics, if you will. 966 00:44:48,280 --> 00:44:49,760 No good reason beyond that. 967 00:44:49,760 --> 00:44:52,210 So if I look back at my code, you quite rightly 968 00:44:52,210 --> 00:44:54,460 notice that I didn't have a backslash n there. 969 00:44:54,460 --> 00:44:57,400 That's just because, for whatever sense of style that I have, 970 00:44:57,400 --> 00:45:00,460 I wanted the name to be typed right after the question. 971 00:45:00,460 --> 00:45:04,030 I totally could have added a backslash n there instead of a space. 972 00:45:04,030 --> 00:45:06,490 That would have just allowed me to type down here. 973 00:45:06,490 --> 00:45:07,490 Totally fine. 974 00:45:07,490 --> 00:45:09,670 Just wanted to show you something different. 975 00:45:09,670 --> 00:45:10,210 Good catch. 976 00:45:10,210 --> 00:45:10,660 Yeah? 977 00:45:10,660 --> 00:45:12,070 AUDIENCE: Can you show an example with two %s's? 978 00:45:12,070 --> 00:45:14,470 DAVID J. MALAN: Can I show an example with two %s's? 979 00:45:14,470 --> 00:45:15,250 Surely. 980 00:45:15,250 --> 00:45:17,570 So let me in VS Code do this. 981 00:45:17,570 --> 00:45:20,050 Let me clear my terminal window to clean things up. 982 00:45:20,050 --> 00:45:21,170 And let me do this. 983 00:45:21,170 --> 00:45:23,620 Instead of calling the variable answer all over the place, 984 00:45:23,620 --> 00:45:26,080 let me call it first. 985 00:45:26,080 --> 00:45:27,490 And I'll ask two questions. 986 00:45:27,490 --> 00:45:28,880 What's your first name? 987 00:45:28,880 --> 00:45:32,620 And now let me do string last equals get_string-- 988 00:45:32,620 --> 00:45:35,560 whoops, capitalization matters, so let me fix my capital S 989 00:45:35,560 --> 00:45:41,720 there-- quote/unquote, What's your last name, question mark, semicolon. 990 00:45:41,720 --> 00:45:47,320 And now we'll plug in one %s and a second %s. 991 00:45:47,320 --> 00:45:52,720 And now I'm going to plug in first first and last last, coincidentally. 992 00:45:52,720 --> 00:45:55,240 And now I'm going to go back to the terminal window. 993 00:45:55,240 --> 00:46:00,280 Make hello-- crossing my fingers, all good-- ./hello. 994 00:46:00,280 --> 00:46:02,620 Here's my first question, David. 995 00:46:02,620 --> 00:46:04,240 Here's my second question, Malan. 996 00:46:04,240 --> 00:46:05,650 And again? 997 00:46:05,650 --> 00:46:06,670 Hello, David Malan. 998 00:46:06,670 --> 00:46:08,440 So it just inserts them left to right. 999 00:46:08,440 --> 00:46:10,510 All I was doing for parity with Scratch though-- 1000 00:46:10,510 --> 00:46:12,670 and let me go ahead and undo this again. 1001 00:46:12,670 --> 00:46:15,130 I'll go back to answer, like this. 1002 00:46:15,130 --> 00:46:17,800 I'll go back to just asking for the person's name. 1003 00:46:17,800 --> 00:46:19,300 I'm going to delete mention of last. 1004 00:46:19,300 --> 00:46:21,520 I'm going to delete mention of the second %s. 1005 00:46:21,520 --> 00:46:24,400 And now if I recompile this simpler version, 1006 00:46:24,400 --> 00:46:27,720 oh, I did screw up-- didn't intend it. 1007 00:46:27,720 --> 00:46:29,220 What did I do wrong? 1008 00:46:29,220 --> 00:46:31,353 AUDIENCE: You forgot to change first in line 7. 1009 00:46:31,353 --> 00:46:33,270 DAVID J. MALAN: Yeah, so just newbie mistakes. 1010 00:46:33,270 --> 00:46:37,800 So I changed my variable back to answer just to be consistent with week 0, 1011 00:46:37,800 --> 00:46:39,610 but I didn't change it here. 1012 00:46:39,610 --> 00:46:42,750 So I have an use of undeclared identifier first. 1013 00:46:42,750 --> 00:46:46,470 It's undeclared in the sense that I declared answer a line prior. 1014 00:46:46,470 --> 00:46:47,950 I didn't declare first. 1015 00:46:47,950 --> 00:46:51,060 So indeed, intuitively, I want to just change that to that. 1016 00:46:51,060 --> 00:46:56,740 Let me now do make hello again, ./hello, type in just my first name this time. 1017 00:46:56,740 --> 00:46:59,400 And there it is-- hello, David. 1018 00:46:59,400 --> 00:47:02,220 Questions on this then syntax with printf? 1019 00:47:02,220 --> 00:47:03,390 Yeah? 1020 00:47:03,390 --> 00:47:04,608 AUDIENCE: [INAUDIBLE] 1021 00:47:04,608 --> 00:47:06,150 DAVID J. MALAN: Ah, the placeholder-- 1022 00:47:06,150 --> 00:47:09,240 I'll zoom in-- is just a single percent then an s. 1023 00:47:09,240 --> 00:47:17,370 So inside of my string here is %s, and then I have a comma outside the quotes, 1024 00:47:17,370 --> 00:47:23,400 and then the name of the variable whose value I want to plug in for that %s. 1025 00:47:23,400 --> 00:47:28,080 And now notice there's technically two commas inside 1026 00:47:28,080 --> 00:47:30,300 of these parentheses on line 7. 1027 00:47:30,300 --> 00:47:33,690 And yet, I claim that printf, at the moment, 1028 00:47:33,690 --> 00:47:37,290 is only taking in two arguments. 1029 00:47:37,290 --> 00:47:41,582 Why is there then two commas but only two arguments? 1030 00:47:41,582 --> 00:47:43,290 If there were two commas, you would think 1031 00:47:43,290 --> 00:47:45,700 there would be three arguments, right? 1032 00:47:45,700 --> 00:47:47,904 AUDIENCE: The comma is between the quotes, 1033 00:47:47,904 --> 00:47:49,700 so it counts as a comma [INAUDIBLE] 1034 00:47:49,700 --> 00:47:50,700 DAVID J. MALAN: Exactly. 1035 00:47:50,700 --> 00:47:53,160 The comma in between the quotes is just an English thing. 1036 00:47:53,160 --> 00:47:55,240 It's separating the hello from the name. 1037 00:47:55,240 --> 00:47:57,690 So that's why indeed it's not only in quotes, 1038 00:47:57,690 --> 00:48:01,710 that's also why programs like VS Code tend to syntax highlight it 1039 00:48:01,710 --> 00:48:05,580 a little differently just so that it jumps out as different to you, 1040 00:48:05,580 --> 00:48:08,790 even though, in this case, it's a little subtle-- a light blue versus white-- 1041 00:48:08,790 --> 00:48:10,830 but indeed, it's trying its best. 1042 00:48:10,830 --> 00:48:13,150 Other questions now on this placeholder? 1043 00:48:13,150 --> 00:48:13,650 Yeah? 1044 00:48:13,650 --> 00:48:16,390 AUDIENCE: If you wanted to put an exclamation point at the end, 1045 00:48:16,390 --> 00:48:18,460 would you put a comma after your answer variable, 1046 00:48:18,460 --> 00:48:21,943 and would that put it [INAUDIBLE],, or would you have to add a new line? 1047 00:48:21,943 --> 00:48:23,360 DAVID J. MALAN: Ah, good question. 1048 00:48:23,360 --> 00:48:25,750 If I wanted to add an exclamation point after the name, 1049 00:48:25,750 --> 00:48:28,230 would I have to add another placeholder and so forth? 1050 00:48:28,230 --> 00:48:29,980 I could actually do that much more simply. 1051 00:48:29,980 --> 00:48:33,610 I can just put the exclamation point right after the percent sign. 1052 00:48:33,610 --> 00:48:35,830 I don't need an additional placeholder, per se. 1053 00:48:35,830 --> 00:48:40,030 If I zoom out now and run make hello again, ./hello, 1054 00:48:40,030 --> 00:48:42,280 and type in just my name-- no exclamation point-- 1055 00:48:42,280 --> 00:48:45,580 now you'll see more excitedly, hello, comma, David. 1056 00:48:45,580 --> 00:48:46,510 So printf is smart. 1057 00:48:46,510 --> 00:48:51,400 It will figure out where the %s is and then go and replace it. 1058 00:48:51,400 --> 00:48:54,662 Now, let me propose that a common thing in programming 1059 00:48:54,662 --> 00:48:57,370 is that as soon as we make a decision as how to design something, 1060 00:48:57,370 --> 00:49:01,240 we often paint ourselves into a corner and regret a decision. 1061 00:49:01,240 --> 00:49:08,410 Can anyone think of a problem that arises from using %s as a placeholder 1062 00:49:08,410 --> 00:49:11,680 in this string to printf? 1063 00:49:11,680 --> 00:49:14,635 What could go wrong if we're using percent in this special way? 1064 00:49:14,635 --> 00:49:16,775 AUDIENCE: [INAUDIBLE] 1065 00:49:16,775 --> 00:49:17,650 DAVID J. MALAN: Yeah. 1066 00:49:17,650 --> 00:49:20,320 If you literally want to say, for whatever weird reason, 1067 00:49:20,320 --> 00:49:23,245 %s on the screen-- or honestly, even just a single %. 1068 00:49:23,245 --> 00:49:25,930 It turns out that a percent sign is treated 1069 00:49:25,930 --> 00:49:29,650 specially inside of printf strings. 1070 00:49:29,650 --> 00:49:31,460 So what's the solution here? 1071 00:49:31,460 --> 00:49:34,690 There's different patterns of solutions to problems like these. 1072 00:49:34,690 --> 00:49:40,990 But suppose you wanted to say, I got 100%, for instance. 1073 00:49:40,990 --> 00:49:43,480 Let me go ahead and change this completely. 1074 00:49:43,480 --> 00:49:47,290 So I got 100% on your test or whatever. 1075 00:49:47,290 --> 00:49:50,860 All right, let me go ahead and run make hello, Enter. 1076 00:49:50,860 --> 00:49:52,950 All right, so invalid conversions specifier. 1077 00:49:52,950 --> 00:49:55,450 I mean, I have no idea what this means, but it's underlining 1078 00:49:55,450 --> 00:49:57,410 the percent sign as problematic. 1079 00:49:57,410 --> 00:50:00,730 Well, it turns out that humans years ago decided, ugh, all right, damn it. 1080 00:50:00,730 --> 00:50:01,615 We already used %. 1081 00:50:01,615 --> 00:50:04,990 Well, two percent signs will mean one %, literally. 1082 00:50:04,990 --> 00:50:09,727 So now if I rerun make hello, aha, ./hello, I got 100%. 1083 00:50:09,727 --> 00:50:13,060 So there's going to be things like that, honestly, that you have to ask someone, 1084 00:50:13,060 --> 00:50:15,190 you have to Google, you have to look it up in the documentation. 1085 00:50:15,190 --> 00:50:17,840 But there's always a solution to those kinds of problems. 1086 00:50:17,840 --> 00:50:19,930 And thankfully, they don't come up all that often. 1087 00:50:19,930 --> 00:50:21,230 Yeah? 1088 00:50:21,230 --> 00:50:22,360 Oh, just pointing. 1089 00:50:22,360 --> 00:50:23,060 Other questions? 1090 00:50:23,060 --> 00:50:23,560 Yeah? 1091 00:50:23,560 --> 00:50:27,622 AUDIENCE: So if you have multiple [INAUDIBLE] 1092 00:50:27,622 --> 00:50:29,580 DAVID J. MALAN: If you have multiple variables, 1093 00:50:29,580 --> 00:50:31,380 it is in the left-right order. 1094 00:50:31,380 --> 00:50:34,187 So printf will analyze the first string of text 1095 00:50:34,187 --> 00:50:35,520 that you pass in between quotes. 1096 00:50:35,520 --> 00:50:40,290 And whatever the first % is, the first variable that's passed in after a comma 1097 00:50:40,290 --> 00:50:41,207 gets plugged in there. 1098 00:50:41,207 --> 00:50:44,290 And then the second gets plugged into the second, third, and to the third, 1099 00:50:44,290 --> 00:50:44,832 and so forth. 1100 00:50:44,832 --> 00:50:47,130 So it's just based on left to right. 1101 00:50:47,130 --> 00:50:48,220 Yeah? 1102 00:50:48,220 --> 00:50:50,760 AUDIENCE: This more of a clarification question. 1103 00:50:50,760 --> 00:50:52,453 What exactly does the %s mean? 1104 00:50:52,453 --> 00:50:54,120 DAVID J. MALAN: It's just a placeholder. 1105 00:50:54,120 --> 00:50:58,570 It's called a format code, and it just means colloquially, plug in some value 1106 00:50:58,570 --> 00:50:59,070 here. 1107 00:50:59,070 --> 00:51:04,060 And printf-- the humans who wrote printf decades ago decided to treat %s 1108 00:51:04,060 --> 00:51:04,560 special. 1109 00:51:04,560 --> 00:51:04,890 Why? 1110 00:51:04,890 --> 00:51:05,490 Just because. 1111 00:51:05,490 --> 00:51:06,900 They needed some placeholder. 1112 00:51:06,900 --> 00:51:10,110 They decided that, eh, no one's ever going to really want to type %s. 1113 00:51:10,110 --> 00:51:12,420 And if they do, they can just do %%s. 1114 00:51:12,420 --> 00:51:17,280 So they decided to implement printf in such a way that they have code that 1115 00:51:17,280 --> 00:51:20,190 analyzes whatever text comes in, looks for %s, 1116 00:51:20,190 --> 00:51:24,960 and then somehow plugs in the subsequent values into that placeholder. 1117 00:51:24,960 --> 00:51:28,390 And just the-- ah, question? 1118 00:51:28,390 --> 00:51:28,890 Sorry? 1119 00:51:28,890 --> 00:51:30,870 AUDIENCE: What if we wanted to do our initials or something? 1120 00:51:30,870 --> 00:51:33,720 DAVID J. MALAN: Ah, so what if you wanted to do a single characters, 1121 00:51:33,720 --> 00:51:38,070 like initials, like D M or D J M for first, middle, last, absolutely. 1122 00:51:38,070 --> 00:51:41,670 And that, too, is a perfect segue from the two of you to what, in general, 1123 00:51:41,670 --> 00:51:44,310 are going to be called data types in C. 1124 00:51:44,310 --> 00:51:48,135 So it turns out, in C, there's not only strings as text. 1125 00:51:48,135 --> 00:51:50,760 And we'll see in more detail over the next couple of weeks what 1126 00:51:50,760 --> 00:51:52,560 a string really is underneath the hood. 1127 00:51:52,560 --> 00:51:55,620 But strings of text are not the only thing that programs can output. 1128 00:51:55,620 --> 00:51:58,860 They can indeed output single characters, as for initials. 1129 00:51:58,860 --> 00:52:01,020 They can output integers as well. 1130 00:52:01,020 --> 00:52:03,510 Turns out that printf has different format codes 1131 00:52:03,510 --> 00:52:05,868 for all sorts of different data types. 1132 00:52:05,868 --> 00:52:08,410 And just some of the data types we'll see in the coming weeks 1133 00:52:08,410 --> 00:52:10,530 will be this list here, which you'll notice it 1134 00:52:10,530 --> 00:52:13,920 almost perfectly lines up with the CS50 functions 1135 00:52:13,920 --> 00:52:17,722 that I rattled off earlier, like get_char, get_int, get_string. 1136 00:52:17,722 --> 00:52:20,430 The reason we called those functions that is because each of them 1137 00:52:20,430 --> 00:52:23,490 is designed to return to you a different type of value. 1138 00:52:23,490 --> 00:52:26,070 We've used get_string already in this example here. 1139 00:52:26,070 --> 00:52:29,880 We'll soon see get_int, and we'll see opportunities to use others. 1140 00:52:29,880 --> 00:52:33,660 But these indeed are the menu of available data 1141 00:52:33,660 --> 00:52:35,940 types plus others-- dot, dot, dot-- that you 1142 00:52:35,940 --> 00:52:38,400 can use when writing a program in C. 1143 00:52:38,400 --> 00:52:41,430 The onus, therefore, is on you to decide in advance, 1144 00:52:41,430 --> 00:52:44,250 do I want to store an int in this variable, or a string, 1145 00:52:44,250 --> 00:52:48,420 or, heck, when writing fancier code, an image, or a sound, or a video, even. 1146 00:52:48,420 --> 00:52:51,030 Those can all be different data types, dot dot dot. 1147 00:52:51,030 --> 00:52:54,300 But for now we'll focus really on just these primitives. 1148 00:52:54,300 --> 00:52:54,988 That was a lot. 1149 00:52:54,988 --> 00:52:57,030 Let's go ahead and take a five-minute break here. 1150 00:52:57,030 --> 00:52:57,680 No cookies yet. 1151 00:52:57,680 --> 00:53:00,180 But in five minutes, we'll come back, dive into more detail. 1152 00:53:00,180 --> 00:53:02,097 On our second break today, we'll have cookies. 1153 00:53:02,097 --> 00:53:05,640 1154 00:53:05,640 --> 00:53:07,295 All right, we are back. 1155 00:53:07,295 --> 00:53:09,170 And so if you have been playing along at home 1156 00:53:09,170 --> 00:53:11,587 but hitting some bumps in the road, that's totally normal. 1157 00:53:11,587 --> 00:53:13,430 And indeed, the goals of lecture generally 1158 00:53:13,430 --> 00:53:16,395 will be to give you a sense, conceptually, of where we'll 1159 00:53:16,395 --> 00:53:18,020 be going during the course of the week. 1160 00:53:18,020 --> 00:53:20,498 But it's indeed through the hands-on labs and problem sets 1161 00:53:20,498 --> 00:53:22,790 that you'll really have an opportunity at your own pace 1162 00:53:22,790 --> 00:53:25,730 to work through some of those same bumps in the road. 1163 00:53:25,730 --> 00:53:28,880 But for today, let me give you a few more building blocks. 1164 00:53:28,880 --> 00:53:31,460 And these two will translate from Scratch initially. 1165 00:53:31,460 --> 00:53:33,860 Namely, like conditionals, like how now in C, 1166 00:53:33,860 --> 00:53:36,690 after knowing now how we can use functions-- 1167 00:53:36,690 --> 00:53:39,530 at least get_string and printf-- 1168 00:53:39,530 --> 00:53:43,370 and we can use variables like the string I created earlier, 1169 00:53:43,370 --> 00:53:46,490 how can I now add to the mix things like decision making and conditionals 1170 00:53:46,490 --> 00:53:47,100 at that? 1171 00:53:47,100 --> 00:53:50,780 Well, with conditionals in Scratch, we had this kind of syntax on the left. 1172 00:53:50,780 --> 00:53:55,220 Here in Scratch is how you might express if two variables, x and y, 1173 00:53:55,220 --> 00:53:56,360 have this relationship. 1174 00:53:56,360 --> 00:54:01,020 If x is less than y, then say on the screen, x is less than y. 1175 00:54:01,020 --> 00:54:03,320 Well, let me translate that to the right now in C code. 1176 00:54:03,320 --> 00:54:06,500 So in C, the corresponding code is going to look like this, 1177 00:54:06,500 --> 00:54:08,390 assuming x and y already exist-- 1178 00:54:08,390 --> 00:54:09,530 more on that later. 1179 00:54:09,530 --> 00:54:13,140 And notice a pattern we're going to see again and again. 1180 00:54:13,140 --> 00:54:18,560 There is going to be parentheses around the x and less than y-- so parentheses 1181 00:54:18,560 --> 00:54:20,390 around the Boolean expression, recall. 1182 00:54:20,390 --> 00:54:23,768 The Boolean expression is the true/false, the yes/no answer, 1183 00:54:23,768 --> 00:54:26,060 a question that you're trying to ask in order to decide 1184 00:54:26,060 --> 00:54:27,680 whether or not to do something. 1185 00:54:27,680 --> 00:54:29,310 So you use parentheses there. 1186 00:54:29,310 --> 00:54:34,550 So similar in functions where we use parentheses for printf and parentheses 1187 00:54:34,550 --> 00:54:38,660 for get_string, and this is just a weird inconsistency stylistically. 1188 00:54:38,660 --> 00:54:42,860 When using the keyword if, you should, as a matter of best practice, 1189 00:54:42,860 --> 00:54:44,690 put a space after the word if. 1190 00:54:44,690 --> 00:54:49,070 When using a function like printf or get_string, you shouldn't. 1191 00:54:49,070 --> 00:54:52,400 Both will work, but you'll find that these are conventions stylistically 1192 00:54:52,400 --> 00:54:55,970 that most people adhere to-- so space when using an if here. 1193 00:54:55,970 --> 00:54:58,850 All right, now inside of the curly braces 1194 00:54:58,850 --> 00:55:02,360 is where the actual code goes that you want to execute conditionally. 1195 00:55:02,360 --> 00:55:05,270 So if you want to print out x is less than y 1196 00:55:05,270 --> 00:55:08,570 only if x is actually less than y in C, you 1197 00:55:08,570 --> 00:55:10,670 use this open curly brace-- which, up until now, 1198 00:55:10,670 --> 00:55:12,740 you've probably rarely used on your keyboard-- 1199 00:55:12,740 --> 00:55:14,820 and the closed curly brace down here. 1200 00:55:14,820 --> 00:55:17,960 And those are hugging, if you will, the one or more lines 1201 00:55:17,960 --> 00:55:20,990 of code underneath the if-- very similar in spirit 1202 00:55:20,990 --> 00:55:25,050 to how the orange block here hugs the purple puzzle piece here. 1203 00:55:25,050 --> 00:55:27,050 So there's no graphics in C. It's all text. 1204 00:55:27,050 --> 00:55:31,760 So you can think of those curly braces as really representing the same idea. 1205 00:55:31,760 --> 00:55:37,460 As a side note, if you only have one line of code inside of the if 1206 00:55:37,460 --> 00:55:41,430 condition, if you will, you strictly, speaking, don't need the curly braces. 1207 00:55:41,430 --> 00:55:43,670 But as a matter of good style, do include them. 1208 00:55:43,670 --> 00:55:46,040 It will make more obvious what your intent is. 1209 00:55:46,040 --> 00:55:48,650 How about in Scratch if you wanted to express this-- 1210 00:55:48,650 --> 00:55:52,700 two ways in the road that you might go, left or right, so to speak? 1211 00:55:52,700 --> 00:55:56,480 Well, if x is less than y, I want to say, x is less than y. 1212 00:55:56,480 --> 00:56:01,190 Else, I want to say the opposite, x is not less than y in this case. 1213 00:56:01,190 --> 00:56:03,710 So I'm making a decision based on that Boolean expression. 1214 00:56:03,710 --> 00:56:08,340 In C, It's almost the same, but you're adding to the mix the key word else-- 1215 00:56:08,340 --> 00:56:11,210 so MIT borrowed for Scratch the same keyword there-- 1216 00:56:11,210 --> 00:56:14,690 and a second pair of curly braces, open and close respectively. 1217 00:56:14,690 --> 00:56:17,150 And you might guess now what goes inside of those. 1218 00:56:17,150 --> 00:56:22,905 Well, you print out x is less than y, or you print out x is not less than y. 1219 00:56:22,905 --> 00:56:25,280 All right, what if there is a three-way fork in the road? 1220 00:56:25,280 --> 00:56:29,370 In Scratch, this actually gets a little unwieldy graphically, if you will. 1221 00:56:29,370 --> 00:56:34,490 But notice that in Scratch, this is how we could express if x is less than y, 1222 00:56:34,490 --> 00:56:36,110 say x is less than y. 1223 00:56:36,110 --> 00:56:40,760 Else if x is greater than y, say x is greater than y. 1224 00:56:40,760 --> 00:56:45,470 Else if x equals y, then say x is equal to y. 1225 00:56:45,470 --> 00:56:48,770 Now, minor inconsistency here. 1226 00:56:48,770 --> 00:56:51,980 Just a little bit ago, I claimed, in C, that an equal sign 1227 00:56:51,980 --> 00:56:54,435 represents what operation? 1228 00:56:54,435 --> 00:56:55,310 AUDIENCE: Assignment. 1229 00:56:55,310 --> 00:56:57,770 DAVID J. MALAN: Assignment from right to left. 1230 00:56:57,770 --> 00:56:59,900 Insofar as Scratch is really meant for kids, 1231 00:56:59,900 --> 00:57:03,350 and they didn't really want to get into the weeds of this kind of semantic, 1232 00:57:03,350 --> 00:57:06,360 equal sign in Scratch means equality. 1233 00:57:06,360 --> 00:57:09,050 However, we're going to need to fix this in C in just a moment. 1234 00:57:09,050 --> 00:57:11,750 In C, equal sign means assignment right to left. 1235 00:57:11,750 --> 00:57:14,210 In Scratch, it literally means what you would expect. 1236 00:57:14,210 --> 00:57:17,690 All right, let's translate this code then to C. On the right, 1237 00:57:17,690 --> 00:57:20,780 this code would correspond really to this. 1238 00:57:20,780 --> 00:57:24,110 And you can perhaps see, somewhat goofily, what the solution was, 1239 00:57:24,110 --> 00:57:28,160 not unlike the %% solution earlier when humans painted themselves into one 1240 00:57:28,160 --> 00:57:29,100 other corner. 1241 00:57:29,100 --> 00:57:32,900 You say if, you say else if, and you say else if, 1242 00:57:32,900 --> 00:57:36,620 and how did we resolve the use of a single equal sign already? 1243 00:57:36,620 --> 00:57:39,650 In C, when you want to express equality-- 1244 00:57:39,650 --> 00:57:42,110 is the thing on the left equal to the thing on the right-- 1245 00:57:42,110 --> 00:57:45,590 you literally use two equal signs right next to each other, no space 1246 00:57:45,590 --> 00:57:47,090 in between them. 1247 00:57:47,090 --> 00:57:50,960 But now this code would be correct on both the left and the right, 1248 00:57:50,960 --> 00:57:53,640 whether you're doing this in Scratch or C respectively. 1249 00:57:53,640 --> 00:57:58,400 But now we can nitpick our code, specifically the design thereof. 1250 00:57:58,400 --> 00:58:02,820 Logically, can anyone critique the design of this code, 1251 00:58:02,820 --> 00:58:04,280 either in Scratch or C? 1252 00:58:04,280 --> 00:58:06,200 I feel like we could do better. 1253 00:58:06,200 --> 00:58:07,576 How about in back? 1254 00:58:07,576 --> 00:58:10,908 AUDIENCE: The only option after it getting greater than or less 1255 00:58:10,908 --> 00:58:12,930 than is [INAUDIBLE]. 1256 00:58:12,930 --> 00:58:13,930 DAVID J. MALAN: Perfect. 1257 00:58:13,930 --> 00:58:17,350 Logically, it's got to be the case that x is less than y, 1258 00:58:17,350 --> 00:58:22,510 or x is greater than y, or by conclusion, it's got to be equal to y. 1259 00:58:22,510 --> 00:58:24,910 So why are you wasting my time or the computer's time 1260 00:58:24,910 --> 00:58:26,170 asking a third question? 1261 00:58:26,170 --> 00:58:30,160 You don't need to ask this final else if because logically, as you note, 1262 00:58:30,160 --> 00:58:31,510 it should go without saying. 1263 00:58:31,510 --> 00:58:33,220 So it's a minor tweak. 1264 00:58:33,220 --> 00:58:37,120 You're doing extra work potentially in the cases where x equals y. 1265 00:58:37,120 --> 00:58:38,350 So we can just refine that. 1266 00:58:38,350 --> 00:58:42,280 And just like in Scratch, you could just use an else block, similarly in C, 1267 00:58:42,280 --> 00:58:47,110 could we simplify this code to just an else, a sort of catch-all logically 1268 00:58:47,110 --> 00:58:49,720 that just handles the reality that, of course, that's going 1269 00:58:49,720 --> 00:58:52,400 to be the final situation instead. 1270 00:58:52,400 --> 00:58:55,570 All right, so we have this ability now to express conditionals 1271 00:58:55,570 --> 00:58:56,770 with Boolean expressions. 1272 00:58:56,770 --> 00:58:59,030 Let's actually do something with this next here. 1273 00:58:59,030 --> 00:59:00,610 So let me go back to VS Code. 1274 00:59:00,610 --> 00:59:03,520 I've closed hello.c, and I want to create a second file 1275 00:59:03,520 --> 00:59:05,020 for the sake of some demos now. 1276 00:59:05,020 --> 00:59:09,160 Recall that you can create a new files by typing code, space, and then 1277 00:59:09,160 --> 00:59:11,440 the name of the file you want to create. 1278 00:59:11,440 --> 00:59:13,565 For instance, I might do compare.c. 1279 00:59:13,565 --> 00:59:15,940 I want to write a program that's going to start comparing 1280 00:59:15,940 --> 00:59:17,740 some values for demonstration's sake. 1281 00:59:17,740 --> 00:59:20,050 But before I do that, let me just show you 1282 00:59:20,050 --> 00:59:23,830 by opening the File Explorer at right, this is similar in spirit 1283 00:59:23,830 --> 00:59:25,180 to a Mac or PC. 1284 00:59:25,180 --> 00:59:28,750 You can go up here and click on an icon, and you can click on the plus icon, 1285 00:59:28,750 --> 00:59:30,010 and you'll get a blue box. 1286 00:59:30,010 --> 00:59:34,120 And I can type in compare.c, and I can just manually create it that way. 1287 00:59:34,120 --> 00:59:37,930 Notice that opens the tab even without my having typed code. 1288 00:59:37,930 --> 00:59:41,470 So again, on the left, you have a GUI, a Graphical User Interface, 1289 00:59:41,470 --> 00:59:42,820 albeit a simplistic one. 1290 00:59:42,820 --> 00:59:45,970 On the right and at the bottom here, you have a command line interface, 1291 00:59:45,970 --> 00:59:47,260 but they're one in the same. 1292 00:59:47,260 --> 00:59:52,090 What's nice, though, is that if I close this file accidentally, intentionally, 1293 00:59:52,090 --> 00:59:54,790 whatnot, I can reopen it without creating 1294 00:59:54,790 --> 00:59:58,930 a new one by just running that same command-- code, space, compare.c. 1295 00:59:58,930 --> 01:00:00,340 So code is a VS Code thing. 1296 01:00:00,340 --> 01:00:02,140 It's just a user-friendly shortcut. 1297 01:00:02,140 --> 01:00:05,888 But it's just creating a file or opening an existing file like that. 1298 01:00:05,888 --> 01:00:08,930 I'm going to hide the File Explorer just to make more room for code here. 1299 01:00:08,930 --> 01:00:10,222 And let's go ahead and do this. 1300 01:00:10,222 --> 01:00:14,200 Let's write a program that compares two values that the human inputs, 1301 01:00:14,200 --> 01:00:15,340 but not strings this time. 1302 01:00:15,340 --> 01:00:17,170 Let's use some actual integers. 1303 01:00:17,170 --> 01:00:20,920 All right, I'm going to go ahead and include the CS50 library's header 1304 01:00:20,920 --> 01:00:22,090 file at top-- 1305 01:00:22,090 --> 01:00:23,260 cs50.h. 1306 01:00:23,260 --> 01:00:25,804 I'm going to also include stdio.h. 1307 01:00:25,804 --> 01:00:26,668 Why? 1308 01:00:26,668 --> 01:00:31,190 One gives me user-friendly input via get_string, get_int, and so forth. 1309 01:00:31,190 --> 01:00:35,560 One gives me user-friendly output via printf in the case of stdio.h. 1310 01:00:35,560 --> 01:00:39,430 Now I'm just going to blindly type this line of code, which we'll come back to 1311 01:00:39,430 --> 01:00:40,310 in future weeks. 1312 01:00:40,310 --> 01:00:42,520 But for now, that's analogous to the when 1313 01:00:42,520 --> 01:00:44,920 green flag clicked code in Scratch. 1314 01:00:44,920 --> 01:00:46,460 And now let's go ahead and do this. 1315 01:00:46,460 --> 01:00:49,210 Let me go ahead and get_int from the user 1316 01:00:49,210 --> 01:00:51,713 and ask the user, What's x, question mark. 1317 01:00:51,713 --> 01:00:53,380 I'm not going to bother with a new line. 1318 01:00:53,380 --> 01:00:56,410 I want to keep it all in one line, just for aesthetics' sake. 1319 01:00:56,410 --> 01:00:59,710 But when I get back and int, just like I get back a string, 1320 01:00:59,710 --> 01:01:01,580 I get back a return value. 1321 01:01:01,580 --> 01:01:06,040 So if I want to store the result of get_int somewhere, 1322 01:01:06,040 --> 01:01:07,927 I had better put it in a variable. 1323 01:01:07,927 --> 01:01:09,760 And I can call the variable anything I want. 1324 01:01:09,760 --> 01:01:12,790 Previously, I used answer, or first, or last. 1325 01:01:12,790 --> 01:01:14,410 Now I'm going to use x. 1326 01:01:14,410 --> 01:01:18,310 But there's still two things left to do here logically, even though we 1327 01:01:18,310 --> 01:01:19,870 haven't technically done this yet. 1328 01:01:19,870 --> 01:01:21,130 What I still need to do? 1329 01:01:21,130 --> 01:01:22,410 AUDIENCE: A semicolon. 1330 01:01:22,410 --> 01:01:24,535 DAVID J. MALAN: So I need the semicolon at the end. 1331 01:01:24,535 --> 01:01:26,010 AUDIENCE: And the int first. 1332 01:01:26,010 --> 01:01:27,885 DAVID J. MALAN: And the int at the beginning. 1333 01:01:27,885 --> 01:01:31,257 You the programmer, starting today, need to decide what you're 1334 01:01:31,257 --> 01:01:32,840 going to be storing in your variables. 1335 01:01:32,840 --> 01:01:35,750 And you just need to tell the computer that so that it knows. 1336 01:01:35,750 --> 01:01:38,990 Now, as a teaser for languages like Python, more modern languages, 1337 01:01:38,990 --> 01:01:41,240 turns out, humans realized, well, gee, this is stupid. 1338 01:01:41,240 --> 01:01:44,115 Why can't the computer just figure out that I'm putting an int there? 1339 01:01:44,115 --> 01:01:45,800 Why do I have to tell it proactively? 1340 01:01:45,800 --> 01:01:48,080 So in some languages nowadays, like Python 1341 01:01:48,080 --> 01:01:50,990 will get rid of some of this syntax, will get rid of the semicolons. 1342 01:01:50,990 --> 01:01:54,530 But for now we're looking at, really, the origins of how this all worked. 1343 01:01:54,530 --> 01:01:57,380 All right, so I've done this one line ending with semicolon. 1344 01:01:57,380 --> 01:01:58,440 Let me do one other. 1345 01:01:58,440 --> 01:02:02,390 And let me get a second int asking the user, What's y, question mark. 1346 01:02:02,390 --> 01:02:06,680 So almost identical but different responses from the user, hopefully. 1347 01:02:06,680 --> 01:02:10,490 And let me just ask simply if x is less than y, 1348 01:02:10,490 --> 01:02:14,690 in parentheses, then some curly braces, let me go ahead and print out, 1349 01:02:14,690 --> 01:02:18,950 quote/unquote, x is less than y backslash n. 1350 01:02:18,950 --> 01:02:20,600 And now just as a side note-- 1351 01:02:20,600 --> 01:02:23,240 I seem to be typing fast. 1352 01:02:23,240 --> 01:02:25,610 Some of that is because VS Code is helping me. 1353 01:02:25,610 --> 01:02:29,720 Let me go back to this first line with the if, hit Enter. 1354 01:02:29,720 --> 01:02:33,630 And now I'm only on my keyboard going to type the open curly brace. 1355 01:02:33,630 --> 01:02:36,410 This is a feature of many text editors nowadays. 1356 01:02:36,410 --> 01:02:37,980 It finishes part of your thought. 1357 01:02:37,980 --> 01:02:38,480 Why? 1358 01:02:38,480 --> 01:02:40,580 Just to save yourself a keystroke to make sure 1359 01:02:40,580 --> 01:02:42,660 you don't accidentally forget the closing one. 1360 01:02:42,660 --> 01:02:45,750 So you'll notice sometimes that things are happening that you didn't type. 1361 01:02:45,750 --> 01:02:49,550 It's just VS Code or future programs you use trying to be helpful for you. 1362 01:02:49,550 --> 01:02:52,445 I'll go ahead and manually type out now printf 1363 01:02:52,445 --> 01:02:57,050 x is less than y backslash n close quote semicolon. 1364 01:02:57,050 --> 01:03:01,400 So let me go ahead now and try to run this, and we'll see-- 1365 01:03:01,400 --> 01:03:02,000 let's see. 1366 01:03:02,000 --> 01:03:05,510 So make-- not hello-- but make compare because this file is 1367 01:03:05,510 --> 01:03:09,050 called compare.c, hitting Enter. 1368 01:03:09,050 --> 01:03:12,320 No output is good because it means I haven't messed up. 1369 01:03:12,320 --> 01:03:16,580 Let me ./compare instead of ./hello, Enter. 1370 01:03:16,580 --> 01:03:17,390 What's x? 1371 01:03:17,390 --> 01:03:18,410 How about 1? 1372 01:03:18,410 --> 01:03:19,040 What's y? 1373 01:03:19,040 --> 01:03:19,840 How about 2? 1374 01:03:19,840 --> 01:03:22,230 X is less than y. 1375 01:03:22,230 --> 01:03:23,387 Well, let's try it again. 1376 01:03:23,387 --> 01:03:25,220 And here, I'll save you some keystrokes too. 1377 01:03:25,220 --> 01:03:26,360 Let me clear my screen. 1378 01:03:26,360 --> 01:03:30,350 Instead of constantly typing ./this and ./that, 1379 01:03:30,350 --> 01:03:34,610 you can also use your keyboard's arrow keys in VS Code to scroll back through 1380 01:03:34,610 --> 01:03:35,310 time. 1381 01:03:35,310 --> 01:03:37,940 So if I hit Up once, there's the last command I wrote. 1382 01:03:37,940 --> 01:03:41,480 If I do it Up twice, there's the second to last command I wrote. 1383 01:03:41,480 --> 01:03:43,460 So sometimes if you see me doing things fast, 1384 01:03:43,460 --> 01:03:46,550 it's just because I'm cheating and going through my history like that. 1385 01:03:46,550 --> 01:03:51,380 All right, let me go ahead, though, and rerun ./compare, Enter. 1386 01:03:51,380 --> 01:03:52,670 Let's reverse it this time-- 1387 01:03:52,670 --> 01:03:55,100 2 for x, 1 for y. 1388 01:03:55,100 --> 01:03:56,870 And now, of course, there's no output. 1389 01:03:56,870 --> 01:03:58,670 All right, well, that's logically to be expected 1390 01:03:58,670 --> 01:04:00,170 because we didn't have an else here. 1391 01:04:00,170 --> 01:04:00,980 So let's add that. 1392 01:04:00,980 --> 01:04:05,060 Else-- now let's open my curly braces, letting VS Code do one of them 1393 01:04:05,060 --> 01:04:12,350 for me-- printf, quote/unquote, x is not less than y backslash n semicolon. 1394 01:04:12,350 --> 01:04:16,430 Let me go ahead and try this again-- ./compare, Enter. 1395 01:04:16,430 --> 01:04:19,100 Again, 2 for x, 1 for y. 1396 01:04:19,100 --> 01:04:20,540 And we should see-- 1397 01:04:20,540 --> 01:04:22,990 huh. 1398 01:04:22,990 --> 01:04:24,830 What did I do wrong? 1399 01:04:24,830 --> 01:04:27,050 Why am I not seeing any else output? 1400 01:04:27,050 --> 01:04:27,550 Yeah? 1401 01:04:27,550 --> 01:04:29,592 AUDIENCE: You changed your code when you rebuild. 1402 01:04:29,592 --> 01:04:30,690 You need to compile it. 1403 01:04:30,690 --> 01:04:31,290 DAVID J. MALAN: Exactly. 1404 01:04:31,290 --> 01:04:34,415 You got to get into the habit after you change your code of recompiling it. 1405 01:04:34,415 --> 01:04:36,420 Or otherwise, the zeros and ones in the server 1406 01:04:36,420 --> 01:04:39,000 are the old ones until you manually compile. 1407 01:04:39,000 --> 01:04:41,040 So let's fix this-- make compare, Enter. 1408 01:04:41,040 --> 01:04:42,030 No error messages. 1409 01:04:42,030 --> 01:04:45,420 That's good. ./compare, 2, 1. 1410 01:04:45,420 --> 01:04:47,320 And now I get back the output. 1411 01:04:47,320 --> 01:04:49,230 So x is not less than y. 1412 01:04:49,230 --> 01:04:52,390 How about if I go and add in the third condition? 1413 01:04:52,390 --> 01:04:55,650 Well, we can do this either efficiently or inefficiently. 1414 01:04:55,650 --> 01:04:57,270 Let me go ahead and refine this. 1415 01:04:57,270 --> 01:05:03,780 So else if x is greater than y, let's literally say, x is greater than y. 1416 01:05:03,780 --> 01:05:07,950 And now I could do x else if x equals equals y. 1417 01:05:07,950 --> 01:05:11,080 But I think we already claimed that that's unnecessarily inefficient. 1418 01:05:11,080 --> 01:05:12,810 So let's just have our catchall. 1419 01:05:12,810 --> 01:05:14,730 And here I'm going to say, quote/unquote, 1420 01:05:14,730 --> 01:05:19,960 x is equal to y backslash n, close quote there. 1421 01:05:19,960 --> 01:05:24,070 So I think now with this code, we've handled all three scenarios. 1422 01:05:24,070 --> 01:05:28,680 Let me go ahead and recompile it properly-- make compare, ./compare. 1423 01:05:28,680 --> 01:05:31,350 And now 1 and 2-- 1424 01:05:31,350 --> 01:05:32,340 is less than y. 1425 01:05:32,340 --> 01:05:33,510 Let me run it again. 1426 01:05:33,510 --> 01:05:36,690 2 and 1-- x is greater than y. 1427 01:05:36,690 --> 01:05:41,100 And lastly, 1 and 1, and x is equal to y. 1428 01:05:41,100 --> 01:05:43,270 So for the most part, our code is getting longer. 1429 01:05:43,270 --> 01:05:45,870 We're up to 21 lines of code, though some of them 1430 01:05:45,870 --> 01:05:47,700 are just single characters on the screen. 1431 01:05:47,700 --> 01:05:49,410 Almost everything else is the same. 1432 01:05:49,410 --> 01:05:56,190 I'm using the CS50 library's header file for my get_int function, stdio.h 1433 01:05:56,190 --> 01:05:58,590 for my printf function, and the rest of this 1434 01:05:58,590 --> 01:06:01,810 is just now new syntax for conditionals as well. 1435 01:06:01,810 --> 01:06:04,350 Questions, then, on this C implementation 1436 01:06:04,350 --> 01:06:08,237 of just some basic comparisons like this? 1437 01:06:08,237 --> 01:06:08,820 Any questions? 1438 01:06:08,820 --> 01:06:09,320 Yeah? 1439 01:06:09,320 --> 01:06:12,360 AUDIENCE: Just a syntax question-- do the opening 1440 01:06:12,360 --> 01:06:14,530 brackets need to be on a separate line? 1441 01:06:14,530 --> 01:06:15,190 DAVID J. MALAN: Good question. 1442 01:06:15,190 --> 01:06:17,440 Do the opening brackets need to be on a separate line? 1443 01:06:17,440 --> 01:06:18,610 In CS50, yes. 1444 01:06:18,610 --> 01:06:21,310 What you'll see is that as part of the submission process, 1445 01:06:21,310 --> 01:06:25,540 we compare your code against a style guide, which is the norm in industry. 1446 01:06:25,540 --> 01:06:29,290 A company would have its own sense of style and how its code should look. 1447 01:06:29,290 --> 01:06:31,540 And there's generally automated tools within a company 1448 01:06:31,540 --> 01:06:35,080 that help give feedback on the code or stylize it as such. 1449 01:06:35,080 --> 01:06:38,410 There are alternative styles than what we use in the class. 1450 01:06:38,410 --> 01:06:41,500 We deliberately keep and ask that you keep 1451 01:06:41,500 --> 01:06:44,110 the curly braces on their own line, if only 1452 01:06:44,110 --> 01:06:48,430 because it rather resembles like the hugging nature of Scratch's blocks 1453 01:06:48,430 --> 01:06:51,370 and just makes clear that they're balanced, opened and closed. 1454 01:06:51,370 --> 01:06:56,020 However, another common paradigm in some languages and with some programmers 1455 01:06:56,020 --> 01:06:59,420 is to do something like this on each of them. 1456 01:06:59,420 --> 01:07:03,670 So you have the opening curly brace on the same line as here. 1457 01:07:03,670 --> 01:07:05,030 We do not recommend this. 1458 01:07:05,030 --> 01:07:07,900 This is en vogue in the JavaScript world and some others. 1459 01:07:07,900 --> 01:07:11,110 But ultimately in the real world, it's up to each individual programmer 1460 01:07:11,110 --> 01:07:13,720 and/or the company they're working for, if applicable, 1461 01:07:13,720 --> 01:07:16,210 to decide on those things. 1462 01:07:16,210 --> 01:07:18,640 All right, so beyond, then, these conditionals, 1463 01:07:18,640 --> 01:07:21,140 what if we want to do something that's maybe pretty common? 1464 01:07:21,140 --> 01:07:24,280 So almost every piece of software or website nowadays that you use 1465 01:07:24,280 --> 01:07:28,360 has you agree to some terms and conditions by typing Yes or No or just 1466 01:07:28,360 --> 01:07:30,280 Y for Yes and N for No. 1467 01:07:30,280 --> 01:07:33,195 So how could we implement some kind of agreement system? 1468 01:07:33,195 --> 01:07:34,070 Well, let me do this. 1469 01:07:34,070 --> 01:07:37,810 Let me create a new program, a third one called agree.c. 1470 01:07:37,810 --> 01:07:41,230 So I'm going to write code agree.c just to give myself a new tab. 1471 01:07:41,230 --> 01:07:44,230 I'm going to start, as always now, include cs50.h. 1472 01:07:44,230 --> 01:07:46,480 Let's include stdio.h. 1473 01:07:46,480 --> 01:07:50,770 And then let me do my int main(void)-- which, again, for today's purposes, 1474 01:07:50,770 --> 01:07:53,200 we'll take at face value is just copy/paste. 1475 01:07:53,200 --> 01:07:57,850 And if I just want to get Y or N, for instance, instead of Yes or No, 1476 01:07:57,850 --> 01:08:00,520 we can just use a simpler variable here. 1477 01:08:00,520 --> 01:08:03,800 How about just a char, a character, a single character? 1478 01:08:03,800 --> 01:08:07,120 So I can use get_char to ask the user, for instance, 1479 01:08:07,120 --> 01:08:09,760 do you agree, question mark. 1480 01:08:09,760 --> 01:08:12,880 But as before, I need to store this somewhere. 1481 01:08:12,880 --> 01:08:15,130 So I don't want a string because that's a single char. 1482 01:08:15,130 --> 01:08:16,180 I don't want an int. 1483 01:08:16,180 --> 01:08:17,380 I just want a char. 1484 01:08:17,380 --> 01:08:21,500 And it's literally C-H-A-R. And then I can call this thing anything I want. 1485 01:08:21,500 --> 01:08:25,370 It's conventional if you have a simple program with just a single variable 1486 01:08:25,370 --> 01:08:27,040 and it's of type char, call it c. 1487 01:08:27,040 --> 01:08:28,569 If it's an int, call it i. 1488 01:08:28,569 --> 01:08:29,830 If it's a string, call it s. 1489 01:08:29,830 --> 01:08:32,590 For now I'm just going to keep it simple and call it c. 1490 01:08:32,590 --> 01:08:34,370 And now I'm going to ask a question. 1491 01:08:34,370 --> 01:08:43,240 So if c equals equals, how about, quote/unquote, y, then 1492 01:08:43,240 --> 01:08:47,290 let me go ahead and print out Agreed backslash n, 1493 01:08:47,290 --> 01:08:50,380 as though they agreed to my terms and conditions. 1494 01:08:50,380 --> 01:08:51,880 Otherwise, let's see. 1495 01:08:51,880 --> 01:08:57,729 Else if the character equals equals, quote/unquote, n, then let me go ahead 1496 01:08:57,729 --> 01:09:03,609 and print out, say, Not agreed, as though they didn't, quote/unquote. 1497 01:09:03,609 --> 01:09:07,060 And let's leave it at that, I think, here initially. 1498 01:09:07,060 --> 01:09:11,830 Now, you'll notice one curiosity, one inconsistency perhaps. 1499 01:09:11,830 --> 01:09:15,760 Does anyone want to call it out, though it's somewhat subtle? 1500 01:09:15,760 --> 01:09:19,720 I've done something ever so slightly differently without explaining it yet. 1501 01:09:19,720 --> 01:09:20,380 Do you see it? 1502 01:09:20,380 --> 01:09:22,625 AUDIENCE: The single quotation mark. 1503 01:09:22,625 --> 01:09:23,500 DAVID J. MALAN: Yeah. 1504 01:09:23,500 --> 01:09:27,880 So I've suddenly used single quotation marks for my single characters 1505 01:09:27,880 --> 01:09:30,590 and double quotes for my actual strings of text. 1506 01:09:30,590 --> 01:09:34,210 This is a necessity in C. When you're dealing with strings, like strings 1507 01:09:34,210 --> 01:09:37,420 of text, like someone's name, a sentence, a paragraph, anything 1508 01:09:37,420 --> 01:09:41,380 really more than one character, you typically use double quotes. 1509 01:09:41,380 --> 01:09:42,399 And indeed, you must. 1510 01:09:42,399 --> 01:09:47,620 When dealing with deliberately single characters, like I am here for y or n, 1511 01:09:47,620 --> 01:09:49,819 you must use single quotes instead. 1512 01:09:49,819 --> 01:09:50,319 Why? 1513 01:09:50,319 --> 01:09:52,240 Because that makes sure that the computer 1514 01:09:52,240 --> 01:09:54,550 knows that it's indeed a char and not a string. 1515 01:09:54,550 --> 01:09:55,930 So double quotes are for strings. 1516 01:09:55,930 --> 01:09:57,520 Single quotes are for chars. 1517 01:09:57,520 --> 01:10:00,550 So with that said, let me go ahead and zoom out. 1518 01:10:00,550 --> 01:10:04,780 Let me go ahead in my terminal window run make agree, Enter. 1519 01:10:04,780 --> 01:10:08,770 Seems to work OK so let me go ahead and do ./agree. 1520 01:10:08,770 --> 01:10:12,250 Let me go ahead now and type in y. 1521 01:10:12,250 --> 01:10:13,090 Here we go. 1522 01:10:13,090 --> 01:10:14,980 Enter. 1523 01:10:14,980 --> 01:10:16,540 Huh. 1524 01:10:16,540 --> 01:10:17,470 Let me try that again. 1525 01:10:17,470 --> 01:10:18,580 Rerun ./agree. 1526 01:10:18,580 --> 01:10:20,170 How about no? 1527 01:10:20,170 --> 01:10:22,480 Enter. 1528 01:10:22,480 --> 01:10:25,720 Why is it not behaving as I would have expected? 1529 01:10:25,720 --> 01:10:28,480 AUDIENCE: Because you entered the capital Y and capital N. 1530 01:10:28,480 --> 01:10:29,590 DAVID J. MALAN: Yeah, I kind of cheated there, 1531 01:10:29,590 --> 01:10:32,230 and I hit the Caps Lock key just as I started typing in input. 1532 01:10:32,230 --> 01:10:32,730 Why? 1533 01:10:32,730 --> 01:10:35,950 Because I deliberately wanted to type in uppercase instead of lowercase, 1534 01:10:35,950 --> 01:10:37,540 which is kind of reasonable. 1535 01:10:37,540 --> 01:10:40,728 It's a little obnoxious if you force the user to toggle their caps lock 1536 01:10:40,728 --> 01:10:42,770 key on or off when you just need a simple answer. 1537 01:10:42,770 --> 01:10:45,310 That's not the best User Experience, or UX. 1538 01:10:45,310 --> 01:10:47,200 But it would work if I cooperated. 1539 01:10:47,200 --> 01:10:49,420 Let me run this again without caps lock-- 1540 01:10:49,420 --> 01:10:52,030 y lowercase for yes. 1541 01:10:52,030 --> 01:10:55,210 Ah, that worked. n lowercase for no. 1542 01:10:55,210 --> 01:10:55,990 That worked. 1543 01:10:55,990 --> 01:10:57,910 But how could I get it to work for both? 1544 01:10:57,910 --> 01:10:59,180 Well, how about this? 1545 01:10:59,180 --> 01:11:01,400 Let me go ahead and just add two possibilities. 1546 01:11:01,400 --> 01:11:06,340 So else if c equals equals quote/unquote capital Y, 1547 01:11:06,340 --> 01:11:10,720 then also do printf agreed backslash n. 1548 01:11:10,720 --> 01:11:17,470 And down here, else if c equals equals single quote capital N, 1549 01:11:17,470 --> 01:11:20,980 then go ahead and print out, again, Not agreed. 1550 01:11:20,980 --> 01:11:23,770 This, I will claim now, is correct. 1551 01:11:23,770 --> 01:11:26,980 And I'll do make agree real fast, ./agree. 1552 01:11:26,980 --> 01:11:28,210 And I'll use capital. 1553 01:11:28,210 --> 01:11:29,170 It now works. 1554 01:11:29,170 --> 01:11:30,610 I'll use capital. 1555 01:11:30,610 --> 01:11:32,200 It again works. 1556 01:11:32,200 --> 01:11:34,510 But this is perhaps not the best design. 1557 01:11:34,510 --> 01:11:39,220 Let me hide the terminal window and pull this up on the screen all at once. 1558 01:11:39,220 --> 01:11:43,195 Why might this arguably not be the best design, even though it's correct? 1559 01:11:43,195 --> 01:11:46,250 1560 01:11:46,250 --> 01:11:49,628 There's another term of art we can toss here, like [SNIFFS] something 1561 01:11:49,628 --> 01:11:51,170 smells kind of funky about this code. 1562 01:11:51,170 --> 01:11:52,450 This is an actual term of art. 1563 01:11:52,450 --> 01:11:54,100 There's code smell here. 1564 01:11:54,100 --> 01:11:55,930 Something smells a little off. 1565 01:11:55,930 --> 01:11:56,620 Why? 1566 01:11:56,620 --> 01:11:57,894 What do you think? 1567 01:11:57,894 --> 01:12:01,846 AUDIENCE: [INAUDIBLE] 1568 01:12:01,846 --> 01:12:06,895 1569 01:12:06,895 --> 01:12:07,770 DAVID J. MALAN: Yeah. 1570 01:12:07,770 --> 01:12:09,370 There's the same output again and again. 1571 01:12:09,370 --> 01:12:10,530 I mean, I manually typed it. 1572 01:12:10,530 --> 01:12:12,905 But honestly, I might as well have just copied and pasted 1573 01:12:12,905 --> 01:12:17,080 most of my original code to do it again and again for the two capital letters. 1574 01:12:17,080 --> 01:12:23,370 So if line 10 and 14 are the same AND line 18 and 22 are the same, AND then 1575 01:12:23,370 --> 01:12:26,875 the rest of these if and else ifs are almost the same, 1576 01:12:26,875 --> 01:12:28,500 [SNIFFS] there's some code smell there. 1577 01:12:28,500 --> 01:12:29,370 It's not well designed. 1578 01:12:29,370 --> 01:12:29,820 Why? 1579 01:12:29,820 --> 01:12:32,778 Because if I want to change things now, just like last week in Scratch, 1580 01:12:32,778 --> 01:12:35,970 I might have to change my code in multiple places or copy/paste 1581 01:12:35,970 --> 01:12:37,120 is never a good thing. 1582 01:12:37,120 --> 01:12:41,280 And god forbid I want to add support for Yes and No as full words, 1583 01:12:41,280 --> 01:12:42,760 it's really going to get long. 1584 01:12:42,760 --> 01:12:44,170 So how can we solve this? 1585 01:12:44,170 --> 01:12:47,160 Well, it turns out, we can combine some of these thoughts. 1586 01:12:47,160 --> 01:12:49,470 So let me try to improve the Yeses first. 1587 01:12:49,470 --> 01:12:54,325 It turns out, if I delete that clause, I can actually or things together. 1588 01:12:54,325 --> 01:12:57,450 In Scratch, there's a couple of puzzle pieces, if you didn't discover them, 1589 01:12:57,450 --> 01:12:59,430 that literally have the word or and the word 1590 01:12:59,430 --> 01:13:02,350 and on them, which allow you to combine Boolean expressions. 1591 01:13:02,350 --> 01:13:06,600 So that either this or this is true, or this and this is true. 1592 01:13:06,600 --> 01:13:09,270 In C, you can't just say the word or. 1593 01:13:09,270 --> 01:13:12,850 You instead use two vertical bars. 1594 01:13:12,850 --> 01:13:16,260 And vertical bars together mean or, logically. 1595 01:13:16,260 --> 01:13:21,780 And so I can say, c equals equals quote/unquote capital Y, Agreed. 1596 01:13:21,780 --> 01:13:24,270 And now I can get rid of this code down here. 1597 01:13:24,270 --> 01:13:29,100 And let me go ahead and say, vertical bar twice c 1598 01:13:29,100 --> 01:13:32,340 equals quote/unquote N in all caps. 1599 01:13:32,340 --> 01:13:36,870 And now my program's roughly a third smaller, which is good. 1600 01:13:36,870 --> 01:13:38,140 There's less redundancy. 1601 01:13:38,140 --> 01:13:43,290 And if I reopen my terminal window, rerun make of agree, ./agree, 1602 01:13:43,290 --> 01:13:49,860 now I can type little y or big Y and same thing for lowercase and uppercase 1603 01:13:49,860 --> 01:13:54,090 N. Any questions then on this syntax, whereby now you can combine thoughts 1604 01:13:54,090 --> 01:13:56,407 and just tighten things up? 1605 01:13:56,407 --> 01:13:57,990 And there'll be other such tricks too. 1606 01:13:57,990 --> 01:13:58,942 Yeah? 1607 01:13:58,942 --> 01:14:01,615 AUDIENCE: Is there not a function to just ignore the case? 1608 01:14:01,615 --> 01:14:03,240 DAVID J. MALAN: A really good question. 1609 01:14:03,240 --> 01:14:06,030 Is there not a function to just ignore the case? 1610 01:14:06,030 --> 01:14:07,890 Short answer, there is. 1611 01:14:07,890 --> 01:14:10,950 And we'll see how to do that in, actually, just about a week's time. 1612 01:14:10,950 --> 01:14:13,080 And in other languages, there's even more ways 1613 01:14:13,080 --> 01:14:17,100 to just canonicalize the user's input, throwing away any space characters 1614 01:14:17,100 --> 01:14:19,890 they might have accidentally hit, forcing everything to lowercase. 1615 01:14:19,890 --> 01:14:23,372 In C, It's going to be a little more work on our part to do that. 1616 01:14:23,372 --> 01:14:26,080 But in fact, as early as next week, we'll see how we can do that. 1617 01:14:26,080 --> 01:14:29,490 But for now we're comparing indeed just these literal values. 1618 01:14:29,490 --> 01:14:30,570 Other questions? 1619 01:14:30,570 --> 01:14:33,874 AUDIENCE: So we're assuming the user's putting in what they're suggesting. 1620 01:14:33,874 --> 01:14:37,618 How do you handle if they were to put in a number? 1621 01:14:37,618 --> 01:14:39,160 DAVID J. MALAN: Really good question. 1622 01:14:39,160 --> 01:14:42,068 So we are assuming, with this program and all of my last ones, 1623 01:14:42,068 --> 01:14:45,360 that the human's cooperating and when I ask for their name, they typed in David 1624 01:14:45,360 --> 01:14:49,290 and not 123, or, in this case, they typed in a single character and not 1625 01:14:49,290 --> 01:14:50,040 a full word. 1626 01:14:50,040 --> 01:14:53,520 So this is one of the features often of using a library. 1627 01:14:53,520 --> 01:14:59,550 So for instance, if I run agree again, and I say something like sure, Enter, 1628 01:14:59,550 --> 01:15:01,330 it rejects it altogether. 1629 01:15:01,330 --> 01:15:01,830 Why? 1630 01:15:01,830 --> 01:15:05,850 Because s, u, r, e is a string of characters. 1631 01:15:05,850 --> 01:15:07,320 It's not a single character. 1632 01:15:07,320 --> 01:15:11,380 Now, I could just say something like x, which is neither y nor n, of course. 1633 01:15:11,380 --> 01:15:14,190 But it tolerates that because it's a single character. 1634 01:15:14,190 --> 01:15:17,790 But built in to CS50's library is some built-in rejections 1635 01:15:17,790 --> 01:15:19,210 of inputs that's not expected. 1636 01:15:19,210 --> 01:15:22,920 So if you use get_int and the user types in not the number 1 or 2 1637 01:15:22,920 --> 01:15:26,940 but cat, C-A-T, it will just prompt them again, prompt them again. 1638 01:15:26,940 --> 01:15:30,480 And this is where, too, if you were to do this manually in C, 1639 01:15:30,480 --> 01:15:34,068 you end up writing this much code just to check for all of these errors. 1640 01:15:34,068 --> 01:15:36,360 That's why we use these training wheels for a few weeks 1641 01:15:36,360 --> 01:15:38,190 just to make the code more robust. 1642 01:15:38,190 --> 01:15:40,500 But in a few weeks' time, we'll take the liberty away. 1643 01:15:40,500 --> 01:15:44,970 And you'll see and understand how it's indeed doing all that. 1644 01:15:44,970 --> 01:15:46,750 All right, so how about this. 1645 01:15:46,750 --> 01:15:50,640 Let's now transition to something a little more Scratch-like, literally, 1646 01:15:50,640 --> 01:15:53,290 by creating how about another program here called meow-- 1647 01:15:53,290 --> 01:15:54,567 so meow.c. 1648 01:15:54,567 --> 01:15:56,650 We won't have any audio capabilities for this one. 1649 01:15:56,650 --> 01:15:57,750 We'll just rely on print. 1650 01:15:57,750 --> 01:16:00,390 And suppose that I wanted to write a program 1651 01:16:00,390 --> 01:16:03,000 and see that just simulates a cat meowing. 1652 01:16:03,000 --> 01:16:04,960 So I don't need any user input just yet. 1653 01:16:04,960 --> 01:16:06,960 So I'm just going to use stdio.h. 1654 01:16:06,960 --> 01:16:09,940 I'm going to do my usual int main(void) up here. 1655 01:16:09,940 --> 01:16:13,710 And then I'm just going to go ahead and do printf meow backslash n. 1656 01:16:13,710 --> 01:16:16,650 And let's have this cat meow three times, like last week. 1657 01:16:16,650 --> 01:16:18,870 So I'm going to do meow, meow, meow. 1658 01:16:18,870 --> 01:16:21,100 Notice as an aside whenever you highlight the lines, 1659 01:16:21,100 --> 01:16:22,350 you'll see little dots appear. 1660 01:16:22,350 --> 01:16:24,780 This is just a visual cue to you to let you figure out 1661 01:16:24,780 --> 01:16:26,460 how many spaces you've indented. 1662 01:16:26,460 --> 01:16:30,133 VS Code, like a lot of editors, will automatically indent your code for you. 1663 01:16:30,133 --> 01:16:32,550 I've not been hitting the space bar four times every time. 1664 01:16:32,550 --> 01:16:34,020 I've not even been hitting Tab. 1665 01:16:34,020 --> 01:16:38,280 However, in C, the convention is indeed to indent lines 1666 01:16:38,280 --> 01:16:40,410 where appropriate by four spaces-- 1667 01:16:40,410 --> 01:16:41,933 so not three, not five. 1668 01:16:41,933 --> 01:16:44,100 And these dots help you see things so that they just 1669 01:16:44,100 --> 01:16:45,850 line up as a matter of good style. 1670 01:16:45,850 --> 01:16:48,600 All right, so this program, I'm just going to stipulate right now, 1671 01:16:48,600 --> 01:16:49,600 is indeed going to work. 1672 01:16:49,600 --> 01:16:52,560 Make meow-- which is kind of cute-- and now meow. 1673 01:16:52,560 --> 01:16:54,000 There, three times. 1674 01:16:54,000 --> 01:16:54,540 Correct. 1675 01:16:54,540 --> 01:16:55,500 It's meowing three times. 1676 01:16:55,500 --> 01:16:57,060 But of course, this is not well designed. 1677 01:16:57,060 --> 01:16:58,935 It wasn't well designed in Scratch last week. 1678 01:16:58,935 --> 01:17:00,480 Why? 1679 01:17:00,480 --> 01:17:03,130 What should I be doing differently? 1680 01:17:03,130 --> 01:17:03,630 Yeah? 1681 01:17:03,630 --> 01:17:04,120 AUDIENCE: A loop? 1682 01:17:04,120 --> 01:17:05,412 AUDIENCE: This could be a loop. 1683 01:17:05,412 --> 01:17:07,140 DAVID J. MALAN: Yeah. 1684 01:17:07,140 --> 01:17:09,310 It's a perfect opportunity for a loop. 1685 01:17:09,310 --> 01:17:09,810 Why? 1686 01:17:09,810 --> 01:17:12,810 Because if you wanted to change maybe the capitalization of these words, 1687 01:17:12,810 --> 01:17:16,260 or you wanted to change the sound to like woof for a dog or something, 1688 01:17:16,260 --> 01:17:18,390 you'd have to change it one, two, three places. 1689 01:17:18,390 --> 01:17:20,160 And that's just kind of stupid, right? 1690 01:17:20,160 --> 01:17:23,020 In code, you should ideally change things in one place. 1691 01:17:23,020 --> 01:17:24,880 So how might I do that? 1692 01:17:24,880 --> 01:17:27,120 Well, we could introduce a loop, yes. 1693 01:17:27,120 --> 01:17:30,420 But we're going to need another building block as well that we had in Scratch, 1694 01:17:30,420 --> 01:17:32,710 namely those things called variables. 1695 01:17:32,710 --> 01:17:35,070 So recall that a variable, like an algebra-- x, 1696 01:17:35,070 --> 01:17:38,520 y, z, whatever-- can store a value for you. 1697 01:17:38,520 --> 01:17:42,630 And a variable in Scratch might have looked like this. 1698 01:17:42,630 --> 01:17:45,880 You use this orange puzzle piece to set a variable of any name, 1699 01:17:45,880 --> 01:17:46,890 not just x, y, or z. 1700 01:17:46,890 --> 01:17:49,710 But you could call it something more descriptive, like counter, 1701 01:17:49,710 --> 01:17:51,840 and you can set it equal to some value. 1702 01:17:51,840 --> 01:17:56,490 In C, the way to do this is similar to spirit to some of the syntax 1703 01:17:56,490 --> 01:17:57,570 we've seen thus far. 1704 01:17:57,570 --> 01:17:59,910 You start by saying the name of the variable you want, 1705 01:17:59,910 --> 01:18:01,740 a single equal sign, and then the value. 1706 01:18:01,740 --> 01:18:05,470 You want to initialize it too, copying therefore from right to left. 1707 01:18:05,470 --> 01:18:05,970 Why? 1708 01:18:05,970 --> 01:18:09,570 Because the equal sign denotes, again, assignment from right to left. 1709 01:18:09,570 --> 01:18:10,740 This isn't enough though. 1710 01:18:10,740 --> 01:18:12,282 You might have the intuition already. 1711 01:18:12,282 --> 01:18:16,170 What's missing probably from this line of code just to create a variable? 1712 01:18:16,170 --> 01:18:16,767 AUDIENCE: Int. 1713 01:18:16,767 --> 01:18:19,350 DAVID J. MALAN: So we need int to make sure the computer knows 1714 01:18:19,350 --> 01:18:20,610 that this is indeed an int. 1715 01:18:20,610 --> 01:18:23,802 And then lastly, semicolon as well. 1716 01:18:23,802 --> 01:18:25,260 And that now completes the thought. 1717 01:18:25,260 --> 01:18:27,302 So a little more annoying than Scratch, but we're 1718 01:18:27,302 --> 01:18:28,660 starting to see patterns here. 1719 01:18:28,660 --> 01:18:30,810 So not every piece of syntax will be new. 1720 01:18:30,810 --> 01:18:33,480 All right, if you want to increment the counter by one, 1721 01:18:33,480 --> 01:18:37,480 Scratch uses the verb change, and they mean add the value to counter. 1722 01:18:37,480 --> 01:18:41,700 So if I want to increment an existing variable called counter, 1723 01:18:41,700 --> 01:18:43,930 this syntax is a little more interesting. 1724 01:18:43,930 --> 01:18:48,690 It turns out the code looks like this, which almost seems like a paradox. 1725 01:18:48,690 --> 01:18:51,990 How can counter equal counter plus 1? 1726 01:18:51,990 --> 01:18:53,160 That's not how math works. 1727 01:18:53,160 --> 01:18:56,860 But again, a single equal sign is assignment from right to left. 1728 01:18:56,860 --> 01:18:59,910 So this is saying, take whatever the value of counter is, add 1 to it, 1729 01:18:59,910 --> 01:19:03,930 and copy that value from right to left into counter itself. 1730 01:19:03,930 --> 01:19:07,530 You still need the semicolon, but I claim 1731 01:19:07,530 --> 01:19:13,330 you do not need to mention the keyword int when updating an existing variable. 1732 01:19:13,330 --> 01:19:18,060 So only when you create a variable in C do you use the word string, or the word 1733 01:19:18,060 --> 01:19:19,950 int, or any of the others we'll eventually 1734 01:19:19,950 --> 01:19:23,370 see-- only when creating it or initializing it for the first time. 1735 01:19:23,370 --> 01:19:25,780 Thereafter if you want to change it, it just exists. 1736 01:19:25,780 --> 01:19:27,060 It's the word you gave it. 1737 01:19:27,060 --> 01:19:29,950 The computer is smart enough to at least remember what type it is. 1738 01:19:29,950 --> 01:19:32,100 So this line is now complete 1739 01:19:32,100 --> 01:19:35,580 Turns out, in code, as we'll see, it's pretty common to want to add things 1740 01:19:35,580 --> 01:19:37,740 together, increment things by one. 1741 01:19:37,740 --> 01:19:40,710 So there's actually different syntax for the same idea. 1742 01:19:40,710 --> 01:19:43,290 The term of art here is syntactic sugar. 1743 01:19:43,290 --> 01:19:46,410 There's often in code many ways to do the same thing, 1744 01:19:46,410 --> 01:19:49,900 even though, at the end of the day, they do exactly the same functionality. 1745 01:19:49,900 --> 01:19:54,120 So for instance, if, after a few days of CS50, you find this a little tedious 1746 01:19:54,120 --> 01:19:57,765 to keep typing in some program, you can simplify it to just this. 1747 01:19:57,765 --> 01:19:59,340 This is the syntactic sugar. 1748 01:19:59,340 --> 01:20:03,810 You can use plus equals and only mention the variable name once on the left, 1749 01:20:03,810 --> 01:20:06,480 and it just knows that means the previous thing. 1750 01:20:06,480 --> 01:20:10,420 It's just slightly more succinct. 1751 01:20:10,420 --> 01:20:12,900 This, too, is such a common thing to add 1 to a value. 1752 01:20:12,900 --> 01:20:13,800 And it doesn't have to be 1. 1753 01:20:13,800 --> 01:20:14,800 But in this case, it is. 1754 01:20:14,800 --> 01:20:19,110 But if it is indeed 1, you can further tighten the code up to just do this, 1755 01:20:19,110 --> 01:20:20,550 counter++. 1756 01:20:20,550 --> 01:20:25,740 So any time in C you see ++, it means literally adding 1 to that particular 1757 01:20:25,740 --> 01:20:26,472 variable. 1758 01:20:26,472 --> 01:20:28,680 There's other ways to do this in the other direction. 1759 01:20:28,680 --> 01:20:31,420 If you want to subtract 1 from a variable, 1760 01:20:31,420 --> 01:20:34,890 you can use any of the previous syntax using a minus sign instead of plus, 1761 01:20:34,890 --> 01:20:38,490 or you can more succinctly do counter--. 1762 01:20:38,490 --> 01:20:42,520 This is the way a typical C programmer would do this. 1763 01:20:42,520 --> 01:20:45,210 All right, so if we have no variables, let's 1764 01:20:45,210 --> 01:20:47,500 go and solve the meowing with loop. 1765 01:20:47,500 --> 01:20:49,320 So in Scratch, we saw loops like this. 1766 01:20:49,320 --> 01:20:52,680 This, of course, had the cat meow three times. 1767 01:20:52,680 --> 01:20:54,480 How do we do this in C? 1768 01:20:54,480 --> 01:20:58,900 Now, this is where things get a little more involved code-wise. 1769 01:20:58,900 --> 01:21:01,140 but if you understand each and every line, 1770 01:21:01,140 --> 01:21:03,520 we'll follow logically what's going on. 1771 01:21:03,520 --> 01:21:07,320 So here, I claim, is one way to implement 1772 01:21:07,320 --> 01:21:12,330 a loop that iterates three times in C. And this is kind of ridiculous, right? 1773 01:21:12,330 --> 01:21:15,900 We went from two super simple puzzle pieces like this to, my god, 1774 01:21:15,900 --> 01:21:18,990 it's 1, 2, 3, 4, 5, 6 lines of code, all of which are pretty involved. 1775 01:21:18,990 --> 01:21:20,740 So that escalated quickly. 1776 01:21:20,740 --> 01:21:21,960 But what's each line doing? 1777 01:21:21,960 --> 01:21:24,120 And we'll see other ways to do this more simply. 1778 01:21:24,120 --> 01:21:28,710 So we're initializing a variable called counter to 3, just like before. 1779 01:21:28,710 --> 01:21:29,370 Why? 1780 01:21:29,370 --> 01:21:32,800 Well, what does it mean to loop or to repeat something three times? 1781 01:21:32,800 --> 01:21:35,190 Well, it's like doing something three times, 1782 01:21:35,190 --> 01:21:37,260 and then do it, and then count down, and then 1783 01:21:37,260 --> 01:21:41,080 do it, and then count down, and then do it, until you're all out of counts. 1784 01:21:41,080 --> 01:21:44,910 So this is declaring a variable called counter, setting it equal to 3. 1785 01:21:44,910 --> 01:21:50,370 Then I'm inducing a loop in C, which is similar in spirit to repeat 3, 1786 01:21:50,370 --> 01:21:52,440 but you have to do more of the math yourself. 1787 01:21:52,440 --> 01:21:54,990 So I'm asking the question in parentheses, 1788 01:21:54,990 --> 01:21:59,200 while count is greater than 0, what do I want to do? 1789 01:21:59,200 --> 01:22:04,080 Well, per the indentation inside the curly braces, I want to meow one time. 1790 01:22:04,080 --> 01:22:06,990 And then, to be clear, what's this last line of code doing? 1791 01:22:06,990 --> 01:22:12,120 If counter starts off at three, this makes it 2 by subtracting 1 from it. 1792 01:22:12,120 --> 01:22:13,320 Then what happens? 1793 01:22:13,320 --> 01:22:17,620 By nature of the loop, just like in Scratch, it knows to go back and forth. 1794 01:22:17,620 --> 01:22:21,010 even though there's a nice, pretty arrow in Scratch, and there isn't here, 1795 01:22:21,010 --> 01:22:26,310 C knows to do this again, and again, and again, constantly asking this question 1796 01:22:26,310 --> 01:22:28,870 and then updating this value at the end. 1797 01:22:28,870 --> 01:22:33,690 So if I highlight just a few of these steps, the variable starts off at 3. 1798 01:22:33,690 --> 01:22:35,100 And actually, let me simplify 2. 1799 01:22:35,100 --> 01:22:37,980 I claimed earlier that when using single variables, 1800 01:22:37,980 --> 01:22:41,280 people very often just call it i for int, or c for char, 1801 01:22:41,280 --> 01:22:43,480 or s for string unless you have multiple variables. 1802 01:22:43,480 --> 01:22:44,730 So let me tighten the code up. 1803 01:22:44,730 --> 01:22:47,220 And this already makes it look a little more tolerable. 1804 01:22:47,220 --> 01:22:50,320 Let me actually tighten it up further, add one more step. 1805 01:22:50,320 --> 01:22:52,860 So now this is about as tight, as succinct 1806 01:22:52,860 --> 01:22:54,653 as you can make this code at the moment. 1807 01:22:54,653 --> 01:22:56,320 So what's actually going to happen here? 1808 01:22:56,320 --> 01:22:59,550 Well, the first line of code executes, and that initializes i to 3. 1809 01:22:59,550 --> 01:23:00,900 Then we check the condition. 1810 01:23:00,900 --> 01:23:03,840 While i is greater than 0, is i greater than 0? 1811 01:23:03,840 --> 01:23:05,580 Well, per my three fingers, obviously. 1812 01:23:05,580 --> 01:23:07,590 So we print out meow on the screen. 1813 01:23:07,590 --> 01:23:13,110 Then we subtract 1 from i, at which point now we have 2 as the value of i. 1814 01:23:13,110 --> 01:23:15,330 Then the code goes back to the condition. 1815 01:23:15,330 --> 01:23:17,580 And notice, the condition there is in parentheses. 1816 01:23:17,580 --> 01:23:19,420 That's another Boolean expression. 1817 01:23:19,420 --> 01:23:23,340 So loops can use Boolean expressions, just like conditionals use 1818 01:23:23,340 --> 01:23:24,990 Boolean expressions to make decisions. 1819 01:23:24,990 --> 01:23:27,840 The loop, though, is deciding not whether to do this thing or that 1820 01:23:27,840 --> 01:23:31,330 but whether to do the same thing again, and again, and again. 1821 01:23:31,330 --> 01:23:34,200 And as it ticks through the code one line after the other, 1822 01:23:34,200 --> 01:23:40,450 it's ultimately going to get down to 1, and then 0, and then stop. 1823 01:23:40,450 --> 01:23:45,330 So put another way-- came with some props here-- so suppose this ball here 1824 01:23:45,330 --> 01:23:49,410 is your variable, and you initialize it to 3 with three stress balls, 1825 01:23:49,410 --> 01:23:51,570 you can do something three times, right? 1826 01:23:51,570 --> 01:23:53,320 If I want to give out three stress balls-- 1827 01:23:53,320 --> 01:23:56,653 here's your chance for free stress balls without having to answer any questions. 1828 01:23:56,653 --> 01:23:57,400 OK, there we go. 1829 01:23:57,400 --> 01:24:00,180 So here we go, subtracting 1 from my variable. 1830 01:24:00,180 --> 01:24:01,830 I'm left with two. 1831 01:24:01,830 --> 01:24:02,460 Oh my god. 1832 01:24:02,460 --> 01:24:04,845 All right, don't tell Sanders. 1833 01:24:04,845 --> 01:24:07,470 [GRUNTS] Oh, I'm sorry. 1834 01:24:07,470 --> 01:24:08,080 Oh. 1835 01:24:08,080 --> 01:24:08,580 [LAUGHTER] 1836 01:24:08,580 --> 01:24:10,350 OK, that ended poorly. 1837 01:24:10,350 --> 01:24:11,070 Apologies. 1838 01:24:11,070 --> 01:24:11,570 All right. 1839 01:24:11,570 --> 01:24:13,740 But now the educational point, though, is 1840 01:24:13,740 --> 01:24:17,037 that my variable has been decrement did further to just have-- 1841 01:24:17,037 --> 01:24:18,370 I'm not throwing that far again. 1842 01:24:18,370 --> 01:24:19,620 I can't do this. 1843 01:24:19,620 --> 01:24:20,143 Here we go. 1844 01:24:20,143 --> 01:24:21,060 All right, here we go. 1845 01:24:21,060 --> 01:24:22,740 And one final subtraction. 1846 01:24:22,740 --> 01:24:24,880 And now our variable is left empty. 1847 01:24:24,880 --> 01:24:28,380 So we had three stress balls there, and that's all a variable is. 1848 01:24:28,380 --> 01:24:29,475 It's some kind of storage. 1849 01:24:29,475 --> 01:24:32,100 It's actually, of course, implemented in the computer's memory. 1850 01:24:32,100 --> 01:24:35,860 But metaphorically, it's really just a bowl with some values. 1851 01:24:35,860 --> 01:24:37,800 And every time you or, in this case, subtract, 1852 01:24:37,800 --> 01:24:39,840 you're just changing the value of that variable. 1853 01:24:39,840 --> 01:24:43,830 And then the code, meanwhile, of course, in parentheses, is just checking, 1854 01:24:43,830 --> 01:24:44,610 is the bowl empty? 1855 01:24:44,610 --> 01:24:45,360 Is the bowl empty? 1856 01:24:45,360 --> 01:24:46,570 Is the bowl empty? 1857 01:24:46,570 --> 01:24:50,350 AKA, is i greater than 0 or not? 1858 01:24:50,350 --> 01:24:55,210 Any questions on how we've implemented loops in this way? 1859 01:24:55,210 --> 01:24:58,080 And I owe you a stress ball after class. 1860 01:24:58,080 --> 01:24:59,820 Questions on loops? 1861 01:24:59,820 --> 01:25:03,240 All right, so it turns out, this is kind of ugly. 1862 01:25:03,240 --> 01:25:05,580 And this really starts to take the fun out 1863 01:25:05,580 --> 01:25:09,422 of programming when you have to write out this sequence of steps. 1864 01:25:09,422 --> 01:25:11,380 So it turns out, there's other ways to do this. 1865 01:25:11,380 --> 01:25:13,110 But first, let's see, logically, how else 1866 01:25:13,110 --> 01:25:16,410 you might express this because it's a little weird that we keep using zero. 1867 01:25:16,410 --> 01:25:19,890 So the one other way to do this would be to invert the logic. 1868 01:25:19,890 --> 01:25:23,820 You could absolutely start with your variable, call it i equal to 1. 1869 01:25:23,820 --> 01:25:28,290 And then you could ask the question, is i less than or equal to 3? 1870 01:25:28,290 --> 01:25:30,210 And notice a bit of new syntax here. 1871 01:25:30,210 --> 01:25:33,330 On your typical keyboard, there is number less than 1872 01:25:33,330 --> 01:25:35,370 or equal sign or greater than or equal sign 1873 01:25:35,370 --> 01:25:37,870 like you would write in math class with 1 over the other. 1874 01:25:37,870 --> 01:25:42,390 And so in C, you use two characters, less than followed by an equal sign 1875 01:25:42,390 --> 01:25:45,360 or, if appropriate, greater than followed by in equal sign. 1876 01:25:45,360 --> 01:25:47,370 And that logically captures that idea. 1877 01:25:47,370 --> 01:25:50,580 So notice that I'm changing my questions. 1878 01:25:50,580 --> 01:25:53,910 I'm initializing i to 1, and then I'm going to increment it ultimately 1879 01:25:53,910 --> 01:25:55,830 to 2 and then 3. 1880 01:25:55,830 --> 01:25:57,930 But because I'm doing less than or equal to, 1881 01:25:57,930 --> 01:26:00,340 it's still going to go from 1, 2, 3. 1882 01:26:00,340 --> 01:26:01,530 So that works too. 1883 01:26:01,530 --> 01:26:03,810 We could similarly do this yet another way. 1884 01:26:03,810 --> 01:26:10,320 We could initialize i to 0, and then we could say, well, i is less than 3 1885 01:26:10,320 --> 01:26:11,640 and keep incrementing it. 1886 01:26:11,640 --> 01:26:14,940 And I showed this last form is actually the most canonical. 1887 01:26:14,940 --> 01:26:18,420 It might be the most human-like to think in terms of 1 to 3. 1888 01:26:18,420 --> 01:26:22,620 It might be the most stressball-like to think in terms of 3 to 0, 1889 01:26:22,620 --> 01:26:23,740 counting down. 1890 01:26:23,740 --> 01:26:26,730 But typically, the go-to syntax for most programmers 1891 01:26:26,730 --> 01:26:31,440 once you get comfortable counting from 0 is to always start counting from 0 1892 01:26:31,440 --> 01:26:35,610 and count up to less than the value you're counting up to. 1893 01:26:35,610 --> 01:26:40,043 So it would be incorrect, why, to change this to less than or equal to 3 here? 1894 01:26:40,043 --> 01:26:42,960 What would happen if I changed the less than to less than or equal to? 1895 01:26:42,960 --> 01:26:44,340 AUDIENCE: It'll only meow twice. 1896 01:26:44,340 --> 01:26:47,280 DAVID J. MALAN: Yeah, it'll meow an extra-- a fourth time, in fact, total, 1897 01:26:47,280 --> 01:26:47,780 right? 1898 01:26:47,780 --> 01:26:51,150 Because you'll start at 0, then 1, then 2, then 3. 1899 01:26:51,150 --> 01:26:53,220 And less than or equal to 3-- sorry-- 1900 01:26:53,220 --> 01:26:55,420 3 will give you the fourth time. 1901 01:26:55,420 --> 01:26:58,650 So we do want indeed to be just a single less than. 1902 01:26:58,650 --> 01:27:01,198 All right, so now that we have those options, 1903 01:27:01,198 --> 01:27:02,490 let me just give you one other. 1904 01:27:02,490 --> 01:27:04,907 And this one takes a little more, getting used to as well, 1905 01:27:04,907 --> 01:27:07,210 but it's probably the more common way to write this. 1906 01:27:07,210 --> 01:27:11,590 Let me go ahead and propose that we implement this as follows. 1907 01:27:11,590 --> 01:27:13,390 Let me go back to my code here. 1908 01:27:13,390 --> 01:27:20,040 Let me go into my several printfs, getting rid of all but one of them 1909 01:27:20,040 --> 01:27:21,000 ultimately. 1910 01:27:21,000 --> 01:27:22,750 And let's implement this in code. 1911 01:27:22,750 --> 01:27:30,510 So let's do int i get 0, how about then while i is less than 3, 1912 01:27:30,510 --> 01:27:33,960 then let's go ahead and say printf quote/unquote meow-- 1913 01:27:33,960 --> 01:27:36,930 melow-- meow backslash n. 1914 01:27:36,930 --> 01:27:41,310 And then we have to do i minus minus or plus plus? 1915 01:27:41,310 --> 01:27:42,237 AUDIENCE: Plus plus. 1916 01:27:42,237 --> 01:27:44,570 DAVID J. MALAN: So plus plus because we're starting at 0 1917 01:27:44,570 --> 01:27:47,120 and going up to but not through 3. 1918 01:27:47,120 --> 01:27:51,678 So let me go ahead now and make meow after clearing my terminal, ./meow, 1919 01:27:51,678 --> 01:27:52,970 and it's still just as correct. 1920 01:27:52,970 --> 01:27:55,400 But it's a little more-- 1921 01:27:55,400 --> 01:27:56,730 it's a little better designed. 1922 01:27:56,730 --> 01:27:57,230 Why? 1923 01:27:57,230 --> 01:28:00,770 Because now if I want to change it from 3 to 30 times, for instance, 1924 01:28:00,770 --> 01:28:01,850 I can change it there. 1925 01:28:01,850 --> 01:28:03,770 I can recompile my code. 1926 01:28:03,770 --> 01:28:06,020 I can do ./meow, and done. 1927 01:28:06,020 --> 01:28:09,450 I don't have to copy and paste it 27 more times to get that effect. 1928 01:28:09,450 --> 01:28:13,400 And I can even change what the word is by changing it in just one location. 1929 01:28:13,400 --> 01:28:15,920 But it turns out, there's other ways to do this too. 1930 01:28:15,920 --> 01:28:20,502 And let me propose that we introduce you to what's called a for loop as well. 1931 01:28:20,502 --> 01:28:22,460 So if you want to repeat something three times, 1932 01:28:22,460 --> 01:28:25,940 you can absolutely take the while loop approach that we just saw, 1933 01:28:25,940 --> 01:28:27,500 or you can do this. 1934 01:28:27,500 --> 01:28:30,270 And this one takes a little more, getting used to, 1935 01:28:30,270 --> 01:28:34,200 but it kind of consolidates into one line all of the same logic. 1936 01:28:34,200 --> 01:28:36,830 So notice, we have the keyword for here. 1937 01:28:36,830 --> 01:28:40,730 And for is just a preposition in this case that generally implies, 1938 01:28:40,730 --> 01:28:42,110 here comes a loop. 1939 01:28:42,110 --> 01:28:46,097 Inside of parentheses here is not just a Boolean expression. 1940 01:28:46,097 --> 01:28:47,930 And this is where things get a little weird. 1941 01:28:47,930 --> 01:28:50,900 There's three things-- to the left of the semicolon, 1942 01:28:50,900 --> 01:28:54,230 in the middle of the two semicolons, and to the right of the semicolon. 1943 01:28:54,230 --> 01:28:58,198 This is really the only other context we'll see semicolons, and it's weird. 1944 01:28:58,198 --> 01:28:59,990 Normally, it's been at the end of the line. 1945 01:28:59,990 --> 01:29:02,030 Now it's two of them in the middle of the line, 1946 01:29:02,030 --> 01:29:04,920 but this is the way humans decided years ago to do it. 1947 01:29:04,920 --> 01:29:06,080 So what is this doing? 1948 01:29:06,080 --> 01:29:07,850 Almost the same thing. 1949 01:29:07,850 --> 01:29:12,320 It is going to initialize a variable called i to 0. 1950 01:29:12,320 --> 01:29:14,240 It's going to then check. 1951 01:29:14,240 --> 01:29:19,880 If it's less than 3, it's then going to do whatever's in the curly braces, 1952 01:29:19,880 --> 01:29:22,980 and it's lastly going to increment i and repeat. 1953 01:29:22,980 --> 01:29:26,240 So just highlighting those in turn, at first, i 1954 01:29:26,240 --> 01:29:28,340 is initialized to 0, just like before. 1955 01:29:28,340 --> 01:29:30,170 Then this condition is checked. 1956 01:29:30,170 --> 01:29:32,150 This is a Boolean expression. 1957 01:29:32,150 --> 01:29:34,610 Yes or no, true or false will be its answer. 1958 01:29:34,610 --> 01:29:37,970 And if i is less than 3, which it should be once it starts at 0, 1959 01:29:37,970 --> 01:29:40,550 well, then we're going to go ahead and print out meow. 1960 01:29:40,550 --> 01:29:42,350 Then i is going to get incremented. 1961 01:29:42,350 --> 01:29:43,580 So it starts at 0. 1962 01:29:43,580 --> 01:29:45,170 It goes now to 1. 1963 01:29:45,170 --> 01:29:48,150 At that point, the Boolean expression is checked again. 1964 01:29:48,150 --> 01:29:50,840 So you don't keep changing i back to 0. 1965 01:29:50,840 --> 01:29:53,210 That first step happens only once. 1966 01:29:53,210 --> 01:29:56,270 But now you repeat through those three other highlights. 1967 01:29:56,270 --> 01:29:57,770 I check if i is less than 3. 1968 01:29:57,770 --> 01:29:58,320 It is. 1969 01:29:58,320 --> 01:29:59,600 So I print out meow. 1970 01:29:59,600 --> 01:30:00,875 It then increments i. 1971 01:30:00,875 --> 01:30:03,410 I check if i, now 2, is less than 3. 1972 01:30:03,410 --> 01:30:03,980 It is. 1973 01:30:03,980 --> 01:30:05,240 I print out meow. 1974 01:30:05,240 --> 01:30:06,380 i gets incremented. 1975 01:30:06,380 --> 01:30:07,100 I now check. 1976 01:30:07,100 --> 01:30:08,120 Is i less than 3? 1977 01:30:08,120 --> 01:30:11,360 No, it's not, because 3 is not less than 3. 1978 01:30:11,360 --> 01:30:12,800 And so the whole thing stops. 1979 01:30:12,800 --> 01:30:15,950 And whatever code is below this curly brace, if any, 1980 01:30:15,950 --> 01:30:17,420 starts executing instead. 1981 01:30:17,420 --> 01:30:21,470 Just like in Scratch, you break out of the loop and the puzzle pieces 1982 01:30:21,470 --> 01:30:22,610 being hugged. 1983 01:30:22,610 --> 01:30:31,520 Questions, then, about this alternative syntax for loops, AKA, a for loop? 1984 01:30:31,520 --> 01:30:34,195 AUDIENCE: Can you explain again why it doesn't go back to 0? 1985 01:30:34,195 --> 01:30:35,570 DAVID J. MALAN: Sorry, say again? 1986 01:30:35,570 --> 01:30:37,400 AUDIENCE: Can you explain again why it doesn't reset to 0? 1987 01:30:37,400 --> 01:30:38,275 DAVID J. MALAN: Yeah. 1988 01:30:38,275 --> 01:30:40,400 Can I explain again why it doesn't reset to 0? 1989 01:30:40,400 --> 01:30:41,690 Honestly, just because. 1990 01:30:41,690 --> 01:30:43,490 This was the syntax they chose. 1991 01:30:43,490 --> 01:30:45,620 This first part before the first semicolon 1992 01:30:45,620 --> 01:30:47,660 is only executed once just because. 1993 01:30:47,660 --> 01:30:48,740 That's how it's designed. 1994 01:30:48,740 --> 01:30:51,660 Everything else cycles again and again. 1995 01:30:51,660 --> 01:30:54,277 And this is just an alternative syntax to using 1996 01:30:54,277 --> 01:30:55,610 the slightly more lines of code. 1997 01:30:55,610 --> 01:30:57,818 It was, like, six lines of code using the while loop. 1998 01:30:57,818 --> 01:30:59,387 Logically, it's the same thing. 1999 01:30:59,387 --> 01:31:01,220 Programmers, once they get more comfortable, 2000 01:31:01,220 --> 01:31:04,053 tend to prefer this because it just expresses all your same thoughts 2001 01:31:04,053 --> 01:31:05,240 more succinctly. 2002 01:31:05,240 --> 01:31:06,380 That's all. 2003 01:31:06,380 --> 01:31:06,890 Yeah? 2004 01:31:06,890 --> 01:31:07,620 AUDIENCE: That was my question. 2005 01:31:07,620 --> 01:31:08,412 DAVID J. MALAN: OK. 2006 01:31:08,412 --> 01:31:11,210 So let's just work this into my meow example. 2007 01:31:11,210 --> 01:31:12,590 Let me go back to the code here. 2008 01:31:12,590 --> 01:31:14,898 And notice, indeed, if I highlight all these lines, 2009 01:31:14,898 --> 01:31:16,190 I think we can tighten this up. 2010 01:31:16,190 --> 01:31:21,350 Let me get rid of all of those and instead do for int i equals 0. 2011 01:31:21,350 --> 01:31:22,790 And I'm saying equals. 2012 01:31:22,790 --> 01:31:24,260 Most programmers would say gets. 2013 01:31:24,260 --> 01:31:28,130 So int i gets 0 means assignment-- the word get. 2014 01:31:28,130 --> 01:31:32,360 Now I'm going to do i is less than 3 i++. 2015 01:31:32,360 --> 01:31:37,670 Now in here I'm going to do my printf quote/unquote meow backslash n. 2016 01:31:37,670 --> 01:31:39,450 And so it's indeed a little tighter. 2017 01:31:39,450 --> 01:31:41,408 I mean, two of the lines are just curly braces. 2018 01:31:41,408 --> 01:31:43,580 There's really only two juicy lines of code now. 2019 01:31:43,580 --> 01:31:47,460 Let me go ahead and do make meow, ./meow. 2020 01:31:47,460 --> 01:31:51,680 And again, we're back in business with three of them printing only. 2021 01:31:51,680 --> 01:31:54,050 All right, there's one last structure we should explore 2022 01:31:54,050 --> 01:31:56,330 just because it's sometimes useful. 2023 01:31:56,330 --> 01:31:58,010 This was a forever block. 2024 01:31:58,010 --> 01:32:00,170 And this would be a little weird in Scratch 2025 01:32:00,170 --> 01:32:02,750 to just say meow forever, or at least without waiting. 2026 01:32:02,750 --> 01:32:06,290 But there is indeed a forever block in Scratch, which means do the following, 2027 01:32:06,290 --> 01:32:07,490 forever. 2028 01:32:07,490 --> 01:32:10,485 And I proposed, I think, verbally last week at least one example 2029 01:32:10,485 --> 01:32:11,360 where this is useful. 2030 01:32:11,360 --> 01:32:13,040 Meowing forever, a little annoying. 2031 01:32:13,040 --> 01:32:14,990 But can you think of common cases where you 2032 01:32:14,990 --> 01:32:19,100 might want to write code or use a program that loops forever? 2033 01:32:19,100 --> 01:32:19,657 Yeah? 2034 01:32:19,657 --> 01:32:21,740 AUDIENCE: Playing music throughout an entire game. 2035 01:32:21,740 --> 01:32:22,970 DAVID J. MALAN: Yeah, playing music. 2036 01:32:22,970 --> 01:32:25,370 Like Spotify playlists, just repeating again and again 2037 01:32:25,370 --> 01:32:26,495 would be some kind of loop. 2038 01:32:26,495 --> 01:32:28,310 AUDIENCE: Checking for collisions. 2039 01:32:28,310 --> 01:32:29,840 DAVID J. MALAN: Checking for collisions in Scratch, 2040 01:32:29,840 --> 01:32:32,548 so seeing if something's bouncing off the wall or another sprite. 2041 01:32:32,548 --> 01:32:33,590 Yeah? 2042 01:32:33,590 --> 01:32:36,512 AUDIENCE: Oh, checking for input. 2043 01:32:36,512 --> 01:32:37,970 DAVID J. MALAN: Checking for input. 2044 01:32:37,970 --> 01:32:40,900 So yeah, get_string is essentially just waiting there forever 2045 01:32:40,900 --> 01:32:43,300 for me to type in some input until I do. 2046 01:32:43,300 --> 01:32:44,470 AUDIENCE: Checking the time. 2047 01:32:44,470 --> 01:32:45,760 DAVID J. MALAN: Checking the time and actually 2048 01:32:45,760 --> 01:32:47,860 maintaining human time, like a wall clock. 2049 01:32:47,860 --> 01:32:48,550 Behind you? 2050 01:32:48,550 --> 01:32:49,420 Is that the same? 2051 01:32:49,420 --> 01:32:50,590 AUDIENCE: I was going to say checking the time. 2052 01:32:50,590 --> 01:32:52,173 DAVID J. MALAN: OK, checking the time. 2053 01:32:52,173 --> 01:32:52,900 And one more? 2054 01:32:52,900 --> 01:32:53,995 Detecting a key press too. 2055 01:32:53,995 --> 01:32:56,620 Like in Scratch, just waiting for some kind of event to happen, 2056 01:32:56,620 --> 01:32:58,182 just like on a phone or a browser. 2057 01:32:58,182 --> 01:32:59,890 And so there's so many examples where you 2058 01:32:59,890 --> 01:33:01,510 might want to do something forever-- 2059 01:33:01,510 --> 01:33:04,520 just so you've seen the corresponding C building block. 2060 01:33:04,520 --> 01:33:08,290 It's a little weird, but this is probably the most canonical way 2061 01:33:08,290 --> 01:33:11,783 to do it in C. If you want to print meow forever-- 2062 01:33:11,783 --> 01:33:14,950 which would be a little crazy because it would literally print and take over 2063 01:33:14,950 --> 01:33:16,990 your computer printing forever meow-- 2064 01:33:16,990 --> 01:33:18,850 you would generally do it like this. 2065 01:33:18,850 --> 01:33:19,490 Why? 2066 01:33:19,490 --> 01:33:22,810 Well, a while loop expects in parentheses a Boolean expression, 2067 01:33:22,810 --> 01:33:26,020 and a Boolean expression is, again, a yes/no, a true/false question. 2068 01:33:26,020 --> 01:33:29,620 But if you want the answer to that question always to be yes-- 2069 01:33:29,620 --> 01:33:33,490 or really, always to be true, turns out in C and a lot of languages 2070 01:33:33,490 --> 01:33:35,950 will then just say true because true-- 2071 01:33:35,950 --> 01:33:38,800 T-R-U-E-- is never going to change magically to false. 2072 01:33:38,800 --> 01:33:41,570 I mean, it's just a special word in the programming language. 2073 01:33:41,570 --> 01:33:45,680 So by saying while true, it just means do the following forever. 2074 01:33:45,680 --> 01:33:48,580 Another common paradigm before true and false 2075 01:33:48,580 --> 01:33:52,300 became commonplace would be to do this instead-- 2076 01:33:52,300 --> 01:33:54,220 change while 1. 2077 01:33:54,220 --> 01:33:57,820 You might see in online examples and texts and the like, 2078 01:33:57,820 --> 01:33:59,770 while 1 is really the same thing. 2079 01:33:59,770 --> 01:34:04,840 Any value that is 0 is generally interpreted as false by a computer. 2080 01:34:04,840 --> 01:34:09,310 Any value that is 1 or any other non-zero value 2081 01:34:09,310 --> 01:34:11,210 is generally interpreted as true. 2082 01:34:11,210 --> 01:34:15,400 And so this, too, would have the same effect, saying while true or while 1. 2083 01:34:15,400 --> 01:34:18,700 Generally speaking, while true is perhaps a little clearer these days. 2084 01:34:18,700 --> 01:34:20,650 Now, meowing forever is not a good thing. 2085 01:34:20,650 --> 01:34:23,770 But suppose I did that by intent or by accident. 2086 01:34:23,770 --> 01:34:24,950 Well, let's try this. 2087 01:34:24,950 --> 01:34:26,570 So here I'll go into my code. 2088 01:34:26,570 --> 01:34:30,550 I'm going to get rid of for loop and change my while loop to, how about, 2089 01:34:30,550 --> 01:34:32,180 true. 2090 01:34:32,180 --> 01:34:36,100 And in this case here, well, we'll keep it-- let's do this. 2091 01:34:36,100 --> 01:34:38,230 Make meow, Enter. 2092 01:34:38,230 --> 01:34:41,840 And you'll see this, use of undeclared identifier true. 2093 01:34:41,840 --> 01:34:46,360 This is actually hinting at my mention that the old way was 0 and 1. 2094 01:34:46,360 --> 01:34:48,220 Nowadays, you could say true or false. 2095 01:34:48,220 --> 01:34:53,560 But true and false are themselves special words that you have to include. 2096 01:34:53,560 --> 01:34:56,740 And it turns out, if you want to use special Boolean values like this, 2097 01:34:56,740 --> 01:35:00,850 there's another header file we haven't seen called stdbool that essentially 2098 01:35:00,850 --> 01:35:03,640 creates true and false as keywords. 2099 01:35:03,640 --> 01:35:06,550 Alternatively, CS50 includes that same file. 2100 01:35:06,550 --> 01:35:08,980 So it's more common in CS50 is to see it like this. 2101 01:35:08,980 --> 01:35:13,360 Now if I clear my terminal window and do make meow and then ./meow and hit 2102 01:35:13,360 --> 01:35:18,970 Enter, well, unfortunately, this isn't the best thing to do infinitely when 2103 01:35:18,970 --> 01:35:21,350 you're in the cloud using a browser. 2104 01:35:21,350 --> 01:35:24,970 This is indeed a browser, just full-screened here. 2105 01:35:24,970 --> 01:35:29,462 This means I'm sending millions of meows over the internet to my computer here. 2106 01:35:29,462 --> 01:35:32,170 So this will happen to you at some point, probably not with meow. 2107 01:35:32,170 --> 01:35:34,150 But you'll lose control over your terminal window. 2108 01:35:34,150 --> 01:35:34,420 Why? 2109 01:35:34,420 --> 01:35:35,170 Because you screwed up. 2110 01:35:35,170 --> 01:35:36,250 And you have an infinite loop. 2111 01:35:36,250 --> 01:35:37,090 You didn't really intend it. 2112 01:35:37,090 --> 01:35:37,690 Or maybe you did. 2113 01:35:37,690 --> 01:35:39,232 You were curious to see what happens. 2114 01:35:39,232 --> 01:35:41,590 What do you do? 2115 01:35:41,590 --> 01:35:43,930 When does the meowing stop? 2116 01:35:43,930 --> 01:35:45,910 What recourse do we have here? 2117 01:35:45,910 --> 01:35:48,550 Well, Control-C will be your friend. 2118 01:35:48,550 --> 01:35:51,070 Sometimes you have to hit it a bunch in a cloud environment. 2119 01:35:51,070 --> 01:35:55,540 But Control-C for cancel will interrupt a program that's running. 2120 01:35:55,540 --> 01:35:58,660 And I promise that almost all of you will at some point 2121 01:35:58,660 --> 01:36:02,560 accidentally introduce an infinite loop because your math is slightly off. 2122 01:36:02,560 --> 01:36:05,680 When in doubt, click in the terminal window and hit Control-C-- 2123 01:36:05,680 --> 01:36:07,060 sometimes multiple times-- 2124 01:36:07,060 --> 01:36:09,545 and that will indeed cancel whatever is happening there. 2125 01:36:09,545 --> 01:36:11,170 In this case, I might have intended it. 2126 01:36:11,170 --> 01:36:14,330 But sometimes it's not, in fact, intended. 2127 01:36:14,330 --> 01:36:18,010 All right, so we've been taking for granted this whole graphical user 2128 01:36:18,010 --> 01:36:22,557 interface for some time and, indeed, the commands that I'm typing 2129 01:36:22,557 --> 01:36:23,890 and the buttons on I'm clicking. 2130 01:36:23,890 --> 01:36:25,848 And let me just give you a better sense of what 2131 01:36:25,848 --> 01:36:29,290 it is we are using underneath the hood this whole time, 2132 01:36:29,290 --> 01:36:31,630 namely an operating system called Linux. 2133 01:36:31,630 --> 01:36:34,270 So I keep alluding verbally, of course, to Macs and PCs 2134 01:36:34,270 --> 01:36:37,690 because almost all of us are running macOS or Windows on our desktops 2135 01:36:37,690 --> 01:36:38,680 or laptops nowadays. 2136 01:36:38,680 --> 01:36:40,930 But there's lots of other operating systems out there, 2137 01:36:40,930 --> 01:36:43,330 and one of the most popular one is called Linux. 2138 01:36:43,330 --> 01:36:47,680 And Linux is very often used on servers nowadays-- companies 2139 01:36:47,680 --> 01:36:51,610 that host email, companies that host websites or apps, more generally. 2140 01:36:51,610 --> 01:36:53,980 Certain computer scientists or computer science students 2141 01:36:53,980 --> 01:36:56,950 often like to brag that they run Linux just because that's a thing. 2142 01:36:56,950 --> 01:37:01,030 But it is really just an alternative to macOS or Windows 2143 01:37:01,030 --> 01:37:04,150 that provides you with both a GUI, if you want it, 2144 01:37:04,150 --> 01:37:07,480 but also an especially a command line environment. 2145 01:37:07,480 --> 01:37:12,040 Now, fun fact-- Windows and macOS do have terminal windows or the equivalent 2146 01:37:12,040 --> 01:37:12,550 thereof. 2147 01:37:12,550 --> 01:37:16,150 And eventually, you might use it on your own Mac or PC to solve some problem. 2148 01:37:16,150 --> 01:37:19,690 But Linux is really known for, along with other operating systems, 2149 01:37:19,690 --> 01:37:23,530 its command line environment, which, again, I distinguished earlier from GUI 2150 01:37:23,530 --> 01:37:26,500 as a Command Line Interface, or CLI. 2151 01:37:26,500 --> 01:37:29,450 And that refers, really, to the terminal window. 2152 01:37:29,450 --> 01:37:33,790 So if I go back to VS Code here, and let me, in fact, go ahead and close my tab 2153 01:37:33,790 --> 01:37:36,160 and focus entirely on the terminal window, 2154 01:37:36,160 --> 01:37:39,640 this terminal window is really just your command line interface 2155 01:37:39,640 --> 01:37:42,390 to your very own server in the cloud. 2156 01:37:42,390 --> 01:37:44,140 The term of art here is you each will have 2157 01:37:44,140 --> 01:37:47,530 your own container in the cloud, which is like your own computer 2158 01:37:47,530 --> 01:37:51,430 running somewhere on the internet with your own username and password 2159 01:37:51,430 --> 01:37:54,530 to which you have access and your own hard drive, if you will, 2160 01:37:54,530 --> 01:37:57,430 your own home folder that has all of your files for the class. 2161 01:37:57,430 --> 01:38:01,390 And it's only accessible to you unless you enable live sharing thereof. 2162 01:38:01,390 --> 01:38:03,880 So when you're typing commands here, it looks 2163 01:38:03,880 --> 01:38:06,400 like you're typing them, of course, on your own Mac or PC. 2164 01:38:06,400 --> 01:38:09,070 But they're actually being sent over the browser 2165 01:38:09,070 --> 01:38:13,570 to some server in the cloud where you are controlling, really, 2166 01:38:13,570 --> 01:38:15,830 your own account therein. 2167 01:38:15,830 --> 01:38:19,390 So it turns out that there are other commands that are worth knowing. 2168 01:38:19,390 --> 01:38:21,292 And we'll give you just a few of these today. 2169 01:38:21,292 --> 01:38:23,500 And over the coming weeks will you have opportunities 2170 01:38:23,500 --> 01:38:24,710 to play with others as well. 2171 01:38:24,710 --> 01:38:26,260 But these are some of the basics. 2172 01:38:26,260 --> 01:38:29,782 And they're all incredibly succinct because, indeed, for things you're 2173 01:38:29,782 --> 01:38:31,990 typing at the command line, humans generally have not 2174 01:38:31,990 --> 01:38:33,640 wanted to type out long commands. 2175 01:38:33,640 --> 01:38:35,890 So a lot of these are abbreviations here. 2176 01:38:35,890 --> 01:38:38,590 Now, perhaps the most common one I'll start with first 2177 01:38:38,590 --> 01:38:44,480 is ls, a lowercase l and a lowercase s that stands for, succinctly, list. 2178 01:38:44,480 --> 01:38:47,380 So if I go to my terminal window now where up until now, 2179 01:38:47,380 --> 01:38:51,370 I've only typed code, which is a VS Code thing for creating an opening files, 2180 01:38:51,370 --> 01:38:56,110 and make, which triggers the compilation of my code, what if I now type ls? 2181 01:38:56,110 --> 01:39:00,070 This will list all of the files in my current folder-- 2182 01:39:00,070 --> 01:39:02,000 my hard drive in the cloud, if you will. 2183 01:39:02,000 --> 01:39:05,780 So if I hit Enter, you'll see a whole bunch of results. 2184 01:39:05,780 --> 01:39:07,240 Now, they're color coded too. 2185 01:39:07,240 --> 01:39:09,910 The white ones here end in .c. 2186 01:39:09,910 --> 01:39:11,980 Those are the source code files I've written 2187 01:39:11,980 --> 01:39:15,790 during class today-- agree.c, compare.c, hello.c, and meow.c. 2188 01:39:15,790 --> 01:39:19,270 And you can perhaps guess, the green ones here that just by convention 2189 01:39:19,270 --> 01:39:24,382 have an asterisk on the end to denote that they're special represent what? 2190 01:39:24,382 --> 01:39:25,340 One of the four others. 2191 01:39:25,340 --> 01:39:26,315 Yeah? 2192 01:39:26,315 --> 01:39:27,800 AUDIENCE: The machine code? 2193 01:39:27,800 --> 01:39:29,520 DAVID J. MALAN: Yeah, the machine code. 2194 01:39:29,520 --> 01:39:33,710 So those are my actual programs that are identically named minus the .c 2195 01:39:33,710 --> 01:39:34,340 extension. 2196 01:39:34,340 --> 01:39:36,830 And the asterisk means that they're executable. 2197 01:39:36,830 --> 01:39:39,582 That is in the world of macOS or Windows, you would double click. 2198 01:39:39,582 --> 01:39:41,540 But in the world of a command line environment, 2199 01:39:41,540 --> 01:39:46,280 that means you do ./ and then the name without the asterisk to execute or run 2200 01:39:46,280 --> 01:39:47,400 the code therein. 2201 01:39:47,400 --> 01:39:51,560 So if I open up my File Explorer-- and I'm hitting Command-B on my computer 2202 01:39:51,560 --> 01:39:54,990 here just as a keyboard shortcut-- you'll see the exact same thing. 2203 01:39:54,990 --> 01:39:59,210 So ls is the command line interface for listing the files in your account. 2204 01:39:59,210 --> 01:40:03,060 But here, because I'm using VS Code or any program like it, 2205 01:40:03,060 --> 01:40:06,213 I also get a graphical user interface as well. 2206 01:40:06,213 --> 01:40:07,880 So it's just two different places to be. 2207 01:40:07,880 --> 01:40:09,680 You're welcome to use whatever you're comfortable with. 2208 01:40:09,680 --> 01:40:12,260 But over time will you naturally get more comfortable 2209 01:40:12,260 --> 01:40:14,720 and capable with the terminal window alone. 2210 01:40:14,720 --> 01:40:16,773 Well, what else is on this list here? 2211 01:40:16,773 --> 01:40:19,190 Well, during the break, I saw that in at least one of you, 2212 01:40:19,190 --> 01:40:23,330 for instance, had created a file called hello instead of hello.c. 2213 01:40:23,330 --> 01:40:27,230 So you were in a situation where you did this accidentally and hit Enter. 2214 01:40:27,230 --> 01:40:30,420 And then you went ahead and typed in all of your code like this. 2215 01:40:30,420 --> 01:40:32,270 And then down in your terminal window, you 2216 01:40:32,270 --> 01:40:34,760 were trying to do make hello, Enter. 2217 01:40:34,760 --> 01:40:38,960 And this now didn't actually do anything. 2218 01:40:38,960 --> 01:40:40,820 I can't-- I'm hitting-- 2219 01:40:40,820 --> 01:40:42,380 I'm trying to run the command. 2220 01:40:42,380 --> 01:40:44,690 I got permission denied, as at least one of you did. 2221 01:40:44,690 --> 01:40:45,433 Now, why is that? 2222 01:40:45,433 --> 01:40:46,850 Well, let's just do a quick check. 2223 01:40:46,850 --> 01:40:50,690 If I do ls, I see now hello, but hello has 2224 01:40:50,690 --> 01:40:53,180 no asterisk next to it, which means it's not executable. 2225 01:40:53,180 --> 01:40:53,930 That's my code. 2226 01:40:53,930 --> 01:40:54,470 Why? 2227 01:40:54,470 --> 01:40:57,540 Well, notice the top of my tab confirms, oh, I screwed up. 2228 01:40:57,540 --> 01:41:00,740 I didn't name my file hello.c, which it just has to be. 2229 01:41:00,740 --> 01:41:01,920 So what do you do? 2230 01:41:01,920 --> 01:41:05,810 Well, you could very hackishly copy this, create a new file, paste it in. 2231 01:41:05,810 --> 01:41:06,770 Or no, no, no. 2232 01:41:06,770 --> 01:41:09,890 We know how to rename things now here because that's one of our options. 2233 01:41:09,890 --> 01:41:11,100 Let me do this. 2234 01:41:11,100 --> 01:41:17,600 Let me do mv for move, hello, and then hello.c, and hit Enter. 2235 01:41:17,600 --> 01:41:20,250 You'll see the tab closes because hello no longer exists. 2236 01:41:20,250 --> 01:41:25,130 But if I now type ls, you'll see, ah, there is hello.c. 2237 01:41:25,130 --> 01:41:28,910 And if I open that file now, whew, there's all of my same code. 2238 01:41:28,910 --> 01:41:31,010 And now if I do make hello-- 2239 01:41:31,010 --> 01:41:37,350 make hello-- now I do get an executable file where in the world is restored. 2240 01:41:37,350 --> 01:41:40,950 So mv, it's just a command not just for renaming, but it also turns out, 2241 01:41:40,950 --> 01:41:43,020 eventually for moving files as well. 2242 01:41:43,020 --> 01:41:45,230 You can also create directories or folders. 2243 01:41:45,230 --> 01:41:48,950 So for instance, if I go into VS Code again, and suppose 2244 01:41:48,950 --> 01:41:52,760 I hover over here and click not on the plus file icon but plus folder, 2245 01:41:52,760 --> 01:41:56,210 I can create a folder called, for instance, pset1 for problem 2246 01:41:56,210 --> 01:41:57,620 set 1 in the class. 2247 01:41:57,620 --> 01:42:00,290 And you'll see now that it's empty because all of my other files 2248 01:42:00,290 --> 01:42:02,840 are in the default folder of my account. 2249 01:42:02,840 --> 01:42:05,460 But I could also go in there like this. 2250 01:42:05,460 --> 01:42:11,060 And I could click on File, and now I can create a new file called mario.c, 2251 01:42:11,060 --> 01:42:13,430 which is one of the first problems, for instance. 2252 01:42:13,430 --> 01:42:18,960 But you'll notice now that mario.c is inside of the pset1 folder. 2253 01:42:18,960 --> 01:42:23,300 So if I zoom out and I type ls at my terminal window, 2254 01:42:23,300 --> 01:42:26,720 I won't see mario.c anywhere. 2255 01:42:26,720 --> 01:42:28,688 But I do see a pset1 folder. 2256 01:42:28,688 --> 01:42:31,730 And it's in light blue followed by a slash, which you don't have to type. 2257 01:42:31,730 --> 01:42:33,300 It just indicates that's a folder. 2258 01:42:33,300 --> 01:42:37,640 Now, I can visually at top left obviously see pwet1 contains mario.c. 2259 01:42:37,640 --> 01:42:40,610 But if I try to do something like make mario here, 2260 01:42:40,610 --> 01:42:42,800 no rule to make target mario. 2261 01:42:42,800 --> 01:42:44,510 It just doesn't seem to exist. 2262 01:42:44,510 --> 01:42:46,650 And that's because you're in the wrong directory. 2263 01:42:46,650 --> 01:42:49,010 So in a command line interface, it's not quite as simple 2264 01:42:49,010 --> 01:42:51,560 as just clicking on a folder, and voila, it opens. 2265 01:42:51,560 --> 01:42:55,250 You have to change into the directory or folder. 2266 01:42:55,250 --> 01:42:57,660 And cd is going to be the command there. 2267 01:42:57,660 --> 01:43:00,600 So if I want to actually change into that directory, 2268 01:43:00,600 --> 01:43:04,070 I can do cd, space, pset1, Enter. 2269 01:43:04,070 --> 01:43:05,960 And now you'll see my prompt changes. 2270 01:43:05,960 --> 01:43:09,200 And this is just a common convention, but it's not the only one out there. 2271 01:43:09,200 --> 01:43:12,470 Now I still have a dollar sign, which indicates where I can type commands. 2272 01:43:12,470 --> 01:43:16,520 But before it, I see a reminder constantly what folder I'm in. 2273 01:43:16,520 --> 01:43:19,550 And we put that there deliberately, like a lot of Linux users 2274 01:43:19,550 --> 01:43:23,620 do just to remind themselves where they are because unlike macOS or Windows, 2275 01:43:23,620 --> 01:43:26,120 where you have a nice, big window telling you where you are, 2276 01:43:26,120 --> 01:43:29,000 at the command line, you need to be reminded textually. 2277 01:43:29,000 --> 01:43:33,350 But now if I type ls and hit Enter, what should I see? 2278 01:43:33,350 --> 01:43:34,340 AUDIENCE: Mario.c 2279 01:43:34,340 --> 01:43:36,170 DAVID J. MALAN: Yeah, mario.c. 2280 01:43:36,170 --> 01:43:38,460 And now if I want to open it-- 2281 01:43:38,460 --> 01:43:42,140 if I want to actually compile it, I can run make mario in this directory 2282 01:43:42,140 --> 01:43:43,940 once I actually type out all of the code. 2283 01:43:43,940 --> 01:43:46,050 Rest assured that in problem sets and labs, 2284 01:43:46,050 --> 01:43:48,800 we'll almost always-- certainly, in the first weeks of the class-- 2285 01:43:48,800 --> 01:43:50,810 give you exactly the commands to type. 2286 01:43:50,810 --> 01:43:52,880 Odds are because it's new to many of you, 2287 01:43:52,880 --> 01:43:55,100 you will accidentally type the wrong commands. 2288 01:43:55,100 --> 01:43:56,000 No big deal. 2289 01:43:56,000 --> 01:43:58,850 Just remember that you have different ways to solve these problems. 2290 01:43:58,850 --> 01:44:00,740 You've got the graphical File Explorer, which 2291 01:44:00,740 --> 01:44:02,198 should feel a little more familiar. 2292 01:44:02,198 --> 01:44:04,940 But in time you'll start to know and, honestly, 2293 01:44:04,940 --> 01:44:08,630 probably prefer commands like these-- so cd for Change Directory, 2294 01:44:08,630 --> 01:44:14,420 cp for copy a file, ls for list, mkdir to make a directory-- 2295 01:44:14,420 --> 01:44:17,630 create a new folder at the command line instead of with the button-- 2296 01:44:17,630 --> 01:44:21,924 mv for move or rename, rm for-- 2297 01:44:21,924 --> 01:44:22,770 AUDIENCE: Remove. 2298 01:44:22,770 --> 01:44:23,728 DAVID J. MALAN: Remove. 2299 01:44:23,728 --> 01:44:24,960 So be careful with that one. 2300 01:44:24,960 --> 01:44:26,520 Rmdir, remove directory. 2301 01:44:26,520 --> 01:44:28,860 And there's dozens, hundreds of other commands. 2302 01:44:28,860 --> 01:44:30,780 You won't need many of them, but we'll start 2303 01:44:30,780 --> 01:44:33,310 to scratch the surface all the more over time. 2304 01:44:33,310 --> 01:44:35,280 But ultimately, this command line interface 2305 01:44:35,280 --> 01:44:38,630 is going to be a more powerful mechanism, a more capable mechanism, 2306 01:44:38,630 --> 01:44:40,380 and ultimately, a more efficient mechanism 2307 01:44:40,380 --> 01:44:43,980 for writing code, running commands, solving problems, analyzing data more 2308 01:44:43,980 --> 01:44:46,050 generally, even though know there's going 2309 01:44:46,050 --> 01:44:49,680 to be some growing pains early on just because it's 2310 01:44:49,680 --> 01:44:51,880 probably so new for many of you. 2311 01:44:51,880 --> 01:44:55,020 So with that said, we have some problems still to solve, 2312 01:44:55,020 --> 01:44:56,475 but we promised cookies today. 2313 01:44:56,475 --> 01:44:58,350 So let's go ahead and take a 10-minute break. 2314 01:44:58,350 --> 01:45:00,150 Cookies are now served in the transept. 2315 01:45:00,150 --> 01:45:02,910 And we'll be back here in 10. 2316 01:45:02,910 --> 01:45:04,740 All right, we are back. 2317 01:45:04,740 --> 01:45:08,400 And up until now, each of the code examples in C we've done 2318 01:45:08,400 --> 01:45:10,740 have been designed to show one specific topic. 2319 01:45:10,740 --> 01:45:14,190 But we thought we'd try to take a step back and solve a more general problem 2320 01:45:14,190 --> 01:45:17,880 and give you a sense of when given a problem set, for instance, or just 2321 01:45:17,880 --> 01:45:20,670 a programming problem more generally, where you even begin 2322 01:45:20,670 --> 01:45:23,280 and how you go about approaching it when it's not obvious 2323 01:45:23,280 --> 01:45:25,260 what the point of the exercise is. 2324 01:45:25,260 --> 01:45:27,330 So one of my favorite games from yesteryear 2325 01:45:27,330 --> 01:45:30,510 is this one here, "Super Mario Brothers" that has come in so many 2326 01:45:30,510 --> 01:45:31,500 different forms since. 2327 01:45:31,500 --> 01:45:35,250 But in this original two-dimensional side scroller game, 2328 01:45:35,250 --> 01:45:37,450 there was a lot of artwork like this. 2329 01:45:37,450 --> 01:45:40,260 So for instance, up here in the sky were four question marks. 2330 01:45:40,260 --> 01:45:44,370 And we'll find that in C and a lot of programming languages initially, 2331 01:45:44,370 --> 01:45:48,030 it's a lot easier, a lot more accessible to focus really on black and white type 2332 01:45:48,030 --> 01:45:49,920 interactive programs textually as opposed 2333 01:45:49,920 --> 01:45:51,900 to full-fledged graphics and the like, but more 2334 01:45:51,900 --> 01:45:55,830 on the more graphical acoustic type of programs before long. 2335 01:45:55,830 --> 01:45:58,500 But for now let me go over and propose that we 2336 01:45:58,500 --> 01:46:00,720 try to just implement in ASCII art-- 2337 01:46:00,720 --> 01:46:03,150 ASCII, again, being the code that maps numbers 2338 01:46:03,150 --> 01:46:08,250 to letters, at least for English, into a textual version of these for question 2339 01:46:08,250 --> 01:46:09,120 marks in the sky. 2340 01:46:09,120 --> 01:46:11,130 So for this, let me go over to VS Code. 2341 01:46:11,130 --> 01:46:13,680 I'll create my own version of mario.c that 2342 01:46:13,680 --> 01:46:16,923 will be different from the one you're challenged with in problem set 1. 2343 01:46:16,923 --> 01:46:18,840 Indeed, in problem set 1, you'll be challenged 2344 01:46:18,840 --> 01:46:22,860 to build a little something like this, albeit with hashtags 2345 01:46:22,860 --> 01:46:24,810 for ASCII art instead of graphics. 2346 01:46:24,810 --> 01:46:28,120 And in mario.c, I want to just solve this simple problem first. 2347 01:46:28,120 --> 01:46:29,710 So it's all involving output. 2348 01:46:29,710 --> 01:46:33,090 So I'll do include stdio.h so I can use printf. 2349 01:46:33,090 --> 01:46:37,043 I'll do my int main(void)-- more on why we keep doing that in future weeks. 2350 01:46:37,043 --> 01:46:39,210 And I'm just going to do something simple initially, 2351 01:46:39,210 --> 01:46:42,210 like 1, 2, 3, 4, backslash n. 2352 01:46:42,210 --> 01:46:46,530 This is about the simplest way I can implement four question 2353 01:46:46,530 --> 01:46:50,410 marks in the sky like these here using pure text like this. 2354 01:46:50,410 --> 01:46:54,180 So let me go ahead and do make mario, ./mario, and voila. 2355 01:46:54,180 --> 01:46:55,830 We have those four question marks. 2356 01:46:55,830 --> 01:46:58,830 But we've seen, of course, that there are better ways to do this. 2357 01:46:58,830 --> 01:47:03,150 And if you wanted to generalize this to be five question marks, six, 2358 01:47:03,150 --> 01:47:06,450 60 different question marks, loop was always the answer 2359 01:47:06,450 --> 01:47:08,100 for not repeating ourselves. 2360 01:47:08,100 --> 01:47:12,570 So maybe I should rewrite this a little bit more flexibly and say something 2361 01:47:12,570 --> 01:47:17,100 like this, for in i get 0, i less than 4, i++. 2362 01:47:17,100 --> 01:47:21,900 And then inside of a for loop, now I can just do a single question mark, 2363 01:47:21,900 --> 01:47:25,800 but I don't think what I've just done is correct. 2364 01:47:25,800 --> 01:47:29,280 Any one spot the aesthetic bug already? 2365 01:47:29,280 --> 01:47:34,200 Yeah, why is this wrong if I want to print the same thing? 2366 01:47:34,200 --> 01:47:34,710 Yeah? 2367 01:47:34,710 --> 01:47:38,275 AUDIENCE: The backslash n, you said to use it into [INAUDIBLE].. 2368 01:47:38,275 --> 01:47:39,150 DAVID J. MALAN: Yeah. 2369 01:47:39,150 --> 01:47:41,800 So I don't think I want a backslash n after every question mark 2370 01:47:41,800 --> 01:47:44,760 because the goal is, again, this row of question marks in the sky. 2371 01:47:44,760 --> 01:47:50,700 So if I now recompile this, make mario, ./mario, OK, it's almost there. 2372 01:47:50,700 --> 01:47:54,820 But now I have that regression to where the dollar sign is not on its own line. 2373 01:47:54,820 --> 01:47:58,265 So I think I need a new line, but I don't think I want it here 2374 01:47:58,265 --> 01:47:59,890 because that was not going to end well. 2375 01:47:59,890 --> 01:48:01,015 Where do I want to instead? 2376 01:48:01,015 --> 01:48:03,310 2377 01:48:03,310 --> 01:48:03,960 Any instinct? 2378 01:48:03,960 --> 01:48:05,610 Yeah? 2379 01:48:05,610 --> 01:48:07,380 Yeah, so outside for loop. 2380 01:48:07,380 --> 01:48:11,640 So indeed, I can just go below line 8 and above line 9, creating a new one. 2381 01:48:11,640 --> 01:48:15,273 And now it's totally fine to just print a new line like that. 2382 01:48:15,273 --> 01:48:17,190 You don't have to print anything else with it. 2383 01:48:17,190 --> 01:48:18,970 It's indeed a character unto itself. 2384 01:48:18,970 --> 01:48:21,900 So let's do make mario one last time, ./mario. 2385 01:48:21,900 --> 01:48:24,010 OK, so now we're back in business there. 2386 01:48:24,010 --> 01:48:28,020 Well, what if we wanted to do some other scene from "Mario," such as this one 2387 01:48:28,020 --> 01:48:31,380 here where there's a lot of vertical obstacles like these bricks here? 2388 01:48:31,380 --> 01:48:34,410 If I wanted to print out now a column of three bricks-- 2389 01:48:34,410 --> 01:48:38,160 and I'll use hashtags for these instead of anything graphical-- well, 2390 01:48:38,160 --> 01:48:40,650 I think we're almost there, right? 2391 01:48:40,650 --> 01:48:42,240 I think I can now-- 2392 01:48:42,240 --> 01:48:44,080 it's almost maybe a little easier. 2393 01:48:44,080 --> 01:48:46,342 I can go back here, change the question mark 2394 01:48:46,342 --> 01:48:49,050 to something that looks more like a brick, like this hash symbol. 2395 01:48:49,050 --> 01:48:52,890 And I think now I do want the new line character because when I now do make 2396 01:48:52,890 --> 01:48:56,368 mario, ./mario, OK, there's my wall of four. 2397 01:48:56,368 --> 01:48:56,910 Oh, but wait. 2398 01:48:56,910 --> 01:48:58,050 I didn't want four. 2399 01:48:58,050 --> 01:49:01,150 I wanted to be consistent just with this particular scene here, 2400 01:49:01,150 --> 01:49:02,320 so I just want three. 2401 01:49:02,320 --> 01:49:04,780 So I can still change it in one place. 2402 01:49:04,780 --> 01:49:06,330 And here, again, is that paradigm. 2403 01:49:06,330 --> 01:49:08,970 Even whether you're using 4 or 3, if you get 2404 01:49:08,970 --> 01:49:11,670 into the habit of starting counting from 0, 2405 01:49:11,670 --> 01:49:15,870 you go on up to but not through the value you want to count up to. 2406 01:49:15,870 --> 01:49:20,055 So that's why I'm using less than instead of less than or equal to there. 2407 01:49:20,055 --> 01:49:22,680 So this would be the common paradigm, though you could count it 2408 01:49:22,680 --> 01:49:25,360 like we saw earlier in different ways. 2409 01:49:25,360 --> 01:49:27,965 But what if things escalate one level further? 2410 01:49:27,965 --> 01:49:30,840 And when you're in the underground version of "Super Mario Brothers," 2411 01:49:30,840 --> 01:49:32,840 there's a lot of these underground obstructions, 2412 01:49:32,840 --> 01:49:35,400 including grids of bricks like this. 2413 01:49:35,400 --> 01:49:38,400 And let me conjecture that if you slice this up, it's roughly a 3 2414 01:49:38,400 --> 01:49:43,560 by 3 grid of bricks that all interlock prettily to give us just one 2415 01:49:43,560 --> 01:49:45,400 big, large brick like this. 2416 01:49:45,400 --> 01:49:50,160 So if I want to print out a 3 by 3 grid, now things are getting a little more 2417 01:49:50,160 --> 01:49:54,510 interesting because up until now, I've printed either one row horizontally 2418 01:49:54,510 --> 01:49:56,580 or one column vertically. 2419 01:49:56,580 --> 01:49:58,380 But we haven't really seen any code where 2420 01:49:58,380 --> 01:50:02,670 I'm printing or living in two different dimensions like the game would imply. 2421 01:50:02,670 --> 01:50:05,560 But let me propose that we could do this. 2422 01:50:05,560 --> 01:50:08,640 Let me go ahead and say, all right, suppose I want to print a 3 2423 01:50:08,640 --> 01:50:10,500 by 3 grid of bricks. 2424 01:50:10,500 --> 01:50:16,590 It's really that I want to print, what, three rows of bricks. 2425 01:50:16,590 --> 01:50:18,063 A grid is three rows. 2426 01:50:18,063 --> 01:50:19,980 So if I take the high-level idea and reduce it 2427 01:50:19,980 --> 01:50:22,345 to something a little simpler, how do I do that? 2428 01:50:22,345 --> 01:50:24,720 Well, let me get rid of the printf for a moment as I did. 2429 01:50:24,720 --> 01:50:27,090 And let me just stipulate that this for loop, 2430 01:50:27,090 --> 01:50:29,230 even though it doesn't do anything useful yet, 2431 01:50:29,230 --> 01:50:33,390 will do something how many times just by design? 2432 01:50:33,390 --> 01:50:34,530 All right, three times. 2433 01:50:34,530 --> 01:50:35,850 This for loop is good to go. 2434 01:50:35,850 --> 01:50:39,390 It will do something three times by just using i to do the counting. 2435 01:50:39,390 --> 01:50:44,070 All right, well, if I want to print out now a row of three bricks all 2436 01:50:44,070 --> 01:50:46,710 on the same line, that's pretty similar to what 2437 01:50:46,710 --> 01:50:49,170 we did earlier when I just wanted to print out 2438 01:50:49,170 --> 01:50:51,090 four question marks in the sky. 2439 01:50:51,090 --> 01:50:52,960 So we've seen a solution there. 2440 01:50:52,960 --> 01:50:55,450 And I daresay we can compose one into the other. 2441 01:50:55,450 --> 01:50:58,590 So if I want to print out a row of bricks, 2442 01:50:58,590 --> 01:51:05,310 I could just do this for in i get 0 i less than 3 i++, 2443 01:51:05,310 --> 01:51:08,310 and then inside of this inner loop, if you will, 2444 01:51:08,310 --> 01:51:11,700 let me print out a single brick like this. 2445 01:51:11,700 --> 01:51:16,862 And then I don't like where this is going but, I think I've taken two ideas 2446 01:51:16,862 --> 01:51:17,820 and I've combined them. 2447 01:51:17,820 --> 01:51:23,080 But what might be problematic about lines 5 and 7 at the moment? 2448 01:51:23,080 --> 01:51:24,700 What might be bad here? 2449 01:51:24,700 --> 01:51:25,345 Yeah, in back? 2450 01:51:25,345 --> 01:51:27,665 AUDIENCE: You used the same integer i. 2451 01:51:27,665 --> 01:51:30,040 DAVID J. MALAN: Yeah, I'm using the same integer i, which 2452 01:51:30,040 --> 01:51:32,080 I feel like could get me into trouble. 2453 01:51:32,080 --> 01:51:34,480 If I'm trying to count three things here, 2454 01:51:34,480 --> 01:51:38,470 but then I'm hijacking this variable and using it inside of the loop, 2455 01:51:38,470 --> 01:51:41,560 I feel like I should avoid this collision of names. 2456 01:51:41,560 --> 01:51:43,930 And so what's a good alternative to i? 2457 01:51:43,930 --> 01:51:46,390 Well, a programmer, if nesting loops in this way, 2458 01:51:46,390 --> 01:51:47,980 would pretty commonly go with j. 2459 01:51:47,980 --> 01:51:50,975 You could certainly change this to be rows and columns 2460 01:51:50,975 --> 01:51:52,600 if you want more descriptive variables. 2461 01:51:52,600 --> 01:51:54,940 But i and j is pretty canonical. 2462 01:51:54,940 --> 01:51:59,020 So I'm going to go ahead and do this, j++ instead of i++ everywhere. 2463 01:51:59,020 --> 01:52:00,280 And let me try compiling this. 2464 01:52:00,280 --> 01:52:04,330 So make mario, Enter, ./mario. 2465 01:52:04,330 --> 01:52:06,560 OK, so a couple of things are wrong here. 2466 01:52:06,560 --> 01:52:08,480 This is not a 3 by 3 grid. 2467 01:52:08,480 --> 01:52:12,855 But if you count these things, how many did I indeed print at least? 2468 01:52:12,855 --> 01:52:14,485 You can probably just guess logically. 2469 01:52:14,485 --> 01:52:15,110 AUDIENCE: Nine. 2470 01:52:15,110 --> 01:52:17,110 DAVID J. MALAN: Yeah, there's nine hashes there. 2471 01:52:17,110 --> 01:52:18,940 Unfortunately, they're all on the same line 2472 01:52:18,940 --> 01:52:21,340 instead of on three different lines. 2473 01:52:21,340 --> 01:52:24,910 So where logically can I fix this? 2474 01:52:24,910 --> 01:52:26,535 I'm definitely printing all the bricks. 2475 01:52:26,535 --> 01:52:28,077 They're just not on the right levels. 2476 01:52:28,077 --> 01:52:28,646 Yeah? 2477 01:52:28,646 --> 01:52:31,078 AUDIENCE: If you put a new line at the first loop, 2478 01:52:31,078 --> 01:52:32,620 then you'll get three separate lines. 2479 01:52:32,620 --> 01:52:33,495 DAVID J. MALAN: Yeah. 2480 01:52:33,495 --> 01:52:36,580 So put a new line after the first loop, this inner loop, if you will, 2481 01:52:36,580 --> 01:52:38,000 the nested loop, if you will. 2482 01:52:38,000 --> 01:52:41,030 So let me go ahead and print out just a backslash n here. 2483 01:52:41,030 --> 01:52:42,073 And what's this doing? 2484 01:52:42,073 --> 01:52:43,990 Well, I think that's going to solve it by just 2485 01:52:43,990 --> 01:52:47,270 moving the cursor to the next line after you've done one row. 2486 01:52:47,270 --> 01:52:50,770 So let me go ahead and do make mario, Enter, ./mario, 2487 01:52:50,770 --> 01:52:52,070 and now we're in business. 2488 01:52:52,070 --> 01:52:54,850 So it's a very simplistic version of this same graphic, 2489 01:52:54,850 --> 01:52:57,400 but I'm leveraging two different ideas now-- 2490 01:52:57,400 --> 01:52:59,350 or the same idea twice rather now. 2491 01:52:59,350 --> 01:53:03,970 I'm using one loop to control my cursor going row, by row, by row. 2492 01:53:03,970 --> 01:53:06,100 But then within that loop, I'm doing left to right, 2493 01:53:06,100 --> 01:53:08,290 dot, dot, dot, dot, dot, with printing out 2494 01:53:08,290 --> 01:53:10,960 each of these individual bricks like this. 2495 01:53:10,960 --> 01:53:13,600 Now, there's a little sloppiness here still. 2496 01:53:13,600 --> 01:53:16,630 If I want this to always be a square just because that's 2497 01:53:16,630 --> 01:53:20,800 what it looks like in the game, well, I could change it to be a 4 by 4 2498 01:53:20,800 --> 01:53:24,430 square by doing this or a 5 by 5 grid-- 2499 01:53:24,430 --> 01:53:26,420 whoops-- by doing this. 2500 01:53:26,420 --> 01:53:30,010 Why is this perhaps not the best design to just keep changing the numbers when 2501 01:53:30,010 --> 01:53:33,330 I want to change the size? 2502 01:53:33,330 --> 01:53:34,440 Where could this go awry? 2503 01:53:34,440 --> 01:53:35,010 Yeah? 2504 01:53:35,010 --> 01:53:38,255 AUDIENCE: If it's a square, [INAUDIBLE] 2505 01:53:38,255 --> 01:53:39,130 DAVID J. MALAN: Yeah. 2506 01:53:39,130 --> 01:53:40,630 If it's always going to be a square and height 2507 01:53:40,630 --> 01:53:43,060 is going to be the same as width, I'm just inviting trouble here, right? 2508 01:53:43,060 --> 01:53:44,110 Eventually, I'm going to screw up. 2509 01:53:44,110 --> 01:53:45,680 I'm going to change one but not the other. 2510 01:53:45,680 --> 01:53:48,070 Then it's going to come out to be a rectangle instead of a proper square. 2511 01:53:48,070 --> 01:53:50,410 So I should probably solve this a little differently. 2512 01:53:50,410 --> 01:53:51,160 So let me do that. 2513 01:53:51,160 --> 01:53:54,700 At the top of my main function here, let me go ahead and give myself 2514 01:53:54,700 --> 01:53:59,980 a variable called maybe n for the number of bricks I want horizontally 2515 01:53:59,980 --> 01:54:01,000 and vertically. 2516 01:54:01,000 --> 01:54:03,550 And I'll just initialize that to 3 initially. 2517 01:54:03,550 --> 01:54:06,610 And instead of putting 3 here, I'll literally just use n. 2518 01:54:06,610 --> 01:54:09,100 But I'll do it in both places so that now, henceforth, 2519 01:54:09,100 --> 01:54:13,000 if I ever want to change this and change it to 4, or 5, or anything else, 2520 01:54:13,000 --> 01:54:13,845 I'm all done. 2521 01:54:13,845 --> 01:54:16,720 It's better designed because there's a lower probability of mistakes. 2522 01:54:16,720 --> 01:54:19,840 But I could technically still screw up somehow. 2523 01:54:19,840 --> 01:54:24,460 I could technically accidentally write a line of code like n++, 2524 01:54:24,460 --> 01:54:28,360 or I could just change the value of that variable even though I don't want it 2525 01:54:28,360 --> 01:54:28,985 to ever change. 2526 01:54:28,985 --> 01:54:31,693 And maybe it's because I'm a bad programmer, I copy/pasted wrong, 2527 01:54:31,693 --> 01:54:34,240 I'm working with someone who doesn't know what n represents, 2528 01:54:34,240 --> 01:54:38,440 I can defend myself and my code against human error 2529 01:54:38,440 --> 01:54:41,020 like that by going up here to line 5. 2530 01:54:41,020 --> 01:54:44,170 And instead of just declaring a simple variable like we did in Scratch, 2531 01:54:44,170 --> 01:54:47,360 I can further harden my code, so to speak, 2532 01:54:47,360 --> 01:54:50,740 by declaring it to be a constant using the keyword const. 2533 01:54:50,740 --> 01:54:53,980 Now, this is just a feature of C and some other languages 2534 01:54:53,980 --> 01:54:57,220 to protect you against yourself by proactively saying, 2535 01:54:57,220 --> 01:55:02,320 n is a constant, specifically the number 5 or, previously, the number 3. 2536 01:55:02,320 --> 01:55:05,530 You cannot accidentally write code elsewhere that changes it. 2537 01:55:05,530 --> 01:55:08,420 The computer will throw an error and catch that error. 2538 01:55:08,420 --> 01:55:12,160 So it's just a way of programming a little more defensively. 2539 01:55:12,160 --> 01:55:13,235 Some languages have this. 2540 01:55:13,235 --> 01:55:14,110 Some languages don't. 2541 01:55:14,110 --> 01:55:15,970 But in general, it's a good practice. 2542 01:55:15,970 --> 01:55:18,790 It makes your code better designed because it's just 2543 01:55:18,790 --> 01:55:22,570 as less vulnerable to mistakes by you, colleagues, or anyone else 2544 01:55:22,570 --> 01:55:23,570 using the code. 2545 01:55:23,570 --> 01:55:26,420 So let me change this back to 3 just to be our default. 2546 01:55:26,420 --> 01:55:28,580 But now I'm using n in both places. 2547 01:55:28,580 --> 01:55:33,250 And if I do make mario, ./mario, we're back to where we originally started. 2548 01:55:33,250 --> 01:55:35,560 But the code is a little more better designed. 2549 01:55:35,560 --> 01:55:37,330 And let me note this too. 2550 01:55:37,330 --> 01:55:40,720 All this time, I've been mentioning that correctness is important. 2551 01:55:40,720 --> 01:55:41,740 Design is important. 2552 01:55:41,740 --> 01:55:43,700 There is also this matter of style. 2553 01:55:43,700 --> 01:55:46,107 I've been very deliberately writing pretty code, 2554 01:55:46,107 --> 01:55:48,940 if you will-- not just the syntax highlighting, which, is automatic. 2555 01:55:48,940 --> 01:55:52,060 But notice that I keep indenting everything nicely. 2556 01:55:52,060 --> 01:55:55,450 Any time I have curly braces, like on lines 4 and 14, 2557 01:55:55,450 --> 01:55:57,400 everything is indented one level. 2558 01:55:57,400 --> 01:56:01,420 When I have additional curly braces on lines 7 and 13, 2559 01:56:01,420 --> 01:56:04,520 everything is nicely indented as well. 2560 01:56:04,520 --> 01:56:09,250 Technically speaking, the computer does not care about that kind of whitespace, 2561 01:56:09,250 --> 01:56:10,090 so to speak. 2562 01:56:10,090 --> 01:56:12,280 And you could really make a mess of things 2563 01:56:12,280 --> 01:56:15,205 like this because you have a strange sense of style 2564 01:56:15,205 --> 01:56:17,080 or just because you're being a little sloppy. 2565 01:56:17,080 --> 01:56:20,170 But this code is actually still correct. 2566 01:56:20,170 --> 01:56:23,260 If I recompile it-- let me open up my terminal window-- 2567 01:56:23,260 --> 01:56:28,270 make mario, no errors, ./mario, it works perfectly fine. 2568 01:56:28,270 --> 01:56:30,910 But you can imagine just how annoying this now 2569 01:56:30,910 --> 01:56:34,693 is to read, certainly for a TA, but certainly for you the next day, 2570 01:56:34,693 --> 01:56:36,860 certainly for a colleague who has to read your code. 2571 01:56:36,860 --> 01:56:38,020 This is just bad style. 2572 01:56:38,020 --> 01:56:42,670 It still works, and it's well designed in that you're writing code 2573 01:56:42,670 --> 01:56:44,230 defensively, you're using a constant. 2574 01:56:44,230 --> 01:56:46,420 But, my god, the style is atrocious. 2575 01:56:46,420 --> 01:56:48,310 Now, you'll often find that there's tools 2576 01:56:48,310 --> 01:56:50,440 that can help you format your code for you 2577 01:56:50,440 --> 01:56:53,710 in a manner consistent with a courses or a company's style. 2578 01:56:53,710 --> 01:56:57,220 But this is the kind of muscle memory you'll want to develop over time too. 2579 01:56:57,220 --> 01:57:00,940 Take these VS Code suggestions as it's outputting lines of code for you 2580 01:57:00,940 --> 01:57:03,565 because it's trying to format your code in a readable way. 2581 01:57:03,565 --> 01:57:06,940 And, oh, my god, if and when you do have bugs in your code 2582 01:57:06,940 --> 01:57:08,717 and things aren't even indented properly, 2583 01:57:08,717 --> 01:57:11,800 there's no way you the human are going to be able to wrap your mind around 2584 01:57:11,800 --> 01:57:13,690 what's happening and where. 2585 01:57:13,690 --> 01:57:16,060 You're just making the problem harder for yourself. 2586 01:57:16,060 --> 01:57:21,190 So do get into this habit too of manifesting good style as well. 2587 01:57:21,190 --> 01:57:24,880 All right, well, let me propose that we don't only want a 3 by 3 grid. 2588 01:57:24,880 --> 01:57:26,840 We want this to be a little more dynamic. 2589 01:57:26,840 --> 01:57:32,020 So suppose we moved away from a constant to just using an integer called n. 2590 01:57:32,020 --> 01:57:35,230 And let's ask the user for the size of this grid 2591 01:57:35,230 --> 01:57:38,320 as by prompting them with get_int, as we've done before. 2592 01:57:38,320 --> 01:57:40,150 And I'll store it in n here. 2593 01:57:40,150 --> 01:57:42,880 And then I can go ahead and, more dynamically, 2594 01:57:42,880 --> 01:57:46,450 run make mario to compile it-- whoops. 2595 01:57:46,450 --> 01:57:49,930 Oh, I screwed up accidentally. 2596 01:57:49,930 --> 01:57:53,785 What is it suggesting I do, albeit cryptically? 2597 01:57:53,785 --> 01:57:56,660 AUDIENCE: You have to include the cs50.h. 2598 01:57:56,660 --> 01:57:59,930 DAVID J. MALAN: Yeah, I forgot to include the CS50 header file up top. 2599 01:57:59,930 --> 01:58:03,420 And that's why it doesn't know that get_int is, in fact, valid. 2600 01:58:03,420 --> 01:58:04,880 So that's an easy fix. 2601 01:58:04,880 --> 01:58:07,730 I'm just going to go up here and include cs50.h. 2602 01:58:07,730 --> 01:58:10,790 Now I'm going to clear my terminal and rerun make mario. 2603 01:58:10,790 --> 01:58:12,800 Now we're good-- ./mario. 2604 01:58:12,800 --> 01:58:14,550 And now notice I'm prompted for size. 2605 01:58:14,550 --> 01:58:16,490 So if I type in 3, it's the same as before. 2606 01:58:16,490 --> 01:58:20,900 If I type in 10, it's even bigger, but it happens all now automatically. 2607 01:58:20,900 --> 01:58:23,360 But there are some things that we're not detecting. 2608 01:58:23,360 --> 01:58:25,940 For instance, suppose I type in cat. 2609 01:58:25,940 --> 01:58:28,770 Well, that's handled by the get_int function, as I claimed earlier. 2610 01:58:28,770 --> 01:58:30,687 That's one of the features of using a library. 2611 01:58:30,687 --> 01:58:32,570 You don't have to deal with erroneous input. 2612 01:58:32,570 --> 01:58:36,200 But we only designed a function called get_int to get you an integer. 2613 01:58:36,200 --> 01:58:39,050 We don't know if you want it to be positive, negative, zero, 2614 01:58:39,050 --> 01:58:40,680 or some combination thereof. 2615 01:58:40,680 --> 01:58:43,940 And it's kind of weird to allow the user to type in negative 1 2616 01:58:43,940 --> 01:58:48,440 for the size of the grid or negative 3 for the size of the grid. 2617 01:58:48,440 --> 01:58:51,230 And indeed, your code does nothing, so at least it's not crashing. 2618 01:58:51,230 --> 01:58:52,730 But that's kind of stupid, right? 2619 01:58:52,730 --> 01:58:54,530 It'd be nice to force the user if they want 2620 01:58:54,530 --> 01:58:57,150 a grid to give us a positive value. 2621 01:58:57,150 --> 01:58:58,530 So how could we do this? 2622 01:58:58,530 --> 01:59:03,920 Well, I could go up here and I could say something like if n is less than 1-- 2623 01:59:03,920 --> 01:59:08,190 so if it's 0 or negative, which I don't want, what could I do? 2624 01:59:08,190 --> 01:59:12,380 Well, I could say, well, prompt the user again for the size. 2625 01:59:12,380 --> 01:59:16,613 And now notice, I'm not declaring n again because once it exists, 2626 01:59:16,613 --> 01:59:18,530 you don't have to mention the data type again. 2627 01:59:18,530 --> 01:59:19,790 We said that earlier. 2628 01:59:19,790 --> 01:59:21,510 But this is kind of stupid. 2629 01:59:21,510 --> 01:59:22,010 Why? 2630 01:59:22,010 --> 01:59:25,190 Because now when you've given the user a second chance, OK, now maybe 2631 01:59:25,190 --> 01:59:29,720 I'll do-- all right, if this version of n is less than 1, well, 2632 01:59:29,720 --> 01:59:33,020 let's just go and prompt the user a third time. 2633 01:59:33,020 --> 01:59:35,240 I mean, you can see where this is stupidly going. 2634 01:59:35,240 --> 01:59:38,510 This can't be the right solution to keep typing recursively 2635 01:59:38,510 --> 01:59:39,860 the same thing again and again. 2636 01:59:39,860 --> 01:59:40,790 Where would it stop? 2637 01:59:40,790 --> 01:59:42,873 You'd have to give them a finite number of chances 2638 01:59:42,873 --> 01:59:44,810 or just make a mess of your code. 2639 01:59:44,810 --> 01:59:48,170 So what would be intuitively a better solution here? 2640 01:59:48,170 --> 01:59:49,128 AUDIENCE: A while loop. 2641 01:59:49,128 --> 01:59:50,920 DAVID J. MALAN: Yeah, so some kind of loop. 2642 01:59:50,920 --> 01:59:52,160 We've seen a while loop. 2643 01:59:52,160 --> 01:59:54,240 We've seen a for loop, so maybe one of those. 2644 01:59:54,240 --> 01:59:55,290 So let me try this. 2645 01:59:55,290 --> 01:59:58,760 Let me delete this messiness and just go back to the first question. 2646 01:59:58,760 --> 01:59:59,790 And let me do this. 2647 01:59:59,790 --> 02:00:02,780 So while n is less than 1-- 2648 02:00:02,780 --> 02:00:05,190 so while the number is not what we want-- 2649 02:00:05,190 --> 02:00:09,560 let's just prompt the user in a loop this time for the size again. 2650 02:00:09,560 --> 02:00:15,470 Now, here too, this is better because it's only two requests for information. 2651 02:00:15,470 --> 02:00:19,640 But clearly, lines 6 and 9 are pretty much identical other than the int. 2652 02:00:19,640 --> 02:00:23,120 And if I went in and changed the size, if I 2653 02:00:23,120 --> 02:00:26,300 add this, if I change the wording here, change it to a different language, 2654 02:00:26,300 --> 02:00:27,350 I have to change it in two places. 2655 02:00:27,350 --> 02:00:27,850 That's bad. 2656 02:00:27,850 --> 02:00:29,330 Copy/paste, bad. 2657 02:00:29,330 --> 02:00:31,040 So what might be better? 2658 02:00:31,040 --> 02:00:33,890 Well, it turns out, there's another paradigm in C 2659 02:00:33,890 --> 02:00:37,730 that you can use that gets around this problem, this duplication of code. 2660 02:00:37,730 --> 02:00:41,210 It would be much nicer if I just write the code once. 2661 02:00:41,210 --> 02:00:45,510 And I can do that using a third type of loop called a do while loop. 2662 02:00:45,510 --> 02:00:48,000 So it turns out, in C, you can do this. 2663 02:00:48,000 --> 02:00:50,210 If you want to get the value of a variable like n, 2664 02:00:50,210 --> 02:00:53,370 first just to create the variable without an initial value. 2665 02:00:53,370 --> 02:00:56,870 So int n semicolon means we don't know what value it has, yes. 2666 02:00:56,870 --> 02:00:57,590 But that's OK. 2667 02:00:57,590 --> 02:00:59,840 We're going to add a value to it eventually. 2668 02:00:59,840 --> 02:01:02,870 Then I'm going to say this, do, literally. 2669 02:01:02,870 --> 02:01:04,460 I'm going to open my curly braces. 2670 02:01:04,460 --> 02:01:05,930 And what do I want to do? 2671 02:01:05,930 --> 02:01:09,920 I want to assign to n the return value of get_int, 2672 02:01:09,920 --> 02:01:11,750 prompting the user for size. 2673 02:01:11,750 --> 02:01:14,040 Well, when do you want to do that? 2674 02:01:14,040 --> 02:01:17,900 I want to do that while n is less than 1. 2675 02:01:17,900 --> 02:01:21,410 And this code now achieves the exact same goal, 2676 02:01:21,410 --> 02:01:23,570 but by never repeating myself. 2677 02:01:23,570 --> 02:01:24,230 Why? 2678 02:01:24,230 --> 02:01:29,210 Well, notice on these lines of code now, I'm literally saying on line 6, 2679 02:01:29,210 --> 02:01:31,175 give me a variable called n of type integer. 2680 02:01:31,175 --> 02:01:33,300 It doesn't have a value initially, but that's fine. 2681 02:01:33,300 --> 02:01:34,640 You can do that. 2682 02:01:34,640 --> 02:01:36,380 Line 7 says, do the following. 2683 02:01:36,380 --> 02:01:39,890 What do you want to do? get_int, prompting the user with the word size, 2684 02:01:39,890 --> 02:01:41,660 and just store that value in n. 2685 02:01:41,660 --> 02:01:45,210 But because C code runs top to bottom, left to right, 2686 02:01:45,210 --> 02:01:49,040 now it's reasonable on line 11 to ask that question, OK, is 2687 02:01:49,040 --> 02:01:53,670 the current value of n, which it definitely got on line 8, less than 1? 2688 02:01:53,670 --> 02:01:56,420 And if the user didn't cooperate-- they typed in 0, or negative 1, 2689 02:01:56,420 --> 02:01:58,400 or negative 3-- what's going to happen? 2690 02:01:58,400 --> 02:02:02,510 It's going to go back up here and repeat, repeat, repeat everything 2691 02:02:02,510 --> 02:02:04,530 in the do while loop. 2692 02:02:04,530 --> 02:02:06,438 So a do while loop in C-- 2693 02:02:06,438 --> 02:02:08,480 which is not something some other languages have. 2694 02:02:08,480 --> 02:02:10,730 Python, if you know it, does not have a do while loop. 2695 02:02:10,730 --> 02:02:13,310 This is perhaps the cleanest way to achieve this, 2696 02:02:13,310 --> 02:02:16,790 even though it's a little weird that you have to declare your variable, 2697 02:02:16,790 --> 02:02:20,570 create your variable up top, and then check it down below. 2698 02:02:20,570 --> 02:02:22,980 But otherwise, it's similar to a while loop. 2699 02:02:22,980 --> 02:02:26,150 It just flips the order in which you're asking the question. 2700 02:02:26,150 --> 02:02:28,820 Any questions on this construct? 2701 02:02:28,820 --> 02:02:30,827 And do while, in general, is super useful when 2702 02:02:30,827 --> 02:02:32,660 you want to get input from the user and make 2703 02:02:32,660 --> 02:02:35,640 sure it meets certain requirements. 2704 02:02:35,640 --> 02:02:39,530 So all right, so now that we have this building block after that interlude. 2705 02:02:39,530 --> 02:02:41,750 How can I go about cleaning up this code? 2706 02:02:41,750 --> 02:02:45,230 And then let's conclude by taking a look at things that our code can't do 2707 02:02:45,230 --> 02:02:47,720 or can't do very well or correctly. 2708 02:02:47,720 --> 02:02:50,930 Let me propose that in a final version of Mario, 2709 02:02:50,930 --> 02:02:53,520 let me just add what are called now some comments. 2710 02:02:53,520 --> 02:02:56,880 So it turns out, in code in C, you can define 2711 02:02:56,880 --> 02:02:59,173 what are called comments, which are just notes to self. 2712 02:02:59,173 --> 02:03:00,840 Some of you discovered these in Scratch. 2713 02:03:00,840 --> 02:03:02,590 There's little yellow sticky notes you can 2714 02:03:02,590 --> 02:03:04,680 use to add citations or explanations. 2715 02:03:04,680 --> 02:03:07,020 In C, there's a couple of ways to write comments. 2716 02:03:07,020 --> 02:03:09,960 And in general, comments are notes for yourself, for your TA, 2717 02:03:09,960 --> 02:03:13,860 for your colleague as to what your code is doing and why or how. 2718 02:03:13,860 --> 02:03:15,660 It's a little explanatory note in English 2719 02:03:15,660 --> 02:03:17,860 or whatever your human language might be. 2720 02:03:17,860 --> 02:03:23,220 So for instance, what I might do here in my implementation 2721 02:03:23,220 --> 02:03:27,870 of this version of mario, I might first ask myself a question like-- 2722 02:03:27,870 --> 02:03:30,420 I might first make a note to self like this on a new line, 2723 02:03:30,420 --> 02:03:34,350 above this first block of code, Get size of grid. 2724 02:03:34,350 --> 02:03:38,100 It's just an explanatory remark in any terse English 2725 02:03:38,100 --> 02:03:41,820 that generally explains the next six or so lines, the next chunk 2726 02:03:41,820 --> 02:03:43,560 or block of code, if you will. 2727 02:03:43,560 --> 02:03:46,500 It would be a little excessive to comment every single line. 2728 02:03:46,500 --> 02:03:49,680 At some point, the programmer should know what individual lines of code do. 2729 02:03:49,680 --> 02:03:53,700 But it's nice to be able to glance at this comment on line 6 2730 02:03:53,700 --> 02:03:56,818 that starts with two slashes, and it gets grayed out 2731 02:03:56,818 --> 02:03:58,110 because of syntax highlighting. 2732 02:03:58,110 --> 02:03:59,070 It's not logic. 2733 02:03:59,070 --> 02:04:00,440 It's just a note to self. 2734 02:04:00,440 --> 02:04:02,190 It generally gives me a little cheat sheet 2735 02:04:02,190 --> 02:04:05,160 as to what the following lines of code should be doing and/or why. 2736 02:04:05,160 --> 02:04:07,910 And then down here, well, there's a second block of code 2737 02:04:07,910 --> 02:04:08,910 that's a bunch of lines. 2738 02:04:08,910 --> 02:04:14,130 But together, this just, what, prints grid of bricks. 2739 02:04:14,130 --> 02:04:16,350 And so it's another comment to myself that 2740 02:04:16,350 --> 02:04:18,540 just makes it a little more understandable what 2741 02:04:18,540 --> 02:04:20,880 these 20-some-odd lines of code are doing by adding 2742 02:04:20,880 --> 02:04:23,760 some English explanations thereof. 2743 02:04:23,760 --> 02:04:26,970 But now that I have these, wouldn't it be nice 2744 02:04:26,970 --> 02:04:31,140 if I could abstract these pieces of functionality away, this 2745 02:04:31,140 --> 02:04:33,600 getting of the size and this printing of the grid? 2746 02:04:33,600 --> 02:04:37,590 In other words, suppose that you didn't know where to begin with this problem. 2747 02:04:37,590 --> 02:04:39,960 And the problem at hand were literally implement 2748 02:04:39,960 --> 02:04:43,530 a program that prints a grid of bricks of some variable size-- 2749 02:04:43,530 --> 02:04:46,440 3, or 4, or 5, or whatever the human types in. 2750 02:04:46,440 --> 02:04:48,810 If you have really no idea where to start, 2751 02:04:48,810 --> 02:04:51,540 comments are actually a good way of getting 2752 02:04:51,540 --> 02:04:55,680 started because comments can be an approximation of what we call last week 2753 02:04:55,680 --> 02:04:56,310 pseudocode. 2754 02:04:56,310 --> 02:05:00,360 Pseudocode is terse English that gets your point across, like for the phone 2755 02:05:00,360 --> 02:05:02,080 book searching like last time. 2756 02:05:02,080 --> 02:05:04,050 So if you didn't really know where to begin, 2757 02:05:04,050 --> 02:05:06,910 you could do something like this. 2758 02:05:06,910 --> 02:05:11,730 I could, for instance, just say, Get size of grid as my first step 2759 02:05:11,730 --> 02:05:14,610 and then Print grid of bricks as my second step. 2760 02:05:14,610 --> 02:05:16,410 And that's it for my program thus far. 2761 02:05:16,410 --> 02:05:18,690 This is now implemented in pseudocode. 2762 02:05:18,690 --> 02:05:20,910 I have some massive placeholders there. 2763 02:05:20,910 --> 02:05:22,380 I still have work to be done. 2764 02:05:22,380 --> 02:05:26,050 But at least I have a high-level solution to the problem in comments. 2765 02:05:26,050 --> 02:05:28,230 And now I can even go this far. 2766 02:05:28,230 --> 02:05:32,010 I could say, well, let's suppose that there's just a function already 2767 02:05:32,010 --> 02:05:34,650 that exists called get size. 2768 02:05:34,650 --> 02:05:36,220 I could do something like this. 2769 02:05:36,220 --> 02:05:38,790 I could do int n equals get_size. 2770 02:05:38,790 --> 02:05:41,010 And now I just have to assume for the moment 2771 02:05:41,010 --> 02:05:43,000 that some abstraction called get_size exists. 2772 02:05:43,000 --> 02:05:43,500 It doesn't. 2773 02:05:43,500 --> 02:05:45,420 This does not come with the CS50 library. 2774 02:05:45,420 --> 02:05:47,520 But I could invent it, I bet. 2775 02:05:47,520 --> 02:05:49,110 How else might I proceed? 2776 02:05:49,110 --> 02:05:51,930 Well, let's just assume for the moment that there's also 2777 02:05:51,930 --> 02:05:57,060 a function called print_grid that just prints a grid of that size n. 2778 02:05:57,060 --> 02:05:58,950 So here too is an abstraction. 2779 02:05:58,950 --> 02:06:00,330 These puzzle pieces don't exist. 2780 02:06:00,330 --> 02:06:01,800 These functions don't yet exist. 2781 02:06:01,800 --> 02:06:06,240 But in C, just like in Scratch, I can create my own functions. 2782 02:06:06,240 --> 02:06:07,600 How do I do that? 2783 02:06:07,600 --> 02:06:09,630 Well, let me go down later in the file. 2784 02:06:09,630 --> 02:06:12,810 And by convention, you generally want to leave main at the top of your code. 2785 02:06:12,810 --> 02:06:13,110 Why? 2786 02:06:13,110 --> 02:06:15,235 Because it's the main function, and it's just where 2787 02:06:15,235 --> 02:06:18,090 the human eye is going to look to see what some file of code does. 2788 02:06:18,090 --> 02:06:19,360 And let me do this. 2789 02:06:19,360 --> 02:06:23,910 I want to create a function of my own called get_size whose purpose in life 2790 02:06:23,910 --> 02:06:26,010 is to get the size that the user wants. 2791 02:06:26,010 --> 02:06:28,380 I want this function to return an integer. 2792 02:06:28,380 --> 02:06:30,420 And the syntax for doing that is this, right, 2793 02:06:30,420 --> 02:06:34,920 similar to a variable, the data type that this function returns. 2794 02:06:34,920 --> 02:06:37,450 I don't need this function to take any inputs. 2795 02:06:37,450 --> 02:06:40,500 And so I'm going to use a new keyword that we've actually been using thus 2796 02:06:40,500 --> 02:06:42,292 far-- more on it another time-- just called 2797 02:06:42,292 --> 02:06:45,810 void, which just means this get_size function does not take any inputs. 2798 02:06:45,810 --> 02:06:46,950 It does have an output. 2799 02:06:46,950 --> 02:06:48,138 It outputs an int. 2800 02:06:48,138 --> 02:06:50,430 And this is just the weird order in which you write it. 2801 02:06:50,430 --> 02:06:54,000 You write the output format, the name of the function, and then the inputs, 2802 02:06:54,000 --> 02:06:55,920 if any, inside of parentheses. 2803 02:06:55,920 --> 02:06:57,727 And now I can implement get_size. 2804 02:06:57,727 --> 02:06:59,310 But I've already implemented get_size. 2805 02:06:59,310 --> 02:07:01,140 Or at least now at this point in the story, 2806 02:07:01,140 --> 02:07:03,180 I at least know concretely what to do. 2807 02:07:03,180 --> 02:07:05,730 And I could figure out eventually, with some trial and error 2808 02:07:05,730 --> 02:07:08,040 perhaps, all right, if I declare a variable 2809 02:07:08,040 --> 02:07:12,270 and I do the following n equals get_int, prompting the user for size, 2810 02:07:12,270 --> 02:07:17,910 and I keep doing that while n is less than 1, once that block of code 2811 02:07:17,910 --> 02:07:22,830 is done, here is a new keyword in C where you can return that value n. 2812 02:07:22,830 --> 02:07:27,330 So I keep referring to these values that some functions return as return values. 2813 02:07:27,330 --> 02:07:30,870 In C, there's literally a keyword called return 2814 02:07:30,870 --> 02:07:33,930 that will hand back to any function that uses 2815 02:07:33,930 --> 02:07:36,970 that function the value in question. 2816 02:07:36,970 --> 02:07:41,220 So in a nutshell, between lines 15 and 21 now, 2817 02:07:41,220 --> 02:07:45,270 here is some code identical to our solution earlier that gets a value 2818 02:07:45,270 --> 02:07:47,280 n from the user that is positive. 2819 02:07:47,280 --> 02:07:48,720 It's 1, or 2, or higher. 2820 02:07:48,720 --> 02:07:51,180 It's not 0, or it's not less than 1. 2821 02:07:51,180 --> 02:07:56,360 And as soon as we've got that value, we hand it back as a return value. 2822 02:07:56,360 --> 02:07:58,990 Notice how I'm using this function on line 7. 2823 02:07:58,990 --> 02:08:01,630 Just like with get_int, just like with get_string, 2824 02:08:01,630 --> 02:08:04,650 I'm calling the function-- nothing in the parentheses in this case. 2825 02:08:04,650 --> 02:08:06,400 But then I'm using the assignment operator 2826 02:08:06,400 --> 02:08:09,970 to copy whatever its return value is into my variable n. 2827 02:08:09,970 --> 02:08:13,570 And so now I have a function that didn't use 2828 02:08:13,570 --> 02:08:19,090 to exist called get_size that gets me a positive integer no matter what. 2829 02:08:19,090 --> 02:08:21,710 And now for the grid, how do I do this? 2830 02:08:21,710 --> 02:08:23,860 How do I invent a function called print_grid 2831 02:08:23,860 --> 02:08:27,160 that takes a single argument, a number and prints a grid of that size? 2832 02:08:27,160 --> 02:08:29,180 Well, let's go down here. 2833 02:08:29,180 --> 02:08:32,050 I'm going to write the name of this function print_grid. 2834 02:08:32,050 --> 02:08:33,590 This function just needs to print. 2835 02:08:33,590 --> 02:08:35,440 It has a side effect, as we keep saying. 2836 02:08:35,440 --> 02:08:38,230 So I'm just going to say it has no return value. 2837 02:08:38,230 --> 02:08:39,040 It's just void. 2838 02:08:39,040 --> 02:08:40,820 It doesn't have an output, per se. 2839 02:08:40,820 --> 02:08:42,670 It's just an aesthetic side effect. 2840 02:08:42,670 --> 02:08:44,660 But it does take in an argument. 2841 02:08:44,660 --> 02:08:47,830 An argument is an input, and the syntax for this in C 2842 02:08:47,830 --> 02:08:52,337 is to name the type of the input it takes and the name of the variable. 2843 02:08:52,337 --> 02:08:53,920 And I could call this anything I want. 2844 02:08:53,920 --> 02:08:54,940 I'll call it size. 2845 02:08:54,940 --> 02:08:56,140 I could call it n. 2846 02:08:56,140 --> 02:08:58,840 And it's OK to use the same variable in different functions, 2847 02:08:58,840 --> 02:09:01,030 but I'll call it size just to be distinct. 2848 02:09:01,030 --> 02:09:03,010 And then in this function, I'm just going 2849 02:09:03,010 --> 02:09:07,210 to copy from memory the same code is before. for int i get 0, 2850 02:09:07,210 --> 02:09:09,250 i less than size-- 2851 02:09:09,250 --> 02:09:18,790 instead of 3-- i++, inside of this, for int j gets 0, j is less than size j++, 2852 02:09:18,790 --> 02:09:23,500 and inside of that, print out with printf a single hash, 2853 02:09:23,500 --> 02:09:28,660 print out after that loop a single new line, and that's it. 2854 02:09:28,660 --> 02:09:30,370 Now, I did this fast, admittedly. 2855 02:09:30,370 --> 02:09:32,860 But it's the same code that I wrote earlier. 2856 02:09:32,860 --> 02:09:34,750 But now, just like I did with Scratch, let 2857 02:09:34,750 --> 02:09:36,910 me just arbitrarily hit Enter a bunch of times 2858 02:09:36,910 --> 02:09:39,190 to move the code out of sight, out of mind. 2859 02:09:39,190 --> 02:09:40,900 Now I have abstractions. 2860 02:09:40,900 --> 02:09:44,350 I have puzzle pieces that now exist called get_size and print_grid, 2861 02:09:44,350 --> 02:09:48,160 syntax for which takes some getting used to, but they now just exist. 2862 02:09:48,160 --> 02:09:50,590 Except I do need to do one thing. 2863 02:09:50,590 --> 02:09:56,260 Because C is a little naive, if I try to do make mario now and hit Enter, 2864 02:09:56,260 --> 02:09:59,500 implicit declaration of function get_size is invalid. 2865 02:09:59,500 --> 02:10:03,460 And we've seen that before when I hadn't included a file. 2866 02:10:03,460 --> 02:10:06,362 When I hadn't included CS50 library, get_int didn't work. 2867 02:10:06,362 --> 02:10:09,070 But that's not the issue here because this is not from a library. 2868 02:10:09,070 --> 02:10:10,270 I just invented this. 2869 02:10:10,270 --> 02:10:12,580 C takes you literally. 2870 02:10:12,580 --> 02:10:15,610 And if you define these functions at the bottom of your file, 2871 02:10:15,610 --> 02:10:18,910 they don't exist on line 7 or 10. 2872 02:10:18,910 --> 02:10:20,690 So I could do this. 2873 02:10:20,690 --> 02:10:23,590 I could, all right, fine, well, let me just highlight all of this, 2874 02:10:23,590 --> 02:10:26,342 cut to my clipboard, and paste it up here. 2875 02:10:26,342 --> 02:10:27,550 This would solve the problem. 2876 02:10:27,550 --> 02:10:30,280 I could just move all of those functions at the top of my file. 2877 02:10:30,280 --> 02:10:33,380 That's annoying because now main is at the bottom of the file. 2878 02:10:33,380 --> 02:10:34,930 It's going to take longer to find it. 2879 02:10:34,930 --> 02:10:36,560 That's not a clean solution. 2880 02:10:36,560 --> 02:10:39,170 So let me put it back where it was at the bottom. 2881 02:10:39,170 --> 02:10:40,730 And let me do this. 2882 02:10:40,730 --> 02:10:44,110 This is the only time in CS50 and, really in C programming 2883 02:10:44,110 --> 02:10:46,060 where copy/paste is reasonable. 2884 02:10:46,060 --> 02:10:50,320 If you copy and paste the first line of code from each function 2885 02:10:50,320 --> 02:10:55,000 and then end it with a semicolon, you can tease the compiler 2886 02:10:55,000 --> 02:10:58,270 by giving it just enough of a hint at the top of the file 2887 02:10:58,270 --> 02:11:01,010 that, OK, these functions don't exist till down later. 2888 02:11:01,010 --> 02:11:03,190 But here's a hint that they will exist. 2889 02:11:03,190 --> 02:11:07,660 This is how you can convince the compiler to trust you. 2890 02:11:07,660 --> 02:11:11,830 So those other functions can still be lower in the file, below main. 2891 02:11:11,830 --> 02:11:14,440 But now when I do make mario-- 2892 02:11:14,440 --> 02:11:15,190 oh, damn it. 2893 02:11:15,190 --> 02:11:17,260 Oh, I said print instead of printf. 2894 02:11:17,260 --> 02:11:20,860 That's my bad-- printf. 2895 02:11:20,860 --> 02:11:26,665 So if I do make mario, ./mario, now I can type in 3, 2896 02:11:26,665 --> 02:11:27,790 and we're back in business. 2897 02:11:27,790 --> 02:11:30,190 Now, this was a very heavy-handed way in long way 2898 02:11:30,190 --> 02:11:32,800 to get to a much more complicated solution. 2899 02:11:32,800 --> 02:11:35,240 But this solution, in some sense, is better designed. 2900 02:11:35,240 --> 02:11:35,740 Why? 2901 02:11:35,740 --> 02:11:38,050 Because now, especially without the comments, 2902 02:11:38,050 --> 02:11:40,060 I mean, look how short my code is. 2903 02:11:40,060 --> 02:11:42,430 My main function is literally two lines of code. 2904 02:11:42,430 --> 02:11:42,940 Why? 2905 02:11:42,940 --> 02:11:46,338 Well, I factored out the juicy stuff into its own functions. 2906 02:11:46,338 --> 02:11:48,880 And now, especially if I'm working with colleagues or others, 2907 02:11:48,880 --> 02:11:52,297 you could imagine splitting up large programs into smaller parts, 2908 02:11:52,297 --> 02:11:54,380 having different people implement different parts, 2909 02:11:54,380 --> 02:11:58,750 so long as you all agree in advance on what those inputs and those outputs 2910 02:11:58,750 --> 02:12:00,410 actually are. 2911 02:12:00,410 --> 02:12:04,300 All right, so let's now consider what computers can do well and not so well. 2912 02:12:04,300 --> 02:12:07,360 C indeed supports a whole bunch of operators, mathematically, 2913 02:12:07,360 --> 02:12:10,610 via which we can do addition, and subtraction, multiplication, division, 2914 02:12:10,610 --> 02:12:14,025 and even calculate the remainder when you divide one number by another. 2915 02:12:14,025 --> 02:12:16,900 In fact, why don't we go ahead and use these in a very simple program 2916 02:12:16,900 --> 02:12:19,130 and make our very own calculator? 2917 02:12:19,130 --> 02:12:21,400 So let me go over here to VS Code. 2918 02:12:21,400 --> 02:12:25,030 Let me go ahead and create a new file called calculator.c. 2919 02:12:25,030 --> 02:12:27,550 And in this file, let's go ahead and first include 2920 02:12:27,550 --> 02:12:33,670 a couple of now familiar header files-- cs50.h as well as stdio.h. 2921 02:12:33,670 --> 02:12:37,540 Let's go ahead then and declare main with int main(void). 2922 02:12:37,540 --> 02:12:40,250 And then inside of main, let's do something relatively simple. 2923 02:12:40,250 --> 02:12:42,790 Let's declare an int and call it x, and set 2924 02:12:42,790 --> 02:12:45,670 it equal to whatever the return value is of get int, 2925 02:12:45,670 --> 02:12:48,040 prompting the user for a value for x. 2926 02:12:48,040 --> 02:12:50,240 Let's then give ourselves a second variable. 2927 02:12:50,240 --> 02:12:51,490 We'll call it, say, y. 2928 02:12:51,490 --> 02:12:55,230 Set that equal to the return value of another call to get_int, 2929 02:12:55,230 --> 02:12:57,780 prompting the user this time for that value y. 2930 02:12:57,780 --> 02:13:00,360 And then let's very simply go ahead at the very end 2931 02:13:00,360 --> 02:13:05,080 and just print out, say, the sum of x plus y, a super simple calculator. 2932 02:13:05,080 --> 02:13:08,640 So I'll use printf, quote/unquote, %i for integer, 2933 02:13:08,640 --> 02:13:10,930 backslash n to give me the new line. 2934 02:13:10,930 --> 02:13:14,640 Then I'm going to go ahead and do x plus y to indeed print out the sum. 2935 02:13:14,640 --> 02:13:16,710 Let me go down to my terminal window now. 2936 02:13:16,710 --> 02:13:20,340 Let me do make calculator in order to compile the code. 2937 02:13:20,340 --> 02:13:22,080 No error messages, so that's good. 2938 02:13:22,080 --> 02:13:23,880 Let me do ./calculator. 2939 02:13:23,880 --> 02:13:28,500 And let's do something like 2 plus 2, which, of course, should equal 4. 2940 02:13:28,500 --> 02:13:29,340 And it does. 2941 02:13:29,340 --> 02:13:33,660 But it turns out that sometimes there are going to be limitations 2942 02:13:33,660 --> 02:13:34,677 that we bump up against. 2943 02:13:34,677 --> 02:13:36,510 And let me get a little more ambitious here. 2944 02:13:36,510 --> 02:13:37,890 Let me clear my terminal window. 2945 02:13:37,890 --> 02:13:39,990 And let me go ahead and rerun calculator again. 2946 02:13:39,990 --> 02:13:47,280 And this time, let's, oh, 2 billion for x, and let's type in the same for y. 2947 02:13:47,280 --> 02:13:49,740 And, of course, now the answer of 2 billion plus 2 billion 2948 02:13:49,740 --> 02:13:52,560 should, of course, be 4 billion. 2949 02:13:52,560 --> 02:13:53,970 And yet, it's not. 2950 02:13:53,970 --> 02:13:56,790 So curiously, we see, of all things, a negative number 2951 02:13:56,790 --> 02:14:00,060 here, which suggests that somehow the plus operator doesn't quite 2952 02:14:00,060 --> 02:14:02,070 work as well as we might like. 2953 02:14:02,070 --> 02:14:04,240 Now, why might this actually be? 2954 02:14:04,240 --> 02:14:07,770 Well, it turns out that inside of your computer is, of course, memory, or RAM, 2955 02:14:07,770 --> 02:14:08,850 Random Access Memory. 2956 02:14:08,850 --> 02:14:11,160 And depending on the size of your computer and the type of computer, 2957 02:14:11,160 --> 02:14:13,410 it might very well look a little something like this-- 2958 02:14:13,410 --> 02:14:15,930 a little circuit board with these black little modules on it 2959 02:14:15,930 --> 02:14:19,320 that actually contain all of the bytes of your computer's memory. 2960 02:14:19,320 --> 02:14:22,200 Unfortunately, you and I only have a finite amount 2961 02:14:22,200 --> 02:14:25,080 of this memory inside of our computers, which 2962 02:14:25,080 --> 02:14:27,250 means no matter how high we want to count, 2963 02:14:27,250 --> 02:14:29,670 there's ultimately going to be a limitation on how high we 2964 02:14:29,670 --> 02:14:32,790 can count because we only have a finite amount of memory. 2965 02:14:32,790 --> 02:14:35,800 We don't have an infinite number of zeros and ones to play with. 2966 02:14:35,800 --> 02:14:38,640 We have to actually be bounded ultimately. 2967 02:14:38,640 --> 02:14:40,072 So what's the implication of this? 2968 02:14:40,072 --> 02:14:42,030 Well, it turns out that computers typically use 2969 02:14:42,030 --> 02:14:46,110 as many as 32 bits in zeros or ones to represent something 2970 02:14:46,110 --> 02:14:48,120 like an integer, or in C, in int. 2971 02:14:48,120 --> 02:14:50,010 So for instance, the smallest number we could 2972 02:14:50,010 --> 02:14:53,830 represent using 32 ints, of course, using 32 bits, of course, 2973 02:14:53,830 --> 02:14:55,020 would be zero-- 2974 02:14:55,020 --> 02:14:56,970 32 zeros like this here. 2975 02:14:56,970 --> 02:14:59,100 And the biggest number we could represent 2976 02:14:59,100 --> 02:15:03,180 is by changing all of those zeros to ones, which, in this case, 2977 02:15:03,180 --> 02:15:07,200 will ideally give us a number that equals roughly 4 billion in total. 2978 02:15:07,200 --> 02:15:15,390 It's actually 4,294,967,295 maximally if you set all 32 of those bits to ones 2979 02:15:15,390 --> 02:15:17,160 and then do out the actual math. 2980 02:15:17,160 --> 02:15:20,520 The catch, though, is that we humans and computers in general 2981 02:15:20,520 --> 02:15:24,730 also sometimes want to and need to be able to represent negative numbers. 2982 02:15:24,730 --> 02:15:28,230 So if you want to represent negative numbers as well as positive numbers 2983 02:15:28,230 --> 02:15:30,960 in 0, you can't really just start counting at 0 2984 02:15:30,960 --> 02:15:33,360 and go all the way up to roughly 4 billion. 2985 02:15:33,360 --> 02:15:35,280 You've got to split the difference and maybe 2986 02:15:35,280 --> 02:15:39,390 allocate half of those patterns of zeros and ones two negative numbers 2987 02:15:39,390 --> 02:15:41,890 and the other half roughly to positive numbers. 2988 02:15:41,890 --> 02:15:46,260 So in fact, in practice, when you're using even as many as 32 bits, 2989 02:15:46,260 --> 02:15:49,740 the highest most computers could count, certainly in a program like this in C 2990 02:15:49,740 --> 02:15:52,500 using an int, would be roughly 2 billion. 2991 02:15:52,500 --> 02:15:57,180 That is 2,147,483,647. 2992 02:15:57,180 --> 02:15:59,880 But the flip side of that is that we could also now, 2993 02:15:59,880 --> 02:16:03,420 using different patterns of bits, represent negative numbers as low 2994 02:16:03,420 --> 02:16:06,630 as negative 2 billion, give or take. 2995 02:16:06,630 --> 02:16:09,240 But the implication then, of course, is that if we only 2996 02:16:09,240 --> 02:16:13,530 have a finite number of bits and can only count so high, at some point, 2997 02:16:13,530 --> 02:16:16,360 we're going to run out of bits, so to speak. 2998 02:16:16,360 --> 02:16:20,280 In other words, we encounter what's generally known as integer overflow 2999 02:16:20,280 --> 02:16:23,080 where you want to use more bits than you have available. 3000 02:16:23,080 --> 02:16:26,767 And as a result, you overflow the available space. 3001 02:16:26,767 --> 02:16:28,600 What does this mean, in fact, in real terms? 3002 02:16:28,600 --> 02:16:30,683 Well, let's suppose that you only have three bits, 3003 02:16:30,683 --> 02:16:32,910 but I'm going to gray out a fourth bit just 3004 02:16:32,910 --> 02:16:37,080 to convey where we'd like to put an additional bit ultimately. 3005 02:16:37,080 --> 02:16:40,230 If this of course, is 0, per week 0's discussion, 3006 02:16:40,230 --> 02:16:45,360 this is 1, 2, 3, 4, 5, 6, 7. 3007 02:16:45,360 --> 02:16:50,100 Now, ideally, in binary, if you want to add one more to this value 7, 3008 02:16:50,100 --> 02:16:53,070 you're going to have to carry the 1 mathematically, 3009 02:16:53,070 --> 02:16:56,250 and that would ideally give 1000. 3010 02:16:56,250 --> 02:17:00,420 But if you don't have four bits and your computer is only sophisticated enough 3011 02:17:00,420 --> 02:17:03,270 to have three bits, not even 32, but three, 3012 02:17:03,270 --> 02:17:07,799 the implication is that you're effectively representing not 1000, 3013 02:17:07,799 --> 02:17:10,620 but rather, 000. 3014 02:17:10,620 --> 02:17:13,770 There's just no room to store that fourth bit 3015 02:17:13,770 --> 02:17:17,850 that I've grayed out here, which is to say that your integer might overflow. 3016 02:17:17,850 --> 02:17:21,540 And as soon as you get to 7, the next number once you add 1 3017 02:17:21,540 --> 02:17:24,299 is actually going to be 0, or worse, as we've seen here 3018 02:17:24,299 --> 02:17:27,129 in my code, a negative value instead. 3019 02:17:27,129 --> 02:17:30,209 So what could we do to perhaps address this kind of concern? 3020 02:17:30,209 --> 02:17:32,490 Well, C does not have just integers or ints. 3021 02:17:32,490 --> 02:17:34,559 It also has longs, which, as the name suggests, 3022 02:17:34,559 --> 02:17:38,469 are just longer integers, which means they have more bits available to them. 3023 02:17:38,469 --> 02:17:40,080 So let me go back into my code here. 3024 02:17:40,080 --> 02:17:41,430 I'll clear the terminal window. 3025 02:17:41,430 --> 02:17:43,590 And let me go ahead and change my integers to 3026 02:17:43,590 --> 02:17:47,010 literally long here, long here. 3027 02:17:47,010 --> 02:17:51,600 I'm going to have to change my function in CS50's library 3028 02:17:51,600 --> 02:17:53,228 to be not get_int, but get_long. 3029 02:17:53,228 --> 02:17:55,770 And that's indeed another function we provide in the library. 3030 02:17:55,770 --> 02:17:57,809 Let me change this get_int to get_long as well. 3031 02:17:57,809 --> 02:18:01,480 I'll keep my variable names the same, but I do need to make one other change. 3032 02:18:01,480 --> 02:18:05,190 It turns out that printf also supports other format codes-- 3033 02:18:05,190 --> 02:18:09,629 so not just %i for integers or %s for strings, but also, for instance, 3034 02:18:09,629 --> 02:18:15,780 %li for a long integer, as well as %f for floating-point values with 3035 02:18:15,780 --> 02:18:16,379 decimals. 3036 02:18:16,379 --> 02:18:20,280 So with that said, let's go ahead and change my printf line to be not %i, 3037 02:18:20,280 --> 02:18:21,690 but %li. 3038 02:18:21,690 --> 02:18:26,219 Now let me go ahead and do make calculator again, Enter-- 3039 02:18:26,219 --> 02:18:29,160 no apparent errors now-- ./calculator. 3040 02:18:29,160 --> 02:18:31,740 And 2 plus 2 still equals 4 as before. 3041 02:18:31,740 --> 02:18:36,910 But now if I do calculator again, and let's do 2 billion 3042 02:18:36,910 --> 02:18:41,170 again as well as 2 billion for y, previously, we 3043 02:18:41,170 --> 02:18:44,629 overflowed the size of an integer and got some weird negative number 3044 02:18:44,629 --> 02:18:47,830 because the pattern was misinterpreted, if you will, as a negative number 3045 02:18:47,830 --> 02:18:48,340 instead. 3046 02:18:48,340 --> 02:18:51,340 But a long, instead of using 32 bits, conventionally 3047 02:18:51,340 --> 02:18:55,240 uses 64 bits, which means we have more than enough spare bits 3048 02:18:55,240 --> 02:18:57,850 to go when we add 2 billion plus 2 billion. 3049 02:18:57,850 --> 02:19:01,190 And now, in fact, we get the correct answer of 4 billion, 3050 02:19:01,190 --> 02:19:04,840 which does fit inside of the size of a long. 3051 02:19:04,840 --> 02:19:07,459 Now, a long can count up quite high. 3052 02:19:07,459 --> 02:19:12,340 And, in fact, it can count as high as this, 9 quintillion. 3053 02:19:12,340 --> 02:19:14,889 And so that will give us quite a bit more runway. 3054 02:19:14,889 --> 02:19:17,837 But, of course, it too is ultimately going to be finite. 3055 02:19:17,837 --> 02:19:20,170 So if you have numbers that need to go bigger than that, 3056 02:19:20,170 --> 02:19:22,930 you might still very well have a problem. 3057 02:19:22,930 --> 02:19:25,430 Now, there's another problem that we might run into as well. 3058 02:19:25,430 --> 02:19:28,660 And we can see it in the context of even this simple calculator. 3059 02:19:28,660 --> 02:19:32,520 Computers also suffer from potentially what's called truncation, 3060 02:19:32,520 --> 02:19:35,770 where especially when you're doing math involving floating-point values-- that 3061 02:19:35,770 --> 02:19:40,420 is numbers with decimals-- you might accidentally unknowingly truncate 3062 02:19:40,420 --> 02:19:43,610 the value-- that is lose everything after the decimal point. 3063 02:19:43,610 --> 02:19:45,549 So in fact, let me go back to VS Code here. 3064 02:19:45,549 --> 02:19:46,900 I'll clear my terminal window. 3065 02:19:46,900 --> 02:19:49,630 And let's still use longs, but let's go ahead and use 3066 02:19:49,630 --> 02:19:52,520 division instead of addition here. 3067 02:19:52,520 --> 02:19:55,090 So let me change this plus to a divide operator. 3068 02:19:55,090 --> 02:19:59,020 Let me go ahead and recompile the code down here with make calculator. 3069 02:19:59,020 --> 02:20:02,620 Let me go ahead and run ./calculator, and let me go ahead and do something 3070 02:20:02,620 --> 02:20:06,370 like 1 for x and 3 for y. 3071 02:20:06,370 --> 02:20:07,547 And we'll see that-- 3072 02:20:07,547 --> 02:20:08,380 well, wait a minute. 3073 02:20:08,380 --> 02:20:11,500 1 divided by 3, I learned, should be 1/3. 3074 02:20:11,500 --> 02:20:18,348 But in a floating-point value, that should 0.33333, maybe 3075 02:20:18,348 --> 02:20:20,140 with a little line over it in grade school, 3076 02:20:20,140 --> 02:20:21,890 but, really, an infinite number of threes. 3077 02:20:21,890 --> 02:20:26,140 And yet, we seem to have lost even one of those threes after the decimal point 3078 02:20:26,140 --> 02:20:30,040 because the answer is coming back here as just 0. 3079 02:20:30,040 --> 02:20:31,700 So why might that be? 3080 02:20:31,700 --> 02:20:35,740 Well, if I know that two integers, when divided one by the other, 3081 02:20:35,740 --> 02:20:38,920 is supposed to give me a fraction, a floating-point value 3082 02:20:38,920 --> 02:20:42,640 with a decimal point, I can't continue to use integers or even, 3083 02:20:42,640 --> 02:20:46,370 in this case, longs, which do not have support for decimal points. 3084 02:20:46,370 --> 02:20:51,040 So let me go ahead and change this format code here from %li to %f, 3085 02:20:51,040 --> 02:20:55,090 which is, again, going to represent a floating-point value instead of a long 3086 02:20:55,090 --> 02:20:56,560 integer or even an integer. 3087 02:20:56,560 --> 02:21:03,400 And let me go ahead further and define maybe a third variable, z, as a float 3088 02:21:03,400 --> 02:21:04,100 itself. 3089 02:21:04,100 --> 02:21:07,300 So I'll give myself a variable z equals x divided by y. 3090 02:21:07,300 --> 02:21:10,720 And now rather than print x divided by y, let's just go ahead and print z. 3091 02:21:10,720 --> 02:21:13,060 So now I'm operating in a world of floating-point values 3092 02:21:13,060 --> 02:21:17,230 because I proactively that a long or an int divided 3093 02:21:17,230 --> 02:21:20,260 by another such value, if it's meant to have a fraction, 3094 02:21:20,260 --> 02:21:24,710 needs to be stored in a floating-point value, something with a decimal point. 3095 02:21:24,710 --> 02:21:27,730 Well, let me go down to my terminal window here and rerun make 3096 02:21:27,730 --> 02:21:31,120 of calculator-- seems to work OK-- ./calculator, 3097 02:21:31,120 --> 02:21:34,180 and let's do 1 divided by 3 again. 3098 02:21:34,180 --> 02:21:36,868 And still here, we see all zeros. 3099 02:21:36,868 --> 02:21:39,910 So we do at least see a decimal point, so we've made some progress Thanks 3100 02:21:39,910 --> 02:21:41,350 to the %f and the float. 3101 02:21:41,350 --> 02:21:46,570 But it seems that we've already truncated the value 1 divided by 3. 3102 02:21:46,570 --> 02:21:48,520 So how do we actually get around this issue? 3103 02:21:48,520 --> 02:21:50,050 Well, if you the programmer know that you're 3104 02:21:50,050 --> 02:21:52,467 dealing in a world that's going to give you floating point 3105 02:21:52,467 --> 02:21:54,760 values with decimal points, you might very well 3106 02:21:54,760 --> 02:21:57,340 need to use what's called a feature known 3107 02:21:57,340 --> 02:22:02,050 as typecasting-- that is convert one data type to another by explicitly 3108 02:22:02,050 --> 02:22:04,390 telling the compiler that you want to do so. 3109 02:22:04,390 --> 02:22:05,480 Now, how do I do this? 3110 02:22:05,480 --> 02:22:07,100 Well, let's go back to my code here. 3111 02:22:07,100 --> 02:22:11,260 And if the issue fundamentally is that C is still 3112 02:22:11,260 --> 02:22:14,920 treating x and y as integers-- or technically, 3113 02:22:14,920 --> 02:22:18,310 longs with no decimal point-- and dividing one by the other, 3114 02:22:18,310 --> 02:22:22,330 therefore has no room, so to speak, for any numbers after a decimal point, 3115 02:22:22,330 --> 02:22:24,830 why don't I proactively do this? 3116 02:22:24,830 --> 02:22:28,030 Let me, using a slightly new syntax with parentheses, 3117 02:22:28,030 --> 02:22:33,910 specify that I want to convert x proactively from a long to a float. 3118 02:22:33,910 --> 02:22:39,100 Let me specify proactively that I want to convert y from a long to a float 3119 02:22:39,100 --> 02:22:39,950 as well. 3120 02:22:39,950 --> 02:22:42,910 And now let me go ahead and trust that nz 3121 02:22:42,910 --> 02:22:46,870 should be the result of dividing not a long by a long or an int by an int, 3122 02:22:46,870 --> 02:22:49,330 but rather, a float by a float. 3123 02:22:49,330 --> 02:22:52,630 Let me clear my terminal window, run make calculator again-- 3124 02:22:52,630 --> 02:22:55,300 seems to work OK-- ./calculator. 3125 02:22:55,300 --> 02:23:00,760 And now 1, 3, and hopefully now we actually see 3126 02:23:00,760 --> 02:23:05,380 that my code has outputted 0.333333. 3127 02:23:05,380 --> 02:23:08,380 And I think if we kept showing more numbers after the decimal point, 3128 02:23:08,380 --> 02:23:11,710 we'd theoretically see as many of those threes as we want. 3129 02:23:11,710 --> 02:23:13,900 But there is still one more catch. 3130 02:23:13,900 --> 02:23:16,240 And especially when we're manipulating numbers 3131 02:23:16,240 --> 02:23:19,090 in this way in a computer using a finite amount of memory, 3132 02:23:19,090 --> 02:23:22,180 another challenge we might run up against-- besides integer 3133 02:23:22,180 --> 02:23:27,100 overflow, besides truncation-- is this known as floating-point imprecision. 3134 02:23:27,100 --> 02:23:31,480 Just as we can't represent as big of an integer as we want using int 3135 02:23:31,480 --> 02:23:34,060 or long alone because there is going to be an upper bound, 3136 02:23:34,060 --> 02:23:39,220 there's similarly going to be a bound on just how precise our numbers can be. 3137 02:23:39,220 --> 02:23:41,560 And indeed, let's go back to VS Code here. 3138 02:23:41,560 --> 02:23:43,430 I'll clear my terminal window yet again. 3139 02:23:43,430 --> 02:23:46,900 And this time, let me use some slightly unlikely syntax to specify that I 3140 02:23:46,900 --> 02:23:49,970 don't want to see the default number of numbers after the decimal point, 3141 02:23:49,970 --> 02:23:52,250 which %f gives us automatically. 3142 02:23:52,250 --> 02:23:57,520 Let's go ahead and show me 20 decimal point numbers after the decimal point. 3143 02:23:57,520 --> 02:24:00,700 And the weird syntax for this is to do not %f, 3144 02:24:00,700 --> 02:24:05,950 but %.20 to indicate to see that I want to see 20 digits, 3145 02:24:05,950 --> 02:24:08,440 not the default after, now, the decimal point. 3146 02:24:08,440 --> 02:24:10,390 Let me rerun make calculator. 3147 02:24:10,390 --> 02:24:12,550 Let me do ./calculator again. 3148 02:24:12,550 --> 02:24:14,890 And let's do 1, let's do 3. 3149 02:24:14,890 --> 02:24:17,560 And now this is even weirder, right? 3150 02:24:17,560 --> 02:24:20,590 From grade school, you presumably learned that 1 divided by 3 3151 02:24:20,590 --> 02:24:21,580 is, of course, 1/3. 3152 02:24:21,580 --> 02:24:26,890 But that should be 0.33333, infinitely many times, or, on paper, 3153 02:24:26,890 --> 02:24:28,180 with a little line over it. 3154 02:24:28,180 --> 02:24:31,660 But the computer is doing some weird approximation here. 3155 02:24:31,660 --> 02:24:37,480 It's a whole bunch of 3's and then 4326744079590. 3156 02:24:37,480 --> 02:24:39,380 Well, what's really happening under the hood, 3157 02:24:39,380 --> 02:24:42,100 well, again, is this issue of floating-point imprecision. 3158 02:24:42,100 --> 02:24:45,220 If you only have a finite number of bits and, in turn, 3159 02:24:45,220 --> 02:24:48,100 a finite amount of memory, the computer can really only 3160 02:24:48,100 --> 02:24:52,300 be so precise intuitively. 3161 02:24:52,300 --> 02:24:55,000 Equivalently, the computer is decided on some way 3162 02:24:55,000 --> 02:24:57,190 of representing floating-point values. 3163 02:24:57,190 --> 02:24:59,470 But the catch is, per grade school math, there's 3164 02:24:59,470 --> 02:25:02,800 an infinite number of numbers out there and an infinite number 3165 02:25:02,800 --> 02:25:06,460 of floating-point values because you can keep adding more and more digits if you 3166 02:25:06,460 --> 02:25:07,040 want. 3167 02:25:07,040 --> 02:25:10,120 So the computer, given the way it's implementing these floating point 3168 02:25:10,120 --> 02:25:14,500 values, is essentially giving us the closest approximation that it can. 3169 02:25:14,500 --> 02:25:17,740 Now, how can we go about improving the situation? 3170 02:25:17,740 --> 02:25:19,180 Well, there is one alternative. 3171 02:25:19,180 --> 02:25:21,115 Instead of using float, I can use something 3172 02:25:21,115 --> 02:25:22,990 called a double, which, as the name suggests, 3173 02:25:22,990 --> 02:25:24,760 uses twice as many bits as a float. 3174 02:25:24,760 --> 02:25:27,820 So instead of 32 typically, it will use 64. 3175 02:25:27,820 --> 02:25:30,570 And that's just like the difference between a long and an int, 3176 02:25:30,570 --> 02:25:31,570 which gave us more bits. 3177 02:25:31,570 --> 02:25:34,480 But in this case, this will be used for more precision. 3178 02:25:34,480 --> 02:25:36,850 Let's go ahead and cast x to a double. 3179 02:25:36,850 --> 02:25:38,740 Let's cast y to a double. 3180 02:25:38,740 --> 02:25:41,530 And now let's go ahead and, using the same format code-- 3181 02:25:41,530 --> 02:25:45,220 %.20f is still OK for doubles. 3182 02:25:45,220 --> 02:25:46,990 Let me do make calculator. 3183 02:25:46,990 --> 02:25:48,970 Let me do ./calculator. 3184 02:25:48,970 --> 02:25:51,460 And now let me do 1 divided by 3. 3185 02:25:51,460 --> 02:25:53,770 And we still have some of that imprecision. 3186 02:25:53,770 --> 02:25:56,590 And it's even more of it if we looked at more than just 20 digits. 3187 02:25:56,590 --> 02:25:59,900 But now we have more threes after the decimal point. 3188 02:25:59,900 --> 02:26:03,640 So it's at least more, and more, and more precise, but it's not perfect. 3189 02:26:03,640 --> 02:26:06,520 But it's at least more precise. 3190 02:26:06,520 --> 02:26:08,500 So these kinds of issues, then, are going 3191 02:26:08,500 --> 02:26:10,360 to be necessary to keep in mind any time you 3192 02:26:10,360 --> 02:26:12,640 do something numerically, scientifically, at least 3193 02:26:12,640 --> 02:26:14,980 with a language C where you're going to bump up 3194 02:26:14,980 --> 02:26:18,910 against these real-world limitations of hardware and, in turn, language. 3195 02:26:18,910 --> 02:26:21,952 Now, later in the semester, we'll transition to a language called Python. 3196 02:26:21,952 --> 02:26:24,660 And that's actually going to solve at least one of these problems 3197 02:26:24,660 --> 02:26:26,950 for us by just automatically giving us more bits, 3198 02:26:26,950 --> 02:26:29,470 so to speak, as we need them, at least for integers. 3199 02:26:29,470 --> 02:26:33,140 But even the issue of floating-point imprecision is going to remain. 3200 02:26:33,140 --> 02:26:35,170 Now, just how real-world are these issues? 3201 02:26:35,170 --> 02:26:37,780 Well, back in the year 1999, we got a taste 3202 02:26:37,780 --> 02:26:40,840 of this when the world realized in the years leading up to that date 3203 02:26:40,840 --> 02:26:45,010 that it might not have been the best idea to implement computers 3204 02:26:45,010 --> 02:26:48,910 and software therein by storing gears using just two digits. 3205 02:26:48,910 --> 02:26:53,440 Like, instead of storing 1999 to represent the year 1999, 3206 02:26:53,440 --> 02:26:56,470 a lot of computers, for reasons of space and cost, 3207 02:26:56,470 --> 02:26:59,200 were in the habit of cutting a corner and just using 3208 02:26:59,200 --> 02:27:01,400 two digits to keep track of the year. 3209 02:27:01,400 --> 02:27:06,850 The problem with that is that if systems were not updated by the year 1999 3210 02:27:06,850 --> 02:27:11,560 to support the year 2000, 2001, and so forth, is that, just like before 3211 02:27:11,560 --> 02:27:14,290 with integer overflow, some computers might 3212 02:27:14,290 --> 02:27:16,990 add 1 to the year in their memory, '99. 3213 02:27:16,990 --> 02:27:19,540 It should be the year 2000, but if they're only 3214 02:27:19,540 --> 02:27:22,090 using two digits to represent years, they 3215 02:27:22,090 --> 02:27:25,330 might mistake the year-- as some systems may very well have-- 3216 02:27:25,330 --> 02:27:28,390 for the year 1900 instead, taking literally 3217 02:27:28,390 --> 02:27:30,740 a big step backwards, if you will. 3218 02:27:30,740 --> 02:27:32,622 Now, you'd like to think that kind of issue 3219 02:27:32,622 --> 02:27:34,330 is behind us, especially as we understand 3220 02:27:34,330 --> 02:27:37,240 all the more about the limitations of code and computing. 3221 02:27:37,240 --> 02:27:40,390 But we're actually going to run up against this very same type of issue 3222 02:27:40,390 --> 02:27:42,160 again in just a few years. 3223 02:27:42,160 --> 02:27:48,850 On January 19 in the year 2038, we will have run out of bits in most computers 3224 02:27:48,850 --> 02:27:50,800 right now to keep track of time. 3225 02:27:50,800 --> 02:27:55,330 It turns out, years ago, humans decided to use a 32-bit integer 3226 02:27:55,330 --> 02:27:58,870 to keep track of how many seconds had elapsed over time. 3227 02:27:58,870 --> 02:28:01,090 They chose a somewhat arbitrary date in the past-- 3228 02:28:01,090 --> 02:28:03,350 January 1, 1970-- 3229 02:28:03,350 --> 02:28:06,860 And they just started counting seconds from there on out. 3230 02:28:06,860 --> 02:28:09,100 And so if a computer stores some number of seconds, 3231 02:28:09,100 --> 02:28:11,350 that tells the computer how many seconds have 3232 02:28:11,350 --> 02:28:14,710 passed since that particular date, January 1, 1970. 3233 02:28:14,710 --> 02:28:17,380 Unfortunately, using a 32-bit integer, as we've 3234 02:28:17,380 --> 02:28:20,480 seen, you can only count so high, at which point, 3235 02:28:20,480 --> 02:28:23,470 you overflow the size of that variable. 3236 02:28:23,470 --> 02:28:27,250 And so potentially, if we don't get ahead of this as humans, as a society, 3237 02:28:27,250 --> 02:28:32,080 as computer scientists, on the date January 19, 2038, 3238 02:28:32,080 --> 02:28:36,910 that bit might flip over, thereby overflowing the size of those integers, 3239 02:28:36,910 --> 02:28:42,460 bringing us back computationally to December 13, 1901. 3240 02:28:42,460 --> 02:28:45,970 So this is to say now, with all of this computational ability and code 3241 02:28:45,970 --> 02:28:48,560 comes a responsibility to actually write correct code. 3242 02:28:48,560 --> 02:28:50,560 Next week, we'll peel back some of these layers. 3243 02:28:50,560 --> 02:28:54,550 But for now, this was week 1, and best of luck on problem set 1. 3244 02:28:54,550 --> 02:28:57,850 [APPLAUSE] 3245 02:28:57,850 --> 02:29:01,500 [MUSIC PLAYING] 3246 02:29:01,500 --> 02:29:33,000