1 00:00:00,000 --> 00:00:02,970 [MUSIC PLAYING] 2 00:00:02,970 --> 00:00:50,050 3 00:00:50,050 --> 00:00:52,480 DAVID MALAN: All right, this is CS50. 4 00:00:52,480 --> 00:00:55,330 And this is week one, our second week. 5 00:00:55,330 --> 00:00:59,330 And today, recall that we'll focus on this other programming language called 6 00:00:59,330 --> 00:00:59,830 C. 7 00:00:59,830 --> 00:01:02,710 And we gave you a little glimpse of this last time, wherein 8 00:01:02,710 --> 00:01:05,140 I proposed that this code here on the screen 9 00:01:05,140 --> 00:01:08,620 is something that you will soon know how to program, if not already. 10 00:01:08,620 --> 00:01:11,350 But suffice it to say it looks quite a bit dissimilar to what 11 00:01:11,350 --> 00:01:14,560 we looked at last week which, of course, was Scratch, which was much more 12 00:01:14,560 --> 00:01:16,120 playful, much more graphical. 13 00:01:16,120 --> 00:01:20,680 And so allow me to disclaim right from the get go today that for most of us, 14 00:01:20,680 --> 00:01:22,990 today will feel like a bit of a fire hose. 15 00:01:22,990 --> 00:01:25,420 In fact, pictured here as an old hack from MIT, 16 00:01:25,420 --> 00:01:28,750 wherein some industrious seniors hooked up an actual fire hydrant 17 00:01:28,750 --> 00:01:30,310 to a water fountain. 18 00:01:30,310 --> 00:01:32,440 The saying being that getting an education from MIT 19 00:01:32,440 --> 00:01:35,525 is like drinking from a fire hydrant. 20 00:01:35,525 --> 00:01:37,150 Today will feel a little bit like that. 21 00:01:37,150 --> 00:01:40,270 Because this is sort of a special occasion that you don't really have 22 00:01:40,270 --> 00:01:42,250 occasion to describe very often. 23 00:01:42,250 --> 00:01:44,988 But it's one in which we're all going to learn a new language. 24 00:01:44,988 --> 00:01:47,030 And indeed, that's not something we do every day. 25 00:01:47,030 --> 00:01:49,270 And so at the first glance, it's going to look 26 00:01:49,270 --> 00:01:51,700 like a lot of new syntax, a lot of new ideas. 27 00:01:51,700 --> 00:01:55,945 And yet, allow me to reassure, that what will soon look like this, 28 00:01:55,945 --> 00:01:59,500 this C code here, is fundamentally the same thing 29 00:01:59,500 --> 00:02:03,760 that you've seen and now experimented with last week by way of Scratch. 30 00:02:03,760 --> 00:02:06,083 That is to say, within this other programming language 31 00:02:06,083 --> 00:02:09,250 C, which is more traditional, which is more text-based, more keyboard-based, 32 00:02:09,250 --> 00:02:13,300 we're still going to see functions, conditions, Boolean expressions, loops, 33 00:02:13,300 --> 00:02:14,065 and so on. 34 00:02:14,065 --> 00:02:15,940 They're going to all look a little different. 35 00:02:15,940 --> 00:02:18,130 But the ideas are the same. 36 00:02:18,130 --> 00:02:22,763 And so much like when walking into someone's home for the very first time 37 00:02:22,763 --> 00:02:25,180 and getting the lay of the land and seeing a lot of things 38 00:02:25,180 --> 00:02:28,180 that you haven't seen before, you typically don't care about all 39 00:02:28,180 --> 00:02:29,200 of those visual details. 40 00:02:29,200 --> 00:02:31,490 You might just simply walk forward and sit down. 41 00:02:31,490 --> 00:02:34,600 Similarly today, we're about to see a whole lot of details 42 00:02:34,600 --> 00:02:36,550 in the world of this programming language. 43 00:02:36,550 --> 00:02:39,160 But the goal at hand is to ignore things at first glance 44 00:02:39,160 --> 00:02:43,060 that we don't necessarily understand and latch onto those ideas that 45 00:02:43,060 --> 00:02:45,440 are familiar from last week. 46 00:02:45,440 --> 00:02:48,950 So how do we go about actually writing computer programs? 47 00:02:48,950 --> 00:02:51,290 How do we go about writing them well? 48 00:02:51,290 --> 00:02:55,750 And so allow me to propose that there's a few guiding lights that 49 00:02:55,750 --> 00:02:57,428 should guide writing of code. 50 00:02:57,428 --> 00:02:58,720 One, of course, is correctness. 51 00:02:58,720 --> 00:03:01,810 And we explored this last week, whereby the correctness of your code 52 00:03:01,810 --> 00:03:04,540 just speaks to does it work as intended. 53 00:03:04,540 --> 00:03:07,300 When you double click some icon, when you run some command, 54 00:03:07,300 --> 00:03:11,020 does the program that you or someone else wrote behave correctly? 55 00:03:11,020 --> 00:03:12,740 Does it do what it says? 56 00:03:12,740 --> 00:03:16,330 But there's other aspects to writing good software 57 00:03:16,330 --> 00:03:18,100 and writing good programs. 58 00:03:18,100 --> 00:03:19,450 And that has to do with design. 59 00:03:19,450 --> 00:03:22,070 And we alluded a little bit this last week. 60 00:03:22,070 --> 00:03:26,050 But with design it's more of a qualitative, a more subjective measure, 61 00:03:26,050 --> 00:03:28,090 just how well written your code is. 62 00:03:28,090 --> 00:03:31,750 So imagine, for instance, from taking a class where you have to write essays, 63 00:03:31,750 --> 00:03:34,720 you could certainly make very correct arguments. 64 00:03:34,720 --> 00:03:37,810 But you could make very correct arguments by writing very long, 65 00:03:37,810 --> 00:03:41,800 rambling sentences, repeating yourself, and generally not writing 66 00:03:41,800 --> 00:03:43,420 a very good essay or paper. 67 00:03:43,420 --> 00:03:44,590 Now it might be correct. 68 00:03:44,590 --> 00:03:46,840 There's nothing in that paper for your English class, 69 00:03:46,840 --> 00:03:50,140 history class, or whatever it may be that you said that was incorrect. 70 00:03:50,140 --> 00:03:52,000 But you might not get very good marks on it, 71 00:03:52,000 --> 00:03:54,078 because it's just not very well-designed. 72 00:03:54,078 --> 00:03:55,870 And so similarly, in the programming world, 73 00:03:55,870 --> 00:03:59,320 is there this notion of actually writing not only correct code, 74 00:03:59,320 --> 00:04:00,940 but well-designed code. 75 00:04:00,940 --> 00:04:02,740 Wherein you don't repeat yourself. 76 00:04:02,740 --> 00:04:04,600 You write code that's fairly efficient. 77 00:04:04,600 --> 00:04:08,960 It doesn't do more work than it actually needs to. 78 00:04:08,960 --> 00:04:12,340 And then lastly, let me propose for today onward in this class, 79 00:04:12,340 --> 00:04:15,070 that there's a third axis you should keep in mind when 80 00:04:15,070 --> 00:04:17,019 it comes to writing good code. 81 00:04:17,019 --> 00:04:18,550 And that has to do with style. 82 00:04:18,550 --> 00:04:20,380 This is much more of an aesthetic. 83 00:04:20,380 --> 00:04:23,260 So this, in the analogous world of writing an essay, 84 00:04:23,260 --> 00:04:26,770 would be are using good punctuation, capitalisation? 85 00:04:26,770 --> 00:04:28,450 Are you indenting new paragraphs? 86 00:04:28,450 --> 00:04:30,760 And those kinds of aesthetics that fundamentally 87 00:04:30,760 --> 00:04:33,430 don't change the correctness of what you're saying, 88 00:04:33,430 --> 00:04:37,220 don't change necessarily the quality of the arguments that you're making, 89 00:04:37,220 --> 00:04:41,230 but the style of your essay, much like the style of your code, 90 00:04:41,230 --> 00:04:44,090 makes your code much, much more readable. 91 00:04:44,090 --> 00:04:47,140 So when it comes to writing good code, you want it first 92 00:04:47,140 --> 00:04:49,840 and foremost to be correct, but also well well-designed 93 00:04:49,840 --> 00:04:51,550 and also well-styled. 94 00:04:51,550 --> 00:04:54,460 Much like, again, you would when writing an essay that you would hope 95 00:04:54,460 --> 00:04:59,150 would reflect well on your capabilities as well. 96 00:04:59,150 --> 00:05:02,603 So when it comes to writing code, like this, for instance, 97 00:05:02,603 --> 00:05:05,020 this first C program that someone last week proposed quite 98 00:05:05,020 --> 00:05:07,660 simply prints out on the screen, hello, world. 99 00:05:07,660 --> 00:05:09,670 Well, how do we go about writing this code? 100 00:05:09,670 --> 00:05:12,580 Last week we wrote code by going to Scratch.MIT.edu 101 00:05:12,580 --> 00:05:14,673 and then dragging and dropping puzzle pieces. 102 00:05:14,673 --> 00:05:16,340 Today is going to be a little different. 103 00:05:16,340 --> 00:05:18,550 We're going to use a different tool here on out. 104 00:05:18,550 --> 00:05:20,425 And we're going to use our keyboard much more 105 00:05:20,425 --> 00:05:22,125 than our mouse to actually program. 106 00:05:22,125 --> 00:05:24,250 But to do so, we're going to go ahead and introduce 107 00:05:24,250 --> 00:05:28,640 the first of several tools this semester, this one, known as CS50 IDE. 108 00:05:28,640 --> 00:05:31,780 IDE is an acronym, a term of art in programming, 109 00:05:31,780 --> 00:05:34,720 that stands for Integrated Development Environment. 110 00:05:34,720 --> 00:05:37,150 Which is just a fancy way of saying, in this context, 111 00:05:37,150 --> 00:05:41,780 that CS50 IDE is CS50's own web-based programming environment. 112 00:05:41,780 --> 00:05:44,470 And it's not specific to CS50 per se. 113 00:05:44,470 --> 00:05:47,760 We've simply added a number of educationally useful features 114 00:05:47,760 --> 00:05:52,860 on top of a third party cloud tool that anyone on the internet can use. 115 00:05:52,860 --> 00:05:57,233 And our own version thereof lives at this URL, ide.cs50.io. 116 00:05:57,233 --> 00:05:59,400 So you're welcome to follow along at that URL today. 117 00:05:59,400 --> 00:06:01,620 But you need not during lecture itself. 118 00:06:01,620 --> 00:06:04,110 But on this upcoming problem set and beyond, 119 00:06:04,110 --> 00:06:08,500 will you actually use and get more familiar with this tool hands on. 120 00:06:08,500 --> 00:06:10,930 So let me go ahead and open up this tool here. 121 00:06:10,930 --> 00:06:12,600 So I've already logged in in advance. 122 00:06:12,600 --> 00:06:17,010 And what you see here is the basic user interface that's available to you. 123 00:06:17,010 --> 00:06:19,650 And fortunately, there's only a couple of salient features 124 00:06:19,650 --> 00:06:21,270 that we need to point out right now. 125 00:06:21,270 --> 00:06:23,460 So at the top of the screen here, it's just 126 00:06:23,460 --> 00:06:27,210 a big black rectangle that in a moment is going to be filled with code. 127 00:06:27,210 --> 00:06:29,850 Much like using Google documents or something 128 00:06:29,850 --> 00:06:32,565 like that, where you can create new tabs and create new files, 129 00:06:32,565 --> 00:06:34,440 this is where I'm going to do my programming, 130 00:06:34,440 --> 00:06:35,680 along the top of the screen. 131 00:06:35,680 --> 00:06:37,680 And along the bottom is what we're, in a moment, 132 00:06:37,680 --> 00:06:39,780 going to start calling our terminal window. 133 00:06:39,780 --> 00:06:44,400 It's in this terminal window that I can actually run commands and ultimately 134 00:06:44,400 --> 00:06:46,210 run my actual code. 135 00:06:46,210 --> 00:06:49,380 But let's go ahead and write our very first program in this environment 136 00:06:49,380 --> 00:06:52,440 and realize that this tool, indeed, is not very CS50 specific. 137 00:06:52,440 --> 00:06:56,610 It's meant to be representative of a very common popular programming 138 00:06:56,610 --> 00:06:58,980 environment, where you have a so-called text editor, 139 00:06:58,980 --> 00:07:01,170 or tabbed windows where you can write code, 140 00:07:01,170 --> 00:07:03,900 and a terminal window where you can actually run commands. 141 00:07:03,900 --> 00:07:05,760 Ours happens to exist in the cloud. 142 00:07:05,760 --> 00:07:07,950 But you can alternatively program, certainly, 143 00:07:07,950 --> 00:07:11,040 on your own Mac, or PC, or any other device these days. 144 00:07:11,040 --> 00:07:13,470 But frankly, it tends to involve just a non-trivial number 145 00:07:13,470 --> 00:07:16,110 of technical difficulties early on, especially when we all 146 00:07:16,110 --> 00:07:19,000 have different versions of Mac OS and Windows and the like. 147 00:07:19,000 --> 00:07:22,440 So this cloud-based environment just ensures that on day zero, 148 00:07:22,440 --> 00:07:25,918 we can all have the same exact programming experience. 149 00:07:25,918 --> 00:07:27,460 So I'm going to go ahead and do this. 150 00:07:27,460 --> 00:07:30,430 I'm going to go ahead and go up to File and New File. 151 00:07:30,430 --> 00:07:33,690 And this is going to create a new tab, by default called Untitled1, 152 00:07:33,690 --> 00:07:34,840 not very interesting. 153 00:07:34,840 --> 00:07:37,200 So I'm going to now go up to File and Save. 154 00:07:37,200 --> 00:07:40,240 And by default, I'm going to save this file as, for instance, 155 00:07:40,240 --> 00:07:42,160 the name hello.c. 156 00:07:42,160 --> 00:07:45,180 So I want to write my very first program in this language called 157 00:07:45,180 --> 00:07:47,230 C. I'm going to call my file hello. 158 00:07:47,230 --> 00:07:50,495 But I'm going to end it in a file extension called .c. 159 00:07:50,495 --> 00:07:51,870 And that's indeed the convention. 160 00:07:51,870 --> 00:07:55,440 When writing C programs, they should end with .c. 161 00:07:55,440 --> 00:07:59,685 Just like Scratch programs, as you may recall, end in .sb3. 162 00:07:59,685 --> 00:08:02,310 So I'm going to go ahead and simply click the green button here 163 00:08:02,310 --> 00:08:03,360 that's called Save. 164 00:08:03,360 --> 00:08:06,540 Nothing is really going to change except for the name and the tab there. 165 00:08:06,540 --> 00:08:10,140 Now I see at top left that this tab is called hello.c. 166 00:08:10,140 --> 00:08:12,060 And now I can start typing anything I want. 167 00:08:12,060 --> 00:08:14,130 And frankly, I'm just going to type from memory 168 00:08:14,130 --> 00:08:17,250 the very first program we saw last week and just a moment ago. 169 00:08:17,250 --> 00:08:21,570 I'm going to do include stdio.h, whatever that is for now. 170 00:08:21,570 --> 00:08:25,530 I'm going then going to do int main(void), whatever that is for now. 171 00:08:25,530 --> 00:08:27,120 I'm going to use the curly brace. 172 00:08:27,120 --> 00:08:30,480 And then close that curly brace, so to speak, thereafter. 173 00:08:30,480 --> 00:08:36,659 And in here, I'm going to go ahead and do printf("hello,world") followed 174 00:08:36,659 --> 00:08:38,230 by a semicolon. 175 00:08:38,230 --> 00:08:41,027 Now that was a whole lot of text right off the top of my head. 176 00:08:41,027 --> 00:08:43,110 This is the kind of muscle memory that you'll soon 177 00:08:43,110 --> 00:08:44,402 develop when writing a program. 178 00:08:44,402 --> 00:08:46,290 I've, of course, done this many times before. 179 00:08:46,290 --> 00:08:48,600 So I was able to just do it off the top of my head. 180 00:08:48,600 --> 00:08:52,500 But in a moment, we'll tease apart what all of the various lines and characters 181 00:08:52,500 --> 00:08:54,750 that I typed actually do. 182 00:08:54,750 --> 00:08:57,030 But what I'd now like to do is run this program. 183 00:08:57,030 --> 00:09:00,990 We conjectured last week that this is just going to print hello, world. 184 00:09:00,990 --> 00:09:01,800 But how? 185 00:09:01,800 --> 00:09:04,440 Well, in the world of our Macs and PCs and phones, 186 00:09:04,440 --> 00:09:08,730 we would all just tap an icon if we want to actually run a program. 187 00:09:08,730 --> 00:09:12,000 That's not going to be the case today, because now we're 188 00:09:12,000 --> 00:09:14,650 in more of a traditional programming environment. 189 00:09:14,650 --> 00:09:17,010 The environment that we're now in requires 190 00:09:17,010 --> 00:09:19,000 that I use my keyboard a little bit more, 191 00:09:19,000 --> 00:09:22,830 or what's known as a Command Line Interface, or CLI. 192 00:09:22,830 --> 00:09:27,780 This is in contrast with a Graphical User Interface, or G-U-I, or GUI, 193 00:09:27,780 --> 00:09:31,050 which is what describes Mac OS windows, iOS, and Android. 194 00:09:31,050 --> 00:09:33,540 But in a command line interface, I have to do everything 195 00:09:33,540 --> 00:09:35,550 at a so-called command line. 196 00:09:35,550 --> 00:09:38,340 And by that, I'm referring to this blinking 197 00:09:38,340 --> 00:09:41,080 prompt along the bottom of my screen. 198 00:09:41,080 --> 00:09:43,080 Along the bottom of my screen here, again, I 199 00:09:43,080 --> 00:09:46,380 described as the terminal window, where I'm going to type commands, 200 00:09:46,380 --> 00:09:48,630 and this is my command line interface. 201 00:09:48,630 --> 00:09:52,000 Anything I type here is going to get sent to this computer 202 00:09:52,000 --> 00:09:55,510 and hopefully execute on its own hardware. 203 00:09:55,510 --> 00:09:57,670 So how do I do this? 204 00:09:57,670 --> 00:09:58,960 And what do I do? 205 00:09:58,960 --> 00:10:04,140 Well, the catch, of course, is that when writing code in C or Python 206 00:10:04,140 --> 00:10:07,320 or Java or bunches of other languages that happen to exist, 207 00:10:07,320 --> 00:10:11,400 that's really meant to be written and understood by me and you, the humans. 208 00:10:11,400 --> 00:10:14,220 But per last week, what is the only language, 209 00:10:14,220 --> 00:10:16,140 in a sense, that computers understand? 210 00:10:16,140 --> 00:10:18,420 Brian, could we call on someone for this? 211 00:10:18,420 --> 00:10:23,730 What language do computers only speak? 212 00:10:23,730 --> 00:10:26,790 Because I think there's a disconnect between where we left off last week 213 00:10:26,790 --> 00:10:31,270 and where we're currently at if I'm writing code that now looks like this. 214 00:10:31,270 --> 00:10:35,100 Cindy, what language do computers speak, would you say? 215 00:10:35,100 --> 00:10:36,007 AUDIENCE: Binary. 216 00:10:36,007 --> 00:10:36,840 DAVID MALAN: Binary. 217 00:10:36,840 --> 00:10:38,173 And just elaborate a little bit. 218 00:10:38,173 --> 00:10:39,977 What do you mean by binary, to recap? 219 00:10:39,977 --> 00:10:40,560 AUDIENCE: Yes. 220 00:10:40,560 --> 00:10:43,825 So they use 1's and 0's to represent everything. 221 00:10:43,825 --> 00:10:44,700 DAVID MALAN: Exactly. 222 00:10:44,700 --> 00:10:46,830 They use 1's and 0's to represent everything. 223 00:10:46,830 --> 00:10:51,090 And last week we focused on only things like numbers and letters 224 00:10:51,090 --> 00:10:54,220 and colors and images and videos and sound and so forth. 225 00:10:54,220 --> 00:10:58,410 But we didn't actually speak to built in functionality, which computers also 226 00:10:58,410 --> 00:11:00,600 use 0's and 1's to represent. 227 00:11:00,600 --> 00:11:04,260 That is to say computers, of course, have the ability these days to print 228 00:11:04,260 --> 00:11:06,120 something on the screen. 229 00:11:06,120 --> 00:11:10,470 And that notion of printing, that function, that functionality, 230 00:11:10,470 --> 00:11:13,780 also is represented underneath the hood of a computer, so to speak, 231 00:11:13,780 --> 00:11:15,720 by some pattern of 0's and 1's. 232 00:11:15,720 --> 00:11:18,510 Which is to say that everything I just typed, 233 00:11:18,510 --> 00:11:21,000 even though it kind of sort of looks like English 234 00:11:21,000 --> 00:11:25,920 and kind of sort of clearly says print hello, world, the computer, ironically, 235 00:11:25,920 --> 00:11:28,620 does not know what it is I have just typed. 236 00:11:28,620 --> 00:11:30,750 In order for it to understand what I've just typed, 237 00:11:30,750 --> 00:11:33,610 I need to actually convert it to 0's and 1's. 238 00:11:33,610 --> 00:11:35,790 And so, indeed, the next step in this process 239 00:11:35,790 --> 00:11:39,930 is to take what I'll describe as my source code, written here in C, 240 00:11:39,930 --> 00:11:42,690 and last week, too, we saw source code, it was just graphical. 241 00:11:42,690 --> 00:11:44,305 It was those puzzle pieces in Scratch. 242 00:11:44,305 --> 00:11:47,430 This is my source code that, even though cryptic, is something I, at least, 243 00:11:47,430 --> 00:11:49,710 the human, eventually can read and write. 244 00:11:49,710 --> 00:11:53,370 But I need to literally convert it to patterns of 0's and 1's 245 00:11:53,370 --> 00:11:54,960 that the computer can understand. 246 00:11:54,960 --> 00:11:56,320 Now how do I get to this point? 247 00:11:56,320 --> 00:11:58,680 Well, thankfully, we have a mental model from last week 248 00:11:58,680 --> 00:12:00,330 that involves problem solving. 249 00:12:00,330 --> 00:12:01,330 And here's a problem. 250 00:12:01,330 --> 00:12:04,650 How do I take source code, written in this language supposedly called C, 251 00:12:04,650 --> 00:12:08,010 and convert it to 0's and 1's that the computer understands? 252 00:12:08,010 --> 00:12:10,980 Well, my input, I daresay, is going to be my source code. 253 00:12:10,980 --> 00:12:16,440 And my output, ideally, is going to be what we'll call machine code. 254 00:12:16,440 --> 00:12:19,230 Machine code is just a term of art describing the 0's 255 00:12:19,230 --> 00:12:21,150 and 1's that computers understand. 256 00:12:21,150 --> 00:12:23,100 We didn't use that expression last week. 257 00:12:23,100 --> 00:12:27,480 But this just refers to 0's and 1's on the right and C code on the left. 258 00:12:27,480 --> 00:12:31,690 So that invites the question, well, what is between my source code and machine 259 00:12:31,690 --> 00:12:32,190 code? 260 00:12:32,190 --> 00:12:36,030 If I take my source code and feed it into the proverbial black box, 261 00:12:36,030 --> 00:12:39,810 how do I get out of this black box the 0's and 1's that the computer 262 00:12:39,810 --> 00:12:40,470 understands? 263 00:12:40,470 --> 00:12:42,270 Well, I need a special program that we're 264 00:12:42,270 --> 00:12:44,220 going to start calling a compiler. 265 00:12:44,220 --> 00:12:47,460 A compiler is a program that you can download for free, 266 00:12:47,460 --> 00:12:50,760 or pay for back in the day, that is a program designed 267 00:12:50,760 --> 00:12:53,410 to convert source code to machine code. 268 00:12:53,410 --> 00:12:55,860 So all I need do if I want to actually solve 269 00:12:55,860 --> 00:13:01,140 the problem as stated earlier, whereby I have written this code in C 270 00:13:01,140 --> 00:13:03,600 and I now need to convert it to 0's and 1's, I just 271 00:13:03,600 --> 00:13:06,180 need to give myself access to a compiler. 272 00:13:06,180 --> 00:13:09,570 And it turns out one of those exists within CS50 IDE. 273 00:13:09,570 --> 00:13:13,230 And this is a tool you could download on your own Mac or PC or the like. 274 00:13:13,230 --> 00:13:16,680 And for now, we're going to describe that tool as being quite simply called 275 00:13:16,680 --> 00:13:17,770 "make." 276 00:13:17,770 --> 00:13:20,250 Literally, if I want to make my program, I'm 277 00:13:20,250 --> 00:13:22,198 going to go ahead and type make hello. 278 00:13:22,198 --> 00:13:24,990 And then I'm going to run it with a little bit of a cryptic syntax, 279 00:13:24,990 --> 00:13:26,820 ./hello. 280 00:13:26,820 --> 00:13:29,760 But let's see that in action to tie this all together. 281 00:13:29,760 --> 00:13:32,970 I'm going to move my cursor down into my terminal window, 282 00:13:32,970 --> 00:13:34,590 or my command line interface. 283 00:13:34,590 --> 00:13:36,360 And I'm going to literally type hello. 284 00:13:36,360 --> 00:13:39,450 Notice I am not typing make hello.c. 285 00:13:39,450 --> 00:13:42,600 I'm typing the name of the program I actually want to make 286 00:13:42,600 --> 00:13:45,090 and I just want to call this program hello. 287 00:13:45,090 --> 00:13:48,570 The compiler is going to infer from this command 288 00:13:48,570 --> 00:13:51,960 that I actually intend to compile a file called hello.c. 289 00:13:51,960 --> 00:13:53,460 I'm going to go ahead and hit Enter. 290 00:13:53,460 --> 00:13:55,140 There's some crazy cryptic output. 291 00:13:55,140 --> 00:13:56,610 More on that another day. 292 00:13:56,610 --> 00:13:59,790 But the fact that I don't see any big scary red error messages 293 00:13:59,790 --> 00:14:00,750 is a good thing. 294 00:14:00,750 --> 00:14:03,570 This means that my program compiled successfully. 295 00:14:03,570 --> 00:14:04,170 Why? 296 00:14:04,170 --> 00:14:07,680 There's just no yellow or red messages to say otherwise. 297 00:14:07,680 --> 00:14:10,410 But now, if I want to actually run this program, 298 00:14:10,410 --> 00:14:13,170 I need to type a different command that's the analog of double 299 00:14:13,170 --> 00:14:15,660 clicking an icon on your Mac or PC or phone. 300 00:14:15,660 --> 00:14:18,990 I'm going to type literally ./hello. 301 00:14:18,990 --> 00:14:23,550 ./hello essentially is like saying go into the current folder on the computer 302 00:14:23,550 --> 00:14:26,190 I'm using and look for a program called hello. 303 00:14:26,190 --> 00:14:30,540 I'm going to go ahead and hit Enter and voila, hello, world. 304 00:14:30,540 --> 00:14:34,133 Now I see, again, a dollar sign and some other text on the screen. 305 00:14:34,133 --> 00:14:36,300 And we'll tease apart in just a bit what this means. 306 00:14:36,300 --> 00:14:39,930 But notice, this dollar sign is just a constant visual reminder 307 00:14:39,930 --> 00:14:43,888 of where my prompt is, where I can type more commands. 308 00:14:43,888 --> 00:14:45,930 And the computer has done literally what I asked. 309 00:14:45,930 --> 00:14:47,340 It printed out hello, world. 310 00:14:47,340 --> 00:14:49,590 And now it's waiting for my second command. 311 00:14:49,590 --> 00:14:53,520 So that was the analog of just printing hello, world out of the cat's mouth 312 00:14:53,520 --> 00:14:54,510 last week. 313 00:14:54,510 --> 00:14:56,490 But surely we can do more than this. 314 00:14:56,490 --> 00:14:59,530 But let's tie it back to what we did last week as well. 315 00:14:59,530 --> 00:15:02,610 So that not everything here is all that dissimilar. 316 00:15:02,610 --> 00:15:04,758 So recall that last week, we had functions. 317 00:15:04,758 --> 00:15:07,800 And it turns out we had something called arguments, even though we didn't 318 00:15:07,800 --> 00:15:09,610 necessarily describe them as such. 319 00:15:09,610 --> 00:15:12,070 So a function is like a mini-program. 320 00:15:12,070 --> 00:15:14,580 It's an action or a verb that you can use when writing 321 00:15:14,580 --> 00:15:16,560 your own program that does something. 322 00:15:16,560 --> 00:15:18,600 We saw the say block last week. 323 00:15:18,600 --> 00:15:20,370 We saw the wait block last week. 324 00:15:20,370 --> 00:15:23,730 Those were verbs, or actions, or more generally noticed functions. 325 00:15:23,730 --> 00:15:27,390 But functions can also take inputs, recall, and we did see that last week. 326 00:15:27,390 --> 00:15:31,860 And nowadays, we're going to start calling inputs to functions arguments, 327 00:15:31,860 --> 00:15:32,680 so to speak. 328 00:15:32,680 --> 00:15:34,860 Another term for them is parameters. 329 00:15:34,860 --> 00:15:37,380 But for all intents and purposes, those are synonyms. 330 00:15:37,380 --> 00:15:39,490 Arguments are the inputs to functions. 331 00:15:39,490 --> 00:15:41,490 So let's consider then, from last week, the say 332 00:15:41,490 --> 00:15:45,750 block that we saw last time, which simply is trying to say out 333 00:15:45,750 --> 00:15:47,430 of the cat's mouth, hello, world. 334 00:15:47,430 --> 00:15:51,480 Well, let me go ahead and convert this, if you will, to corresponding C code, 335 00:15:51,480 --> 00:15:55,800 just to emphasize how similar, fundamentally, these two languages 336 00:15:55,800 --> 00:16:00,120 are, even though syntactically C absolutely looks visually different. 337 00:16:00,120 --> 00:16:03,540 It turns out that if you want to say something in C, 338 00:16:03,540 --> 00:16:06,070 using this text-based language like I just did, 339 00:16:06,070 --> 00:16:07,320 you're not going to write say. 340 00:16:07,320 --> 00:16:08,940 You're instead going to write print. 341 00:16:08,940 --> 00:16:10,320 That's actually a bit of a white lie. 342 00:16:10,320 --> 00:16:11,280 You're not going to say print. 343 00:16:11,280 --> 00:16:14,197 You're actually going to say printf, for reasons we'll eventually see. 344 00:16:14,197 --> 00:16:17,050 It means print a formatted something or other. 345 00:16:17,050 --> 00:16:20,580 So printf is the analog in C of say in Scratch. 346 00:16:20,580 --> 00:16:23,190 Now notice in C, I've got this open parenthesis 347 00:16:23,190 --> 00:16:26,500 and closed parenthesis that, nicely enough, are kind of ovular in shape. 348 00:16:26,500 --> 00:16:28,950 And notice that they kind of mimic the white oval 349 00:16:28,950 --> 00:16:31,480 into which we provided input last week. 350 00:16:31,480 --> 00:16:33,690 So in between those parentheses are going 351 00:16:33,690 --> 00:16:37,932 to be my inputs to this function printf, otherwise known as arguments. 352 00:16:37,932 --> 00:16:40,140 But they're going to be a little different this week. 353 00:16:40,140 --> 00:16:43,080 Yes, I'm going to say hello, world, with a comma in between, 354 00:16:43,080 --> 00:16:44,790 grammatically, just like last week. 355 00:16:44,790 --> 00:16:47,940 But in the world of C, I have to be a little more particular. 356 00:16:47,940 --> 00:16:51,450 I also have to add double quotes on the left and the right. 357 00:16:51,450 --> 00:16:55,440 And, somewhat annoyingly, I also have to add a semicolon 358 00:16:55,440 --> 00:16:56,773 at the end of this line of code. 359 00:16:56,773 --> 00:16:59,107 So just like in English, or in a lot of human languages, 360 00:16:59,107 --> 00:17:01,200 you end a sentence, for instance, with a period, 361 00:17:01,200 --> 00:17:04,470 in many lines of code you will write in C 362 00:17:04,470 --> 00:17:08,650 you've also got to finish your thought, in this case, with a semicolon. 363 00:17:08,650 --> 00:17:11,369 So this, then, on the right, is the closest way 364 00:17:11,369 --> 00:17:16,557 of translating this thing on the left from Scratch to C respectively. 365 00:17:16,557 --> 00:17:17,890 So the ideas are still the same. 366 00:17:17,890 --> 00:17:19,410 But the syntax looks a little different. 367 00:17:19,410 --> 00:17:21,702 And we've just got to ingrain in ourselves, ultimately, 368 00:17:21,702 --> 00:17:24,660 what these patterns are and what these human conventions are. 369 00:17:24,660 --> 00:17:28,990 But notice that what we just did follows the same paradigm as last week. 370 00:17:28,990 --> 00:17:31,660 But let's add a little more terminology this week. 371 00:17:31,660 --> 00:17:35,250 Last week, we described the black box as potentially being algorithms, 372 00:17:35,250 --> 00:17:36,060 initially. 373 00:17:36,060 --> 00:17:38,050 And then we started calling them functions. 374 00:17:38,050 --> 00:17:42,780 Functions are just a programmed version of an algorithm, the implementation 375 00:17:42,780 --> 00:17:45,390 of an algorithm in code, in software. 376 00:17:45,390 --> 00:17:49,050 So a function might be represented here as taking inputs otherwise known now 377 00:17:49,050 --> 00:17:50,430 as arguments. 378 00:17:50,430 --> 00:17:54,540 But it turns out that functions can do at least two different types of things 379 00:17:54,540 --> 00:17:55,893 in the world of programming. 380 00:17:55,893 --> 00:17:58,560 And we've seen these things already, but we didn't describe them 381 00:17:58,560 --> 00:18:00,780 quite as particularly as we will today. 382 00:18:00,780 --> 00:18:04,290 When a function takes inputs, that is to say arguments, 383 00:18:04,290 --> 00:18:08,670 just like hello, world is an input to the say block in Scratch 384 00:18:08,670 --> 00:18:14,070 or the printf function in C, functions can have what are called side effects. 385 00:18:14,070 --> 00:18:16,110 And recall, we did see this last time. 386 00:18:16,110 --> 00:18:20,010 When we used the say block, it did output something. 387 00:18:20,010 --> 00:18:23,640 But more technically, it had a side effect, a visual side effect. 388 00:18:23,640 --> 00:18:27,450 When I used the say block last week and the printf function this week, 389 00:18:27,450 --> 00:18:29,160 you see something on the screen. 390 00:18:29,160 --> 00:18:31,080 And that is, yes, some form of output. 391 00:18:31,080 --> 00:18:34,140 But it's a little different from a different form of output 392 00:18:34,140 --> 00:18:35,070 that we saw last time. 393 00:18:35,070 --> 00:18:38,760 So a side effect of a function is often something visual 394 00:18:38,760 --> 00:18:43,048 that happens on the screen, like text or audio in that case. 395 00:18:43,048 --> 00:18:45,840 But there's this other feature of functions that we're going to see 396 00:18:45,840 --> 00:18:49,620 and leverage today known as return values, where a function can really 397 00:18:49,620 --> 00:18:51,340 just hand you back a value. 398 00:18:51,340 --> 00:18:53,100 It's not going to say it on the screen. 399 00:18:53,100 --> 00:18:55,440 It's not going to vocalize it audibly. 400 00:18:55,440 --> 00:18:58,680 It's going to just pass it back to you in a way that you, the programmer, 401 00:18:58,680 --> 00:19:01,530 can reuse whatever the output of that function 402 00:19:01,530 --> 00:19:03,940 was, ideally storing it even in a variable. 403 00:19:03,940 --> 00:19:07,110 So for instance, recall last week that we asked the human 404 00:19:07,110 --> 00:19:09,390 their name by way of this ask block. 405 00:19:09,390 --> 00:19:13,020 And the input to the ask block in this white oval was, what's your name. 406 00:19:13,020 --> 00:19:17,130 And then recall that this ask block was a little special last week. 407 00:19:17,130 --> 00:19:21,900 Because it gave us access to whatever the human ultimately typed in. 408 00:19:21,900 --> 00:19:27,660 And that is to say that the ask block last week essentially returned a value. 409 00:19:27,660 --> 00:19:32,790 It didn't just blindly display whatever word the human typed in on the screen. 410 00:19:32,790 --> 00:19:36,420 No, it instead returned it in some sense metaphorically 411 00:19:36,420 --> 00:19:39,798 and stored it in a special variable called answer. 412 00:19:39,798 --> 00:19:41,340 And so, again, that's the difference. 413 00:19:41,340 --> 00:19:44,040 The say block literally says something on the screen. 414 00:19:44,040 --> 00:19:46,110 And there's an immediate visual effect. 415 00:19:46,110 --> 00:19:48,900 With the ask block, after you type in your name, 416 00:19:48,900 --> 00:19:53,340 you don't see your name printed or displayed again on the screen. 417 00:19:53,340 --> 00:19:56,010 Instead, your name is sort of tucked away in a variable, 418 00:19:56,010 --> 00:20:00,240 just like a mathematician would store a number in a variable like x or y or z. 419 00:20:00,240 --> 00:20:02,610 The onus was then on us, the programmer, last week 420 00:20:02,610 --> 00:20:07,320 to eventually do something with the value, my name, that 421 00:20:07,320 --> 00:20:09,610 was in that variable called answer. 422 00:20:09,610 --> 00:20:13,140 So how are we going to translate last week's ask block to C this week? 423 00:20:13,140 --> 00:20:16,140 Well, it turns out there's different ways to do this in C, none of which 424 00:20:16,140 --> 00:20:20,020 are very easy unless you use what's called a library. 425 00:20:20,020 --> 00:20:22,495 A library is code that someone else has written. 426 00:20:22,495 --> 00:20:24,370 And indeed, one of the things we'll use today 427 00:20:24,370 --> 00:20:28,480 is the so-called CS50 library, which is a bunch of code, not terribly much, 428 00:20:28,480 --> 00:20:32,560 that the staff and I wrote just to make it easier to do simple things. 429 00:20:32,560 --> 00:20:35,470 These are training wheels of sorts that we'll take off completely 430 00:20:35,470 --> 00:20:36,702 within a few weeks' time. 431 00:20:36,702 --> 00:20:38,410 But in order to get started quickly, it's 432 00:20:38,410 --> 00:20:41,690 going to make it easier to do things like getting text from the user. 433 00:20:41,690 --> 00:20:44,530 So string is a term of art in the programming world. 434 00:20:44,530 --> 00:20:46,810 A string is text. 435 00:20:46,810 --> 00:20:47,710 It's a word. 436 00:20:47,710 --> 00:20:48,310 It's a letter. 437 00:20:48,310 --> 00:20:49,400 It's a paragraph. 438 00:20:49,400 --> 00:20:50,330 It's a page of text. 439 00:20:50,330 --> 00:20:52,150 It's just text in some form. 440 00:20:52,150 --> 00:20:55,210 String is what a computer scientist would call text. 441 00:20:55,210 --> 00:20:58,150 get_string is a function that we wrote that we will 442 00:20:58,150 --> 00:21:00,340 provide to you that does take inputs. 443 00:21:00,340 --> 00:21:03,610 Notice, per the parentheses here in C, it can take input. 444 00:21:03,610 --> 00:21:05,110 What might that input be? 445 00:21:05,110 --> 00:21:06,910 Well, just like the ask block, it's going 446 00:21:06,910 --> 00:21:09,910 to be a prompt that the human should ultimately see. 447 00:21:09,910 --> 00:21:14,200 So there's a bit more involved, though, than just using this function. 448 00:21:14,200 --> 00:21:18,730 When you use get_string in C, as we will soon see in a live demo, 449 00:21:18,730 --> 00:21:20,910 you want to do something with the human's name. 450 00:21:20,910 --> 00:21:22,660 And to do something with the human's name, 451 00:21:22,660 --> 00:21:25,180 it's not quite sufficient to just trust that Scratch 452 00:21:25,180 --> 00:21:27,200 will put it in a variable for you. 453 00:21:27,200 --> 00:21:31,450 In C, as with most programming languages, it's a lot more pedantic. 454 00:21:31,450 --> 00:21:33,760 Like, if you want something to end up in a variable, 455 00:21:33,760 --> 00:21:35,100 you've got to do it yourself. 456 00:21:35,100 --> 00:21:38,650 MIT is not going to magically put it in an answer variable for you. 457 00:21:38,650 --> 00:21:40,040 You have to do it yourself. 458 00:21:40,040 --> 00:21:44,290 So to do this, you simply come up with the name of the variable that you want, 459 00:21:44,290 --> 00:21:48,220 be it x or y or z, or more compellingly, answer, 460 00:21:48,220 --> 00:21:50,980 and you use an equal sign, a single equal sign. 461 00:21:50,980 --> 00:21:55,870 And even though in math this generally implies equality, in the context of C, 462 00:21:55,870 --> 00:21:59,110 and most programming languages, the equal sign actually 463 00:21:59,110 --> 00:22:01,030 means what we'll call assignment. 464 00:22:01,030 --> 00:22:04,720 It means, effectively, copy whatever is on the right 465 00:22:04,720 --> 00:22:07,130 into whatever's on the left. 466 00:22:07,130 --> 00:22:10,150 So if on the right-hand side there's a function whose purpose in life 467 00:22:10,150 --> 00:22:13,540 is to ask the human what their name is, that name 468 00:22:13,540 --> 00:22:16,570 is going to get copied from right to left ultimately 469 00:22:16,570 --> 00:22:18,790 into this variable called answer. 470 00:22:18,790 --> 00:22:21,550 MIT did that automatically for us in Scratch. 471 00:22:21,550 --> 00:22:24,500 In C, you have to do it yourself. 472 00:22:24,500 --> 00:22:26,650 But you have to be a little more particular, too. 473 00:22:26,650 --> 00:22:30,280 It turns out that in the world of C, you can't just have variables. 474 00:22:30,280 --> 00:22:34,090 You have to tell the computer in advance what type of variable you want. 475 00:22:34,090 --> 00:22:38,050 And specifically, I'm going to tell the computer that the type of variable 476 00:22:38,050 --> 00:22:39,820 I want is going to be a string. 477 00:22:39,820 --> 00:22:43,840 And the convention for doing so is you literally write the name of the type 478 00:22:43,840 --> 00:22:47,170 that you want, string being the only one we've seen thus far. 479 00:22:47,170 --> 00:22:49,180 Then you write the name of the variable. 480 00:22:49,180 --> 00:22:53,810 And then, again, to assign a value to that variable from right to left, 481 00:22:53,810 --> 00:22:56,710 we have to use the single equal sign here. 482 00:22:56,710 --> 00:22:58,450 And now, just a quick pause. 483 00:22:58,450 --> 00:23:00,430 Brian, if we could call on someone for this, 484 00:23:00,430 --> 00:23:03,490 even if you've never programmed before, if you've taken to heart 485 00:23:03,490 --> 00:23:06,040 one of my pieces of advice earlier. 486 00:23:06,040 --> 00:23:08,110 I'm still missing something. 487 00:23:08,110 --> 00:23:11,710 How might I want to finish the translation of this Scratch code 488 00:23:11,710 --> 00:23:13,370 to C on the right-hand side? 489 00:23:13,370 --> 00:23:16,368 What is missing from what you can tell? 490 00:23:16,368 --> 00:23:18,910 If you've programmed before, odds are it will jump right out. 491 00:23:18,910 --> 00:23:20,500 If you've never programmed before, you'll 492 00:23:20,500 --> 00:23:22,250 have to think back on what I said earlier. 493 00:23:22,250 --> 00:23:23,920 Jacob, what do you think? 494 00:23:23,920 --> 00:23:24,995 AUDIENCE: Semicolon? 495 00:23:24,995 --> 00:23:25,870 DAVID MALAN: Exactly. 496 00:23:25,870 --> 00:23:28,960 There's just one single, stupid semicolon 497 00:23:28,960 --> 00:23:32,980 missing at the end of the line, which is necessary to make clear to the computer 498 00:23:32,980 --> 00:23:34,810 that this is the end of this thought. 499 00:23:34,810 --> 00:23:36,533 And I sort of impugn it as stupid. 500 00:23:36,533 --> 00:23:39,700 Because honestly, one of the biggest frustrations when learning how to code, 501 00:23:39,700 --> 00:23:42,730 as will now happen today and this week and beyond, 502 00:23:42,730 --> 00:23:46,510 is initially you're going to forget stupid things like the semicolon, 503 00:23:46,510 --> 00:23:49,570 or you're going to forget a single quote mark, or a parenthesis, 504 00:23:49,570 --> 00:23:50,540 or things like this. 505 00:23:50,540 --> 00:23:52,780 And the most important advice I can give today 506 00:23:52,780 --> 00:23:57,010 is just try not to get frustrated by those kinds of stupid things. 507 00:23:57,010 --> 00:23:58,880 It's a lot more interesting. 508 00:23:58,880 --> 00:24:01,900 It's a lot more useful in life to understand functions and loops 509 00:24:01,900 --> 00:24:04,600 and conditions and not to let yourself get frustrated 510 00:24:04,600 --> 00:24:08,870 by the more minor aesthetic things that honestly will just come with practice. 511 00:24:08,870 --> 00:24:11,890 So if the very first mistake you make is missing a semicolon, 512 00:24:11,890 --> 00:24:14,650 and it takes you 10 minutes, an hour to figure out what 513 00:24:14,650 --> 00:24:16,900 is wrong with your code, totally normal. 514 00:24:16,900 --> 00:24:21,670 And those frustrations go away quite quickly in time. 515 00:24:21,670 --> 00:24:25,330 So we then have this translation of one function to another. 516 00:24:25,330 --> 00:24:27,550 Where else can we take it from here? 517 00:24:27,550 --> 00:24:29,590 Well, let's take a look at one other translation 518 00:24:29,590 --> 00:24:31,600 that we used after that ask block. 519 00:24:31,600 --> 00:24:34,120 Last week, after we asked the human their name, 520 00:24:34,120 --> 00:24:37,630 as by providing an input to the function and getting some output, 521 00:24:37,630 --> 00:24:44,050 we then proceeded to do something with the return value or output of ask. 522 00:24:44,050 --> 00:24:46,030 Again, we asked the human their name. 523 00:24:46,030 --> 00:24:50,810 Scratch magically, last week, put the name into the answer variable. 524 00:24:50,810 --> 00:24:52,520 But then I did something with it. 525 00:24:52,520 --> 00:24:56,710 And this is what I mean to distinguish side effects, which just kind of happen 526 00:24:56,710 --> 00:24:58,900 to you, like something printing on the screen, 527 00:24:58,900 --> 00:25:04,400 like the cat saying something out of its mouth, versus a return value, 528 00:25:04,400 --> 00:25:07,780 which is a piece of information, like a name a human has typed 529 00:25:07,780 --> 00:25:13,310 in being stored somewhere where you, the programmer, can make use of it later. 530 00:25:13,310 --> 00:25:14,410 It's not happening to you. 531 00:25:14,410 --> 00:25:16,840 It's being handed to you for subsequent use. 532 00:25:16,840 --> 00:25:20,650 And last week, in order to say hello comma world all in one breath, 533 00:25:20,650 --> 00:25:23,560 so to speak, we kind of had to stack these puzzle pieces 534 00:25:23,560 --> 00:25:27,700 on top of one another, making the output of join the input of say. 535 00:25:27,700 --> 00:25:31,810 In C, this is actually a little easier even though it's some new syntax. 536 00:25:31,810 --> 00:25:34,450 Again, printf is going to be the analog for say. 537 00:25:34,450 --> 00:25:36,660 And we've seen that a moment ago. 538 00:25:36,660 --> 00:25:38,410 We're still going to have the parentheses. 539 00:25:38,410 --> 00:25:40,077 We're still going to have the semicolon. 540 00:25:40,077 --> 00:25:42,040 So what goes inside now the input? 541 00:25:42,040 --> 00:25:46,120 How do I provide hello, answer to C? 542 00:25:46,120 --> 00:25:50,500 Well, I'm going to go ahead and do hello, in double quotes, but then, 543 00:25:50,500 --> 00:25:54,670 this strange new syntax here, %s. 544 00:25:54,670 --> 00:25:59,170 This is what we're going to call a format code, a format code, and hence 545 00:25:59,170 --> 00:26:01,125 the f in printf. 546 00:26:01,125 --> 00:26:02,500 Printf doesn't just print things. 547 00:26:02,500 --> 00:26:04,880 It can print format codes as well. 548 00:26:04,880 --> 00:26:09,880 And this is just fancy syntax for saying plug in some actual value here. 549 00:26:09,880 --> 00:26:12,010 Don't print out s literally. 550 00:26:12,010 --> 00:26:16,143 This is a placeholder for what will be s, a string. 551 00:26:16,143 --> 00:26:17,560 Well, what do I want to put there? 552 00:26:17,560 --> 00:26:18,700 Here's something new, too. 553 00:26:18,700 --> 00:26:21,250 In Scratch, if you had two inputs to a function, 554 00:26:21,250 --> 00:26:24,010 you would have two ovals like this and this one 555 00:26:24,010 --> 00:26:28,060 here that you could either type words or numbers into or drag variables into. 556 00:26:28,060 --> 00:26:31,660 In C, there's no notion of ovals or graphics at all. 557 00:26:31,660 --> 00:26:34,900 So instead, we're just going to go old school and just use a comma. 558 00:26:34,900 --> 00:26:39,580 If you use a comma in between the parentheses as the arguments 559 00:26:39,580 --> 00:26:43,030 or inputs to a function, that's going to separate the one on the left 560 00:26:43,030 --> 00:26:45,970 from the one on the right, thereby being analogous to having 561 00:26:45,970 --> 00:26:48,400 two ovals in the world of Scratch now there's 562 00:26:48,400 --> 00:26:51,220 something that's potentially a little visually confusing here. 563 00:26:51,220 --> 00:26:54,980 There's actually two commas here, of course, and here. 564 00:26:54,980 --> 00:26:56,560 But notice the important detail. 565 00:26:56,560 --> 00:26:59,710 That first one, that's an English grammatical comma 566 00:26:59,710 --> 00:27:04,900 that I've put inside of my quoted string, my quoted phrase of text. 567 00:27:04,900 --> 00:27:06,817 That has nothing to do with programming. 568 00:27:06,817 --> 00:27:08,650 That just has everything to do with English. 569 00:27:08,650 --> 00:27:11,440 The fact that this comma is outside of those double quotes, 570 00:27:11,440 --> 00:27:14,620 though, means it's significant in this language called C. 571 00:27:14,620 --> 00:27:18,710 And it separates first argument from second argument. 572 00:27:18,710 --> 00:27:20,770 And so in this way do we have the ability now 573 00:27:20,770 --> 00:27:28,260 to also say something on the screen using printf in this slightly new way. 574 00:27:28,260 --> 00:27:31,900 So let me go ahead then and do this for real. 575 00:27:31,900 --> 00:27:34,930 Let me go back to CS50 IDE. 576 00:27:34,930 --> 00:27:37,780 And I'm going to go ahead and go back into this program 577 00:27:37,780 --> 00:27:39,970 here and consider for just a moment how we 578 00:27:39,970 --> 00:27:43,780 can improve upon this very first program which literally just prints 579 00:27:43,780 --> 00:27:44,500 hello, world. 580 00:27:44,500 --> 00:27:45,487 Not that interesting. 581 00:27:45,487 --> 00:27:46,570 I can run it all day long. 582 00:27:46,570 --> 00:27:48,170 It's going to say the same thing. 583 00:27:48,170 --> 00:27:50,710 How do I now get input from the user? 584 00:27:50,710 --> 00:27:55,040 Well, it turns out that I can simply enhance this code a little bit. 585 00:27:55,040 --> 00:27:59,290 Let me go ahead and per the translation of Scratch earlier, 586 00:27:59,290 --> 00:28:05,650 let me do something like string answer equals get_string("What's your name?"). 587 00:28:05,650 --> 00:28:08,320 588 00:28:08,320 --> 00:28:11,380 So I'm literally typing out what we saw in C a moment ago. 589 00:28:11,380 --> 00:28:13,940 I'm going to remember my semicolon over here. 590 00:28:13,940 --> 00:28:17,630 And then I have to change this second line of code now to not say hello, 591 00:28:17,630 --> 00:28:21,350 world, but instead to say hello, %s. 592 00:28:21,350 --> 00:28:24,620 And then, outside of the double quotes, I'm going to do a comma 593 00:28:24,620 --> 00:28:28,070 and then provide literally the word answer, which 594 00:28:28,070 --> 00:28:29,750 is the name of that variable. 595 00:28:29,750 --> 00:28:30,953 But I'm not quite done. 596 00:28:30,953 --> 00:28:32,120 And this is a little subtle. 597 00:28:32,120 --> 00:28:34,385 And invariably, you'll forget this at some point, too. 598 00:28:34,385 --> 00:28:37,610 In order to use get_string, I have to use this thing 599 00:28:37,610 --> 00:28:40,730 called the CS50 library, code that the staff wrote 600 00:28:40,730 --> 00:28:42,470 that you don't have default access to. 601 00:28:42,470 --> 00:28:45,230 And in order to do that, I need to add one line of code 602 00:28:45,230 --> 00:28:47,400 that we'll explain in more detail in a little bit. 603 00:28:47,400 --> 00:28:51,230 But for now, just take it on faith that by adding this line of code 604 00:28:51,230 --> 00:28:55,370 at the very top, include CS50.h, that will now 605 00:28:55,370 --> 00:28:59,360 give me access to the get_string function, which I otherwise 606 00:28:59,360 --> 00:29:00,412 wouldn't have access to. 607 00:29:00,412 --> 00:29:02,870 All right, now I'm going to go back to the terminal window. 608 00:29:02,870 --> 00:29:04,370 And notice the dichotomy here. 609 00:29:04,370 --> 00:29:07,502 If I just run ./hello, sort of enthusiastically, 610 00:29:07,502 --> 00:29:08,960 let's see what my new program does. 611 00:29:08,960 --> 00:29:11,522 I'm about to be, unfortunately, disappointed. 612 00:29:11,522 --> 00:29:12,980 Because it still says hello, world. 613 00:29:12,980 --> 00:29:15,770 And you might realize intuitively what the problem, of course, 614 00:29:15,770 --> 00:29:19,512 here is I haven't actually recompiled to the code. 615 00:29:19,512 --> 00:29:21,470 And so any time you make a change to your code, 616 00:29:21,470 --> 00:29:25,370 it does not suffice to just save the file via file save or Control 617 00:29:25,370 --> 00:29:27,770 or Command-s, I need to recompile it. 618 00:29:27,770 --> 00:29:30,540 And to recompile my code, that's not such a big deal. 619 00:29:30,540 --> 00:29:33,170 I just type make hello, enter. 620 00:29:33,170 --> 00:29:36,050 Cross my fingers that there's no yellow or red scary text. 621 00:29:36,050 --> 00:29:37,430 This is all good. 622 00:29:37,430 --> 00:29:40,010 It seems to have compiled into machine code. 623 00:29:40,010 --> 00:29:42,860 Now I can retype ./hello. 624 00:29:42,860 --> 00:29:43,790 and enter. 625 00:29:43,790 --> 00:29:46,400 And you'll see now my program is running and waiting for me. 626 00:29:46,400 --> 00:29:50,182 Let me go ahead and type my name, David enter hello, David. 627 00:29:50,182 --> 00:29:52,640 Let me go ahead and run it again after clearing the screen. 628 00:29:52,640 --> 00:29:53,473 Let me run it again. 629 00:29:53,473 --> 00:29:55,520 And this time, let's say my name is Brian. 630 00:29:55,520 --> 00:29:57,508 And I say hello, Brian. 631 00:29:57,508 --> 00:29:59,300 So quite similar to what we did in Scratch, 632 00:29:59,300 --> 00:30:05,690 but now we're more powerfully doing this all thus far via my keyboard alone. 633 00:30:05,690 --> 00:30:07,490 All right, so that was a lot. 634 00:30:07,490 --> 00:30:10,190 We wrote hello, world super quickly off the top of my memory 635 00:30:10,190 --> 00:30:12,650 and then enhanced it to now take input from the user. 636 00:30:12,650 --> 00:30:13,940 Let me pause here. 637 00:30:13,940 --> 00:30:16,160 If there are any questions, you're welcome to ask 638 00:30:16,160 --> 00:30:18,950 via chat for either staff or classmates to answer. 639 00:30:18,950 --> 00:30:22,430 But if you'd like to raise your virtual hand in Zoom, 640 00:30:22,430 --> 00:30:28,990 please feel free so that I can clarify or expound on anything here. 641 00:30:28,990 --> 00:30:31,235 Yeah, question from Ryan? 642 00:30:31,235 --> 00:30:32,860 AUDIENCE: I had asked this in the chat. 643 00:30:32,860 --> 00:30:37,460 But so the string before the answer, that's not the name of the variable. 644 00:30:37,460 --> 00:30:44,360 So hypothetically, you could make it, like, string A or string anything else. 645 00:30:44,360 --> 00:30:47,375 It just matters what comes after string is the name of the variable? 646 00:30:47,375 --> 00:30:48,250 DAVID MALAN: Exactly. 647 00:30:48,250 --> 00:30:49,180 Really good question. 648 00:30:49,180 --> 00:30:52,390 In the world of Scratch, you were required 649 00:30:52,390 --> 00:30:54,310 to use the variable called "answer." 650 00:30:54,310 --> 00:30:57,980 In C, we have the complete flexibility over what we want to do. 651 00:30:57,980 --> 00:31:02,652 So as Ryan proposed, I could change my variable's name to just A for short. 652 00:31:02,652 --> 00:31:04,360 I would have to change it elsewhere, too, 653 00:31:04,360 --> 00:31:06,970 to make clear that the variable being used 654 00:31:06,970 --> 00:31:08,560 is the same one by a different name. 655 00:31:08,560 --> 00:31:09,760 That's perfectly fine. 656 00:31:09,760 --> 00:31:15,280 But here's where we now get into a matter of better style. 657 00:31:15,280 --> 00:31:19,390 Having a variable called just A, it doesn't really lend itself 658 00:31:19,390 --> 00:31:20,780 to the readability of your code. 659 00:31:20,780 --> 00:31:22,572 I might now glance at my code and be, like, 660 00:31:22,572 --> 00:31:24,850 what is the variable A. It's a little better when 661 00:31:24,850 --> 00:31:27,910 it comes to writing good code to actually be more verbose 662 00:31:27,910 --> 00:31:31,120 and using an actual word like "answer" in this case. 663 00:31:31,120 --> 00:31:34,030 Indeed, even though I keep describing x and y and z as the go 664 00:31:34,030 --> 00:31:36,160 to variables for a mathematician, those really 665 00:31:36,160 --> 00:31:39,200 say nothing outside the context of a Cartesian plane. 666 00:31:39,200 --> 00:31:42,880 So in a program that you write in C or Scratch or anything else, 667 00:31:42,880 --> 00:31:48,280 using descriptive variable names is a matter of good style as well. 668 00:31:48,280 --> 00:31:49,665 Jonathan, over to you. 669 00:31:49,665 --> 00:31:50,290 AUDIENCE: Yeah. 670 00:31:50,290 --> 00:31:51,290 Just a quick question. 671 00:31:51,290 --> 00:31:54,640 How come we have to compile the code every single time? 672 00:31:54,640 --> 00:31:57,310 And unlike different IDEs, which if you just run the code, 673 00:31:57,310 --> 00:31:59,020 it automatically compiles. 674 00:31:59,020 --> 00:32:00,470 Why do we have to manually do it? 675 00:32:00,470 --> 00:32:00,950 DAVID MALAN: Yeah. 676 00:32:00,950 --> 00:32:01,875 Really good question. 677 00:32:01,875 --> 00:32:03,750 Why do you have to keep recompiling the code? 678 00:32:03,750 --> 00:32:07,990 The short answer is just because this is the way C is. 679 00:32:07,990 --> 00:32:10,600 It's an older language, decades now old. 680 00:32:10,600 --> 00:32:13,300 And so back then, everything was very deliberate. 681 00:32:13,300 --> 00:32:15,370 User interface was not the top priority. 682 00:32:15,370 --> 00:32:17,750 Performance instead was, for instance. 683 00:32:17,750 --> 00:32:21,340 And so nowadays, there are fancier integrated development environments. 684 00:32:21,340 --> 00:32:25,510 And some of you might have used things like codecademy online, or co.org, 685 00:32:25,510 --> 00:32:28,450 where there's very often literally a play button that you can just 686 00:32:28,450 --> 00:32:31,300 click in the user interface, and it just plays your program 687 00:32:31,300 --> 00:32:32,665 or runs your program. 688 00:32:32,665 --> 00:32:34,540 What we're doing in this class is showing you 689 00:32:34,540 --> 00:32:36,320 what those buttons are doing. 690 00:32:36,320 --> 00:32:39,880 So if you do use in an environment like that that seems to automate this, 691 00:32:39,880 --> 00:32:40,755 it's still happening. 692 00:32:40,755 --> 00:32:43,463 But for our purposes, certainly at the beginning of the semester, 693 00:32:43,463 --> 00:32:45,400 we're going to do it manually ourselves. 694 00:32:45,400 --> 00:32:48,275 Later in the term, when we introduce a different language altogether, 695 00:32:48,275 --> 00:32:51,110 for instance, Python, then kind of, sort of you 696 00:32:51,110 --> 00:32:55,150 don't need to compile anymore, but more on that in a few weeks. 697 00:32:55,150 --> 00:32:56,050 Good question. 698 00:32:56,050 --> 00:32:56,920 Sophia? 699 00:32:56,920 --> 00:32:57,933 Over to you. 700 00:32:57,933 --> 00:32:59,350 AUDIENCE: I had a question about-- 701 00:32:59,350 --> 00:33:01,058 I noticed in the source code that there's 702 00:33:01,058 --> 00:33:04,390 a backslash like n at the end of the string. 703 00:33:04,390 --> 00:33:07,503 Is that necessary for every time, even if it's just one line? 704 00:33:07,503 --> 00:33:08,920 DAVID MALAN: Really good question. 705 00:33:08,920 --> 00:33:12,310 This backslash n that you're seeing elsewhere, a bit of a spoiler. 706 00:33:12,310 --> 00:33:15,370 But yeah, let's go ahead and fix this problem that we've seen, 707 00:33:15,370 --> 00:33:16,990 even though I'm kind of ignoring it. 708 00:33:16,990 --> 00:33:18,893 You know, this now gets a little particular. 709 00:33:18,893 --> 00:33:20,560 But this looks kind of stupid, honestly. 710 00:33:20,560 --> 00:33:23,620 It says hello, Brian tilde slash dollar sign. 711 00:33:23,620 --> 00:33:25,630 Like, that is not my intended output. 712 00:33:25,630 --> 00:33:28,900 I literally only wanted to say hello, Brian, or hello, David. 713 00:33:28,900 --> 00:33:32,995 This visual artifact here, the dollar sign and the tilde and the slash 714 00:33:32,995 --> 00:33:36,015 have to do with my terminal window, this command line environment 715 00:33:36,015 --> 00:33:36,640 that I'm using. 716 00:33:36,640 --> 00:33:38,890 And honestly, just to be a little nitpicky, 717 00:33:38,890 --> 00:33:40,870 frankly, it should probably be on a new line. 718 00:33:40,870 --> 00:33:45,190 It should just be on its own line so it's not confused with my own output. 719 00:33:45,190 --> 00:33:48,260 And as Sophie notes, there is a solution to this. 720 00:33:48,260 --> 00:33:51,910 But, again, per last week, you need to m when writing algorithms 721 00:33:51,910 --> 00:33:54,610 and in turn, code, you have to be super precise. 722 00:33:54,610 --> 00:33:57,640 Nowhere in my code have I told the computer 723 00:33:57,640 --> 00:33:59,950 to move the cursor to the next line. 724 00:33:59,950 --> 00:34:07,540 So I can do that explicitly by doing backslash n immediately after the %s 725 00:34:07,540 --> 00:34:09,980 but still inside of the double quotes. 726 00:34:09,980 --> 00:34:13,900 This is shorthand notation for what would be telling the computer, 727 00:34:13,900 --> 00:34:15,860 move the cursor to the next line. 728 00:34:15,860 --> 00:34:19,100 Now you might think that, well, why don't I just hit Enter like this? 729 00:34:19,100 --> 00:34:23,199 And even though this is all might be new to most of us, suffice it to say 730 00:34:23,199 --> 00:34:25,510 this just feels like it's going to get messy quickly. 731 00:34:25,510 --> 00:34:27,909 If you start hitting Enter in the middle of your code, 732 00:34:27,909 --> 00:34:29,659 that's probably not the right solution. 733 00:34:29,659 --> 00:34:32,320 So instead, programmers years ago decided 734 00:34:32,320 --> 00:34:35,590 to come up with shorthand notation like backslash n, otherwise known 735 00:34:35,590 --> 00:34:41,800 as an escape character that signals to the computer, put a new line here. 736 00:34:41,800 --> 00:34:43,780 So backslash n is new line. 737 00:34:43,780 --> 00:34:45,489 And let me go ahead and recompile this. 738 00:34:45,489 --> 00:34:50,230 After saving my file, let me go ahead and do make hello. 739 00:34:50,230 --> 00:34:52,210 It seems to compile OK. ./hello. 740 00:34:52,210 --> 00:34:54,400 And let me go ahead and type in Brian's name again. 741 00:34:54,400 --> 00:34:58,010 And voila, still the same output, but it's a little cleaner. 742 00:34:58,010 --> 00:35:00,880 So we're being a little bit better about housekeeping now. 743 00:35:00,880 --> 00:35:03,580 Really good question. 744 00:35:03,580 --> 00:35:06,207 BJ is it? 745 00:35:06,207 --> 00:35:06,790 AUDIENCE: Yes. 746 00:35:06,790 --> 00:35:09,610 So one question I had is why don't you have 747 00:35:09,610 --> 00:35:13,930 to call the function get string in order for you for it to ask for input? 748 00:35:13,930 --> 00:35:17,485 Like, it still asked your input when you assigned it to the variable answer. 749 00:35:17,485 --> 00:35:19,068 DAVID MALAN: Ah, really good question. 750 00:35:19,068 --> 00:35:21,310 Why don't I have to call get string, for instance, 751 00:35:21,310 --> 00:35:23,680 by putting it on a line of its own? 752 00:35:23,680 --> 00:35:28,150 The way that C and a lot of programming languages work is they 753 00:35:28,150 --> 00:35:31,150 will evaluate an entire line of code, for instance, 754 00:35:31,150 --> 00:35:36,370 what I have here on line six from right to left, at least in this context. 755 00:35:36,370 --> 00:35:39,730 When you have an equal sign in the code like I do here, 756 00:35:39,730 --> 00:35:43,000 that's telling the computer you first have to execute, 757 00:35:43,000 --> 00:35:45,640 that is do what is said on the right-hand side. 758 00:35:45,640 --> 00:35:47,800 And then whatever the output of that thing is, 759 00:35:47,800 --> 00:35:49,880 store it on the left-hand side. 760 00:35:49,880 --> 00:35:53,470 So it is indeed getting executed, we're just now spreading things out 761 00:35:53,470 --> 00:35:57,560 on longer lines of code, if you will, if that makes sense. 762 00:35:57,560 --> 00:36:02,800 So get string is getting executed because it appears on that line. 763 00:36:02,800 --> 00:36:03,310 All right. 764 00:36:03,310 --> 00:36:05,230 So we've been taking for granted, frankly, 765 00:36:05,230 --> 00:36:08,110 a few details of these programs that it's probably 766 00:36:08,110 --> 00:36:09,790 only fair to start teasing apart. 767 00:36:09,790 --> 00:36:11,740 For instance, there was that int, main, void, 768 00:36:11,740 --> 00:36:13,210 and a whole bunch of other syntax. 769 00:36:13,210 --> 00:36:15,730 So let's tease apart some of these other lines of code 770 00:36:15,730 --> 00:36:18,760 that I just typed off the top of my head from memory, but kind of do 771 00:36:18,760 --> 00:36:21,143 need to be there in every C program you write. 772 00:36:21,143 --> 00:36:23,560 Let's at least start to make sense of some of that detail. 773 00:36:23,560 --> 00:36:27,250 Recall that in Scratch, we always started our programs initially 774 00:36:27,250 --> 00:36:29,320 with when green flag clicked. 775 00:36:29,320 --> 00:36:34,000 We eventually saw some other puzzle pieces, like when you hear an event, 776 00:36:34,000 --> 00:36:36,160 or when there's camera motion. 777 00:36:36,160 --> 00:36:40,330 But this really kick started most of the programs that we wrote in Scratch. 778 00:36:40,330 --> 00:36:45,340 What is the analog in C of the when green flag clicked puzzle piece? 779 00:36:45,340 --> 00:36:46,540 It's essentially this. 780 00:36:46,540 --> 00:36:49,120 We won't spend time in detail today explaining 781 00:36:49,120 --> 00:36:53,170 why it's int, why it's void, why there's curly braces, why there's parentheses. 782 00:36:53,170 --> 00:36:55,870 For today's purposes only, let me just stipulate 783 00:36:55,870 --> 00:37:00,160 that this is the analog for this when green flag clicked puzzle piece. 784 00:37:00,160 --> 00:37:02,260 You've just got to start your programs initially 785 00:37:02,260 --> 00:37:04,750 with this kind of boilerplate code, so to speak. 786 00:37:04,750 --> 00:37:07,092 We will start to explain this in much more detail. 787 00:37:07,092 --> 00:37:08,800 But for now, just take on faith that this 788 00:37:08,800 --> 00:37:10,630 is how you start writing a program. 789 00:37:10,630 --> 00:37:14,260 But there's, of course, a little more to the programs we've written thus far. 790 00:37:14,260 --> 00:37:17,780 And particularly, we've seen a couple of things called header files. 791 00:37:17,780 --> 00:37:22,480 This is another term of art that refers to a file written in the language 792 00:37:22,480 --> 00:37:27,580 called C whose name ends with not .c, but with .h. 793 00:37:27,580 --> 00:37:30,740 So we've seen these before as follows. 794 00:37:30,740 --> 00:37:33,910 Here, recall, was the simplest program we wrote last week in Scratch. 795 00:37:33,910 --> 00:37:37,030 It just says hello, world when you clicked on the green flag. 796 00:37:37,030 --> 00:37:40,270 This is the analog, the more complete analog on the right, 797 00:37:40,270 --> 00:37:42,190 of that program today. 798 00:37:42,190 --> 00:37:43,540 But there's something missing. 799 00:37:43,540 --> 00:37:45,950 And it's probably jumping out at some of you, 800 00:37:45,950 --> 00:37:48,850 because the program is a little shorter than it was before. 801 00:37:48,850 --> 00:37:51,170 Something's missing, which is this line here. 802 00:37:51,170 --> 00:37:54,490 And I just wrote that from memory earlier, but it's referring to a file 803 00:37:54,490 --> 00:38:00,760 called stdio.h, which stands for standard input output dot h. 804 00:38:00,760 --> 00:38:03,190 So io is an acronym in the computer world 805 00:38:03,190 --> 00:38:05,360 that just generally refers to input and output. 806 00:38:05,360 --> 00:38:10,150 So standard io.h is just a very popular file 807 00:38:10,150 --> 00:38:12,910 that is used in C programs that gives you the ability 808 00:38:12,910 --> 00:38:15,370 to get input and output from the user. 809 00:38:15,370 --> 00:38:17,502 And it does so by providing you with printf, 810 00:38:17,502 --> 00:38:19,210 for instance, which of course, allows you 811 00:38:19,210 --> 00:38:22,270 to generate some form of output via those side effects 812 00:38:22,270 --> 00:38:23,770 that we described earlier. 813 00:38:23,770 --> 00:38:25,780 But when I wrote my other program, recall, 814 00:38:25,780 --> 00:38:28,630 that actually had get string, as BJ noted earlier, 815 00:38:28,630 --> 00:38:31,270 where I can get a line of text from the user, 816 00:38:31,270 --> 00:38:33,130 I needed something else altogether. 817 00:38:33,130 --> 00:38:37,570 And that's when we added, a moment ago, a second header file called CS50.h. 818 00:38:37,570 --> 00:38:41,770 So these header files just give you access to more functions 819 00:38:41,770 --> 00:38:45,590 than you might automatically get from the language you're using, 820 00:38:45,590 --> 00:38:46,840 which here is C. 821 00:38:46,840 --> 00:38:48,880 It's similar in spirit, recall last week, 822 00:38:48,880 --> 00:38:51,850 when I started poking around Scratch's extension menu 823 00:38:51,850 --> 00:38:55,420 and I used the translate block and the voice block, 824 00:38:55,420 --> 00:38:59,230 the sort of fancier features that were buried under the extensions menu. 825 00:38:59,230 --> 00:39:04,240 Using an extension in Scratch is similar to using a header file in C. 826 00:39:04,240 --> 00:39:08,140 It's giving me access to a bit more functionality than you otherwise get 827 00:39:08,140 --> 00:39:12,320 for free out of the box, so to speak. 828 00:39:12,320 --> 00:39:14,680 All right, well, let me go ahead and propose 829 00:39:14,680 --> 00:39:17,740 that there are so many different ways in which I 830 00:39:17,740 --> 00:39:22,240 could have screwed up over the past few minutes of writing these programs. 831 00:39:22,240 --> 00:39:24,790 I might have omitted a semicolon, as I implied. 832 00:39:24,790 --> 00:39:26,650 I might have not closed my quotes. 833 00:39:26,650 --> 00:39:28,450 I might have gotten my parentheses wrong. 834 00:39:28,450 --> 00:39:30,430 I might have misspelled words altogether. 835 00:39:30,430 --> 00:39:33,340 There's many different ways I could have screwed that program up. 836 00:39:33,340 --> 00:39:36,673 And frankly, off the record, I'm sort of crossing my fingers that I didn't screw 837 00:39:36,673 --> 00:39:38,230 up our very first program together. 838 00:39:38,230 --> 00:39:41,950 But invariably, at some point, maybe not your first program, 839 00:39:41,950 --> 00:39:46,000 but early on in learning how to program or learning how to program in C, 840 00:39:46,000 --> 00:39:47,050 you will screw up. 841 00:39:47,050 --> 00:39:48,730 And you're going to make some typo. 842 00:39:48,730 --> 00:39:51,758 There's going to be some disconnect between what your understanding is 843 00:39:51,758 --> 00:39:53,800 and what you're trying to get the computer to do. 844 00:39:53,800 --> 00:39:56,710 And this is to say there are tools, thankfully, 845 00:39:56,710 --> 00:39:59,260 that can help you solve those problems. 846 00:39:59,260 --> 00:40:01,060 And the first of which is called help50. 847 00:40:01,060 --> 00:40:04,150 Any of the tools whose names end with 50 are specifically 848 00:40:04,150 --> 00:40:07,930 educationally oriented, written by CS50 staff, that are temporary training 849 00:40:07,930 --> 00:40:10,520 wheels that we'll use for the first several weeks of the class 850 00:40:10,520 --> 00:40:13,360 but then eventually, optionally, take away in the sense 851 00:40:13,360 --> 00:40:15,470 that you won't need them anymore. 852 00:40:15,470 --> 00:40:17,620 And so help50 is one command that's going 853 00:40:17,620 --> 00:40:20,920 to allow you to troubleshoot problems that you might not otherwise 854 00:40:20,920 --> 00:40:24,020 see obviously in your own code. 855 00:40:24,020 --> 00:40:27,440 And let me go and simulate this as follows. 856 00:40:27,440 --> 00:40:29,980 Let me go back to the very first program that we 857 00:40:29,980 --> 00:40:34,583 wrote in C, which was quite simply this one whereby it only said hello, world. 858 00:40:34,583 --> 00:40:37,250 And there's a few different places I could have screwed up here. 859 00:40:37,250 --> 00:40:39,940 For instance, suppose I was getting a little ahead of myself 860 00:40:39,940 --> 00:40:45,250 and I admitted the standard io.h file at the top of my program. 861 00:40:45,250 --> 00:40:48,820 The implication is that now my computer is not 862 00:40:48,820 --> 00:40:54,370 going to know what printf is, because it hasn't been included via standard io.h. 863 00:40:54,370 --> 00:40:56,530 So let's see what the error message is. 864 00:40:56,530 --> 00:40:58,810 Hopefully, it'll be a very self-explanatory message 865 00:40:58,810 --> 00:41:00,260 that makes perfect sense. 866 00:41:00,260 --> 00:41:02,260 Let me go ahead and recompile this program, 867 00:41:02,260 --> 00:41:04,300 knowing it already to be incorrect. 868 00:41:04,300 --> 00:41:05,320 And oh, my God. 869 00:41:05,320 --> 00:41:10,310 Like, I have more lines of errors than I actually have lines of code. 870 00:41:10,310 --> 00:41:15,010 And this is kind of a reality of programming. 871 00:41:15,010 --> 00:41:17,410 A lot of programming languages, a lot of tools, 872 00:41:17,410 --> 00:41:20,470 frankly, were not designed with ease of use in mind, 873 00:41:20,470 --> 00:41:22,120 or user-friendliness in mind. 874 00:41:22,120 --> 00:41:25,150 They were really designed with succinctness and precision in mind. 875 00:41:25,150 --> 00:41:28,420 And they tend, unfortunately, to assume that the audience is 876 00:41:28,420 --> 00:41:30,702 as technical as the person who wrote the program. 877 00:41:30,702 --> 00:41:33,160 This, of course, can backfire when you're just learning how 878 00:41:33,160 --> 00:41:34,952 to program in the first place, and you have 879 00:41:34,952 --> 00:41:37,810 to make sense of crazy cryptic output like this. 880 00:41:37,810 --> 00:41:40,570 Today we don't have to focus on every single word that's 881 00:41:40,570 --> 00:41:43,600 been outputted on the screen, but let's start to recognize patterns. 882 00:41:43,600 --> 00:41:45,670 Walking into a new space and just recognizing 883 00:41:45,670 --> 00:41:49,120 familiar objects in the physical world, let's now do that with code. 884 00:41:49,120 --> 00:41:53,740 The most important thing, perhaps, to take notice of is that when you mess up 885 00:41:53,740 --> 00:41:56,980 and you make some mistake in your code such that your program doesn't even 886 00:41:56,980 --> 00:41:59,650 compile from source code into machine code, 887 00:41:59,650 --> 00:42:03,520 odds are you're going to see a clue toward the top of the erroneous output 888 00:42:03,520 --> 00:42:05,890 that tells you the name of the file where you messed up 889 00:42:05,890 --> 00:42:07,990 and the line number where you messed up. 890 00:42:07,990 --> 00:42:11,350 Three implying line three, and then five might 891 00:42:11,350 --> 00:42:14,530 imply what column or what character in that line, 892 00:42:14,530 --> 00:42:17,900 but it depends on the particular problem if that's that useful. 893 00:42:17,900 --> 00:42:22,510 So on line three, I am getting an error, implicitly declaring library function 894 00:42:22,510 --> 00:42:25,090 printf with type int const char star. 895 00:42:25,090 --> 00:42:27,550 I mean, like, who knows what that even means? 896 00:42:27,550 --> 00:42:29,060 You will eventually. 897 00:42:29,060 --> 00:42:31,780 But for today, it just means something bad went wrong. 898 00:42:31,780 --> 00:42:32,980 And you might not see it. 899 00:42:32,980 --> 00:42:35,050 You might not know, if I hadn't told you, 900 00:42:35,050 --> 00:42:37,135 that I intentionally deleted that line. 901 00:42:37,135 --> 00:42:39,760 So let's see if we can't make sense of this by using this tool. 902 00:42:39,760 --> 00:42:42,820 Help50 is a tool written by CS50 staff that 903 00:42:42,820 --> 00:42:46,570 will help translate arcane cryptic computer 904 00:42:46,570 --> 00:42:51,010 messages to more human friendly advice and questions 905 00:42:51,010 --> 00:42:54,070 that you're teaching fellow or teaching assistant might offer you, 906 00:42:54,070 --> 00:42:56,030 say, in the context of office hours. 907 00:42:56,030 --> 00:42:59,740 So to use help50, instead of running the same command again and again 908 00:42:59,740 --> 00:43:03,130 and seeing the same erroneous output, literally just right help50 909 00:43:03,130 --> 00:43:07,960 first, at your terminal window, then write the same exact command 910 00:43:07,960 --> 00:43:11,320 that you're struggling with for whatever reason, and hit Enter then. 911 00:43:11,320 --> 00:43:14,110 And what will happen is the same command will get run. 912 00:43:14,110 --> 00:43:18,340 We will analyze, using the help50 program, what that output is. 913 00:43:18,340 --> 00:43:20,950 And we'll try to highlight in yellow the stuff we recognize. 914 00:43:20,950 --> 00:43:23,290 And then translate it to more human friendly language. 915 00:43:23,290 --> 00:43:27,460 For instance, after running help50, we're asking for help, dot dot dot. 916 00:43:27,460 --> 00:43:29,170 In yellow here is the thing we recognize, 917 00:43:29,170 --> 00:43:31,660 oh, the staff have seen this problem before. 918 00:43:31,660 --> 00:43:36,700 And then down here, did you forget to include stdio.h, in which printf 919 00:43:36,700 --> 00:43:38,710 is declared atop of your file? 920 00:43:38,710 --> 00:43:41,440 So hopefully, if we recognize the problem, 921 00:43:41,440 --> 00:43:43,690 we can guide you with this sort of rhetorical question 922 00:43:43,690 --> 00:43:45,250 that makes you realize, oh, yes. 923 00:43:45,250 --> 00:43:46,640 That's what I did wrong. 924 00:43:46,640 --> 00:43:50,380 So now I can go back up here, move to the top of my file, 925 00:43:50,380 --> 00:43:53,980 and add include stdio.h. 926 00:43:53,980 --> 00:43:59,373 And now notice, if I rerun make hello, voila, the problem is gone altogether. 927 00:43:59,373 --> 00:44:00,790 And we could do this all day long. 928 00:44:00,790 --> 00:44:02,207 There's so many places to mess up. 929 00:44:02,207 --> 00:44:04,120 For instance, I omit the semicolon now. 930 00:44:04,120 --> 00:44:06,910 Let me go ahead and make hello now without the semicolon. 931 00:44:06,910 --> 00:44:09,050 Now we're going to get a different error message. 932 00:44:09,050 --> 00:44:12,610 And you'll see, again, the name of the file where I messed up, hello.c. 933 00:44:12,610 --> 00:44:14,680 This time it's on line five. 934 00:44:14,680 --> 00:44:16,990 And that's true because the line numbers moved down 935 00:44:16,990 --> 00:44:18,640 after I added more stuff up there. 936 00:44:18,640 --> 00:44:21,637 And you can see expected semicolon after expression. 937 00:44:21,637 --> 00:44:23,470 So this one's a little more straightforward. 938 00:44:23,470 --> 00:44:25,210 But you could run help50 on this command, 939 00:44:25,210 --> 00:44:29,050 too, just to get back a little more explicit advice. 940 00:44:29,050 --> 00:44:31,960 So help50 will be your friend any time you 941 00:44:31,960 --> 00:44:36,220 are having trouble getting your code to actually compile. 942 00:44:36,220 --> 00:44:39,010 Well, let me do something else that's bad now. 943 00:44:39,010 --> 00:44:43,060 I've very deliberately been writing fairly pretty code. 944 00:44:43,060 --> 00:44:45,130 I've indented the word printf. 945 00:44:45,130 --> 00:44:47,320 I included some blank line up here. 946 00:44:47,320 --> 00:44:49,700 Just to make it clear, I've put these curly braces, 947 00:44:49,700 --> 00:44:51,520 so to speak, on their own lines. 948 00:44:51,520 --> 00:44:56,080 But frankly, my computer, or CS50 IDE is not so particular. 949 00:44:56,080 --> 00:44:58,570 I could technically get rid of this blank line. 950 00:44:58,570 --> 00:45:00,580 I could move this curly brace way up here. 951 00:45:00,580 --> 00:45:04,660 I could get rid of this indentation altogether and move it on its own line. 952 00:45:04,660 --> 00:45:07,000 And then I could just move this curly brace up here. 953 00:45:07,000 --> 00:45:12,340 Thereby writing a program that's now only two lines long, not six. 954 00:45:12,340 --> 00:45:15,040 But hopefully already, even if you've never programmed before, 955 00:45:15,040 --> 00:45:17,620 this should probably rub you the wrong way. 956 00:45:17,620 --> 00:45:19,510 This is like people in the real world that 957 00:45:19,510 --> 00:45:21,910 don't use punctuation in their social media posts 958 00:45:21,910 --> 00:45:23,500 or their emails or the text messages. 959 00:45:23,500 --> 00:45:25,170 They just kind of go on and on and on. 960 00:45:25,170 --> 00:45:27,168 And yes, the information is there. 961 00:45:27,168 --> 00:45:29,460 You can glean what it is they're trying to communicate. 962 00:45:29,460 --> 00:45:31,200 But my God, is it annoying. 963 00:45:31,200 --> 00:45:32,630 It's hard to read. 964 00:45:32,630 --> 00:45:35,130 There's probably a higher probability that there's a mistake 965 00:45:35,130 --> 00:45:38,560 and it's going to be harder to find it because things aren't nicely balanced 966 00:45:38,560 --> 00:45:41,200 on the left and on the right and on the top and the bottom. 967 00:45:41,200 --> 00:45:43,740 So this is what would be described as bad style. 968 00:45:43,740 --> 00:45:45,270 My program is still correct. 969 00:45:45,270 --> 00:45:49,030 I've got the stdio.h, I've got the semicolon, and everything else. 970 00:45:49,030 --> 00:45:50,310 But it's really bad style. 971 00:45:50,310 --> 00:45:51,720 Because it's just ugly. 972 00:45:51,720 --> 00:45:53,430 There's not much white space. 973 00:45:53,430 --> 00:45:55,560 There's not a lot of blank lines or indentation 974 00:45:55,560 --> 00:46:00,190 that just make it easier for you and I to read this thing from top to bottom. 975 00:46:00,190 --> 00:46:02,400 So notice, it does compile. 976 00:46:02,400 --> 00:46:06,840 So help50 is not going to help me fix this problem because it compiles OK. 977 00:46:06,840 --> 00:46:11,610 But it can run another program that we're going to call style50. 978 00:46:11,610 --> 00:46:13,470 This is another educationally oriented tool 979 00:46:13,470 --> 00:46:17,610 that's installed in CS50 IDE that allows you to figure out 980 00:46:17,610 --> 00:46:19,810 how to improve the style of your code. 981 00:46:19,810 --> 00:46:24,760 So when I run style50 on this prettier code, it indeed looks good. 982 00:46:24,760 --> 00:46:26,130 But it's still giving me advice. 983 00:46:26,130 --> 00:46:28,050 It's telling me to add something called comments. 984 00:46:28,050 --> 00:46:30,210 And a bunch of you figured this out in the world of Scratch. 985 00:46:30,210 --> 00:46:32,370 You can add little sticky notes or post-it notes 986 00:46:32,370 --> 00:46:34,530 to Scratch that are sort of notes to self 987 00:46:34,530 --> 00:46:38,310 that remind you what something does, or maybe explains to your teaching fellow 988 00:46:38,310 --> 00:46:40,170 or teaching assistant what something does. 989 00:46:40,170 --> 00:46:41,890 C supports these as well. 990 00:46:41,890 --> 00:46:45,270 So for instance, if I just wanted to be really pedantic here and make 991 00:46:45,270 --> 00:46:49,170 clear to the human reading my code what I'm trying to do, 992 00:46:49,170 --> 00:46:52,140 I could say something like greet user. 993 00:46:52,140 --> 00:46:53,790 And notice the syntax here. 994 00:46:53,790 --> 00:46:57,000 I've put a new line above my existing line of code, 995 00:46:57,000 --> 00:46:59,610 and I've similarly indented it so everything lines up 996 00:46:59,610 --> 00:47:01,260 visually beautifully. 997 00:47:01,260 --> 00:47:05,520 I've done slash slash, which says, hey, compiler, this is a comment. 998 00:47:05,520 --> 00:47:07,270 This is for human eyes only. 999 00:47:07,270 --> 00:47:09,690 This is not actual C code, per se. 1000 00:47:09,690 --> 00:47:10,917 Then I hit the spacebar. 1001 00:47:10,917 --> 00:47:12,750 And then I just typed out an English phrase. 1002 00:47:12,750 --> 00:47:14,610 And this could be any spoken language. 1003 00:47:14,610 --> 00:47:16,350 But I went ahead and typed greet user. 1004 00:47:16,350 --> 00:47:16,862 Why? 1005 00:47:16,862 --> 00:47:18,570 Well, it's just a reminder to myself what 1006 00:47:18,570 --> 00:47:22,330 the purpose of the following line of code is, to greet the user. 1007 00:47:22,330 --> 00:47:28,455 This is marginally better, for instance, than saying print hello, world. 1008 00:47:28,455 --> 00:47:30,330 And let me just ask you, even if you've never 1009 00:47:30,330 --> 00:47:34,350 programmed before why is the first comment a better 1010 00:47:34,350 --> 00:47:36,480 comment than the second? 1011 00:47:36,480 --> 00:47:40,650 Like, why should I say, if anything, greet user instead of print 1012 00:47:40,650 --> 00:47:43,800 hello, world in the form of these comments. 1013 00:47:43,800 --> 00:47:46,558 Yeah, Olivia, what do you think? 1014 00:47:46,558 --> 00:47:47,100 AUDIENCE: OK. 1015 00:47:47,100 --> 00:47:48,807 It tells you the purpose of the code. 1016 00:47:48,807 --> 00:47:51,390 DAVID MALAN: Yeah, the purpose of the code as opposed to what? 1017 00:47:51,390 --> 00:47:53,670 What distinction are you making? 1018 00:47:53,670 --> 00:47:56,475 AUDIENCE: Versus telling you exactly what it's doing. 1019 00:47:56,475 --> 00:47:57,600 DAVID MALAN: Yeah, exactly. 1020 00:47:57,600 --> 00:48:00,697 If your comment is almost identical to the actual code, 1021 00:48:00,697 --> 00:48:03,780 you're not really conveying much more information to the reader, let alone 1022 00:48:03,780 --> 00:48:05,460 yourself in the future. 1023 00:48:05,460 --> 00:48:09,120 Explaining it more generally, what the purpose of this line of code is to do, 1024 00:48:09,120 --> 00:48:11,730 is to greet the user, that's a little more descriptive. 1025 00:48:11,730 --> 00:48:14,070 Now to be super fair, honestly, this program 1026 00:48:14,070 --> 00:48:16,650 is so short that even though style50, yes, would 1027 00:48:16,650 --> 00:48:20,250 prefer that you add some comment, if your program really 1028 00:48:20,250 --> 00:48:23,730 reduces to one line of code, you probably don't need a comment here. 1029 00:48:23,730 --> 00:48:26,037 However, pretty much every other program we're 1030 00:48:26,037 --> 00:48:28,620 going to write here on after is going to be more than just one 1031 00:48:28,620 --> 00:48:30,690 main line of code, like this printf. 1032 00:48:30,690 --> 00:48:32,850 So it's going to make much more sense soon 1033 00:48:32,850 --> 00:48:36,000 to come that we're going to want to actually add 1034 00:48:36,000 --> 00:48:38,460 to our code some actual comments. 1035 00:48:38,460 --> 00:48:40,920 Well, let me introduce one final tool here 1036 00:48:40,920 --> 00:48:43,260 that will help us solve problems as we proceed now 1037 00:48:43,260 --> 00:48:45,000 to write more sophisticated programs. 1038 00:48:45,000 --> 00:48:46,080 And this is check50. 1039 00:48:46,080 --> 00:48:50,790 This is a tool specifically that you'll use either in labs or in problem sets, 1040 00:48:50,790 --> 00:48:53,160 the course's programming assignments, to actually check 1041 00:48:53,160 --> 00:48:54,910 the correctness of your code. 1042 00:48:54,910 --> 00:48:58,530 So whereas help50 just helps you compile your code typically, 1043 00:48:58,530 --> 00:49:01,410 when it's not compiling at all, style50 helps 1044 00:49:01,410 --> 00:49:04,560 you improve the style of your code, check50 1045 00:49:04,560 --> 00:49:09,060 will check the correctness of your code against some automated tests 1046 00:49:09,060 --> 00:49:12,690 that we, the staff, have written that are consistent with whatever 1047 00:49:12,690 --> 00:49:14,202 the homework problem actually is. 1048 00:49:14,202 --> 00:49:17,160 So we write some tests to make sure that your code is working correctly 1049 00:49:17,160 --> 00:49:19,200 as per our own specifications. 1050 00:49:19,200 --> 00:49:22,080 So how might I run check50? 1051 00:49:22,080 --> 00:49:25,440 This will totally depend on the problem set or the lab. 1052 00:49:25,440 --> 00:49:28,170 And we will always, in the problem set or lab, 1053 00:49:28,170 --> 00:49:30,543 tell you what command to type for check50. 1054 00:49:30,543 --> 00:49:33,210 It's not something you could necessarily figure out on your own. 1055 00:49:33,210 --> 00:49:35,580 I happen to remember that we have a check, that 1056 00:49:35,580 --> 00:49:40,560 is a test, called CS50/problems/hello. 1057 00:49:40,560 --> 00:49:42,870 Odds are you will never run this identical command. 1058 00:49:42,870 --> 00:49:46,920 Again, in the problem set or lab, we will always tell you what to type. 1059 00:49:46,920 --> 00:49:50,970 You won't know what otherwise to type unless we tell you what test to use. 1060 00:49:50,970 --> 00:49:55,500 This is going to now upload my file hello.c to a service called 1061 00:49:55,500 --> 00:49:58,050 GitHub, which again is a popular tool for sharing code. 1062 00:49:58,050 --> 00:50:00,150 We use it to collect submissions for this. 1063 00:50:00,150 --> 00:50:02,160 I'm going to then type in my password. 1064 00:50:02,160 --> 00:50:02,880 You won't see it. 1065 00:50:02,880 --> 00:50:05,940 You'll instead see asterisks or, like, bullets in a web page. 1066 00:50:05,940 --> 00:50:07,650 I'm going to go ahead and hit Enter then. 1067 00:50:07,650 --> 00:50:09,240 It's going to verify my code. 1068 00:50:09,240 --> 00:50:10,560 It's going to do some thinking. 1069 00:50:10,560 --> 00:50:13,218 It's uploading now, dot dot dot. 1070 00:50:13,218 --> 00:50:15,840 And now we're just waiting for the internet to respond. 1071 00:50:15,840 --> 00:50:18,390 Because somewhere on CS50 servers, we are 1072 00:50:18,390 --> 00:50:22,980 running your code after compiling your code, or in this case mine, 1073 00:50:22,980 --> 00:50:26,830 and making sure, yes, it actually behaved as it should have. 1074 00:50:26,830 --> 00:50:30,060 And what you'll typically see, hopefully, are a bunch of green smiley 1075 00:50:30,060 --> 00:50:33,990 faces saying yes, that your code exists, yes, that your code compiles, 1076 00:50:33,990 --> 00:50:36,450 and yes, for instance, it prints hello, world. 1077 00:50:36,450 --> 00:50:38,610 Sometimes you might see red frowny faces, 1078 00:50:38,610 --> 00:50:42,840 which means no, your code did not work exactly as it should, per the lab, 1079 00:50:42,840 --> 00:50:43,830 or of the problem set. 1080 00:50:43,830 --> 00:50:47,190 At which point, it's back to the drawing board on your part to figure out 1081 00:50:47,190 --> 00:50:49,450 exactly what needs to be fixed up here. 1082 00:50:49,450 --> 00:50:52,830 Sometimes you'll see yellow output with just a straight yellow face, which 1083 00:50:52,830 --> 00:50:55,710 just means we weren't even able to run a certain test 1084 00:50:55,710 --> 00:50:57,620 because some other test already failed. 1085 00:50:57,620 --> 00:51:00,630 So it's meant to be relatively quick feedback 1086 00:51:00,630 --> 00:51:05,440 on the correctness of your code before you even submit it and call it a day. 1087 00:51:05,440 --> 00:51:10,770 And check50 instructions will always be accompanied by the problem itself 1088 00:51:10,770 --> 00:51:13,150 in the lab or problem set. 1089 00:51:13,150 --> 00:51:15,420 So some final commands here now. 1090 00:51:15,420 --> 00:51:21,450 Within this terminal window, I can do more than just run make and ./hello, 1091 00:51:21,450 --> 00:51:23,220 or whatever my program's name is. 1092 00:51:23,220 --> 00:51:26,040 And I can do more than help50 and style50 1093 00:51:26,040 --> 00:51:30,510 and Check50 it turns out that I'm really using, in the form of CS50 IDE, 1094 00:51:30,510 --> 00:51:32,280 my own server in the cloud. 1095 00:51:32,280 --> 00:51:34,150 So yes, I'm using a website. 1096 00:51:34,150 --> 00:51:37,920 But what CS50 IDE really is, it's like your own server 1097 00:51:37,920 --> 00:51:40,080 or your own computer in the cloud. 1098 00:51:40,080 --> 00:51:43,740 Somewhere out there on the internet, you have your own username and password 1099 00:51:43,740 --> 00:51:45,450 in the form of CS50 IDE. 1100 00:51:45,450 --> 00:51:49,830 And only you can access the files that you write, the programs that you 1101 00:51:49,830 --> 00:51:51,900 write that are stored in this IDE. 1102 00:51:51,900 --> 00:51:54,660 And there's a few more features I'll now draw our attention to. 1103 00:51:54,660 --> 00:51:58,350 Perhaps the most friendly one is this little folder icon at top left. 1104 00:51:58,350 --> 00:52:00,570 If I click this little folder icon, you'll 1105 00:52:00,570 --> 00:52:03,120 now see what's generally called a file browser 1106 00:52:03,120 --> 00:52:06,210 or a file tree, which is just a graphical representation 1107 00:52:06,210 --> 00:52:10,680 of the files in my account, or in my IDE, in this case. 1108 00:52:10,680 --> 00:52:12,090 It looks similar to Mac OS. 1109 00:52:12,090 --> 00:52:13,410 It looks similar to Windows. 1110 00:52:13,410 --> 00:52:16,860 And this is just a graphical user interface built into the IDE 1111 00:52:16,860 --> 00:52:20,970 so that, for instance, if I close my tab by clicking this little x button up 1112 00:52:20,970 --> 00:52:23,760 here, and I want to reopen the file, much like you 1113 00:52:23,760 --> 00:52:25,860 would imagine on a Mac or PC, it's as simple 1114 00:52:25,860 --> 00:52:28,710 as double clicking the file on the left-hand side. 1115 00:52:28,710 --> 00:52:31,800 But notice I didn't click on hello. 1116 00:52:31,800 --> 00:52:33,150 Because notice what happens. 1117 00:52:33,150 --> 00:52:38,550 If I open hello, my gosh, like, what is going on here? 1118 00:52:38,550 --> 00:52:39,810 This is kind of a mess. 1119 00:52:39,810 --> 00:52:40,710 There's redness. 1120 00:52:40,710 --> 00:52:41,790 There's dots. 1121 00:52:41,790 --> 00:52:47,865 Any thoughts from someone on why I'm seeing what I'm seeing? 1122 00:52:47,865 --> 00:52:50,250 Because odds are you will, accidentally, at some point, 1123 00:52:50,250 --> 00:52:56,520 click on a file like hello instead of on a file like hello.c. 1124 00:52:56,520 --> 00:52:58,260 Sara, what do you think? 1125 00:52:58,260 --> 00:52:59,850 AUDIENCE: It's a binary code. 1126 00:52:59,850 --> 00:53:01,740 So it's the machine language. 1127 00:53:01,740 --> 00:53:05,385 So it doesn't allow the user to see them, besides the code they write in C. 1128 00:53:05,385 --> 00:53:06,510 DAVID MALAN: Yeah, exactly. 1129 00:53:06,510 --> 00:53:11,410 What you're trying to look at in this tab is binary code, 0's and 1's. 1130 00:53:11,410 --> 00:53:14,220 However, those 0's and 1's are technically 1131 00:53:14,220 --> 00:53:18,060 being misinterpreted at the moment as ASCII characters, 1132 00:53:18,060 --> 00:53:19,260 or Unicode characters. 1133 00:53:19,260 --> 00:53:24,090 So recall from last week, ASCII is this mapping between numbers and letters. 1134 00:53:24,090 --> 00:53:26,850 And numbers, of course, are just patterns of 0's and 1's. 1135 00:53:26,850 --> 00:53:32,100 And this looks super cryptic, because we're trying to misinterpret 0's and 1136 00:53:32,100 --> 00:53:34,230 1's as though they're ASCII characters. 1137 00:53:34,230 --> 00:53:37,830 And recall that there's many more characters in ASCII and Unicode 1138 00:53:37,830 --> 00:53:41,820 than A through Z. And the numbers, there's some unprintable characters. 1139 00:53:41,820 --> 00:53:44,160 And indeed, all the funkiness we're seeing here 1140 00:53:44,160 --> 00:53:47,190 is just a misinterpretation of 0's and 1's that 1141 00:53:47,190 --> 00:53:51,780 are instructions to the computer, machine code for the computer being 1142 00:53:51,780 --> 00:53:53,130 misinterpreted as text. 1143 00:53:53,130 --> 00:53:56,130 So if you can't edit a binary file like this, so to speak, 1144 00:53:56,130 --> 00:53:58,680 you should just close hello when you do something like that 1145 00:53:58,680 --> 00:54:02,190 and make sure you've double clicked on and opened your actual source code 1146 00:54:02,190 --> 00:54:04,420 file as well. 1147 00:54:04,420 --> 00:54:06,450 So we've seen strings. 1148 00:54:06,450 --> 00:54:08,100 And there's other data types. 1149 00:54:08,100 --> 00:54:09,300 And there's other functions. 1150 00:54:09,300 --> 00:54:11,730 And there's loops and conditions and so much more. 1151 00:54:11,730 --> 00:54:15,000 I think we're at a good point now to perhaps take a break, let this sink in. 1152 00:54:15,000 --> 00:54:18,270 Why don't we go ahead and take a seven minute break? 1153 00:54:18,270 --> 00:54:20,910 And when we resume, we'll introduce a few more features of C 1154 00:54:20,910 --> 00:54:23,790 and compare them against what we saw last week in Scratch. 1155 00:54:23,790 --> 00:54:25,500 So we'll see you in seven minutes. 1156 00:54:25,500 --> 00:54:28,260 All right, we are back. 1157 00:54:28,260 --> 00:54:32,190 So recall where we left off was we were looking at this graphical user 1158 00:54:32,190 --> 00:54:33,390 interface at top left. 1159 00:54:33,390 --> 00:54:36,960 The file browser, the file tree, that just gives us more graphical access 1160 00:54:36,960 --> 00:54:38,450 to the files in our account. 1161 00:54:38,450 --> 00:54:44,730 But let's now do this the old school command line way in my terminal window. 1162 00:54:44,730 --> 00:54:47,040 So it turns out that using our terminal window, 1163 00:54:47,040 --> 00:54:51,090 can we not only compile code and run code and run check50 style, help50, 1164 00:54:51,090 --> 00:54:53,850 and the like, we can also manipulate files 1165 00:54:53,850 --> 00:54:57,480 and folders, even, that happen to exist in my IDE. 1166 00:54:57,480 --> 00:55:01,060 That is in the computer I have access to here in the cloud. 1167 00:55:01,060 --> 00:55:04,620 And the first command I've proposed is that we type ls. 1168 00:55:04,620 --> 00:55:07,020 Ls is shorthand notation for list. 1169 00:55:07,020 --> 00:55:12,040 And quite simply, ls lists the files or folders in your current folder. 1170 00:55:12,040 --> 00:55:15,540 So this would be like double clicking on your My Documents folder in Windows, 1171 00:55:15,540 --> 00:55:17,010 or documents in Mac OS. 1172 00:55:17,010 --> 00:55:19,000 Ls just lists the contents. 1173 00:55:19,000 --> 00:55:20,580 Now, notice hello is a little weird. 1174 00:55:20,580 --> 00:55:25,360 It's highlighted in green and there's an asterisk after it. 1175 00:55:25,360 --> 00:55:28,830 And that's just a visual cue that that file is executable. 1176 00:55:28,830 --> 00:55:32,580 That is, that is a program that you can run with ./hello. 1177 00:55:32,580 --> 00:55:34,710 The star is not part of the file name. 1178 00:55:34,710 --> 00:55:36,570 And of course, we see hello.c. 1179 00:55:36,570 --> 00:55:40,620 Now, suppose that I wanted to maybe rename my file. 1180 00:55:40,620 --> 00:55:43,050 Well, I could, much like in Mac OS or Windows, 1181 00:55:43,050 --> 00:55:45,000 I could go up to the file browser up here. 1182 00:55:45,000 --> 00:55:46,830 I could Control click or Right click. 1183 00:55:46,830 --> 00:55:49,110 And notice there's a whole bunch of menu options 1184 00:55:49,110 --> 00:55:51,220 that pop up just like on your own computer. 1185 00:55:51,220 --> 00:55:53,280 And I could rename the file right up here. 1186 00:55:53,280 --> 00:55:56,113 But generally speaking, we're going to do things at the command line 1187 00:55:56,113 --> 00:55:58,710 only because, rudimentary as some of these operations today 1188 00:55:58,710 --> 00:56:02,700 are, it's going to be a much more powerful command line interface for me. 1189 00:56:02,700 --> 00:56:04,920 So suppose I change my mind, and you know what? 1190 00:56:04,920 --> 00:56:06,570 I don't like this version of hello. 1191 00:56:06,570 --> 00:56:08,790 I want to delete that program and start over. 1192 00:56:08,790 --> 00:56:11,070 Strictly speaking, I don't need to delete hello ever. 1193 00:56:11,070 --> 00:56:14,620 I can just recompile it, and it will keep getting changed and changed. 1194 00:56:14,620 --> 00:56:19,050 But if I do want to remove it, I can type rm hello, and then hit Enter. 1195 00:56:19,050 --> 00:56:22,140 And then I'll be asked, remove regular file hello? 1196 00:56:22,140 --> 00:56:25,170 That's just a visual confirmation that I do indeed want to delete. 1197 00:56:25,170 --> 00:56:28,500 And I can type y or yes or some such reply. 1198 00:56:28,500 --> 00:56:31,830 And if I hit y and Enter, nothing seems to happen, 1199 00:56:31,830 --> 00:56:34,990 but notice what happened up here at top left. 1200 00:56:34,990 --> 00:56:38,700 Notice that hello is now gone, leaving only hello.c. 1201 00:56:38,700 --> 00:56:42,623 And if I type ls again, now I see only my code file. 1202 00:56:42,623 --> 00:56:44,790 Maybe now I want to change this program, and I don't 1203 00:56:44,790 --> 00:56:47,760 want to write hello.c, but goodbye.c. 1204 00:56:47,760 --> 00:56:49,860 Well, let me close the tab up there. 1205 00:56:49,860 --> 00:56:52,560 And yes, I could go and Right click or Control click on it, 1206 00:56:52,560 --> 00:56:54,960 but, again, we don't need to use the graphical interface. 1207 00:56:54,960 --> 00:57:00,990 Let me go ahead and instead do mv hello.c goodbye.c. 1208 00:57:00,990 --> 00:57:03,150 Mv is the move command. 1209 00:57:03,150 --> 00:57:06,260 And even though it would be nice if it's called rename instead of move, 1210 00:57:06,260 --> 00:57:10,750 move just moves one file to another location or to another name. 1211 00:57:10,750 --> 00:57:12,840 So if I do mv hello.c goodbye.c. 1212 00:57:12,840 --> 00:57:15,910 Notice what happened at top left. 1213 00:57:15,910 --> 00:57:18,210 Now my same file is called goodbye.c. 1214 00:57:18,210 --> 00:57:23,248 And if, again, I type ls, I can see that it's indeed renamed. 1215 00:57:23,248 --> 00:57:25,290 Now, let me go ahead and move that back because I 1216 00:57:25,290 --> 00:57:27,810 want to stay on my hello.c program. 1217 00:57:27,810 --> 00:57:29,970 But suppose I want to start organizing my files. 1218 00:57:29,970 --> 00:57:32,262 In a moment we're going to start writing more programs, 1219 00:57:32,262 --> 00:57:34,200 and so my account is going to get a little bit 1220 00:57:34,200 --> 00:57:36,900 messy with more and more files over the course of today. 1221 00:57:36,900 --> 00:57:41,050 So suppose you want to create a folder, otherwise known as a directory. 1222 00:57:41,050 --> 00:57:45,598 I'm going to go ahead and type mkdir for make directory. 1223 00:57:45,598 --> 00:57:48,640 And then the name of the directory I want to make, for instance, lecture. 1224 00:57:48,640 --> 00:57:51,765 You can call it anything you want, but if I'm in lecture, I'm writing code, 1225 00:57:51,765 --> 00:57:54,910 maybe I want to store all of today's files in a lecture directory. 1226 00:57:54,910 --> 00:57:58,630 When I hit Enter there, notice what happens in my file tree up here. 1227 00:57:58,630 --> 00:58:00,620 I now see a lecture folder. 1228 00:58:00,620 --> 00:58:04,310 If I click the triangle, it's empty because I haven't put anything in it. 1229 00:58:04,310 --> 00:58:08,170 So let me go ahead and move hello.c into the lecture folder. 1230 00:58:08,170 --> 00:58:13,090 Mv hello.c lecture, and now let me hit Enter. 1231 00:58:13,090 --> 00:58:17,800 And voila, now notice that it's nested inside of this lecture folder. 1232 00:58:17,800 --> 00:58:22,210 And indeed, if I now type ls for list, I only see the lecture folder. 1233 00:58:22,210 --> 00:58:24,730 Unfortunately, I kind of now don't have access 1234 00:58:24,730 --> 00:58:27,730 to hello.c within this command line environment 1235 00:58:27,730 --> 00:58:29,620 unless I change into that directory. 1236 00:58:29,620 --> 00:58:32,020 Now, in the world of Macs and PCs we, obviously, 1237 00:58:32,020 --> 00:58:35,140 would just double click on a folder and voila we're inside of it. 1238 00:58:35,140 --> 00:58:37,810 In a command line interface you need to be more deliberate. 1239 00:58:37,810 --> 00:58:40,960 So I'm going to do cd, for change directory, 1240 00:58:40,960 --> 00:58:43,840 then lecture, and then I'm going to go ahead and hit Enter. 1241 00:58:43,840 --> 00:58:46,180 And now notice, and now it might make more sense 1242 00:58:46,180 --> 00:58:50,815 why this whole time we've been seeing in blue this tilde lecture slash. 1243 00:58:50,815 --> 00:58:53,650 The tilde just means my so-called home directory. 1244 00:58:53,650 --> 00:58:57,970 Like my own account, my own default folder, like my documents and windows, 1245 00:58:57,970 --> 00:58:59,500 or documents on Mac OS. 1246 00:58:59,500 --> 00:59:02,140 That's what tilde represents in shorthand notation. 1247 00:59:02,140 --> 00:59:05,770 Lecture is the name of the folder that I am now inside. 1248 00:59:05,770 --> 00:59:09,850 So it's as though I double clicked on lecture in Mac OS or Windows 1249 00:59:09,850 --> 00:59:11,050 to open a folder. 1250 00:59:11,050 --> 00:59:15,140 Now I'm inside this lecture directory in my terminal window. 1251 00:59:15,140 --> 00:59:18,940 So if I now type ls enter, I should see voila, 1252 00:59:18,940 --> 00:59:23,775 the hello.c file that I moved into it. 1253 00:59:23,775 --> 00:59:25,900 Now, let me undo this because I'm going to go ahead 1254 00:59:25,900 --> 00:59:27,730 and keep things a little simpler for now. 1255 00:59:27,730 --> 00:59:32,650 And suppose that I want to move hello.c into where it previously was. 1256 00:59:32,650 --> 00:59:34,120 Last piece of syntax. 1257 00:59:34,120 --> 00:59:37,670 There's this shorthand notation for what we'll call a parent folder. 1258 00:59:37,670 --> 00:59:40,930 So just like in family trees, there's the notion of parents, and children, 1259 00:59:40,930 --> 00:59:42,490 and grandchildren, and so forth. 1260 00:59:42,490 --> 00:59:45,130 That's also true in computer systems that have folders. 1261 00:59:45,130 --> 00:59:46,840 And folders inside of folders. 1262 00:59:46,840 --> 00:59:49,360 And folders inside of folders inside of folders. 1263 00:59:49,360 --> 00:59:52,220 There's a hierarchy there much like a family tree. 1264 00:59:52,220 --> 00:59:55,960 So if I want to move hello.c one level up, 1265 00:59:55,960 --> 01:00:00,250 I can actually do mv hello.c space dot dot. 1266 01:00:00,250 --> 01:00:04,300 And that's like saying move this file to the folder up above. 1267 01:00:04,300 --> 01:00:07,270 When I do that, notice what happened at top left. 1268 01:00:07,270 --> 01:00:11,920 Now hello.c is not inside of the lecture folder, but below it. 1269 01:00:11,920 --> 01:00:16,090 And indeed, if I type ls now in the lecture folder, there's nothing there. 1270 01:00:16,090 --> 01:00:21,130 How do I move myself up one level in the family tree that are these folders? 1271 01:00:21,130 --> 01:00:24,270 Let me go ahead and type cd space dot dot. 1272 01:00:24,270 --> 01:00:26,650 So change directory to my parent. 1273 01:00:26,650 --> 01:00:28,180 Dot dot just means your parent. 1274 01:00:28,180 --> 01:00:30,160 The folder up above, Enter. 1275 01:00:30,160 --> 01:00:33,250 And now, I'm apparently in just tilde slash, 1276 01:00:33,250 --> 01:00:37,240 which is, again, cryptic shorthand notation for your own home directory-- 1277 01:00:37,240 --> 01:00:40,010 your My Documents or documents folder. 1278 01:00:40,010 --> 01:00:43,647 And if, lastly, I type ls here, I'm done with this lecture folder. 1279 01:00:43,647 --> 01:00:45,730 I don't want to bother storing things in a folder. 1280 01:00:45,730 --> 01:00:50,560 I can do not rm for remove, like I did to get rid of hello, 1281 01:00:50,560 --> 01:00:53,680 but rmdir to remove a directory. 1282 01:00:53,680 --> 01:00:55,300 And voila, it's gone. 1283 01:00:55,300 --> 01:00:59,050 And I've undone all of the various changes that I made earlier. 1284 01:00:59,050 --> 01:01:01,510 But perhaps now it makes a little more sense 1285 01:01:01,510 --> 01:01:03,220 why I was doing something earlier. 1286 01:01:03,220 --> 01:01:05,510 Let me open up my hello.c file. 1287 01:01:05,510 --> 01:01:08,860 Let me make hello again, which is way back where we left off. 1288 01:01:08,860 --> 01:01:13,060 And recall that all this time I've been doing dot slash hello. 1289 01:01:13,060 --> 01:01:14,500 Well, why is that? 1290 01:01:14,500 --> 01:01:18,190 Well, just as dot dot refers to your parent directory, 1291 01:01:18,190 --> 01:01:21,380 a single dot refers to your current directory. 1292 01:01:21,380 --> 01:01:23,350 So even though this looks a little silly, 1293 01:01:23,350 --> 01:01:26,950 dot slash hello is just a very explicit way 1294 01:01:26,950 --> 01:01:30,610 of telling the computer, run the program called hello 1295 01:01:30,610 --> 01:01:33,430 that's right here in my current directory. 1296 01:01:33,430 --> 01:01:35,200 Dot means current directory. 1297 01:01:35,200 --> 01:01:37,180 Dot dot means parent directory. 1298 01:01:37,180 --> 01:01:40,000 And so there we see, finally, why I've been 1299 01:01:40,000 --> 01:01:41,980 typing dot slash hello all this time. 1300 01:01:41,980 --> 01:01:45,310 But again, it's just the textual analog of doing something 1301 01:01:45,310 --> 01:01:50,530 like double clicking on an icon in Mac OS or Windows. 1302 01:01:50,530 --> 01:01:53,740 So there's other commands too, and over time you'll get exposed to these 1303 01:01:53,740 --> 01:01:55,450 and use them for various problems. 1304 01:01:55,450 --> 01:01:58,910 Cp for copy, for instance, is yet another. 1305 01:01:58,910 --> 01:02:01,630 And many others, but these are all just standard commands. 1306 01:02:01,630 --> 01:02:03,610 They are not CS50 specific. 1307 01:02:03,610 --> 01:02:07,900 Standard commands that allow us to manipulate files and folders 1308 01:02:07,900 --> 01:02:10,150 in a computer like this. 1309 01:02:10,150 --> 01:02:12,508 And question from Max. 1310 01:02:12,508 --> 01:02:13,050 AUDIENCE: Hi. 1311 01:02:13,050 --> 01:02:13,660 Yeah, sorry. 1312 01:02:13,660 --> 01:02:14,290 I was just wondering. 1313 01:02:14,290 --> 01:02:16,600 I don't really understand the difference between the hello program 1314 01:02:16,600 --> 01:02:17,800 and the hello.c program. 1315 01:02:17,800 --> 01:02:21,830 It seems like the one that doesn't have dot c on it isn't used for anything. 1316 01:02:21,830 --> 01:02:23,080 DAVID MALAN: Oh, it is though. 1317 01:02:23,080 --> 01:02:25,812 So recall that we have two things in the story. 1318 01:02:25,812 --> 01:02:28,270 We have source code, which is the C code I've been writing. 1319 01:02:28,270 --> 01:02:30,010 And then machine code, which is the zeros 1320 01:02:30,010 --> 01:02:31,790 and ones that the computer understands. 1321 01:02:31,790 --> 01:02:35,860 I have been writing all of my code in the file called hello.c. 1322 01:02:35,860 --> 01:02:39,790 But after I compile it with make, the make program 1323 01:02:39,790 --> 01:02:44,320 creates a new file called hello that technically contains only zeros 1324 01:02:44,320 --> 01:02:45,100 and ones. 1325 01:02:45,100 --> 01:02:47,410 And that is the machine code that I'm actually 1326 01:02:47,410 --> 01:02:50,110 running when I do dot slash hello. 1327 01:02:50,110 --> 01:02:53,710 So again, I can use rm and I can get rid of the hello program 1328 01:02:53,710 --> 01:02:54,820 just like I did before. 1329 01:02:54,820 --> 01:02:57,028 And now we're back at the very beginning of the story 1330 01:02:57,028 --> 01:02:58,750 where we wrote this code from scratch. 1331 01:02:58,750 --> 01:03:01,870 If I now type make, and let me do this now, ls. 1332 01:03:01,870 --> 01:03:03,680 Notice I've only got one file. 1333 01:03:03,680 --> 01:03:05,410 Let me now do make hello. 1334 01:03:05,410 --> 01:03:09,250 I see that cryptic output, but if I type ls again, now I have two files. 1335 01:03:09,250 --> 01:03:14,020 And that's because only the green one with the asterisk is executable. 1336 01:03:14,020 --> 01:03:18,293 That is the machine code that the compiler has created for me. 1337 01:03:18,293 --> 01:03:21,460 And I should say and disclaim, I've been telling a little bit of a white lie 1338 01:03:21,460 --> 01:03:21,960 today. 1339 01:03:21,960 --> 01:03:23,890 Make itself is not actually a compiler. 1340 01:03:23,890 --> 01:03:26,500 We'll see next week exactly what make is doing. 1341 01:03:26,500 --> 01:03:30,460 But it's making it easier for us to actually compile our code, 1342 01:03:30,460 --> 01:03:32,740 but more on that next time. 1343 01:03:32,740 --> 01:03:33,340 All right. 1344 01:03:33,340 --> 01:03:37,600 So we've seen only strings thus far, but it turns out in C, 1345 01:03:37,600 --> 01:03:41,380 and in a lot of languages, there's other things known as types or data types. 1346 01:03:41,380 --> 01:03:43,840 That is to say, you can have variables and values 1347 01:03:43,840 --> 01:03:47,290 that aren't just strings of text, but that are maybe integers, 1348 01:03:47,290 --> 01:03:49,060 like numbers, one, two, three, four. 1349 01:03:49,060 --> 01:03:54,280 Or maybe floating point values, like 3.14159, or other such values. 1350 01:03:54,280 --> 01:03:58,360 You can have Boolean values, which are only true or false. 1351 01:03:58,360 --> 01:04:02,200 You can have characters or chars, which are single characters. 1352 01:04:02,200 --> 01:04:06,010 This is to say, within a language like C there's actually a whole bunch of data 1353 01:04:06,010 --> 01:04:07,660 types that are available to you. 1354 01:04:07,660 --> 01:04:09,740 String is only one of them. 1355 01:04:09,740 --> 01:04:12,070 And there's even more than are on this list here, 1356 01:04:12,070 --> 01:04:16,180 but this is just a list of some of the most common ones that we'll see today 1357 01:04:16,180 --> 01:04:18,820 and we'll use this coming week in the first problem set 1358 01:04:18,820 --> 01:04:22,820 that allow you to tell the computer not only to store a value in a variable, 1359 01:04:22,820 --> 01:04:25,510 but what type of value to store in a variable. 1360 01:04:25,510 --> 01:04:29,740 Moreover, we have in the CS50 library a whole bunch more functions. 1361 01:04:29,740 --> 01:04:31,480 We've seen get_string already. 1362 01:04:31,480 --> 01:04:34,300 But similarly have we created functions that you 1363 01:04:34,300 --> 01:04:36,700 can use for problem sets, labs, and beyond that 1364 01:04:36,700 --> 01:04:40,180 allow you to get a single character via a get_char. 1365 01:04:40,180 --> 01:04:43,120 That can allow you to get an integer via get_int. 1366 01:04:43,120 --> 01:04:45,010 That can allow you to get a floating point 1367 01:04:45,010 --> 01:04:47,650 value, which is a fancy way of describing a real number, 1368 01:04:47,650 --> 01:04:50,440 with a decimal point using get_float. 1369 01:04:50,440 --> 01:04:56,110 But it turns out that each of these data types, like int and float, 1370 01:04:56,110 --> 01:04:58,300 only have a finite number of bits. 1371 01:04:58,300 --> 01:05:01,180 And recall from last week that we played around with light bulbs 1372 01:05:01,180 --> 01:05:03,910 and we played around with bits and zeros and ones more generally. 1373 01:05:03,910 --> 01:05:06,730 It turns out that every one of these data types, 1374 01:05:06,730 --> 01:05:11,500 char, double, floats, int, long, string, and so forth, all 1375 01:05:11,500 --> 01:05:13,930 use a specific number of bits. 1376 01:05:13,930 --> 01:05:20,380 And it turns out that int, for instance, integers in C, only use 32 bits. 1377 01:05:20,380 --> 01:05:24,820 And that's great until such time as you want to count higher than roughly 4 1378 01:05:24,820 --> 01:05:27,220 billion, at which point you can't. 1379 01:05:27,220 --> 01:05:30,610 We'll see later today that if you're only using a specific number of bits 1380 01:05:30,610 --> 01:05:33,550 you can only count so high, and so there exist other data types. 1381 01:05:33,550 --> 01:05:35,230 For instance, a long. 1382 01:05:35,230 --> 01:05:39,520 A long is another type of number in C that just uses 64 bits. 1383 01:05:39,520 --> 01:05:43,300 So it gives you way more expressiveness, way more patterns of zeros and ones 1384 01:05:43,300 --> 01:05:44,320 to count even higher. 1385 01:05:44,320 --> 01:05:47,290 Similarly, a double is like a floating point value. 1386 01:05:47,290 --> 01:05:50,590 A real number with a decimal point and some number of digits after it. 1387 01:05:50,590 --> 01:05:56,050 A double allows you to have even more digits after it than a float would. 1388 01:05:56,050 --> 01:05:59,200 So we'll see and use some of these data types in just a bit. 1389 01:05:59,200 --> 01:06:02,380 Printf, similarly, has the ability to print out not only strings 1390 01:06:02,380 --> 01:06:06,080 as we saw, but also using different format codes other data types as well. 1391 01:06:06,080 --> 01:06:09,413 These are a little more cryptic and it's fine to look these things up as needed, 1392 01:06:09,413 --> 01:06:12,385 but you'll eventually ingrain them for common use cases. 1393 01:06:12,385 --> 01:06:16,015 Percent c is going to be the placeholder for printing a single character. 1394 01:06:16,015 --> 01:06:18,310 Percent c for a char, so to speak. 1395 01:06:18,310 --> 01:06:21,055 Percent f is going to be for a floating point value. 1396 01:06:21,055 --> 01:06:23,680 So if you want to print out a real number with a decimal point, 1397 01:06:23,680 --> 01:06:25,090 you're going to use percent f. 1398 01:06:25,090 --> 01:06:27,370 If you want to print an integer using print f, 1399 01:06:27,370 --> 01:06:29,442 you're going to use percent i for integer. 1400 01:06:29,442 --> 01:06:31,900 If you want to print a string we've already seen percent s. 1401 01:06:31,900 --> 01:06:34,840 And if you want to print a long integer, a.k.a. 1402 01:06:34,840 --> 01:06:36,940 long, you're going to use percent li. 1403 01:06:36,940 --> 01:06:39,910 And there's even others, but these are perhaps some of the most common. 1404 01:06:39,910 --> 01:06:44,050 And it just means that, again, C really needs you, the programmer, 1405 01:06:44,050 --> 01:06:44,858 to be precise. 1406 01:06:44,858 --> 01:06:46,150 You can't just say, print this. 1407 01:06:46,150 --> 01:06:50,830 You have to tell printf how to print the variable or the value 1408 01:06:50,830 --> 01:06:52,310 that you're passing into it. 1409 01:06:52,310 --> 01:06:54,790 And then lastly, it turns out that in C there's 1410 01:06:54,790 --> 01:06:59,480 a whole bunch of operators, certainly mathematical ones and bunches of others 1411 01:06:59,480 --> 01:06:59,980 as well. 1412 01:06:59,980 --> 01:07:02,740 Just like Scratch out a whole toolkit of operators. 1413 01:07:02,740 --> 01:07:06,920 And suffice it to say for now that C also supports addition, subtraction, 1414 01:07:06,920 --> 01:07:09,430 multiplication, division, and even the remainder 1415 01:07:09,430 --> 01:07:13,060 operator, which a little cryptically is represented with a percent sign. 1416 01:07:13,060 --> 01:07:15,497 Not to be confused with printf's format codes, 1417 01:07:15,497 --> 01:07:18,580 but this is to say that some of the earliest uses of computers, of course, 1418 01:07:18,580 --> 01:07:21,220 were all mathematically oriented in spreadsheet programs. 1419 01:07:21,220 --> 01:07:24,880 Programs like VisiCalc and the like back before there was Excel and Google 1420 01:07:24,880 --> 01:07:25,690 spreadsheets. 1421 01:07:25,690 --> 01:07:29,380 And they certainly, computers, are very good at supporting math. 1422 01:07:29,380 --> 01:07:31,990 And so these are just some of the operators that will now see 1423 01:07:31,990 --> 01:07:33,188 are available to us. 1424 01:07:33,188 --> 01:07:34,480 So let me go ahead and do this. 1425 01:07:34,480 --> 01:07:39,250 Let me go back to my IDE after cleaning things 1426 01:07:39,250 --> 01:07:44,110 up, and starting fresh with just nothing in my terminal window and no tabs open. 1427 01:07:44,110 --> 01:07:46,810 And let me go ahead and write my next program this time 1428 01:07:46,810 --> 01:07:48,700 using some more of these functions. 1429 01:07:48,700 --> 01:07:52,630 I'm going to go ahead and create a file up here called addition.c. 1430 01:07:52,630 --> 01:07:55,750 So addition.c, but I could call this anything I want, 1431 01:07:55,750 --> 01:07:58,180 but it's important to add the dot c. 1432 01:07:58,180 --> 01:08:00,970 Otherwise the computer will not know that it's actual source 1433 01:08:00,970 --> 01:08:02,840 code as opposed to machine code. 1434 01:08:02,840 --> 01:08:05,750 And let me go ahead and make use of the CS50 library. 1435 01:08:05,750 --> 01:08:07,780 So let me include cs50.h. 1436 01:08:07,780 --> 01:08:13,330 Let me include stdio.h, so that I can use things like get_int and printf. 1437 01:08:13,330 --> 01:08:15,140 And then, again, for today's purposes, 1438 01:08:15,140 --> 01:08:19,840 I'm just going to do int main void, and then the curly braces. 1439 01:08:19,840 --> 01:08:22,750 And again, for today, just take on faith this is necessary. 1440 01:08:22,750 --> 01:08:25,600 But we'll explain within a week or two exactly why 1441 01:08:25,600 --> 01:08:27,250 we keep writing int main void. 1442 01:08:27,250 --> 01:08:31,420 But for now, it's like the win green flag clicked puzzle piece. 1443 01:08:31,420 --> 01:08:34,227 Let me go ahead now and get an integer from the user. 1444 01:08:34,227 --> 01:08:36,310 Suppose my goal now is not to write a program that 1445 01:08:36,310 --> 01:08:39,850 gets a string of text and prints out hello, Brian, or hello, David. 1446 01:08:39,850 --> 01:08:42,670 Let me go ahead and write a program that maybe asks 1447 01:08:42,670 --> 01:08:46,220 for two integers, two numbers, and then just adds them together. 1448 01:08:46,220 --> 01:08:49,479 So let me make the simplest of calculators using code. 1449 01:08:49,479 --> 01:08:52,990 Well, I'm going to go ahead and declare a variable called 1450 01:08:52,990 --> 01:08:54,910 x, just like a mathematician would. 1451 01:08:54,910 --> 01:08:59,260 And I'm going to assign it the value of calling get_int. 1452 01:08:59,260 --> 01:09:01,630 And I'll just say something like x colon. 1453 01:09:01,630 --> 01:09:04,450 I could say anything I want, what is x? 1454 01:09:04,450 --> 01:09:06,939 But I'm going to keep it simple and just say x colon. 1455 01:09:06,939 --> 01:09:08,740 Semicolon to end my thought. 1456 01:09:08,740 --> 01:09:11,920 So again, similar in spirit to what I did with string before, 1457 01:09:11,920 --> 01:09:16,029 but now I'm using get_int to get a number or an integer from the user. 1458 01:09:16,029 --> 01:09:21,279 The quoted parameter here or argument is the input 1459 01:09:21,279 --> 01:09:24,520 to get_int, which is going to be the prompt that the human sees. 1460 01:09:24,520 --> 01:09:27,560 The equals sign, recall, is the assignment operator, 1461 01:09:27,560 --> 01:09:31,810 which says, copy the return value on the right-- 1462 01:09:31,810 --> 01:09:34,149 the integer that the human hopefully will type in-- 1463 01:09:34,149 --> 01:09:35,800 over to the left. 1464 01:09:35,800 --> 01:09:39,430 And the left says, give me a variable called, x, 1465 01:09:39,430 --> 01:09:42,710 and let me store integers in it. 1466 01:09:42,710 --> 01:09:46,128 So before, we use string on the left and we used get_string the right. 1467 01:09:46,128 --> 01:09:47,920 The only difference now is int on the left, 1468 01:09:47,920 --> 01:09:50,979 because I want a number, and get_int on the right. 1469 01:09:50,979 --> 01:09:54,220 Then let me go ahead and do this again and get another number. 1470 01:09:54,220 --> 01:09:56,320 Get_int, and I'll just say, y colon. 1471 01:09:56,320 --> 01:10:00,052 But again, I could say, what is y question mark, or anything in English. 1472 01:10:00,052 --> 01:10:02,260 But the last line is going to be the interesting one. 1473 01:10:02,260 --> 01:10:05,150 Now, I'm going to go ahead and print out for instance, 1474 01:10:05,150 --> 01:10:07,210 the sum of these two numbers. 1475 01:10:07,210 --> 01:10:12,760 But printf, again, takes an input that tells it what to print out exactly. 1476 01:10:12,760 --> 01:10:15,790 So I can't really type a number here yet because I don't know 1477 01:10:15,790 --> 01:10:17,600 what the human is going to type in. 1478 01:10:17,600 --> 01:10:19,030 So I'm going to put a placeholder. 1479 01:10:19,030 --> 01:10:22,030 I'm going to percent i, which says, put a number here, 1480 01:10:22,030 --> 01:10:23,725 I just don't know yet what it is. 1481 01:10:23,725 --> 01:10:25,600 And then just to keep things clean, I'm going 1482 01:10:25,600 --> 01:10:28,690 to do backslash n, which just says, give me a new line also. 1483 01:10:28,690 --> 01:10:31,690 That's just an aesthetic detail to move the cursor to the next line just 1484 01:10:31,690 --> 01:10:33,280 to keep things clean. 1485 01:10:33,280 --> 01:10:36,475 But now printf is going to take a second argument. 1486 01:10:36,475 --> 01:10:38,350 And whether you've programmed or not before-- 1487 01:10:38,350 --> 01:10:40,870 Brian, let's go to someone in the audience if we could-- 1488 01:10:40,870 --> 01:10:44,440 what should I type after the comma if the purpose of this program 1489 01:10:44,440 --> 01:10:47,560 is quite simply to add two numbers together? 1490 01:10:47,560 --> 01:10:51,310 Even if you've never programmed before, based on the operators that exist 1491 01:10:51,310 --> 01:10:53,200 and some of the syntax we've seen thus far, 1492 01:10:53,200 --> 01:10:55,075 what would your instincts have you type here? 1493 01:10:55,075 --> 01:10:57,220 Even if you've never done this before. 1494 01:10:57,220 --> 01:11:00,160 Santiago, what do you think? 1495 01:11:00,160 --> 01:11:03,460 AUDIENCE: I would say to just write x plus y. 1496 01:11:03,460 --> 01:11:06,400 DAVID MALAN: Yeah, it is simple and as straightforward as that. 1497 01:11:06,400 --> 01:11:08,122 X plus y is the right intuition. 1498 01:11:08,122 --> 01:11:11,080 I'm going to add a semicolon to the very end just to finish my thought. 1499 01:11:11,080 --> 01:11:13,660 But indeed, computers, and C in this case, 1500 01:11:13,660 --> 01:11:17,110 absolutely understand arithmetic and mathematical operations, so just type 1501 01:11:17,110 --> 01:11:17,890 what you mean. 1502 01:11:17,890 --> 01:11:20,800 I'm going to go ahead now and save the file and go down below. 1503 01:11:20,800 --> 01:11:22,690 And I'm not going to type make hello anymore. 1504 01:11:22,690 --> 01:11:26,470 Now I want to type make addition, because that is the name of my file 1505 01:11:26,470 --> 01:11:27,310 implicitly. 1506 01:11:27,310 --> 01:11:28,540 Addition.c. 1507 01:11:28,540 --> 01:11:31,870 I want to compile into a program called addition. 1508 01:11:31,870 --> 01:11:35,170 Hopefully, this is where I cross my fingers, I didn't make any mistakes. 1509 01:11:35,170 --> 01:11:38,350 And I'm going to go ahead and run make addition. 1510 01:11:38,350 --> 01:11:40,305 All this well, no error messages. 1511 01:11:40,305 --> 01:11:42,430 If I had made a mistake and it didn't even compile, 1512 01:11:42,430 --> 01:11:44,920 help50 might have been my next instinct. 1513 01:11:44,920 --> 01:11:47,230 Now I'm going to go ahead and run dot slash addition. 1514 01:11:47,230 --> 01:11:49,510 And notice, I'm first prompted for x. 1515 01:11:49,510 --> 01:11:51,130 I'm going to go ahead and do one. 1516 01:11:51,130 --> 01:11:52,630 I'm next prompted for y. 1517 01:11:52,630 --> 01:11:54,460 I'm going to go ahead and do one again. 1518 01:11:54,460 --> 01:11:59,230 And voila, as Santiago proposed, I indeed see on the screen x plus y, 1519 01:11:59,230 --> 01:12:00,160 or the value two. 1520 01:12:00,160 --> 01:12:01,450 And I didn't hardcode two. 1521 01:12:01,450 --> 01:12:07,600 I substituted in using i whatever the result of x plus y actually is. 1522 01:12:07,600 --> 01:12:11,260 Now notice, some of the features of the get_int function for you. 1523 01:12:11,260 --> 01:12:14,860 Suppose that you're not being very cooperative and you type in cat for x. 1524 01:12:14,860 --> 01:12:18,100 Notice that get_int just ignores you and prompts you again. 1525 01:12:18,100 --> 01:12:21,760 If I type in dog it ignores me and prompts me again. 1526 01:12:21,760 --> 01:12:25,450 If I type in 1.23, it ignores me and prompts me again 1527 01:12:25,450 --> 01:12:27,640 because it wants an integer in this case. 1528 01:12:27,640 --> 01:12:29,140 A number like one, two, three, four. 1529 01:12:29,140 --> 01:12:32,650 Or negative one, two, three, four, or zero, or anything above or below. 1530 01:12:32,650 --> 01:12:35,350 So fine, I'll cooperate now and give it the number one. 1531 01:12:35,350 --> 01:12:36,250 Same for y. 1532 01:12:36,250 --> 01:12:38,437 It's going to ignore any non-integer input. 1533 01:12:38,437 --> 01:12:40,270 So if I give it a number like two this time, 1534 01:12:40,270 --> 01:12:42,720 I'll hopefully get the answer of three. 1535 01:12:42,720 --> 01:12:43,220 All right. 1536 01:12:43,220 --> 01:12:46,930 So we have a basic calculator in C. We're using some basic building 1537 01:12:46,930 --> 01:12:47,800 blocks as before. 1538 01:12:47,800 --> 01:12:52,360 We've got these header files, which just give me access to get_int and printf 1539 01:12:52,360 --> 01:12:53,380 respectively. 1540 01:12:53,380 --> 01:12:55,497 But suppose now I want to count up even higher. 1541 01:12:55,497 --> 01:12:56,080 You know what? 1542 01:12:56,080 --> 01:12:57,372 Let me try something like this. 1543 01:12:57,372 --> 01:12:58,930 Let me run this program once more. 1544 01:12:58,930 --> 01:13:00,640 And let me get a little greedy. 1545 01:13:00,640 --> 01:13:05,540 How about 4,000,000,000. 1546 01:13:05,540 --> 01:13:07,330 So roughly-- well, exactly-- 1547 01:13:07,330 --> 01:13:08,800 4 billion. 1548 01:13:08,800 --> 01:13:10,750 That's the number I want to type in. 1549 01:13:10,750 --> 01:13:13,630 Notice that x does not like that. 1550 01:13:13,630 --> 01:13:16,420 So get_int does not accept 4 billion. 1551 01:13:16,420 --> 01:13:20,500 Well, let me try it maybe 3 billion. 1552 01:13:20,500 --> 01:13:21,062 Uh-huh. 1553 01:13:21,062 --> 01:13:21,770 Didn't like that. 1554 01:13:21,770 --> 01:13:23,960 How about 2 billion? 1555 01:13:23,960 --> 01:13:25,610 OK, that one worked. 1556 01:13:25,610 --> 01:13:27,320 Let me pause here. 1557 01:13:27,320 --> 01:13:29,600 What's going on perhaps? 1558 01:13:29,600 --> 01:13:32,450 Now again, we the staff wrote get_int, so we 1559 01:13:32,450 --> 01:13:36,860 are the ones that are rejecting cats, and rejecting dogs, and rejecting 1560 01:13:36,860 --> 01:13:39,080 4 billion, and even 3 billion. 1561 01:13:39,080 --> 01:13:41,210 But in this case, it's a little less clear. 1562 01:13:41,210 --> 01:13:45,260 Why did we reject 4 billion and 3 billion do you think? 1563 01:13:45,260 --> 01:13:48,780 Based on some of the definitions thus far today. 1564 01:13:48,780 --> 01:13:49,620 Why might this be? 1565 01:13:49,620 --> 01:13:52,260 Nathaniel, what do you think? 1566 01:13:52,260 --> 01:13:54,540 AUDIENCE: There's a cap on the size of the number 1567 01:13:54,540 --> 01:13:59,095 since it would take too many bits and bytes after the size of 2 billion. 1568 01:13:59,095 --> 01:13:59,970 DAVID MALAN: Perfect. 1569 01:13:59,970 --> 01:14:03,900 So integers, again, are implemented in C as these things ints. 1570 01:14:03,900 --> 01:14:06,582 Ints only use, it turns out, 32 bits total. 1571 01:14:06,582 --> 01:14:08,790 And you would only know that by having been taught it 1572 01:14:08,790 --> 01:14:10,960 or looked it up for a particular computer system. 1573 01:14:10,960 --> 01:14:15,842 But they on CS50 IDE, and most modern systems, an integer is only 32 bits. 1574 01:14:15,842 --> 01:14:17,550 And that then invites the question, well, 1575 01:14:17,550 --> 01:14:20,550 if you've got 32 bits or light bulbs, how high can you count? 1576 01:14:20,550 --> 01:14:23,400 Well, it turns out with 32 light bulbs, or bits, 1577 01:14:23,400 --> 01:14:26,040 you can count roughly as high as 4 billion. 1578 01:14:26,040 --> 01:14:28,950 You can absolutely count as high as 3 billion. 1579 01:14:28,950 --> 01:14:31,140 And yet, get_int still rejecting it. 1580 01:14:31,140 --> 01:14:35,640 But that's because the get_int function supports integers broadly 1581 01:14:35,640 --> 01:14:38,340 speaking, which includes not only positive numbers, 1582 01:14:38,340 --> 01:14:41,040 but also negative numbers and zero. 1583 01:14:41,040 --> 01:14:44,190 And the catch is that if you want to support both positive numbers 1584 01:14:44,190 --> 01:14:49,900 and negative numbers, you can represent 4 billion or so total possible values. 1585 01:14:49,900 --> 01:14:53,820 But if you want to go as far to the left and as far to the right on the number 1586 01:14:53,820 --> 01:14:55,200 line that I'm describing. 1587 01:14:55,200 --> 01:14:58,710 You can only really count as high as 2 billion in the positive direction 1588 01:14:58,710 --> 01:15:01,560 and negative 2 billion in the negative direction. 1589 01:15:01,560 --> 01:15:03,900 Because that still gives you a total of 4 billion, 1590 01:15:03,900 --> 01:15:06,840 but not nearly as high as 3 billion or 4 billion. 1591 01:15:06,840 --> 01:15:08,760 So what might the solution here be? 1592 01:15:08,760 --> 01:15:12,040 Well, I recall earlier noting that there's other data types. 1593 01:15:12,040 --> 01:15:14,790 Not just ints and strings, but also longs, which literally 1594 01:15:14,790 --> 01:15:17,730 are longer integers, namely 64 bit. 1595 01:15:17,730 --> 01:15:19,400 So let me go ahead and try this. 1596 01:15:19,400 --> 01:15:21,720 Let me go ahead and change get_int to get_long. 1597 01:15:21,720 --> 01:15:23,740 This get_int to get_long. 1598 01:15:23,740 --> 01:15:26,820 Let me change this int a long, and this int to a long. 1599 01:15:26,820 --> 01:15:29,190 So same program, same calculator, but I'm 1600 01:15:29,190 --> 01:15:31,200 now using a different data type that's just 1601 01:15:31,200 --> 01:15:33,380 going to use more bits to store values. 1602 01:15:33,380 --> 01:15:36,420 Let me run make addition again to recompile my program. 1603 01:15:36,420 --> 01:15:37,590 And, oh, damn it. 1604 01:15:37,590 --> 01:15:39,040 I screwed up. 1605 01:15:39,040 --> 01:15:41,580 So let's see if we can't glean what's wrong here. 1606 01:15:41,580 --> 01:15:42,390 Let me scroll up. 1607 01:15:42,390 --> 01:15:43,920 And I can't emphasize this enough. 1608 01:15:43,920 --> 01:15:47,010 Sometimes-- I got lucky here and I only have one mistake, apparently, 1609 01:15:47,010 --> 01:15:51,150 in the error messages-- it is not going to be uncommon 1610 01:15:51,150 --> 01:15:55,830 for you to have two errors, 10 errors, in like two lines of code. 1611 01:15:55,830 --> 01:15:58,680 This is because sometimes when you have errors in your code, 1612 01:15:58,680 --> 01:16:01,228 the compiler sometimes just gets confused. 1613 01:16:01,228 --> 01:16:04,020 And if it gets sufficiently confused, it starts thinking everything 1614 01:16:04,020 --> 01:16:06,010 is an error in your actual code. 1615 01:16:06,010 --> 01:16:08,520 So the most important takeaway is that no matter 1616 01:16:08,520 --> 01:16:13,230 how many errors you seem to have, always scroll up to the top of the output 1617 01:16:13,230 --> 01:16:15,210 and address the first error first. 1618 01:16:15,210 --> 01:16:18,680 So that's why I scrolled up in my window to look immediately below what I typed, 1619 01:16:18,680 --> 01:16:20,430 make addition, and here's the first error. 1620 01:16:20,430 --> 01:16:21,910 Addition.c on line 10. 1621 01:16:21,910 --> 01:16:22,410 All right. 1622 01:16:22,410 --> 01:16:24,900 I can't see line 10, so let me scroll my code up. 1623 01:16:24,900 --> 01:16:28,200 And it's saying something about format specifies type int, 1624 01:16:28,200 --> 01:16:30,360 but the argument has type long. 1625 01:16:30,360 --> 01:16:33,570 We haven't seen this error before, but I think I can infer from this. 1626 01:16:33,570 --> 01:16:36,900 It's not super cryptic even though it's unfamiliar. 1627 01:16:36,900 --> 01:16:40,650 I think what this means is that percent i recall was for integers. 1628 01:16:40,650 --> 01:16:46,200 I think what I need is a different format code for long integers, which 1629 01:16:46,200 --> 01:16:48,510 is going to be li instead. 1630 01:16:48,510 --> 01:16:50,620 And that was from my little cheat sheet earlier. 1631 01:16:50,620 --> 01:16:52,203 So let me go ahead and try this again. 1632 01:16:52,203 --> 01:16:54,360 Make addition after changing the i to an li. 1633 01:16:54,360 --> 01:16:55,470 That indeed works. 1634 01:16:55,470 --> 01:16:56,850 Now let me do-- 1635 01:16:56,850 --> 01:16:57,720 oops, typo. 1636 01:16:57,720 --> 01:16:59,610 Now let me dot slash addition. 1637 01:16:59,610 --> 01:17:04,108 And now I'll type in 4,000,000,000. 1638 01:17:04,108 --> 01:17:05,340 4 billion. 1639 01:17:05,340 --> 01:17:10,440 Now get_long is happy, and it will accept such a long integer 1640 01:17:10,440 --> 01:17:13,650 because it has enough bits. 1641 01:17:13,650 --> 01:17:19,560 All right, questions on types like ints and longs, 1642 01:17:19,560 --> 01:17:22,080 or functions like get_int or get_long. 1643 01:17:22,080 --> 01:17:23,820 Yeah, Peter. 1644 01:17:23,820 --> 01:17:24,780 AUDIENCE: Yeah. 1645 01:17:24,780 --> 01:17:30,090 When I typed 2 billion and both were integers, well, 1646 01:17:30,090 --> 01:17:32,130 eventually it just gives you the wrong answer. 1647 01:17:32,130 --> 01:17:33,160 Some negative numbers. 1648 01:17:33,160 --> 01:17:34,807 Is that because of the bits and bytes? 1649 01:17:34,807 --> 01:17:35,640 DAVID MALAN: Indeed. 1650 01:17:35,640 --> 01:17:36,640 It's the same answer. 1651 01:17:36,640 --> 01:17:39,330 So I didn't demonstrate that, but if you inputed both 2 billion 1652 01:17:39,330 --> 01:17:45,660 for x and 2 billion for y and then you try to add those together, 1653 01:17:45,660 --> 01:17:48,090 that would give you mathematically 4 billion. 1654 01:17:48,090 --> 01:17:52,170 But again, an int is not big enough to store 4 billion 1655 01:17:52,170 --> 01:17:55,360 if we want to also be able to represent negative numbers. 1656 01:17:55,360 --> 01:17:58,590 So Peter what you're seeing is that you can't fit 1657 01:17:58,590 --> 01:18:01,440 the result in the data type allowed. 1658 01:18:01,440 --> 01:18:02,850 And we'll see in a moment-- 1659 01:18:02,850 --> 01:18:05,657 in a little bit today, actually, what the ramifications of that 1660 01:18:05,657 --> 01:18:07,740 are, but the symptom you're describing is exactly. 1661 01:18:07,740 --> 01:18:13,020 That you tried to cram too big of a number into finitely many bits, 32. 1662 01:18:13,020 --> 01:18:16,990 You can avoid that problem though, of course, by switching over to long. 1663 01:18:16,990 --> 01:18:19,090 Let me try one other thing that's a bit curious. 1664 01:18:19,090 --> 01:18:21,690 Let me go ahead and write a slightly different program now. 1665 01:18:21,690 --> 01:18:25,562 And I'm going to describe this as truncation.c. 1666 01:18:25,562 --> 01:18:28,020 Fancy term, but we'll see what this means in just a moment. 1667 01:18:28,020 --> 01:18:30,450 I'm going to give myself at the top, cs50.h. 1668 01:18:30,450 --> 01:18:32,875 And I'm going to give myself stdio.h. 1669 01:18:32,875 --> 01:18:36,000 And it's certainly fine, once you get started with the first lab or problem 1670 01:18:36,000 --> 01:18:39,270 set, if it takes you much longer to type some of these things out. 1671 01:18:39,270 --> 01:18:41,130 I'm just doing it for muscle memory. 1672 01:18:41,130 --> 01:18:42,450 Int main void. 1673 01:18:42,450 --> 01:18:46,560 And now we're good to go with a new program in a file called truncation.c. 1674 01:18:46,560 --> 01:18:49,690 I'm going to go ahead and prompt a user for an int, again. 1675 01:18:49,690 --> 01:18:51,380 So just like before. 1676 01:18:51,380 --> 01:18:55,760 I'm going to prompt the user for another int, just like before. 1677 01:18:55,760 --> 01:18:57,580 And then I'm going to go ahead and do this. 1678 01:18:57,580 --> 01:18:58,930 I want to do division this time. 1679 01:18:58,930 --> 01:19:00,790 So not just a addition, that was a little too easy. 1680 01:19:00,790 --> 01:19:01,790 Let me do a division. 1681 01:19:01,790 --> 01:19:08,140 So let me give myself another variable, z equals x divided by y. 1682 01:19:08,140 --> 01:19:10,270 And let me pause here for a moment and just ask 1683 01:19:10,270 --> 01:19:14,530 the question, what data type should I perhaps use for z? 1684 01:19:14,530 --> 01:19:17,470 This line of code is not yet correct, because recall that any time you 1685 01:19:17,470 --> 01:19:20,440 create a new variable on the left here, I'm 1686 01:19:20,440 --> 01:19:24,430 going to need to put something to the left of that variable's name 1687 01:19:24,430 --> 01:19:27,370 so that C knows what type of variable I want. 1688 01:19:27,370 --> 01:19:30,380 And thus far we've seen string and int and long. 1689 01:19:30,380 --> 01:19:34,510 So would you propose we use one of those or something else for z? 1690 01:19:34,510 --> 01:19:35,330 How about Jack. 1691 01:19:35,330 --> 01:19:37,360 What do you think? 1692 01:19:37,360 --> 01:19:38,890 AUDIENCE: Would it be a float? 1693 01:19:38,890 --> 01:19:40,090 DAVID MALAN: Yeah, so float. 1694 01:19:40,090 --> 01:19:44,050 So float, which is short for floating point value, which is the programmer's 1695 01:19:44,050 --> 01:19:45,640 way of describing a real number. 1696 01:19:45,640 --> 01:19:46,480 Let me go ahead and do that. 1697 01:19:46,480 --> 01:19:46,990 A float. 1698 01:19:46,990 --> 01:19:51,040 And I'm guessing your instincts for float were that, well, 1699 01:19:51,040 --> 01:19:53,860 if you type in one number for x and another for y 1700 01:19:53,860 --> 01:19:56,285 and the result is a fraction of some sort, so something 1701 01:19:56,285 --> 01:19:57,160 with a decimal point. 1702 01:19:57,160 --> 01:20:01,060 We need to store it in a float so that we can actually 1703 01:20:01,060 --> 01:20:05,030 store whatever the numbers are after the decimal point. 1704 01:20:05,030 --> 01:20:06,280 So let's go ahead and do this. 1705 01:20:06,280 --> 01:20:08,440 Let me now go ahead and print this out. 1706 01:20:08,440 --> 01:20:11,740 Percent f backslash n, because I'm printing a float this time. 1707 01:20:11,740 --> 01:20:14,740 And then let me go ahead and print out the value of z. 1708 01:20:14,740 --> 01:20:15,490 And you know what? 1709 01:20:15,490 --> 01:20:19,050 Just for good measure, let me start practicing good style here too. 1710 01:20:19,050 --> 01:20:21,502 So get a number from user. 1711 01:20:21,502 --> 01:20:22,960 Let me give myself another comment. 1712 01:20:22,960 --> 01:20:24,952 Get another number from user. 1713 01:20:24,952 --> 01:20:25,660 Or you know what? 1714 01:20:25,660 --> 01:20:26,830 This seems a little silly. 1715 01:20:26,830 --> 01:20:28,060 I can combine these lines. 1716 01:20:28,060 --> 01:20:31,420 And why don't I just say, get, for instance, numbers from user. 1717 01:20:31,420 --> 01:20:33,640 That's a reasonable way to comment your code. 1718 01:20:33,640 --> 01:20:37,740 And then let's just go ahead and divide x by y. 1719 01:20:37,740 --> 01:20:39,490 But even this is getting a little pedantic 1720 01:20:39,490 --> 01:20:41,540 because you can kind of read that from the code. 1721 01:20:41,540 --> 01:20:44,900 So at some point we might not even need a comment for that. 1722 01:20:44,900 --> 01:20:47,050 So let's just simplify as such. 1723 01:20:47,050 --> 01:20:49,780 Let's go ahead now and compile this. 1724 01:20:49,780 --> 01:20:51,880 Make-- come on-- 1725 01:20:51,880 --> 01:20:54,520 make truncation. 1726 01:20:54,520 --> 01:20:56,020 All right, it compiles OK. 1727 01:20:56,020 --> 01:20:57,580 And I like how we used a float here. 1728 01:20:57,580 --> 01:20:58,750 That does feel correct. 1729 01:20:58,750 --> 01:21:00,340 So let me run truncation. 1730 01:21:00,340 --> 01:21:04,690 And let me go ahead and type in, for instance, 4 for x and 2 for y. 1731 01:21:04,690 --> 01:21:05,710 OK, I like that. 1732 01:21:05,710 --> 01:21:09,580 It's 2.000, so that's the correct math calculation. 1733 01:21:09,580 --> 01:21:11,290 How about 1 divided by 2. 1734 01:21:11,290 --> 01:21:17,935 So x is 1, y is 2, and it's 0.000000. 1735 01:21:17,935 --> 01:21:19,810 All right, well, maybe that was just a fluke. 1736 01:21:19,810 --> 01:21:22,000 Let me try running it again. 1737 01:21:22,000 --> 01:21:23,230 How about 2/3? 1738 01:21:23,230 --> 01:21:26,560 2 divided by 3. 1739 01:21:26,560 --> 01:21:28,610 That's not right either. 1740 01:21:28,610 --> 01:21:29,110 All right. 1741 01:21:29,110 --> 01:21:30,760 How about 4/3? 1742 01:21:30,760 --> 01:21:35,060 Let's put a bigger number for the x, so 4/3. 1743 01:21:35,060 --> 01:21:37,570 OK, it's closer to right. 1744 01:21:37,570 --> 01:21:41,000 But this is an example, this week, of a bug. 1745 01:21:41,000 --> 01:21:42,980 So my code compile. 1746 01:21:42,980 --> 01:21:46,180 So syntactically it's fine, but this is a logical bug. 1747 01:21:46,180 --> 01:21:49,460 Like I've somehow used C code improperly. 1748 01:21:49,460 --> 01:21:51,860 So what might be going on here? 1749 01:21:51,860 --> 01:21:56,860 Why is 1 divided by 2 and 2 divided by 3 both apparently zero, 1750 01:21:56,860 --> 01:22:00,200 followed by six zeros after the decimal point. 1751 01:22:00,200 --> 01:22:08,290 And even 4/3 gives me 1.000000 instead of 1.33333. 1752 01:22:08,290 --> 01:22:10,300 Nina, what do you think? 1753 01:22:10,300 --> 01:22:15,160 AUDIENCE: Because with int they don't recognize decimals. 1754 01:22:15,160 --> 01:22:20,740 So 4/3 question three only goes into 4 one time, so it returns a 1. 1755 01:22:20,740 --> 01:22:23,470 And you need to use other types of character, 1756 01:22:23,470 --> 01:22:27,145 like a float or a double if you want the actual decimal. 1757 01:22:27,145 --> 01:22:28,270 DAVID MALAN: Yeah, exactly. 1758 01:22:28,270 --> 01:22:30,850 This one's more subtle than the mistakes I've made before. 1759 01:22:30,850 --> 01:22:34,900 But C, like most programming languages, is going to take you literally. 1760 01:22:34,900 --> 01:22:38,500 So if on the right hand side of this expression, on line 11, 1761 01:22:38,500 --> 01:22:41,650 I am literally doing x divided by y. 1762 01:22:41,650 --> 01:22:44,860 You first have to ask yourself, well, what is the type of x? 1763 01:22:44,860 --> 01:22:46,690 What is the type of y? 1764 01:22:46,690 --> 01:22:51,020 If they are both ints, by definition of how C works, 1765 01:22:51,020 --> 01:22:54,260 you are going to get back an integer as your answer. 1766 01:22:54,260 --> 01:22:56,080 So if you do 1 divided by 2. 1767 01:22:56,080 --> 01:23:00,820 Yes, mathematically that's 0.50000. 1768 01:23:00,820 --> 01:23:06,160 However, if you convert that to an int, in so far as x and y are ints, 1769 01:23:06,160 --> 01:23:09,980 the way C works is it truncates everything after the decimal point. 1770 01:23:09,980 --> 01:23:14,140 So it does the math correctly, but because you cannot fit floating point 1771 01:23:14,140 --> 01:23:18,280 values, you cannot fit decimal points and numbers thereafter in an integer, 1772 01:23:18,280 --> 01:23:23,140 you get you lose all of those digits after the decimal point because you can 1773 01:23:23,140 --> 01:23:27,550 only fit the integer part of the answer into an integer. 1774 01:23:27,550 --> 01:23:32,020 It's not relevant that I'm saving the result ultimately in a float 1775 01:23:32,020 --> 01:23:33,160 because that's too late. 1776 01:23:33,160 --> 01:23:36,110 The math has already been done on the right hand side. 1777 01:23:36,110 --> 01:23:40,220 And so yes, I'm storing an integer in a float so I can print it as a float, 1778 01:23:40,220 --> 01:23:40,990 but it's too late. 1779 01:23:40,990 --> 01:23:44,390 Everything after the decimal point has already been thrown away. 1780 01:23:44,390 --> 01:23:46,780 So what are the implications of this, or how could I fix? 1781 01:23:46,780 --> 01:23:49,900 Well, I could go through and just change all of this right. 1782 01:23:49,900 --> 01:23:52,073 Well, if the problem is that x and y are ints, 1783 01:23:52,073 --> 01:23:53,740 well, let me just change them to floats. 1784 01:23:53,740 --> 01:23:57,880 And change this up here, change x to a float, change y to a float, 1785 01:23:57,880 --> 01:23:58,780 and so forth. 1786 01:23:58,780 --> 01:24:00,072 That would fix the problem. 1787 01:24:00,072 --> 01:24:02,530 But that's kind of a heavy handed solution to this problem. 1788 01:24:02,530 --> 01:24:04,300 Go through and change all of your code. 1789 01:24:04,300 --> 01:24:07,210 You can instead be a little more clever, and you 1790 01:24:07,210 --> 01:24:11,590 can convince the computer to convert an integer to a float 1791 01:24:11,590 --> 01:24:13,240 by something known as casting. 1792 01:24:13,240 --> 01:24:17,390 So I can actually go in here, and using a new syntax I can say float y. 1793 01:24:17,390 --> 01:24:20,140 And I can even, for good measure, but it's not strictly necessary, 1794 01:24:20,140 --> 01:24:21,670 also do it to x. 1795 01:24:21,670 --> 01:24:27,190 You can in C, cast or typecast one data type to another 1796 01:24:27,190 --> 01:24:31,070 by literally in parentheses just putting the new data type that you want. 1797 01:24:31,070 --> 01:24:35,590 And if it makes mathematical sense for one to be converted into the other, 1798 01:24:35,590 --> 01:24:37,340 the computer will do it for you. 1799 01:24:37,340 --> 01:24:41,320 So in this way I'm telling the computer, convert x to a float, 1800 01:24:41,320 --> 01:24:43,990 convert y to a float, then do the math. 1801 01:24:43,990 --> 01:24:48,010 And so before when I typed in one and two respectively for x and y, 1802 01:24:48,010 --> 01:24:53,140 now it's like I typed in 1.0 and 2.0. 1803 01:24:53,140 --> 01:24:59,080 And 1.0 divided by 2.0 is going to be mathematically 0.5, 1804 01:24:59,080 --> 01:25:03,160 but because x and y now were converted in advance to floats, 1805 01:25:03,160 --> 01:25:06,520 the answer is going to remain a float, 0.5. 1806 01:25:06,520 --> 01:25:10,400 And that's what's going to get stored in z and ultimately printed. 1807 01:25:10,400 --> 01:25:14,020 So if I rerun truncation having now fixed this problem. 1808 01:25:14,020 --> 01:25:15,760 Let me do dot slash truncation. 1809 01:25:15,760 --> 01:25:17,530 Type in one, type in two. 1810 01:25:17,530 --> 01:25:19,480 I don't have to type the 0.0 myself. 1811 01:25:19,480 --> 01:25:23,560 The computer's doing that for me via these casts in parentheses. 1812 01:25:23,560 --> 01:25:27,910 Now I see that the answer is indeed 0.5. 1813 01:25:27,910 --> 01:25:29,020 All right. 1814 01:25:29,020 --> 01:25:32,410 So we seem to have now some very basic low level control 1815 01:25:32,410 --> 01:25:34,310 over what you can do with the program. 1816 01:25:34,310 --> 01:25:36,247 Let's now add back all of the fancy features 1817 01:25:36,247 --> 01:25:38,080 that we had from Scratch last week so we can 1818 01:25:38,080 --> 01:25:40,330 start making more interesting programs. 1819 01:25:40,330 --> 01:25:44,740 So variables and another term of art called syntactic sugar is also 1820 01:25:44,740 --> 01:25:46,220 among C's features here. 1821 01:25:46,220 --> 01:25:49,150 So recall from last week when we wanted to have a variable called 1822 01:25:49,150 --> 01:25:50,980 counter set equal to zero. 1823 01:25:50,980 --> 01:25:52,960 We can go ahead and define it like this. 1824 01:25:52,960 --> 01:25:56,080 In C, starting today, we're going to instead say something 1825 01:25:56,080 --> 01:25:57,730 like, counter equals zero. 1826 01:25:57,730 --> 01:26:01,420 But we additionally need to specify the data type of that variable, 1827 01:26:01,420 --> 01:26:04,860 and we need to end our thought with a semicolon. 1828 01:26:04,860 --> 01:26:08,020 So whereas we set counter to zero like this last week, now 1829 01:26:08,020 --> 01:26:11,170 it's going to translate quite simply to this on the right hand side. 1830 01:26:11,170 --> 01:26:12,400 Well, what comes after that? 1831 01:26:12,400 --> 01:26:16,120 Well, if we wanted to increment a counter variable last week by one, 1832 01:26:16,120 --> 01:26:18,790 adding one to it, we used quite simply this puzzle piece. 1833 01:26:18,790 --> 01:26:23,200 This week we need to be a little more explicit and say something like this. 1834 01:26:23,200 --> 01:26:27,730 Counter equals counter plus one, and semicolon to finish the thought. 1835 01:26:27,730 --> 01:26:30,670 Now, this might seem very mathematically paradoxical. 1836 01:26:30,670 --> 01:26:34,030 Like, how can counter equal counter plus one? 1837 01:26:34,030 --> 01:26:36,700 Like, that just doesn't work logically. 1838 01:26:36,700 --> 01:26:39,820 But that's not the equal sign in this case. 1839 01:26:39,820 --> 01:26:42,940 In C, as with other languages we'll encounter, 1840 01:26:42,940 --> 01:26:46,880 the equals sign is the assignment operator from right to left. 1841 01:26:46,880 --> 01:26:49,210 So this is saying, take counter plus one, 1842 01:26:49,210 --> 01:26:52,300 and store that mathematical result on the left. 1843 01:26:52,300 --> 01:26:57,550 So whatever counter is, add one, store the result in counter thereafter. 1844 01:26:57,550 --> 01:26:59,950 Effectively, increasing its total by one. 1845 01:26:59,950 --> 01:27:02,170 Now this is a very common operation in programs 1846 01:27:02,170 --> 01:27:04,150 we'll see over the term where you just want to add something up 1847 01:27:04,150 --> 01:27:06,610 because you want to keep track of the count of something. 1848 01:27:06,610 --> 01:27:09,460 So it turns out there's some syntactic sugar, which 1849 01:27:09,460 --> 01:27:12,850 means there's a different way of doing this syntactically that doesn't give 1850 01:27:12,850 --> 01:27:15,010 you any new capabilities that you didn't already 1851 01:27:15,010 --> 01:27:19,510 have in C. It just makes it marginally more pleasant or quicker to type. 1852 01:27:19,510 --> 01:27:24,100 So this line of code in C is identical to saying this line of code 1853 01:27:24,100 --> 01:27:30,130 in C. Counter plus equals one semicolon means take the variable on the left 1854 01:27:30,130 --> 01:27:31,417 and just add one to it. 1855 01:27:31,417 --> 01:27:33,250 And it's slightly more succinct, and it just 1856 01:27:33,250 --> 01:27:36,550 makes your code a little more readable because it's just fewer things for us 1857 01:27:36,550 --> 01:27:38,290 humans to have to read. 1858 01:27:38,290 --> 01:27:40,150 But you can even do one step further. 1859 01:27:40,150 --> 01:27:42,585 Additional syntactic sugar exists, whereby 1860 01:27:42,585 --> 01:27:43,960 you don't even need to type this. 1861 01:27:43,960 --> 01:27:46,990 You can instead just do counter plus plus. 1862 01:27:46,990 --> 01:27:49,520 Counter plus plus is the shortest hand notation 1863 01:27:49,520 --> 01:27:53,320 in C for just adding one to a variable. 1864 01:27:53,320 --> 01:27:54,040 All right. 1865 01:27:54,040 --> 01:27:58,360 Besides variables, what else do we have in our toolkit as of last week? 1866 01:27:58,360 --> 01:28:01,270 Well, we also had in our toolkit last week the notion, of course, 1867 01:28:01,270 --> 01:28:02,230 of conditions. 1868 01:28:02,230 --> 01:28:04,065 A condition was like a fork in the road that 1869 01:28:04,065 --> 01:28:06,940 could allow you to do this thing, this other thing, or something else 1870 01:28:06,940 --> 01:28:07,630 altogether. 1871 01:28:07,630 --> 01:28:11,570 In Scratch for instance, if we wanted last week to compare two variables, 1872 01:28:11,570 --> 01:28:13,780 x and y for inequality. 1873 01:28:13,780 --> 01:28:15,010 Is x less than y? 1874 01:28:15,010 --> 01:28:17,800 And if so, say x is less than y. 1875 01:28:17,800 --> 01:28:19,780 How can we translate this to C? 1876 01:28:19,780 --> 01:28:23,140 Well, the syntax is going to be quite simply this. 1877 01:28:23,140 --> 01:28:24,010 Some new stuff. 1878 01:28:24,010 --> 01:28:26,500 Some more parentheses, some more curly braces. 1879 01:28:26,500 --> 01:28:29,830 But it kind of visually looks the same, albeit in text form. 1880 01:28:29,830 --> 01:28:33,130 I literally say, if a space, then in parentheses I 1881 01:28:33,130 --> 01:28:36,160 include my Boolean expression, recall those from last week. 1882 01:28:36,160 --> 01:28:38,680 X less than y is my Boolean expression. 1883 01:28:38,680 --> 01:28:42,100 Then notice I use an open curly brace and a close curly brace. 1884 01:28:42,100 --> 01:28:45,460 And then I'm just leaving a blank line for one or more lines of code 1885 01:28:45,460 --> 01:28:47,260 just like I might of last week. 1886 01:28:47,260 --> 01:28:49,750 And in fact, let's put the equivalent line of code here. 1887 01:28:49,750 --> 01:28:55,030 Print out using printf, x is less than y, backslash n. 1888 01:28:55,030 --> 01:28:56,950 So we've already done that translation before. 1889 01:28:56,950 --> 01:29:01,390 Say is just like printf, just like if now is like if. 1890 01:29:01,390 --> 01:29:04,090 Strictly speaking, especially if you've programmed before, 1891 01:29:04,090 --> 01:29:07,690 you do not need these two curly braces if you only 1892 01:29:07,690 --> 01:29:10,820 have one line of code inside of the condition. 1893 01:29:10,820 --> 01:29:14,410 However, stylistically for CS50 and for style50's sake, 1894 01:29:14,410 --> 01:29:19,420 always include these curly braces nonetheless, and on their own lines. 1895 01:29:19,420 --> 01:29:21,190 All right, what else can we do in Scratch? 1896 01:29:21,190 --> 01:29:23,140 Recall that we can do if else. 1897 01:29:23,140 --> 01:29:27,130 And we can go either one way in the fork or the other way in the fork. 1898 01:29:27,130 --> 01:29:29,990 In C, the corresponding code is going to look like this. 1899 01:29:29,990 --> 01:29:31,600 So it's almost the same as before. 1900 01:29:31,600 --> 01:29:35,470 I've just added else, and then another curly brace and a close curly brace. 1901 01:29:35,470 --> 01:29:37,240 And let me just add in the printf's. 1902 01:29:37,240 --> 01:29:40,030 And you can see that in C this is really like the black and white, 1903 01:29:40,030 --> 01:29:43,300 the text based version of what was very graphical last week, 1904 01:29:43,300 --> 01:29:44,430 but the idea is the same. 1905 01:29:44,430 --> 01:29:46,930 You just got to start to recognize where the parentheses go, 1906 01:29:46,930 --> 01:29:48,850 where the curly braces go, the semicolons, 1907 01:29:48,850 --> 01:29:51,100 and all that sort of visual stuff. 1908 01:29:51,100 --> 01:29:54,940 All right, let's make one more Scratch comparison. 1909 01:29:54,940 --> 01:29:58,870 Here is one where I said if x is less than y, say x is less than y. 1910 01:29:58,870 --> 01:30:02,470 Else if x is greater than y, say x is greater than y. 1911 01:30:02,470 --> 01:30:06,490 Else if x equals y, then say x equal to y. 1912 01:30:06,490 --> 01:30:08,590 Now, here is where Scratch and C diverge. 1913 01:30:08,590 --> 01:30:10,810 Because Scratch is meant to be very user friendly 1914 01:30:10,810 --> 01:30:15,460 and not require long explanations of assignment operators, MIT for Scratch 1915 01:30:15,460 --> 01:30:18,550 just use the equal sign for equality. 1916 01:30:18,550 --> 01:30:22,120 Whereas C uses the equal sign for assignment from left to right, 1917 01:30:22,120 --> 01:30:24,910 but this means equality as before. 1918 01:30:24,910 --> 01:30:25,630 All right. 1919 01:30:25,630 --> 01:30:27,930 Now, notice the difference here. 1920 01:30:27,930 --> 01:30:30,990 Everything is a line by line translation, 1921 01:30:30,990 --> 01:30:34,140 although we can put else if on the same line and else if on the same line. 1922 01:30:34,140 --> 01:30:36,540 Except here is kind of a stupid workaround, right? 1923 01:30:36,540 --> 01:30:40,200 In some sense humans decades ago realized, oh, shoot, at one point. 1924 01:30:40,200 --> 01:30:42,870 We've already used the equal sign for assignment. 1925 01:30:42,870 --> 01:30:45,180 What do we use now for equality? 1926 01:30:45,180 --> 01:30:49,590 Well, MIT ignored that problem and just used a single equal sign for equality. 1927 01:30:49,590 --> 01:30:53,100 Computer scientists inventing C and subsequent languages 1928 01:30:53,100 --> 01:30:56,460 when comparing two values on the left and right for equality 1929 01:30:56,460 --> 01:30:59,400 used two equal signs just because. 1930 01:30:59,400 --> 01:31:01,950 One equal sign is assignment from right to left. 1931 01:31:01,950 --> 01:31:04,800 Two equal signs is equality comparisons. 1932 01:31:04,800 --> 01:31:06,870 Are these two values equal? 1933 01:31:06,870 --> 01:31:08,220 But you know what? 1934 01:31:08,220 --> 01:31:10,890 This is not necessarily well designed. 1935 01:31:10,890 --> 01:31:11,760 It is correct. 1936 01:31:11,760 --> 01:31:15,360 Logically both my scratch code and my C code is correct, 1937 01:31:15,360 --> 01:31:19,560 but can anyone make an observation as to why the code is not 1938 01:31:19,560 --> 01:31:21,300 necessarily well designed? 1939 01:31:21,300 --> 01:31:24,090 I'm doing a little more work than I need to. 1940 01:31:24,090 --> 01:31:26,730 I could tighten this code up a little bit. 1941 01:31:26,730 --> 01:31:29,790 I could type slightly fewer characters and accomplish 1942 01:31:29,790 --> 01:31:34,120 the same correct decision making. 1943 01:31:34,120 --> 01:31:39,820 Any thoughts on in what sense this code is not perfectly designed? 1944 01:31:39,820 --> 01:31:41,640 [INAUDIBLE], over to you. 1945 01:31:41,640 --> 01:31:45,450 AUDIENCE: Yeah, so you used else if two times. 1946 01:31:45,450 --> 01:31:48,828 You could have used else in the end and without the condition. 1947 01:31:48,828 --> 01:31:50,370 DAVID MALAN: Really good observation. 1948 01:31:50,370 --> 01:31:53,260 I'm using else if twice, which logically is fine. 1949 01:31:53,260 --> 01:31:54,210 This code is correct. 1950 01:31:54,210 --> 01:31:58,050 It's asking and answering the right questions, but consider this. 1951 01:31:58,050 --> 01:32:02,460 If x is less than y, is one possibility, one fork in the road. 1952 01:32:02,460 --> 01:32:05,100 Else if x greater than y is the second. 1953 01:32:05,100 --> 01:32:08,610 What's the only other possibility logically in the world of math? 1954 01:32:08,610 --> 01:32:11,730 Either it's less than or greater than or equal to. 1955 01:32:11,730 --> 01:32:16,380 There's no reason to belabor the point and ask that third question explicitly. 1956 01:32:16,380 --> 01:32:20,820 Let's simplify the code and marginally better design it as this. 1957 01:32:20,820 --> 01:32:23,340 Just get rid of the else if as you proposed. 1958 01:32:23,340 --> 01:32:26,580 Which isn't that much cleaner, isn't that much shorter, 1959 01:32:26,580 --> 01:32:29,170 but it does avoid asking an additional question. 1960 01:32:29,170 --> 01:32:32,497 So instead of maybe three questions being asked, now there's only two. 1961 01:32:32,497 --> 01:32:35,580 And frankly, if you're writing a lot of code or doing this again and again 1962 01:32:35,580 --> 01:32:39,780 and again, that kind of difference might very well add up and indeed 1963 01:32:39,780 --> 01:32:42,130 give us now some better code. 1964 01:32:42,130 --> 01:32:44,910 So now that I have the ability to use these conditions. 1965 01:32:44,910 --> 01:32:47,337 Let's actually try converting this into a program. 1966 01:32:47,337 --> 01:32:49,170 Let me go ahead and open up a program that I 1967 01:32:49,170 --> 01:32:51,590 wrote in advance called conditions.c. 1968 01:32:51,590 --> 01:32:55,170 And I have at the top of the file my two includes as usual. 1969 01:32:55,170 --> 01:32:58,110 And then down here, I have pretty much what we just saw on the slide, 1970 01:32:58,110 --> 01:33:02,220 plus two calls, or uses, of get_int. 1971 01:33:02,220 --> 01:33:05,730 And then I'm just asking this question down here, if x less than y. 1972 01:33:05,730 --> 01:33:07,260 Else if x greater than y. 1973 01:33:07,260 --> 01:33:09,400 Else go ahead and do the following. 1974 01:33:09,400 --> 01:33:13,410 So it's just a copy paste pretty much of the Scratch translation. 1975 01:33:13,410 --> 01:33:16,410 Let me go ahead and make conditions, which again, conditions.c 1976 01:33:16,410 --> 01:33:17,490 is the name of the file. 1977 01:33:17,490 --> 01:33:18,840 No apparent mistakes. 1978 01:33:18,840 --> 01:33:22,200 So let me go ahead and run dot slash conditions, Enter. 1979 01:33:22,200 --> 01:33:24,330 And x will be 1, y is 2. 1980 01:33:24,330 --> 01:33:26,610 And indeed, x is less than y. 1981 01:33:26,610 --> 01:33:31,560 If I go ahead and run this, this time for instance, with how about 10 and 5. 1982 01:33:31,560 --> 01:33:33,060 X is greater than y. 1983 01:33:33,060 --> 01:33:36,170 And then lastly, if I go ahead and run this with 4 and 4. 1984 01:33:36,170 --> 01:33:37,410 X is equal to y. 1985 01:33:37,410 --> 01:33:40,080 So I now have a C program that is adding conditions 1986 01:33:40,080 --> 01:33:43,650 for me, which is actually then allowing me to make decisions and print out 1987 01:33:43,650 --> 01:33:46,410 one thing potentially or the other. 1988 01:33:46,410 --> 01:33:49,050 But let me do something slightly fancier. 1989 01:33:49,050 --> 01:33:51,720 Let me go ahead and open up another-- 1990 01:33:51,720 --> 01:33:53,640 let me write this program from Scratch. 1991 01:33:53,640 --> 01:33:56,820 Suppose I want to write a program called agree.c 1992 01:33:56,820 --> 01:33:59,010 that stimulates the idea of like these stupid forms 1993 01:33:59,010 --> 01:34:02,100 that you have to agree to when using a piece of software 1994 01:34:02,100 --> 01:34:03,480 for the first time or the like. 1995 01:34:03,480 --> 01:34:07,530 Or even when I deleted a file before I had to type in yes or y in order 1996 01:34:07,530 --> 01:34:08,340 to proceed. 1997 01:34:08,340 --> 01:34:12,240 Let me go ahead and include cd50.h at the top. 1998 01:34:12,240 --> 01:34:15,420 Let me go ahead and include stdio.h at the top. 1999 01:34:15,420 --> 01:34:18,480 And then my int main void, which is copy paste from before. 2000 01:34:18,480 --> 01:34:19,500 And now let me do this. 2001 01:34:19,500 --> 01:34:22,542 Let me go ahead and get, not an input from the user, and not even a word. 2002 01:34:22,542 --> 01:34:27,060 Let's keep it simple and just ask the user for y or n, for yes or no. 2003 01:34:27,060 --> 01:34:30,660 Let me go ahead and give myself a char, and I'll call it c. 2004 01:34:30,660 --> 01:34:32,790 But I could call it anything, like answer. 2005 01:34:32,790 --> 01:34:35,580 But c seems reasonable if I only have one char. 2006 01:34:35,580 --> 01:34:38,520 Let me go ahead and call the function, get_char. 2007 01:34:38,520 --> 01:34:42,120 And let me just ask, do you agree, question mark. 2008 01:34:42,120 --> 01:34:43,870 And then let me go ahead and compare this. 2009 01:34:43,870 --> 01:34:52,890 So if c equals y, then let me go ahead and print out agreed backslash n. 2010 01:34:52,890 --> 01:35:01,590 Else if c equals n, let me go ahead and print out for instance, not agreed. 2011 01:35:01,590 --> 01:35:07,108 Now unfortunately, I've made a couple of mistakes here that at least one 2012 01:35:07,108 --> 01:35:09,400 of which might be a little more obvious than the other. 2013 01:35:09,400 --> 01:35:13,950 Any thoughts on what mistakes or bugs I might have introduced already 2014 01:35:13,950 --> 01:35:16,260 into this program? 2015 01:35:16,260 --> 01:35:17,100 Anyone at all? 2016 01:35:17,100 --> 01:35:19,020 Yeah, how about, Olivia. 2017 01:35:19,020 --> 01:35:20,460 What do you think? 2018 01:35:20,460 --> 01:35:23,580 AUDIENCE: For one thing that for the Boolean 2019 01:35:23,580 --> 01:35:27,330 you did use a single equals sign instead of the double. 2020 01:35:27,330 --> 01:35:28,080 DAVID MALAN: Good. 2021 01:35:28,080 --> 01:35:31,650 So I use the single equal sign instead of double, so I need to fix that. 2022 01:35:31,650 --> 01:35:34,070 And there's another even more subtle bug. 2023 01:35:34,070 --> 01:35:38,390 And this is because C is very specific when it comes to its data types. 2024 01:35:38,390 --> 01:35:41,330 All this time I've been using double quotes for strings, 2025 01:35:41,330 --> 01:35:45,230 but it turns out in C you have to use single quotes when 2026 01:35:45,230 --> 01:35:47,030 you're comparing individual characters. 2027 01:35:47,030 --> 01:35:51,440 So I'm going to go in here and change only the quotes around y and n 2028 01:35:51,440 --> 01:35:52,320 to be single quotes. 2029 01:35:52,320 --> 01:35:52,820 Why? 2030 01:35:52,820 --> 01:35:55,100 Because I'm now dealing with the world of chars. 2031 01:35:55,100 --> 01:35:58,400 Chars are individual characters like y or n. 2032 01:35:58,400 --> 01:36:00,560 And when you are talking about characters, 2033 01:36:00,560 --> 01:36:03,060 you need to quote them literally like this. 2034 01:36:03,060 --> 01:36:05,060 The variable name, c, doesn't need to be quoted. 2035 01:36:05,060 --> 01:36:07,100 But y and n do need to be quoted. 2036 01:36:07,100 --> 01:36:09,860 But I don't need to change any of my other quotes in the file 2037 01:36:09,860 --> 01:36:14,810 because those are still strings of text that is actual phrases or sentences. 2038 01:36:14,810 --> 01:36:17,420 So let me go ahead and try running make agree. 2039 01:36:17,420 --> 01:36:18,590 It compiles OK. 2040 01:36:18,590 --> 01:36:20,870 Let me go ahead and run dot slash agree. 2041 01:36:20,870 --> 01:36:21,680 Do I agree? 2042 01:36:21,680 --> 01:36:23,210 Let me go ahead and type in y. 2043 01:36:23,210 --> 01:36:24,540 Agreed, I like that. 2044 01:36:24,540 --> 01:36:26,510 So let me try n, no. 2045 01:36:26,510 --> 01:36:27,620 Not I agreed. 2046 01:36:27,620 --> 01:36:31,550 And I left off a backslash n, so let me fix that real quick just 2047 01:36:31,550 --> 01:36:32,780 for consistency. 2048 01:36:32,780 --> 01:36:35,330 Let me recompile my program and pretend that never happened. 2049 01:36:35,330 --> 01:36:37,020 But let me very reasonably now do this. 2050 01:36:37,020 --> 01:36:38,330 Dot slash agree. 2051 01:36:38,330 --> 01:36:39,170 I want to agree. 2052 01:36:39,170 --> 01:36:41,656 And yes, capital y. 2053 01:36:41,656 --> 01:36:43,020 Huh, nothing happened. 2054 01:36:43,020 --> 01:36:45,480 What about n, capital N? 2055 01:36:45,480 --> 01:36:46,413 Nothing happened. 2056 01:36:46,413 --> 01:36:47,580 But the program still works. 2057 01:36:47,580 --> 01:36:49,560 If I do lower case it works. 2058 01:36:49,560 --> 01:36:51,390 And if I do lower case there it works. 2059 01:36:51,390 --> 01:36:52,388 So what's going on? 2060 01:36:52,388 --> 01:36:54,930 Well, again, the computer's only going to take you literally. 2061 01:36:54,930 --> 01:36:57,013 And even though we humans might be, oh, it's fine. 2062 01:36:57,013 --> 01:36:58,440 It's upper case or a lower case. 2063 01:36:58,440 --> 01:37:00,700 You have to be more explicit. 2064 01:37:00,700 --> 01:37:03,010 So we can ask two questions as follows. 2065 01:37:03,010 --> 01:37:05,400 We could do something like else if c equals 2066 01:37:05,400 --> 01:37:08,460 equals capital Y in single quotes. 2067 01:37:08,460 --> 01:37:11,880 You could imagine, again, saying agreed like this. 2068 01:37:11,880 --> 01:37:15,740 But just like last week when I started copying and pasting Scratch blocks, 2069 01:37:15,740 --> 01:37:17,730 that's probably not very good design. 2070 01:37:17,730 --> 01:37:24,150 Similarly, this block of code, lines 11 through 14, is almost identical to 7 2071 01:37:24,150 --> 01:37:25,020 through 10. 2072 01:37:25,020 --> 01:37:26,590 Let's just get rid of one of them. 2073 01:37:26,590 --> 01:37:28,632 And let's see if we can't combine these thoughts. 2074 01:37:28,632 --> 01:37:34,170 Let me express if c equals equals y, or c equals equals capital Y. 2075 01:37:34,170 --> 01:37:36,480 And indeed, you can use this vertical bar 2076 01:37:36,480 --> 01:37:39,960 operator, which is the logical or operator, 2077 01:37:39,960 --> 01:37:43,290 and actually say two questions at once. 2078 01:37:43,290 --> 01:37:46,320 It turns out you can do this with the notion of and, a logical 2079 01:37:46,320 --> 01:37:48,330 and, by using ampersand ampersand. 2080 01:37:48,330 --> 01:37:49,750 More on those another time. 2081 01:37:49,750 --> 01:37:52,320 But two vertical bars is the equivalent of just saying, 2082 01:37:52,320 --> 01:37:55,650 if this on the left or this on the right. 2083 01:37:55,650 --> 01:37:58,230 And now if I save and recompile the program with make 2084 01:37:58,230 --> 01:38:00,600 agree, and dot slash agree. 2085 01:38:00,600 --> 01:38:05,910 You'll see that I can type in y in lowercase, or Y in uppercase, 2086 01:38:05,910 --> 01:38:07,660 and now it works. 2087 01:38:07,660 --> 01:38:10,500 So again, it would have been correct to just add 2088 01:38:10,500 --> 01:38:12,240 another else if and another else if. 2089 01:38:12,240 --> 01:38:15,810 But again, not necessary because I can combine these thoughts 2090 01:38:15,810 --> 01:38:17,730 and make my program better designed. 2091 01:38:17,730 --> 01:38:21,810 And notice too, all this time I've been very religiously 2092 01:38:21,810 --> 01:38:25,380 indenting every time I'm inside of curly braces. 2093 01:38:25,380 --> 01:38:29,130 Indenting every time I have an if condition or an else if. 2094 01:38:29,130 --> 01:38:34,600 So I'm manifesting, hopefully, good style aesthetics as well. 2095 01:38:34,600 --> 01:38:35,290 All right. 2096 01:38:35,290 --> 01:38:37,980 Well, now let's consider that we have the ability not 2097 01:38:37,980 --> 01:38:41,730 only to express conditions, but how about also these things called loops. 2098 01:38:41,730 --> 01:38:44,340 Well, turns out in Scratch we had very straightforward loops. 2099 01:38:44,340 --> 01:38:45,810 Do the following forever. 2100 01:38:45,810 --> 01:38:47,070 C is a little clunkier. 2101 01:38:47,070 --> 01:38:51,870 There's no forever keyword in C, but we can mimic this idea as follows. 2102 01:38:51,870 --> 01:38:54,960 The closest way to translate forever in C 2103 01:38:54,960 --> 01:38:58,410 is actually to say while, which kind of has the right semantics in English. 2104 01:38:58,410 --> 01:39:01,500 Like, while something is the case, do this, 2105 01:39:01,500 --> 01:39:03,120 but you have to be even more explicit. 2106 01:39:03,120 --> 01:39:06,550 You can't just say while and then say printf hello, world. 2107 01:39:06,550 --> 01:39:10,470 It turns out in C that while, similar to a condition, 2108 01:39:10,470 --> 01:39:15,180 is constantly asking a question to decide whether or not to continue. 2109 01:39:15,180 --> 01:39:18,970 Very similar, again, to a condition with its own Boolean expression. 2110 01:39:18,970 --> 01:39:23,970 So with while in C, you have to have parentheses after the word while, 2111 01:39:23,970 --> 01:39:26,670 and you have to ask a question in those parentheses. 2112 01:39:26,670 --> 01:39:30,240 You have to say something like, x greater than y, x less than y, 2113 01:39:30,240 --> 01:39:31,120 or the like. 2114 01:39:31,120 --> 01:39:33,120 But this is a bit of a corner case in the sense 2115 01:39:33,120 --> 01:39:35,130 that if you want to do something forever, 2116 01:39:35,130 --> 01:39:36,765 who cares what the question is. 2117 01:39:36,765 --> 01:39:39,450 You just want the answer always to be yes. 2118 01:39:39,450 --> 01:39:42,060 Or in computer terms, always to be true. 2119 01:39:42,060 --> 01:39:46,050 And the most blunt way to express true always 2120 01:39:46,050 --> 01:39:48,250 is literally to write the word true. 2121 01:39:48,250 --> 01:39:50,432 So even though this looks a little weird, this in C 2122 01:39:50,432 --> 01:39:52,140 is how you deliberately induce what we'll 2123 01:39:52,140 --> 01:39:57,300 call an infinite loop that never stops because true is always by definition 2124 01:39:57,300 --> 01:39:57,960 true. 2125 01:39:57,960 --> 01:40:00,420 You don't even have to ask a more complicated question. 2126 01:40:00,420 --> 01:40:03,490 You could put a less than sign, a greater than sign, or the like. 2127 01:40:03,490 --> 01:40:05,532 But if you just want something to happen forever, 2128 01:40:05,532 --> 01:40:09,450 this is the most canonical way to express something forever. 2129 01:40:09,450 --> 01:40:12,120 Well, what if you want to do something finitely many times? 2130 01:40:12,120 --> 01:40:14,850 Well, we can do that in C as well using what's 2131 01:40:14,850 --> 01:40:18,120 going to be called a for loop, or a while loop. 2132 01:40:18,120 --> 01:40:21,070 Well, let's consider both of these in turn. 2133 01:40:21,070 --> 01:40:25,920 So if I want to do something 50 times, the most mechanical manual way 2134 01:40:25,920 --> 01:40:28,620 I can think of is like just count on my fingers, right? 2135 01:40:28,620 --> 01:40:31,200 Like, one, two, three, all the way up to 50 somehow. 2136 01:40:31,200 --> 01:40:34,050 Or 10 maximally on my hands. 2137 01:40:34,050 --> 01:40:37,260 So how can I do something finitely many times in C? 2138 01:40:37,260 --> 01:40:39,300 Well, I have at my disposal variables. 2139 01:40:39,300 --> 01:40:41,610 So let me give myself a variable called counter. 2140 01:40:41,610 --> 01:40:44,025 Initialize it to zero semicolon. 2141 01:40:44,025 --> 01:40:45,900 And the data type will be int, because I just 2142 01:40:45,900 --> 01:40:47,640 need to count much like on my fingers. 2143 01:40:47,640 --> 01:40:48,390 But you know what? 2144 01:40:48,390 --> 01:40:50,310 Counter is a little verbose. 2145 01:40:50,310 --> 01:40:54,150 Programmers whenever they're counting frequently, just counting up from zero 2146 01:40:54,150 --> 01:40:58,680 on up, they'll often just use i for integer, or c for character, 2147 01:40:58,680 --> 01:41:00,000 or s for string. 2148 01:41:00,000 --> 01:41:02,110 You don't want to do that always in your code. 2149 01:41:02,110 --> 01:41:05,280 It's sometimes better for your variables to be more descriptively named, 2150 01:41:05,280 --> 01:41:08,230 but for a stupid variable that's just going to count from zero on up, 2151 01:41:08,230 --> 01:41:10,092 let's just keep it simple and call it i. 2152 01:41:10,092 --> 01:41:12,202 I can now do a while loop again, but now I 2153 01:41:12,202 --> 01:41:14,910 have to ask a question because I don't want this running forever. 2154 01:41:14,910 --> 01:41:16,200 I want it running 50 times. 2155 01:41:16,200 --> 01:41:17,542 What question could I ask? 2156 01:41:17,542 --> 01:41:18,750 Well, why don't I just check. 2157 01:41:18,750 --> 01:41:20,970 While i is less than 50. 2158 01:41:20,970 --> 01:41:23,010 So it's like counting up on 50 fingers. 2159 01:41:23,010 --> 01:41:27,300 Let me start at zero and count up to, but not through i equals 50. 2160 01:41:27,300 --> 01:41:30,870 So so long as i is less than 50, do the following. 2161 01:41:30,870 --> 01:41:31,800 What do I want to do? 2162 01:41:31,800 --> 01:41:33,300 I want to keep printing out hello, world. 2163 01:41:33,300 --> 01:41:33,870 Hello, world. 2164 01:41:33,870 --> 01:41:34,980 Hello, world. 2165 01:41:34,980 --> 01:41:36,210 But I'm not done. 2166 01:41:36,210 --> 01:41:40,830 Because on every iteration of this loop, on every cycle of this loop, 2167 01:41:40,830 --> 01:41:42,750 I need to do one more thing mathematically. 2168 01:41:42,750 --> 01:41:45,330 I need to add another finger, add another finger. 2169 01:41:45,330 --> 01:41:48,270 Or in other words, I need to add one to i. 2170 01:41:48,270 --> 01:41:52,410 So let me go ahead and set i equal to whatever it is now, plus one. 2171 01:41:52,410 --> 01:41:54,300 But again, we have some syntactic sugar just 2172 01:41:54,300 --> 01:41:56,680 to make this a little cleaner, a little tighter. 2173 01:41:56,680 --> 01:41:58,140 I could do i plus equals one. 2174 01:41:58,140 --> 01:42:01,410 Or even more succinctly, i plus plus. 2175 01:42:01,410 --> 01:42:05,310 So even though this is way more annoying to implement than in Scratch 2176 01:42:05,310 --> 01:42:09,840 where MIT just gives you what you want, in C we have all of the building blocks 2177 01:42:09,840 --> 01:42:16,920 now with variables and with loops to implement the notion of repeating 2178 01:42:16,920 --> 01:42:18,540 some finite number of times. 2179 01:42:18,540 --> 01:42:20,208 But there's another way to do this. 2180 01:42:20,208 --> 01:42:22,500 And as you might have discovered with problem set zero, 2181 01:42:22,500 --> 01:42:25,440 there's different ways to achieve the same goals in Scratch. 2182 01:42:25,440 --> 01:42:27,600 Similarly in C, I could do this. 2183 01:42:27,600 --> 01:42:31,650 I could just start counting at one and count up through 50. 2184 01:42:31,650 --> 01:42:34,560 So there's no greater than or equal sign key on your keyboard, 2185 01:42:34,560 --> 01:42:36,570 most likely, or less than or equal to. 2186 01:42:36,570 --> 01:42:40,080 So in C, as with other languages, you just use two characters. 2187 01:42:40,080 --> 01:42:43,290 You do less than sign followed by the equals sign. 2188 01:42:43,290 --> 01:42:45,570 And that expresses less than or equal to. 2189 01:42:45,570 --> 01:42:46,800 So this is also correct. 2190 01:42:46,800 --> 01:42:49,870 If I start counting at one I need to count through 50. 2191 01:42:49,870 --> 01:42:51,220 You can do this. 2192 01:42:51,220 --> 01:42:51,885 Don't do this. 2193 01:42:51,885 --> 01:42:53,370 This is unconventional. 2194 01:42:53,370 --> 01:42:55,800 And like programmers will conventionally, 2195 01:42:55,800 --> 01:42:58,590 per last week when we started always counting from zero with all 2196 01:42:58,590 --> 01:43:03,480 the light bulbs off, they'll instead start at zero and count up to 50. 2197 01:43:03,480 --> 01:43:06,760 Which gives you zero through 49 implicitly. 2198 01:43:06,760 --> 01:43:08,350 So do this, not that. 2199 01:43:08,350 --> 01:43:10,440 But this does speak to the fact that you can solve 2200 01:43:10,440 --> 01:43:12,790 problems in so many different ways. 2201 01:43:12,790 --> 01:43:14,490 There's another way, fundamentally, too. 2202 01:43:14,490 --> 01:43:18,090 We could start counting from 50 down to zero. 2203 01:43:18,090 --> 01:43:22,650 The only difference being we have to do i minus minus instead of i plus plus. 2204 01:43:22,650 --> 01:43:25,410 So again, that's three different ways to solve the same problem. 2205 01:43:25,410 --> 01:43:28,327 And again, you'll start to have the right instincts and muscle memory, 2206 01:43:28,327 --> 01:43:31,260 and you'll also start to see common patterns in lecture code, your TF 2207 01:43:31,260 --> 01:43:34,410 or teaching assistants code, books and references online. 2208 01:43:34,410 --> 01:43:38,130 There just tend to be the ways to do things even though all of these 2209 01:43:38,130 --> 01:43:39,520 are still right. 2210 01:43:39,520 --> 01:43:40,050 All right. 2211 01:43:40,050 --> 01:43:42,000 One more approach to loops here. 2212 01:43:42,000 --> 01:43:45,060 It turns out there's another loop construct that's a little more cryptic, 2213 01:43:45,060 --> 01:43:46,500 and it's called a for loop. 2214 01:43:46,500 --> 01:43:48,900 And it allows you to automate-- or rather, 2215 01:43:48,900 --> 01:43:52,560 allows you to express all of those steps a little more concisely. 2216 01:43:52,560 --> 01:43:57,720 So for printf hello, world is going to get us one step closer to printing 2217 01:43:57,720 --> 01:43:59,340 hello, world 50 times. 2218 01:43:59,340 --> 01:44:03,090 But the for statement, just like the while statement, 2219 01:44:03,090 --> 01:44:05,580 comes with necessary parentheses after it, 2220 01:44:05,580 --> 01:44:08,130 but this time you can put more stuff in the parentheses. 2221 01:44:08,130 --> 01:44:10,050 It's not just a Boolean expression. 2222 01:44:10,050 --> 01:44:12,630 First, the first thing in the parentheses 2223 01:44:12,630 --> 01:44:16,110 is you can initialize any variable you want to some value. 2224 01:44:16,110 --> 01:44:18,830 I might say encounter equals zero, or more succinctly, 2225 01:44:18,830 --> 01:44:21,450 int i equals zero semicolon. 2226 01:44:21,450 --> 01:44:23,860 But the way the for loop looks, it's a little funky. 2227 01:44:23,860 --> 01:44:25,990 You can do multiple things on one line. 2228 01:44:25,990 --> 01:44:29,040 The second thing inside of the parentheses to a for loop 2229 01:44:29,040 --> 01:44:32,370 is a condition that you want to check again and again and again. 2230 01:44:32,370 --> 01:44:35,220 And the last thing in the parentheses of a for loop 2231 01:44:35,220 --> 01:44:38,790 is an update, or an incrementation or decrementation 2232 01:44:38,790 --> 01:44:41,490 whereby you can do i equals i plus one. 2233 01:44:41,490 --> 01:44:44,010 Or rather, let's just do i plus equals one. 2234 01:44:44,010 --> 01:44:46,830 Or even more succinctly, i plus plus. 2235 01:44:46,830 --> 01:44:49,710 This is perhaps the most conventional way 2236 01:44:49,710 --> 01:44:54,540 in C and in other programming languages to do something 50 times, 2237 01:44:54,540 --> 01:44:56,042 or a finite number of times. 2238 01:44:56,042 --> 01:44:58,500 It's different looking from the things we've seen thus far. 2239 01:44:58,500 --> 01:45:00,540 There's semicolons in weirder places. 2240 01:45:00,540 --> 01:45:02,020 There's more stuff in parentheses. 2241 01:45:02,020 --> 01:45:04,200 So again, you'll develop the muscle memory overall. 2242 01:45:04,200 --> 01:45:08,430 But for now just realize this says, initialize i to zero. 2243 01:45:08,430 --> 01:45:09,540 Check the condition. 2244 01:45:09,540 --> 01:45:12,420 And if i is less than 50 print hello, world. 2245 01:45:12,420 --> 01:45:14,460 Then update i. 2246 01:45:14,460 --> 01:45:16,060 Then check the condition. 2247 01:45:16,060 --> 01:45:18,420 If it's less than 50, print hello, world. 2248 01:45:18,420 --> 01:45:20,190 Then increment i. 2249 01:45:20,190 --> 01:45:21,690 Then check the condition. 2250 01:45:21,690 --> 01:45:24,340 Then if it's less then, print hello, world. 2251 01:45:24,340 --> 01:45:27,660 So the initialization of the variable happens once. 2252 01:45:27,660 --> 01:45:29,970 Everything else happens again and again and again 2253 01:45:29,970 --> 01:45:33,810 until you've done this some 50 times. 2254 01:45:33,810 --> 01:45:34,530 All right. 2255 01:45:34,530 --> 01:45:36,780 So with those building blocks, that's kind of it 2256 01:45:36,780 --> 01:45:40,110 for our translation of Scratch into C. Let's now start 2257 01:45:40,110 --> 01:45:44,130 to build up some more interesting programs in practice 2258 01:45:44,130 --> 01:45:45,450 for instance, abstraction. 2259 01:45:45,450 --> 01:45:48,570 So abstraction, recall, was this problem solving principle 2260 01:45:48,570 --> 01:45:53,250 whereby you can simplify otherwise more complicated details. 2261 01:45:53,250 --> 01:45:57,570 And abstraction is a simplification on top of more complicated details 2262 01:45:57,570 --> 01:46:00,480 or implementation details as a programmer might say. 2263 01:46:00,480 --> 01:46:02,430 So for instance, let me go ahead and write 2264 01:46:02,430 --> 01:46:06,690 a program here called meow, similar to last week, but this time in C. 2265 01:46:06,690 --> 01:46:09,690 And in order to make a cat meow textually, 2266 01:46:09,690 --> 01:46:12,980 let me give myself stdio.h at the top. 2267 01:46:12,980 --> 01:46:16,140 Int main void down here. 2268 01:46:16,140 --> 01:46:18,105 Again, I'm in a file called meow.c. 2269 01:46:18,105 --> 01:46:21,387 And I've included stdio.h and int main void. 2270 01:46:21,387 --> 01:46:23,970 And now I'm going to go ahead and just do something like this. 2271 01:46:23,970 --> 01:46:27,810 Printf, quote unquote, "meow", backslash n. 2272 01:46:27,810 --> 01:46:31,110 And I want this cat to meow textually three times. 2273 01:46:31,110 --> 01:46:32,700 Let me save that file. 2274 01:46:32,700 --> 01:46:34,150 Make meow. 2275 01:46:34,150 --> 01:46:34,650 All right. 2276 01:46:34,650 --> 01:46:36,090 Now, dot slash meow. 2277 01:46:36,090 --> 01:46:37,660 Meow, meow, meow all in text. 2278 01:46:37,660 --> 01:46:40,740 So not nearly as cute or pretty as the one with the cat last week, 2279 01:46:40,740 --> 01:46:42,630 but it's correct. 2280 01:46:42,630 --> 01:46:45,210 But it's not very well designed, right? 2281 01:46:45,210 --> 01:46:46,740 Because I'm repeating myself. 2282 01:46:46,740 --> 01:46:50,010 I literally copied and pasted, and those are bad instincts. 2283 01:46:50,010 --> 01:46:52,770 But now we have the ability to do things with loops. 2284 01:46:52,770 --> 01:46:55,530 So let me actually delete this part of the function. 2285 01:46:55,530 --> 01:46:58,740 And let me try to remember from the example before. 2286 01:46:58,740 --> 01:47:01,557 If I want to do something three times I could use a while loop, 2287 01:47:01,557 --> 01:47:03,390 but that felt like a bunch of lines of code. 2288 01:47:03,390 --> 01:47:04,050 Let me do this. 2289 01:47:04,050 --> 01:47:06,150 Int i equals zero. 2290 01:47:06,150 --> 01:47:07,950 i less than three. 2291 01:47:07,950 --> 01:47:09,510 i plus plus. 2292 01:47:09,510 --> 01:47:14,850 So cryptic, but this, again, is the de facto way of doing something 2293 01:47:14,850 --> 01:47:16,290 a finite number of times. 2294 01:47:16,290 --> 01:47:20,790 Initialize some variable, like i to zero, check a condition, 2295 01:47:20,790 --> 01:47:23,490 and keep incrementing your variable again and again 2296 01:47:23,490 --> 01:47:26,400 so that it executes a total of that many times. 2297 01:47:26,400 --> 01:47:28,830 Now, let me go ahead and printf meow-- 2298 01:47:28,830 --> 01:47:32,130 mellow-- meow on the inside. 2299 01:47:32,130 --> 01:47:35,280 Let me go ahead and recompile meow by make meow. 2300 01:47:35,280 --> 01:47:37,470 Let me dot slash meow, and voila. 2301 01:47:37,470 --> 01:47:40,297 Now the program is arguably better designed. 2302 01:47:40,297 --> 01:47:41,880 But let me take this one step further. 2303 01:47:41,880 --> 01:47:48,150 Recall that the trajectory last week was to not only implement meow 2304 01:47:48,150 --> 01:47:51,382 with better design, without repeating yourself, thereby using a loop. 2305 01:47:51,382 --> 01:47:53,340 But remember we introduced the abstraction that 2306 01:47:53,340 --> 01:47:55,350 was a custom puzzle piece called meow. 2307 01:47:55,350 --> 01:47:59,462 So in C, turns out we have the ability to make our own functions as well. 2308 01:47:59,462 --> 01:48:02,670 And the syntax is going to take a little getting used to, but let me go ahead 2309 01:48:02,670 --> 01:48:03,330 and do this. 2310 01:48:03,330 --> 01:48:05,250 Let me get rid of my printf here. 2311 01:48:05,250 --> 01:48:08,640 And at the bottom of my file-- actually, at the top of my file 2312 01:48:08,640 --> 01:48:13,890 I'm going to go ahead and type void meow void. 2313 01:48:13,890 --> 01:48:16,140 Which is very cryptic for today, but again, this 2314 01:48:16,140 --> 01:48:19,140 is fine to be boilerplate, copy pasted for now. 2315 01:48:19,140 --> 01:48:21,720 Let me go ahead and just printf meow here. 2316 01:48:21,720 --> 01:48:24,780 Even though we haven't explained and won't explain today 2317 01:48:24,780 --> 01:48:29,010 what this keyword void means, what I've done in lines three through six 2318 01:48:29,010 --> 01:48:31,230 is create my own custom function. 2319 01:48:31,230 --> 01:48:33,990 C does not come with a function called meow. 2320 01:48:33,990 --> 01:48:37,170 CS50's library does not come with a function called meow. 2321 01:48:37,170 --> 01:48:39,510 But now thanks to me, there exists a function 2322 01:48:39,510 --> 01:48:43,440 called meow whose sole purpose in life is just to print out meow. 2323 01:48:43,440 --> 01:48:46,860 But what's cool about this now is that down here, just 2324 01:48:46,860 --> 01:48:51,630 like with Scratch last week, I can now call a function called meow. 2325 01:48:51,630 --> 01:48:53,940 And my code is a little more readable because it rather 2326 01:48:53,940 --> 01:48:58,500 says what it does by just by way of the function's name. 2327 01:48:58,500 --> 01:49:01,020 And let me go ahead now and compile this. 2328 01:49:01,020 --> 01:49:02,760 Make meow. 2329 01:49:02,760 --> 01:49:04,080 So far so good. 2330 01:49:04,080 --> 01:49:08,010 Dot slash meow, and it seems to work OK. 2331 01:49:08,010 --> 01:49:10,950 But I don't love the fact that I've implemented meow 2332 01:49:10,950 --> 01:49:12,120 at the top of the file. 2333 01:49:12,120 --> 01:49:13,290 It's not a big deal. 2334 01:49:13,290 --> 01:49:18,210 By convention we'll typically put custom functions at the bottom of the file. 2335 01:49:18,210 --> 01:49:18,900 Why? 2336 01:49:18,900 --> 01:49:21,570 Only because when a programmer, or in our case, 2337 01:49:21,570 --> 01:49:25,110 a teaching fellow wants to understand your code from top to bottom. 2338 01:49:25,110 --> 01:49:29,100 It's just human convention to put the main program, the main function rather, 2339 01:49:29,100 --> 01:49:31,410 at the top of your file. 2340 01:49:31,410 --> 01:49:36,270 The problem is when I do this, I'm going to have created a problem for myself. 2341 01:49:36,270 --> 01:49:38,670 When I run make meow now, darn it. 2342 01:49:38,670 --> 01:49:42,750 Two errors generated, and so there's a couple of bugs to be solved. 2343 01:49:42,750 --> 01:49:44,583 But first, Brian, a question from the group. 2344 01:49:44,583 --> 01:49:47,375 BRIAN YU: There was a question that came in from the chat about why 2345 01:49:47,375 --> 01:49:49,770 it is that on line five, for example, you don't have 2346 01:49:49,770 --> 01:49:51,480 a semicolon at the end of the for loop. 2347 01:49:51,480 --> 01:49:53,580 And on line 11 you don't have a semicolon 2348 01:49:53,580 --> 01:49:54,940 at the end of the function name. 2349 01:49:54,940 --> 01:49:58,403 So why do some lines need semicolons at the end, but other lines don't? 2350 01:49:58,403 --> 01:49:59,820 DAVID MALAN: Really good question. 2351 01:49:59,820 --> 01:50:03,340 Why do some of these lines not have semicolons, but others do? 2352 01:50:03,340 --> 01:50:06,990 The short answer, not to be glib, is honestly just because. 2353 01:50:06,990 --> 01:50:10,710 The way the language was designed was that you should generally 2354 01:50:10,710 --> 01:50:15,120 finish your thoughts when expressing verbs or actions or functions 2355 01:50:15,120 --> 01:50:16,110 with semicolons. 2356 01:50:16,110 --> 01:50:18,300 And we've seen that after printf for instance. 2357 01:50:18,300 --> 01:50:20,130 We've just seen that after meow. 2358 01:50:20,130 --> 01:50:22,830 However, when you're using other programming constructs, 2359 01:50:22,830 --> 01:50:28,500 like loops or like custom functions, you don't have semicolons there. 2360 01:50:28,500 --> 01:50:29,070 Why? 2361 01:50:29,070 --> 01:50:31,200 Some humans years ago just decided that we 2362 01:50:31,200 --> 01:50:32,783 don't need semicolons in those places. 2363 01:50:32,783 --> 01:50:36,075 And this is one of those things that it will take a while to develop the muscle 2364 01:50:36,075 --> 01:50:39,030 memory and the mental model for recognizing where those things go 2365 01:50:39,030 --> 01:50:39,630 and don't. 2366 01:50:39,630 --> 01:50:42,450 But thus far the only places we've seen semicolons 2367 01:50:42,450 --> 01:50:46,140 are at the ends of functions, like meow and printf here. 2368 01:50:46,140 --> 01:50:51,750 And now, admittedly weirdly, inside of the parentheses for the for loop. 2369 01:50:51,750 --> 01:50:55,740 But again, when tackling problem sets one and the first lab and so forth, 2370 01:50:55,740 --> 01:50:58,920 you'll often want to refer back to examples like these in the slides 2371 01:50:58,920 --> 01:51:01,410 and the references in your section so that you can 2372 01:51:01,410 --> 01:51:03,640 wrap your mind around these patterns. 2373 01:51:03,640 --> 01:51:07,320 So let me go ahead now and solve the two problems I seem to have created here. 2374 01:51:07,320 --> 01:51:10,560 It's a little non obvious, but it's reminiscent of what we've seen before. 2375 01:51:10,560 --> 01:51:14,670 Implicit declaration of function meow is invalid in C99. 2376 01:51:14,670 --> 01:51:19,230 C99 is referring to the 1999 version of C the language we're using, 2377 01:51:19,230 --> 01:51:22,500 but it's just getting confused, C is right now. 2378 01:51:22,500 --> 01:51:23,250 Well, why is that? 2379 01:51:23,250 --> 01:51:27,120 Well, let me scroll up here and let me make the point that frankly C, 2380 01:51:27,120 --> 01:51:29,640 and in turn my compiler, they're not that bright. 2381 01:51:29,640 --> 01:51:32,370 Like, they're only going to do what I tell them to do explicitly. 2382 01:51:32,370 --> 01:51:36,420 And the problem at the moment is that when the compiler reads my code 2383 01:51:36,420 --> 01:51:41,650 from top to bottom, left or right, it is not until line 11 2384 01:51:41,650 --> 01:51:43,960 the meow function even exists. 2385 01:51:43,960 --> 01:51:48,880 However, I am trying on line seven at the moment to use that meow function. 2386 01:51:48,880 --> 01:51:51,250 So my compiler, frankly, just doesn't know 2387 01:51:51,250 --> 01:51:53,830 what meow is because it hasn't gotten to meow later. 2388 01:51:53,830 --> 01:51:56,290 And the compiler is not smart enough, or not 2389 01:51:56,290 --> 01:51:59,765 user friendly enough to read everything first and then decide 2390 01:51:59,765 --> 01:52:00,640 if there's a problem. 2391 01:52:00,640 --> 01:52:03,310 It's only going to read it once through top to bottom, 2392 01:52:03,310 --> 01:52:06,320 and it's going to yell at you the moment it encounters the problem. 2393 01:52:06,320 --> 01:52:09,430 So the solution to this is quite simply, move the function 2394 01:52:09,430 --> 01:52:10,507 to the top of your file. 2395 01:52:10,507 --> 01:52:13,090 But again, that just gets annoying eventually because then you 2396 01:52:13,090 --> 01:52:15,298 have to go fishing for your main function which might 2397 01:52:15,298 --> 01:52:17,320 be dozens of lines down in the file. 2398 01:52:17,320 --> 01:52:20,620 Or there's another way, and we'll explain this in due time too. 2399 01:52:20,620 --> 01:52:26,260 But you can also copy the very first line only of your custom function. 2400 01:52:26,260 --> 01:52:29,890 Put it at the top of your file above main. 2401 01:52:29,890 --> 01:52:33,710 And then, to Brian's question end that with a semicolon. 2402 01:52:33,710 --> 01:52:34,840 So this is weird. 2403 01:52:34,840 --> 01:52:39,490 This is what's generally known as a prototype, which is a hint only. 2404 01:52:39,490 --> 01:52:42,250 It's sort of a clever way of telling the compiler there 2405 01:52:42,250 --> 01:52:45,430 will exist a function called meow, but just not yet. 2406 01:52:45,430 --> 01:52:46,720 But know that it will. 2407 01:52:46,720 --> 01:52:49,480 And it's just kind of a workaround, a common workaround, 2408 01:52:49,480 --> 01:52:52,040 for that particular problem. 2409 01:52:52,040 --> 01:52:52,540 All right. 2410 01:52:52,540 --> 01:52:56,020 So let me go ahead and make one more change, one more change here. 2411 01:52:56,020 --> 01:52:59,440 Suppose that I want to really finish off this meow example 2412 01:52:59,440 --> 01:53:00,610 just like we did in Scratch. 2413 01:53:00,610 --> 01:53:06,110 Whereby we also allow meow to take some number of meows as input. 2414 01:53:06,110 --> 01:53:09,470 So I don't want to have this for loop anymore in my main function. 2415 01:53:09,470 --> 01:53:15,010 Suppose I just want to be able to say, meow three, inside of my main function. 2416 01:53:15,010 --> 01:53:17,560 Three thereby being the input to the meow function. 2417 01:53:17,560 --> 01:53:22,810 I now need to change my custom function, just like I did last week, as follows. 2418 01:53:22,810 --> 01:53:25,390 It turns out-- and more on this in the weeks to come-- 2419 01:53:25,390 --> 01:53:31,150 that this mention a void here on line 11 refers to the return value or output 2420 01:53:31,150 --> 01:53:31,870 of this function. 2421 01:53:31,870 --> 01:53:36,400 Long story short, my custom meow function today has no return value. 2422 01:53:36,400 --> 01:53:39,520 It doesn't output anything per se, it instead only 2423 01:53:39,520 --> 01:53:42,700 has a side effect of printing visually on the screen. 2424 01:53:42,700 --> 01:53:44,140 But it does have an input. 2425 01:53:44,140 --> 01:53:48,850 And if you want to function in C to take input or arguments, 2426 01:53:48,850 --> 01:53:52,128 you can literally do something like, the name of the type you want 2427 01:53:52,128 --> 01:53:53,920 and the name of the variable that you want. 2428 01:53:53,920 --> 01:53:57,640 So suppose I want meow to take as input some number, we'll call it n. 2429 01:53:57,640 --> 01:53:59,560 And I want to use that number in a loop. 2430 01:53:59,560 --> 01:54:01,060 I could then do something like this. 2431 01:54:01,060 --> 01:54:06,940 For int i gets zero, i is less than n, i plus plus. 2432 01:54:06,940 --> 01:54:10,480 I can then surround my printf with curly braces. 2433 01:54:10,480 --> 01:54:15,100 And now notice just like last week with my final implementation of meow, 2434 01:54:15,100 --> 01:54:19,190 my custom function can take input as denoted by the parentheses. i 2435 01:54:19,190 --> 01:54:22,120 doesn't have output per se, that's why I'm leaving void here. 2436 01:54:22,120 --> 01:54:25,390 But again, we'll explain void more in detail down the road. 2437 01:54:25,390 --> 01:54:29,530 But now I'm using that input inside of the for loop. 2438 01:54:29,530 --> 01:54:32,272 So even though this is a new implementation in C, 2439 01:54:32,272 --> 01:54:33,730 I'm using the same building blocks. 2440 01:54:33,730 --> 01:54:37,080 I'm using a for loop like before, but instead of hard coding three, 2441 01:54:37,080 --> 01:54:41,980 or 50 like I did earlier, now I'm actually going to go ahead and just 2442 01:54:41,980 --> 01:54:48,176 plug-in that variable just like Scratch allowed me to do as well. 2443 01:54:48,176 --> 01:54:50,747 Well, what if I want to do something even fancier. 2444 01:54:50,747 --> 01:54:51,330 You know what? 2445 01:54:51,330 --> 01:54:52,497 Let me go ahead and do this. 2446 01:54:52,497 --> 01:54:55,540 Suppose that we want to get input from the user, 2447 01:54:55,540 --> 01:54:58,770 but we really want them to provide a specific type of input. 2448 01:54:58,770 --> 01:55:01,313 Let me go ahead and introduce one other type of loop. 2449 01:55:01,313 --> 01:55:04,230 And this one I'm going to go ahead and grab from my archives, the code 2450 01:55:04,230 --> 01:55:06,240 that I brought with me today. 2451 01:55:06,240 --> 01:55:11,340 And I'm going to go ahead and copy over a file called positive.c, 2452 01:55:11,340 --> 01:55:14,770 which is going to insist that the user give me a positive value. 2453 01:55:14,770 --> 01:55:16,810 So this too is on the course's website. 2454 01:55:16,810 --> 01:55:19,560 And let me just walk us through code that I already wrote. 2455 01:55:19,560 --> 01:55:23,130 Here at the top of my file, I'm including some now familiar header 2456 01:55:23,130 --> 01:55:23,820 files. 2457 01:55:23,820 --> 01:55:26,850 And down here, I'm including a prototype. 2458 01:55:26,850 --> 01:55:29,610 That is a hint for a function that's going to be called, 2459 01:55:29,610 --> 01:55:31,980 quite simply, get_positive_int. 2460 01:55:31,980 --> 01:55:34,870 So this is a function that's only going to get a positive integer. 2461 01:55:34,870 --> 01:55:37,600 Then in my main function, notice I'm going to use this. 2462 01:55:37,600 --> 01:55:40,410 I'm going to get a variable called i on line 10, 2463 01:55:40,410 --> 01:55:43,020 and I'm going to get a positive int from the user. 2464 01:55:43,020 --> 01:55:45,180 And then I'm just going to print it out. 2465 01:55:45,180 --> 01:55:48,720 But what's interesting now is I have this additional abstraction. 2466 01:55:48,720 --> 01:55:52,050 The CS50 library does not come with a function called get_positive_int, 2467 01:55:52,050 --> 01:55:54,660 but it does come with a function called get_int. 2468 01:55:54,660 --> 01:55:58,830 And notice what I've done down here between lines 15 and 24. 2469 01:55:58,830 --> 01:56:03,270 Down here I've declared a function called get_positive_int, 2470 01:56:03,270 --> 01:56:06,060 and notice that's my own custom function name. 2471 01:56:06,060 --> 01:56:09,540 It doesn't take any inputs, it just gets a positive integer from the human. 2472 01:56:09,540 --> 01:56:13,350 But now notice it does have a return value. 2473 01:56:13,350 --> 01:56:16,650 Previously I used the word void to say the absence of input 2474 01:56:16,650 --> 01:56:17,880 or the absence of output. 2475 01:56:17,880 --> 01:56:20,130 Here I'm using it's still to say, no inputs. 2476 01:56:20,130 --> 01:56:22,170 It just always gets a positive int. 2477 01:56:22,170 --> 01:56:25,770 But I'm saying int on the left hand side of this custom function's name 2478 01:56:25,770 --> 01:56:28,420 because this function does have output. 2479 01:56:28,420 --> 01:56:29,910 What is the output going to be? 2480 01:56:29,910 --> 01:56:33,960 We'll, notice here on line 17, I give myself a variable and I call it n. 2481 01:56:33,960 --> 01:56:38,340 Then I have one final new feature of C today, this loop which is called, 2482 01:56:38,340 --> 01:56:41,310 not a while loop, but a do while loop. 2483 01:56:41,310 --> 01:56:44,460 A do while loop is almost the same as a while loop, 2484 01:56:44,460 --> 01:56:49,470 except that it blindly does one thing first before checking a condition. 2485 01:56:49,470 --> 01:56:51,930 So notice here I'm going to do the following. 2486 01:56:51,930 --> 01:56:54,960 Call get_int with this prompt, positive integer, 2487 01:56:54,960 --> 01:56:58,650 and then store the return value into the variable called n. 2488 01:56:58,650 --> 01:57:03,120 Then down here, notice I'm saying while n less than one. 2489 01:57:03,120 --> 01:57:06,000 So this is kind of a weird syntax, but if mathematically I 2490 01:57:06,000 --> 01:57:08,250 want the user to give me a positive integer, 2491 01:57:08,250 --> 01:57:11,850 that's technically the same thing as wanting the user to give me an integer 2492 01:57:11,850 --> 01:57:16,368 and just make sure that it is not less than one. 2493 01:57:16,368 --> 01:57:19,410 Because if it's less than one, it's zero or negative one or negative two, 2494 01:57:19,410 --> 01:57:21,220 that's obviously not a positive integer. 2495 01:57:21,220 --> 01:57:22,890 So how can I express this in code? 2496 01:57:22,890 --> 01:57:24,975 The only new thing at the moment now is the fact 2497 01:57:24,975 --> 01:57:26,850 that there exists this thing called do while. 2498 01:57:26,850 --> 01:57:30,300 And again, the value of do while is that you will do things at least 2499 01:57:30,300 --> 01:57:32,460 once and then check a condition. 2500 01:57:32,460 --> 01:57:36,222 A while loop checks the condition first and then does something instead. 2501 01:57:36,222 --> 01:57:37,930 This is what I want in this case, though. 2502 01:57:37,930 --> 01:57:40,050 I want to do this. 2503 01:57:40,050 --> 01:57:44,080 Get an integer from the user prompting them for a positive integer. 2504 01:57:44,080 --> 01:57:48,090 Then while n is less than one-- so if the human 2505 01:57:48,090 --> 01:57:51,810 typed in zero, or negative one, or negative two, what do I want to do? 2506 01:57:51,810 --> 01:57:54,750 The same thing again and again and again. 2507 01:57:54,750 --> 01:57:56,370 So it reads rather grammatically. 2508 01:57:56,370 --> 01:58:00,590 Do the following while n is less than one. 2509 01:58:00,590 --> 01:58:04,670 And then lastly, and the only other new line here is return n. 2510 01:58:04,670 --> 01:58:08,880 This is the way that a program can actually return some value to you. 2511 01:58:08,880 --> 01:58:11,570 It can hand you back a value, not by printing it on the screen, 2512 01:58:11,570 --> 01:58:14,270 not by saying it audibly or visually from a cat's mouth. 2513 01:58:14,270 --> 01:58:17,300 It returns it in the sense that what's being returned here 2514 01:58:17,300 --> 01:58:21,410 is n, which is an integer that matches the output of this function. 2515 01:58:21,410 --> 01:58:22,830 Why is this useful? 2516 01:58:22,830 --> 01:58:24,200 Well let's scroll back up. 2517 01:58:24,200 --> 01:58:28,320 Let's now take for granted that we get_positive_int function exists. 2518 01:58:28,320 --> 01:58:31,610 And now notice how we can use it in main. 2519 01:58:31,610 --> 01:58:34,070 I call get_positive_int on the right. 2520 01:58:34,070 --> 01:58:37,160 It returns a value I claim that is of type integer. 2521 01:58:37,160 --> 01:58:41,420 I'm storing that return value on the left in this variable called i. 2522 01:58:41,420 --> 01:58:42,830 And then I'm printing out i. 2523 01:58:42,830 --> 01:58:46,010 And just like last week with the meow example in Scratch, 2524 01:58:46,010 --> 01:58:48,590 now that I have implemented get_positive_int, 2525 01:58:48,590 --> 01:58:50,570 it sort of out of sight, out of mind. 2526 01:58:50,570 --> 01:58:53,930 I know that it can be done, and I can abstract away 2527 01:58:53,930 --> 01:58:59,090 the underlying implementation details by just calling it by its name. 2528 01:58:59,090 --> 01:59:01,610 But there's one weird thing that I do want to point out 2529 01:59:01,610 --> 01:59:03,890 about these implementation details. 2530 01:59:03,890 --> 01:59:07,640 Why did I declare n out here? 2531 01:59:07,640 --> 01:59:11,840 Every other time I've created a variable, I've done this. 2532 01:59:11,840 --> 01:59:14,600 It turns out we've been getting lucky this whole time, 2533 01:59:14,600 --> 01:59:17,540 and any time I've declared variables they've technically 2534 01:59:17,540 --> 01:59:19,070 been in between curly braces. 2535 01:59:19,070 --> 01:59:23,120 The curly braces belonging to the main function or my other functions 2536 01:59:23,120 --> 01:59:24,740 that I've written thus far. 2537 01:59:24,740 --> 01:59:26,840 But in this case, the problem is when you 2538 01:59:26,840 --> 01:59:30,050 declare a variable inside of curly braces, 2539 01:59:30,050 --> 01:59:32,390 you run into what we'll call an issue of scope. 2540 01:59:32,390 --> 01:59:36,800 The scope of a variable is the lines of code in which it exists. 2541 01:59:36,800 --> 01:59:41,510 The scope of a variable are the lines of code where you can use that variable. 2542 01:59:41,510 --> 01:59:44,750 And the rule of thumb for today is that if you 2543 01:59:44,750 --> 01:59:47,150 declare a variable inside of curly braces 2544 01:59:47,150 --> 01:59:49,580 like those here on line 26 and 28, which you 2545 01:59:49,580 --> 01:59:53,360 must do for a do while loop, that variable, n, 2546 01:59:53,360 --> 01:59:56,570 only exists inside of those curly braces. 2547 01:59:56,570 --> 02:00:00,530 Which means you cannot compare it against one in line 29. 2548 02:00:00,530 --> 02:00:03,560 Which means you cannot return it in line 30. 2549 02:00:03,560 --> 02:00:05,400 It just no longer exists. 2550 02:00:05,400 --> 02:00:08,840 So you're doing all of this work getting the variable n, and then boom. 2551 02:00:08,840 --> 02:00:13,650 It's gone once you exit top to bottom these curly braces. 2552 02:00:13,650 --> 02:00:16,850 So the workaround for that, stupid though it is frankly, 2553 02:00:16,850 --> 02:00:21,020 is that you can declare n initially on its own line, 25. 2554 02:00:21,020 --> 02:00:23,450 You don't need to assign it a value even, because you're 2555 02:00:23,450 --> 02:00:25,430 going to assign it a value eventually. 2556 02:00:25,430 --> 02:00:29,180 But again, to create a variable, as I keep saying, is to declare a variable. 2557 02:00:29,180 --> 02:00:34,680 You don't need to define it as having a value necessarily right away. 2558 02:00:34,680 --> 02:00:39,980 So this is a way to work around what's otherwise known as an issue of scope. 2559 02:00:39,980 --> 02:00:43,770 All right, with all of these puzzle pieces now in place so to speak, 2560 02:00:43,770 --> 02:00:45,650 let me go ahead and propose that we solve 2561 02:00:45,650 --> 02:00:47,150 something a little more graphical. 2562 02:00:47,150 --> 02:00:51,560 So you'll recall, of course, Super Mario Brothers is one of the first problem 2563 02:00:51,560 --> 02:00:53,130 sets that we alluded to last week. 2564 02:00:53,130 --> 02:00:55,100 And within this game there's a whole bunch of visuals. 2565 02:00:55,100 --> 02:00:57,100 For instance, there's this visual early on where 2566 02:00:57,100 --> 02:00:59,030 there's four question marks in the sky. 2567 02:00:59,030 --> 02:01:02,030 And these question marks, if you jump up and underneath them, 2568 02:01:02,030 --> 02:01:03,232 give you coins for instance. 2569 02:01:03,232 --> 02:01:05,690 So let me draw our attention to that, and let me ask, well, 2570 02:01:05,690 --> 02:01:08,803 how could I write a program in C that just prints out four question marks? 2571 02:01:08,803 --> 02:01:10,220 Well, let me go ahead and do this. 2572 02:01:10,220 --> 02:01:13,040 Let me go ahead and write a program called mario.c. 2573 02:01:13,040 --> 02:01:19,340 Let me go ahead and include stdio.h in a file called mario.c. 2574 02:01:19,340 --> 02:01:21,240 Give myself a main function, int main void. 2575 02:01:21,240 --> 02:01:22,490 I'm going to keep this simple. 2576 02:01:22,490 --> 02:01:26,280 Printf one, two, three, four, backslash n semicolon. 2577 02:01:26,280 --> 02:01:29,840 This is not nearly as cool or pretty as the old school game, 2578 02:01:29,840 --> 02:01:34,280 but if I run make mario and then do dot slash mario, voila. 2579 02:01:34,280 --> 02:01:41,030 I get a very poor approximation of these four blocks in the sky 2580 02:01:41,030 --> 02:01:43,905 using just Ascii, or really called Ascii art. 2581 02:01:43,905 --> 02:01:45,530 But I can do a little better than that. 2582 02:01:45,530 --> 02:01:47,810 Recall that now we have the ability to use loops. 2583 02:01:47,810 --> 02:01:50,180 So I could say for int i gets zero. 2584 02:01:50,180 --> 02:01:53,030 i is less than four, i plus plus. 2585 02:01:53,030 --> 02:01:57,380 And then I could just print out one question mark at a time. 2586 02:01:57,380 --> 02:01:59,470 And then at the very end of my program, I 2587 02:01:59,470 --> 02:02:02,927 could print out a new line just to move the cursor at the very last moment. 2588 02:02:02,927 --> 02:02:04,760 I don't want to do that every question mark, 2589 02:02:04,760 --> 02:02:06,177 because then it would be vertical. 2590 02:02:06,177 --> 02:02:07,680 I want to do it only at the end. 2591 02:02:07,680 --> 02:02:11,000 So now if I make mario, and I run mario now. 2592 02:02:11,000 --> 02:02:13,850 Same exact result, but a little better in the sense 2593 02:02:13,850 --> 02:02:22,550 that now it's using a loop instead of a hard coded value. 2594 02:02:22,550 --> 02:02:26,240 But let me be a little more clever now, and let me do this instead. 2595 02:02:26,240 --> 02:02:29,205 Let me borrow the logic of that positive integer example 2596 02:02:29,205 --> 02:02:30,330 and do something like this. 2597 02:02:30,330 --> 02:02:32,930 Let me give myself a variable called, n, for a number. 2598 02:02:32,930 --> 02:02:35,240 And let me do the following just like before. 2599 02:02:35,240 --> 02:02:37,910 Let me get an integer from the user, and ask the user 2600 02:02:37,910 --> 02:02:41,970 for the width of the bricks that I want to print. 2601 02:02:41,970 --> 02:02:43,250 So it's not always four. 2602 02:02:43,250 --> 02:02:44,780 Maybe it's a variable number. 2603 02:02:44,780 --> 02:02:48,320 And then let me go ahead and do this while n is less than one. 2604 02:02:48,320 --> 02:02:51,330 So identical to my logic before. 2605 02:02:51,330 --> 02:02:52,310 And then you know what? 2606 02:02:52,310 --> 02:02:54,590 Once I have a value of n-- 2607 02:02:54,590 --> 02:02:57,410 so let me go ahead up here and give myself a comment. 2608 02:02:57,410 --> 02:03:00,050 Get positive integer from user. 2609 02:03:00,050 --> 02:03:02,390 That rather says what all of these lines of code do. 2610 02:03:02,390 --> 02:03:04,460 I don't need to comment every single line. 2611 02:03:04,460 --> 02:03:07,700 You can comment every few if it makes logical sense to do so. 2612 02:03:07,700 --> 02:03:12,440 Let me go ahead now and print out that many question marks. 2613 02:03:12,440 --> 02:03:13,520 So I can do a loop. 2614 02:03:13,520 --> 02:03:18,740 For int i gets zero, i is less than n this time, i plus plus. 2615 02:03:18,740 --> 02:03:22,520 And now I can print out a single question mark without a new line. 2616 02:03:22,520 --> 02:03:24,580 And then at the very end of my program, I 2617 02:03:24,580 --> 02:03:28,040 can print out a single new line semicolon. 2618 02:03:28,040 --> 02:03:31,590 Let me go ahead now and increase the size of my terminal window. 2619 02:03:31,590 --> 02:03:33,550 Let me do make mario. 2620 02:03:33,550 --> 02:03:35,470 And now-- oh, darn it. 2621 02:03:35,470 --> 02:03:38,140 Implicit declaration of function get_int. 2622 02:03:38,140 --> 02:03:40,360 Here's where help50 might be my friend. 2623 02:03:40,360 --> 02:03:43,540 So let me go ahead and run help50 make mario. 2624 02:03:43,540 --> 02:03:45,490 It's going to ask for help. 2625 02:03:45,490 --> 02:03:48,190 You seem to have an error in mario.c on line nine. 2626 02:03:48,190 --> 02:03:50,303 By implicit declaration of function get_int, 2627 02:03:50,303 --> 02:03:53,470 clang means-- which is the name of the compiler, which we'll see next week-- 2628 02:03:53,470 --> 02:03:55,390 means that it doesn't recognize get_int. 2629 02:03:55,390 --> 02:03:58,540 Did you forget to include cs50.h in which get_int 2630 02:03:58,540 --> 02:03:59,920 declared at top of your file. 2631 02:03:59,920 --> 02:04:00,890 And indeed, I did. 2632 02:04:00,890 --> 02:04:02,300 So let me fix this. 2633 02:04:02,300 --> 02:04:06,070 So include cs50.h. 2634 02:04:06,070 --> 02:04:07,570 Save the file. 2635 02:04:07,570 --> 02:04:09,730 Recompile with make mario. 2636 02:04:09,730 --> 02:04:13,750 And now let me go ahead and do dot slash mario, 2637 02:04:13,750 --> 02:04:15,370 and I'll give myself a width of four. 2638 02:04:15,370 --> 02:04:16,150 It's the same. 2639 02:04:16,150 --> 02:04:17,920 Let me give myself a width of 40. 2640 02:04:17,920 --> 02:04:19,300 Now I get that dynamism. 2641 02:04:19,300 --> 02:04:22,010 Let me give myself a width of 50, and so forth. 2642 02:04:22,010 --> 02:04:25,360 So now we have a program that's much more dynamic, but you know what? 2643 02:04:25,360 --> 02:04:27,940 Let's go ahead and enhance this a little further. 2644 02:04:27,940 --> 02:04:31,060 Later on in Super Mario Brothers, there's like a lot of this underworld 2645 02:04:31,060 --> 02:04:32,830 here where you see these grids of bricks, 2646 02:04:32,830 --> 02:04:34,413 and let me draw our attention to this. 2647 02:04:34,413 --> 02:04:38,050 This looks like multiple bricks both horizontally and vertically. 2648 02:04:38,050 --> 02:04:40,130 So there's a width and a height. 2649 02:04:40,130 --> 02:04:43,750 So how can I go about printing out, maybe that's three by three. 2650 02:04:43,750 --> 02:04:46,600 Three bricks across by three bricks down. 2651 02:04:46,600 --> 02:04:49,450 Let me actually go into my program here. 2652 02:04:49,450 --> 02:04:52,390 Get rid of all the question mark stuff from before. 2653 02:04:52,390 --> 02:04:56,110 And consider how I could print out a three by three grid. 2654 02:04:56,110 --> 02:05:00,160 Well, the bad approach here, if I go back into my code, 2655 02:05:00,160 --> 02:05:02,620 would be to print out three of these. 2656 02:05:02,620 --> 02:05:04,990 And then maybe three more. 2657 02:05:04,990 --> 02:05:07,720 Maybe three more, and then three more. 2658 02:05:07,720 --> 02:05:10,383 But of course, this copy paste is not going to fly long term, 2659 02:05:10,383 --> 02:05:11,050 but that's fine. 2660 02:05:11,050 --> 02:05:12,730 Let me do make mario. 2661 02:05:12,730 --> 02:05:14,330 Dot slash mario. 2662 02:05:14,330 --> 02:05:14,830 All right. 2663 02:05:14,830 --> 02:05:17,800 I kind of sort of have a grid that looks like this thing here. 2664 02:05:17,800 --> 02:05:20,470 It's not exactly, but at least it's the right idea. 2665 02:05:20,470 --> 02:05:23,170 But this is not necessarily the best way to do this. 2666 02:05:23,170 --> 02:05:26,590 I really want to go three across and three down. 2667 02:05:26,590 --> 02:05:31,850 Well, it turns out using C we can actually express that as well. 2668 02:05:31,850 --> 02:05:33,430 Let me go ahead and do this. 2669 02:05:33,430 --> 02:05:38,050 Let me go ahead and print out for instance, the following. 2670 02:05:38,050 --> 02:05:41,380 Let me go ahead and print out not just hash, hash, hash, again 2671 02:05:41,380 --> 02:05:42,530 and again and again. 2672 02:05:42,530 --> 02:05:43,810 Let me go ahead and do this. 2673 02:05:43,810 --> 02:05:46,160 Let me print out one row at a time. 2674 02:05:46,160 --> 02:05:49,838 So for int i gets zero, i less than three, plus plus. 2675 02:05:49,838 --> 02:05:51,880 I don't know what I'm about to do yet, but I know 2676 02:05:51,880 --> 02:05:53,470 that I'm going to do it three times. 2677 02:05:53,470 --> 02:05:54,845 What do I want to do three times? 2678 02:05:54,845 --> 02:05:58,480 Well, I want three rows, and on every row I want three hashes. 2679 02:05:58,480 --> 02:05:59,830 So you know what you can do? 2680 02:05:59,830 --> 02:06:01,210 You can nest loops. 2681 02:06:01,210 --> 02:06:06,662 Let me do for int j gets zero, j is less than three, and j plus plus. 2682 02:06:06,662 --> 02:06:08,620 I don't know what I'm going to do yet, but I do 2683 02:06:08,620 --> 02:06:10,630 know I'm going to do this three times. 2684 02:06:10,630 --> 02:06:12,490 And you can perhaps see where this is going. 2685 02:06:12,490 --> 02:06:15,850 Three things three times, that's going to give me all nine bricks. 2686 02:06:15,850 --> 02:06:21,040 So long as inside of this inner loop, so to speak, this nested loop, 2687 02:06:21,040 --> 02:06:22,840 I print one of those hashes. 2688 02:06:22,840 --> 02:06:27,770 So long as after that loop, I print out a new line over here. 2689 02:06:27,770 --> 02:06:30,700 So to be clear, even if it's not obvious at first glance what's 2690 02:06:30,700 --> 02:06:35,380 going on, we already know that this is the type of syntax you use for doing 2691 02:06:35,380 --> 02:06:37,750 something finitely many times, three. 2692 02:06:37,750 --> 02:06:40,520 This is the same syntax, but I'm using a different variable name. 2693 02:06:40,520 --> 02:06:42,460 So I can keep track of two different values. 2694 02:06:42,460 --> 02:06:45,543 Essentially, rows and columns. 2695 02:06:45,543 --> 02:06:47,710 And then I'm just printing a single brick each time. 2696 02:06:47,710 --> 02:06:50,080 But after I'm done printing a whole row, I 2697 02:06:50,080 --> 02:06:53,170 do want to move the cursor to a new line. 2698 02:06:53,170 --> 02:06:54,230 So let me try this. 2699 02:06:54,230 --> 02:06:56,950 Let me go ahead and do make mario on my code. 2700 02:06:56,950 --> 02:06:59,680 Dot slash mario, and voila. 2701 02:06:59,680 --> 02:07:02,453 Now I'm using a nested loop to print out bricks like this. 2702 02:07:02,453 --> 02:07:03,370 And I can change this. 2703 02:07:03,370 --> 02:07:06,970 If I want to do a 10 by 10, all I have to do is change that in one place. 2704 02:07:06,970 --> 02:07:10,390 Or if I really wanted to be fancy, I could go use get_int again. 2705 02:07:10,390 --> 02:07:12,550 I could get the width and the height from the user 2706 02:07:12,550 --> 02:07:14,110 and do it completely dynamically. 2707 02:07:14,110 --> 02:07:18,692 But now if I do 10 by 10 for instance, I can at least see an even bigger grid. 2708 02:07:18,692 --> 02:07:21,400 So if you wonder how things like Super Mario Brothers, or frankly 2709 02:07:21,400 --> 02:07:25,450 any game nowadays on a PC or console or phone are made, 2710 02:07:25,450 --> 02:07:27,400 it's with this kind of generation of maps. 2711 02:07:27,400 --> 02:07:30,580 Maybe back in the day they were hard coded, maybe they were generated. 2712 02:07:30,580 --> 02:07:34,690 Using code you can absolutely imagine generating brick after brick 2713 02:07:34,690 --> 02:07:39,070 after brick like that so that, ultimately, your game even, your world, 2714 02:07:39,070 --> 02:07:41,110 is partly dynamically generated. 2715 02:07:41,110 --> 02:07:44,770 And we already have the building blocks via which to do that. 2716 02:07:44,770 --> 02:07:51,340 Unfortunately, we haven't really spoken to the limitations 2717 02:07:51,340 --> 02:07:52,832 of what computers can do. 2718 02:07:52,832 --> 02:07:55,540 And in our final minutes we thought we'd set the stage for things 2719 02:07:55,540 --> 02:07:57,340 that computers aren't very good at. 2720 02:07:57,340 --> 02:08:01,270 And in fact, problems that are latent in pretty much everything 2721 02:08:01,270 --> 02:08:04,630 we've done today, but I've been very carefully avoiding tripping over. 2722 02:08:04,630 --> 02:08:07,930 This picture here is a picture of a typical computer's memory, 2723 02:08:07,930 --> 02:08:09,477 or RAM, random access memory. 2724 02:08:09,477 --> 02:08:11,560 It's just one of the pieces of hardware that you'd 2725 02:08:11,560 --> 02:08:14,410 have in your phone, your desktop, your laptop these days. 2726 02:08:14,410 --> 02:08:17,180 And it's where programs are stored when they're running. 2727 02:08:17,180 --> 02:08:19,630 So in a Mac or PC, if you double click a program 2728 02:08:19,630 --> 02:08:22,570 it's ultimately stored in a piece of hardware that looks like this. 2729 02:08:22,570 --> 02:08:25,930 When you dot slash mario and hit Enter in a program like this, 2730 02:08:25,930 --> 02:08:29,830 you're using CS50 IDE's RAM, but same idea, albeit, 2731 02:08:29,830 --> 02:08:31,750 somewhere else in the cloud. 2732 02:08:31,750 --> 02:08:36,110 So it turns out, though, that if you only have a finite amount of memory, 2733 02:08:36,110 --> 02:08:39,200 like this, you can only do so much with it. 2734 02:08:39,200 --> 02:08:41,590 You can't solve all of the world's problems 2735 02:08:41,590 --> 02:08:43,900 if you only have a finite amount of memory. 2736 02:08:43,900 --> 02:08:45,770 And what do I mean by that? 2737 02:08:45,770 --> 02:08:51,130 Well, let me go ahead and create another program here called imprecision.c, 2738 02:08:51,130 --> 02:08:53,470 and we'll see why I've named it that in just a moment. 2739 02:08:53,470 --> 02:08:57,220 Let me go ahead and include stdio.h, again, and int main void just 2740 02:08:57,220 --> 02:08:58,990 to give myself some set up here. 2741 02:08:58,990 --> 02:09:01,090 And then let me go ahead and very reasonably very 2742 02:09:01,090 --> 02:09:05,290 simply ask the user for a variable called x as a type float. 2743 02:09:05,290 --> 02:09:07,630 Let me ask for the value just like before. 2744 02:09:07,630 --> 02:09:11,557 Let me ask for another one in the form of y, quote unquote "y." 2745 02:09:11,557 --> 02:09:13,390 And then let me go ahead, and you know what? 2746 02:09:13,390 --> 02:09:19,085 Let me go ahead and print out with percent f the value of x divided by y. 2747 02:09:19,085 --> 02:09:20,710 So I'm pretty sure we did this earlier. 2748 02:09:20,710 --> 02:09:22,690 We did division with values. 2749 02:09:22,690 --> 02:09:25,690 This time I'm using floats, but let's go ahead and just run this. 2750 02:09:25,690 --> 02:09:28,960 Make imprecision-- and I goofed here. 2751 02:09:28,960 --> 02:09:32,710 Implicit-- I keep doing it-- implicit declaration of function get_float. 2752 02:09:32,710 --> 02:09:34,750 I didn't practice what I've been preaching. 2753 02:09:34,750 --> 02:09:39,700 I also need to include cs50.h, which is where it get_float is defined. 2754 02:09:39,700 --> 02:09:40,900 Now, let me recompile. 2755 02:09:40,900 --> 02:09:41,890 Now it works. 2756 02:09:41,890 --> 02:09:43,900 Now, let me go ahead and run imprecision. 2757 02:09:43,900 --> 02:09:47,320 And let me go ahead and type in one tenth. 2758 02:09:47,320 --> 02:09:47,980 OK. 2759 02:09:47,980 --> 02:09:51,550 So one tenth it turns out, according to my very simple calculator here, 2760 02:09:51,550 --> 02:09:54,928 is 0.100000. 2761 02:09:54,928 --> 02:09:56,470 But I'm getting a little curious now. 2762 02:09:56,470 --> 02:09:59,920 It turns out that printf is even more powerful than we've seen, 2763 02:09:59,920 --> 02:10:02,650 and you can actually print out more than just single digits. 2764 02:10:02,650 --> 02:10:08,080 Suppose I want to print out not six significant digits, but maybe 10. 2765 02:10:08,080 --> 02:10:11,350 It's a little funky the syntax, but instead of saying percent f, 2766 02:10:11,350 --> 02:10:15,550 you can instead say literally, percent dot the number of digits 2767 02:10:15,550 --> 02:10:17,830 you want to see and then the f. 2768 02:10:17,830 --> 02:10:21,670 So let me go ahead and recompile this, make imprecision. 2769 02:10:21,670 --> 02:10:25,225 Now let me do dot slash imprecision and one tenth-- 2770 02:10:25,225 --> 02:10:26,980 uh-huh. 2771 02:10:26,980 --> 02:10:28,870 Well, that's a little curious. 2772 02:10:28,870 --> 02:10:32,920 I don't recall knowing that there's a 15 at the end of one tenth. 2773 02:10:32,920 --> 02:10:34,630 Well, let's get a little more curious. 2774 02:10:34,630 --> 02:10:38,570 Let's print out 50 decimal points to really dig into what's going on here. 2775 02:10:38,570 --> 02:10:40,310 Let me recompile my code. 2776 02:10:40,310 --> 02:10:44,350 And let me rerun dot slash imprecision and do one divided by ten, 2777 02:10:44,350 --> 02:10:45,610 and oh my God. 2778 02:10:45,610 --> 02:10:49,150 I am quite sure in grade school when we all learned one divided by ten, 2779 02:10:49,150 --> 02:10:52,120 the teacher did tell us one tenth or 0.1. 2780 02:10:52,120 --> 02:11:00,050 And they never mentioned the fact that it's 0.10000000149011, and so forth. 2781 02:11:00,050 --> 02:11:01,300 So what is going on? 2782 02:11:01,300 --> 02:11:03,940 Well, it turns out as powerful as computers 2783 02:11:03,940 --> 02:11:08,320 are and is as sophisticated as all of the syntax we've been looking at today 2784 02:11:08,320 --> 02:11:13,220 is, my God, a computer can't even calculate one tenth correctly. 2785 02:11:13,220 --> 02:11:15,950 And so we're bumping up against a fundamental limitation here, 2786 02:11:15,950 --> 02:11:18,940 which is that if computers are finite in their capacity. 2787 02:11:18,940 --> 02:11:23,320 They only have so much RAM, so much hardware, so many bits. 2788 02:11:23,320 --> 02:11:27,250 Well, it stands to reason that if you only are using a finite number of bits, 2789 02:11:27,250 --> 02:11:29,710 32 for instance, or 64. 2790 02:11:29,710 --> 02:11:33,520 Yes, you can count pretty high or pretty precisely. 2791 02:11:33,520 --> 02:11:37,810 You cannot count infinitely high or infinitely precisely. 2792 02:11:37,810 --> 02:11:40,903 At some point you have to start to approximate values. 2793 02:11:40,903 --> 02:11:42,820 And indeed, that's what the computer is doing. 2794 02:11:42,820 --> 02:11:47,770 If it only has a finite number of bits, 32, via which to represent a float. 2795 02:11:47,770 --> 02:11:52,215 There's an infinite number of floating point real numbers in the world. 2796 02:11:52,215 --> 02:11:54,340 Unfortunately, if you have a finite number of bits, 2797 02:11:54,340 --> 02:11:55,900 you've got to start cutting some corners. 2798 02:11:55,900 --> 02:11:57,483 And that's what the computer is doing. 2799 02:11:57,483 --> 02:12:01,030 It's representing one tenth as closely as it can, 2800 02:12:01,030 --> 02:12:04,210 and this is what you then see when you look enough significant digits out. 2801 02:12:04,210 --> 02:12:07,820 Now, for most problems that's probably not a big deal. 2802 02:12:07,820 --> 02:12:10,450 But it could very well be a big deal if you're doing math, 2803 02:12:10,450 --> 02:12:14,650 you're dealing with finance or monetary values or military operations 2804 02:12:14,650 --> 02:12:18,430 where a lot of small numbers, scientifically, really start to add up. 2805 02:12:18,430 --> 02:12:20,950 And indeed, there have been many examples in the real world 2806 02:12:20,950 --> 02:12:24,970 where bad things happen because of this so-called imprecision. 2807 02:12:24,970 --> 02:12:27,430 And there's another issue that computers run into. 2808 02:12:27,430 --> 02:12:30,940 Not only this floating point imprecision, even integers 2809 02:12:30,940 --> 02:12:32,530 have their limitations. 2810 02:12:32,530 --> 02:12:36,820 Recall that integers, of course, can be represented in decimal or in binary. 2811 02:12:36,820 --> 02:12:38,830 And if we have three light bulbs or three bits, 2812 02:12:38,830 --> 02:12:41,260 let's consider how we might count in binary. 2813 02:12:41,260 --> 02:12:43,630 Zero, zero, zero is where we began last week. 2814 02:12:43,630 --> 02:12:50,060 001, 010, 011, 100, 101, 110, 111. 2815 02:12:50,060 --> 02:12:54,860 And now, this recall from last week is the number we know is seven in decimal. 2816 02:12:54,860 --> 02:12:57,410 How do I count one digit higher? 2817 02:12:57,410 --> 02:12:59,780 Well, I just carry the one, so to speak. 2818 02:12:59,780 --> 02:13:04,430 But if I only have three light bulbs or in turn three bits, or heck, 32 bits. 2819 02:13:04,430 --> 02:13:08,390 That additional bit, the carry, disappears. 2820 02:13:08,390 --> 02:13:10,820 And so there's this problem with integers too. 2821 02:13:10,820 --> 02:13:15,980 And someone noted earlier when you tried to do 2 billion plus 2 billion, 2822 02:13:15,980 --> 02:13:19,040 it couldn't fit in the result. That's because integers 2823 02:13:19,040 --> 02:13:24,410 too if they're only 32 bits or a long in C. If it's only 64 bits, those are big 2824 02:13:24,410 --> 02:13:26,990 numbers, but they're not infinitely large. 2825 02:13:26,990 --> 02:13:29,800 And we humans have tripped over this again and again. 2826 02:13:29,800 --> 02:13:33,890 You might recall hearing about if not living through the Y2K problem. 2827 02:13:33,890 --> 02:13:36,710 Where a lot of stuff in the world broke or was 2828 02:13:36,710 --> 02:13:40,520 worried to be broken on January 1st, 2000, because humans 2829 02:13:40,520 --> 02:13:43,790 had made the reasonable but not very long sighted 2830 02:13:43,790 --> 02:13:46,700 decision to store years using just two digits. 2831 02:13:46,700 --> 02:13:52,460 So 1995 would be represented as 95, 96, 97, 98, 99. 2832 02:13:52,460 --> 02:13:56,310 Then around the change of the year from 1999 to 2000, 2833 02:13:56,310 --> 02:14:00,170 any computer program or system that was still using two digits 2834 02:14:00,170 --> 02:14:02,810 would, of course, add one at the stroke of midnight. 2835 02:14:02,810 --> 02:14:07,370 Unfortunately, if there's no third digit available it disappears. 2836 02:14:07,370 --> 02:14:12,560 And the entire world confuses the year 2000 for the year 1900, 2837 02:14:12,560 --> 02:14:16,820 because 1900 was assumed as being the prefix. 2838 02:14:16,820 --> 02:14:20,900 And if you can believe it, we humans are about to do this again 2839 02:14:20,900 --> 02:14:25,350 in the year 2038, which is not that far off from now. 2840 02:14:25,350 --> 02:14:30,950 We are going to run out of bits via which to keep track of time. 2841 02:14:30,950 --> 02:14:34,220 Because years ago, humans decided reasonably at the time, 2842 02:14:34,220 --> 02:14:37,440 they are going to use 32 bits to represent numbers. 2843 02:14:37,440 --> 02:14:42,110 And we are going to use 32 bits to count up the number of seconds 2844 02:14:42,110 --> 02:14:46,520 from the year a date, January 1st, 1970. 2845 02:14:46,520 --> 02:14:49,500 So that's when time began computing wise, in some sense, 2846 02:14:49,500 --> 02:14:51,530 and we've been counting the seconds ever since. 2847 02:14:51,530 --> 02:14:55,490 Unfortunately, with 32 bits you can only count as high as 4 billion 2848 02:14:55,490 --> 02:14:56,420 give or take. 2849 02:14:56,420 --> 02:15:02,210 And unfortunately, we are going to hit the four billionth second on January 19 2850 02:15:02,210 --> 02:15:03,800 in the year 2038. 2851 02:15:03,800 --> 02:15:07,010 So unless all of us upgrade our Macs and PCS, and worse, 2852 02:15:07,010 --> 02:15:12,320 embedded systems and satellites and any hardware baked into various devices 2853 02:15:12,320 --> 02:15:14,660 that we now use, we're about to run into this problem 2854 02:15:14,660 --> 02:15:19,220 again where all of a sudden and it's going to be like January 1st, 1970 2855 02:15:19,220 --> 02:15:19,910 again. 2856 02:15:19,910 --> 02:15:22,050 Unless we stay ahead of this problem. 2857 02:15:22,050 --> 02:15:25,333 So with all the power we've seen in C and all of the capabilities 2858 02:15:25,333 --> 02:15:27,500 that we've seen in C and in Scratch, there are still 2859 02:15:27,500 --> 02:15:28,800 these fundamental limitations. 2860 02:15:28,800 --> 02:15:32,575 So when it comes to solving your own problems in C and in turn CS50, 2861 02:15:32,575 --> 02:15:35,450 it's going to be ever so important to be mindful of these constraints 2862 02:15:35,450 --> 02:15:38,600 and to, ultimately, find solutions even to these problems. 2863 02:15:38,600 --> 02:15:41,330 But for now, we'll adjourn here, and leave you 2864 02:15:41,330 --> 02:15:44,870 for your first problem set in C on Mario and more. 2865 02:15:44,870 --> 02:15:47,300 We'll see you next time. 2866 02:15:47,300 --> 02:15:50,650 [MUSIC PLAYING] 2867 02:15:50,650 --> 02:16:47,000