All language subtitles for Course _ edX(1)

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

Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.