1 00:00:00,000 --> 00:01:17,917 [MUSIC PLAYING] 2 00:01:17,917 --> 00:01:19,000 DAVID J. MALAN: All right. 3 00:01:19,000 --> 00:01:20,560 So this is CS50. 4 00:01:20,560 --> 00:01:24,670 And this is week 1, the one in which you learn a new language, which 5 00:01:24,670 --> 00:01:27,550 is something we technically said last week, at least if you had never 6 00:01:27,550 --> 00:01:30,850 played with this graphical language known as Scratch before, which itself 7 00:01:30,850 --> 00:01:32,530 was a programming language. 8 00:01:32,530 --> 00:01:34,660 But today, as promised, we transition to something 9 00:01:34,660 --> 00:01:37,120 a little more traditional, a little more text-based, 10 00:01:37,120 --> 00:01:39,700 not puzzle piece- or block-based, known as C. 11 00:01:39,700 --> 00:01:40,970 This is an older language. 12 00:01:40,970 --> 00:01:42,178 It's been around for decades. 13 00:01:42,178 --> 00:01:45,700 But it's a language that underlies so many of today's more modern languages, 14 00:01:45,700 --> 00:01:48,460 among them something called Python that we'll also 15 00:01:48,460 --> 00:01:50,020 come to in a few weeks' time. 16 00:01:50,020 --> 00:01:52,120 Indeed, at the end of the semester, the goal 17 00:01:52,120 --> 00:01:53,860 is for you to feel that you've not learned Scratch, 18 00:01:53,860 --> 00:01:56,110 you've not learned C, or even Python, for that matter, 19 00:01:56,110 --> 00:01:58,570 but fundamentally that you've learned how to program. 20 00:01:58,570 --> 00:02:01,000 Unfortunately, when you learn how to program 21 00:02:01,000 --> 00:02:04,880 with a more traditional language like this, there's just so much distraction. 22 00:02:04,880 --> 00:02:08,290 Last week I described all of the syntax, all of the weird punctuation 23 00:02:08,290 --> 00:02:11,080 that you see in this, like the hash symbol, these angled brackets, 24 00:02:11,080 --> 00:02:13,960 parentheses, curly braces, backslash n, and more. 25 00:02:13,960 --> 00:02:17,990 Well, today we're not going to reveal what all of those little particulars 26 00:02:17,990 --> 00:02:18,490 mean. 27 00:02:18,490 --> 00:02:22,660 But by next week, will this no longer look like the proverbial Greek 28 00:02:22,660 --> 00:02:26,590 to you, a language that, presumably, you've never actually seen or typed 29 00:02:26,590 --> 00:02:27,520 before. 30 00:02:27,520 --> 00:02:31,400 But to do that, we'll explore some of the very same topics as last week. 31 00:02:31,400 --> 00:02:34,420 So recall that, via Scratch-- and presumably via problem set 1-- 32 00:02:34,420 --> 00:02:37,780 we took a look at things called functions that are actions or verbs. 33 00:02:37,780 --> 00:02:40,510 And related to functions were arguments like inputs. 34 00:02:40,510 --> 00:02:43,960 And related to some functions were returned values like outputs. 35 00:02:43,960 --> 00:02:47,350 Then we talked a bit about conditionals, forks in the road, so to speak, 36 00:02:47,350 --> 00:02:50,740 Boolean expressions, which are just yes/no questions or true/false 37 00:02:50,740 --> 00:02:54,340 questions, loops, which let you do things again and again, variables, 38 00:02:54,340 --> 00:02:57,190 like in math, that let you store values temporarily, 39 00:02:57,190 --> 00:02:58,870 and then even other topics still. 40 00:02:58,870 --> 00:03:02,620 So if you were comfortable on the heels of problem set 0 and last week, 41 00:03:02,620 --> 00:03:05,690 realize that all of these topics are going to remain with us. 42 00:03:05,690 --> 00:03:09,430 So really, today is just about acquiring all the more of a mental model for how 43 00:03:09,430 --> 00:03:14,110 you translate those ideas into, presumably, a very cryptic new syntax-- 44 00:03:14,110 --> 00:03:16,898 a new syntax, frankly, that's actually more 45 00:03:16,898 --> 00:03:18,940 simple in some ways than your own human language, 46 00:03:18,940 --> 00:03:22,622 be it English or something else, because there's far fewer vocabulary words. 47 00:03:22,622 --> 00:03:24,580 There's actually far less syntax that you might 48 00:03:24,580 --> 00:03:26,650 have in, say, a typical human language. 49 00:03:26,650 --> 00:03:30,800 But you need to be with these computer languages all the more precise 50 00:03:30,800 --> 00:03:33,050 so that you're most, ultimately, correct, 51 00:03:33,050 --> 00:03:37,240 and ultimately will see to your code is successful along a few other lines 52 00:03:37,240 --> 00:03:37,820 as well. 53 00:03:37,820 --> 00:03:40,990 So if you think about the last time you kind of wandered around not really 54 00:03:40,990 --> 00:03:43,180 knowing what you were doing or encountered something new-- 55 00:03:43,180 --> 00:03:46,055 might not have been that long ago, entering Harvard Yard for the very 56 00:03:46,055 --> 00:03:49,660 first time, or Old Campus or the like, be it in Cambridge or New Haven-- 57 00:03:49,660 --> 00:03:53,022 you didn't really need to know how to do everything as a first year. 58 00:03:53,022 --> 00:03:54,730 You didn't need to know who everyone was, 59 00:03:54,730 --> 00:03:58,430 where everything was, how Harvard or Yale, or anything else for that matter, 60 00:03:58,430 --> 00:03:58,930 worked. 61 00:03:58,930 --> 00:04:02,055 You sort of got by day to day by just focusing on those things that matter. 62 00:04:02,055 --> 00:04:03,805 And anything you didn't really understand, 63 00:04:03,805 --> 00:04:06,160 you sort of turned a blind eye to until it's important. 64 00:04:06,160 --> 00:04:07,960 And that's, indeed, what we're going to do today. 65 00:04:07,960 --> 00:04:09,835 And really, for the next several weeks, we'll 66 00:04:09,835 --> 00:04:12,370 focus on details that are initially important 67 00:04:12,370 --> 00:04:15,542 and try to wave our hands, so to speak, at details that, yeah, eventually 68 00:04:15,542 --> 00:04:17,000 we'll get to, might be interesting. 69 00:04:17,000 --> 00:04:18,667 But for now, they might be distractions. 70 00:04:18,667 --> 00:04:21,100 And by distractions, I really mean some of that syntax 71 00:04:21,100 --> 00:04:22,700 to which I alluded earlier. 72 00:04:22,700 --> 00:04:25,870 So by the end of today-- and really, by the end of problem set 1, 73 00:04:25,870 --> 00:04:28,600 your first foray, presumably, into this language called C-- 74 00:04:28,600 --> 00:04:30,370 you'll have written some code. 75 00:04:30,370 --> 00:04:32,980 And you'll be asking yourself-- we'll be asking yourselves-- 76 00:04:32,980 --> 00:04:34,360 just how good is that code? 77 00:04:34,360 --> 00:04:37,240 Well, first and foremost, per last week, be it in Scratch 78 00:04:37,240 --> 00:04:42,790 or phone book form, code ultimately needs to be correct, to be well done. 79 00:04:42,790 --> 00:04:44,740 You want the problem to be solved correctly. 80 00:04:44,740 --> 00:04:46,690 So that one sort of goes without saying. 81 00:04:46,690 --> 00:04:50,710 And along the way this term, we'll provide you with tools and techniques 82 00:04:50,710 --> 00:04:53,945 so you don't have to just sit there sort of endlessly trying an input, 83 00:04:53,945 --> 00:04:56,570 checking the output, trying another input, checking the output. 84 00:04:56,570 --> 00:04:58,360 There's a lot of automation tools in the real world-- 85 00:04:58,360 --> 00:05:00,400 and in this class and others like it-- that 86 00:05:00,400 --> 00:05:04,210 will help facilitate you answering that question for yourself, is my code 87 00:05:04,210 --> 00:05:07,100 correct, according to our specifications or the like. 88 00:05:07,100 --> 00:05:09,640 But then something that's going to take more time 89 00:05:09,640 --> 00:05:13,060 and you're probably not going to feel 100% comfortable with the first week, 90 00:05:13,060 --> 00:05:16,090 the first weeks, is just how well designed your code is. 91 00:05:16,090 --> 00:05:18,813 It's one thing to speak English or write English, 92 00:05:18,813 --> 00:05:21,230 but it's another thing-- or any language, for that matter. 93 00:05:21,230 --> 00:05:23,390 But it's another thing to speak it or write it well. 94 00:05:23,390 --> 00:05:26,348 And we spend all these years in middle school, high school, presumably, 95 00:05:26,348 --> 00:05:29,800 writing papers and other documents, getting grades and feedback on them 96 00:05:29,800 --> 00:05:33,010 as to how well formulated your arguments were, how well structured 97 00:05:33,010 --> 00:05:34,219 your paper was, and the like. 98 00:05:34,219 --> 00:05:36,170 And there's that same idea in programming. 99 00:05:36,170 --> 00:05:40,790 It doesn't matter necessarily that you've just solved a problem correctly. 100 00:05:40,790 --> 00:05:44,815 If your code is a complete visual mess, or if it's crazy long, 101 00:05:44,815 --> 00:05:46,690 it's going to be really hard for someone else 102 00:05:46,690 --> 00:05:50,320 to wrap their mind around what your code is doing and, indeed, to be confident 103 00:05:50,320 --> 00:05:51,400 if it is correct. 104 00:05:51,400 --> 00:05:55,210 And honestly, you-- the next morning, the next year, 105 00:05:55,210 --> 00:05:58,750 the next time you look at that code-- might have no idea 106 00:05:58,750 --> 00:06:00,580 what you yourself were even thinking. 107 00:06:00,580 --> 00:06:04,930 But you will if you focus, too, on designing good code, 108 00:06:04,930 --> 00:06:07,840 getting your algorithms efficient, getting your code nice and clean, 109 00:06:07,840 --> 00:06:10,360 and even making sure your code looks pretty, which 110 00:06:10,360 --> 00:06:12,080 we'd describe as a matter of style. 111 00:06:12,080 --> 00:06:15,713 So in the written human world, having punctuation in the right place, 112 00:06:15,713 --> 00:06:18,380 capitalization and the like-- the sort of way you write an essay 113 00:06:18,380 --> 00:06:20,420 but not necessarily send a text message-- 114 00:06:20,420 --> 00:06:22,620 relates to style, for instance. 115 00:06:22,620 --> 00:06:24,560 And so good style in code is going to have 116 00:06:24,560 --> 00:06:28,160 a few of these characteristics that are pretty easily taught and remembered. 117 00:06:28,160 --> 00:06:33,180 But you just have to start to get in the habit of writing code in a certain way. 118 00:06:33,180 --> 00:06:36,140 So these three axes, so to speak, correctness, design, and style, 119 00:06:36,140 --> 00:06:39,320 are really the overarching goals when writing code that 120 00:06:39,320 --> 00:06:41,400 ultimately is going to look like this. 121 00:06:41,400 --> 00:06:43,400 So this program we conjectured last week does 122 00:06:43,400 --> 00:06:48,063 what if you run it on a Mac or PC or somewhere else, presumably? 123 00:06:48,063 --> 00:06:48,730 What does it do? 124 00:06:48,730 --> 00:06:50,500 Yeah? 125 00:06:50,500 --> 00:06:51,460 AUDIENCE: [INAUDIBLE]. 126 00:06:51,460 --> 00:06:53,335 DAVID J. MALAN: It just prints, Hello, world. 127 00:06:53,335 --> 00:06:55,510 And honestly, that's kind of atrocious that you 128 00:06:55,510 --> 00:06:59,260 need to hit your keyboard keys this many times with this cryptic syntax just 129 00:06:59,260 --> 00:07:00,940 to get a program to say, Hello, world. 130 00:07:00,940 --> 00:07:03,190 So a spoiler-- in a few weeks' time when we 131 00:07:03,190 --> 00:07:05,650 introduce other, more modern languages, like Python, 132 00:07:05,650 --> 00:07:09,830 you can distill this same logic into literally one line of code. 133 00:07:09,830 --> 00:07:11,500 And so we're getting there, ultimately. 134 00:07:11,500 --> 00:07:14,493 But it's helpful to understand what it is that's going on here, 135 00:07:14,493 --> 00:07:16,660 because even though this is a pretty cryptic syntax, 136 00:07:16,660 --> 00:07:19,300 there's nothing after this week and, really, next week that you shouldn't 137 00:07:19,300 --> 00:07:22,120 be able to understand even about something that right now looks 138 00:07:22,120 --> 00:07:23,510 a little something like this. 139 00:07:23,510 --> 00:07:24,843 So how do you write code? 140 00:07:24,843 --> 00:07:27,010 Well, I've given us sort of the answer to a problem. 141 00:07:27,010 --> 00:07:28,927 How do you print, Hello, world, on the screen? 142 00:07:28,927 --> 00:07:30,377 So what do I do with this code? 143 00:07:30,377 --> 00:07:33,460 Well, we're in the habit of typically writing things with, like, Microsoft 144 00:07:33,460 --> 00:07:35,110 Word or Google documents. 145 00:07:35,110 --> 00:07:39,230 And yeah, I could open up Word or Google Docs or Pages or the like 146 00:07:39,230 --> 00:07:41,980 and just literally transcribe that character for character, 147 00:07:41,980 --> 00:07:44,590 save it, and boom, I've got a program. 148 00:07:44,590 --> 00:07:47,830 But the problem, per last week, is that computers only understand or speak 149 00:07:47,830 --> 00:07:50,363 what other language, so to speak? 150 00:07:50,363 --> 00:07:51,280 AUDIENCE: [INAUDIBLE]. 151 00:07:51,280 --> 00:07:53,510 DAVID J. MALAN: Yeah, so binary, zeros and ones. 152 00:07:53,510 --> 00:07:55,510 And so this, obviously, is not zeros and ones. 153 00:07:55,510 --> 00:07:58,240 So it doesn't matter if I put it in a Word doc, Google Doc, Pages file, 154 00:07:58,240 --> 00:07:58,832 or the like. 155 00:07:58,832 --> 00:08:01,249 The computer is not going to understand it until I somehow 156 00:08:01,249 --> 00:08:02,770 translate it to zeros and ones. 157 00:08:02,770 --> 00:08:05,320 And honestly, none of those tools that I rattled off 158 00:08:05,320 --> 00:08:07,180 are really appropriate for programming. 159 00:08:07,180 --> 00:08:07,750 Why? 160 00:08:07,750 --> 00:08:10,210 Well, they come with features like bold facing and italics 161 00:08:10,210 --> 00:08:14,080 and sort of fluffy, aesthetic stuff that has no functional impact on what 162 00:08:14,080 --> 00:08:15,830 you're trying to do with your code. 163 00:08:15,830 --> 00:08:17,860 And they don't have the ability, it would 164 00:08:17,860 --> 00:08:20,860 seem, to convert that code ultimately to zeros and ones. 165 00:08:20,860 --> 00:08:23,650 But tools that do have this capability might 166 00:08:23,650 --> 00:08:27,550 be called Integrated Development Environments, or IDEs, 167 00:08:27,550 --> 00:08:29,380 or, more simply, text editors. 168 00:08:29,380 --> 00:08:33,760 A text editor is a tool that a programmer uses perhaps every day 169 00:08:33,760 --> 00:08:35,230 to write their code. 170 00:08:35,230 --> 00:08:38,050 And it's a simple program-- here, for instance, a very popular one 171 00:08:38,050 --> 00:08:40,742 called Visual Studio Code, or VS Code. 172 00:08:40,742 --> 00:08:42,700 And at the top here, you see that I've actually 173 00:08:42,700 --> 00:08:47,590 created in advance before class a very simple empty file called "hello.c." 174 00:08:47,590 --> 00:08:48,220 Why? 175 00:08:48,220 --> 00:08:51,940 Well, .c indicates by convention that this is going to be a file in which 176 00:08:51,940 --> 00:08:52,840 there is C code. 177 00:08:52,840 --> 00:08:57,250 It's not .docx, which would mean in this file is a Microsoft Word document, 178 00:08:57,250 --> 00:08:59,260 or .pages is a Pages file. 179 00:08:59,260 --> 00:09:03,820 This is .c, which means in this file is going to be text in the language called 180 00:09:03,820 --> 00:09:07,270 C. This number 1 here is just an automatic line number that's going help 181 00:09:07,270 --> 00:09:09,640 me keep track of how long or short this program is. 182 00:09:09,640 --> 00:09:12,250 And the cursor is just blinking there, waiting 183 00:09:12,250 --> 00:09:14,230 for me to start typing some code. 184 00:09:14,230 --> 00:09:17,230 Well, let me go ahead and type out exactly the same code. 185 00:09:17,230 --> 00:09:19,460 For me, it comes pretty comfortably from memory. 186 00:09:19,460 --> 00:09:22,990 So I'm going to go ahead and include something called standardio.h-- 187 00:09:22,990 --> 00:09:24,160 more on that later. 188 00:09:24,160 --> 00:09:28,420 I'm going to magically type int main(void), whatever that means-- 189 00:09:28,420 --> 00:09:29,810 we'll come back to that later-- 190 00:09:29,810 --> 00:09:34,760 one of these curly braces and then a sibling there that closes the same. 191 00:09:34,760 --> 00:09:37,810 Then I'm going to hit Tab to indent a few spaces. 192 00:09:37,810 --> 00:09:44,050 And then I'm going to type not print, but printf, then "Hello, world," /n, 193 00:09:44,050 --> 00:09:47,050 close quote, close parenthesis, semicolon. 194 00:09:47,050 --> 00:09:51,250 And I dare say this was essentially the very first program I wrote some 195 00:09:51,250 --> 00:09:52,419 25 years ago. 196 00:09:52,419 --> 00:09:54,490 I wrote it to say, "Hi, CS50." 197 00:09:54,490 --> 00:09:57,400 Now it just says the more canonical, conventional, "Hello, world." 198 00:09:57,400 --> 00:09:58,299 But that's it. 199 00:09:58,299 --> 00:09:59,590 That's my very first program. 200 00:09:59,590 --> 00:10:02,440 And all I need to now do is maybe hit Command-S or Control-S 201 00:10:02,440 --> 00:10:03,310 to save the file. 202 00:10:03,310 --> 00:10:06,280 And voila, I am a programmer. 203 00:10:06,280 --> 00:10:09,027 The catch though, is, OK, how do I run this? 204 00:10:09,027 --> 00:10:11,110 Like, on your Mac or PC, how do you run a program? 205 00:10:11,110 --> 00:10:12,610 Well, usually double-click an icon. 206 00:10:12,610 --> 00:10:14,320 On your phone, you tap an icon. 207 00:10:14,320 --> 00:10:18,010 In this environment that we're using and that many programmers-- dare 208 00:10:18,010 --> 00:10:22,870 say most programmers-- use, you don't have immediately a nice, pretty icon 209 00:10:22,870 --> 00:10:23,710 to double-click on. 210 00:10:23,710 --> 00:10:26,933 That's very user friendly, but it's not very necessary. 211 00:10:26,933 --> 00:10:29,350 Especially when you get more comfortable with programming, 212 00:10:29,350 --> 00:10:32,230 you're going to want to type commands because it's just faster than pointing 213 00:10:32,230 --> 00:10:33,220 and clicking a mouse. 214 00:10:33,220 --> 00:10:35,053 And you're going to want to automate things, 215 00:10:35,053 --> 00:10:37,990 which is a lot easier if it's all command or text-based, as opposed 216 00:10:37,990 --> 00:10:40,330 to mouse and muscular movements. 217 00:10:40,330 --> 00:10:43,210 And so here I have my program. 218 00:10:43,210 --> 00:10:45,790 It lives in this file called "hello.c." 219 00:10:45,790 --> 00:10:49,330 I need to now convert it, though, to zeros and ones. 220 00:10:49,330 --> 00:10:53,530 Well, how do I go about doing this, and how am I going to get from this 221 00:10:53,530 --> 00:10:54,880 so-called code-- 222 00:10:54,880 --> 00:10:57,670 or source code, as it's conventionally called-- 223 00:10:57,670 --> 00:11:02,240 to this, these zeros and ones that we'll now start calling machine code. 224 00:11:02,240 --> 00:11:04,690 The zeros and ones from last week can be used not only 225 00:11:04,690 --> 00:11:09,950 to represent numbers and letters, colors, audio, video, and more. 226 00:11:09,950 --> 00:11:15,250 It can also represent instructions to a computer, like print, or play a sound, 227 00:11:15,250 --> 00:11:17,290 or delete a file, or save a file. 228 00:11:17,290 --> 00:11:19,960 All the sort of basics of a computer somehow 229 00:11:19,960 --> 00:11:23,560 can be represented by other patterns of zeros and ones. 230 00:11:23,560 --> 00:11:26,133 And just like last week, it depends on the context 231 00:11:26,133 --> 00:11:27,550 in which these numbers are stored. 232 00:11:27,550 --> 00:11:30,880 Sometimes they're interpreted as numbers, like in a spreadsheet. 233 00:11:30,880 --> 00:11:32,590 Sometimes they're interpreted as colors. 234 00:11:32,590 --> 00:11:37,240 Sometimes they're interpreted as instructions, commands to your computer 235 00:11:37,240 --> 00:11:42,020 to do very low-level operations, like print something on the screen. 236 00:11:42,020 --> 00:11:46,810 So fortunately, last week's definition of computer science of problem solving 237 00:11:46,810 --> 00:11:49,220 is a nice mental model for exactly the goal at hand. 238 00:11:49,220 --> 00:11:52,000 I have some input, AKA source code. 239 00:11:52,000 --> 00:11:56,200 I want to output ultimately machine code, those zeros and ones. 240 00:11:56,200 --> 00:11:58,780 I certainly don't want to do this kind of process by hand. 241 00:11:58,780 --> 00:12:02,380 So hopefully there's an algorithm implemented by some special program 242 00:12:02,380 --> 00:12:03,825 that does exactly that. 243 00:12:03,825 --> 00:12:05,950 And those of you who do have some prior experience, 244 00:12:05,950 --> 00:12:08,146 this program might be called a? 245 00:12:08,146 --> 00:12:09,350 A compiler. 246 00:12:09,350 --> 00:12:11,350 So a few of you have, indeed, programmed before. 247 00:12:11,350 --> 00:12:13,030 Not all languages use compilers. 248 00:12:13,030 --> 00:12:15,550 C, in fact, is a language that does use a compiler. 249 00:12:15,550 --> 00:12:18,880 And so I just need to find myself-- 250 00:12:18,880 --> 00:12:22,480 on my computer somewhere, presumably-- a so-called compiler, 251 00:12:22,480 --> 00:12:26,930 a program whose purpose in life is to convert one language to another. 252 00:12:26,930 --> 00:12:31,660 And source code written textually in C, like we saw a moment ago, 253 00:12:31,660 --> 00:12:32,860 is source code. 254 00:12:32,860 --> 00:12:35,690 The machine code is the corresponding zeros and ones. 255 00:12:35,690 --> 00:12:39,460 So let me go back to the same programming environment called 256 00:12:39,460 --> 00:12:41,620 Visual Studio Code or VS Code. 257 00:12:41,620 --> 00:12:44,740 This is typically a program you or any programmer on the internet 258 00:12:44,740 --> 00:12:48,550 can download onto their own Mac or PC and be on their way with whatever 259 00:12:48,550 --> 00:12:50,950 computer you own writing some code. 260 00:12:50,950 --> 00:12:53,380 A downside, though, of that approach is that all of us 261 00:12:53,380 --> 00:12:55,990 have slightly different versions of Macs or PCs. 262 00:12:55,990 --> 00:12:58,570 We have slightly different versions of operating systems. 263 00:12:58,570 --> 00:13:00,130 They may or may not be up to date. 264 00:13:00,130 --> 00:13:04,220 It's just a technical support nightmare to create a uniform environment, 265 00:13:04,220 --> 00:13:07,030 especially for an introductory class, where everyone should ideally 266 00:13:07,030 --> 00:13:10,400 be on the same page so we can get you up and running quickly. 267 00:13:10,400 --> 00:13:14,380 And so I'm actually using a cloud-based version of VS Code, something 268 00:13:14,380 --> 00:13:17,170 that you only need a browser to access. 269 00:13:17,170 --> 00:13:19,960 And then you can be on any computer, today or tomorrow. 270 00:13:19,960 --> 00:13:23,540 By the end of the semester, we're going to get you out of the cloud, 271 00:13:23,540 --> 00:13:27,220 so to speak, as best we can and get you onto your own Mac or PC, 272 00:13:27,220 --> 00:13:30,730 so that after this class, especially if it's the only CS class you ever take, 273 00:13:30,730 --> 00:13:34,330 you feel like you can continue programming in any number of languages, 274 00:13:34,330 --> 00:13:36,470 even with CS50 behind you. 275 00:13:36,470 --> 00:13:39,160 But for now, wonderfully, the browser version of VS Code 276 00:13:39,160 --> 00:13:42,992 should pretty much be identical to what the eventual downloadable 277 00:13:42,992 --> 00:13:44,200 version of the same would be. 278 00:13:44,200 --> 00:13:46,720 And you'll see in problem set 1 how to access this 279 00:13:46,720 --> 00:13:49,990 and how to get going yourself with your first programs. 280 00:13:49,990 --> 00:13:52,840 But I haven't mentioned this bottom part of the screen, 281 00:13:52,840 --> 00:13:54,340 this bottom part of the screen. 282 00:13:54,340 --> 00:13:57,770 And this is an area where we have what's called a terminal window. 283 00:13:57,770 --> 00:14:01,600 So this is sort of old-school technology that allows you, with a keyboard, 284 00:14:01,600 --> 00:14:06,580 to interact with a computer, wherever it may be-- on your lap, in your pocket, 285 00:14:06,580 --> 00:14:08,800 or even, in this case, in the cloud. 286 00:14:08,800 --> 00:14:11,350 So on the top-hand portion of this screen 287 00:14:11,350 --> 00:14:15,940 is my text editor, like tabbed windows, like in many programs, where 288 00:14:15,940 --> 00:14:18,130 I can just create files and write code. 289 00:14:18,130 --> 00:14:21,250 The bottom of the screen here, my so-called terminal window, 290 00:14:21,250 --> 00:14:24,340 gives me the ability to run commands on a server 291 00:14:24,340 --> 00:14:26,800 that currently I have exclusive access to. 292 00:14:26,800 --> 00:14:30,880 So because I logged into VS Code with my account online, 293 00:14:30,880 --> 00:14:35,650 I have my own sort of virtual server, if you will, in the cloud-- 294 00:14:35,650 --> 00:14:37,900 otherwise known as, in this context, a container. 295 00:14:37,900 --> 00:14:40,970 This has its own operating system for me, its own hard drive, 296 00:14:40,970 --> 00:14:43,840 if you will, where I can save and create files of my own, 297 00:14:43,840 --> 00:14:46,190 separate from yours and vice versa. 298 00:14:46,190 --> 00:14:48,580 And it's at this very simple prompt, which 299 00:14:48,580 --> 00:14:51,417 is conventionally-- but not always-- abbreviated by a dollar sign, 300 00:14:51,417 --> 00:14:52,750 has nothing to do with currency. 301 00:14:52,750 --> 00:14:54,843 It just means, type your commands here. 302 00:14:54,843 --> 00:14:57,010 This is where I'm going to be able to type commands, 303 00:14:57,010 --> 00:15:01,070 like compile my source code into machine code. 304 00:15:01,070 --> 00:15:06,722 So it's a Command Line Interface, or CLI, on top of an operating system 305 00:15:06,722 --> 00:15:09,430 that you might not have ever used or seen, but it's very popular, 306 00:15:09,430 --> 00:15:10,420 called Linux. 307 00:15:10,420 --> 00:15:14,930 Odds are almost all of us in this room are using Mac OS or Windows right now, 308 00:15:14,930 --> 00:15:18,190 but we're all going to start using an operating system called Linux, which 309 00:15:18,190 --> 00:15:21,340 is in a family of operating systems that offer not only this command 310 00:15:21,340 --> 00:15:24,430 line interface, but are used not just for programming, but for serving 311 00:15:24,430 --> 00:15:27,050 websites and developing applications and the like. 312 00:15:27,050 --> 00:15:31,490 And it's, indeed, a familiar and very powerful interface, as we'll see. 313 00:15:31,490 --> 00:15:37,000 So how do I go about making this file, hello.c, into a program? 314 00:15:37,000 --> 00:15:39,940 There's no icon to double-click, but there is a command. 315 00:15:39,940 --> 00:15:45,340 I can type, make hello, at this dollar sign prompt, go ahead and hit Enter, 316 00:15:45,340 --> 00:15:47,500 and nothing appears to happen. 317 00:15:47,500 --> 00:15:48,732 But that's a good thing. 318 00:15:48,732 --> 00:15:50,690 And as we'll see in programming, almost always, 319 00:15:50,690 --> 00:15:53,860 if you don't see anything go wrong, that means everything went right. 320 00:15:53,860 --> 00:15:55,600 So this is going to be a rarity at first, 321 00:15:55,600 --> 00:15:58,690 but this is a good thing that it just seems to do nothing. 322 00:15:58,690 --> 00:16:02,860 But now there is in the folder in my accounts 323 00:16:02,860 --> 00:16:06,460 in this on the cloud a file called "hello." 324 00:16:06,460 --> 00:16:09,970 And it's a bit of a weird command, but you'll get familiar with it 325 00:16:09,970 --> 00:16:10,780 before long. 326 00:16:10,780 --> 00:16:13,780 . just means go into my current folder. 327 00:16:13,780 --> 00:16:19,570 /hello means run the program called "hello" in this current folder. 328 00:16:19,570 --> 00:16:24,070 So ./hello, and then Enter, and voila, now I'm actually not just programming, 329 00:16:24,070 --> 00:16:26,990 but running my actual code. 330 00:16:26,990 --> 00:16:29,500 So what have I just done? 331 00:16:29,500 --> 00:16:31,310 Let me go ahead and do this. 332 00:16:31,310 --> 00:16:33,970 I'm going to go ahead and open up the sidebar of this program, 333 00:16:33,970 --> 00:16:36,110 and you'll see in problem set 1 how to do this. 334 00:16:36,110 --> 00:16:39,250 And this might look a little different based on your own configuration. 335 00:16:39,250 --> 00:16:42,390 Even the color scheme I'm using might ultimately look different from yours, 336 00:16:42,390 --> 00:16:44,140 because it supports a nice colorful theme. 337 00:16:44,140 --> 00:16:47,920 So you can have different colors and brightnesses depending 338 00:16:47,920 --> 00:16:49,450 on your mood or the time of day. 339 00:16:49,450 --> 00:16:52,840 What I've opened here, though, is what is called in VS Code Explorer, 340 00:16:52,840 --> 00:16:55,478 and this is just all of the files in my cloud account. 341 00:16:55,478 --> 00:16:56,770 And there's not many right now. 342 00:16:56,770 --> 00:16:57,775 There's only two. 343 00:16:57,775 --> 00:17:00,280 One is the file called hello.c, and it's highlighted 344 00:17:00,280 --> 00:17:02,050 because I've got it open right there. 345 00:17:02,050 --> 00:17:05,530 And the other is a file called "hello," which is brand new 346 00:17:05,530 --> 00:17:08,530 and was created when I ran that command. 347 00:17:08,530 --> 00:17:12,630 And what's now worth noting is that now things are getting a little more 348 00:17:12,630 --> 00:17:13,980 like Mac OS and Windows. 349 00:17:13,980 --> 00:17:17,340 Like on the left-hand side, you have a GUI, a Graphical User Interface. 350 00:17:17,340 --> 00:17:21,475 But on the bottom here, again, you have a CLI, Command Line Interface. 351 00:17:21,475 --> 00:17:23,850 These are just different ways to interact with computers, 352 00:17:23,850 --> 00:17:25,392 and you'll get comfortable with both. 353 00:17:25,392 --> 00:17:28,650 And honestly, you're certainly familiar and comfortable with GUIs already, 354 00:17:28,650 --> 00:17:32,110 so it's the command line one with which we'll spend some time. 355 00:17:32,110 --> 00:17:34,800 Now suppose that I just wanted to do something 356 00:17:34,800 --> 00:17:36,638 more than compile this program. 357 00:17:36,638 --> 00:17:38,430 Suppose I wanted to go ahead and remove it. 358 00:17:38,430 --> 00:17:39,900 Like, uh-uh, no, I made a mistake. 359 00:17:39,900 --> 00:17:42,270 I want to say, "Hello, CS50," not "Hello, world." 360 00:17:42,270 --> 00:17:46,320 I could just hover up here, like in any software, and I could right-click, 361 00:17:46,320 --> 00:17:49,080 and I could poke around, and there, delete permanently. 362 00:17:49,080 --> 00:17:51,570 So most of us might have that instinct on a Mac or PC. 363 00:17:51,570 --> 00:17:54,000 You right-click or Control-click, and you poke around. 364 00:17:54,000 --> 00:17:57,150 But in a command line interface, let me do this instead. 365 00:17:57,150 --> 00:17:59,640 The command for removing or deleting a file 366 00:17:59,640 --> 00:18:03,300 in the world of Linux, this other operating system, 367 00:18:03,300 --> 00:18:07,530 is just a type rm for remove, and then "hello," Enter. 368 00:18:07,530 --> 00:18:10,290 It's a somewhat cryptic confirmation message, but this just means, 369 00:18:10,290 --> 00:18:11,160 are you sure? 370 00:18:11,160 --> 00:18:12,960 I'm going to go ahead and type Y for Yes. 371 00:18:12,960 --> 00:18:15,390 And now when I hit Enter, watch what happens 372 00:18:15,390 --> 00:18:19,440 at top left in the Explorer, the GUI, the graphical interface. 373 00:18:19,440 --> 00:18:21,989 Voila, it disappears. 374 00:18:21,989 --> 00:18:24,180 Not terribly exciting, but this just means 375 00:18:24,180 --> 00:18:26,739 this is a graphical version of what we're seeing here. 376 00:18:26,739 --> 00:18:29,999 And in fact, if you want to never use the GUI again-- 377 00:18:29,999 --> 00:18:32,890 I'll go ahead and close it with a keyboard shortcut here-- 378 00:18:32,890 --> 00:18:36,630 you can forever just type ls for list and hit Enter. 379 00:18:36,630 --> 00:18:39,300 And you will see in the command line interface 380 00:18:39,300 --> 00:18:41,817 all of the files in your current folder. 381 00:18:41,817 --> 00:18:43,650 So anything you can do with a mouse, you can 382 00:18:43,650 --> 00:18:45,239 do with this command line interface. 383 00:18:45,239 --> 00:18:48,610 And indeed, we'll see many more things that you can do as well. 384 00:18:48,610 --> 00:18:52,290 But the inventors of this, this operating system and its predecessors, 385 00:18:52,290 --> 00:18:53,490 were very succinct. 386 00:18:53,490 --> 00:18:55,560 Like, the command is rm for remove. 387 00:18:55,560 --> 00:18:57,330 The command is ls for list. 388 00:18:57,330 --> 00:18:58,090 It's very terse. 389 00:18:58,090 --> 00:18:58,590 Why? 390 00:18:58,590 --> 00:19:01,680 Because it's just faster to type. 391 00:19:01,680 --> 00:19:05,460 So before we forge ahead with making something more interesting than 392 00:19:05,460 --> 00:19:07,380 just "Hello, world," let me pause here to see 393 00:19:07,380 --> 00:19:10,620 if there's questions on source code or machine 394 00:19:10,620 --> 00:19:15,420 code or compiler or this command line interface. 395 00:19:15,420 --> 00:19:16,293 Yeah? 396 00:19:16,293 --> 00:19:17,828 AUDIENCE: [INAUDIBLE]. 397 00:19:17,828 --> 00:19:20,120 DAVID J. MALAN: Really good question, and let me recap. 398 00:19:20,120 --> 00:19:21,950 If I were to make changes to the program, 399 00:19:21,950 --> 00:19:25,070 run it, and then maybe make other changes and try to rerun it, 400 00:19:25,070 --> 00:19:28,227 would those changes be reflected, even though I've reworded slightly. 401 00:19:28,227 --> 00:19:29,060 Well, let's do this. 402 00:19:29,060 --> 00:19:31,160 I already removed the old version. 403 00:19:31,160 --> 00:19:34,730 So let me go ahead and point out that if I do ./hello now, 404 00:19:34,730 --> 00:19:38,960 I'm going to see some kind of error because I just deleted the file. 405 00:19:38,960 --> 00:19:41,630 No such file or directory, so it's not terribly user friendly, 406 00:19:41,630 --> 00:19:43,160 but it's saying what the problem is. 407 00:19:43,160 --> 00:19:46,430 Let me go ahead and remake it by typing make hello. 408 00:19:46,430 --> 00:19:51,110 Now if I type ls, I'll see not one but two files again, and one of them 409 00:19:51,110 --> 00:19:54,815 is even green with a little asterisk to indicate that it's executable. 410 00:19:54,815 --> 00:19:56,690 It's sort of the textual version of something 411 00:19:56,690 --> 00:19:58,450 you could double-click in our human world. 412 00:19:58,450 --> 00:20:01,700 So now, of course, if I run hello, we're back where I started, "Hello, world." 413 00:20:01,700 --> 00:20:07,010 But now suppose I change it to "Hello, CS50," like I did years ago. 414 00:20:07,010 --> 00:20:12,200 Let me go ahead and save the file with Command-S or Control-S. Down here now, 415 00:20:12,200 --> 00:20:14,880 let me run ./hello again, and voila. 416 00:20:14,880 --> 00:20:16,370 Huh. 417 00:20:16,370 --> 00:20:18,630 So let me ask someone else to answer that question. 418 00:20:18,630 --> 00:20:20,210 What's the missing step? 419 00:20:20,210 --> 00:20:22,250 Why did it not say, "Hello, CS50." 420 00:20:22,250 --> 00:20:23,453 Yeah? 421 00:20:23,453 --> 00:20:24,370 AUDIENCE: [INAUDIBLE]. 422 00:20:24,370 --> 00:20:26,440 DAVID J. MALAN: Yeah, so I didn't compile it again. 423 00:20:26,440 --> 00:20:29,620 So sort of newbie mistake, you're going to make this mistake and many others 424 00:20:29,620 --> 00:20:30,190 before long. 425 00:20:30,190 --> 00:20:33,250 But now let me go ahead and remake hello, enter. 426 00:20:33,250 --> 00:20:36,370 It's going to seemingly make the same program. 427 00:20:36,370 --> 00:20:40,630 But this time when I run it, it's, "Hello, CS50." 428 00:20:40,630 --> 00:20:44,380 Any other questions on some of these building blocks? 429 00:20:44,380 --> 00:20:47,780 And we'll come back to all the crazy syntax I typed before long. 430 00:20:47,780 --> 00:20:50,080 But for now, we're focusing on just the output. 431 00:20:50,080 --> 00:20:51,030 Yeah? 432 00:20:51,030 --> 00:20:52,052 AUDIENCE: [INAUDIBLE]. 433 00:20:52,052 --> 00:20:53,760 DAVID J. MALAN: When I keep running make, 434 00:20:53,760 --> 00:20:56,710 it creates a new version of the machine code. 435 00:20:56,710 --> 00:21:00,690 So it keeps changing the hello program and the hello file, and that's it. 436 00:21:00,690 --> 00:21:03,798 There's no make file, per se. 437 00:21:03,798 --> 00:21:04,833 AUDIENCE: [INAUDIBLE]. 438 00:21:04,833 --> 00:21:06,250 DAVID J. MALAN: Good question, no. 439 00:21:06,250 --> 00:21:09,340 If I open up that directory, you'll see that there's just the one. 440 00:21:09,340 --> 00:21:12,430 And it doesn't matter how many times I run make hello-- 441 00:21:12,430 --> 00:21:16,450 three, four, five-- it just keeps overwriting the original. 442 00:21:16,450 --> 00:21:19,952 So it's kind of like just saving in the world of Google Docs or Microsoft 443 00:21:19,952 --> 00:21:20,660 Word or the like. 444 00:21:20,660 --> 00:21:22,202 But there's an additional step today. 445 00:21:22,202 --> 00:21:27,480 We have to then convert my words to the computer's, the zeros and ones. 446 00:21:27,480 --> 00:21:28,793 Yeah, in front. 447 00:21:28,793 --> 00:21:29,740 AUDIENCE: [INAUDIBLE]. 448 00:21:29,740 --> 00:21:31,930 DAVID J. MALAN: Oh, what happens if I run hello.c? 449 00:21:31,930 --> 00:21:36,280 So let me go ahead and do ./hello.c, which is a mistake you'll invariably 450 00:21:36,280 --> 00:21:37,720 make early on. 451 00:21:37,720 --> 00:21:39,020 Permission denied. 452 00:21:39,020 --> 00:21:40,000 So what does that mean? 453 00:21:40,000 --> 00:21:42,160 This is where the error messages mean something 454 00:21:42,160 --> 00:21:44,860 to the people who designed the operating system, but it's a little cryptic. 455 00:21:44,860 --> 00:21:46,900 It's not that you don't have access to the file. 456 00:21:46,900 --> 00:21:48,610 It means that it's not executable. 457 00:21:48,610 --> 00:21:51,400 This is not something you have permission to run, 458 00:21:51,400 --> 00:21:55,942 but you do have permission to read or write it-- that is, change it. 459 00:21:55,942 --> 00:21:57,220 AUDIENCE: [INAUDIBLE]. 460 00:21:57,720 --> 00:21:59,428 DAVID J. MALAN: Oh, really good question. 461 00:21:59,428 --> 00:22:03,000 So if I have named my file, hello dot C, or more generally something 462 00:22:03,000 --> 00:22:06,960 dot C, of the things that Make does is it automatically 463 00:22:06,960 --> 00:22:08,580 picks the file name for me. 464 00:22:08,580 --> 00:22:10,110 And we'll discuss a bit-- 465 00:22:10,110 --> 00:22:11,910 we'll discuss this a bit more next week. 466 00:22:11,910 --> 00:22:14,910 Make itself-- is kind of the first of white lies today-- 467 00:22:14,910 --> 00:22:16,680 itself is not a compiler. 468 00:22:16,680 --> 00:22:22,020 It's a program that knows how to find and use the compiler on the system 469 00:22:22,020 --> 00:22:24,360 and automatically create the program. 470 00:22:24,360 --> 00:22:28,290 If I use, as we'll discuss next week, the actual compiler myself, 471 00:22:28,290 --> 00:22:32,280 I have to type a much longer sequence of commands to specify explicitly 472 00:22:32,280 --> 00:22:34,470 what do I want the name of my program to be. 473 00:22:34,470 --> 00:22:36,510 Make is a nice program, especially in week 1, 474 00:22:36,510 --> 00:22:38,860 because it just automates all of that for us. 475 00:22:38,860 --> 00:22:42,420 And so here, we have now a program that very simply prints 476 00:22:42,420 --> 00:22:43,420 something on the screen. 477 00:22:43,420 --> 00:22:45,990 So let's not put this into the context of where 478 00:22:45,990 --> 00:22:50,070 we left off last time in the context of Scratch and inputs and outputs. 479 00:22:50,070 --> 00:22:53,160 So we discuss the last time, of course, functions and arguments. 480 00:22:53,160 --> 00:22:58,210 Functions, again, are those actions and verbs like say, or ask, or the like. 481 00:22:58,210 --> 00:23:00,602 And the arguments were the inputs to those functions, 482 00:23:00,602 --> 00:23:03,060 generally in those little white ovals that, in Scratch, you 483 00:23:03,060 --> 00:23:05,160 could type words or numbers into. 484 00:23:05,160 --> 00:23:08,160 We'll see, in all of the languages we're going to see this term, 485 00:23:08,160 --> 00:23:09,482 have that same capability. 486 00:23:09,482 --> 00:23:12,190 And let's just start to translate one of these things to another. 487 00:23:12,190 --> 00:23:16,110 So for instance, let's put this same program in C, 488 00:23:16,110 --> 00:23:17,310 in the context of Scratch. 489 00:23:17,310 --> 00:23:20,820 This is what Hello, World looked like last week in the form of one function. 490 00:23:20,820 --> 00:23:23,730 This week, of course, it looks like print. 491 00:23:23,730 --> 00:23:26,190 And then the parentheses, notice, are kind of 492 00:23:26,190 --> 00:23:29,878 deliberately designed in the world of Scratch to resemble that same shape. 493 00:23:29,878 --> 00:23:31,920 Even though this is a white oval, you kind of get 494 00:23:31,920 --> 00:23:36,600 that it's kind of evoking that same idea with the parentheses. 495 00:23:36,600 --> 00:23:40,380 Technically the function in C, it's not called say. 496 00:23:40,380 --> 00:23:41,670 It's not even called print. 497 00:23:41,670 --> 00:23:42,870 It's called printf. 498 00:23:42,870 --> 00:23:46,260 The F stands for formatted, but we'll see what that means in a moment. 499 00:23:46,260 --> 00:23:48,810 But printf is the closest analogous function 500 00:23:48,810 --> 00:23:52,080 for say in the world of C. Notice if, though, you 501 00:23:52,080 --> 00:23:56,700 want to print something like Hello, World or Hello CS50 in C, 502 00:23:56,700 --> 00:24:00,180 you don't just write the words as we did last week. 503 00:24:00,180 --> 00:24:02,610 You also had an add what, if you notice already 504 00:24:02,610 --> 00:24:04,560 what's missing from this version. 505 00:24:04,560 --> 00:24:06,880 Yeah, so the double quotes on the left and the right. 506 00:24:06,880 --> 00:24:12,198 So, that's necessary in C whenever you have a string of words. 507 00:24:12,198 --> 00:24:13,740 And I'm using that word deliberately. 508 00:24:13,740 --> 00:24:18,030 Whenever you have multiple words like this, this is known as a string 509 00:24:18,030 --> 00:24:18,660 as we'll see. 510 00:24:18,660 --> 00:24:22,170 And you have to put it in double quotes, not single quotes. 511 00:24:22,170 --> 00:24:23,880 You have to put it in double quotes. 512 00:24:23,880 --> 00:24:28,080 There's one other stupid thing that we need to have in my C code 513 00:24:28,080 --> 00:24:32,170 in order to get this function to do something ultimately, which is what? 514 00:24:32,170 --> 00:24:33,040 Semicolon. 515 00:24:33,040 --> 00:24:35,440 So just like in our human world, you eventually 516 00:24:35,440 --> 00:24:38,470 got into the habit of using, at least in formal writing, periods. 517 00:24:38,470 --> 00:24:41,890 Semicolon is generally what you use to finish your thought 518 00:24:41,890 --> 00:24:44,980 in the world of programming with C. 519 00:24:44,980 --> 00:24:47,110 All right, so we have that function in place. 520 00:24:47,110 --> 00:24:50,860 Now, what does this really fit into in terms of the mental model? 521 00:24:50,860 --> 00:24:52,270 Well, functions take arguments. 522 00:24:52,270 --> 00:24:55,960 And it turns out functions can have different types of outputs. 523 00:24:55,960 --> 00:24:58,270 And we've actually seen both already last week. 524 00:24:58,270 --> 00:25:02,560 One type of output from a function can be something called a side effect. 525 00:25:02,560 --> 00:25:04,630 And it generally refers to something visual, 526 00:25:04,630 --> 00:25:08,770 like something appearing on the screen or a sound playing from your computer. 527 00:25:08,770 --> 00:25:11,410 It's sort of a side effect of the function doing its thing. 528 00:25:11,410 --> 00:25:15,430 And indeed, last week we saw this in the context of passing in something 529 00:25:15,430 --> 00:25:18,380 like Hello, World as input to the say function. 530 00:25:18,380 --> 00:25:22,240 And we saw on the screen Hello, World, but it was kind of a one off. 531 00:25:22,240 --> 00:25:24,130 It's one and done. 532 00:25:24,130 --> 00:25:27,040 You can't actually do anything with that visual output 533 00:25:27,040 --> 00:25:29,780 other than consume it, visually, with your human eyes. 534 00:25:29,780 --> 00:25:34,450 But sometimes, recall last week, we had functions like the ask block that 535 00:25:34,450 --> 00:25:36,160 actually returned me some value. 536 00:25:36,160 --> 00:25:38,200 Remember the ask, what's your name. 537 00:25:38,200 --> 00:25:41,883 It handed me back whatever answer the human typed in. 538 00:25:41,883 --> 00:25:44,050 It didn't just arbitrarily display it on the screen. 539 00:25:44,050 --> 00:25:46,390 The cat didn't necessarily say it on the screen. 540 00:25:46,390 --> 00:25:52,840 It was stored, instead, in that special variable that was called answer. 541 00:25:52,840 --> 00:25:56,710 Because some functions have not side effects but return values. 542 00:25:56,710 --> 00:26:00,520 They hand you back an output that you can use and reuse, 543 00:26:00,520 --> 00:26:03,160 unlike the side effect, which, again displays and that's it. 544 00:26:03,160 --> 00:26:05,660 You can't sort of catch it and hold on to it. 545 00:26:05,660 --> 00:26:08,800 So, in the context of last week, we had the ask block. 546 00:26:08,800 --> 00:26:11,470 And that had this special answer return value. 547 00:26:11,470 --> 00:26:14,170 In C, we're going to see in just a moment, 548 00:26:14,170 --> 00:26:16,600 we could translate this as follows. 549 00:26:16,600 --> 00:26:20,200 The closest match I can propose for the ask block 550 00:26:20,200 --> 00:26:22,780 is a function that we're going to start calling get string. 551 00:26:22,780 --> 00:26:25,930 String is, again, a word, a set of words, like a phrase 552 00:26:25,930 --> 00:26:27,910 or a sentence in programming. 553 00:26:27,910 --> 00:26:32,530 It, too, is a function insofar as it takes input and pretty much-- 554 00:26:32,530 --> 00:26:34,750 this isn't always true-- but very often when 555 00:26:34,750 --> 00:26:39,460 you have a word in C followed by an open parenthesis and a closed parenthesis, 556 00:26:39,460 --> 00:26:42,160 it's most likely the name of a function. 557 00:26:42,160 --> 00:26:44,660 And we're going to see that there's some exceptions to that. 558 00:26:44,660 --> 00:26:46,990 But for now this indeed looks like a function 559 00:26:46,990 --> 00:26:48,400 because it matches that pattern. 560 00:26:48,400 --> 00:26:51,868 If I want to ask the question, what's your name, question mark-- 561 00:26:51,868 --> 00:26:54,910 and I'm even going to deliberately put a space there just to kind of move 562 00:26:54,910 --> 00:26:58,360 the cursor a little bit over so that the human isn't typing literally 563 00:26:58,360 --> 00:26:59,390 after the question mark. 564 00:26:59,390 --> 00:27:01,400 So that's just the nitpicky aesthetic. 565 00:27:01,400 --> 00:27:05,680 This is perhaps the closest analog to just asking that question. 566 00:27:05,680 --> 00:27:09,880 But because the ask block returns a value, 567 00:27:09,880 --> 00:27:13,220 the analog here forget string is that it, too, returns a value. 568 00:27:13,220 --> 00:27:15,160 It doesn't just print the human's input. 569 00:27:15,160 --> 00:27:19,330 It hands it back to you in the form of a variable, a.k.a. return value, 570 00:27:19,330 --> 00:27:21,700 that I can then use and reuse. 571 00:27:21,700 --> 00:27:24,670 Now ideally it would be as simple as this literally 572 00:27:24,670 --> 00:27:28,090 saying answer on the left equals. 573 00:27:28,090 --> 00:27:29,980 And this is where things start to diverge 574 00:27:29,980 --> 00:27:31,840 from math and sort of our human world. 575 00:27:31,840 --> 00:27:35,410 This equal sign, henceforth, is not the equal sign. 576 00:27:35,410 --> 00:27:37,720 It is the assignment operator. 577 00:27:37,720 --> 00:27:41,230 To assign a value means to store a value in some variable. 578 00:27:41,230 --> 00:27:44,840 And you read these things, weirdly, right to left. 579 00:27:44,840 --> 00:27:47,020 So here is a function called get string. 580 00:27:47,020 --> 00:27:49,510 I claim that it's going to return to you whatever 581 00:27:49,510 --> 00:27:51,610 the human types in as their name. 582 00:27:51,610 --> 00:27:54,520 It's going to get stored over here on the left because 583 00:27:54,520 --> 00:27:57,530 of this so-called assignment operator, that yes is an equal sign. 584 00:27:57,530 --> 00:27:59,780 But it doesn't mean equality in this context. 585 00:27:59,780 --> 00:28:01,370 It makes things equal. 586 00:28:01,370 --> 00:28:06,160 But it does so by copying the value on the right into the thing on the left. 587 00:28:06,160 --> 00:28:08,140 Unfortunately, we're not quite done yet with C. 588 00:28:08,140 --> 00:28:10,870 And this is where, again, it gets a little annoying at first 589 00:28:10,870 --> 00:28:14,980 where Scratch just let us express our ideas without so much syntax. 590 00:28:14,980 --> 00:28:18,310 In C when you have a variable you don't just 591 00:28:18,310 --> 00:28:20,200 give it a name like you did in Scratch. 592 00:28:20,200 --> 00:28:24,250 You also have to tell the computer in advance what type of value 593 00:28:24,250 --> 00:28:25,510 it is storing. 594 00:28:25,510 --> 00:28:28,540 String is one such type of value. 595 00:28:28,540 --> 00:28:31,270 Int, for integer, is going to be another. 596 00:28:31,270 --> 00:28:34,060 And there's even more than that we'll see today and beyond. 597 00:28:34,060 --> 00:28:37,270 And this is partly an answer to the question that came up one or more times 598 00:28:37,270 --> 00:28:41,170 last week, which was how does a computer distinguish this pattern of zeros 599 00:28:41,170 --> 00:28:42,520 and ones from this. 600 00:28:42,520 --> 00:28:46,717 Like is this a letter, a number, a color, a piece of video. 601 00:28:46,717 --> 00:28:49,550 And I just claimed last week that it totally depends on the program. 602 00:28:49,550 --> 00:28:50,633 It depends on the context. 603 00:28:50,633 --> 00:28:52,070 And that's true. 604 00:28:52,070 --> 00:28:55,390 But within those programs, it often depends 605 00:28:55,390 --> 00:29:00,010 on what the human programmer said the type of the value is. 606 00:29:00,010 --> 00:29:02,050 If this specifies that the string, which means 607 00:29:02,050 --> 00:29:04,090 interpret the following zeros and ones that 608 00:29:04,090 --> 00:29:07,840 are stored in my program as words or letters, more generally. 609 00:29:07,840 --> 00:29:12,160 If it's an int for integer, it would be implying, by the programmer, 610 00:29:12,160 --> 00:29:16,180 treat the following zeros and ones in my program as a number, 611 00:29:16,180 --> 00:29:17,990 an integer, not a string. 612 00:29:17,990 --> 00:29:20,860 So here's where this week, unlike with Scratch, 613 00:29:20,860 --> 00:29:24,280 which is kind of figures out what you mean, with C in a lot of languages 614 00:29:24,280 --> 00:29:27,400 you have to be this pedantic and tell it what you mean. 615 00:29:27,400 --> 00:29:30,920 There's still one stupid thing missing from my code here. 616 00:29:30,920 --> 00:29:32,150 What's still missing here? 617 00:29:32,150 --> 00:29:32,450 Yeah. 618 00:29:32,450 --> 00:29:33,350 AUDIENCE: [INAUDIBLE] 619 00:29:33,350 --> 00:29:35,430 DAVID J. MALAN: And we still need the stupid semicolon. 620 00:29:35,430 --> 00:29:36,847 And I'm sort of impugning it here. 621 00:29:36,847 --> 00:29:39,260 Because honestly, these are the kinds of stupid mistakes 622 00:29:39,260 --> 00:29:41,900 you're going to make today, tomorrow, this weekend, next week, 623 00:29:41,900 --> 00:29:45,680 a few weeks from now, until you start to notice this and recognize it 624 00:29:45,680 --> 00:29:49,640 as well as you do English or whatever your spoken language is. 625 00:29:49,640 --> 00:29:51,127 Yeah, question. 626 00:29:51,127 --> 00:29:51,710 Good question. 627 00:29:51,710 --> 00:29:54,230 Suppose I mix apples and oranges, so to speak, 628 00:29:54,230 --> 00:29:57,620 and I try to put a string in an int or an int in a string, 629 00:29:57,620 --> 00:29:59,780 the compiler is going to complain. 630 00:29:59,780 --> 00:30:02,040 So when I run that make command as I did earlier, 631 00:30:02,040 --> 00:30:06,092 it's not going to be nice and blissfully quiet and just give me another prompt. 632 00:30:06,092 --> 00:30:08,300 It's going to yell at me with honestly a very cryptic 633 00:30:08,300 --> 00:30:11,550 looking error message until we get the muscle memory for reading it. 634 00:30:11,550 --> 00:30:14,300 Other questions. 635 00:30:14,300 --> 00:30:16,190 Ah, what happened to the backslash n. 636 00:30:16,190 --> 00:30:18,020 So, we'll come back to that in just a moment, if we may. 637 00:30:18,020 --> 00:30:20,978 Because I have deliberately omitted it here but we did have it earlier. 638 00:30:20,978 --> 00:30:23,510 And we'll see the different behavior in a sec. 639 00:30:23,510 --> 00:30:27,260 Other questions. 640 00:30:27,260 --> 00:30:28,670 Yeah, not at all nitpicky. 641 00:30:28,670 --> 00:30:30,920 These are the kinds of things that just matter. 642 00:30:30,920 --> 00:30:34,910 And it's going to take time to recognize and develop this muscle memory. 643 00:30:34,910 --> 00:30:39,505 Everything I've typed here except, for the W at the moment, is lowercase. 644 00:30:39,505 --> 00:30:41,630 And the W is capitalized just because it's English. 645 00:30:41,630 --> 00:30:43,100 Everything else is lowercase. 646 00:30:43,100 --> 00:30:45,710 And this kind of varies by language and also context. 647 00:30:45,710 --> 00:30:49,820 So, in many languages the convention is to use all lowercase letters 648 00:30:49,820 --> 00:30:51,260 for your variable names. 649 00:30:51,260 --> 00:30:53,640 Other languages might use some capitals, as well. 650 00:30:53,640 --> 00:30:55,250 But we'll talk about that before long. 651 00:30:55,250 --> 00:30:57,150 But this is the kind of thing that matters 652 00:30:57,150 --> 00:31:00,680 and is hard to see at first, especially when a little S doesn't look that 653 00:31:00,680 --> 00:31:04,130 different when it's on your tiny laptop screen from a capital S. 654 00:31:04,130 --> 00:31:07,050 But you'll start to develop these instincts. 655 00:31:07,050 --> 00:31:09,260 All right, so besides this particular block, 656 00:31:09,260 --> 00:31:13,380 let's go ahead and consider how we can go about implementing this now in code. 657 00:31:13,380 --> 00:31:15,500 So let me switch back to VS Code here. 658 00:31:15,500 --> 00:31:17,280 This was the program I had earlier. 659 00:31:17,280 --> 00:31:20,090 And let me go ahead and undo my CS50 change. 660 00:31:20,090 --> 00:31:21,920 And this time just rerun it. 661 00:31:21,920 --> 00:31:26,450 Rerun Make on Hello with the original version with the backslash n. 662 00:31:26,450 --> 00:31:28,430 Enter, nothing bad seems to have happened. 663 00:31:28,430 --> 00:31:31,940 So dot slash Hello, enter Hello, World. 664 00:31:31,940 --> 00:31:34,340 Now, if you're curious, this is a good instinct 665 00:31:34,340 --> 00:31:36,758 to start to acquire what happens if I get rid of this. 666 00:31:36,758 --> 00:31:39,050 Well, I'm probably not going to break things too badly. 667 00:31:39,050 --> 00:31:39,980 So let's try. 668 00:31:39,980 --> 00:31:42,440 Let me go ahead now and do Make Hello. 669 00:31:42,440 --> 00:31:43,530 Still compile. 670 00:31:43,530 --> 00:31:45,180 So it's not a really bad mistake. 671 00:31:45,180 --> 00:31:47,900 So let me go ahead and run dot slash Hello. 672 00:31:47,900 --> 00:31:50,120 What's the difference here? 673 00:31:50,120 --> 00:31:52,760 Yeah, what do you see that's different? 674 00:31:52,760 --> 00:31:56,290 Yeah, the dollar sign, my so-called prompt, stayed on the same line. 675 00:31:56,290 --> 00:31:56,830 Why? 676 00:31:56,830 --> 00:31:59,980 Well, we can presumably infer now that the backslash 677 00:31:59,980 --> 00:32:03,730 n is some fancy notation for saying create a new line, 678 00:32:03,730 --> 00:32:06,080 move the cursor, so to speak, to the next line. 679 00:32:06,080 --> 00:32:09,970 Notice that the cursor will move to the next line in my terminal window. 680 00:32:09,970 --> 00:32:11,980 If I keep hitting it, it just automatically, 681 00:32:11,980 --> 00:32:13,570 by nature of hitting enter, does it. 682 00:32:13,570 --> 00:32:16,510 But it'd be kind of stupid if when you run a program in this world, 683 00:32:16,510 --> 00:32:19,510 simple as it is, if the next command is now 684 00:32:19,510 --> 00:32:22,970 weirdly spaced in the middle of the terminal with the dollar sign, 685 00:32:22,970 --> 00:32:24,310 it just looks sloppy. 686 00:32:24,310 --> 00:32:26,260 It's really just an aesthetic argument. 687 00:32:26,260 --> 00:32:32,140 And notice that it's not acceptable or correct to do this, to hit enter there. 688 00:32:32,140 --> 00:32:34,640 Let me go ahead and save that, though, and see what happens. 689 00:32:34,640 --> 00:32:38,200 Let me go ahead now and run Make Hello enter. 690 00:32:38,200 --> 00:32:40,360 Oh my god, like four errors. 691 00:32:40,360 --> 00:32:44,590 This is like, what, 10 lines of errors for a one line program. 692 00:32:44,590 --> 00:32:47,590 And this is where, again, you'll start to develop the instincts for just 693 00:32:47,590 --> 00:32:48,580 reading this stuff. 694 00:32:48,580 --> 00:32:51,730 These kinds of tools, like the compiler tool we're using, 695 00:32:51,730 --> 00:32:55,060 were not designed necessarily with user friendliness in mind. 696 00:32:55,060 --> 00:32:57,280 That's changed over the decades, but certainly early 697 00:32:57,280 --> 00:33:01,010 on it's really just meant to be correct and precise with its errors. 698 00:33:01,010 --> 00:33:02,350 So what did I do here? 699 00:33:02,350 --> 00:33:05,140 Missing terminating close quote character, 700 00:33:05,140 --> 00:33:08,260 long story short, when you have a string in C, 701 00:33:08,260 --> 00:33:11,710 your double quotes just have to be on the same line just because. 702 00:33:11,710 --> 00:33:13,248 Now, there's the slight white lie. 703 00:33:13,248 --> 00:33:14,290 There's ways around this. 704 00:33:14,290 --> 00:33:20,830 But the best way around it is to use this so-called escape sequence. 705 00:33:20,830 --> 00:33:23,590 To escape something means generally to put a backslash, and then 706 00:33:23,590 --> 00:33:25,910 a special symbol like n for new line. 707 00:33:25,910 --> 00:33:30,710 And this is just the agreed upon way that humans, decades ago, decided, 708 00:33:30,710 --> 00:33:33,850 OK you don't just hit your enter key. 709 00:33:33,850 --> 00:33:38,140 You instead put backslash n and that tells the computer 710 00:33:38,140 --> 00:33:40,670 to move the cursor to the new line. 711 00:33:40,670 --> 00:33:42,177 So again, kind of cryptic. 712 00:33:42,177 --> 00:33:43,510 But once you know it, that's it. 713 00:33:43,510 --> 00:33:46,670 It's just another word in our vocabulary. 714 00:33:46,670 --> 00:33:49,750 So now let me transition to making my program a little more interactive. 715 00:33:49,750 --> 00:33:51,340 Instead of just saying Hello, world, let me 716 00:33:51,340 --> 00:33:53,215 change it like last week to say Hello, David, 717 00:33:53,215 --> 00:33:55,520 or whoever is interacting with the program. 718 00:33:55,520 --> 00:33:59,050 So I'm going to do string answer gets, get string, 719 00:33:59,050 --> 00:34:02,455 quote unquote, what's your name. 720 00:34:02,455 --> 00:34:04,330 I'm not going to bother with a new line here. 721 00:34:04,330 --> 00:34:04,930 I could. 722 00:34:04,930 --> 00:34:06,380 This is now just a judgment call. 723 00:34:06,380 --> 00:34:09,088 I deliberately want the human to type their name on the same line 724 00:34:09,088 --> 00:34:10,150 just because. 725 00:34:10,150 --> 00:34:11,990 And how do I now print this? 726 00:34:11,990 --> 00:34:14,170 Well last week recall we used say. 727 00:34:14,170 --> 00:34:16,450 And then we use the other block called join. 728 00:34:16,450 --> 00:34:18,880 So the idea here is the same. 729 00:34:18,880 --> 00:34:21,380 But the syntax this week is going to be a little different. 730 00:34:21,380 --> 00:34:25,070 It's going to be printf, which prints something on the screen. 731 00:34:25,070 --> 00:34:29,290 I'm going to go ahead and say Hello comma. 732 00:34:29,290 --> 00:34:34,270 And let me just go with this initially with the backslash n, semicolon. 733 00:34:34,270 --> 00:34:37,900 Let me go ahead and recompile my code. 734 00:34:37,900 --> 00:34:41,492 Whoops, damn doesn't work still. 735 00:34:41,492 --> 00:34:42,700 And look at all these errors. 736 00:34:42,700 --> 00:34:45,640 There's more errors than code I wrote. 737 00:34:45,640 --> 00:34:47,630 But what's going on here? 738 00:34:47,630 --> 00:34:50,080 Well, this is actually something, a mistake you'll see, 739 00:34:50,080 --> 00:34:52,330 somewhat often, at least initially. 740 00:34:52,330 --> 00:34:54,470 And let's start to glean what's going on here. 741 00:34:54,470 --> 00:34:58,120 So here, if I look at the very first line of output after the dollar sign-- 742 00:34:58,120 --> 00:35:01,120 so even though it jumped down the screen pretty fast, 743 00:35:01,120 --> 00:35:04,030 I wrote Make Hello at the dollar sign, prompt. 744 00:35:04,030 --> 00:35:05,560 And then here's the first error. 745 00:35:05,560 --> 00:35:08,320 On Hello dot C, line 5-- 746 00:35:08,320 --> 00:35:12,220 technically character 5, but generally line is enough to get you going-- 747 00:35:12,220 --> 00:35:16,150 there's an error, use of undeclared identifier string. 748 00:35:16,150 --> 00:35:18,320 Did you mean standard in? 749 00:35:18,320 --> 00:35:19,300 So, I didn't. 750 00:35:19,300 --> 00:35:21,560 And this is not an obvious solution at first. 751 00:35:21,560 --> 00:35:25,360 But you'll start to recognize these patterns in error messages. 752 00:35:25,360 --> 00:35:30,940 It turns out that if I want to use string, I actually have to do this. 753 00:35:30,940 --> 00:35:35,079 I have to include another library up here, another line of code, 754 00:35:35,079 --> 00:35:37,660 rather, called CS50 dot H. We'll come back 755 00:35:37,660 --> 00:35:39,500 to what this means in just a moment. 756 00:35:39,500 --> 00:35:45,760 But if I now retroactively say, all right, what does standard I/O 757 00:35:45,760 --> 00:35:46,869 do for us up here. 758 00:35:46,869 --> 00:35:50,920 Before I added that new line, what is standard I/O doing? 759 00:35:50,920 --> 00:35:52,869 Well, if you think back to Scratch, there 760 00:35:52,869 --> 00:35:58,960 were a few examples with the camera and with the speech to-- the text to voice. 761 00:35:58,960 --> 00:36:01,480 Remember I had to poke around in the extensions button. 762 00:36:01,480 --> 00:36:03,309 And then I had to load it into Scratch. 763 00:36:03,309 --> 00:36:05,440 It didn't come natively with Scratch. 764 00:36:05,440 --> 00:36:07,119 C is quite like that. 765 00:36:07,119 --> 00:36:09,369 Some functions come with the language. 766 00:36:09,369 --> 00:36:13,360 But for the most part, if you want to use a function, an action or a verb 767 00:36:13,360 --> 00:36:17,770 like printf, you have to load that extension, so to speak, 768 00:36:17,770 --> 00:36:20,560 that more traditionally is called a library. 769 00:36:20,560 --> 00:36:26,320 So there is a standard I/O library, STD I/O, standard I/O, 770 00:36:26,320 --> 00:36:28,550 where I/O just means input and output. 771 00:36:28,550 --> 00:36:30,640 Which means, just like in MIT's World, there 772 00:36:30,640 --> 00:36:34,360 was an extension for doing text to voice or for using your camera. 773 00:36:34,360 --> 00:36:36,670 In C, there's an extension, a.k.a. 774 00:36:36,670 --> 00:36:40,430 a library, for doing standard input and output. 775 00:36:40,430 --> 00:36:44,650 And so if you want to use any functions related to standard input and output, 776 00:36:44,650 --> 00:36:49,330 like text from a keyboard, you have to include standard I/O dot 777 00:36:49,330 --> 00:36:53,560 H. And then can you use printf. 778 00:36:53,560 --> 00:36:55,090 Same goes here. 779 00:36:55,090 --> 00:36:59,890 Get string, it turns out, is a function that CS50 wrote some time ago. 780 00:36:59,890 --> 00:37:02,170 And as we'll see over the coming weeks, it just 781 00:37:02,170 --> 00:37:05,980 makes it way easier to get input from a user. 782 00:37:05,980 --> 00:37:09,310 C is very good with printf at printing output on the screen. 783 00:37:09,310 --> 00:37:12,610 C makes it really annoying and hard, as we'll see in a few weeks, 784 00:37:12,610 --> 00:37:14,390 to just get input from the user. 785 00:37:14,390 --> 00:37:17,020 So we wrote a function called get_string, 786 00:37:17,020 --> 00:37:20,440 but the only way you can use that is to load the extension, 787 00:37:20,440 --> 00:37:23,470 a.k.a. load the library called CS50. 788 00:37:23,470 --> 00:37:27,040 And we'll come back in time, like, why is it .h, why is it a hash symbol. 789 00:37:27,040 --> 00:37:30,490 But for now, standard I/O is a library that 790 00:37:30,490 --> 00:37:33,740 gives you access to printf and input- and output-related stuff. 791 00:37:33,740 --> 00:37:36,310 CS50 is a second library that provides you 792 00:37:36,310 --> 00:37:39,640 with access to functions that don't come with C 793 00:37:39,640 --> 00:37:42,700 that include something like get_string. 794 00:37:42,700 --> 00:37:46,390 So with that said, we've now kind of teased apart 795 00:37:46,390 --> 00:37:49,370 at a high level what lines 2 and now 1 are doing. 796 00:37:49,370 --> 00:37:51,580 Let me go ahead and rerun make hello. 797 00:37:51,580 --> 00:37:52,810 Now it worked. 798 00:37:52,810 --> 00:37:56,298 So all those crazy error messages were resolved by just one fix, 799 00:37:56,298 --> 00:37:58,840 so key takeaway is not to get overwhelmed by the sheer number 800 00:37:58,840 --> 00:37:59,780 of errors. 801 00:37:59,780 --> 00:38:04,720 Let me now do ./hello and if I type in my name, what am I going to say? 802 00:38:07,720 --> 00:38:10,670 What do you think? 803 00:38:10,670 --> 00:38:15,290 Yeah, hello answer, because the computer is going to take me literally. 804 00:38:15,290 --> 00:38:17,870 And it turns out that if you just write "hello, 805 00:38:17,870 --> 00:38:20,810 answer" all in the double quotes, you're really just passing 806 00:38:20,810 --> 00:38:23,750 English as the input to the printf function, 807 00:38:23,750 --> 00:38:25,670 you're not actually passing in the variable. 808 00:38:25,670 --> 00:38:28,520 And unfortunately in C, it's not quite as 809 00:38:28,520 --> 00:38:32,060 easy to plug things in to other things that you've typed. 810 00:38:32,060 --> 00:38:34,310 Remember in Scratch, there was not just the Save block 811 00:38:34,310 --> 00:38:36,860 but the Join block, which was kind of pretty, 812 00:38:36,860 --> 00:38:38,660 you can combine apples and oranges-- 813 00:38:38,660 --> 00:38:40,100 or was it apple and banana? 814 00:38:40,100 --> 00:38:43,840 Then we changed it to hello and then the answer that the human typed in. 815 00:38:43,840 --> 00:38:45,965 In C, the syntax is going to be a little different. 816 00:38:45,965 --> 00:38:51,050 You tell the computer inside of your double quotes that you want to have 817 00:38:51,050 --> 00:38:56,390 a placeholder there, a so-called format code. %s means, hey, computer, 818 00:38:56,390 --> 00:38:59,240 put a string here eventually. 819 00:38:59,240 --> 00:39:03,860 Then outside of your quotes, you just add a comma and then you type 820 00:39:03,860 --> 00:39:09,620 in whatever variable you want the computer to plug in at that %s location 821 00:39:09,620 --> 00:39:10,430 for you. 822 00:39:10,430 --> 00:39:14,870 So %s is a format code which serves as a placeholder. 823 00:39:14,870 --> 00:39:17,630 And now the printf function was designed by humans years 824 00:39:17,630 --> 00:39:19,850 ago to figure out how to do the apple and banana 825 00:39:19,850 --> 00:39:22,172 thing of joining two words together. 826 00:39:22,172 --> 00:39:24,380 It's not nearly as user-friendly as it is in Scratch, 827 00:39:24,380 --> 00:39:26,900 but it's a very common paradigm. 828 00:39:26,900 --> 00:39:30,080 So let me try and rerun this now. make hello. 829 00:39:30,080 --> 00:39:31,640 No errors, that's good. 830 00:39:31,640 --> 00:39:32,720 ./hello. 831 00:39:32,720 --> 00:39:33,830 What's my name, David? 832 00:39:33,830 --> 00:39:36,980 If I type Enter now, now it's hello. 833 00:39:36,980 --> 00:39:37,550 David. 834 00:39:37,550 --> 00:39:40,010 And the printf, here's the F in printf. 835 00:39:40,010 --> 00:39:44,780 It formats its input for you by using these placeholders for things like 836 00:39:44,780 --> 00:39:49,400 strings, represented again by %s. 837 00:39:49,400 --> 00:39:53,850 So a quick question then, if I focus here on line 7 for just a moment 838 00:39:53,850 --> 00:40:00,680 and even zoom in here, how many inputs is printf taking as a function? 839 00:40:00,680 --> 00:40:04,700 A moment ago, I'll admit that it was taking one input, "hello, world," 840 00:40:04,700 --> 00:40:05,990 quote unquote. 841 00:40:05,990 --> 00:40:11,180 How many inputs might you infer printf is taking now? 842 00:40:11,180 --> 00:40:11,720 2. 843 00:40:11,720 --> 00:40:16,400 And it's implied by this comma here, which is separating the first one, 844 00:40:16,400 --> 00:40:20,510 quote, unquote, "hello, %s" from the second one, answer. 845 00:40:20,510 --> 00:40:23,930 And then just as a quick safety check here, why is it not 3? 846 00:40:23,930 --> 00:40:26,520 Because there's obviously two commas here. 847 00:40:26,520 --> 00:40:29,480 Why is it not actually 3 arguments or inputs? 848 00:40:29,480 --> 00:40:33,200 AUDIENCE: [INAUDIBLE] 849 00:40:33,200 --> 00:40:34,200 DAVID J. MALAN: Exactly. 850 00:40:34,200 --> 00:40:37,410 The comma to the left is actually part of my English grammar, 851 00:40:37,410 --> 00:40:38,893 that's all, so same syntax. 852 00:40:38,893 --> 00:40:41,310 And, again, here's where programming can just be confusing 853 00:40:41,310 --> 00:40:44,100 early on because we're using the same special punctuation to mean 854 00:40:44,100 --> 00:40:46,930 different things, it just depends on the context. 855 00:40:46,930 --> 00:40:49,170 And so now is actually a good time to point out 856 00:40:49,170 --> 00:40:52,950 all of the somewhat pretty colors that have been popping up on the screen 857 00:40:52,950 --> 00:40:53,490 here-- 858 00:40:53,490 --> 00:40:57,240 even though I wasn't going to a format menu, I wasn't boldfacing things, 859 00:40:57,240 --> 00:41:00,190 I certainly wasn't changing things to red or blue or whatnot-- 860 00:41:00,190 --> 00:41:05,100 that's because a text editor like VS Code syntax highlights for you. 861 00:41:05,100 --> 00:41:08,250 This is a feature of so many different programming environments nowadays, 862 00:41:08,250 --> 00:41:09,840 VS Code does it as well. 863 00:41:09,840 --> 00:41:14,220 If your text editor understands the language that you're programming in-- 864 00:41:14,220 --> 00:41:15,520 C, in this case-- 865 00:41:15,520 --> 00:41:19,900 it highlights in different colors the different types of ideas in your code. 866 00:41:19,900 --> 00:41:23,070 So, for instance, string and answer here are in black, 867 00:41:23,070 --> 00:41:27,027 but get_string a function is in this sort of nasty brown-yellow 868 00:41:27,027 --> 00:41:29,610 here right now, but that's just how it displays on the screen. 869 00:41:29,610 --> 00:41:32,310 The string, though, here in red is kind of jumping out at me, 870 00:41:32,310 --> 00:41:33,990 and that's marginally useful. 871 00:41:33,990 --> 00:41:35,313 The %s is in blue. 872 00:41:35,313 --> 00:41:37,480 That's kind of nice, because it's jumping out at me. 873 00:41:37,480 --> 00:41:40,800 And so it's just using different colors to make different things on the screen 874 00:41:40,800 --> 00:41:44,220 pop so you can focus on how these ideas interrelate 875 00:41:44,220 --> 00:41:46,320 and, honestly, when you might make a mistake. 876 00:41:46,320 --> 00:41:49,230 For instance, let me accidentally leave off this quote here. 877 00:41:49,230 --> 00:41:54,210 And now all of a sudden, notice if I delete the quote, 878 00:41:54,210 --> 00:41:56,910 the colors start to get a little awry. 879 00:41:56,910 --> 00:42:00,840 But if I go back there and put it back, now everything's back in place. 880 00:42:00,840 --> 00:42:02,670 What's another feature of this text editor? 881 00:42:02,670 --> 00:42:06,450 Notice when my cursor is next to this parenthesis, which 882 00:42:06,450 --> 00:42:09,310 demarcates the end of the inputs to the function, 883 00:42:09,310 --> 00:42:12,810 notice that highlighted in green here is the opening parenthesis. 884 00:42:12,810 --> 00:42:13,350 Why? 885 00:42:13,350 --> 00:42:15,437 It's just a visually useful thing, especially when 886 00:42:15,437 --> 00:42:17,520 you start writing more and more code, just to make 887 00:42:17,520 --> 00:42:19,440 sure your parentheses are lining up. 888 00:42:19,440 --> 00:42:22,590 And that's true for these curly braces over here on the left and the right. 889 00:42:22,590 --> 00:42:24,210 We'll come back to those in a moment. 890 00:42:24,210 --> 00:42:28,020 If I put my cursor there, you can see that these things correspond 891 00:42:28,020 --> 00:42:28,900 to one another. 892 00:42:28,900 --> 00:42:31,800 So it's nothing in your code fundamentally, it's just the editor 893 00:42:31,800 --> 00:42:34,110 trying to help you, the human, program. 894 00:42:34,110 --> 00:42:36,450 And you can even see it, though it's a little subtle-- 895 00:42:36,450 --> 00:42:39,330 see these four dots here and these four dots here? 896 00:42:39,330 --> 00:42:40,890 That's my indentation. 897 00:42:40,890 --> 00:42:44,730 I configured VS Code to indent by four spaces, which 898 00:42:44,730 --> 00:42:45,960 is a very common convention. 899 00:42:45,960 --> 00:42:49,290 Any time I hit the Tab key, this too can help you make sure-- 900 00:42:49,290 --> 00:42:52,140 once we have more interesting and longer programs-- 901 00:42:52,140 --> 00:42:55,320 that everything lines up nice and neatly. 902 00:42:55,320 --> 00:42:56,580 Phew. 903 00:42:56,580 --> 00:42:58,590 All right, any questions then on printf or more? 904 00:42:58,590 --> 00:42:59,852 Yeah. 905 00:42:59,852 --> 00:43:02,322 AUDIENCE: [? Would ?] the printf [INAUDIBLE]?? 906 00:43:02,322 --> 00:43:04,030 DAVID J. MALAN: Short answer, yes. printf 907 00:43:04,030 --> 00:43:07,330 can handle more than one type of variable or value. 908 00:43:07,330 --> 00:43:08,440 %s is one. 909 00:43:08,440 --> 00:43:11,870 We're going to see %i is another for plugging in an integer. 910 00:43:11,870 --> 00:43:15,460 You can have multiple i's, multiple s's, and even other symbols too. 911 00:43:15,460 --> 00:43:17,350 We'll come back to that in just a little bit. 912 00:43:17,350 --> 00:43:21,040 printf can take many more arguments than just these two. 913 00:43:21,040 --> 00:43:23,350 This is just meant to be representative. 914 00:43:23,350 --> 00:43:25,390 Yeah, over here. 915 00:43:25,390 --> 00:43:27,400 Can you declare variables within the printf? 916 00:43:27,400 --> 00:43:28,810 No. 917 00:43:28,810 --> 00:43:30,850 The only variable I'm using right now is answer, 918 00:43:30,850 --> 00:43:34,450 and it's got to be done outside the context of printf in this case. 919 00:43:34,450 --> 00:43:37,510 Good question, we'll see more of that before long. 920 00:43:37,510 --> 00:43:39,152 Yeah, in back. 921 00:43:39,152 --> 00:43:40,943 AUDIENCE: [INAUDIBLE] 922 00:43:40,943 --> 00:43:43,110 DAVID J. MALAN: How do we download the CS50 library? 923 00:43:43,110 --> 00:43:46,290 So we will show you in problems set 1 exactly how to do that. 924 00:43:46,290 --> 00:43:49,620 It's automatically done for you in our version of VS Code in the cloud. 925 00:43:49,620 --> 00:43:53,010 If, ultimately, you program on your own Mac or PC, either initially or later 926 00:43:53,010 --> 00:43:54,900 on, it's also installable online. 927 00:43:54,900 --> 00:43:58,273 But if you want to ask that via online or afterward, 928 00:43:58,273 --> 00:43:59,940 we can point you in the right direction. 929 00:43:59,940 --> 00:44:01,590 But PSet 1 will itself. 930 00:44:01,590 --> 00:44:02,431 Yeah. 931 00:44:02,431 --> 00:44:04,540 AUDIENCE: [INAUDIBLE] 932 00:44:04,540 --> 00:44:08,170 DAVID J. MALAN: String is the type of the variable or, more properly, 933 00:44:08,170 --> 00:44:10,300 the data type of the variable. 934 00:44:10,300 --> 00:44:13,480 int is another keyword I alluded to earlier, I haven't used it yet. 935 00:44:13,480 --> 00:44:17,390 int, for integer, is going to be another type, or data type, of variable. 936 00:44:17,390 --> 00:44:18,640 AUDIENCE: OK. [? Thank you. ?] 937 00:44:18,640 --> 00:44:19,515 DAVID J. MALAN: Yeah. 938 00:44:19,515 --> 00:44:20,890 AUDIENCE: [INAUDIBLE] 939 00:44:20,890 --> 00:44:22,307 DAVID J. MALAN: Oh, good question. 940 00:44:22,307 --> 00:44:26,170 Could I go ahead and just plug in this function, 941 00:44:26,170 --> 00:44:30,460 kind of like we did in Scratch, getting rid of the variable altogether 942 00:44:30,460 --> 00:44:33,670 and just do this, which recall, is reminiscent of what 943 00:44:33,670 --> 00:44:37,120 I did in Scratch by plopping block on top of block on block? 944 00:44:37,120 --> 00:44:39,470 Am I answering that right? 945 00:44:39,470 --> 00:44:41,430 Can I put string in front of get_string? 946 00:44:41,430 --> 00:44:41,930 No. 947 00:44:41,930 --> 00:44:44,900 You only put the word string in front of a variable 948 00:44:44,900 --> 00:44:46,400 that you want to make string. 949 00:44:46,400 --> 00:44:49,070 And even though I'm apparently answering the wrong question, 950 00:44:49,070 --> 00:44:52,910 let me go ahead and zoom out, save this, do make hello again. 951 00:44:52,910 --> 00:44:54,650 Seems to compile OK. 952 00:44:54,650 --> 00:44:57,380 If I run ./hello, type in David, voila. 953 00:44:57,380 --> 00:44:58,650 That, too, works. 954 00:44:58,650 --> 00:45:01,590 And so, actually, let's go down this rabbit hole for just a moment. 955 00:45:01,590 --> 00:45:03,410 Clearly, it's still correct-- 956 00:45:03,410 --> 00:45:05,810 at least, based on my limited testing. 957 00:45:05,810 --> 00:45:09,200 Is this better designed or worse designed? 958 00:45:09,200 --> 00:45:11,330 Let's open that question like we did last week. 959 00:45:11,330 --> 00:45:12,680 Yeah? 960 00:45:12,680 --> 00:45:15,020 Yeah, I kind of agree with that. 961 00:45:15,020 --> 00:45:17,210 Reasonable people could disagree, but I do 962 00:45:17,210 --> 00:45:21,170 agree that this seems harder to read because I start reading here, 963 00:45:21,170 --> 00:45:23,637 but wait a minute. get_string is going to get used first, 964 00:45:23,637 --> 00:45:25,470 and then it's going to give me back a value. 965 00:45:25,470 --> 00:45:28,700 So, yeah, it just feels like it was nicer to read top to bottom, 966 00:45:28,700 --> 00:45:29,360 I would say. 967 00:45:29,360 --> 00:45:29,990 Your thoughts? 968 00:45:29,990 --> 00:45:30,940 AUDIENCE: [INAUDIBLE] 969 00:45:30,940 --> 00:45:31,815 DAVID J. MALAN: Yeah. 970 00:45:31,815 --> 00:45:35,810 And so this is useful if I only want to print out the person's name once. 971 00:45:35,810 --> 00:45:38,973 If I want to use it later in a longer program, I'm out of luck, 972 00:45:38,973 --> 00:45:40,640 and so I haven't saved it in a variable. 973 00:45:40,640 --> 00:45:44,240 So I think, long story short, we could debate this all day long. 974 00:45:44,240 --> 00:45:47,350 But in this case, eh, if you can make a reasonable argument one 975 00:45:47,350 --> 00:45:50,440 way or the other, that's a pretty solid ground to stand on. 976 00:45:50,440 --> 00:45:52,300 But, invariably, reasonable people are going 977 00:45:52,300 --> 00:45:56,840 to disagree, whether first-time programmers or many years after that. 978 00:45:56,840 --> 00:46:00,940 So let's frame this one last example in the context of the same process 979 00:46:00,940 --> 00:46:02,580 of taking inputs and outputs. 980 00:46:02,580 --> 00:46:04,330 The functions we've been talking about all 981 00:46:04,330 --> 00:46:08,920 take inputs, otherwise now known as arguments, or parameters, pretty much 982 00:46:08,920 --> 00:46:09,730 synonymous. 983 00:46:09,730 --> 00:46:12,940 That's just the fancy word for an input to a function. 984 00:46:12,940 --> 00:46:16,245 And some functions have either side effects, like we saw-- 985 00:46:16,245 --> 00:46:18,370 printing something, saying something on the screen, 986 00:46:18,370 --> 00:46:20,110 sort of visually or audibly-- 987 00:46:20,110 --> 00:46:25,120 or they return a value, which is a reusable value, like name or answer, 988 00:46:25,120 --> 00:46:26,450 in this case. 989 00:46:26,450 --> 00:46:30,460 If we look then at what we did last time in the world of Scratch last week, 990 00:46:30,460 --> 00:46:33,010 the input was what's your name, the function was ask, 991 00:46:33,010 --> 00:46:35,980 and the return value was answer. 992 00:46:35,980 --> 00:46:40,720 And now let's take a look at this block, which is honestly a more user-friendly 993 00:46:40,720 --> 00:46:42,466 version of what we just did with the %s. 994 00:46:42,466 --> 00:46:46,120 Last week we said save, then join, then hello and answer. 995 00:46:46,120 --> 00:46:49,780 But the interesting takeaway there was not how to say hello anything. 996 00:46:49,780 --> 00:46:54,220 It was the fact that in Scratch 2, the output of one function, 997 00:46:54,220 --> 00:46:59,350 like the green join, could become the input to another function, 998 00:46:59,350 --> 00:47:00,700 the purple say. 999 00:47:00,700 --> 00:47:03,670 The syntax in C is admittedly pretty different, 1000 00:47:03,670 --> 00:47:05,680 but the idea is essentially the same. 1001 00:47:05,680 --> 00:47:09,580 Here, though, we have hello, a placeholder, 1002 00:47:09,580 --> 00:47:13,090 but we have to, in this world of C, tell printf 1003 00:47:13,090 --> 00:47:16,310 what we want to plug in for that placeholder. 1004 00:47:16,310 --> 00:47:17,180 It's just different. 1005 00:47:17,180 --> 00:47:18,347 But that's the way to do it. 1006 00:47:18,347 --> 00:47:20,890 When we get to Python and other languages later in the term, 1007 00:47:20,890 --> 00:47:22,720 there's actually easier ways to do this. 1008 00:47:22,720 --> 00:47:25,510 But this is a very common paradigm, particularly when 1009 00:47:25,510 --> 00:47:28,690 you want to format your data in some way. 1010 00:47:28,690 --> 00:47:31,250 All right, let's then take a step back to where we began, 1011 00:47:31,250 --> 00:47:34,900 which was with that whole program, which had the include 1012 00:47:34,900 --> 00:47:38,830 and it had int main(void) and all of this other cryptic syntax. 1013 00:47:38,830 --> 00:47:42,550 This Scratch piece last week was kind of like the go-to 1014 00:47:42,550 --> 00:47:45,068 whenever you want to have a main part of your program. 1015 00:47:45,068 --> 00:47:47,110 It's not the only way to start a Scratch program. 1016 00:47:47,110 --> 00:47:50,380 You could listen for clicks or other things, not just the green flag. 1017 00:47:50,380 --> 00:47:55,030 But this was probably the most popular place to start a program in Scratch. 1018 00:47:55,030 --> 00:47:58,678 In C, the closest analog is to literally write this out. 1019 00:47:58,678 --> 00:48:01,720 So just like last week, if you were in the habit of dragging and dropping 1020 00:48:01,720 --> 00:48:04,300 when green flag clicked, as a C programmer, 1021 00:48:04,300 --> 00:48:06,970 the first thing you would do is after creating an empty file, 1022 00:48:06,970 --> 00:48:09,820 like I did with hello.c, you'd probably type int 1023 00:48:09,820 --> 00:48:13,240 main(void) open curly brace, closed curly brace, 1024 00:48:13,240 --> 00:48:17,300 and then you can put all of your code inside of those curly braces. 1025 00:48:17,300 --> 00:48:20,410 So just like Scratch had this sort of magnetic nature 1026 00:48:20,410 --> 00:48:24,730 to it where the puzzle pieces would snap together, C, as a text-based language, 1027 00:48:24,730 --> 00:48:29,440 tends to use these curly braces, one of them opened, the other one closed. 1028 00:48:29,440 --> 00:48:32,680 And anything inside of those braces, so to speak, 1029 00:48:32,680 --> 00:48:35,770 is part of this puzzle piece, a.k.a. 1030 00:48:35,770 --> 00:48:37,090 main. 1031 00:48:37,090 --> 00:48:38,650 So what was atop them? 1032 00:48:38,650 --> 00:48:42,040 We went down this rabbit hole moment ago with these things called header files, 1033 00:48:42,040 --> 00:48:43,873 even though I didn't call them by this name. 1034 00:48:43,873 --> 00:48:48,055 But, indeed, when we have a whole program in Scratch, super easy. 1035 00:48:48,055 --> 00:48:50,680 Just have the one green flag clicked and then say hello, world. 1036 00:48:50,680 --> 00:48:51,880 There's no special syntax. 1037 00:48:51,880 --> 00:48:54,550 After all, it's meant to be very user-friendly and graphical. 1038 00:48:54,550 --> 00:49:00,730 In C, though, you technically can't just put int main(void) printf hello, world. 1039 00:49:00,730 --> 00:49:01,900 You also need this. 1040 00:49:01,900 --> 00:49:07,540 Because, again, you need to tell the compiler to load the library-- 1041 00:49:07,540 --> 00:49:13,240 code that someone else wrote-- so that the compiler knows what printf even is. 1042 00:49:13,240 --> 00:49:16,180 You have to load the CS50 library whenever 1043 00:49:16,180 --> 00:49:19,480 you want to use get_string or other functions, like get_int, 1044 00:49:19,480 --> 00:49:20,830 as we'll soon see. 1045 00:49:20,830 --> 00:49:23,890 Otherwise, the compiler won't know what get_string is. 1046 00:49:23,890 --> 00:49:26,210 You just have to do it this way. 1047 00:49:26,210 --> 00:49:28,540 The specific file name I'm mentioning here, 1048 00:49:28,540 --> 00:49:35,510 stdio.h, cs50.h, is what C programmers called a call a header file. 1049 00:49:35,510 --> 00:49:38,030 We'll see eventually what's inside of those files. 1050 00:49:38,030 --> 00:49:42,260 But long story short, it's like a menu of all of the available functions. 1051 00:49:42,260 --> 00:49:45,760 So in cs50.h, there's a menu mentioning get_string, get_int, 1052 00:49:45,760 --> 00:49:47,350 and a bunch of other stuff. 1053 00:49:47,350 --> 00:49:52,990 And in stdio.h, there's a menu of functions, among which are printf. 1054 00:49:52,990 --> 00:49:55,840 And that menu is what prepares the compiler 1055 00:49:55,840 --> 00:50:00,145 to know how to implement those same functions. 1056 00:50:00,145 --> 00:50:01,510 All right, let me pause here. 1057 00:50:01,510 --> 00:50:02,571 Question. 1058 00:50:02,571 --> 00:50:07,077 AUDIENCE: [INAUDIBLE] 1059 00:50:07,077 --> 00:50:08,160 DAVID J. MALAN: Not quite. 1060 00:50:08,160 --> 00:50:11,760 A library provides all of the functionality we're talking about. 1061 00:50:11,760 --> 00:50:16,920 A header file is the very specific mechanism via which you include it. 1062 00:50:16,920 --> 00:50:18,970 And we'll discuss this more next week. 1063 00:50:18,970 --> 00:50:21,360 For now, they're essentially the same, but we'll discuss 1064 00:50:21,360 --> 00:50:24,000 nuances between the two next week. 1065 00:50:24,000 --> 00:50:27,660 Yeah, the library would be standard I/O. The library would CS50. 1066 00:50:27,660 --> 00:50:32,920 The corresponding header file is stdio.h, cs50.h. 1067 00:50:32,920 --> 00:50:33,420 Indeed. 1068 00:50:33,420 --> 00:50:34,140 Other questions. 1069 00:50:34,140 --> 00:50:34,876 Yeah. 1070 00:50:34,876 --> 00:50:37,060 AUDIENCE: [INAUDIBLE] 1071 00:50:37,060 --> 00:50:38,090 DAVID J. MALAN: Indeed. 1072 00:50:38,090 --> 00:50:39,280 That, too, is on the menu. 1073 00:50:39,280 --> 00:50:40,280 We'll come back to that. 1074 00:50:40,280 --> 00:50:41,680 But the word string-- 1075 00:50:41,680 --> 00:50:45,430 incredibly common in the world of programming, it's not a CS50 idea-- 1076 00:50:45,430 --> 00:50:50,500 but in C, there's technically no such data type as string by default. 1077 00:50:50,500 --> 00:50:53,415 We have sort of conjured it up to simplify the first few weeks. 1078 00:50:53,415 --> 00:50:56,290 That's a training wheel that we'll very deliberately, in a few weeks, 1079 00:50:56,290 --> 00:51:00,610 take away, and we'll see why we've been using get_string and string. 1080 00:51:00,610 --> 00:51:05,360 Because C otherwise makes things quite more challenging early on, 1081 00:51:05,360 --> 00:51:07,390 which then gets besides the point for us. 1082 00:51:07,390 --> 00:51:08,656 Yeah. 1083 00:51:08,656 --> 00:51:10,937 AUDIENCE: [INAUDIBLE] 1084 00:51:10,937 --> 00:51:11,770 DAVID J. MALAN: Yes. 1085 00:51:11,770 --> 00:51:14,680 Early on, you will have to use whatever is prescribed by the specification. 1086 00:51:14,680 --> 00:51:16,150 That will include CS50's functions. 1087 00:51:16,150 --> 00:51:19,390 Long story short, you referred, I think, a moment ago to another function 1088 00:51:19,390 --> 00:51:22,180 called scanf, we won't talk about for a few weeks. 1089 00:51:22,180 --> 00:51:27,910 Long story short, in C, it's pretty easy and possible to get input from a user. 1090 00:51:27,910 --> 00:51:31,510 The catch is that it's really easy to do it dangerously. 1091 00:51:31,510 --> 00:51:36,310 And C, because it's an older, lower-level language, so to speak, 1092 00:51:36,310 --> 00:51:40,630 that gives you pretty much ultimate control over your computer's hardware. 1093 00:51:40,630 --> 00:51:42,820 It's very easy to make mistakes. 1094 00:51:42,820 --> 00:51:46,300 And, indeed, that's too why we use the library, 1095 00:51:46,300 --> 00:51:49,740 so your code won't crash unintendedly. 1096 00:51:49,740 --> 00:51:52,820 All right, so with this in mind, we have this now mapping 1097 00:51:52,820 --> 00:51:54,570 between the Scratch version and the other. 1098 00:51:54,570 --> 00:51:57,737 Let me just give you a quick tour of some of the other placeholders and data 1099 00:51:57,737 --> 00:52:01,440 types that students will start seeing as we assemble more interesting programs. 1100 00:52:01,440 --> 00:52:04,710 In the world of Linux, here is a non-exhaustive list 1101 00:52:04,710 --> 00:52:08,010 of commands with which you'll get familiar over the next few weeks 1102 00:52:08,010 --> 00:52:09,240 by playing with problem sets. 1103 00:52:09,240 --> 00:52:13,983 We've only seen two of these so far, ls for list, rm for others. 1104 00:52:13,983 --> 00:52:15,900 But I mention them now just so that it doesn't 1105 00:52:15,900 --> 00:52:21,540 feel too foreign when you see them on screen or online in a problem set. 1106 00:52:21,540 --> 00:52:23,610 cp is going to stand for copy. 1107 00:52:23,610 --> 00:52:26,910 mkdir is going to stand for make directory. mv is 1108 00:52:26,910 --> 00:52:29,670 going to stand for move or rename. 1109 00:52:29,670 --> 00:52:35,670 rmdir is going to be remove directory, and cd is going to be for change / 1110 00:52:35,670 --> 00:52:38,160 and let me show you this last one here first, 1111 00:52:38,160 --> 00:52:40,710 only because it's something you'll use so commonly. 1112 00:52:40,710 --> 00:52:44,880 If I go back to my code here on the screen, I'm going to go ahead 1113 00:52:44,880 --> 00:52:49,290 and re-open the little GUI on the left-hand side, the so-called Explorer, 1114 00:52:49,290 --> 00:52:52,650 revealing that I've got two files, hello and hello.c 1115 00:52:52,650 --> 00:52:54,150 so nothing has changed since there. 1116 00:52:54,150 --> 00:52:57,000 Suppose now that it's a few weeks into class 1117 00:52:57,000 --> 00:52:58,860 and I want to start organizing the code I'm 1118 00:52:58,860 --> 00:53:01,710 writing so that I have a folder for this week or next week, 1119 00:53:01,710 --> 00:53:04,620 or maybe a folder for problem set 1, problem set 2. 1120 00:53:04,620 --> 00:53:06,330 I can do this in a few ways. 1121 00:53:06,330 --> 00:53:09,390 In the GUI, I can go up here and do what most of you 1122 00:53:09,390 --> 00:53:11,160 would do instinctively on a Mac or PC. 1123 00:53:11,160 --> 00:53:13,650 You look for like a folder icon, you click it, 1124 00:53:13,650 --> 00:53:17,160 and then you name a folder like PSet1, Enter. 1125 00:53:17,160 --> 00:53:19,890 Voila, you've got a folder called PSet1. 1126 00:53:19,890 --> 00:53:25,900 I can confirm as much with my command line interface by typing what command? 1127 00:53:25,900 --> 00:53:28,090 How can I list what's in my folder? 1128 00:53:28,090 --> 00:53:29,590 Yeah, so ls for list. 1129 00:53:29,590 --> 00:53:30,703 And now I see hello-- 1130 00:53:30,703 --> 00:53:32,620 and it's green with an asterisk because that's 1131 00:53:32,620 --> 00:53:34,780 my executable, my runnable program-- 1132 00:53:34,780 --> 00:53:37,900 hello.c, which is my source code, and now PSet1 with a slash 1133 00:53:37,900 --> 00:53:41,230 at the end, which just implies that it's indeed a folder. 1134 00:53:41,230 --> 00:53:43,520 All right, I didn't really want to do it that way. 1135 00:53:43,520 --> 00:53:45,070 I'd like to do it more advanced. 1136 00:53:45,070 --> 00:53:48,730 So let me go ahead and right-click on PSet1, delete permanently. 1137 00:53:48,730 --> 00:53:50,910 I get a scary irreversible error message. 1138 00:53:50,910 --> 00:53:52,660 But there's nothing in it, so that's fine. 1139 00:53:52,660 --> 00:53:54,760 Now I've deleted it using the GUI. 1140 00:53:54,760 --> 00:54:00,050 But now let me go ahead and start doing the same thing from the command line. 1141 00:54:00,050 --> 00:54:02,260 And if you're wondering how things keep disappearing, 1142 00:54:02,260 --> 00:54:06,490 if you hit Control-L in your terminal window or explicitly type clear, 1143 00:54:06,490 --> 00:54:09,670 it will delete everything you previously typed just to clean things up. 1144 00:54:09,670 --> 00:54:11,795 In practice, you don't need to be doing this often. 1145 00:54:11,795 --> 00:54:14,680 I'm doing it just to keep our focus on my latest commands. 1146 00:54:14,680 --> 00:54:18,162 If I do-- what was the command to make a new directory? 1147 00:54:18,162 --> 00:54:19,520 AUDIENCE: [INAUDIBLE] 1148 00:54:19,520 --> 00:54:21,740 DAVID J. MALAN: Yeah, so mkdir, make directory. 1149 00:54:21,740 --> 00:54:23,450 Let me create PSet1, Enter. 1150 00:54:23,450 --> 00:54:25,820 And notice at left, there's my PSet1. 1151 00:54:25,820 --> 00:54:28,410 If I want to get a little overzealous, plan for next week, 1152 00:54:28,410 --> 00:54:30,320 here's my PSet2 directory. 1153 00:54:30,320 --> 00:54:35,922 Suppose now I want to open those folders on a Mac or PC or in this GUI, 1154 00:54:35,922 --> 00:54:37,880 I could double-click on it like this, and you'd 1155 00:54:37,880 --> 00:54:39,607 see this little arrow is moving. 1156 00:54:39,607 --> 00:54:42,690 It's not doing anything because there's nothing in there, but that's fine. 1157 00:54:42,690 --> 00:54:46,250 But suppose again I want to get more comfortable with my command line. 1158 00:54:46,250 --> 00:54:50,330 Notice if I type ls now, I see all four same things. 1159 00:54:50,330 --> 00:54:57,020 Let me change directories with cd space PSet1 Enter. 1160 00:54:57,020 --> 00:54:59,660 And now notice two things will have happened. 1161 00:54:59,660 --> 00:55:05,270 One, my prompt has changed slightly to remind me where I am, 1162 00:55:05,270 --> 00:55:08,930 just to keep me sane so that I don't forget what folder I'm actually in. 1163 00:55:08,930 --> 00:55:12,810 So here is just a visual reminder of what folder I'm currently in. 1164 00:55:12,810 --> 00:55:18,110 If I type ls now, what should I see after hitting Enter? 1165 00:55:18,110 --> 00:55:20,790 Nothing, because I've only created empty folders so far. 1166 00:55:20,790 --> 00:55:22,250 And, indeed, I see nothing. 1167 00:55:22,250 --> 00:55:26,690 If I wanted to create a folder called Mario for a program that might be 1168 00:55:26,690 --> 00:55:29,090 called Mario this week, I can do that. 1169 00:55:29,090 --> 00:55:31,730 Now if I type ls, there is Mario. 1170 00:55:31,730 --> 00:55:34,070 Now if I do cd Mario, notice my prompt's going 1171 00:55:34,070 --> 00:55:35,720 to change to be a little more precise. 1172 00:55:35,720 --> 00:55:38,390 Now I'm in PSet1/Mario. 1173 00:55:38,390 --> 00:55:40,250 And notice what's happening at top left. 1174 00:55:40,250 --> 00:55:42,350 Nothing now, because these folders are collapsed. 1175 00:55:42,350 --> 00:55:45,590 But if I click the little triangle, there I see Mario. 1176 00:55:45,590 --> 00:55:48,110 Nothing's going on in there because there's no files yet. 1177 00:55:48,110 --> 00:55:52,010 But suppose now I want to create a file called mario.c. 1178 00:55:52,010 --> 00:55:55,970 I could go up here, I could click the little plus icon, and use the GUI. 1179 00:55:55,970 --> 00:55:58,790 Or I can just type code mario.c. 1180 00:55:58,790 --> 00:55:59,420 Voila. 1181 00:55:59,420 --> 00:56:01,282 That creates a new tab for me. 1182 00:56:01,282 --> 00:56:04,490 I'm not going to write any code in here yet, but I am going to save the file. 1183 00:56:04,490 --> 00:56:08,150 And now at top left, you'll see that mario.c appears. 1184 00:56:08,150 --> 00:56:10,692 So at some point, you can eventually just close the Explorer. 1185 00:56:10,692 --> 00:56:13,358 Because, again, it's not providing you with any new information. 1186 00:56:13,358 --> 00:56:15,170 It's maybe more user-friendly, but there's 1187 00:56:15,170 --> 00:56:19,160 nothing you can't do at the command line that you could do with the GUI. 1188 00:56:19,160 --> 00:56:21,080 All right, but now I'm kind of stuck. 1189 00:56:21,080 --> 00:56:23,420 How do I get out of this folder? 1190 00:56:23,420 --> 00:56:25,220 In my Mac or PC world, I'd probably click 1191 00:56:25,220 --> 00:56:28,520 the Back button or something like that or just close it and start all over. 1192 00:56:28,520 --> 00:56:33,380 In the terminal window, I can do cd dot dot. 1193 00:56:33,380 --> 00:56:37,850 Dot dot is a nickname, if you will, for the parent directory. 1194 00:56:37,850 --> 00:56:39,300 That is, the previous directory. 1195 00:56:39,300 --> 00:56:43,800 So if I hit Enter now, notice I'm going to close the Mario folder, 1196 00:56:43,800 --> 00:56:47,330 a.k.a. directory, and now I'm back in PSet1. 1197 00:56:47,330 --> 00:56:51,440 Or, if I want to be fancy, let me go back into Mario temporarily. 1198 00:56:51,440 --> 00:56:54,500 If I type ls, there's mario.c, just to orient us. 1199 00:56:54,500 --> 00:56:57,658 If I want to do multiple things at a time, I could do cd../.. 1200 00:57:00,470 --> 00:57:04,220 which goes to my parent to my grandparent all in one breath. 1201 00:57:04,220 --> 00:57:07,740 And voila, now I'm back in my default folder, if you will. 1202 00:57:07,740 --> 00:57:12,110 And one last little trick of the trade, if I'm in PSet1/Mario like I 1203 00:57:12,110 --> 00:57:15,380 was a moment ago, and you're just tired of all the navigation, 1204 00:57:15,380 --> 00:57:18,080 if you just type cd and hit Enter, it'll whisk you 1205 00:57:18,080 --> 00:57:20,270 away back to your default folder, and you don't have 1206 00:57:20,270 --> 00:57:22,520 to worry about getting there manually. 1207 00:57:22,520 --> 00:57:29,720 Recall a bit ago, though, that I was running hello as this, ./hello. 1208 00:57:29,720 --> 00:57:33,950 If dot refers to my parent, perhaps infer here syntactically, 1209 00:57:33,950 --> 00:57:37,920 what does a single dot mean instead? 1210 00:57:37,920 --> 00:57:40,680 It means this directory, your current directory. 1211 00:57:40,680 --> 00:57:42,100 Why is that necessary? 1212 00:57:42,100 --> 00:57:44,192 It just makes super explicit to the computer 1213 00:57:44,192 --> 00:57:46,650 that I want the program called hello that's installed here, 1214 00:57:46,650 --> 00:57:50,700 not in some random other folder on my hard drive, so to speak. 1215 00:57:50,700 --> 00:57:53,625 I want the one that's right here instead. 1216 00:57:53,625 --> 00:57:55,500 All right, so besides these commands, there's 1217 00:57:55,500 --> 00:57:57,652 going to be others that we encounter over time. 1218 00:57:57,652 --> 00:57:58,860 Those are kind of the basics. 1219 00:57:58,860 --> 00:58:02,910 That allows you to wean yourself off of a GUI, Graphical User Interface, 1220 00:58:02,910 --> 00:58:05,670 and start using more comfortably, with practice and time, 1221 00:58:05,670 --> 00:58:07,560 a command line interface instead. 1222 00:58:07,560 --> 00:58:10,830 Well, what about those other types, now back in the world of C? 1223 00:58:10,830 --> 00:58:15,150 Those commands were not C. Those are just command-specific to a command line 1224 00:58:15,150 --> 00:58:19,500 interface, like in Linux, which, again, we're using in the cloud. 1225 00:58:19,500 --> 00:58:21,510 It's an alternative to Mac OS and Windows. 1226 00:58:21,510 --> 00:58:26,010 Back in the world of C now, we've seen strings, which are words. 1227 00:58:26,010 --> 00:58:29,550 I mentioned int or integer, but there's others as well. 1228 00:58:29,550 --> 00:58:33,780 In the world of C, we've seen string, we will see int. 1229 00:58:33,780 --> 00:58:37,230 If you want a bigger integer, there's something literally called a long. 1230 00:58:37,230 --> 00:58:40,650 If you want a single character, there's something called a char. 1231 00:58:40,650 --> 00:58:44,880 If you want a Boolean value, true or false, there is a bool. 1232 00:58:44,880 --> 00:58:47,310 And if you want a floating-point value-- 1233 00:58:47,310 --> 00:58:50,980 a fancy way of saying a real number, something with a decimal point in it-- 1234 00:58:50,980 --> 00:58:54,400 that is what C and other languages call a float. 1235 00:58:54,400 --> 00:58:57,810 And if you want even more numbers after the decimal point that 1236 00:58:57,810 --> 00:59:01,410 is more precision, you can use something called a double. 1237 00:59:01,410 --> 00:59:05,220 That is to say, here is, again, an example in programming 1238 00:59:05,220 --> 00:59:08,880 where it's up to you now to provide the computer with hints, essentially, 1239 00:59:08,880 --> 00:59:12,840 that it will rely on to know what is this pattern of zeros and ones. 1240 00:59:12,840 --> 00:59:14,530 Is it a number, a letter? 1241 00:59:14,530 --> 00:59:17,820 Is it a sound, an image, a color, or the like? 1242 00:59:17,820 --> 00:59:22,170 These are the types of data types that provide exactly those hints. 1243 00:59:22,170 --> 00:59:27,000 What are the functions that come in the menu that is the CS50 library? 1244 00:59:27,000 --> 00:59:30,450 We talked about standard I/O, and that's just one function so far, printf. 1245 00:59:30,450 --> 00:59:34,110 In the CS50 library, you can see that it follows a pattern. 1246 00:59:34,110 --> 00:59:36,780 The C50 library exists largely for the first few weeks 1247 00:59:36,780 --> 00:59:42,197 of the class to make our lives easier when you just want to get user input. 1248 00:59:42,197 --> 00:59:45,030 So if you want to get a string, like a word or words from the human, 1249 00:59:45,030 --> 00:59:45,900 you use get_string. 1250 00:59:45,900 --> 00:59:48,942 If you want to get an integer from the user, you're going to use get_int. 1251 00:59:48,942 --> 00:59:52,290 When you want to get any of those other data types, for the most part, 1252 00:59:52,290 --> 00:59:55,060 you use get_ something else. 1253 00:59:55,060 --> 00:59:57,420 And they're indeed all lowercase by convention. 1254 00:59:57,420 --> 00:59:58,530 What about printf? 1255 00:59:58,530 --> 01:00:01,830 If we have the ability now to store different types of data 1256 01:00:01,830 --> 01:00:04,950 and we have functions with which to get different types of data, 1257 01:00:04,950 --> 01:00:08,040 how might you go about printing different types of data? 1258 01:00:08,040 --> 01:00:15,000 Well, we've seen %s for string, %i for integer, %c for char, 1259 01:00:15,000 --> 01:00:21,330 %f for a float or a double, those real numbers I described earlier, 1260 01:00:21,330 --> 01:00:24,960 and then %li for a long integer. 1261 01:00:24,960 --> 01:00:27,480 So here's the first example of inconsistencies. 1262 01:00:27,480 --> 01:00:30,180 In an ideal world, that would just be %l and we'd move on. 1263 01:00:30,180 --> 01:00:34,140 It's %li instead in this case. 1264 01:00:34,140 --> 01:00:36,900 That's printf and some of its format codes. 1265 01:00:36,900 --> 01:00:38,460 What more might we do? 1266 01:00:38,460 --> 01:00:40,710 Well, in C, as we'll see-- 1267 01:00:40,710 --> 01:00:43,057 no pun intended-- there is a whole bunch of operators. 1268 01:00:43,057 --> 01:00:45,390 And, indeed, computers, one of the first things they did 1269 01:00:45,390 --> 01:00:49,140 was a lot of math and calculations, so there's a lot of operators like these. 1270 01:00:49,140 --> 01:00:52,360 Computers, and in turn, C, really good at addition, subtraction, 1271 01:00:52,360 --> 01:00:55,390 multiplication, division, and even the percent sign, 1272 01:00:55,390 --> 01:00:56,940 which is the remainder operator. 1273 01:00:56,940 --> 01:00:59,850 There's a special symbol in C and other languages 1274 01:00:59,850 --> 01:01:04,360 just for getting the remainder, when you divide one number by another. 1275 01:01:04,360 --> 01:01:10,110 There are other features in the world of C, like variables, as we've seen. 1276 01:01:10,110 --> 01:01:14,130 And there's also what is of playfully called syntactic sugar that 1277 01:01:14,130 --> 01:01:18,570 makes it easier over time to write fewer characters 1278 01:01:18,570 --> 01:01:20,290 but express your thoughts the same. 1279 01:01:20,290 --> 01:01:24,670 So just as a single example of this, as a single example, 1280 01:01:24,670 --> 01:01:28,530 consider this use of a variable last week. 1281 01:01:28,530 --> 01:01:32,940 Here in Scratch is how you might set a variable called counter to 0. 1282 01:01:32,940 --> 01:01:35,160 In C, it's going to be similar. 1283 01:01:35,160 --> 01:01:37,440 If you want the variable to be called counter, 1284 01:01:37,440 --> 01:01:40,740 you literally write the word counter, or whatever you want it to be called. 1285 01:01:40,740 --> 01:01:44,550 You then use the assignment operator, a.k.a. the equals sign, 1286 01:01:44,550 --> 01:01:48,130 and you assign it whatever its initial value should be here on the right. 1287 01:01:48,130 --> 01:01:52,200 So, again, the 0 is going to get copied from right to left into the variable 1288 01:01:52,200 --> 01:01:54,190 because of that single equal sign. 1289 01:01:54,190 --> 01:01:57,030 But this isn't sufficient in C. What else 1290 01:01:57,030 --> 01:02:00,090 is missing on the right-hand side, instinctively now? 1291 01:02:00,090 --> 01:02:02,685 Even if you've never programmed in this before. 1292 01:02:02,685 --> 01:02:03,310 Yeah, in front. 1293 01:02:03,310 --> 01:02:04,350 AUDIENCE: Semicolon. 1294 01:02:04,350 --> 01:02:05,975 DAVID J. MALAN: A semicolon at the end. 1295 01:02:05,975 --> 01:02:08,140 And one other thing, I think, is probably missing. 1296 01:02:08,140 --> 01:02:08,640 Again. 1297 01:02:08,640 --> 01:02:09,613 AUDIENCE: A data type. 1298 01:02:09,613 --> 01:02:10,780 DAVID J. MALAN: A data type. 1299 01:02:10,780 --> 01:02:13,870 So if we can keep going back and forth here, 1300 01:02:13,870 --> 01:02:17,520 what data type seems appropriate intuitively for counter? 1301 01:02:17,520 --> 01:02:18,630 int for integer. 1302 01:02:18,630 --> 01:02:21,060 So, indeed, we need to tell the computer when 1303 01:02:21,060 --> 01:02:23,730 creating a variable what type of data we want, 1304 01:02:23,730 --> 01:02:26,920 and we need to finish our thought with the semicolon. 1305 01:02:26,920 --> 01:02:29,340 So there might be a counterpart there. 1306 01:02:29,340 --> 01:02:34,470 What about in Scratch if we wanted to increment that counter variable? 1307 01:02:34,470 --> 01:02:36,870 We had this very user-friendly puzzle piece last time 1308 01:02:36,870 --> 01:02:40,940 that was change counter by 1, or add 1 to counter. 1309 01:02:40,940 --> 01:02:45,320 In C, here's where things get a little more interesting. 1310 01:02:45,320 --> 01:02:49,310 And pretty commonly done, you might do this. counter = counter + 1; 1311 01:02:49,310 --> 01:02:50,510 with a semicolon. 1312 01:02:50,510 --> 01:02:53,420 And this is where, again, it's important to note, the equal sign, 1313 01:02:53,420 --> 01:02:54,560 it's not equality. 1314 01:02:54,560 --> 01:02:56,540 Otherwise, this makes no sense. 1315 01:02:56,540 --> 01:02:59,450 counter cannot equal counter plus 1, right? 1316 01:02:59,450 --> 01:03:02,370 That just doesn't work if we're talking about integers here. 1317 01:03:02,370 --> 01:03:04,610 That's because the equal sign is assignment. 1318 01:03:04,610 --> 01:03:06,950 So it can certainly be the case that you calculate 1319 01:03:06,950 --> 01:03:11,120 counter plus 1, whatever that is, then you update the value of counter 1320 01:03:11,120 --> 01:03:14,070 from right to left to be that new value. 1321 01:03:14,070 --> 01:03:16,400 This, as we'll see, is a very common thing 1322 01:03:16,400 --> 01:03:20,300 to do in programming just to kind of count upward, for whatever reason. 1323 01:03:20,300 --> 01:03:22,130 You can write this more succinctly. 1324 01:03:22,130 --> 01:03:25,910 This code here is what we'll call syntactic sugar, sort 1325 01:03:25,910 --> 01:03:30,740 of a fancy way of saying the same thing with fewer words or fewer characters 1326 01:03:30,740 --> 01:03:31,520 on the screen. 1327 01:03:31,520 --> 01:03:35,420 This also adds 1, or whatever number you type over here, 1328 01:03:35,420 --> 01:03:37,280 to the variable on the left. 1329 01:03:37,280 --> 01:03:40,970 And there's one other form of syntactic sugar we're going to start seeing too, 1330 01:03:40,970 --> 01:03:42,800 and it's even more terse than this. 1331 01:03:42,800 --> 01:03:48,050 That too will increment counter by 1 by literally changing its value by 1. 1332 01:03:48,050 --> 01:03:50,900 Or if you change it to minus minus, subtracting 1 from it. 1333 01:03:50,900 --> 01:03:53,510 You can't do that with 2 and 3 and 4, but you 1334 01:03:53,510 --> 01:03:59,060 can do it by default with just plus plus or minus minus adding or subtracting 1. 1335 01:03:59,060 --> 01:03:59,961 Yeah. 1336 01:03:59,961 --> 01:04:03,810 AUDIENCE: [INAUDIBLE] 1337 01:04:03,810 --> 01:04:06,840 DAVID J. MALAN: Ah, so when you are changing a variable that already 1338 01:04:06,840 --> 01:04:11,400 has been created, as we did with the code that looked like this, 1339 01:04:11,400 --> 01:04:14,790 you no longer need to remind the computer what the data type is. 1340 01:04:14,790 --> 01:04:18,420 Thankfully, the computer is at least as smart as that. 1341 01:04:18,420 --> 01:04:23,190 It will remember the type of the data that you intended. 1342 01:04:23,190 --> 01:04:26,140 Other questions or comments on this? 1343 01:04:26,140 --> 01:04:27,390 All right, that's quite a lot. 1344 01:04:27,390 --> 01:04:29,770 Why don't we go ahead and here take a 10-minute break? 1345 01:04:29,770 --> 01:04:32,970 And we'll be back, we'll start writing some code. 1346 01:04:32,970 --> 01:04:36,180 All right, so we are back. 1347 01:04:36,180 --> 01:04:39,780 We've just looked at some of the basics of compiling, 1348 01:04:39,780 --> 01:04:41,535 even if it doesn't quite feel that basic. 1349 01:04:41,535 --> 01:04:43,410 But now, let's actually start focusing really 1350 01:04:43,410 --> 01:04:46,710 on writing more and more code, more and more interesting 1351 01:04:46,710 --> 01:04:49,900 code, kind of like we dove into Scratch last week. 1352 01:04:49,900 --> 01:04:51,810 So here I have these code open. 1353 01:04:51,810 --> 01:04:52,770 I've closed the GUI. 1354 01:04:52,770 --> 01:04:55,560 I'm going to focus more on my terminal window and my code editors. 1355 01:04:55,560 --> 01:04:58,643 Many different ways I can create new files, but I want to create something 1356 01:04:58,643 --> 01:04:59,710 called a calculator. 1357 01:04:59,710 --> 01:05:02,700 So, again, within this environment of VS Code, 1358 01:05:02,700 --> 01:05:06,780 I can literally write the code command which is VS Code specific, 1359 01:05:06,780 --> 01:05:09,570 and it just creates a new file for me automatically. 1360 01:05:09,570 --> 01:05:11,610 Or I could do that in the GUI. 1361 01:05:11,610 --> 01:05:14,582 I'm going to go ahead and create this file called calculator.c 1362 01:05:14,582 --> 01:05:17,040 and I'm going to go ahead and include some familiar things. 1363 01:05:17,040 --> 01:05:22,050 So I'm just going to go ahead and proactively include cs50.h, stdio.h. 1364 01:05:22,050 --> 01:05:25,110 I'm going to go ahead from memory and do the int void main-- 1365 01:05:25,110 --> 01:05:29,448 more on that next week, why it's int, why it's void, and so forth. 1366 01:05:29,448 --> 01:05:31,740 And now let me just implement a very simple calculator. 1367 01:05:31,740 --> 01:05:35,560 We saw some mathematical operators, like plus and the like. 1368 01:05:35,560 --> 01:05:37,060 So let's actually use this. 1369 01:05:37,060 --> 01:05:39,870 So let me go ahead and first give myself a variable 1370 01:05:39,870 --> 01:05:43,680 called x, sort of like grade school math or algebra. 1371 01:05:43,680 --> 01:05:46,770 Let me go ahead then and get an int, which is new, 1372 01:05:46,770 --> 01:05:48,450 but I mentioned this exists. 1373 01:05:48,450 --> 01:05:51,840 And then let me just ask the user for whatever their x value is. 1374 01:05:51,840 --> 01:05:55,183 The thing in the quotes is just the English, or the string 1375 01:05:55,183 --> 01:05:57,850 that I'm printing on the screen. so I could say anything I want. 1376 01:05:57,850 --> 01:06:01,130 I'm just going to say x colon to prompt the user accordingly. 1377 01:06:01,130 --> 01:06:03,630 Now I'm going to go ahead and get another variable called y. 1378 01:06:03,630 --> 01:06:04,830 I'm going to get int again. 1379 01:06:04,830 --> 01:06:07,470 And now, I'm going to prompt the user for y. 1380 01:06:07,470 --> 01:06:09,750 And I'm just very nitpickly using a space just 1381 01:06:09,750 --> 01:06:13,230 to move the cursor so it doesn't look too messy on the screen. 1382 01:06:13,230 --> 01:06:18,420 And then lastly, let me go ahead and just print out the sum of x and y. 1383 01:06:18,420 --> 01:06:22,920 In an ideal world, I would just say something like printf x + y. 1384 01:06:22,920 --> 01:06:27,840 But that is not valid in C. The first argument, recall, in printf 1385 01:06:27,840 --> 01:06:30,460 has to be a string in double quotes. 1386 01:06:30,460 --> 01:06:34,260 So if I want to print out the value of an integer, 1387 01:06:34,260 --> 01:06:38,520 I need to put something in quotes here, maybe followed by a newline, 1388 01:06:38,520 --> 01:06:40,420 if I want to move the cursor as well. 1389 01:06:40,420 --> 01:06:42,840 So, again, we only glimpsed it briefly, but what 1390 01:06:42,840 --> 01:06:46,680 do I replace these question marks with if I want a placeholder for an integer? 1391 01:06:46,680 --> 01:06:47,770 AUDIENCE: [INAUDIBLE] 1392 01:06:47,770 --> 01:06:49,180 DAVID J. MALAN: Yeah, so %i. 1393 01:06:49,180 --> 01:06:51,790 Just like %s was string, %i is integer. 1394 01:06:51,790 --> 01:06:53,560 So I change this %i. 1395 01:06:53,560 --> 01:06:57,550 And now if I want to add x and y, for instance, super-- simple calculator, 1396 01:06:57,550 --> 01:07:00,970 doesn't do much of anything other than addition of two integers-- 1397 01:07:00,970 --> 01:07:02,540 I think this works. 1398 01:07:02,540 --> 01:07:05,290 And, again, it looks definitely cryptic at first glance. 1399 01:07:05,290 --> 01:07:07,690 It would be if programming weren't this cryptic. 1400 01:07:07,690 --> 01:07:09,710 Other languages will clean this up for us. 1401 01:07:09,710 --> 01:07:13,390 But, again, if you focus on the basics, printf takes one input first-- 1402 01:07:13,390 --> 01:07:17,350 which is a format string with English or whatever language, 1403 01:07:17,350 --> 01:07:18,790 some placeholders, maybe-- 1404 01:07:18,790 --> 01:07:22,750 then it takes potentially more arguments after the comma, 1405 01:07:22,750 --> 01:07:25,120 like the value of x plus y. 1406 01:07:25,120 --> 01:07:28,000 All right, let me go ahead now and make calculator, 1407 01:07:28,000 --> 01:07:32,500 which, again, compiles my source code in C, 1408 01:07:32,500 --> 01:07:35,680 pictured above, and converts it into corresponding machine 1409 01:07:35,680 --> 01:07:37,630 code, or zeros and ones. 1410 01:07:37,630 --> 01:07:38,680 No error messages. 1411 01:07:38,680 --> 01:07:39,970 so that's already good. 1412 01:07:39,970 --> 01:07:41,920 Now I do ./calculator. 1413 01:07:41,920 --> 01:07:45,040 Let's do 1 plus 1 and Enter. 1414 01:07:45,040 --> 01:07:45,880 Voila. 1415 01:07:45,880 --> 01:07:48,730 Now I have the makings of a calculator. 1416 01:07:48,730 --> 01:07:51,620 Now let's start to tinker with this a little bit. 1417 01:07:51,620 --> 01:07:53,470 What if I instead had done this? 1418 01:07:53,470 --> 01:07:59,350 int z = x + y and then plug-in z here. 1419 01:07:59,350 --> 01:08:06,040 If I rerun make calculator, Enter, rerun ./calculator, type in 1 plus 1, 1420 01:08:06,040 --> 01:08:11,990 still equals 2, and let me claim that it will work for other values as well-- 1421 01:08:11,990 --> 01:08:14,020 which of these versions is better designed? 1422 01:08:14,020 --> 01:08:18,850 If both seem to be correct at very cursory glance, is this version better 1423 01:08:18,850 --> 01:08:21,910 or is the previous one without the z? 1424 01:08:21,910 --> 01:08:25,390 OK, so this one is arguably better because I've now got a reusable 1425 01:08:25,390 --> 01:08:27,700 variable called z that I cannot only print but, heck, 1426 01:08:27,700 --> 01:08:30,500 if my program is longer, I can use it elsewhere. 1427 01:08:30,500 --> 01:08:31,722 Counterthoughts? 1428 01:08:31,722 --> 01:08:32,597 AUDIENCE: [INAUDIBLE] 1429 01:08:32,597 --> 01:08:33,472 DAVID J. MALAN: Yeah. 1430 01:08:33,472 --> 01:08:35,880 Debatable, like before, because it depends on my intent. 1431 01:08:35,880 --> 01:08:37,755 And, honestly, I think a pretty good argument 1432 01:08:37,755 --> 01:08:39,200 can be made for the first version. 1433 01:08:39,200 --> 01:08:42,050 Because if I have no intention of-- as you note-- 1434 01:08:42,050 --> 01:08:45,000 using that variable again, you know what? 1435 01:08:45,000 --> 01:08:47,000 Maybe I might as well do this, just because it's 1436 01:08:47,000 --> 01:08:48,530 one less thing to think about. 1437 01:08:48,530 --> 01:08:49,640 It's one less distraction. 1438 01:08:49,640 --> 01:08:52,100 It's one less line of code to have to understand. 1439 01:08:52,100 --> 01:08:53,240 It's just a little tighter. 1440 01:08:53,240 --> 01:08:55,970 So here, again, it does depend on your intention. 1441 01:08:55,970 --> 01:08:58,220 But this field is pretty reasonable. 1442 01:08:58,220 --> 01:09:00,500 And I think, as someone noted earlier, when 1443 01:09:00,500 --> 01:09:04,610 I did the same thing with get_string, that, yeah, maybe kind of crossed 1444 01:09:04,610 --> 01:09:07,535 s line because get_string and the what's your name inside of it, 1445 01:09:07,535 --> 01:09:08,660 it was just so much longer. 1446 01:09:08,660 --> 01:09:12,050 But x + y, eh, it's not that hard to wrap our mind around what's 1447 01:09:12,050 --> 01:09:14,260 going on inside of the printf argument. 1448 01:09:14,260 --> 01:09:17,030 So, again, these are the kinds of thoughts that hopefully you'll 1449 01:09:17,030 --> 01:09:19,730 acquire the instinct for on not necessarily reaching 1450 01:09:19,730 --> 01:09:22,190 the same answer as someone else, but, again, the thought 1451 01:09:22,190 --> 01:09:24,420 process is what matters here. 1452 01:09:24,420 --> 01:09:27,380 All right, so how might I enhance this program a little bit? 1453 01:09:27,380 --> 01:09:29,670 Let's just talk about style for just a moment. 1454 01:09:29,670 --> 01:09:34,190 So x and y, at least in this case, are pretty reasonable variable names. 1455 01:09:34,190 --> 01:09:34,699 Why? 1456 01:09:34,699 --> 01:09:36,949 Because that's the go-to variable names in math 1457 01:09:36,949 --> 01:09:38,574 when you're adding two things together. 1458 01:09:38,574 --> 01:09:40,109 So x and y seem pretty reasonable. 1459 01:09:40,109 --> 01:09:44,359 I could have done something like, well, maybe my first variable 1460 01:09:44,359 --> 01:09:47,930 should be called first number and my next variable 1461 01:09:47,930 --> 01:09:49,752 should be called second number. 1462 01:09:49,752 --> 01:09:51,710 And then down here, I would have to change this 1463 01:09:51,710 --> 01:09:55,529 to first number plus second number. 1464 01:09:55,529 --> 01:09:58,250 Like, eh, this isn't really adding anything semantically 1465 01:09:58,250 --> 01:09:59,540 to help my comprehension. 1466 01:09:59,540 --> 01:10:02,430 But that would be one other direction we could have taken things. 1467 01:10:02,430 --> 01:10:05,960 So if you have very simple ideas that are conventionally 1468 01:10:05,960 --> 01:10:09,989 expressed with common variable names like x and y, totally fine here. 1469 01:10:09,989 --> 01:10:13,790 What if I want to annotate this program and remind myself what it is it does? 1470 01:10:13,790 --> 01:10:16,580 Well, I can add in C what are called comments. 1471 01:10:16,580 --> 01:10:21,230 With a slash slash, two forward slashes, you can write a note to yourself, 1472 01:10:21,230 --> 01:10:23,779 like prompt user for x. 1473 01:10:23,779 --> 01:10:26,600 And then down here, I could do something like prompt user 1474 01:10:26,600 --> 01:10:28,819 for y, just to remind myself what I'm doing there. 1475 01:10:28,819 --> 01:10:31,370 And down here, perform addition. 1476 01:10:31,370 --> 01:10:34,190 Now, in this case, I'm not sure these commands are really 1477 01:10:34,190 --> 01:10:35,300 adding all that much. 1478 01:10:35,300 --> 01:10:39,020 Because in the time it took me to write and eventually read these comments, 1479 01:10:39,020 --> 01:10:41,150 I could have just read the three lines of code. 1480 01:10:41,150 --> 01:10:44,090 But as our programs get more sophisticated 1481 01:10:44,090 --> 01:10:46,748 and you start to learn more syntax-- 1482 01:10:46,748 --> 01:10:49,290 that, honestly, you might forget the next day, the next week, 1483 01:10:49,290 --> 01:10:53,090 the next month-- might be useful to have these notes to self that 1484 01:10:53,090 --> 01:10:55,880 reminds you of what your code is doing or maybe even 1485 01:10:55,880 --> 01:10:57,620 how it is doing that thing. 1486 01:10:57,620 --> 01:11:00,529 With these early programs, not really necessary, 1487 01:11:00,529 --> 01:11:02,870 doesn't really add all that much to our comprehension, 1488 01:11:02,870 --> 01:11:05,359 but it is a mechanism you have in place that 1489 01:11:05,359 --> 01:11:09,260 can help you actually remind yourself or remind someone 1490 01:11:09,260 --> 01:11:11,478 else what it is that's going on. 1491 01:11:11,478 --> 01:11:14,270 Well, let me go ahead and rerun this again in this current version, 1492 01:11:14,270 --> 01:11:15,630 make calculator. 1493 01:11:15,630 --> 01:11:18,200 And here, too, you might think I'm typing crazy fast-- 1494 01:11:18,200 --> 01:11:18,890 not really. 1495 01:11:18,890 --> 01:11:19,970 I'm hitting Tab a lot. 1496 01:11:19,970 --> 01:11:23,400 So it turns out that Linux, the operating system 1497 01:11:23,400 --> 01:11:24,710 we're using here in the cloud-- 1498 01:11:24,710 --> 01:11:28,160 but, actually, Windows and Mac OS nowadays support this too-- 1499 01:11:28,160 --> 01:11:30,000 supports autocomplete. 1500 01:11:30,000 --> 01:11:33,500 So if you only have one program that starts with C-A-L, 1501 01:11:33,500 --> 01:11:36,410 you don't have to finish writing calculator, you can just hit Tab, 1502 01:11:36,410 --> 01:11:38,970 and the computer will finish your thought for you. 1503 01:11:38,970 --> 01:11:43,130 The other thing you can do is if you hit Up and keep going up, 1504 01:11:43,130 --> 01:11:45,623 you'll scroll through your entire history of commands. 1505 01:11:45,623 --> 01:11:47,540 So there too, I've been saving some keystrokes 1506 01:11:47,540 --> 01:11:50,373 by hitting Up quickly rather than retyping the same darn thing again 1507 01:11:50,373 --> 01:11:51,030 and again. 1508 01:11:51,030 --> 01:11:53,330 So, again, just another little convenience 1509 01:11:53,330 --> 01:11:57,110 to make programming and interacting with the command line interface even faster. 1510 01:11:57,110 --> 01:12:00,480 All right, let me go ahead and just make sure it's compiled in the current form. 1511 01:12:00,480 --> 01:12:02,330 The comments have no functional impact. 1512 01:12:02,330 --> 01:12:04,430 These green things are just notes to self. 1513 01:12:04,430 --> 01:12:06,620 Let me run calculator with maybe-- how about this? 1514 01:12:06,620 --> 01:12:10,640 Instead of 1 plus 1, how about 1 billion-- 1515 01:12:13,203 --> 01:12:14,370 whoops, let's do that again. 1516 01:12:14,370 --> 01:12:15,660 Wa, da, da. 1517 01:12:15,660 --> 01:12:21,375 1 million, 1 billion, and another 1 billion, and that answer is 2 billion. 1518 01:12:21,375 --> 01:12:22,750 All right, so that seems correct. 1519 01:12:22,750 --> 01:12:24,292 Let's run this program one more time. 1520 01:12:24,292 --> 01:12:30,480 How about 2 billion plus another 2 billion? 1521 01:12:30,480 --> 01:12:33,320 Did you know that? 1522 01:12:33,320 --> 01:12:36,320 So, apparently, it's not so correct. 1523 01:12:36,320 --> 01:12:40,790 And, clearly, running 1 plus 1 was not the most robust testing of my code 1524 01:12:40,790 --> 01:12:41,750 here. 1525 01:12:41,750 --> 01:12:44,435 What might have gone wrong? 1526 01:12:44,435 --> 01:12:45,560 What might have gone wrong? 1527 01:12:45,560 --> 01:12:46,445 Yeah. 1528 01:12:46,445 --> 01:12:48,665 AUDIENCE: [INAUDIBLE] 1529 01:12:48,665 --> 01:12:49,540 DAVID J. MALAN: Yeah. 1530 01:12:49,540 --> 01:12:51,710 The computer probably ran out of space with bits. 1531 01:12:51,710 --> 01:12:56,470 So it turns out with these data types-- we've been talking about string and int 1532 01:12:56,470 --> 01:13:00,850 and also float and char and those other things-- they all use a specific, 1533 01:13:00,850 --> 01:13:04,480 and, most importantly, finite number of bits to represent them. 1534 01:13:04,480 --> 01:13:06,160 It can vary by computer. 1535 01:13:06,160 --> 01:13:10,090 Newer computers use more bits, older computers tended to use fewer bits. 1536 01:13:10,090 --> 01:13:13,040 It's not necessarily standardized for all of these data types. 1537 01:13:13,040 --> 01:13:19,360 But in this case, in this environment, it is using 32 bits for an integer. 1538 01:13:19,360 --> 01:13:20,035 That's a lot. 1539 01:13:20,035 --> 01:13:22,180 So with 32 bits, you can count pretty high. 1540 01:13:22,180 --> 01:13:25,360 This is 64 light bulbs on the stage and could count even higher. 1541 01:13:25,360 --> 01:13:29,530 An int is only using half of these, or we have two integers here on the stage. 1542 01:13:29,530 --> 01:13:33,550 Now, if you think back to last week, we talked about 8 bits at one point. 1543 01:13:33,550 --> 01:13:38,570 And if you have 8 bits, 8 zeros and ones, you can count as high as 256-- 1544 01:13:38,570 --> 01:13:40,900 just a good number to generally remember as trivia. 1545 01:13:40,900 --> 01:13:44,740 8 bits gives you 256 permutations of zeros and ones. 1546 01:13:44,740 --> 01:13:48,640 32 gives you roughly how many, if anyone knows? 1547 01:13:48,640 --> 01:13:51,040 It's 2 to the 32 power. 1548 01:13:51,040 --> 01:13:53,710 So it's roughly 4 billion, 2 to the 32. 1549 01:13:53,710 --> 01:13:55,510 If you don't know that, it's fine. 1550 01:13:55,510 --> 01:13:58,510 Most programmers, though, eventually remember these kinds of heuristics. 1551 01:13:58,510 --> 01:14:00,010 So it's roughly 4 billion. 1552 01:14:00,010 --> 01:14:01,990 So that feels like enough. 1553 01:14:01,990 --> 01:14:05,080 2 billion plus 2 billion is exactly 4 billion. 1554 01:14:05,080 --> 01:14:09,160 And that actually should fit in a 32-bit integer. 1555 01:14:09,160 --> 01:14:11,950 The catch is that my Mac, your PC, and the like 1556 01:14:11,950 --> 01:14:13,990 also like to support negative numbers. 1557 01:14:13,990 --> 01:14:17,350 And if you want to support both positive and negative numbers, that technically 1558 01:14:17,350 --> 01:14:20,470 means with 32-bit integers, you can count as high 1559 01:14:20,470 --> 01:14:24,742 as roughly 2 billion positive or 2 billion negative 1560 01:14:24,742 --> 01:14:25,700 in the other direction. 1561 01:14:25,700 --> 01:14:29,260 That's still 4 billion, give or take, but it's only half as many 1562 01:14:29,260 --> 01:14:30,860 in one direction or the other. 1563 01:14:30,860 --> 01:14:35,410 So how could I go about implementing a correct calculator here? 1564 01:14:35,410 --> 01:14:38,800 What might the solution be? 1565 01:14:38,800 --> 01:14:41,380 Yeah, so not just li, which was for long integer. 1566 01:14:41,380 --> 01:14:45,830 I have to make one more change, which is to the data type itself. 1567 01:14:45,830 --> 01:14:50,290 So let me go back up here and change x from an int to a long, a.k.a. 1568 01:14:50,290 --> 01:14:51,430 long integer. 1569 01:14:51,430 --> 01:14:53,600 And then let me change y as well. 1570 01:14:53,600 --> 01:14:57,100 And then let me change the format code per the little cheat sheet we had up 1571 01:14:57,100 --> 01:14:59,170 a few minutes ago to li. 1572 01:14:59,170 --> 01:15:01,780 Let me recompile the calculator-- 1573 01:15:01,780 --> 01:15:02,770 seems to work OK. 1574 01:15:02,770 --> 01:15:03,830 Let's rerun it. 1575 01:15:03,830 --> 01:15:05,260 Now let's do 1 plus 1. 1576 01:15:05,260 --> 01:15:06,800 That's should obviously be the same. 1577 01:15:06,800 --> 01:15:11,900 Now let's do 2 billion and another 2 billion 1578 01:15:11,900 --> 01:15:13,530 and cross our fingers this time. 1579 01:15:13,530 --> 01:15:15,920 Now we're counting as high as 4 billion. 1580 01:15:15,920 --> 01:15:19,070 And we can go way higher than 4 billion, but we're only 1581 01:15:19,070 --> 01:15:20,960 kicking the can down the street a bit. 1582 01:15:20,960 --> 01:15:22,460 Even though we're now using-- 1583 01:15:22,460 --> 01:15:23,630 with a long-- 1584 01:15:23,630 --> 01:15:28,980 64 bits, which is as long as this stage now, that's still a finite value. 1585 01:15:28,980 --> 01:15:31,580 It might be a really big value, but it's still finite. 1586 01:15:31,580 --> 01:15:34,010 And we'll come back at the end of today to these kinds 1587 01:15:34,010 --> 01:15:35,240 of fundamental limitations. 1588 01:15:35,240 --> 01:15:39,510 Because arguably now, my calculator is correct for like millions, 1589 01:15:39,510 --> 01:15:42,480 billions of possible inputs but not all. 1590 01:15:42,480 --> 01:15:44,600 And that's problematic if you actually want 1591 01:15:44,600 --> 01:15:49,940 to use my calculator for any possible inputs, not just 1592 01:15:49,940 --> 01:15:54,500 ones that are roughly less than, say, 2 billion, as in this case. 1593 01:15:54,500 --> 01:15:56,492 All right, any questions then on that? 1594 01:15:56,492 --> 01:15:58,700 But it's really just a precursor for all the problems 1595 01:15:58,700 --> 01:16:01,705 that we're going to have to eventually deal with later on. 1596 01:16:01,705 --> 01:16:06,887 AUDIENCE: [INAUDIBLE] 1597 01:16:06,887 --> 01:16:08,220 DAVID J. MALAN: A good question. 1598 01:16:08,220 --> 01:16:08,460 Yes. 1599 01:16:08,460 --> 01:16:11,550 If we were still using z, we would also have to change it to a long. 1600 01:16:11,550 --> 01:16:14,670 Otherwise, we'd be ignoring 32 of the bits that 1601 01:16:14,670 --> 01:16:17,190 had been added together via the longs. 1602 01:16:17,190 --> 01:16:19,030 Good question. 1603 01:16:19,030 --> 01:16:23,550 All right, so how about we spice things up with maybe not just addition here, 1604 01:16:23,550 --> 01:16:26,910 how about something with some conditions? 1605 01:16:26,910 --> 01:16:28,830 Let's start to ask some actual questions. 1606 01:16:28,830 --> 01:16:35,290 So a moment ago, recall that we had just the declaration of variables. 1607 01:16:35,290 --> 01:16:37,290 Now let's look back at something in Scratch that 1608 01:16:37,290 --> 01:16:39,832 looked a little something like this, a bunch of puzzle pieces 1609 01:16:39,832 --> 01:16:41,910 asking questions by way of these conditionals 1610 01:16:41,910 --> 01:16:44,910 and then these Boolean expressions here in green, maybe saying something 1611 01:16:44,910 --> 01:16:46,440 like x is less than y. 1612 01:16:46,440 --> 01:16:49,500 In C, this actually maps pretty cleanly. 1613 01:16:49,500 --> 01:16:53,490 It's much cleaner from left to right than it was with printf and join. 1614 01:16:53,490 --> 01:16:56,190 Here, we have just code that looks like this. 1615 01:16:56,190 --> 01:17:00,450 If, a space, two parentheses and then x less than y, 1616 01:17:00,450 --> 01:17:03,423 and then we have something like printf there in the middle. 1617 01:17:03,423 --> 01:17:05,340 So here, it's actually kind of a nice mapping. 1618 01:17:05,340 --> 01:17:07,710 Notice that, just as the yellow puzzle piece in Scratch 1619 01:17:07,710 --> 01:17:09,843 is kind of hugging the purple puzzle piece, 1620 01:17:09,843 --> 01:17:12,510 that's effectively the role that these curly braces are playing. 1621 01:17:12,510 --> 01:17:15,900 They're sort of encapsulating all of the code on the inside. 1622 01:17:15,900 --> 01:17:19,050 The parentheses represent the Boolean expression 1623 01:17:19,050 --> 01:17:23,610 that needs to be asked and answered to decide whether or not to do this thing. 1624 01:17:23,610 --> 01:17:26,040 And here's an exception to what I alluded to earlier. 1625 01:17:26,040 --> 01:17:30,090 Usually, when you see a word and then a parenthesis, something, 1626 01:17:30,090 --> 01:17:33,330 and then closed parenthesis, I claimed that's usually a function. 1627 01:17:33,330 --> 01:17:35,520 And I'm still feeling pretty good about that claim. 1628 01:17:35,520 --> 01:17:36,960 But there are exceptions. 1629 01:17:36,960 --> 01:17:39,480 And the word if is not a function. 1630 01:17:39,480 --> 01:17:41,700 It's just a programming construct. 1631 01:17:41,700 --> 01:17:46,620 It's a feature of the C language that similarly uses parentheses, just 1632 01:17:46,620 --> 01:17:49,200 for different purposes for a Boolean expression. 1633 01:17:49,200 --> 01:17:50,610 How about something like this? 1634 01:17:50,610 --> 01:17:53,700 Last week, if you wanted to have a two-way fork in the road, 1635 01:17:53,700 --> 01:17:56,700 go this way or that way, you can have if and else. 1636 01:17:56,700 --> 01:17:59,290 In C, that would look a little something like this. 1637 01:17:59,290 --> 01:18:02,310 And if we add in the printf's, it now looks quite like the same, 1638 01:18:02,310 --> 01:18:06,240 but it adds, of course, the word else and then a couple of more curly braces. 1639 01:18:06,240 --> 01:18:12,390 As an aside, in C, It's not strictly necessary to have curly braces 1640 01:18:12,390 --> 01:18:16,980 if you have only one line of code indented underneath. 1641 01:18:16,980 --> 01:18:21,267 For best practice, though, do so anyway, because it makes super clear to you 1642 01:18:21,267 --> 01:18:23,100 and ultimately anyone else reading your code 1643 01:18:23,100 --> 01:18:26,610 that you intend for just that one or more line of code to execute. 1644 01:18:26,610 --> 01:18:28,260 How about this from last week? 1645 01:18:28,260 --> 01:18:29,880 Here was a three-way fork in the road. 1646 01:18:29,880 --> 01:18:36,272 If x is less than y, else if x is greater than y, else if x equals y. 1647 01:18:36,272 --> 01:18:38,730 Now, here's where you have some disparities between Scratch 1648 01:18:38,730 --> 01:18:43,950 and C. Scratch uses an equals sign for equality, to compare two values. 1649 01:18:43,950 --> 01:18:47,040 C uses a single equals sign for assignment from right 1650 01:18:47,040 --> 01:18:49,810 to left, minor difference between the two worlds. 1651 01:18:49,810 --> 01:18:54,030 In C, we could implement the same code like this, the addition being 1652 01:18:54,030 --> 01:18:55,530 just this additional else if. 1653 01:18:55,530 --> 01:18:59,895 And if we add in the printf's, it looks a little something now like this. 1654 01:18:59,895 --> 01:19:03,660 This is correct both in the Scratch world and in the C world. 1655 01:19:03,660 --> 01:19:07,620 But could someone make a claim that this is not, again, well-designed? 1656 01:19:07,620 --> 01:19:08,340 Exactly. 1657 01:19:08,340 --> 01:19:09,780 We don't need the last if. 1658 01:19:09,780 --> 01:19:12,930 We need the else, at least, but we don't need the last if. 1659 01:19:12,930 --> 01:19:15,420 Because, at least in the world of comparing integers, 1660 01:19:15,420 --> 01:19:18,420 it's either going to be less than, greater than, or equal to. 1661 01:19:18,420 --> 01:19:19,930 There is no other case. 1662 01:19:19,930 --> 01:19:22,530 So you can save a few seconds, if you will, 1663 01:19:22,530 --> 01:19:26,580 of your program running-- a blink of the eye-- by only asking two questions 1664 01:19:26,580 --> 01:19:29,070 and then inferring what the answer to the third 1665 01:19:29,070 --> 01:19:32,680 must be just by nature of your own human logic here. 1666 01:19:32,680 --> 01:19:34,020 Now, why is that a good thing? 1667 01:19:34,020 --> 01:19:37,770 If, for instance, x and y happen to equal each other-- 1668 01:19:37,770 --> 01:19:42,540 I type in 1 and 1 for both values, either in Scratch or in the C world-- 1669 01:19:42,540 --> 01:19:46,770 in the case of this version, you're sort of stupidly 1670 01:19:46,770 --> 01:19:50,220 asking three questions, all of which are going to get asked 1671 01:19:50,220 --> 01:19:53,520 even though the answer is no, no, yes. 1672 01:19:53,520 --> 01:19:57,000 That is false, false, true. 1673 01:19:57,000 --> 01:20:00,840 That seems to be unnecessary because if we instead optimize this code, 1674 01:20:00,840 --> 01:20:04,650 get rid of the unnecessary if and just do as you proposed logically-- 1675 01:20:04,650 --> 01:20:07,680 else print that x is equal to y-- 1676 01:20:07,680 --> 01:20:12,160 now if x indeed equals y because they're both 1 or some other value, 1677 01:20:12,160 --> 01:20:17,400 now you're only going to ask two questions, so 2/3 as many questions, 1678 01:20:17,400 --> 01:20:20,680 and then you're going to get your same correct result. 1679 01:20:20,680 --> 01:20:23,340 So, again, a minor detail, but, again, the kinds of things 1680 01:20:23,340 --> 01:20:25,048 you should be thinking about, not only as 1681 01:20:25,048 --> 01:20:27,630 you write your code to be correct but also write 1682 01:20:27,630 --> 01:20:30,030 it to be well-designed as well. 1683 01:20:30,030 --> 01:20:32,280 All right, so why don't we go ahead and translate this 1684 01:20:32,280 --> 01:20:35,850 into the context of an actual program here? 1685 01:20:35,850 --> 01:20:37,770 I'll create a blank window here. 1686 01:20:37,770 --> 01:20:41,640 And let's do something with points, like points on my own very first CS50 1687 01:20:41,640 --> 01:20:42,720 problem set. 1688 01:20:42,720 --> 01:20:45,840 Let me go ahead and run code of points.c. 1689 01:20:45,840 --> 01:20:47,910 That's just going to give me a new text file. 1690 01:20:47,910 --> 01:20:51,960 And then up here, I'm going to do my usual, include cs50.h. 1691 01:20:51,960 --> 01:20:54,360 include stdio.h. 1692 01:20:54,360 --> 01:20:55,980 int main void. 1693 01:20:55,980 --> 01:20:59,430 So a lot of boilerplate, so to speak, in these early programs. 1694 01:20:59,430 --> 01:21:00,720 And now, let's see. 1695 01:21:00,720 --> 01:21:04,020 Let's ask the user, how many points did they 1696 01:21:04,020 --> 01:21:06,260 lose on their most recent CS50 PSet? 1697 01:21:06,260 --> 01:21:10,240 So sort of evoke my photograph of my own very first PSet last week 1698 01:21:10,240 --> 01:21:11,890 where I lost a couple of points myself. 1699 01:21:11,890 --> 01:21:15,000 So int points = get_int. 1700 01:21:15,000 --> 01:21:18,940 Then I'll ask a question in English like, how many points did you lose, 1701 01:21:18,940 --> 01:21:20,500 question mark, space? 1702 01:21:20,500 --> 01:21:24,800 And then once I have this answer, let's now ask some questions of it. 1703 01:21:24,800 --> 01:21:28,060 So if points is less than 2-- 1704 01:21:28,060 --> 01:21:31,720 borrowing the syntax that we saw on the screen a moment ago-- 1705 01:21:31,720 --> 01:21:34,120 let's go ahead and print out something explanatory 1706 01:21:34,120 --> 01:21:40,390 like you lost fewer points than me, backslash n. 1707 01:21:40,390 --> 01:21:43,420 else if points greater than 2-- 1708 01:21:43,420 --> 01:21:45,190 which is, again how many I lost-- 1709 01:21:45,190 --> 01:21:50,860 I'm going to go ahead and print out you lost more points than me, backslash n. 1710 01:21:50,860 --> 01:21:55,047 else if-- wait a minute, else seems to be sufficient logically here. 1711 01:21:55,047 --> 01:21:57,130 I'm just going to go ahead and print out something 1712 01:21:57,130 --> 01:22:03,820 like you lost the same number of points as me, backslash n. 1713 01:22:03,820 --> 01:22:07,990 So, really, just a straightforward application of that simple idea 1714 01:22:07,990 --> 01:22:10,160 but to a concrete scenario here. 1715 01:22:10,160 --> 01:22:12,290 So let me go ahead and save this. 1716 01:22:12,290 --> 01:22:15,340 Let me go ahead and run make points, Enter. 1717 01:22:15,340 --> 01:22:17,230 No errors, that's good. 1718 01:22:17,230 --> 01:22:18,220 Run points. 1719 01:22:18,220 --> 01:22:20,530 And then, how many points did you lose? 1720 01:22:20,530 --> 01:22:22,302 How about, it's 1 point? 1721 01:22:22,302 --> 01:22:24,010 All right, you lost fewer points than me. 1722 01:22:24,010 --> 01:22:25,540 How about 0 points? 1723 01:22:25,540 --> 01:22:26,140 Even better. 1724 01:22:26,140 --> 01:22:27,370 How about 3 points? 1725 01:22:27,370 --> 01:22:28,280 And so forth. 1726 01:22:28,280 --> 01:22:32,050 So, again, we have the ability to express in C now pretty basic idea 1727 01:22:32,050 --> 01:22:36,040 from last week in reality, which is this notion of conditionals and asking 1728 01:22:36,040 --> 01:22:37,310 questions. 1729 01:22:37,310 --> 01:22:42,010 There's something subtle here, though, that's maybe not super well-designed 1730 01:22:42,010 --> 01:22:44,590 that someone might call a magic number. 1731 01:22:44,590 --> 01:22:47,780 This is programming speak for something I've done here. 1732 01:22:47,780 --> 01:22:53,080 There's a bit of redundancy unrelated to the if and the else and the else. 1733 01:22:53,080 --> 01:22:58,670 But is there something I typed twice just to ask, perhaps, for the obvious? 1734 01:22:58,670 --> 01:23:02,630 Exactly, I've hard-coded, so to speak, manually typed out the number 2-- 1735 01:23:02,630 --> 01:23:04,970 in two locations, in this case-- 1736 01:23:04,970 --> 01:23:06,900 that did not come from the user. 1737 01:23:06,900 --> 01:23:09,800 So, apparently, once I compile this, this is it. 1738 01:23:09,800 --> 01:23:12,870 You're always comparing yourself to me in like, 1996, 1739 01:23:12,870 --> 01:23:15,830 which for better or for worse, is all the program can do. 1740 01:23:15,830 --> 01:23:19,130 But this is an example too of a magic number in the sense 1741 01:23:19,130 --> 01:23:22,890 like, wait, where did that 2 come from, and why is it in two places? 1742 01:23:22,890 --> 01:23:26,450 It feels like we are setting the stage for just a higher probability 1743 01:23:26,450 --> 01:23:27,680 of screwing up down the road. 1744 01:23:27,680 --> 01:23:31,130 Because the longer this code gets, suppose I'm comparing against 2 points 1745 01:23:31,130 --> 01:23:31,880 elsewhere-- 1746 01:23:31,880 --> 01:23:34,100 2, 3, 4, 5 places-- 1747 01:23:34,100 --> 01:23:36,230 am I going to keep typing the number 2? 1748 01:23:36,230 --> 01:23:37,490 Like, yeah, that's fine. 1749 01:23:37,490 --> 01:23:38,180 It's correct. 1750 01:23:38,180 --> 01:23:39,110 It's going to work. 1751 01:23:39,110 --> 01:23:41,060 But, honestly, eventually, you're going to screw up, 1752 01:23:41,060 --> 01:23:43,610 and you're going to miss one of the 2's, you're going to change it to a 3, 1753 01:23:43,610 --> 01:23:46,110 because maybe I did worse the next year, or 1, I did better. 1754 01:23:46,110 --> 01:23:48,750 And you don't want these numbers to get out of sync. 1755 01:23:48,750 --> 01:23:52,250 So what would be a logical improvement to this design, 1756 01:23:52,250 --> 01:23:55,310 rather than hard-coding the same number sort of magically 1757 01:23:55,310 --> 01:23:58,210 in two or more places? 1758 01:23:58,210 --> 01:24:00,888 Yeah, why don't I make a variable that I can use in there? 1759 01:24:00,888 --> 01:24:02,680 So, for instance, I could create a variable 1760 01:24:02,680 --> 01:24:05,740 like this, another integer called mine. 1761 01:24:05,740 --> 01:24:07,570 And I'm just going to initialize it to 2. 1762 01:24:07,570 --> 01:24:10,570 And then I'm going to change mentions of 2 to this. 1763 01:24:10,570 --> 01:24:14,200 And mine is a pretty reasonable name for a variable insofar 1764 01:24:14,200 --> 01:24:18,460 as it refers to exactly whose points are in question. 1765 01:24:18,460 --> 01:24:20,980 There's a risk here, though, minor though it is. 1766 01:24:20,980 --> 01:24:23,560 I could accidentally change mine at some point. 1767 01:24:23,560 --> 01:24:27,650 Maybe I forget what mine represents, and I do some addition or subtraction. 1768 01:24:27,650 --> 01:24:30,220 So there's a way to tell the computer "don't trust me, 1769 01:24:30,220 --> 01:24:31,930 because I'm going to screw up eventually" 1770 01:24:31,930 --> 01:24:34,510 by making a variable constant too. 1771 01:24:34,510 --> 01:24:36,980 So a constant in a programming language-- 1772 01:24:36,980 --> 01:24:38,620 this did not exist in Scratch-- 1773 01:24:38,620 --> 01:24:41,740 is just an additional hint to the computer that essentially enables 1774 01:24:41,740 --> 01:24:43,330 you to program more defensively. 1775 01:24:43,330 --> 01:24:46,540 If you don't trust yourself necessarily to not 1776 01:24:46,540 --> 01:24:48,850 screw up later, or honestly, in practice, 1777 01:24:48,850 --> 01:24:52,360 if you know that number should never change, make it constant 1778 01:24:52,360 --> 01:24:54,020 and never think about it again. 1779 01:24:54,020 --> 01:24:59,290 This tells the compiler to make sure that even you later in your code cannot 1780 01:24:59,290 --> 01:25:00,940 change the number 2. 1781 01:25:00,940 --> 01:25:05,440 And another convention in C and other languages, when you have a constant, 1782 01:25:05,440 --> 01:25:07,892 it's often common to just capitalize the variable. 1783 01:25:07,892 --> 01:25:09,850 Kind of like you're yelling, but it really just 1784 01:25:09,850 --> 01:25:11,202 visually makes it stand out. 1785 01:25:11,202 --> 01:25:12,910 So it's kind of like a nice rule of thumb 1786 01:25:12,910 --> 01:25:15,790 that helps you realize, oh, that must be a constant. 1787 01:25:15,790 --> 01:25:18,490 Capitalization alone does not make it constant. 1788 01:25:18,490 --> 01:25:20,080 The word const does. 1789 01:25:20,080 --> 01:25:22,330 But the capitalization is just a visual reminder 1790 01:25:22,330 --> 01:25:26,240 that this is somewhere, somehow a constant. 1791 01:25:26,240 --> 01:25:28,690 So just a minor refinement, but, again, we're 1792 01:25:28,690 --> 01:25:32,650 sort of getting better at programming just by instilling 1793 01:25:32,650 --> 01:25:34,900 these kinds of heuristics. 1794 01:25:34,900 --> 01:25:39,220 Questions, then, on conditionals in C or these constants? 1795 01:25:39,220 --> 01:25:39,956 Yeah. 1796 01:25:39,956 --> 01:25:45,010 AUDIENCE: Why do you not use semicolons after line 9 and line 13? 1797 01:25:45,010 --> 01:25:49,960 DAVID J. MALAN: Yeah, why do you not use a semicolon in lines 9, 13? 1798 01:25:49,960 --> 01:25:50,560 Just because. 1799 01:25:50,560 --> 01:25:52,600 This is the way the language was designed. 1800 01:25:52,600 --> 01:25:54,700 And it's confusing early on. 1801 01:25:54,700 --> 01:25:58,420 Generally speaking, when you're using conditionals-- and eventually, 1802 01:25:58,420 --> 01:25:59,380 we'll see loops-- 1803 01:25:59,380 --> 01:26:01,060 there's no semicolons involved. 1804 01:26:01,060 --> 01:26:05,980 For now, assume that semicolons usually finish your thought after a function. 1805 01:26:05,980 --> 01:26:09,610 That's not 100% reliable of a heuristic, but it'll get you most of the way 1806 01:26:09,610 --> 01:26:11,140 there. 1807 01:26:11,140 --> 01:26:11,920 And just because. 1808 01:26:11,920 --> 01:26:14,920 Left hand was not talking to the right hand when some of these languages 1809 01:26:14,920 --> 01:26:16,390 were designed. 1810 01:26:16,390 --> 01:26:18,590 All right, so let's do something else. 1811 01:26:18,590 --> 01:26:19,880 How about this? 1812 01:26:19,880 --> 01:26:22,960 If I have the ability to ask something conditionally-- 1813 01:26:22,960 --> 01:26:24,940 is this thing true or is this other thing-- 1814 01:26:24,940 --> 01:26:27,850 could I write a very simple program that does something basic like, 1815 01:26:27,850 --> 01:26:31,180 tells me if a number the human types is even or odd? 1816 01:26:31,180 --> 01:26:33,590 Well, let me just get the framework for that in place. 1817 01:26:33,590 --> 01:26:36,190 Let me go ahead and write code of a parity-- 1818 01:26:36,190 --> 01:26:38,260 is a fancy way of saying even or odd. 1819 01:26:38,260 --> 01:26:44,710 And let me go ahead and include cs50.h, include stdio.h, int main void-- 1820 01:26:44,710 --> 01:26:46,720 again, more on those down the road. 1821 01:26:46,720 --> 01:26:50,980 But, for now, I'm going to go ahead and get a number n from the user 1822 01:26:50,980 --> 01:26:54,550 by calling get_int and asking them for whatever n is. 1823 01:26:54,550 --> 01:26:58,370 And then now I'm going to introduce some pseudocode. 1824 01:26:58,370 --> 01:27:00,130 So here's the first example of a program, 1825 01:27:00,130 --> 01:27:03,200 honestly, that I'm not really sure how to proceed. 1826 01:27:03,200 --> 01:27:05,890 So let me just resort to some pseudocode using comments. 1827 01:27:05,890 --> 01:27:08,420 Eventually, I'll get rid of this and write actual code. 1828 01:27:08,420 --> 01:27:13,875 But if n is even, then print-- 1829 01:27:13,875 --> 01:27:15,250 actually, let me just print that. 1830 01:27:15,250 --> 01:27:18,610 Let me just go ahead and say printf, quote unquote, "even", 1831 01:27:18,610 --> 01:27:20,830 because I know how to use printf. 1832 01:27:20,830 --> 01:27:24,430 else-- all right, I know how to printf odd, 1833 01:27:24,430 --> 01:27:27,100 so let me just say printf, quote unquote, "odd". 1834 01:27:27,100 --> 01:27:30,830 So here, I've sort of taken a bite out of the problem, if you will. 1835 01:27:30,830 --> 01:27:33,880 And let me go ahead and put in my little placeholders. 1836 01:27:33,880 --> 01:27:35,780 I want to do some kind of conditions. 1837 01:27:35,780 --> 01:27:40,600 So if, question marks now, let me go ahead and fill in the blanks here. 1838 01:27:40,600 --> 01:27:42,710 else I'll put this here. 1839 01:27:42,710 --> 01:27:44,740 So I think I'm OK now. 1840 01:27:44,740 --> 01:27:46,840 I'm getting closer to solving this. 1841 01:27:46,840 --> 01:27:50,570 But I still have this question mark here. 1842 01:27:50,570 --> 01:27:57,290 How, using syntax we've seen, might I determine if n is even or odd? 1843 01:27:57,290 --> 01:27:58,820 What do you think? 1844 01:27:58,820 --> 01:27:59,320 Nice. 1845 01:27:59,320 --> 01:28:03,250 There's this little operator I mentioned by name earlier, the remainder 1846 01:28:03,250 --> 01:28:05,300 operator, that will let you do exactly that. 1847 01:28:05,300 --> 01:28:07,862 If you divide any number by 2, that mathematical heuristic 1848 01:28:07,862 --> 01:28:10,570 is going to tell you if it's even or odd based on whether there's 1849 01:28:10,570 --> 01:28:12,490 a remainder of 0 or 1. 1850 01:28:12,490 --> 01:28:16,240 And that's nice because the alternative would seem to be doing something stupid 1851 01:28:16,240 --> 01:28:24,640 like if n == 0 or if n equals 2 or n equals 4-- 1852 01:28:24,640 --> 01:28:28,270 your code would be infinitely long if you had to ask all possible questions. 1853 01:28:28,270 --> 01:28:35,110 But if I do n divided by 2 and look at the remainder-- 1854 01:28:35,110 --> 01:28:38,480 it's a little cryptic, but this will indeed do the trick. 1855 01:28:38,480 --> 01:28:42,670 So the percent sign is the remainder operator. 1856 01:28:42,670 --> 01:28:47,990 It does numerator divided by denominator and returns not the result of that 1857 01:28:47,990 --> 01:28:50,180 but, rather, the remainder of that. 1858 01:28:50,180 --> 01:28:53,710 So if you divide anything by 2, it's going to be a 0 or 1 remainder. 1859 01:28:53,710 --> 01:28:57,880 And if, indeed, 2 divides into n evenly, giving you 0, 1860 01:28:57,880 --> 01:28:59,260 then you're going to print even. 1861 01:28:59,260 --> 01:29:01,270 Else, it's got to be odd. 1862 01:29:01,270 --> 01:29:05,950 But there is something odd-- pun intended-- in this highlighted line. 1863 01:29:05,950 --> 01:29:11,840 What is another new piece of syntax, apparently, besides the percent sign? 1864 01:29:11,840 --> 01:29:13,100 What's a little off there? 1865 01:29:13,100 --> 01:29:15,210 Yeah. 1866 01:29:15,210 --> 01:29:16,740 Yeah, so that's not a typo. 1867 01:29:16,740 --> 01:29:19,290 And I even caught myself verbally saying it a moment ago, 1868 01:29:19,290 --> 01:29:20,670 just because it's so ingrained. 1869 01:29:20,670 --> 01:29:24,180 What must this mean here? 1870 01:29:24,180 --> 01:29:24,905 Yeah. 1871 01:29:24,905 --> 01:29:25,780 AUDIENCE: [INAUDIBLE] 1872 01:29:25,780 --> 01:29:27,530 DAVID J. MALAN: Yeah, if something's equivalent to the other. 1873 01:29:27,530 --> 01:29:29,680 So now this is the equality operator. 1874 01:29:29,680 --> 01:29:31,480 It's not assignment from right to left. 1875 01:29:31,480 --> 01:29:33,760 And this one too is an example of, literally, 1876 01:29:33,760 --> 01:29:36,640 humans not really planning ahead, perhaps, left hand 1877 01:29:36,640 --> 01:29:38,740 not talking to right hand in that someone decided, 1878 01:29:38,740 --> 01:29:40,360 let's use the equals sign for assignment. 1879 01:29:40,360 --> 01:29:43,235 And then some number of minutes or days later, people are like, damn, 1880 01:29:43,235 --> 01:29:45,040 how do we now compare for equality? 1881 01:29:45,040 --> 01:29:46,253 Well, let's just use two. 1882 01:29:46,253 --> 01:29:49,420 And if you think this is a little weird, in some languages, like JavaScript, 1883 01:29:49,420 --> 01:29:52,250 there's a third version where you use three equal signs. 1884 01:29:52,250 --> 01:29:54,530 So, again, it's humans that design these languages. 1885 01:29:54,530 --> 01:29:57,727 So if you're ever frustrated by them, confused by them, eh, admittedly, 1886 01:29:57,727 --> 01:29:59,560 it might just not have been the best design. 1887 01:29:59,560 --> 01:30:02,390 But we just kind of have to live with it ever since. 1888 01:30:02,390 --> 01:30:04,090 So let me go ahead and zoom out here. 1889 01:30:04,090 --> 01:30:06,950 Let me go ahead and make parity here. 1890 01:30:06,950 --> 01:30:11,770 So make parity-- and, again, parity is just the name of my file, parity.c. 1891 01:30:11,770 --> 01:30:14,500 ./parity, type in a number like 2. 1892 01:30:14,500 --> 01:30:15,580 That's indeed even. 1893 01:30:15,580 --> 01:30:17,620 4, that's indeed even. 1894 01:30:17,620 --> 01:30:20,920 3, that's indeed odd, and so forth. 1895 01:30:20,920 --> 01:30:24,070 If we continue testing, presumably, we'll get the same kinds of answers. 1896 01:30:24,070 --> 01:30:25,370 How about something else? 1897 01:30:25,370 --> 01:30:28,900 Let me go ahead now and let me start copying and pasting some of this code 1898 01:30:28,900 --> 01:30:31,960 because, admittedly, it's getting a little tedious to keep typing out 1899 01:30:31,960 --> 01:30:33,880 all of that boilerplate at the top. 1900 01:30:33,880 --> 01:30:37,210 Let me create a program called agree.c that's 1901 01:30:37,210 --> 01:30:39,310 reminiscent of any of those forms you have 1902 01:30:39,310 --> 01:30:43,490 to agree to online with a checkbox or typing in yes or no or the like. 1903 01:30:43,490 --> 01:30:46,660 So let me throw away all the guts of this main program 1904 01:30:46,660 --> 01:30:48,980 and now ask something like this. 1905 01:30:48,980 --> 01:30:52,820 Let me go ahead and prompt user to agree to something. 1906 01:30:52,820 --> 01:30:58,000 I'm going to go ahead and say, how about get_string do you agree-- 1907 01:30:58,000 --> 01:31:03,310 whatever the question might be-- and I want the human to type y or n 1908 01:31:03,310 --> 01:31:05,150 for yes or no, respectively. 1909 01:31:05,150 --> 01:31:08,170 So if it's only a single character, actually, I 1910 01:31:08,170 --> 01:31:09,810 can actually get by with just get_char. 1911 01:31:09,810 --> 01:31:11,560 Not used it before, but it was on our menu 1912 01:31:11,560 --> 01:31:13,540 of functions from the CS50 library. 1913 01:31:13,540 --> 01:31:16,630 And if I want to get the user's response, 1914 01:31:16,630 --> 01:31:19,700 the return value should be a char also on the left. 1915 01:31:19,700 --> 01:31:22,480 So now we've seen strings, ints, and now chars, 1916 01:31:22,480 --> 01:31:24,370 if we only care about a single letter. 1917 01:31:24,370 --> 01:31:29,350 And now let's go ahead, check whether user agreed. 1918 01:31:29,350 --> 01:31:38,950 So how about if c == "y", then let me go ahead and, inside of my curly braces, 1919 01:31:38,950 --> 01:31:43,100 print out agreed or some such sentence like that. 1920 01:31:43,100 --> 01:31:45,760 else if they did not type c-- or you know what? 1921 01:31:45,760 --> 01:31:47,590 Let's be explicit here, just so they can't 1922 01:31:47,590 --> 01:31:50,260 type z or b or some random letter. 1923 01:31:50,260 --> 01:31:58,210 else if c=="n" n for no, then let me go ahead and print out not agreed, 1924 01:31:58,210 --> 01:31:59,178 or something like that. 1925 01:31:59,178 --> 01:32:01,720 And I'm just going to ignore the user if they don't cooperate 1926 01:32:01,720 --> 01:32:05,980 and they type z or b or something that's not y or n. 1927 01:32:05,980 --> 01:32:12,340 All right, let me go ahead now and compile this code, make agree, ./agree. 1928 01:32:12,340 --> 01:32:13,270 All right, do I agree? 1929 01:32:13,270 --> 01:32:13,770 Yes. 1930 01:32:13,770 --> 01:32:16,450 Let's go with the default. OK, so that seems to work. 1931 01:32:16,450 --> 01:32:18,400 No, I don't agree this time. 1932 01:32:18,400 --> 01:32:19,610 That seems to work. 1933 01:32:19,610 --> 01:32:25,120 How about my caps lock key is on or I'm just really yelling, capital Y? 1934 01:32:25,120 --> 01:32:26,110 It ignores me. 1935 01:32:26,110 --> 01:32:29,172 Capital N, it ignores me. 1936 01:32:29,172 --> 01:32:32,380 So, obviously, a bug, at least if I want to tolerate uppercase and lowercase, 1937 01:32:32,380 --> 01:32:34,220 which is kind of reasonable. 1938 01:32:34,220 --> 01:32:39,680 So what would be the possible solutions here, do you think? 1939 01:32:39,680 --> 01:32:42,820 How do I solve this and tolerate both capital and lowercase? 1940 01:32:42,820 --> 01:32:45,535 Maybe what's the simplest, most naive implementation? 1941 01:32:45,535 --> 01:32:47,690 AUDIENCE: [INAUDIBLE] 1942 01:32:47,690 --> 01:32:50,190 DAVID J. MALAN: Yeah, so why don't I just ask two questions? 1943 01:32:50,190 --> 01:32:54,750 Or you know what, even more simplistic based only on what we've seen before-- 1944 01:32:54,750 --> 01:32:58,110 if you will, let me just copy and paste some of this code. 1945 01:32:58,110 --> 01:33:02,980 Change this to an else-- whoops, not in caps-- else if "Y". 1946 01:33:02,980 --> 01:33:04,980 And then I bet I could do the same thing with n. 1947 01:33:04,980 --> 01:33:06,840 But here too, just like with Scratch, as soon 1948 01:33:06,840 --> 01:33:08,923 as you start to find yourself copying and pasting, 1949 01:33:08,923 --> 01:33:10,680 you're probably doing something wrong. 1950 01:33:10,680 --> 01:33:14,010 And what you said verbally, if I may, was actually better. 1951 01:33:14,010 --> 01:33:20,700 Because you're implying that I could just say something like OR c == "Y" 1952 01:33:20,700 --> 01:33:24,040 or, down here, c == "N". 1953 01:33:24,040 --> 01:33:30,910 The catch is, you can't use the word OR in C. It's actually two vertical bars. 1954 01:33:30,910 --> 01:33:34,380 So you can express one question or another. 1955 01:33:34,380 --> 01:33:37,500 You only need one of the answers to be yes or true, 1956 01:33:37,500 --> 01:33:39,420 and you use two vertical bars. 1957 01:33:39,420 --> 01:33:42,180 By contrast, just so you've seen it, if you 1958 01:33:42,180 --> 01:33:45,540 wanted to check if something is equal to something AND something else, 1959 01:33:45,540 --> 01:33:48,090 you could use two ampersands. 1960 01:33:48,090 --> 01:33:50,610 This logically would make no sense here, though. 1961 01:33:50,610 --> 01:33:53,850 Certainly, what the human typed can't both be lowercase and uppercase. 1962 01:33:53,850 --> 01:33:55,120 That just makes no sense. 1963 01:33:55,120 --> 01:33:56,910 So in this case, we do want OR. 1964 01:33:56,910 --> 01:33:58,675 But that allows me to tighten my code up. 1965 01:33:58,675 --> 01:34:01,050 I don't have to start copying and pasting whole branches. 1966 01:34:01,050 --> 01:34:04,760 I can now ask two questions at once. 1967 01:34:04,760 --> 01:34:08,070 Questions, then, on this variation? 1968 01:34:08,070 --> 01:34:09,068 Really good question. 1969 01:34:09,068 --> 01:34:10,860 Can you convert the input to all lowercase? 1970 01:34:10,860 --> 01:34:12,030 Absolutely, you could. 1971 01:34:12,030 --> 01:34:13,680 We don't have the capability yet. 1972 01:34:13,680 --> 01:34:16,140 It turns out that's going to require-- 1973 01:34:16,140 --> 01:34:18,365 to be easy, another library, though we could do it 1974 01:34:18,365 --> 01:34:21,240 ourselves knowing a little bit about ASCII or Unicode from last week. 1975 01:34:21,240 --> 01:34:25,313 But, yes, that would be an alternative, but more on that a different time. 1976 01:34:25,313 --> 01:34:25,980 Other questions? 1977 01:34:25,980 --> 01:34:28,340 AUDIENCE: [INAUDIBLE] 1978 01:34:28,340 --> 01:34:29,590 DAVID J. MALAN: Good question. 1979 01:34:29,590 --> 01:34:33,187 Unfortunately, you have to be explicit in C. You can't just say this, 1980 01:34:33,187 --> 01:34:35,520 even though that's kind of how you might think about it. 1981 01:34:35,520 --> 01:34:40,440 You have to ask a complete question using the equality sign twice 1982 01:34:40,440 --> 01:34:41,430 in this case. 1983 01:34:41,430 --> 01:34:43,140 Let me ask a question now too. 1984 01:34:43,140 --> 01:34:44,250 It's not a typo. 1985 01:34:44,250 --> 01:34:48,960 I deliberately used single quotes around all of my single letters here. 1986 01:34:48,960 --> 01:34:50,550 Why might that be? 1987 01:34:50,550 --> 01:34:54,720 Previously, we used double quotes for anything that looked like text. 1988 01:34:54,720 --> 01:34:57,110 Yeah. 1989 01:34:57,110 --> 01:35:00,170 Correct, string is double quotes for multiple characters-- or even one, 1990 01:35:00,170 --> 01:35:01,250 technically, but yes. 1991 01:35:01,250 --> 01:35:05,410 And single quotes for single characters. 1992 01:35:05,410 --> 01:35:07,000 Because my data type is different. 1993 01:35:07,000 --> 01:35:09,970 I chose the simple route of just using a single char. 1994 01:35:09,970 --> 01:35:12,550 In fact, this program won't work with Y-E-S 1995 01:35:12,550 --> 01:35:16,240 or N-O. That's not supported at the moment-- more on that another time. 1996 01:35:16,240 --> 01:35:19,030 I had to use single quotes because that's how C does it. 1997 01:35:19,030 --> 01:35:20,990 If you're dealing with single characters, 1998 01:35:20,990 --> 01:35:23,050 a.k.a. chars, use single quotes. 1999 01:35:23,050 --> 01:35:23,980 If it's a string-- 2000 01:35:23,980 --> 01:35:27,790 even if it's one single character in a string 2001 01:35:27,790 --> 01:35:30,823 as though you're starting to write out a longer word or sentence-- 2002 01:35:30,823 --> 01:35:31,990 that would be double quotes. 2003 01:35:31,990 --> 01:35:34,060 And we'll see why this is before long too. 2004 01:35:34,060 --> 01:35:37,750 But, again, just things to keep in mind whenever writing code 2005 01:35:37,750 --> 01:35:39,940 in this particular language. 2006 01:35:39,940 --> 01:35:42,170 Yeah, down here. 2007 01:35:42,170 --> 01:35:47,260 So, short answer, if I'm understanding correctly, this would be incorrect. 2008 01:35:47,260 --> 01:35:49,470 And this would be even more incorrect. 2009 01:35:49,470 --> 01:35:51,970 But if you don't mind, let me kick the can a couple of weeks 2010 01:35:51,970 --> 01:35:53,680 on this as to why this doesn't work. 2011 01:35:53,680 --> 01:35:58,052 The most pleasant way to do this would indeed be to do something like this. 2012 01:35:58,052 --> 01:36:00,010 But even this is a slippery slope, because what 2013 01:36:00,010 --> 01:36:03,378 if the user does something weird, like they capitalize just the Y? 2014 01:36:03,378 --> 01:36:05,170 You can imagine this getting messy quickly. 2015 01:36:05,170 --> 01:36:07,510 I like your idea earlier about just forcing everything 2016 01:36:07,510 --> 01:36:09,760 to lowercase just to standardize things. 2017 01:36:09,760 --> 01:36:13,900 Unfortunately, you cannot compare strings for equality like this 2018 01:36:13,900 --> 01:36:15,980 for, again, reasons will come to before long. 2019 01:36:15,980 --> 01:36:18,880 So for today, we're keeping it simple, even though, arguably, it's 2020 01:36:18,880 --> 01:36:22,840 not nearly as user-friendly to only tolerate individual letters. 2021 01:36:22,840 --> 01:36:26,020 And there's a question over here. 2022 01:36:26,020 --> 01:36:28,180 On the US English keyboard it's shift and then 2023 01:36:28,180 --> 01:36:31,280 the backslash key above Return, but depending on your keyboard, 2024 01:36:31,280 --> 01:36:33,520 it will vary. 2025 01:36:33,520 --> 01:36:36,340 All right, so let's actually now look back 2026 01:36:36,340 --> 01:36:38,380 at something we did a little bit of last week. 2027 01:36:38,380 --> 01:36:41,170 Let me go ahead and open a file called meow.c, 2028 01:36:41,170 --> 01:36:43,660 because, recall, that's what we had Scratch do initially. 2029 01:36:43,660 --> 01:36:46,450 Let me include not the C50 library this time, 2030 01:36:46,450 --> 01:36:50,350 but just stdio.h because I only want printf for this demo. 2031 01:36:50,350 --> 01:36:53,920 Let me go ahead now and just print out meow. 2032 01:36:53,920 --> 01:36:57,610 And then if I want the cat to meow three times, like it did last week, 2033 01:36:57,610 --> 01:36:58,990 meow, meow, meow. 2034 01:36:58,990 --> 01:36:59,830 Save it. 2035 01:36:59,830 --> 01:37:01,910 make meow, ./meow. 2036 01:37:01,910 --> 01:37:02,410 Voila. 2037 01:37:02,410 --> 01:37:05,320 The program is written-- correct, I claim. 2038 01:37:05,320 --> 01:37:05,950 It ran. 2039 01:37:05,950 --> 01:37:06,790 It compiled OK. 2040 01:37:06,790 --> 01:37:09,040 But, again, this was the beginning of our conversation 2041 01:37:09,040 --> 01:37:11,740 last week of not being particularly well-designed. 2042 01:37:11,740 --> 01:37:14,830 And if someone wants to maybe point out the now obvious, 2043 01:37:14,830 --> 01:37:19,580 why is this not well-designed, necessarily? 2044 01:37:19,580 --> 01:37:21,020 Yeah, it's just repetition, right? 2045 01:37:21,020 --> 01:37:23,093 Again, I literally resorted to copy-paste. 2046 01:37:23,093 --> 01:37:25,010 That should be the signal that you're probably 2047 01:37:25,010 --> 01:37:29,070 doing something wrong or, at best, just lazy of you, in this case. 2048 01:37:29,070 --> 01:37:31,395 So the solution, as you might glean from last week, 2049 01:37:31,395 --> 01:37:33,770 is probably going to be one of those things called loops. 2050 01:37:33,770 --> 01:37:36,470 So let's just take a look at some of the syntax for loops in C. 2051 01:37:36,470 --> 01:37:39,283 But, again, no new ideas, it's just some new syntax 2052 01:37:39,283 --> 01:37:40,700 that'll take some getting used to. 2053 01:37:40,700 --> 01:37:44,330 In Scratch, if you wanted to meow forever with something like this, 2054 01:37:44,330 --> 01:37:49,080 there's not a forever keyword in C, so this one's a little weird to look at. 2055 01:37:49,080 --> 01:37:50,420 But this is the best we can do. 2056 01:37:50,420 --> 01:37:54,530 It turns out there is a keyword called while in C. 2057 01:37:54,530 --> 01:37:56,750 And that kind of has the right semantics, 2058 01:37:56,750 --> 01:37:59,940 because it's like while I do something again and again, 2059 01:37:59,940 --> 01:38:01,430 that's the best I can do. 2060 01:38:01,430 --> 01:38:05,990 But just like an if condition or an else if condition, 2061 01:38:05,990 --> 01:38:09,260 those took a Boolean expression in parentheses, 2062 01:38:09,260 --> 01:38:12,330 a while loop also takes a Boolean expression in parentheses. 2063 01:38:12,330 --> 01:38:13,730 So I have to ask a question. 2064 01:38:13,730 --> 01:38:17,240 Now, if I want to do something forever, I could kind of stupidly just 2065 01:38:17,240 --> 01:38:21,740 say while 2 is greater than 1, while 3 is greater than 2, 2066 01:38:21,740 --> 01:38:23,630 or just something completely arbitrary. 2067 01:38:23,630 --> 01:38:27,440 But that should rub you the wrong way, because like, why 2 versus 1? 2068 01:38:27,440 --> 01:38:32,330 Why 3-- if you want true, just say true. 2069 01:38:32,330 --> 01:38:36,980 So it turns out in C, there are special keywords, true and false, 2070 01:38:36,980 --> 01:38:40,100 that are literally true and false, respectively. 2071 01:38:40,100 --> 01:38:44,540 I could also put the number 1 for true and the number 0 for false, 2072 01:38:44,540 --> 01:38:47,280 but most people would just say true to be explicit. 2073 01:38:47,280 --> 01:38:50,630 So it's a little hackish, if you will, but very conventional. 2074 01:38:50,630 --> 01:38:54,980 There's no forever keyword in C. If I want to then print meow forever, 2075 01:38:54,980 --> 01:38:57,390 I'm going to just use something like printf here. 2076 01:38:57,390 --> 01:38:59,930 So, again, not perfect translation from one 2077 01:38:59,930 --> 01:39:02,907 to the other, but absolutely possible in C. What about this? 2078 01:39:02,907 --> 01:39:05,240 This is a little more common if you want to do something 2079 01:39:05,240 --> 01:39:08,480 a finite number of times, like repeat 3. 2080 01:39:08,480 --> 01:39:13,100 There's a few different ways we can do this in C. Here's one approach. 2081 01:39:13,100 --> 01:39:16,670 And here's where C-- like a lot of text-based languages, 2082 01:39:16,670 --> 01:39:20,120 you kind of have to whip out that toolkit of all of the basic building 2083 01:39:20,120 --> 01:39:22,370 blocks and think about, all right, how can I 2084 01:39:22,370 --> 01:39:27,080 build a little machine in software that does something some number of times? 2085 01:39:27,080 --> 01:39:31,580 Well, let me give myself a variable called counter, set it equal to 0. 2086 01:39:31,580 --> 01:39:37,940 Let me create a loop whose Boolean expression is counter less than 3, 2087 01:39:37,940 --> 01:39:41,510 the idea being here, why don't I just kind of count 1, 2, 3? 2088 01:39:41,510 --> 01:39:44,990 So how do I implement this physicality in code? 2089 01:39:44,990 --> 01:39:48,380 I give myself a variable, set it to 0, 0 fingers up. 2090 01:39:48,380 --> 01:39:51,200 Now, I ask the question, is counter less than 3? 2091 01:39:51,200 --> 01:39:54,170 If so, go ahead and print out meow. 2092 01:39:54,170 --> 01:39:57,530 And just intuitively, even if you've never seen C code or any code 2093 01:39:57,530 --> 01:40:00,680 before Scratch, what more do I need to do? 2094 01:40:00,680 --> 01:40:03,620 I've left room here for one more line of logic. 2095 01:40:03,620 --> 01:40:05,190 Yeah. 2096 01:40:05,190 --> 01:40:06,420 We have to increase counter. 2097 01:40:06,420 --> 01:40:10,350 So I need code like I showed earlier, like counter equals counter plus 1. 2098 01:40:10,350 --> 01:40:12,600 And so here's where programming sometimes 2099 01:40:12,600 --> 01:40:14,120 becomes a bit more like plumbing. 2100 01:40:14,120 --> 01:40:16,620 You can't just say what you mean, like you couldn't Scratch. 2101 01:40:16,620 --> 01:40:19,200 You have to build a little sort of software machine 2102 01:40:19,200 --> 01:40:22,380 that initializes a value, does something, increments it, checks it. 2103 01:40:22,380 --> 01:40:25,290 And so it's kind of like this software-based machine, 2104 01:40:25,290 --> 01:40:28,410 but together, that's just using some familiar building blocks. 2105 01:40:28,410 --> 01:40:29,580 But this is pretty common. 2106 01:40:29,580 --> 01:40:31,872 Just like in Scratch, you might have used loops a bunch 2107 01:40:31,872 --> 01:40:33,360 of times, pretty common in C. 2108 01:40:33,360 --> 01:40:35,250 So can we tighten this code up? 2109 01:40:35,250 --> 01:40:39,780 This is correct, but here are some conventions that are popular. 2110 01:40:39,780 --> 01:40:42,225 If you're going to count, just say i. 2111 01:40:42,225 --> 01:40:44,100 A convention in programming-- with, at least, 2112 01:40:44,100 --> 01:40:48,690 languages like C-- is just use i as an integer if all its purpose is 2113 01:40:48,690 --> 01:40:50,850 is to count from like, 0 on up. 2114 01:40:50,850 --> 01:40:52,240 Counter is not wrong. 2115 01:40:52,240 --> 01:40:53,100 It's not bad. 2116 01:40:53,100 --> 01:40:55,980 It's just more verbose than you need to be. 2117 01:40:55,980 --> 01:40:56,940 Just call it i. 2118 01:40:56,940 --> 01:40:58,732 You don't need more semantics than that. 2119 01:40:58,732 --> 01:41:00,190 All right, what else can I do here? 2120 01:41:00,190 --> 01:41:03,377 There's another opportunity to tighten up this code. 2121 01:41:03,377 --> 01:41:03,960 Do you recall? 2122 01:41:03,960 --> 01:41:05,920 Yeah. 2123 01:41:05,920 --> 01:41:08,920 Yeah, that syntactic sugar that does nothing new, 2124 01:41:08,920 --> 01:41:10,720 but it does it more succinctly. 2125 01:41:10,720 --> 01:41:15,190 I can change this to either the intermediate format or even tighter 2126 01:41:15,190 --> 01:41:16,900 format of just i++. 2127 01:41:16,900 --> 01:41:19,120 Now, this is pretty canonical. 2128 01:41:19,120 --> 01:41:23,140 This is how most people would implement something 2129 01:41:23,140 --> 01:41:25,810 three times using a loop in C-- 2130 01:41:25,810 --> 01:41:27,535 using a while loop, that is. 2131 01:41:27,535 --> 01:41:30,550 Turns out that it's so common in C and other languages 2132 01:41:30,550 --> 01:41:34,360 to do something finitely many times, there's a couple of ways to do it. 2133 01:41:34,360 --> 01:41:37,220 In this model, to be clear, the logic, though, 2134 01:41:37,220 --> 01:41:40,420 is that we start by initializing the variable, like I've highlighted here. 2135 01:41:40,420 --> 01:41:43,510 We then ask the question, is i less than 0? 2136 01:41:43,510 --> 01:41:47,230 If so, everything that's indented inside the curly braces 2137 01:41:47,230 --> 01:41:50,440 gets executed-- namely, meow then the update. 2138 01:41:50,440 --> 01:41:54,130 Then the computer is going to have to recheck the condition 2139 01:41:54,130 --> 01:41:57,730 to make sure that i hasn't gotten so big that it's greater than 3. 2140 01:41:57,730 --> 01:42:00,820 But if not, it then does this again and it does this again. 2141 01:42:00,820 --> 01:42:03,245 And then it repeats, constantly checking the condition 2142 01:42:03,245 --> 01:42:05,620 and executing what's in the block, checking the condition 2143 01:42:05,620 --> 01:42:07,037 and executing what's in the block. 2144 01:42:07,037 --> 01:42:11,590 After three times of that, the condition is going to be false, or a no answer, 2145 01:42:11,590 --> 01:42:12,820 and that's it for the code. 2146 01:42:12,820 --> 01:42:15,940 It just proceeds to whatever's down here, just like with Scratch. 2147 01:42:15,940 --> 01:42:18,590 It jumps to the next blocks down below. 2148 01:42:18,590 --> 01:42:21,380 All right, what's another way, though, to do this? 2149 01:42:21,380 --> 01:42:23,380 Well, I've deliberately been counting from 0-- 2150 01:42:23,380 --> 01:42:25,172 and that's a programming convention, right? 2151 01:42:25,172 --> 01:42:27,887 We started last week with all the light bulbs off, which was 0. 2152 01:42:27,887 --> 01:42:30,220 So it's pretty reasonable to start counting at 0's, just 2153 01:42:30,220 --> 01:42:31,053 like you would here. 2154 01:42:31,053 --> 01:42:33,070 Like, no fingers are up, this is 0-- 2155 01:42:33,070 --> 01:42:34,760 fingers on your hand. 2156 01:42:34,760 --> 01:42:39,040 But if you prefer, you could start counting at i equals 1. 2157 01:42:39,040 --> 01:42:42,340 But then you don't want to do it while i is less than 3, 2158 01:42:42,340 --> 01:42:45,400 you want to do i is less than or equal to 3. 2159 01:42:45,400 --> 01:42:49,840 On most keyboards, there's no symbol for less than or equal to or greater than 2160 01:42:49,840 --> 01:42:53,890 or equal to, so in C, you use two characters, less than 2161 01:42:53,890 --> 01:42:57,010 and then an equals sign with no spaces in between. 2162 01:42:57,010 --> 01:42:59,450 That just means less than or equal to. 2163 01:42:59,450 --> 01:43:03,970 We could change it to set i to 2 and make this condition be less than 2164 01:43:03,970 --> 01:43:05,020 or equal to 4. 2165 01:43:05,020 --> 01:43:10,100 We could make this be a 10 and less than or equal to 12. 2166 01:43:10,100 --> 01:43:12,010 But, again, just stick with the basics. 2167 01:43:12,010 --> 01:43:15,130 Start at 0 and count on up would be the convention. 2168 01:43:15,130 --> 01:43:18,490 Or if you prefer to count down, that's fine too. 2169 01:43:18,490 --> 01:43:22,900 Set i to 3 and then do this so long as i is greater than 0, 2170 01:43:22,900 --> 01:43:25,752 but you have to decrement instead of increment. 2171 01:43:25,752 --> 01:43:27,460 So, again, we could do this all day long. 2172 01:43:27,460 --> 01:43:30,595 There's literally an infinite number of ways to implement this idea. 2173 01:43:30,595 --> 01:43:32,470 And that's why I keep emphasizing convention. 2174 01:43:32,470 --> 01:43:34,960 Call the variable i for something like this, 2175 01:43:34,960 --> 01:43:38,470 initialize it to 0 for something like this, and just generally count up, 2176 01:43:38,470 --> 01:43:40,360 unless you really prefer to count down. 2177 01:43:40,360 --> 01:43:43,120 Again, just certain human conventions. 2178 01:43:43,120 --> 01:43:46,310 All right, how about another way to do this? 2179 01:43:46,310 --> 01:43:50,270 This is what's called a for loop in C, also very common. 2180 01:43:50,270 --> 01:43:53,290 It's not quite as straightforward in that it doesn't really read top 2181 01:43:53,290 --> 01:43:55,210 to bottom in exactly the same way. 2182 01:43:55,210 --> 01:43:58,600 This kind of has a lot more logic tucked into its first line. 2183 01:43:58,600 --> 01:44:01,120 But it does exactly the same thing. 2184 01:44:01,120 --> 01:44:02,830 What happens here is-- 2185 01:44:02,830 --> 01:44:06,550 notice that inside the parentheses, next to the word for, 2186 01:44:06,550 --> 01:44:09,722 there's two semicolons-- which is another weird use of syntax. 2187 01:44:09,722 --> 01:44:11,680 They're not at the end of the line, now they're 2188 01:44:11,680 --> 01:44:13,055 in the middle of the parentheses. 2189 01:44:13,055 --> 01:44:15,230 But that's what the humans chose years ago. 2190 01:44:15,230 --> 01:44:22,150 The first thing before the semicolons initializes your variable, int i = 0. 2191 01:44:22,150 --> 01:44:25,240 The next thing is the condition that's going to constantly get 2192 01:44:25,240 --> 01:44:27,760 checked every cycle through this loop. 2193 01:44:27,760 --> 01:44:32,560 And the last thing is going to be what you do after each loop, which 2194 01:44:32,560 --> 01:44:34,190 in this case is going to be count up. 2195 01:44:34,190 --> 01:44:36,910 So, again, if I rewind we initialize i to 0. 2196 01:44:36,910 --> 01:44:39,550 We then ask the question, is i less than 3? 2197 01:44:39,550 --> 01:44:43,810 If so, execute what's inside of the loop. 2198 01:44:43,810 --> 01:44:49,690 Then the computer does this, it does the update, incrementing i by 1. 2199 01:44:49,690 --> 01:44:52,420 And then it's not going to blindly meow again. 2200 01:44:52,420 --> 01:44:55,780 It's going to check again the condition, is i less than 3? 2201 01:44:55,780 --> 01:44:57,550 Then it's going to meow if so. 2202 01:44:57,550 --> 01:45:01,960 Then it might go ahead and increment i and check the condition again. 2203 01:45:01,960 --> 01:45:05,648 So, again, this does not read quite the same simple fashion top to bottom. 2204 01:45:05,648 --> 01:45:07,940 You kind of read it left to right and then jump around. 2205 01:45:07,940 --> 01:45:13,090 But, again, the initialization, the constant Boolean expression 2206 01:45:13,090 --> 01:45:15,880 being checked, and the update after each time 2207 01:45:15,880 --> 01:45:23,750 does the exact same thing as what we saw a moment ago in this while loop format. 2208 01:45:23,750 --> 01:45:25,300 Which one is better? 2209 01:45:25,300 --> 01:45:26,210 Eh, they're the same. 2210 01:45:26,210 --> 01:45:28,252 I think most people would probably eventually use 2211 01:45:28,252 --> 01:45:33,770 a for loop once comfortable, but just because is really the answer there. 2212 01:45:33,770 --> 01:45:36,870 All right, any questions, then, on loops as we've translated them to C? 2213 01:45:36,870 --> 01:45:37,370 Yeah. 2214 01:45:37,370 --> 01:45:39,122 AUDIENCE: [INAUDIBLE] 2215 01:45:39,122 --> 01:45:40,830 DAVID J. MALAN: A for loop and while loop 2216 01:45:40,830 --> 01:45:44,340 can both be used to do exactly the same thing. 2217 01:45:44,340 --> 01:45:47,932 There are subtle differences with issues of scope, 2218 01:45:47,932 --> 01:45:49,890 which we'll discuss before long, where when you 2219 01:45:49,890 --> 01:45:52,120 create a variable in a for loop-- 2220 01:45:52,120 --> 01:45:55,590 notice that it was, again, inside of those parentheses, which 2221 01:45:55,590 --> 01:46:00,030 technically means it's only going to exist in these four lines of code. 2222 01:46:00,030 --> 01:46:03,780 By contrast, with the while loop, I declared my variable outside 2223 01:46:03,780 --> 01:46:04,410 of the loop. 2224 01:46:04,410 --> 01:46:08,230 That variable is going to continue to exist elsewhere in my program. 2225 01:46:08,230 --> 01:46:11,207 So that's one of the minor differences there. 2226 01:46:11,207 --> 01:46:11,790 Good question. 2227 01:46:11,790 --> 01:46:14,070 But you'll see some others over time. 2228 01:46:14,070 --> 01:46:17,290 All right, so we claim then that it's better in some form 2229 01:46:17,290 --> 01:46:18,490 to do this with loops. 2230 01:46:18,490 --> 01:46:20,530 So let's actually jump back to the code. 2231 01:46:20,530 --> 01:46:25,030 Let me go ahead and now re-implement meowing with a for loop, for instance. 2232 01:46:25,030 --> 01:46:30,900 So how about for int i = 0, i less than 3, i++. 2233 01:46:30,900 --> 01:46:35,640 Then inside my curly braces, let me go ahead and print out with printf, meow, 2234 01:46:35,640 --> 01:46:38,110 with a newline and a semicolon. 2235 01:46:38,110 --> 01:46:41,860 So I did it pretty quickly just because I've long acquired the muscle memory. 2236 01:46:41,860 --> 01:46:44,790 But if I now make meow, no errors there. 2237 01:46:44,790 --> 01:46:46,050 Run ./meow. 2238 01:46:46,050 --> 01:46:48,300 And I see meow, meow, meow. 2239 01:46:48,300 --> 01:46:50,430 Well, let's do now what we did last week, which 2240 01:46:50,430 --> 01:46:54,700 was to begin to make our own custom functions, if you will, 2241 01:46:54,700 --> 01:47:00,630 by using our own in C. So here's where the syntax gets a little funky, 2242 01:47:00,630 --> 01:47:05,040 but we'll explain over time what each of these keywords is doing. 2243 01:47:05,040 --> 01:47:08,400 If I want to create a function called meow-- 2244 01:47:08,400 --> 01:47:12,480 because the authors of C did not create a function called meow decades ago-- 2245 01:47:12,480 --> 01:47:15,150 I need to give it a name, like meow. 2246 01:47:15,150 --> 01:47:17,730 I need to specify if it takes any inputs. 2247 01:47:17,730 --> 01:47:19,590 For now, I'm going to say no. 2248 01:47:19,590 --> 01:47:25,400 And I'm going to explicitly say no by writing the special word void. 2249 01:47:25,400 --> 01:47:28,280 It's also necessary when implementing a function in C-- 2250 01:47:28,280 --> 01:47:30,050 which was not necessary in Scratch-- 2251 01:47:30,050 --> 01:47:32,610 to specify what its return type is. 2252 01:47:32,610 --> 01:47:36,260 But for now, I'm just going to say that meow is the name of the function, 2253 01:47:36,260 --> 01:47:37,790 it takes no inputs-- 2254 01:47:37,790 --> 01:47:40,730 and that's what the void in parentheses means-- 2255 01:47:40,730 --> 01:47:45,290 and it does not return anything like ask did, 2256 01:47:45,290 --> 01:47:47,420 or like get_string or get_int does. 2257 01:47:47,420 --> 01:47:51,140 meow's purpose in life is just to have side effects, visual side effects 2258 01:47:51,140 --> 01:47:53,190 by printing something on the screen. 2259 01:47:53,190 --> 01:47:55,460 So what is meow going to do? 2260 01:47:55,460 --> 01:47:57,680 I'm going to have it quite simply say printf, 2261 01:47:57,680 --> 01:48:01,490 quote unquote, "meow", backslash n. 2262 01:48:01,490 --> 01:48:05,870 And now, just like in Scratch, I can now just call 2263 01:48:05,870 --> 01:48:08,030 a brand new function called meow. 2264 01:48:08,030 --> 01:48:10,730 And here's where too, if you really don't like the curly braces, 2265 01:48:10,730 --> 01:48:13,790 technically speaking, you can get rid of them when there's 2266 01:48:13,790 --> 01:48:16,010 only one line of code inside your loop. 2267 01:48:16,010 --> 01:48:18,710 But, again, stylistically, I would encourage 2268 01:48:18,710 --> 01:48:21,710 you to preserve them to make super clear to yourself and others 2269 01:48:21,710 --> 01:48:23,670 what it is that's going on. 2270 01:48:23,670 --> 01:48:26,300 Let me go ahead and save this and do make meow. 2271 01:48:26,300 --> 01:48:27,730 Whoops. 2272 01:48:27,730 --> 01:48:28,230 Darn. 2273 01:48:28,230 --> 01:48:29,272 All right, what did I do? 2274 01:48:29,272 --> 01:48:30,295 Something stupid. 2275 01:48:30,295 --> 01:48:31,170 AUDIENCE: [INAUDIBLE] 2276 01:48:31,170 --> 01:48:33,340 DAVID J. MALAN: Yeah, so 0 does not belong there. 2277 01:48:33,340 --> 01:48:35,760 I meant to hit parenthesis. 2278 01:48:35,760 --> 01:48:38,190 So let me rerun make meow. 2279 01:48:38,190 --> 01:48:39,720 OK, fixed. 2280 01:48:39,720 --> 01:48:40,800 My mistake. 2281 01:48:40,800 --> 01:48:42,820 All right, it's still working OK. 2282 01:48:42,820 --> 01:48:45,970 But recall what I did in Scratch, kind of out of sight, out of mind. 2283 01:48:45,970 --> 01:48:49,020 And just to make a point, let me just highlight this and move it 2284 01:48:49,020 --> 01:48:50,460 way down in the file. 2285 01:48:50,460 --> 01:48:53,490 Because, again, now that meow exists, it's an abstraction. 2286 01:48:53,490 --> 01:48:55,800 I just know a meow function exists. 2287 01:48:55,800 --> 01:48:57,310 I want to be able to use it. 2288 01:48:57,310 --> 01:48:59,220 So let me scroll back up. 2289 01:48:59,220 --> 01:49:00,930 My main function is the same. 2290 01:49:00,930 --> 01:49:03,480 Let me go ahead and make meow again. 2291 01:49:03,480 --> 01:49:08,730 And now, just by moving that function, I've created all these lines of errors. 2292 01:49:08,730 --> 01:49:10,050 And let's look at the first. 2293 01:49:10,050 --> 01:49:12,217 Again, the rule of thumb here-- it's a little small, 2294 01:49:12,217 --> 01:49:16,260 but it says meow.c in bold-- which is the name of the file where the bug is-- 2295 01:49:16,260 --> 01:49:19,110 5 is the line number, and 20 is the character. 2296 01:49:19,110 --> 01:49:21,940 So line number is enough alone. 2297 01:49:21,940 --> 01:49:23,700 Let's see. 2298 01:49:23,700 --> 01:49:27,810 Oh, this is what happens when I scrolled up too far. 2299 01:49:27,810 --> 01:49:28,410 Sorry. 2300 01:49:28,410 --> 01:49:30,960 This is the error we're now looking at, line 7. 2301 01:49:30,960 --> 01:49:34,890 I was looking at the old error message from earlier before I fixed the 0. 2302 01:49:34,890 --> 01:49:36,750 meow.c line 7. 2303 01:49:36,750 --> 01:49:40,980 All right, apparently, C does not know what the meow function is. 2304 01:49:40,980 --> 01:49:44,640 Implicit declaration of function meow is invalid in C99. 2305 01:49:44,640 --> 01:49:45,780 Well, what does that mean? 2306 01:49:45,780 --> 01:49:49,140 Declaration of function means your creation of a function. 2307 01:49:49,140 --> 01:49:52,710 Like, I'm declaring that meow exists, but I haven't apparently 2308 01:49:52,710 --> 01:49:53,700 defined it yet. 2309 01:49:53,700 --> 01:49:57,430 And then C99 is the version of C from the year 1999, 2310 01:49:57,430 --> 01:50:00,390 which we generally use here, it's one of the more recent versions. 2311 01:50:00,390 --> 01:50:03,660 So why is that the case? 2312 01:50:03,660 --> 01:50:07,230 Can you infer from the mere fact that I just moved meow to the bottom 2313 01:50:07,230 --> 01:50:10,240 of the file-- which was fine in Scratch but now is bad-- 2314 01:50:10,240 --> 01:50:11,618 why is that? 2315 01:50:11,618 --> 01:50:13,065 AUDIENCE: [INAUDIBLE] 2316 01:50:13,065 --> 01:50:15,190 DAVID J. MALAN: Yeah, C is just kind of old school. 2317 01:50:15,190 --> 01:50:16,880 It reads your code top to bottom. 2318 01:50:16,880 --> 01:50:21,200 And if it does not know what meow is when you first try to use it, 2319 01:50:21,200 --> 01:50:24,110 it just freaks out and prints out these error messages. 2320 01:50:24,110 --> 01:50:29,710 So the solution is, quite simply, don't do that, just leave it where it was. 2321 01:50:29,710 --> 01:50:33,670 But you can imagine this getting a little annoying over time, if only 2322 01:50:33,670 --> 01:50:37,960 because main is, by name, the main part of your program. 2323 01:50:37,960 --> 01:50:41,170 And, honestly, it would just be nice if main were always 2324 01:50:41,170 --> 01:50:42,298 at the top of your code. 2325 01:50:42,298 --> 01:50:44,590 Because if you want to understand what a file is doing, 2326 01:50:44,590 --> 01:50:46,600 it makes sense to just read it top to bottom. 2327 01:50:46,600 --> 01:50:48,775 Well, there is a solution to this. 2328 01:50:48,775 --> 01:50:53,920 You can put functions in different orders with main at the top so long 2329 01:50:53,920 --> 01:50:58,700 as you-- and this is perhaps the only time copy paste is appropriate-- 2330 01:50:58,700 --> 01:51:01,870 so long as you leave a little breadcrumb for the compiler 2331 01:51:01,870 --> 01:51:04,330 at the very top of your file that literally 2332 01:51:04,330 --> 01:51:08,290 repeats the return value, the name, and the arguments 2333 01:51:08,290 --> 01:51:10,880 to that function, semicolon. 2334 01:51:10,880 --> 01:51:13,990 This is, so to speak, declaring your function-- 2335 01:51:13,990 --> 01:51:16,460 and the real fancy way is this is a prototype. 2336 01:51:16,460 --> 01:51:18,740 It's like, what is this thing going to look like? 2337 01:51:18,740 --> 01:51:21,680 But the semicolon means I'm not going to deal with this yet. 2338 01:51:21,680 --> 01:51:23,530 I'm going to actually define the function 2339 01:51:23,530 --> 01:51:25,900 or implement it down below here. 2340 01:51:25,900 --> 01:51:27,880 This is kind of a stupid detail. 2341 01:51:27,880 --> 01:51:31,420 More recent languages get rid of this need, 2342 01:51:31,420 --> 01:51:33,193 you can put your functions in any order. 2343 01:51:33,193 --> 01:51:35,110 But, again, if you just think about the basics 2344 01:51:35,110 --> 01:51:37,430 of programming languages like this one here-- 2345 01:51:37,430 --> 01:51:38,410 and as you noted-- 2346 01:51:38,410 --> 01:51:40,550 it must just be reading your code top to bottom. 2347 01:51:40,550 --> 01:51:44,260 So annoying, yes, but explained, yes too. 2348 01:51:44,260 --> 01:51:49,480 So let me go ahead and make meow one more time, ./meow, still working OK. 2349 01:51:49,480 --> 01:51:53,530 And let me make one final enhancement to this meow program here. 2350 01:51:53,530 --> 01:51:56,420 Let me go ahead now and say something like this. 2351 01:51:56,420 --> 01:51:58,390 Let me go ahead and say, all right, wouldn't it 2352 01:51:58,390 --> 01:52:04,140 be nice if my meow function could do something for me some number of times? 2353 01:52:04,140 --> 01:52:05,900 So suppose I want to do this. 2354 01:52:05,900 --> 01:52:09,070 This meow function at the moment is going to meow three times. 2355 01:52:09,070 --> 01:52:12,310 But suppose I want to meow n times, where n is just 2356 01:52:12,310 --> 01:52:14,380 some number provided by the user. 2357 01:52:14,380 --> 01:52:18,760 Well, just like in Scratch, custom functions can take inputs, 2358 01:52:18,760 --> 01:52:21,320 I just presently am saying void. 2359 01:52:21,320 --> 01:52:25,750 But if I change this to int n, thereby telling the compiler, 2360 01:52:25,750 --> 01:52:29,350 hey, meow still doesn't return something, 2361 01:52:29,350 --> 01:52:31,780 but it does take something as input. 2362 01:52:31,780 --> 01:52:34,780 It takes an integer, and I want to call it n. 2363 01:52:34,780 --> 01:52:37,270 So this is another way of declaring a variable 2364 01:52:37,270 --> 01:52:40,090 but a way of declaring a variable that gets handed into, 2365 01:52:40,090 --> 01:52:41,630 as input, the function. 2366 01:52:41,630 --> 01:52:46,300 So now if I tighten up main here, now I can actually do something really cool 2367 01:52:46,300 --> 01:52:49,750 just like in Scratch, which is this. 2368 01:52:49,750 --> 01:52:52,240 If I now look at this code-- let me Zoom in here-- 2369 01:52:52,240 --> 01:52:55,510 now my main program is really well-written in the sense 2370 01:52:55,510 --> 01:52:58,390 that it just says what it does, meow three times. 2371 01:52:58,390 --> 01:53:02,230 This works, though, because I defined meow as now taking an input, 2372 01:53:02,230 --> 01:53:08,890 an integer called n, and then using n in my now familiar for loop. 2373 01:53:08,890 --> 01:53:09,970 There's one change. 2374 01:53:09,970 --> 01:53:12,470 You might have caught my one mistake. 2375 01:53:12,470 --> 01:53:16,300 I also have to remind myself up here to make that change too. 2376 01:53:16,300 --> 01:53:19,090 Again, this is one of the only redundancies or copy-paste 2377 01:53:19,090 --> 01:53:20,710 that's sort of reasonable. 2378 01:53:20,710 --> 01:53:23,230 But there, I have now a better version. 2379 01:53:23,230 --> 01:53:27,580 So let me go ahead and rerun this, make meow, ./meow. 2380 01:53:27,580 --> 01:53:28,180 Voila. 2381 01:53:28,180 --> 01:53:30,730 So, again, no change in correctness but now, 2382 01:53:30,730 --> 01:53:32,590 again, we're sort of modularizing our code. 2383 01:53:32,590 --> 01:53:35,920 And, heck, what you could do now-- and this is just a tease about a feature 2384 01:53:35,920 --> 01:53:36,700 down the road-- 2385 01:53:36,700 --> 01:53:39,520 those header files we talked about early, those libraries, 2386 01:53:39,520 --> 01:53:42,250 this is the kind of modularization we're talking about. 2387 01:53:42,250 --> 01:53:46,120 We, the staff, wrote a function called get_string, get_int, and so forth, 2388 01:53:46,120 --> 01:53:52,390 we put it in a file called CS50, and we put little breadcrumbs-- specifically, 2389 01:53:52,390 --> 01:53:54,580 these things called prototypes-- 2390 01:53:54,580 --> 01:53:56,770 in cs50.h. 2391 01:53:56,770 --> 01:54:01,450 So that when you all, as aspiring programmers, include cs50.h, 2392 01:54:01,450 --> 01:54:05,500 you are sort of secretly telling the compiler at the very top of your code 2393 01:54:05,500 --> 01:54:07,490 what the menu of available functions is. 2394 01:54:07,490 --> 01:54:07,990 Why? 2395 01:54:07,990 --> 01:54:12,760 Because in CS50 is lines like these-- obviously, not for meow, 2396 01:54:12,760 --> 01:54:15,340 but for get_string, get_int, and so forth. 2397 01:54:15,340 --> 01:54:20,740 And stdio.h is the same lines of code for things like printf. 2398 01:54:20,740 --> 01:54:22,940 So that's all that's going on there. 2399 01:54:22,940 --> 01:54:29,240 It's just a way of telling the computer in advance what functions to expect. 2400 01:54:29,240 --> 01:54:32,120 All right, any questions, then, on these here? 2401 01:54:35,000 --> 01:54:35,510 Correct. 2402 01:54:35,510 --> 01:54:38,330 So if you don't mind, I want to continue to wave 2403 01:54:38,330 --> 01:54:40,250 my hand at that detail for today. 2404 01:54:40,250 --> 01:54:44,780 Indeed, int main void is a little weird, because what would the input domain be? 2405 01:54:44,780 --> 01:54:46,867 We have no mechanism for providing input yet. 2406 01:54:46,867 --> 01:54:48,950 And what does it mean for main to return anything? 2407 01:54:48,950 --> 01:54:50,450 Like, who is it returning to? 2408 01:54:50,450 --> 01:54:51,577 For another day, if we may. 2409 01:54:51,577 --> 01:54:53,660 They're going to come into play but that, for now, 2410 01:54:53,660 --> 01:54:56,300 today is just something you should take at face value, 2411 01:54:56,300 --> 01:54:59,520 as necessary copy-paste to begin programs. 2412 01:54:59,520 --> 01:55:02,690 So meow is a function that takes an input, the number of times to meow, 2413 01:55:02,690 --> 01:55:06,170 but it didn't actually have a return value, hence the void. 2414 01:55:06,170 --> 01:55:08,720 But what if we actually want to create our own function that 2415 01:55:08,720 --> 01:55:11,630 not only takes 0 or more inputs as arguments 2416 01:55:11,630 --> 01:55:15,260 but also returns some value, maybe an int, maybe a float, maybe something 2417 01:55:15,260 --> 01:55:16,190 else altogether? 2418 01:55:16,190 --> 01:55:18,840 Well, it turns out, in C, we can do that as well. 2419 01:55:18,840 --> 01:55:22,280 Let me go ahead and create a new file here called discount. 2420 01:55:22,280 --> 01:55:24,320 And let's implement a quick program via which 2421 01:55:24,320 --> 01:55:26,840 we can discount some regular price by some percentage, 2422 01:55:26,840 --> 01:55:28,940 as though there's a sale going on in a store. 2423 01:55:28,940 --> 01:55:35,690 Let me go ahead and include our usual cs50.h followed by stdio.h at the top. 2424 01:55:35,690 --> 01:55:38,750 Let me give myself int main void as before. 2425 01:55:38,750 --> 01:55:41,580 And inside of main, let's go ahead and do something simple. 2426 01:55:41,580 --> 01:55:43,670 Let's give ourselves a float called regular, 2427 01:55:43,670 --> 01:55:46,550 representing the regular price of something in a store. 2428 01:55:46,550 --> 01:55:49,310 Let's go ahead and get a float from the user asking them 2429 01:55:49,310 --> 01:55:51,680 what that regular price is. 2430 01:55:51,680 --> 01:55:55,940 Then, next, let's go ahead and declare a second variable-- also a float-- 2431 01:55:55,940 --> 01:55:59,150 called sale, ultimately representing the sale price 2432 01:55:59,150 --> 01:56:01,010 after some percentage discount off. 2433 01:56:01,010 --> 01:56:04,220 And let's go ahead and simply calculate whatever regular is. 2434 01:56:04,220 --> 01:56:07,050 And, say, 15% off is a pretty good discount. 2435 01:56:07,050 --> 01:56:11,670 So let's go ahead and discount regular, whatever it is, by 15%, 2436 01:56:11,670 --> 01:56:15,110 which is equivalent, of course, to multiplying it with the asterisk 2437 01:56:15,110 --> 01:56:16,880 by 0.85. 2438 01:56:16,880 --> 01:56:21,325 Of course, if we're taking off 15%, we multiply the regular price by 0.85. 2439 01:56:21,325 --> 01:56:23,450 Now, let's go ahead and print out the results here. 2440 01:56:23,450 --> 01:56:27,470 Let me go ahead and say printf sale price, colon-- 2441 01:56:27,470 --> 01:56:30,140 let me go ahead and %f, but, more specifically, 2442 01:56:30,140 --> 01:56:35,150 %.2f because, at least in US currency we typically show cents to two decimal 2443 01:56:35,150 --> 01:56:35,810 places-- 2444 01:56:35,810 --> 01:56:36,950 followed by a newline. 2445 01:56:36,950 --> 01:56:39,830 And then let me go ahead and plug in the value of sale. 2446 01:56:39,830 --> 01:56:43,430 All right, let's go down here and do make discount, Enter. 2447 01:56:43,430 --> 01:56:45,980 So far, so good-- ./discount. 2448 01:56:45,980 --> 01:56:48,200 And the regular price is maybe $100. 2449 01:56:48,200 --> 01:56:50,760 So the sale price should be $85. 2450 01:56:50,760 --> 01:56:52,682 So our arithmetic seems to be correct here. 2451 01:56:52,682 --> 01:56:54,140 But let's fast-forward now in time. 2452 01:56:54,140 --> 01:56:56,000 Suppose that we find ourselves discounting 2453 01:56:56,000 --> 01:56:58,927 a lot of prices in an application, maybe a website 2454 01:56:58,927 --> 01:57:01,760 like Amazon where they're offering some kind of percentage discount. 2455 01:57:01,760 --> 01:57:04,400 And it'd be nice to have a reusable function that 2456 01:57:04,400 --> 01:57:07,620 just does this arithmetic for us, simple though it may be. 2457 01:57:07,620 --> 01:57:09,710 So let's go ahead and modify discount this time 2458 01:57:09,710 --> 01:57:13,250 to give ourselves our own function called discount, 2459 01:57:13,250 --> 01:57:14,977 for instance, that takes an input-- 2460 01:57:14,977 --> 01:57:17,060 like the regular price that you want to discount-- 2461 01:57:17,060 --> 01:57:19,272 and then it also returns a value. 2462 01:57:19,272 --> 01:57:20,480 It doesn't just print it out. 2463 01:57:20,480 --> 01:57:25,280 It returns a value, namely, a float that represents what the sale price is. 2464 01:57:25,280 --> 01:57:28,430 So let me go down below main and go ahead 2465 01:57:28,430 --> 01:57:31,100 and define a function that's going to return a float, 2466 01:57:31,100 --> 01:57:33,317 because we're dealing with dollar amount still. 2467 01:57:33,317 --> 01:57:35,150 The function is going to be called discount. 2468 01:57:35,150 --> 01:57:39,170 And it's going to take one input, like the price that we want to discount. 2469 01:57:39,170 --> 01:57:41,370 In here, I'm going to do something very simple. 2470 01:57:41,370 --> 01:57:47,010 I'm going to say float sale equals whatever that price is times 0.85. 2471 01:57:47,010 --> 01:57:49,252 And then I'm going to go ahead and return sale. 2472 01:57:49,252 --> 01:57:51,710 Now, for that matter, I can actually tighten this up a bit. 2473 01:57:51,710 --> 01:57:55,280 If I'm only declaring a variable to store a value that I'm then 2474 01:57:55,280 --> 01:58:00,390 returning with this keyword return, I actually don't even need that variable. 2475 01:58:00,390 --> 01:58:02,240 So I can delete the second line. 2476 01:58:02,240 --> 01:58:04,880 And I can actually just go ahead and get rid of that variable 2477 01:58:04,880 --> 01:58:07,490 altogether and immediately return whatever the arithmetic 2478 01:58:07,490 --> 01:58:11,360 result is of taking the price input, the argument that's being passed in, 2479 01:58:11,360 --> 01:58:13,100 times 0.85. 2480 01:58:13,100 --> 01:58:16,880 So very simple function that simply does the discounting for me. 2481 01:58:16,880 --> 01:58:20,210 As always, let me go ahead and copy-paste-- 2482 01:58:20,210 --> 01:58:23,450 the only time it's OK to copy-paste-- the prototype of that function, so 2483 01:58:23,450 --> 01:58:26,540 the top of the file, so that when compiling this code, 2484 01:58:26,540 --> 01:58:29,810 main has already seen the word discount before. 2485 01:58:29,810 --> 01:58:31,470 And now let me go into the code here. 2486 01:58:31,470 --> 01:58:34,610 And instead of doing the math myself in main, 2487 01:58:34,610 --> 01:58:37,670 let me presume that we have some function already 2488 01:58:37,670 --> 01:58:41,990 in our toolkit called discount that lets me discount the regular price 2489 01:58:41,990 --> 01:58:44,045 and return that value. 2490 01:58:44,045 --> 01:58:46,170 And then down here, my code doesn't need to change. 2491 01:58:46,170 --> 01:58:49,400 I'm still going to print out sale the variable in which I'm 2492 01:58:49,400 --> 01:58:51,640 storing that result. But notice what I've done here. 2493 01:58:51,640 --> 01:58:53,390 I've sort of abstracted the way the notion 2494 01:58:53,390 --> 01:58:57,290 of taking a discount by creating my own function that takes a float called 2495 01:58:57,290 --> 01:58:59,150 price, or anything else as input. 2496 01:58:59,150 --> 01:59:01,640 It does a little bit of math, simple though it is here, 2497 01:59:01,640 --> 01:59:03,210 and then it returns a value. 2498 01:59:03,210 --> 01:59:06,140 But notice that discount is not printing that value. 2499 01:59:06,140 --> 01:59:08,390 It's literally using this other keyword called 2500 01:59:08,390 --> 01:59:13,010 return so that I can hand back that value, just like get_string hands 2501 01:59:13,010 --> 01:59:16,610 back a value, just like get_int back an integer without printing it 2502 01:59:16,610 --> 01:59:21,050 for you-- so that I up here on line 9 can go ahead and store 2503 01:59:21,050 --> 01:59:24,920 that value in a variable if I want and then actually print it out. 2504 01:59:24,920 --> 01:59:29,640 Let me go ahead now and recompile this code with make discount. 2505 01:59:29,640 --> 01:59:31,580 Let me go ahead and do ./discount. 2506 01:59:31,580 --> 01:59:34,240 And let's, again, do $100. 2507 01:59:34,240 --> 01:59:37,730 Sale price is going to be $85 as well. 2508 01:59:37,730 --> 01:59:41,920 Now, it turns out that functions don't have to take just 0 or 1 argument 2509 01:59:41,920 --> 01:59:42,460 as input. 2510 01:59:42,460 --> 01:59:44,440 They can actually take 2 or 3 or more. 2511 01:59:44,440 --> 01:59:48,400 So, in fact, suppose we wanted to now enhance this version of my program 2512 01:59:48,400 --> 01:59:52,600 and take in as input to the discount function, not just the price 2513 01:59:52,600 --> 01:59:55,090 that I want to discount but also the percentage off, 2514 01:59:55,090 --> 01:59:59,350 thereby allowing us to support not just 15% off but any number of percentage 2515 01:59:59,350 --> 02:00:00,070 points off. 2516 02:00:00,070 --> 02:00:04,810 Well, let me go up here and declare an int, say, and call it percent_off. 2517 02:00:04,810 --> 02:00:07,150 And let me ask the user for how many percentage 2518 02:00:07,150 --> 02:00:09,010 points they want to take off. 2519 02:00:09,010 --> 02:00:12,700 So I'm going to say percent_off inside of the prompt here, 2520 02:00:12,700 --> 02:00:14,950 get that int called percent_off. 2521 02:00:14,950 --> 02:00:18,070 And now in addition to passing in regular as an input 2522 02:00:18,070 --> 02:00:22,000 to the discount function, I'm also going to pass in percent_off. 2523 02:00:22,000 --> 02:00:26,020 But I need to tell the computer that it is taking now two arguments, 2524 02:00:26,020 --> 02:00:28,330 and the way I do this is just with a comma 2525 02:00:28,330 --> 02:00:30,580 down here in the function's own definition. 2526 02:00:30,580 --> 02:00:34,810 Here is going to be a percentage argument, a second argument, 2527 02:00:34,810 --> 02:00:35,710 per the comma. 2528 02:00:35,710 --> 02:00:41,290 And I'm now going to use that percentage in a slightly familiar way. 2529 02:00:41,290 --> 02:00:44,680 I don't want to just do percentage like this, because, of course, 2530 02:00:44,680 --> 02:00:47,943 that's going to increase the size of the total price. 2531 02:00:47,943 --> 02:00:50,860 I actually need to do a little bit of real-world math where if this is 2532 02:00:50,860 --> 02:00:54,580 a percentage off, like the number 15 for 15 percentage points, 2533 02:00:54,580 --> 02:00:57,790 I need to do 100 minus that many percentage points, 2534 02:00:57,790 --> 02:01:00,070 thereby giving me 100 minus 15-- 2535 02:01:00,070 --> 02:01:00,910 85. 2536 02:01:00,910 --> 02:01:04,330 And then I need to divide that by 100 in order now 2537 02:01:04,330 --> 02:01:09,230 to give myself 0.85 times the price that was passed in. 2538 02:01:09,230 --> 02:01:14,110 But if I go ahead now and save this, run, make discount one last time, 2539 02:01:14,110 --> 02:01:16,090 I notice that I've actually got an error here. 2540 02:01:16,090 --> 02:01:17,500 What have I done wrong? 2541 02:01:17,500 --> 02:01:19,420 Well, I need to change that prototype too. 2542 02:01:19,420 --> 02:01:21,918 And, again, this is admittedly an annoying aspect of C 2543 02:01:21,918 --> 02:01:23,710 that you have to maintain consistency here. 2544 02:01:23,710 --> 02:01:24,377 But that's fine. 2545 02:01:24,377 --> 02:01:26,590 I'm just going to go up here, change this to int 2546 02:01:26,590 --> 02:01:28,840 percentage-- spelling incorrectly. 2547 02:01:28,840 --> 02:01:31,780 And now let me retry compilation, make discount, 2548 02:01:31,780 --> 02:01:33,310 crossing my fingers this time. 2549 02:01:33,310 --> 02:01:37,900 Worked OK. ./discount, and voila, $100. 2550 02:01:37,900 --> 02:01:40,420 And percent off, say, 15 points. 2551 02:01:40,420 --> 02:01:44,180 And, voila, $85. 2552 02:01:44,180 --> 02:01:46,510 Now, it's worth noting that I've deliberately 2553 02:01:46,510 --> 02:01:49,600 returned the results of my math from this function. 2554 02:01:49,600 --> 02:01:52,990 I haven't just done the math on the original variable that's being passed. 2555 02:01:52,990 --> 02:01:55,150 In fact, if we take a look at this second version 2556 02:01:55,150 --> 02:01:58,970 where discount is now taking a price argument and a percentage argument, 2557 02:01:58,970 --> 02:02:01,240 notice that I'm not doing something like this. 2558 02:02:01,240 --> 02:02:05,620 I'm not just saying price equals price times 100 2559 02:02:05,620 --> 02:02:09,460 minus percentage divided by 100 and leaving at that. 2560 02:02:09,460 --> 02:02:13,150 The problem there is that this variable price is going 2561 02:02:13,150 --> 02:02:15,490 to be scoped to that discount function. 2562 02:02:15,490 --> 02:02:18,430 And we'll encounter this again before long, but this notion of scope 2563 02:02:18,430 --> 02:02:23,290 just refers to where in which a variable actually lives or exists 2564 02:02:23,290 --> 02:02:24,410 or is accessible. 2565 02:02:24,410 --> 02:02:27,400 So it turns out if I change price in the context of this discount 2566 02:02:27,400 --> 02:02:29,800 function, that's not going to have a lasting effect. 2567 02:02:29,800 --> 02:02:31,510 If I actually want to get the result back 2568 02:02:31,510 --> 02:02:34,960 to the function that used the discount function, namely, main, 2569 02:02:34,960 --> 02:02:38,200 I actually do need to take this approach of actually returning 2570 02:02:38,200 --> 02:02:42,920 the value explicitly so that ultimately I'm handing back the discounted price. 2571 02:02:42,920 --> 02:02:43,420 All right. 2572 02:02:43,420 --> 02:02:45,545 Well, let's go ahead and maybe how about let's just 2573 02:02:45,545 --> 02:02:49,000 use these primitives in just a few different ways. 2574 02:02:49,000 --> 02:02:53,500 How about a little game of yesteryear, Super Mario Brothers? 2575 02:02:53,500 --> 02:02:56,860 And in the original Super Mario Brothers and in bunches of variants, 2576 02:02:56,860 --> 02:02:59,260 so you have these side-scrolling worlds that 2577 02:02:59,260 --> 02:03:02,670 look like this where there's some coins in the sky hidden behind these question 2578 02:03:02,670 --> 02:03:03,170 marks. 2579 02:03:03,170 --> 02:03:06,430 So let's just use this as a visual to consider how in C could 2580 02:03:06,430 --> 02:03:08,260 I start to make something semi-graphical. 2581 02:03:08,260 --> 02:03:11,470 Like, not actual colors or fanciness, that feels like too much too soon-- 2582 02:03:11,470 --> 02:03:14,210 just something like printing out some question marks. 2583 02:03:14,210 --> 02:03:17,230 Well, if I go back over here, let me create that actual file 2584 02:03:17,230 --> 02:03:18,620 that I alluded to earlier. 2585 02:03:18,620 --> 02:03:21,490 So let me code up mario.c. 2586 02:03:21,490 --> 02:03:25,390 Let me go ahead and include stdio.h, int main void, again, 2587 02:03:25,390 --> 02:03:27,520 which we'll continue to copy-paste for today. 2588 02:03:27,520 --> 02:03:31,630 And then let me just go ahead and do something simple like 1, 2, 3, 4, 2589 02:03:31,630 --> 02:03:32,620 and a newline. 2590 02:03:32,620 --> 02:03:35,808 All right, this is what we might call ASCII art, which 2591 02:03:35,808 --> 02:03:38,600 just means graphics but really just implemented with your keyboard. 2592 02:03:38,600 --> 02:03:43,330 And if I make mario and do ./mario, it's not nearly as engaging visually 2593 02:03:43,330 --> 02:03:47,110 as this, but it's the beginning of this kind of map for a game. 2594 02:03:47,110 --> 02:03:51,250 Well, if I wanted to now print out of those things dynamically, 2595 02:03:51,250 --> 02:03:52,930 let me go back to my code here. 2596 02:03:52,930 --> 02:03:55,030 And instead of printing out for all at once, 2597 02:03:55,030 --> 02:03:59,650 I could do something like four int i gets 0, i less than 4, i plus plus. 2598 02:03:59,650 --> 02:04:04,430 And then inside here, I could just print out one of them at a time. 2599 02:04:04,430 --> 02:04:07,090 Let me save that, make mario. 2600 02:04:07,090 --> 02:04:11,830 And, at the risk of disappointing, so close 2601 02:04:11,830 --> 02:04:15,000 but I made a mistake, just a stupid aesthetic. 2602 02:04:15,000 --> 02:04:17,170 The prompt is not on the new line. 2603 02:04:17,170 --> 02:04:18,675 How could I move it? 2604 02:04:18,675 --> 02:04:20,260 AUDIENCE: [INAUDIBLE] 2605 02:04:20,260 --> 02:04:23,010 DAVID J. MALAN: Yeah, I need an escape character, the backslash n. 2606 02:04:23,010 --> 02:04:26,740 But should I put it here? 2607 02:04:26,740 --> 02:04:28,990 OK, no, because that's going to put it after everyone, 2608 02:04:28,990 --> 02:04:31,698 and it's going to make this thing vertical instead of horizontal. 2609 02:04:31,698 --> 02:04:35,230 So, logically, just like in Scratch, put it at the end of the loop, so something 2610 02:04:35,230 --> 02:04:35,950 out here. 2611 02:04:35,950 --> 02:04:39,500 And just print out, for instance, only, quote unquote, new line. 2612 02:04:39,500 --> 02:04:42,550 And now if I do make mario again, ./mario, OK. 2613 02:04:42,550 --> 02:04:43,537 We're back in business. 2614 02:04:43,537 --> 02:04:45,370 But a little better designed in that now I'm 2615 02:04:45,370 --> 02:04:48,590 not repeating myself multiple times, I'm doing this again and again. 2616 02:04:48,590 --> 02:04:51,910 But let's do one other thing here with mario. 2617 02:04:51,910 --> 02:04:57,160 Let me go ahead and ask the user how many question marks or coins to print. 2618 02:04:57,160 --> 02:05:00,910 The catch here is that there's another type of loop that's helpful for this, 2619 02:05:00,910 --> 02:05:03,370 and it's called a do while loop, generally. 2620 02:05:03,370 --> 02:05:06,910 A do while loop is similar to a while loop, 2621 02:05:06,910 --> 02:05:10,420 but it checks the condition last instead of first. 2622 02:05:10,420 --> 02:05:12,238 Recall earlier on the slide, we had while, 2623 02:05:12,238 --> 02:05:13,780 open parenthesis, closed parenthesis. 2624 02:05:13,780 --> 02:05:17,140 And I kept claiming that we check whether i is less than-- whatever 2625 02:05:17,140 --> 02:05:20,270 it was, 3 in advance again and again. 2626 02:05:20,270 --> 02:05:23,830 A do while loop just inverts the logic so that you can actually 2627 02:05:23,830 --> 02:05:25,240 do something like this. 2628 02:05:25,240 --> 02:05:27,580 At the top of this program, I'm going to go ahead now 2629 02:05:27,580 --> 02:05:31,660 and give myself a variable n like this of type integer. 2630 02:05:31,660 --> 02:05:36,070 And then I'm going to do, literally, the following with the keyword do. 2631 02:05:36,070 --> 02:05:39,790 n equals get_int-- and I'm going to ask the user for the width, 2632 02:05:39,790 --> 02:05:42,640 like the number of dollar signs to print. 2633 02:05:42,640 --> 02:05:47,230 And I'm going to do this while n is less than, say, 1. 2634 02:05:47,230 --> 02:05:50,230 So this is a little cryptic, but the salient differences 2635 02:05:50,230 --> 02:05:55,390 are the Boolean expression is now at the bottom of my block of code, 2636 02:05:55,390 --> 02:05:57,100 not at the top. 2637 02:05:57,100 --> 02:05:58,580 Now, why is this? 2638 02:05:58,580 --> 02:06:02,590 Well, the difference here if I make mario is-- 2639 02:06:02,590 --> 02:06:04,090 whoops. 2640 02:06:04,090 --> 02:06:07,820 I need to add cs50.h, because I'm now using get_int. 2641 02:06:07,820 --> 02:06:13,250 If I now compile this version of Mario and do ./mario, 2642 02:06:13,250 --> 02:06:17,840 a do while loop is helpful when you want to do something no matter what first 2643 02:06:17,840 --> 02:06:22,130 and then check some condition or some Boolean expression to see if maybe, 2644 02:06:22,130 --> 02:06:23,660 in this case, the user cooperated. 2645 02:06:23,660 --> 02:06:26,972 It would make no sense if the user typed in, say, 0, 2646 02:06:26,972 --> 02:06:28,430 because there's no work to be done. 2647 02:06:28,430 --> 02:06:30,650 It'd be really weird if they said negative 100, 2648 02:06:30,650 --> 02:06:32,420 because that makes no sense logically. 2649 02:06:32,420 --> 02:06:37,460 So with this simple construct here, I am doing the following 2650 02:06:37,460 --> 02:06:40,010 while n is less than 1. 2651 02:06:40,010 --> 02:06:44,277 The implication is that as soon as n equals 1 or is bigger than 1, 2652 02:06:44,277 --> 02:06:46,610 I'm going to break out of this loop, and I've got myself 2653 02:06:46,610 --> 02:06:51,830 a variable called n containing, essentially, a positive value, 1 2654 02:06:51,830 --> 02:06:54,410 through 2 billion or so. 2655 02:06:54,410 --> 02:06:58,520 And I can now use this, for instance, here, change the 4 to an n 2656 02:06:58,520 --> 02:07:01,010 so now my program is completely dynamic. 2657 02:07:01,010 --> 02:07:04,910 Let me go ahead and do make mario, ./mario again. 2658 02:07:04,910 --> 02:07:07,070 And I'll do 4, still works. 2659 02:07:07,070 --> 02:07:09,950 I'll do 40, still works. 2660 02:07:09,950 --> 02:07:13,340 And the difference here with the do while is if something like this 2661 02:07:13,340 --> 02:07:16,520 involves getting user input, well, there's no question to ask. 2662 02:07:16,520 --> 02:07:18,360 The user hasn't given you anything yet. 2663 02:07:18,360 --> 02:07:22,310 So you have to do something first, then check, and break out of the loop 2664 02:07:22,310 --> 02:07:27,007 if the human has, for instance, cooperated, in this case. 2665 02:07:27,007 --> 02:07:29,090 All right, well why don't we escalate to something 2666 02:07:29,090 --> 02:07:33,140 more like this in the same game, where you're underground as Mario, 2667 02:07:33,140 --> 02:07:36,680 and this is like a two-dimensional wall that's popping up here? 2668 02:07:36,680 --> 02:07:39,680 It looks like a 3 by 3, for instance, for the sake of discussion. 2669 02:07:39,680 --> 02:07:43,130 And it's like, made of bricks, so I'll use maybe hash symbols this time. 2670 02:07:43,130 --> 02:07:44,960 Well, it turns out that we can nest-- 2671 02:07:44,960 --> 02:07:48,510 that is, combine-- some of these same ideas as follows. 2672 02:07:48,510 --> 02:07:52,310 Let me go ahead now and change back to this code. 2673 02:07:52,310 --> 02:07:56,700 And I'm going to keep the do while loop from before. 2674 02:07:56,700 --> 02:07:58,640 And I'm going to ask, though, this question, 2675 02:07:58,640 --> 02:08:00,290 what's the size of this square? 2676 02:08:00,290 --> 02:08:05,040 I'm going to assume it's n by n, so 3 by 3, 4 by 4, whatever. 2677 02:08:05,040 --> 02:08:07,820 So I'm just going to ask for the size of this square of bricks. 2678 02:08:07,820 --> 02:08:09,573 And now, how do I do this? 2679 02:08:09,573 --> 02:08:11,990 Well, I'm going to go ahead, for instance, and print out-- 2680 02:08:11,990 --> 02:08:17,107 how about for int i = 0, i less than n, i++. 2681 02:08:17,107 --> 02:08:19,190 Let me just keep it simple and print out something 2682 02:08:19,190 --> 02:08:23,990 like this, just a single hash symbol that is a brick, 2683 02:08:23,990 --> 02:08:26,000 and a newline after it. 2684 02:08:26,000 --> 02:08:27,470 All right, let's make mario. 2685 02:08:27,470 --> 02:08:29,600 Run mario of 3. 2686 02:08:29,600 --> 02:08:31,520 OK, that's close to being it. 2687 02:08:31,520 --> 02:08:32,630 I've got a column. 2688 02:08:32,630 --> 02:08:34,380 All right, but I need it to be wider. 2689 02:08:34,380 --> 02:08:36,950 So the solution last time was to get rid of the newline 2690 02:08:36,950 --> 02:08:41,120 and then maybe put the newline here, after the loop. 2691 02:08:41,120 --> 02:08:47,150 All right, so let's do make mario, ./mario, and type in 3 and huh. 2692 02:08:47,150 --> 02:08:51,680 All right, so I kind of need to combine these two ideas somehow. 2693 02:08:51,680 --> 02:08:55,550 So how might we solve this problem? 2694 02:08:55,550 --> 02:09:01,790 I want to print rows and columns, not row or column. 2695 02:09:01,790 --> 02:09:03,320 How do I do this? 2696 02:09:03,320 --> 02:09:03,830 Yeah. 2697 02:09:03,830 --> 02:09:06,215 AUDIENCE: Add another loop in the for loop. 2698 02:09:06,215 --> 02:09:07,090 DAVID J. MALAN: Yeah. 2699 02:09:07,090 --> 02:09:08,770 Add another loop in the for loop, right? 2700 02:09:08,770 --> 02:09:13,090 If you use one loop conceptually to kind of count the rows from top 2701 02:09:13,090 --> 02:09:15,670 to bottom, and then within each row, you then 2702 02:09:15,670 --> 02:09:18,070 sort of typewriter style-- old school typewriter-- 2703 02:09:18,070 --> 02:09:21,220 do like, character, character, character, character horizontally, 2704 02:09:21,220 --> 02:09:23,720 I think we could do exactly what we want to achieve here. 2705 02:09:23,720 --> 02:09:24,620 So how about this? 2706 02:09:24,620 --> 02:09:27,640 Let me get rid of this line and get rid of this line for now. 2707 02:09:27,640 --> 02:09:30,400 And let me just give myself another loop on the inside. 2708 02:09:30,400 --> 02:09:34,120 And since I'm already using i, another reasonable convention 2709 02:09:34,120 --> 02:09:36,220 here would be to say something like j. 2710 02:09:36,220 --> 02:09:40,510 So j also gets 0, j is less than n, j++. 2711 02:09:40,510 --> 02:09:42,820 And now, what's going to happen? 2712 02:09:42,820 --> 02:09:47,380 Let me go ahead and print out just one of these things at a time. 2713 02:09:47,380 --> 02:09:49,640 And let me save and let me run this. 2714 02:09:49,640 --> 02:09:51,190 Let me see how close we are. 2715 02:09:51,190 --> 02:09:53,170 Make mario 3. 2716 02:09:53,170 --> 02:09:57,620 OK, three, that's clearly wrong, but I see nine things there on the screen. 2717 02:09:57,620 --> 02:09:58,780 So we're close. 2718 02:09:58,780 --> 02:10:04,090 What's the one fix I need now to move the old school typewriter head 2719 02:10:04,090 --> 02:10:06,400 down to the next row when appropriate? 2720 02:10:06,400 --> 02:10:08,340 What do you think? 2721 02:10:08,340 --> 02:10:10,290 Yeah, I need one of these backslash n's. 2722 02:10:10,290 --> 02:10:15,120 And let me add some comments now to help everyone visualize what I've done. 2723 02:10:15,120 --> 02:10:22,170 For each row, for each column, how about print a brick-- 2724 02:10:22,170 --> 02:10:24,300 just to kind of explain the logic? 2725 02:10:24,300 --> 02:10:29,010 And so I add that because now move to next row, 2726 02:10:29,010 --> 02:10:31,590 I could do something like this with a backslash n. 2727 02:10:31,590 --> 02:10:34,950 So here is where the comments, really, my pseudocode 2728 02:10:34,950 --> 02:10:37,930 actually kind of illuminates the situation a bit. 2729 02:10:37,930 --> 02:10:42,553 Let me go ahead and recompile mario, ./mario 3, now we're talking. 2730 02:10:42,553 --> 02:10:44,970 It's not a perfect square, just because these hash symbols 2731 02:10:44,970 --> 02:10:48,750 are a little taller than they are wide, but that's just a font detail here. 2732 02:10:48,750 --> 02:10:54,950 Now I've done something that's quite more akin to something like this. 2733 02:10:54,950 --> 02:10:59,443 All right, so let me pause here and see if there are any questions. 2734 02:10:59,443 --> 02:11:01,610 Again, the code's getting a little more complicated, 2735 02:11:01,610 --> 02:11:05,315 but we're just building more complicated programs like in Scratch, 2736 02:11:05,315 --> 02:11:07,190 with familiar puzzle pieces-- some variables, 2737 02:11:07,190 --> 02:11:08,540 some loops, some conditionals. 2738 02:11:08,540 --> 02:11:10,610 It's all the same as before. 2739 02:11:10,610 --> 02:11:12,080 Yeah. 2740 02:11:12,080 --> 02:11:13,340 Can you multiply strings in C? 2741 02:11:13,340 --> 02:11:14,090 No. 2742 02:11:14,090 --> 02:11:17,007 But ask that same question again in a few weeks when we get to Python, 2743 02:11:17,007 --> 02:11:18,973 and the answer will be yes. 2744 02:11:18,973 --> 02:11:19,640 Other questions. 2745 02:11:19,640 --> 02:11:21,080 Yeah. 2746 02:11:21,080 --> 02:11:23,720 In C, you must specify the return type, the name 2747 02:11:23,720 --> 02:11:25,780 of the function, and the inputs, or arguments, 2748 02:11:25,780 --> 02:11:27,030 to the function in that order. 2749 02:11:27,030 --> 02:11:30,380 And if none of them are applicable, you write the word void. 2750 02:11:30,380 --> 02:11:33,260 So same question as earlier, let me kick that can a week or so, 2751 02:11:33,260 --> 02:11:35,460 and we'll come back to that and we'll see why. 2752 02:11:35,460 --> 02:11:38,480 But for now, just take on faith that you need to do that with main. 2753 02:11:38,480 --> 02:11:40,850 Because main is a little special, similar to the 2754 02:11:40,850 --> 02:11:42,230 when green flag is clicked. 2755 02:11:42,230 --> 02:11:45,470 It too was a little special as well. 2756 02:11:45,470 --> 02:11:46,448 Yeah 2757 02:11:46,448 --> 02:11:52,777 AUDIENCE: [INAUDIBLE] 2758 02:11:52,777 --> 02:11:53,610 DAVID J. MALAN: Yes. 2759 02:11:53,610 --> 02:11:57,160 If you want to get out of a loop early, you could do this. 2760 02:11:57,160 --> 02:11:59,520 So let me answer this question this way. 2761 02:11:59,520 --> 02:12:05,590 An alternative to a do while loop would be to do something like this. 2762 02:12:05,590 --> 02:12:07,080 How about while true-- 2763 02:12:07,080 --> 02:12:09,490 so do the following forever-- 2764 02:12:09,490 --> 02:12:14,670 let me go ahead and get an inch from the user for the size of this thing. 2765 02:12:14,670 --> 02:12:17,970 If n is greater than 0-- 2766 02:12:17,970 --> 02:12:19,810 that is, a positive integer-- 2767 02:12:19,810 --> 02:12:23,610 then go ahead and use a new keyword called break. 2768 02:12:23,610 --> 02:12:26,890 This is identical to what we just did. 2769 02:12:26,890 --> 02:12:28,330 It's just a little longer. 2770 02:12:28,330 --> 02:12:30,870 It's like a couple extra lines, a lot of them are blank. 2771 02:12:30,870 --> 02:12:32,310 And so it's just an alternative. 2772 02:12:32,310 --> 02:12:35,055 But a do while does the same thing but a little tighter-- 2773 02:12:35,055 --> 02:12:38,200 if that's in answer to your question. 2774 02:12:38,200 --> 02:12:42,633 All right, so let's now introduce, finally, a sequence of problems 2775 02:12:42,633 --> 02:12:44,550 that I've kind of been brushing under the rug, 2776 02:12:44,550 --> 02:12:46,980 though we did see a little bit of evidence of this earlier 2777 02:12:46,980 --> 02:12:49,080 when we tried to add 2 billion and 2 billion, 2778 02:12:49,080 --> 02:12:53,380 and it overflowed the number of bits in an int, so to speak. 2779 02:12:53,380 --> 02:12:57,630 Let me go ahead and code up a program called calculator again. 2780 02:12:57,630 --> 02:13:00,420 But I'm going to go ahead now and change this to floats. 2781 02:13:00,420 --> 02:13:04,020 So I'm going to change x to a float, and I'm going to use get_float. 2782 02:13:04,020 --> 02:13:06,850 And a float, again, is just a floating point value, 2783 02:13:06,850 --> 02:13:10,270 which is a fancy way of saying a real number with a decimal point in it. 2784 02:13:10,270 --> 02:13:13,680 And down here, I'm going to go ahead and use %f for float. 2785 02:13:13,680 --> 02:13:16,050 And I'm going to go ahead now and do one more thing. 2786 02:13:16,050 --> 02:13:18,842 Instead of addition, I want to do something fancier, like division, 2787 02:13:18,842 --> 02:13:20,700 so divide x by y. 2788 02:13:20,700 --> 02:13:23,250 And I'm going to give myself another third float called z, 2789 02:13:23,250 --> 02:13:24,930 as we did at the beginning of today. 2790 02:13:24,930 --> 02:13:28,530 And I'm going to print out z instead of x and y explicitly. 2791 02:13:28,530 --> 02:13:33,210 So I'm going to go ahead now and do make calculator, ./calculator. 2792 02:13:33,210 --> 02:13:35,520 And let's do something like, oh, 2/3. 2793 02:13:35,520 --> 02:13:38,910 2 divided by 3 is 0.66667. 2794 02:13:38,910 --> 02:13:40,800 So that's what you would rather expect. 2795 02:13:40,800 --> 02:13:43,510 Let me run it again, 1/10. 2796 02:13:43,510 --> 02:13:45,700 All right, so 0.1, and a bunch of zeros. 2797 02:13:45,700 --> 02:13:47,720 That too is what you would rather expect. 2798 02:13:47,720 --> 02:13:49,390 But now let me get a little curious. 2799 02:13:49,390 --> 02:13:53,470 It turns out that in C, you can modify the behavior of these format 2800 02:13:53,470 --> 02:13:54,430 codes a little bit. 2801 02:13:54,430 --> 02:13:56,590 By default, you get 6 or so digits. 2802 02:13:56,590 --> 02:13:59,050 Suppose that you want to get exactly 2 digits. 2803 02:13:59,050 --> 02:14:03,015 You can more succinctly say 0.2 before the f and after the percent. 2804 02:14:03,015 --> 02:14:05,890 This is the kind of thing that's hard to remember, but you Google it, 2805 02:14:05,890 --> 02:14:08,110 and you find that, OK, format code for floats 2806 02:14:08,110 --> 02:14:10,730 uses 0.2 to do two decimal points. 2807 02:14:10,730 --> 02:14:14,260 So let me do make calculator again, ./calculator. 2808 02:14:14,260 --> 02:14:15,610 How about 2/3? 2809 02:14:15,610 --> 02:14:16,700 0.67. 2810 02:14:16,700 --> 02:14:19,690 So it handles the display of significant digits for us here. 2811 02:14:19,690 --> 02:14:23,380 And now let me go ahead and do 1/10 and 0.10. 2812 02:14:23,380 --> 02:14:24,693 So it's adhering to that. 2813 02:14:24,693 --> 02:14:26,860 Well, maybe I really want a lot of precision, right? 2814 02:14:26,860 --> 02:14:28,360 I've got a really powerful computer. 2815 02:14:28,360 --> 02:14:30,880 Let me see 50 numbers after the decimal point. 2816 02:14:30,880 --> 02:14:32,750 That's a lot of significant digits. 2817 02:14:32,750 --> 02:14:35,540 Let me remake the calculator-- whoops, typo. 2818 02:14:35,540 --> 02:14:40,180 Let me remake the calculator, ./mario calculator. 2819 02:14:40,180 --> 02:14:42,930 And how about 2/3 again? 2820 02:14:42,930 --> 02:14:45,600 Well, that's interesting. 2821 02:14:45,600 --> 02:14:49,590 Pretty sure it's supposed to be a 0.6 with a line over it, right? 2822 02:14:49,590 --> 02:14:50,730 In grade school math. 2823 02:14:50,730 --> 02:14:52,438 All right, well, maybe that's just a bug. 2824 02:14:52,438 --> 02:14:53,490 How about 1/10? 2825 02:14:53,490 --> 02:14:56,250 OK, that's really getting funky. 2826 02:14:56,250 --> 02:14:57,600 So what's going on? 2827 02:14:57,600 --> 02:15:01,647 It seems that my program cannot only not do addition very well-- 2828 02:15:01,647 --> 02:15:03,480 we eventually hit problems in the billions-- 2829 02:15:03,480 --> 02:15:08,060 we can't even do very precise numbers here. 2830 02:15:08,060 --> 02:15:10,520 What's going on? 2831 02:15:10,520 --> 02:15:11,060 Exactly. 2832 02:15:11,060 --> 02:15:13,400 In a nutshell, the computer's approximating the answer 2833 02:15:13,400 --> 02:15:16,342 using that many numbers after the decimal point. 2834 02:15:16,342 --> 02:15:18,050 But the problem fundamentally is actually 2835 02:15:18,050 --> 02:15:21,300 very similar to that integer overflow from before. 2836 02:15:21,300 --> 02:15:23,000 And I'm using that now as a term of art. 2837 02:15:23,000 --> 02:15:27,410 Integers can overflow if you're trying to use more bits than you actually 2838 02:15:27,410 --> 02:15:28,327 have available to you. 2839 02:15:28,327 --> 02:15:31,577 You sort of change them all to ones, and then you're out of bits, so to speak. 2840 02:15:31,577 --> 02:15:33,960 Same thing here, but in the different context of floats-- 2841 02:15:33,960 --> 02:15:36,260 if you only have 32 bits-- or, heck, if we 2842 02:15:36,260 --> 02:15:39,920 change to double and only have 64 bits, that's a lot of precision, 2843 02:15:39,920 --> 02:15:41,270 but it's not infinite. 2844 02:15:41,270 --> 02:15:45,270 And, yet, pretty sure there's an infinite number of real numbers. 2845 02:15:45,270 --> 02:15:50,240 In the world, which is to say a computer with finite memory cannot possibly 2846 02:15:50,240 --> 02:15:52,613 represent all possible numbers in the world. 2847 02:15:52,613 --> 02:15:54,530 Because, again, there's not an infinite number 2848 02:15:54,530 --> 02:15:57,770 of permutations of 32 or 64 bits. 2849 02:15:57,770 --> 02:16:01,550 It might be a lot, in the billions or more, but it's still finite. 2850 02:16:01,550 --> 02:16:04,970 And so, indeed, this is the computer's closest approximation 2851 02:16:04,970 --> 02:16:07,170 to what's actually going on there. 2852 02:16:07,170 --> 02:16:10,190 And so this is an example of what we would actually generally call 2853 02:16:10,190 --> 02:16:12,200 floating-point imprecision. 2854 02:16:12,200 --> 02:16:17,540 Floating-point imprecision refers to the inability for computers fundamentally 2855 02:16:17,540 --> 02:16:20,540 to represent all possible real numbers 100% 2856 02:16:20,540 --> 02:16:24,317 precisely, at least by default in languages like C. Thankfully, 2857 02:16:24,317 --> 02:16:26,400 in the world of scientific computing and so forth, 2858 02:16:26,400 --> 02:16:30,020 there are solutions to this problem that just give you more digits. 2859 02:16:30,020 --> 02:16:33,270 But the problem fundamentally is still going to be there. 2860 02:16:33,270 --> 02:16:35,990 So there's a reason I changed x and y to floats. 2861 02:16:35,990 --> 02:16:38,250 Let's see what would happen if we rewound a bit. 2862 02:16:38,250 --> 02:16:43,700 And instead of using floats for x and y, again, you say integer, so int x and y. 2863 02:16:43,700 --> 02:16:47,360 And let's go far back and use get_int as well, 2864 02:16:47,360 --> 02:16:50,337 thereby giving us integers x and y. 2865 02:16:50,337 --> 02:16:52,920 Let's still leave z as a float, because at the end of the day, 2866 02:16:52,920 --> 02:16:55,640 we want to be able to handle fractions or floating-point values. 2867 02:16:55,640 --> 02:16:58,580 But let's go ahead now and print out this value of z 2868 02:16:58,580 --> 02:17:00,920 having changed x and y now to ints. 2869 02:17:00,920 --> 02:17:06,590 make calculator, ./calculator, and let's do, say, 2 for the numerator, 2870 02:17:06,590 --> 02:17:07,910 3 for the denominator. 2871 02:17:07,910 --> 02:17:13,160 And it's not 0.666, and it's not even rounding oddly. 2872 02:17:13,160 --> 02:17:14,960 It's just all zeros this time. 2873 02:17:14,960 --> 02:17:16,170 So why is that? 2874 02:17:16,170 --> 02:17:19,970 Well, it turns out that C, when dividing an integer by an integer, 2875 02:17:19,970 --> 02:17:22,970 is always going to give you back an integer, an int. 2876 02:17:22,970 --> 02:17:26,150 The problem is that floating-point values don't fit in ints. 2877 02:17:26,150 --> 02:17:28,850 Only the integral part to the left of the decimal point does. 2878 02:17:28,850 --> 02:17:32,690 Everything at and beyond the decimal point itself get thrown away, 2879 02:17:32,690 --> 02:17:35,480 known as a feature in C called truncation. 2880 02:17:35,480 --> 02:17:38,790 When dividing an integer by an integer, you get back an integer. 2881 02:17:38,790 --> 02:17:42,380 But if you're trying to then store what's actually a floating point 2882 02:17:42,380 --> 02:17:45,830 result in that integer, C is just going to throw away everything 2883 02:17:45,830 --> 02:17:48,620 at and beyond the decimal point, leaving us with this case, 2884 02:17:48,620 --> 02:17:54,720 in just the 0 from what should have been 0.666666 and so forth. 2885 02:17:54,720 --> 02:17:56,429 So let's see one more example, in fact. 2886 02:17:56,429 --> 02:17:58,040 Let me go back to my terminal here. 2887 02:17:58,040 --> 02:17:59,750 Let me do ./calculator again. 2888 02:17:59,750 --> 02:18:00,950 And let's do 4/3. 2889 02:18:00,950 --> 02:18:04,950 This time, It should be 1.33333 and so forth. 2890 02:18:04,950 --> 02:18:11,929 But let's see, 4 divided by 3, both as integers, this time gives us 1.0000, 2891 02:18:11,929 --> 02:18:14,960 but there too the answer should be 1.333. 2892 02:18:14,960 --> 02:18:19,070 But the floating-point part is getting truncated or thrown away, 2893 02:18:19,070 --> 02:18:20,370 leaving us with just 1. 2894 02:18:20,370 --> 02:18:21,570 So how do we solve this? 2895 02:18:21,570 --> 02:18:25,170 Well, certainly, we could just use floats from the get-go, as I did. 2896 02:18:25,170 --> 02:18:28,790 But if, by nature of your program, you only have access to integers-- 2897 02:18:28,790 --> 02:18:32,000 or maybe even longs, for which the same problem would occur-- 2898 02:18:32,000 --> 02:18:35,269 what we can actually do is called type conversion. 2899 02:18:35,269 --> 02:18:38,240 And we can explicitly tell the computer that we actually 2900 02:18:38,240 --> 02:18:41,429 want to treat this int as though it's a floating-point value. 2901 02:18:41,429 --> 02:18:43,220 And we can do that for both x and y. 2902 02:18:43,220 --> 02:18:47,070 So let me go back to my code here, and I have a couple of options, in fact. 2903 02:18:47,070 --> 02:18:52,460 I can convert y to a float by doing this, I can cast y to a float 2904 02:18:52,460 --> 02:18:55,460 by literally writing the type float inside of parentheses 2905 02:18:55,460 --> 02:18:56,630 right before the y. 2906 02:18:56,630 --> 02:19:00,080 And if I really want to be explicit, I can also do the same to x. 2907 02:19:00,080 --> 02:19:03,990 But, strictly speaking, it suffices to just change one or the other, 2908 02:19:03,990 --> 02:19:05,269 not necessarily both. 2909 02:19:05,269 --> 02:19:10,310 Let me go ahead now and do make calculator again, ./calculator, 2910 02:19:10,310 --> 02:19:13,099 and let's try 2 divided by 3. 2911 02:19:13,099 --> 02:19:16,339 And now, we're back to an answer that's closer to correct. 2912 02:19:16,339 --> 02:19:19,040 But, indeed, we're still having some rounding issues there. 2913 02:19:19,040 --> 02:19:22,820 Let's run it one more time for 4 divided by 3. 2914 02:19:22,820 --> 02:19:25,189 There too we're closer to the right answer, at least. 2915 02:19:25,189 --> 02:19:27,650 But we still have that floating-point imprecision, 2916 02:19:27,650 --> 02:19:30,500 but that's going to be another problem altogether to solve. 2917 02:19:30,500 --> 02:19:32,420 And here in a little more detail is that issue 2918 02:19:32,420 --> 02:19:35,599 of integer overflow, which is in the context of ints. 2919 02:19:35,599 --> 02:19:39,589 Suppose that we think back to last week when we had three bits, 2920 02:19:39,589 --> 02:19:45,170 and we counted from 0 to 7, 0, 1, 2, 3, 4, 5, 6, 7. 2921 02:19:45,170 --> 02:19:47,420 I think I asked the question, how would we count to 8? 2922 02:19:47,420 --> 02:19:49,490 Someone proposed, well, we need a fourth bit. 2923 02:19:49,490 --> 02:19:52,759 That's fine if you have a fourth bit, if you have access 2924 02:19:52,759 --> 02:19:54,679 to another light bulb or transistor. 2925 02:19:54,679 --> 02:20:00,439 If you don't, though, the next number after this is technically 1000. 2926 02:20:00,439 --> 02:20:04,310 But if you don't have space for or hardware for that fourth bit, 2927 02:20:04,310 --> 02:20:07,540 you might as well just be representing the number 0. 2928 02:20:07,540 --> 02:20:10,839 So in the world of integers, if you're only using three bits, 2929 02:20:10,839 --> 02:20:14,560 those three bits eventually overflow when you count past 7. 2930 02:20:14,560 --> 02:20:19,210 Because what should be 8 can't fit, so to speak, so it rolls back over to 0. 2931 02:20:19,210 --> 02:20:22,040 And as arcane as this problem might seem, 2932 02:20:22,040 --> 02:20:24,250 we humans have done this a couple of times. 2933 02:20:24,250 --> 02:20:26,527 You might recall knowing about or reading 2934 02:20:26,527 --> 02:20:28,360 about the Y2K problem, where a lot of people 2935 02:20:28,360 --> 02:20:29,660 thought the world was going to end. 2936 02:20:29,660 --> 02:20:30,160 Why? 2937 02:20:30,160 --> 02:20:35,110 Because on January 1st of 2000, a lot of computers, 2938 02:20:35,110 --> 02:20:39,700 presumably, were going to update their clocks from 1999 to the year 2000. 2939 02:20:39,700 --> 02:20:43,030 The problem is, though, for decades, for efficiency, we humans 2940 02:20:43,030 --> 02:20:45,910 were honestly in the habit of not storing years as four digits. 2941 02:20:45,910 --> 02:20:46,432 Why? 2942 02:20:46,432 --> 02:20:49,390 Because that's just a lot of space to waste, especially since centuries 2943 02:20:49,390 --> 02:20:50,660 don't happen that often. 2944 02:20:50,660 --> 02:20:53,740 So a lot of computer systems, especially early on when 2945 02:20:53,740 --> 02:20:56,980 hardware was very expensive and memory was very tight, 2946 02:20:56,980 --> 02:20:59,589 just stored the last two digits of any year. 2947 02:20:59,589 --> 02:21:05,470 The problem, of course, on January 1st of 2000 is that 99 rolls over to 100. 2948 02:21:05,470 --> 02:21:10,540 But if you don't have room for another digit it's just 00. 2949 02:21:10,540 --> 02:21:14,920 And if your code assumes a prefix of 19, well, we just went from the year 2950 02:21:14,920 --> 02:21:18,062 1999 back to the year 1900. 2951 02:21:18,062 --> 02:21:20,770 Thankfully, long story short, a lot of people wrote a lot of code 2952 02:21:20,770 --> 02:21:24,080 in a lot of old languages and mostly warded off this problem, 2953 02:21:24,080 --> 02:21:25,600 so the world did not end. 2954 02:21:25,600 --> 02:21:31,180 The next time the world might end though, is on January 19, 2038. 2955 02:21:31,180 --> 02:21:33,760 Now, that might feel like a long time away, 2956 02:21:33,760 --> 02:21:36,130 but so did the year 2000, at one point. 2957 02:21:36,130 --> 02:21:42,550 Why might clocks again break in today's modern computers in 2038, 2958 02:21:42,550 --> 02:21:43,420 might you think? 2959 02:21:43,420 --> 02:21:45,222 AUDIENCE: [INAUDIBLE] 2960 02:21:45,222 --> 02:21:46,180 DAVID J. MALAN: Indeed. 2961 02:21:46,180 --> 02:21:48,350 So this refers to some number of seconds. 2962 02:21:48,350 --> 02:21:51,760 So it turns out that the way computers generally keep track of time 2963 02:21:51,760 --> 02:21:55,330 is they count the total number of seconds since the epoch, which 2964 02:21:55,330 --> 02:21:57,820 is defined as January 1, 1970. 2965 02:21:57,820 --> 02:21:58,420 Why? 2966 02:21:58,420 --> 02:22:01,090 It was just a good year to start counting at, 2967 02:22:01,090 --> 02:22:03,080 when computers really came onto the scene. 2968 02:22:03,080 --> 02:22:07,600 Unfortunately, most computers used 32 bits to count the number of seconds 2969 02:22:07,600 --> 02:22:11,530 since January 1, 1970, the implication of which is we 2970 02:22:11,530 --> 02:22:14,410 can only count up to roughly 2 billion seconds. 2971 02:22:14,410 --> 02:22:21,010 2 billion seconds is going to happen in 2038, at which 30 11's 2972 02:22:21,010 --> 02:22:22,900 are going to roll over as follows. 2973 02:22:22,900 --> 02:22:26,098 That number 2 billion, which is the max-- 2974 02:22:26,098 --> 02:22:28,640 because if you're representing positive and negative numbers, 2975 02:22:28,640 --> 02:22:31,140 recall that you can only count as high as positive 2 billion 2976 02:22:31,140 --> 02:22:32,380 or negative 2 billion-- 2977 02:22:32,380 --> 02:22:33,580 looks like this. 2978 02:22:33,580 --> 02:22:35,620 This is roughly the number 2 billion in binary. 2979 02:22:35,620 --> 02:22:38,240 It's all ones with one zero way over here. 2980 02:22:38,240 --> 02:22:42,190 If I count one second past that 2 billion number, give or take-- 2981 02:22:42,190 --> 02:22:45,250 that means, all right, I add 1, I carry the 1-- 2982 02:22:45,250 --> 02:22:48,490 it's just like 9's becoming 0's in decimal. 2983 02:22:48,490 --> 02:22:52,360 If I keep this sort of simple animation and I keep carrying the 1, 2984 02:22:52,360 --> 02:22:56,650 carrying the 1, carrying the 1, 1 second after 2 billion seconds, give or take, 2985 02:22:56,650 --> 02:22:59,420 I have this number in the computer's memory. 2986 02:22:59,420 --> 02:23:02,980 So there's still 1 bit that's a 1 all the way to the left. 2987 02:23:02,980 --> 02:23:07,240 Unfortunately, that bit often represents negativity, 2988 02:23:07,240 --> 02:23:11,920 whereby if that first bit is negative, that represents that the rest of it 2989 02:23:11,920 --> 02:23:13,480 somehow represents a negative number. 2990 02:23:13,480 --> 02:23:14,530 It's not negative 0. 2991 02:23:14,530 --> 02:23:16,030 There's a fancier representation. 2992 02:23:16,030 --> 02:23:19,000 But a very big, positive number very suddenly 2993 02:23:19,000 --> 02:23:20,890 becomes a very big, negative number. 2994 02:23:20,890 --> 02:23:23,870 And that number is roughly negative 2 billion. 2995 02:23:23,870 --> 02:23:26,740 That means computers in 2038 on that date 2996 02:23:26,740 --> 02:23:29,170 are going to accidentally think that it's 2997 02:23:29,170 --> 02:23:34,810 been negative 2 billion seconds since January 1, 1970, which is going to make 2998 02:23:34,810 --> 02:23:37,930 computers potentially think it's 1901. 2999 02:23:37,930 --> 02:23:42,190 So what is the solution to the 2038 problem, perhaps? 3000 02:23:42,190 --> 02:23:44,800 Y2K was because we were using two digits for years. 3001 02:23:44,800 --> 02:23:46,360 What about 2038? 3002 02:23:46,360 --> 02:23:47,170 More bits. 3003 02:23:47,170 --> 02:23:51,790 And, thankfully, we're getting a little better at lessons learned here, 3004 02:23:51,790 --> 02:23:54,520 and computers now are increasingly using 64 bits. 3005 02:23:54,520 --> 02:23:56,915 And all of us will be long gone by the time we run out 3006 02:23:56,915 --> 02:23:59,290 of that number of seconds, so it's someone else's problem 3007 02:23:59,290 --> 02:24:01,040 many, many years from now. 3008 02:24:01,040 --> 02:24:02,973 But that's really the fundamental solution. 3009 02:24:02,973 --> 02:24:05,140 If you're running up against something finite, well, 3010 02:24:05,140 --> 02:24:07,570 just kick the can further and just give yourself more bits. 3011 02:24:07,570 --> 02:24:09,910 And, frankly, because hardware is so much cheaper these days, 3012 02:24:09,910 --> 02:24:12,400 computers are so much faster, it's not as big of a deal 3013 02:24:12,400 --> 02:24:13,930 as it might have been decades ago. 3014 02:24:13,930 --> 02:24:15,700 But that's indeed the solution. 3015 02:24:15,700 --> 02:24:18,490 But this arises in very common contexts. 3016 02:24:18,490 --> 02:24:23,320 In fact, let me go ahead and write a real quick program here called pennies. 3017 02:24:23,320 --> 02:24:26,350 You might think that just converting dollars to pennies in US currency 3018 02:24:26,350 --> 02:24:28,930 might be simple, but let me go ahead and do this. 3019 02:24:28,930 --> 02:24:32,530 In pennies.c, I'm going to go ahead and include cs50.h. 3020 02:24:32,530 --> 02:24:39,470 And I'm going to include stdio.h, int main void as my starting point. 3021 02:24:39,470 --> 02:24:41,600 And now down here, I'm going to do this. 3022 02:24:41,600 --> 02:24:43,570 I'm going to get a float called amount, and I'm 3023 02:24:43,570 --> 02:24:47,740 going to ask the user for some amount of dollars, so a dollar amount, 3024 02:24:47,740 --> 02:24:50,470 and I'm going to store that in a variable called amount. 3025 02:24:50,470 --> 02:24:58,660 Then I'm going to simply convert that amount to pennies by doing, say, how 3026 02:24:58,660 --> 02:25:01,310 about amount times 100? 3027 02:25:01,310 --> 02:25:07,480 And then I'm going to go ahead and print out that the number of pennies is %i-- 3028 02:25:07,480 --> 02:25:09,430 because that's just an integer in pennies-- 3029 02:25:09,430 --> 02:25:13,690 backslash n, quote unquote, comma, pennies. 3030 02:25:13,690 --> 02:25:17,380 All right, so if I didn't make any mistakes here, let me make pennies, 3031 02:25:17,380 --> 02:25:19,000 ./pennies. 3032 02:25:19,000 --> 02:25:22,900 And suppose I have, say, $0.99, so 0.99. 3033 02:25:22,900 --> 02:25:24,190 That's 99 pennies. 3034 02:25:24,190 --> 02:25:26,998 Suppose I have $1.23. 3035 02:25:26,998 --> 02:25:27,790 That's pretty good. 3036 02:25:27,790 --> 02:25:31,050 Suppose I have $4.20. 3037 02:25:31,050 --> 02:25:32,510 Huh. 3038 02:25:32,510 --> 02:25:34,130 There's that imprecision issue. 3039 02:25:34,130 --> 02:25:36,440 And this isn't even that big of an amount. 3040 02:25:36,440 --> 02:25:40,502 Now, not a big deal if the cashier gives you one penny less than you're owed, 3041 02:25:40,502 --> 02:25:41,960 but you can imagine this adding up. 3042 02:25:41,960 --> 02:25:45,440 You can imagine this being worrisome for financial implications, 3043 02:25:45,440 --> 02:25:48,830 for financial transactions, for scientific measurements and the like. 3044 02:25:48,830 --> 02:25:51,060 My program can't even handle this. 3045 02:25:51,060 --> 02:25:53,180 Well, there are some solutions here. 3046 02:25:53,180 --> 02:25:55,370 And it looks like what's really happening-- 3047 02:25:55,370 --> 02:25:59,930 if I print it out using the %f with a 0.50 or whatever to see more decimal 3048 02:25:59,930 --> 02:26:00,650 points-- 3049 02:26:00,650 --> 02:26:05,480 presumably, the computer is struggling to represent $4.20 precisely. 3050 02:26:05,480 --> 02:26:11,960 It's probably storing 4 dollars and 19.9999-something cents. 3051 02:26:11,960 --> 02:26:14,750 So it's close, but it's not quite there. 3052 02:26:14,750 --> 02:26:19,280 So I could at least solve this by rounding up, for instance. 3053 02:26:19,280 --> 02:26:22,280 And it turns out there is a round function out there. 3054 02:26:22,280 --> 02:26:25,040 And it turns out that it's in a library called the math library. 3055 02:26:25,040 --> 02:26:28,040 And you would know this by looking at online documentation and the like, 3056 02:26:28,040 --> 02:26:29,150 as we'll point you to. 3057 02:26:29,150 --> 02:26:35,000 And if I now make pennies again and do ./pennies, I can now do $4.20. 3058 02:26:35,000 --> 02:26:35,900 And, voila. 3059 02:26:35,900 --> 02:26:37,370 Now it's correct. 3060 02:26:37,370 --> 02:26:40,730 So at least in this context, it seems like a solvable problem. 3061 02:26:40,730 --> 02:26:44,660 But it's certainly something I need to be mindful of, nonetheless. 3062 02:26:44,660 --> 02:26:48,380 Unfortunately, even professional, full-time programmers over the years 3063 02:26:48,380 --> 02:26:51,272 have not been particularly attentive to these kinds of details. 3064 02:26:51,272 --> 02:26:54,230 And in a class like this, the goal is not just to teach you programming 3065 02:26:54,230 --> 02:26:57,750 but to really teach you what's going on underneath the hood, so to speak, 3066 02:26:57,750 --> 02:27:00,800 so that you have a bottom-up understanding of how data 3067 02:27:00,800 --> 02:27:03,180 is represented, how computers are manipulating it, 3068 02:27:03,180 --> 02:27:07,260 so that you are not on the failing end of some program having some bug. 3069 02:27:07,260 --> 02:27:10,560 And so that we as a society are not beholden to those kinds of mistakes 3070 02:27:10,560 --> 02:27:11,060 too. 3071 02:27:11,060 --> 02:27:13,430 And this happens, unfortunately, all of the time. 3072 02:27:13,430 --> 02:27:17,210 This is a Boeing airplane that a few years ago needed 3073 02:27:17,210 --> 02:27:20,820 to be rebooted after every 248 days. 3074 02:27:20,820 --> 02:27:21,320 Why? 3075 02:27:21,320 --> 02:27:25,940 Because this Boeing airplane software was using a 32-bit integer counting up 3076 02:27:25,940 --> 02:27:28,190 tenths of a second to keep track of something or other 3077 02:27:28,190 --> 02:27:29,960 related to its electrical power. 3078 02:27:29,960 --> 02:27:34,670 And, unfortunately, after 248 days of the airplane being continuously on-- 3079 02:27:34,670 --> 02:27:36,890 which in the airline industry is apparently not 3080 02:27:36,890 --> 02:27:40,580 uncommon to make every dollar count, keeping the planes up and running 3081 02:27:40,580 --> 02:27:41,780 all the time-- 3082 02:27:41,780 --> 02:27:45,710 the 32-bit number would roll over and the power 3083 02:27:45,710 --> 02:27:48,800 would shut off on the airplane as a side effect because of sort 3084 02:27:48,800 --> 02:27:50,880 of undefined behavior in that case. 3085 02:27:50,880 --> 02:27:54,140 The temporary solution by Boeing at the time was apparently, essentially, 3086 02:27:54,140 --> 02:27:57,350 sort of operating system style, well, have you rebooted your plane? 3087 02:27:57,350 --> 02:28:01,040 And that was indeed the fix until they rolled out an actual software patch. 3088 02:28:01,040 --> 02:28:02,550 This stuff really matters. 3089 02:28:02,550 --> 02:28:05,600 And the more hardware we carry around and the more we as a society 3090 02:28:05,600 --> 02:28:08,750 use these kinds of devices, the more of these problems 3091 02:28:08,750 --> 02:28:11,630 we're going to run into down the road. 3092 02:28:11,630 --> 02:28:13,170 That's it for CS50. 3093 02:28:13,170 --> 02:28:15,460 We'll see you next time. 3094 02:28:15,460 --> 02:28:50,000 [MUSIC PLAYING]