All language subtitles for 2024_fall_lecture1-720p-en

af Afrikaans
ak Akan
sq Albanian
am Amharic
ar Arabic
hy Armenian
az Azerbaijani
eu Basque
be Belarusian
bem Bemba
bn Bengali
bh Bihari
bs Bosnian
br Breton
bg Bulgarian
km Cambodian
ca Catalan
ceb Cebuano
chr Cherokee
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
ee Ewe
fo Faroese
tl Filipino
fi Finnish
fr French
fy Frisian
gaa Ga
gl Galician
ka Georgian
de German
el Greek
gn Guarani
gu Gujarati
ht Haitian Creole
ha Hausa
haw Hawaiian
iw Hebrew
hi Hindi
hmn Hmong
hu Hungarian
is Icelandic
ig Igbo
id Indonesian
ia Interlingua
ga Irish
it Italian
ja Japanese
jw Javanese
kn Kannada
kk Kazakh
rw Kinyarwanda
rn Kirundi
kg Kongo
ko Korean
kri Krio (Sierra Leone)
ku Kurdish
ckb Kurdish (SoranĂ®)
ky Kyrgyz
lo Laothian
la Latin
lv Latvian
ln Lingala
lt Lithuanian
loz Lozi
lg Luganda
ach Luo
lb Luxembourgish
mk Macedonian
mg Malagasy
ms Malay
ml Malayalam
mt Maltese
mi Maori
mr Marathi
mfe Mauritian Creole
mo Moldavian
mn Mongolian
my Myanmar (Burmese)
sr-ME Montenegrin
ne Nepali
pcm Nigerian Pidgin
nso Northern Sotho
no Norwegian
nn Norwegian (Nynorsk)
oc Occitan
or Oriya
om Oromo
ps Pashto
fa Persian
pl Polish
pt-BR Portuguese (Brazil)
pt Portuguese (Portugal)
pa Punjabi
qu Quechua
ro Romanian
rm Romansh
nyn Runyakitara
ru Russian
sm Samoan
gd Scots Gaelic
sr Serbian
sh Serbo-Croatian
st Sesotho
tn Setswana
crs Seychellois Creole
sn Shona
sd Sindhi
si Sinhalese
sk Slovak
sl Slovenian
so Somali
es Spanish
es-419 Spanish (Latin American)
su Sundanese
sw Swahili
sv Swedish
tg Tajik
ta Tamil
tt Tatar
te Telugu
th Thai
ti Tigrinya
to Tonga
lua Tshiluba
tum Tumbuka
tr Turkish
tk Turkmen
tw Twi
ug Uighur
uk Ukrainian
ur Urdu
uz Uzbek
vi Vietnamese
cy Welsh
wo Wolof
xh Xhosa
yi Yiddish
yo Yoruba
zu Zulu
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,490 [MUSIC PLAYING] 1 00:00:02,490 --> 00:01:15,240 2 00:01:15,240 --> 00:01:17,140 DAVID J. MALAN: All right. 3 00:01:17,140 --> 00:01:19,520 This is CS50. 4 00:01:19,520 --> 00:01:22,172 This is week one, because of course, last week was week zero. 5 00:01:22,172 --> 00:01:24,630 And this is the week where we'll actually start programming 6 00:01:24,630 --> 00:01:27,960 in a much more traditional way, that programming language we promised 7 00:01:27,960 --> 00:01:28,997 called C. 8 00:01:28,997 --> 00:01:30,330 Of course, we started with this. 9 00:01:30,330 --> 00:01:32,550 And hopefully by now, with problem set 1, you've had a little bit of fun, 10 00:01:32,550 --> 00:01:34,092 even if you've played with it before. 11 00:01:34,092 --> 00:01:36,360 And the goals of Scratch, beyond making things 12 00:01:36,360 --> 00:01:39,210 feel very accessible and user friendly is really 13 00:01:39,210 --> 00:01:41,850 to elucidate some of the fundamental concepts 14 00:01:41,850 --> 00:01:45,330 that we'll see again today, and really every week subsequently, like 15 00:01:45,330 --> 00:01:49,870 functions and conditionals and loops and variables and so much more. 16 00:01:49,870 --> 00:01:52,600 And in fact, among the goals of Scratch is, again, 17 00:01:52,600 --> 00:01:54,460 to plant these visuals in your mind. 18 00:01:54,460 --> 00:01:57,580 So even as today onward feels all the more like a fire hose, 19 00:01:57,580 --> 00:02:01,270 especially when it comes to really weird, cryptic textual syntax, 20 00:02:01,270 --> 00:02:04,000 the ideas are still going to be the same. 21 00:02:04,000 --> 00:02:07,960 So today, this program, Hello, world, becomes this instead. 22 00:02:07,960 --> 00:02:10,740 And in fact, just to color code things temporarily, I 23 00:02:10,740 --> 00:02:14,130 dare say that what I've color coded here in orange, which looks probably, 24 00:02:14,130 --> 00:02:16,960 to those of you who've never programmed, pretty cryptic 25 00:02:16,960 --> 00:02:22,940 is the equivalent of when green flag clicked orange puzzle piece like this. 26 00:02:22,940 --> 00:02:26,120 What remains is just one line in purple with a bit of white, 27 00:02:26,120 --> 00:02:28,510 which is what ultimately is going to get the screen today 28 00:02:28,510 --> 00:02:30,350 to say, Hello, world on the screen. 29 00:02:30,350 --> 00:02:33,230 And of course, we had a name for something in purple. 30 00:02:33,230 --> 00:02:36,280 In fact, if we rewind to week zero, this block in purple 31 00:02:36,280 --> 00:02:40,090 represented what type of functionality? 32 00:02:40,090 --> 00:02:41,665 AUDIENCE: [INAUDIBLE]. 33 00:02:41,665 --> 00:02:43,540 DAVID J. MALAN: A function itself, an action, 34 00:02:43,540 --> 00:02:45,507 a verb that gets the computer to do something. 35 00:02:45,507 --> 00:02:48,090 So what looked like this last week is about to look like this. 36 00:02:48,090 --> 00:02:50,340 Let's take away the color coding and focus really 37 00:02:50,340 --> 00:02:52,870 on what we're going to now start calling source code. 38 00:02:52,870 --> 00:02:55,720 So this is what programmers do in the real world. 39 00:02:55,720 --> 00:02:58,870 This is what software developers, software engineers do in the real world. 40 00:02:58,870 --> 00:03:01,180 They write code that looks like this. 41 00:03:01,180 --> 00:03:03,533 And clearly, it's a little English-like, but it's not 42 00:03:03,533 --> 00:03:05,950 English in the way you would compose an essay or an email. 43 00:03:05,950 --> 00:03:08,670 Clearly, there's some patterns and some special syntax to it 44 00:03:08,670 --> 00:03:10,750 that will highlight ultimately today. 45 00:03:10,750 --> 00:03:14,740 The problem is, though, that computers, of course, don't understand source code. 46 00:03:14,740 --> 00:03:17,680 They only, per last week, understand zeros and ones. 47 00:03:17,680 --> 00:03:20,500 That is it, the so-called binary system. 48 00:03:20,500 --> 00:03:23,730 So somehow, we've got to get what already looks cryptic into something 49 00:03:23,730 --> 00:03:26,400 that looks at a glance even more cryptic, the zeros and ones 50 00:03:26,400 --> 00:03:27,850 that computers do understand. 51 00:03:27,850 --> 00:03:32,260 And for today's purposes, just know that built into your Macs, PCs and phones, 52 00:03:32,260 --> 00:03:36,340 there is a built in understanding of what these patterns mean. 53 00:03:36,340 --> 00:03:39,220 Maybe it means a number, maybe it means a letter. 54 00:03:39,220 --> 00:03:41,600 But today, maybe it means an instruction, 55 00:03:41,600 --> 00:03:45,770 like print something on the screen, or save something, or load something. 56 00:03:45,770 --> 00:03:48,175 That is to say, computers use patterns of bits 57 00:03:48,175 --> 00:03:50,800 not only to represent all the stuff we talked about last week-- 58 00:03:50,800 --> 00:03:54,020 numbers, letters, colors, images, sounds, and all of that, 59 00:03:54,020 --> 00:03:58,130 they also use patterns of bits to represent fundamental functionality. 60 00:03:58,130 --> 00:04:01,910 Print things, play things, much like those same scratch blocks. 61 00:04:01,910 --> 00:04:05,320 But no computer scientist really, unless they take out a paper pencil 62 00:04:05,320 --> 00:04:07,690 or write a program or use a website to convert this 63 00:04:07,690 --> 00:04:09,830 can read this and know what's going on. 64 00:04:09,830 --> 00:04:13,210 That's why we humans are actually going to use not machine code, as it 65 00:04:13,210 --> 00:04:16,110 is called, the zeros and ones that computers understand, 66 00:04:16,110 --> 00:04:17,860 we are going to start writing source code. 67 00:04:17,860 --> 00:04:20,440 And last week you already wrote source code, but in the form 68 00:04:20,440 --> 00:04:22,417 of dragging and dropping those puzzle pieces. 69 00:04:22,417 --> 00:04:25,000 So this too is going to be the paradigm that sort of guides us 70 00:04:25,000 --> 00:04:26,420 through the entire semester. 71 00:04:26,420 --> 00:04:30,500 Problem solving programming is really about input becoming output. 72 00:04:30,500 --> 00:04:33,770 And we'll focus today then on a certain type of input becoming output. 73 00:04:33,770 --> 00:04:37,330 Someone has to get the source code, that's written in a language like C, 74 00:04:37,330 --> 00:04:39,550 into the machine code, the zeros and ones 75 00:04:39,550 --> 00:04:41,480 that the computer actually understands. 76 00:04:41,480 --> 00:04:43,750 So source code today is going to be our input. 77 00:04:43,750 --> 00:04:45,530 Machine code is going to be our output. 78 00:04:45,530 --> 00:04:48,220 And we're going to give you today a special program called 79 00:04:48,220 --> 00:04:52,852 a compiler, whose purpose in life is to translate one to the other. 80 00:04:52,852 --> 00:04:55,310 And there's compilers for different languages in the world. 81 00:04:55,310 --> 00:04:58,880 We're going to focus on one that supports today's language, known as C. 82 00:04:58,880 --> 00:05:01,570 And here, as promised, is the programming environment 83 00:05:01,570 --> 00:05:02,660 we are going to use. 84 00:05:02,660 --> 00:05:04,600 It's tailored to CS50, which is to say, we've 85 00:05:04,600 --> 00:05:08,360 pre-installed certain software that you might find useful during the term. 86 00:05:08,360 --> 00:05:12,010 But for all intents and purposes, the tool you will use for CS50 problem sets 87 00:05:12,010 --> 00:05:15,910 henceforth is a very popular industry standard tool called Visual Studio 88 00:05:15,910 --> 00:05:18,020 Code, or VS Code for short. 89 00:05:18,020 --> 00:05:19,990 We are using a cloud based version of it that 90 00:05:19,990 --> 00:05:22,580 lives at literally this URL, cs50.dev. 91 00:05:22,580 --> 00:05:26,740 You can sign in to that so long as you have a free GitHub account, for which 92 00:05:26,740 --> 00:05:28,400 you signed up presumably already. 93 00:05:28,400 --> 00:05:31,690 And that will give you access to not only an industry standard programming 94 00:05:31,690 --> 00:05:35,650 environment, but again, an environment that has some CS50 specific things 95 00:05:35,650 --> 00:05:36,530 pre-installed. 96 00:05:36,530 --> 00:05:38,780 And at the end of the semester, or even in the middle, 97 00:05:38,780 --> 00:05:42,520 if you so you're so inclined, you can actually download for free VS Code 98 00:05:42,520 --> 00:05:43,805 onto your Mac, PC. 99 00:05:43,805 --> 00:05:46,180 You can disconnect from the internet and you can actually 100 00:05:46,180 --> 00:05:48,140 program on your own computer. 101 00:05:48,140 --> 00:05:50,770 Caveat, though, is that you tend to hit technical support 102 00:05:50,770 --> 00:05:52,638 headaches in the very beginning of the term, 103 00:05:52,638 --> 00:05:54,430 so we suggest you do that later in the term 104 00:05:54,430 --> 00:05:57,730 once you're already comfortable with this cloud based environment here. 105 00:05:57,730 --> 00:05:58,870 And here it is. 106 00:05:58,870 --> 00:06:01,040 This is what programming shall look like, 107 00:06:01,040 --> 00:06:05,440 whether we're using C now or Python in a few weeks or JavaScript or SQL 108 00:06:05,440 --> 00:06:06,260 thereafter. 109 00:06:06,260 --> 00:06:10,250 So here is what looks-- what is VS Code configured as follows. 110 00:06:10,250 --> 00:06:13,430 At the top right, you'll generally have one or more tabs for code, 111 00:06:13,430 --> 00:06:14,597 much like tabs in a browser. 112 00:06:14,597 --> 00:06:17,763 And this is where you'll write code that looks a little something like this. 113 00:06:17,763 --> 00:06:20,690 And in fact, this is exactly the code that you saw a moment ago. 114 00:06:20,690 --> 00:06:23,530 What VS Code does, among other things, is it actually 115 00:06:23,530 --> 00:06:25,010 highlights your code for you. 116 00:06:25,010 --> 00:06:29,270 It colorizes it in what's generally an illuminating way. 117 00:06:29,270 --> 00:06:31,190 So I did not choose to make this red. 118 00:06:31,190 --> 00:06:33,350 I did not choose to make this blue and this purple. 119 00:06:33,350 --> 00:06:35,600 The computer sort of automatically does that for you, 120 00:06:35,600 --> 00:06:40,730 as we'll soon see to draw your attention to different ideas in the program itself 121 00:06:40,730 --> 00:06:42,490 that all happens automatically. 122 00:06:42,490 --> 00:06:45,790 At the bottom here, you're going to use a more advanced interface today 123 00:06:45,790 --> 00:06:49,540 onward, known as a command line interface in the form of a terminal 124 00:06:49,540 --> 00:06:50,060 window. 125 00:06:50,060 --> 00:06:52,300 So you can still use your mouse or trackpad 126 00:06:52,300 --> 00:06:55,280 and click and drag and do things like that in this environment. 127 00:06:55,280 --> 00:06:58,090 But you'll find, and many programmers prefer 128 00:06:58,090 --> 00:07:02,050 that it's much more efficient ultimately to use your keyboard more 129 00:07:02,050 --> 00:07:03,920 often than the mouse or the trackpad. 130 00:07:03,920 --> 00:07:07,220 So we'll introduce you to that text based terminal window there. 131 00:07:07,220 --> 00:07:09,620 Up here at top left, you'll have a File Explorer. 132 00:07:09,620 --> 00:07:12,070 So what's nice about VS Code is that not only will you 133 00:07:12,070 --> 00:07:14,300 have textual commands, with which you'll get comfy, 134 00:07:14,300 --> 00:07:17,145 you also have a normal Mac or PC or phone nowadays, 135 00:07:17,145 --> 00:07:21,670 like literally files and folders will visually appear to you 136 00:07:21,670 --> 00:07:23,632 so you can play with or manipulate them there. 137 00:07:23,632 --> 00:07:26,590 And then, lastly, this is sort of like the menu, the so-called activity 138 00:07:26,590 --> 00:07:31,280 bar that just has icons for various features, including CS50's duck. 139 00:07:31,280 --> 00:07:33,550 So in fact, if you poke around, you'll see ultimately 140 00:07:33,550 --> 00:07:37,450 a duck icon when you log in, which is your own CS50 specific chat 141 00:07:37,450 --> 00:07:41,020 bot of which you can ask questions throughout the process. 142 00:07:41,020 --> 00:07:44,050 So now that we've got VS Code here, let's go ahead 143 00:07:44,050 --> 00:07:46,880 and actually consider what it represents. 144 00:07:46,880 --> 00:07:50,420 So this is generally, for jargon sake, a graphical user interface, 145 00:07:50,420 --> 00:07:52,880 which means buttons and icons and menus and all of that. 146 00:07:52,880 --> 00:07:55,750 We all take that for granted on most any device nowadays. 147 00:07:55,750 --> 00:08:00,490 That's abbreviated, just so you know, as GUI, G-U-I. But built into VS Code, 148 00:08:00,490 --> 00:08:03,890 again, is what's not only the terminal window by name, 149 00:08:03,890 --> 00:08:06,795 but conceptually this is a command line interface. 150 00:08:06,795 --> 00:08:10,720 So not a graphical user interface, but a command line interface, 151 00:08:10,720 --> 00:08:14,120 whereby there aren't icons to click on or double click on. 152 00:08:14,120 --> 00:08:16,150 Rather, if you want to run a program, you 153 00:08:16,150 --> 00:08:20,830 use the command line interface, or CLI, to type the name of the program 154 00:08:20,830 --> 00:08:21,802 that you want to run. 155 00:08:21,802 --> 00:08:24,010 And so this will feel like a step backwards initially 156 00:08:24,010 --> 00:08:28,280 today, because we all tap and point and double click on things nowadays. 157 00:08:28,280 --> 00:08:31,210 But again, it's going to give us more power, more efficiency 158 00:08:31,210 --> 00:08:33,260 ultimately beyond this. 159 00:08:33,260 --> 00:08:37,120 So with that said, let's go ahead and actually use it for just a moment. 160 00:08:37,120 --> 00:08:39,020 During class, you're welcome to follow along. 161 00:08:39,020 --> 00:08:41,760 But suffice it to say, we'll generally go somewhat quickly. 162 00:08:41,760 --> 00:08:45,930 Really, you're going to learn how to program by way of the problem sets 163 00:08:45,930 --> 00:08:46,880 each week. 164 00:08:46,880 --> 00:08:48,960 I'll introduce and focus on the concepts, 165 00:08:48,960 --> 00:08:51,510 the ideas, the sort of primitives that will get you started, 166 00:08:51,510 --> 00:08:55,130 but only through actually doing the problem sets is the muscle memory 167 00:08:55,130 --> 00:08:56,550 and practice going to come. 168 00:08:56,550 --> 00:09:00,450 So not to worry if it doesn't all go down easily the first time around. 169 00:09:00,450 --> 00:09:03,650 So here is the code that I claim is equivalent to last week's 170 00:09:03,650 --> 00:09:04,920 Hello, world program. 171 00:09:04,920 --> 00:09:07,770 Let's actually go ahead and do this in the programming environment. 172 00:09:07,770 --> 00:09:09,895 So I'm going to go ahead and switch over to VS Code 173 00:09:09,895 --> 00:09:12,090 itself, which is now running on my Mac here. 174 00:09:12,090 --> 00:09:13,280 It's not just a screenshot. 175 00:09:13,280 --> 00:09:15,590 And I'm going to go ahead and do the following 176 00:09:15,590 --> 00:09:17,280 to get started with programming. 177 00:09:17,280 --> 00:09:20,820 I'm going to write literally in my terminal window, the word code, 178 00:09:20,820 --> 00:09:23,090 and I might have to give it focus by clicking down 179 00:09:23,090 --> 00:09:24,780 in that quadrant of the screen. 180 00:09:24,780 --> 00:09:28,260 And then I'm going to give the name of the file that I want to code. 181 00:09:28,260 --> 00:09:31,490 And in this case, I'm going to propose that we call it hello.c. 182 00:09:31,490 --> 00:09:33,600 In the world of Scratch, when you downloaded it, 183 00:09:33,600 --> 00:09:37,520 you might have noticed the files are all called like SB3 or some such file 184 00:09:37,520 --> 00:09:38,190 extension. 185 00:09:38,190 --> 00:09:40,430 When writing code in C, you literally name 186 00:09:40,430 --> 00:09:43,240 the file something dot C by convention. 187 00:09:43,240 --> 00:09:44,490 But notice some other details. 188 00:09:44,490 --> 00:09:47,730 Especially if I zoom in, everything I've typed thus far is lowercase. 189 00:09:47,730 --> 00:09:49,500 There's no spaces. 190 00:09:49,500 --> 00:09:51,150 And so this is going to be important. 191 00:09:51,150 --> 00:09:53,580 And unfortunately, computers are not forgiving. 192 00:09:53,580 --> 00:09:55,700 And odds are one of the first stupid mistakes 193 00:09:55,700 --> 00:09:58,890 you'll do is miscapitalize something, misspell something, 194 00:09:58,890 --> 00:10:00,335 add too many spaces or the like. 195 00:10:00,335 --> 00:10:01,310 Not to worry. 196 00:10:01,310 --> 00:10:04,470 In time, that kind of muscle memory will come with practice. 197 00:10:04,470 --> 00:10:05,550 So let me zoom out. 198 00:10:05,550 --> 00:10:08,450 Let me now just hit Enter and you'll see at top right 199 00:10:08,450 --> 00:10:10,320 the Code tab that I promised. 200 00:10:10,320 --> 00:10:13,070 So I'm going to go ahead and type out this program pretty quickly, 201 00:10:13,070 --> 00:10:14,370 because I've done it before. 202 00:10:14,370 --> 00:10:21,030 Include stdio.h, int main void, and then some curly braces, as they're called, 203 00:10:21,030 --> 00:10:22,710 and then printf quote unquote. 204 00:10:22,710 --> 00:10:26,260 Hello, comma, world, backslash n, close quote, semicolon. 205 00:10:26,260 --> 00:10:26,760 All right. 206 00:10:26,760 --> 00:10:27,510 So that's a lot. 207 00:10:27,510 --> 00:10:29,730 But that too will come in time with practice. 208 00:10:29,730 --> 00:10:33,150 But this is the exact same code that we saw just a moment ago. 209 00:10:33,150 --> 00:10:36,420 Indeed, if I zoom in, it's color coded just as in the screenshot, 210 00:10:36,420 --> 00:10:38,660 and thus I have written my first program. 211 00:10:38,660 --> 00:10:41,090 VS Code will automatically save for you, but you can also 212 00:10:41,090 --> 00:10:43,590 hit control or Command S to ensure that it's saved. 213 00:10:43,590 --> 00:10:45,720 But notice what's happened at top left. 214 00:10:45,720 --> 00:10:48,800 Not only do you see my code over here, you 215 00:10:48,800 --> 00:10:51,050 see a visual icon, just like on a Mac or PC 216 00:10:51,050 --> 00:10:54,290 that, yes, this file now exists in your account. 217 00:10:54,290 --> 00:10:57,330 And that too is what you're getting with VS Code for CS50. 218 00:10:57,330 --> 00:11:00,330 You're getting your own sort of server in the cloud. 219 00:11:00,330 --> 00:11:01,890 It's called a container nowadays. 220 00:11:01,890 --> 00:11:05,840 So there's some virtual disk space somewhere in the cloud, ala iCloud 221 00:11:05,840 --> 00:11:08,400 or Google Drive, that's going to store all of your files. 222 00:11:08,400 --> 00:11:11,490 And at the moment, because I refreshed my account before class, 223 00:11:11,490 --> 00:11:14,490 I only have one file in my own account. 224 00:11:14,490 --> 00:11:15,210 What's this? 225 00:11:15,210 --> 00:11:15,840 What's this? 226 00:11:15,840 --> 00:11:17,893 Well, this is like my ID number for GitHub. 227 00:11:17,893 --> 00:11:18,810 Not really a big deal. 228 00:11:18,810 --> 00:11:21,080 That's just randomly generated by GitHub. 229 00:11:21,080 --> 00:11:24,930 Urban Adventure is the name of my programming environment today, 230 00:11:24,930 --> 00:11:26,490 otherwise known as a code space. 231 00:11:26,490 --> 00:11:30,000 This is just a GitHub thing which is, again, one of these cloud companies. 232 00:11:30,000 --> 00:11:32,360 Instead of choosing random letters and numbers 233 00:11:32,360 --> 00:11:35,617 to uniquely identify all of our programming environments, 234 00:11:35,617 --> 00:11:37,700 it's popular in the tech industry nowadays to just 235 00:11:37,700 --> 00:11:41,310 put together random English words that sometimes sound kind of cool. 236 00:11:41,310 --> 00:11:43,560 But it's just by coincidence, not something I chose. 237 00:11:43,560 --> 00:11:45,920 Yours will be different. 238 00:11:45,920 --> 00:11:48,150 All right, so I've written some code. 239 00:11:48,150 --> 00:11:49,710 I created hello.c. 240 00:11:49,710 --> 00:11:51,210 I typed in all of that code. 241 00:11:51,210 --> 00:11:53,700 I confirmed visually at left that it was created. 242 00:11:53,700 --> 00:11:55,950 I'm going to hide my File Explorer henceforth, just so 243 00:11:55,950 --> 00:11:57,217 that we can focus on the code. 244 00:11:57,217 --> 00:11:58,675 How do I actually run this program? 245 00:11:58,675 --> 00:12:02,297 Well, on a Mac or a PC, we would be in the habit of like opening the folder 246 00:12:02,297 --> 00:12:03,380 and double clicking on it. 247 00:12:03,380 --> 00:12:06,060 Or on your phone, you would take it out and tap on an icon. 248 00:12:06,060 --> 00:12:06,960 But not here. 249 00:12:06,960 --> 00:12:10,610 Here, we're focusing primarily on the command line interface 250 00:12:10,610 --> 00:12:12,720 within this whole environment. 251 00:12:12,720 --> 00:12:16,260 So I'm actually going to have to introduce a few commands. 252 00:12:16,260 --> 00:12:19,400 You saw already the code command, which for our purposes 253 00:12:19,400 --> 00:12:24,600 is VS Code specific, that just creates a new file called hello.c in this case. 254 00:12:24,600 --> 00:12:27,720 But I need two other commands to actually run this program. 255 00:12:27,720 --> 00:12:29,960 The first nicely is called make, and then 256 00:12:29,960 --> 00:12:32,070 I specify what program I want to make. 257 00:12:32,070 --> 00:12:35,190 And then a little weirdly, I have to type dot slash hello. 258 00:12:35,190 --> 00:12:37,830 But just to take a step back, make hello. 259 00:12:37,830 --> 00:12:40,410 If this is about to be my second command that I type, 260 00:12:40,410 --> 00:12:43,790 what does that step represent, perhaps? 261 00:12:43,790 --> 00:12:45,872 Given what I said just a minute or so ago. 262 00:12:45,872 --> 00:12:48,955 AUDIENCE: That's going to translate your source code into ones and zeroes. 263 00:12:48,955 --> 00:12:49,955 DAVID J. MALAN: Perfect. 264 00:12:49,955 --> 00:12:52,630 So make represents the compiler, so to speak, the program that 265 00:12:52,630 --> 00:12:54,940 converts source code to machine code. 266 00:12:54,940 --> 00:12:58,210 I have to do that for now manually by running make hello. 267 00:12:58,210 --> 00:13:00,250 Now, make is kind of smart, and even though I'm 268 00:13:00,250 --> 00:13:04,280 saying make hello, not make hello.c, make it smart, and it's going to say, 269 00:13:04,280 --> 00:13:06,610 if you want to make a program called hello, I'm 270 00:13:06,610 --> 00:13:10,820 going to assume that there is somewhere in this folder a file called hello.c. 271 00:13:10,820 --> 00:13:12,530 So you should not type make hello.c. 272 00:13:12,530 --> 00:13:13,960 You just type make hello. 273 00:13:13,960 --> 00:13:18,500 And then this third command, even more cryptic, what might it do? 274 00:13:18,500 --> 00:13:21,200 If this is step three of three. 275 00:13:21,200 --> 00:13:23,250 That's going to run the machine code. 276 00:13:23,250 --> 00:13:25,890 It's going to tell the computer in this folder, 277 00:13:25,890 --> 00:13:29,030 the dot implies this current folder, and dot slash just 278 00:13:29,030 --> 00:13:30,870 means something in this current folder. 279 00:13:30,870 --> 00:13:32,730 Run the program called Hello. 280 00:13:32,730 --> 00:13:33,390 So that's it. 281 00:13:33,390 --> 00:13:35,580 Like there's three steps to writing a program in C. 282 00:13:35,580 --> 00:13:37,770 You create the file, as with the code command. 283 00:13:37,770 --> 00:13:39,030 But there are other ways to do that too. 284 00:13:39,030 --> 00:13:40,655 And you don't even have to use VS Code. 285 00:13:40,655 --> 00:13:43,410 You can use dozens of other alternative programs in the world. 286 00:13:43,410 --> 00:13:46,260 You run the compiler, which, in this case, is called make. 287 00:13:46,260 --> 00:13:48,860 Little white lie, make's not actually the compiler, but more 288 00:13:48,860 --> 00:13:49,770 on that next week. 289 00:13:49,770 --> 00:13:54,210 But make is going to trigger compilation of this code. 290 00:13:54,210 --> 00:13:58,290 And the last step three is to execute, or run the program called Hello. 291 00:13:58,290 --> 00:14:00,380 So let me go back to VS Code here. 292 00:14:00,380 --> 00:14:03,030 And you'll see that my code is still at the top. 293 00:14:03,030 --> 00:14:04,530 My terminal window is at the bottom. 294 00:14:04,530 --> 00:14:07,488 I hid my File Explorer, just because it's not that interesting anymore. 295 00:14:07,488 --> 00:14:12,560 And I'm going to do what you proposed, which was M-A-K-E space hello. 296 00:14:12,560 --> 00:14:14,090 All lowercase. 297 00:14:14,090 --> 00:14:15,420 Enter. 298 00:14:15,420 --> 00:14:18,132 And ironically, thankfully, nothing happened. 299 00:14:18,132 --> 00:14:20,340 And that's actually a good thing in this environment. 300 00:14:20,340 --> 00:14:22,990 If nothing seems to happen you probably did, good. 301 00:14:22,990 --> 00:14:25,920 If anything does seem to happen on the screen, you probably screwed up 302 00:14:25,920 --> 00:14:27,310 and you've made some mistake. 303 00:14:27,310 --> 00:14:29,590 So seeing nothing is generally a good thing. 304 00:14:29,590 --> 00:14:30,790 But what has happened? 305 00:14:30,790 --> 00:14:34,260 Well, let me actually go back and open up my File Explorer. 306 00:14:34,260 --> 00:14:38,710 And notice, there's not only hello.c, but there's a second file now. 307 00:14:38,710 --> 00:14:41,650 Hello, which is the name of the program. 308 00:14:41,650 --> 00:14:44,530 So Hello is the program I want to run. 309 00:14:44,530 --> 00:14:47,620 I'm going to go back to my terminal here and to run this program, 310 00:14:47,620 --> 00:14:51,040 I'm going to do dot slash H-E-L-L-O. I'm going to cross my fingers, 311 00:14:51,040 --> 00:14:57,150 as I'll often now do, and voila, my very first program in C. 312 00:14:57,150 --> 00:14:59,140 How else can we see this file? 313 00:14:59,140 --> 00:15:00,880 Well, down here in my terminal window. 314 00:15:00,880 --> 00:15:01,593 Let me zoom in. 315 00:15:01,593 --> 00:15:02,760 You keep seeing dollar sign. 316 00:15:02,760 --> 00:15:04,302 That has nothing to do with currency. 317 00:15:04,302 --> 00:15:07,380 It's just a weird, geeky convention that your prompt at a terminal 318 00:15:07,380 --> 00:15:10,750 window, like where you type commands, generally starts with a dollar sign. 319 00:15:10,750 --> 00:15:12,010 Sometimes it's a hash symbol. 320 00:15:12,010 --> 00:15:13,702 Sometimes it's an angled bracket. 321 00:15:13,702 --> 00:15:15,160 It depends on the system you're on. 322 00:15:15,160 --> 00:15:16,630 But dollar sign is very common. 323 00:15:16,630 --> 00:15:18,480 It just means type your commands here. 324 00:15:18,480 --> 00:15:21,910 Well, I've typed code, I've typed make, and I've typed dot slash hello. 325 00:15:21,910 --> 00:15:23,470 But I can type other things too. 326 00:15:23,470 --> 00:15:24,600 And more on these later. 327 00:15:24,600 --> 00:15:28,620 Like ls, which doesn't actually spell something, but is short for list, 328 00:15:28,620 --> 00:15:32,140 L-I-S-T. Programmers tend to just be as succinct as they can, 329 00:15:32,140 --> 00:15:33,760 so most commands are not full words. 330 00:15:33,760 --> 00:15:35,770 They're often abbreviations. 331 00:15:35,770 --> 00:15:39,340 If I hit Enter now, you'll see also two things. 332 00:15:39,340 --> 00:15:40,890 You'll see hello.c. 333 00:15:40,890 --> 00:15:44,770 And you'll see in green, just to draw attention to it, hello as well. 334 00:15:44,770 --> 00:15:48,310 The asterisk here just means in the programming environment, 335 00:15:48,310 --> 00:15:50,050 this program is executable. 336 00:15:50,050 --> 00:15:52,810 Like you can actually run this by doing dot slash hello. 337 00:15:52,810 --> 00:15:56,140 The fact that this is just white here, that just means it's some text file. 338 00:15:56,140 --> 00:15:57,860 It's in fact source code. 339 00:15:57,860 --> 00:16:01,700 So in other words, ls lists the file in my current folder. 340 00:16:01,700 --> 00:16:04,810 Or you can use your human eyes in the File Explorer at top left 341 00:16:04,810 --> 00:16:06,800 and just look at what files exist. 342 00:16:06,800 --> 00:16:07,930 These are one and the same. 343 00:16:07,930 --> 00:16:10,120 One is a GUI one, is a CLI. 344 00:16:10,120 --> 00:16:11,960 Graphical command line. 345 00:16:11,960 --> 00:16:12,620 And so forth. 346 00:16:12,620 --> 00:16:18,020 And we'll start to take these kinds of paradigms soon for granted. 347 00:16:18,020 --> 00:16:20,320 But let me pause here and see thus far, now 348 00:16:20,320 --> 00:16:23,980 that we've written our first of many C programs, any questions? 349 00:16:23,980 --> 00:16:27,263 Or confusion we can clear up? 350 00:16:27,263 --> 00:16:29,680 It's OK if you don't understand most of the lines of code. 351 00:16:29,680 --> 00:16:31,150 That's what today is about. 352 00:16:31,150 --> 00:16:31,996 Yeah. 353 00:16:31,996 --> 00:16:34,480 AUDIENCE: I don't fully understand the difference between hello and hello.c. 354 00:16:34,480 --> 00:16:37,147 DAVID J. MALAN: What's the difference between hello and hello.c? 355 00:16:37,147 --> 00:16:38,928 So hello.c is literally my source code. 356 00:16:38,928 --> 00:16:41,470 It is a file that exists somewhere in the cloud that contains 357 00:16:41,470 --> 00:16:43,185 all of the code I myself wrote. 358 00:16:43,185 --> 00:16:47,680 The hello file is the file that the compiler 359 00:16:47,680 --> 00:16:51,920 created for me by converting the source code to the machine code. 360 00:16:51,920 --> 00:16:55,400 So inside of hello, theoretically, is a whole bunch of zeros and ones. 361 00:16:55,400 --> 00:16:57,170 We can't quite see them. 362 00:16:57,170 --> 00:16:59,260 But if I do this, let me zoom out. 363 00:16:59,260 --> 00:17:00,700 Let me click on hello. 364 00:17:00,700 --> 00:17:02,750 And notice that VS Code is going to yell at me. 365 00:17:02,750 --> 00:17:06,220 This file-- the file is not displayed in the text editor because it is either 366 00:17:06,220 --> 00:17:06,880 binary-- 367 00:17:06,880 --> 00:17:09,730 that is zeros and ones-- or uses an unsupported text 368 00:17:09,730 --> 00:17:11,089 encoding, whatever that means. 369 00:17:11,089 --> 00:17:13,609 If I do open it anyway, but I don't recommend this. 370 00:17:13,609 --> 00:17:14,990 Like heed these warnings. 371 00:17:14,990 --> 00:17:19,010 You won't see zeros and ones, but you will see sort of nonsense. 372 00:17:19,010 --> 00:17:22,450 And this is because VS Code is trying to interpret those zeros 373 00:17:22,450 --> 00:17:25,970 and ones incorrectly, as ASCII text, like English text. 374 00:17:25,970 --> 00:17:26,710 But it's not. 375 00:17:26,710 --> 00:17:28,760 They're instructions for the computer. 376 00:17:28,760 --> 00:17:31,540 So as soon as you see scary red stuff like this, like undo, 377 00:17:31,540 --> 00:17:33,880 close whatever tab you open, because odds are you 378 00:17:33,880 --> 00:17:36,145 can only break the program you just created. 379 00:17:36,145 --> 00:17:37,020 It's not a huge deal. 380 00:17:37,020 --> 00:17:38,070 You can recreate it. 381 00:17:38,070 --> 00:17:41,560 But that's what's inside of those files. 382 00:17:41,560 --> 00:17:42,570 Yeah. 383 00:17:42,570 --> 00:17:46,708 AUDIENCE: What if [? you don't ?] [INAUDIBLE]? 384 00:17:46,708 --> 00:17:48,250 DAVID J. MALAN: Really good question. 385 00:17:48,250 --> 00:17:50,820 What if we don't type dot slash hello we, just type hello. 386 00:17:50,820 --> 00:17:51,490 Well, let me do this. 387 00:17:51,490 --> 00:17:53,448 Let me hide my File Explorer again because it's 388 00:17:53,448 --> 00:17:55,440 not that interesting here on out. 389 00:17:55,440 --> 00:17:58,470 I'm going to clear my terminal window by hitting Control L, 390 00:17:58,470 --> 00:17:59,980 just to be neat and tidy in class. 391 00:17:59,980 --> 00:18:02,050 Or you can literally type clear and it will clear it. 392 00:18:02,050 --> 00:18:03,842 But again, that's just to keep things tidy. 393 00:18:03,842 --> 00:18:05,530 Your TFs might do that in section 2. 394 00:18:05,530 --> 00:18:07,598 If I just type Hello, enter. 395 00:18:07,598 --> 00:18:08,890 I'm going to get this, weirdly. 396 00:18:08,890 --> 00:18:10,870 Bash, hello, command not found. 397 00:18:10,870 --> 00:18:12,302 So more on bash down the line. 398 00:18:12,302 --> 00:18:14,010 But this just means literally the command 399 00:18:14,010 --> 00:18:16,960 hello is not found because you need to tell the computer where it is. 400 00:18:16,960 --> 00:18:22,360 So dot slash hello means run the hello program that is, in fact, right here. 401 00:18:22,360 --> 00:18:27,210 By contrast, you don't run dot slash for code, for make, 402 00:18:27,210 --> 00:18:30,180 or other commands that we'll soon see, like ls, because why? 403 00:18:30,180 --> 00:18:32,890 Those are installed in the system for everyone, 404 00:18:32,890 --> 00:18:34,578 not just in your individual folder. 405 00:18:34,578 --> 00:18:35,620 So that's the difference. 406 00:18:35,620 --> 00:18:38,970 Any programs we write, it'll be dot slash something. 407 00:18:38,970 --> 00:18:42,930 All right, so let's tease apart what is actually going on here 408 00:18:42,930 --> 00:18:45,610 and see if we can lean heavily today on Scratch, 409 00:18:45,610 --> 00:18:48,650 especially as the syntax gets weird, perhaps a little overwhelming. 410 00:18:48,650 --> 00:18:49,940 Still the same idea. 411 00:18:49,940 --> 00:18:52,540 So this last time, of course, was our Scratch program 412 00:18:52,540 --> 00:18:53,960 that just said Hello, world. 413 00:18:53,960 --> 00:18:58,270 I claim today that this is the nearest equivalent that any programmer can 414 00:18:58,270 --> 00:19:02,120 convert Scratch into C. If we color coded it accordingly, indeed, 415 00:19:02,120 --> 00:19:05,350 this sort of lines up with when green flag clicked is the orange. 416 00:19:05,350 --> 00:19:08,150 And then the purple is just the equivalent of the say block. 417 00:19:08,150 --> 00:19:10,610 So the say block, we said earlier, was a function. 418 00:19:10,610 --> 00:19:12,490 So let's compare these things side by side 419 00:19:12,490 --> 00:19:16,060 because there's actually some rhyme and reason to what MIT did with Scratch, 420 00:19:16,060 --> 00:19:19,610 as to why these shapes look like they do and so forth. 421 00:19:19,610 --> 00:19:22,460 So in Scratch, there's a function called say. 422 00:19:22,460 --> 00:19:25,840 Recall that it takes an input, otherwise known as an argument, 423 00:19:25,840 --> 00:19:27,860 or a parameter is another name. 424 00:19:27,860 --> 00:19:32,020 And that's always provided in these white ovals, zero or more white ovals. 425 00:19:32,020 --> 00:19:35,170 In C, we've already seen, but let's do it a little more pedantically, 426 00:19:35,170 --> 00:19:38,750 the equivalent say is essentially the word print. 427 00:19:38,750 --> 00:19:40,625 Why did MIT say you say? 428 00:19:40,625 --> 00:19:42,500 Just because it's a little more kid friendly. 429 00:19:42,500 --> 00:19:44,505 But print is the idea in our environment. 430 00:19:44,505 --> 00:19:46,630 It's actually not print, it's printf, because we're 431 00:19:46,630 --> 00:19:48,890 going to be able to format our text in interesting ways. 432 00:19:48,890 --> 00:19:49,932 More on that in a moment. 433 00:19:49,932 --> 00:19:52,930 But notice, the opening parentheses and closing parentheses 434 00:19:52,930 --> 00:19:56,210 here conjure up the idea of that white oval. 435 00:19:56,210 --> 00:19:58,700 So that's kind of intentional on MIT's part. 436 00:19:58,700 --> 00:20:01,460 What, though, in C goes between these parentheses? 437 00:20:01,460 --> 00:20:04,030 Well, literally the input or the argument 438 00:20:04,030 --> 00:20:06,530 you want to pass to the function, like Hello, world. 439 00:20:06,530 --> 00:20:09,010 But in C, you have to be a little more pedantic because you 440 00:20:09,010 --> 00:20:12,500 don't have a nice little graphic like this purple block with the white oval. 441 00:20:12,500 --> 00:20:15,272 You have to surround everything in double quotes. 442 00:20:15,272 --> 00:20:17,230 Those of you with prior programming experience, 443 00:20:17,230 --> 00:20:21,110 in C, you need double quotes, not single quotes in this context. 444 00:20:21,110 --> 00:20:23,290 And then there's this arcane detail here, 445 00:20:23,290 --> 00:20:26,660 backslash n, which we'll come back to in just a moment. 446 00:20:26,660 --> 00:20:30,920 But that's essentially what's going on, line by line from Scratch to C, 447 00:20:30,920 --> 00:20:33,880 there's kind of an equality between those two, even though, 448 00:20:33,880 --> 00:20:36,440 of course, look a little bit different. 449 00:20:36,440 --> 00:20:39,370 Well, let's see what that backslash n is doing, just 450 00:20:39,370 --> 00:20:40,790 to highlight some details here. 451 00:20:40,790 --> 00:20:45,200 So let me actually zoom in a little bit here and let me go up to my code. 452 00:20:45,200 --> 00:20:48,850 And let me just recklessly delete the backslash n. 453 00:20:48,850 --> 00:20:50,330 I'm going to let it auto save. 454 00:20:50,330 --> 00:20:51,070 I'll zoom out. 455 00:20:51,070 --> 00:20:55,750 In my terminal window now, I'm going to run make hello 456 00:20:55,750 --> 00:20:58,960 to recompile the code from source code to machine code, 457 00:20:58,960 --> 00:21:00,950 because I changed the source code. 458 00:21:00,950 --> 00:21:02,090 Nothing seems to happen. 459 00:21:02,090 --> 00:21:02,840 That's good. 460 00:21:02,840 --> 00:21:06,230 Now I'm going to type dot slash hello, enter. 461 00:21:06,230 --> 00:21:10,340 And there's a subtle bug. 462 00:21:10,340 --> 00:21:11,970 Since I made that change. 463 00:21:11,970 --> 00:21:14,962 What looks wrong to your eye now? 464 00:21:14,962 --> 00:21:16,545 AUDIENCE: The dollar sign [INAUDIBLE]. 465 00:21:16,545 --> 00:21:19,004 DAVID J. MALAN: Yeah, the dollar sign, our so-called prompt 466 00:21:19,004 --> 00:21:21,252 is at the end of the line instead of on its new line. 467 00:21:21,252 --> 00:21:22,960 I mean, this isn't really a deal breaker. 468 00:21:22,960 --> 00:21:25,400 Like the code works, and you can still type a new command. 469 00:21:25,400 --> 00:21:26,817 But it just looks a little stupid. 470 00:21:26,817 --> 00:21:28,760 Like this was not the intent of the program. 471 00:21:28,760 --> 00:21:31,790 It's sort of good practice to move the prompt to the next line, 472 00:21:31,790 --> 00:21:33,825 and that's because the backslash n is what 473 00:21:33,825 --> 00:21:35,450 we're going to call an escape sequence. 474 00:21:35,450 --> 00:21:40,360 So it turns out in programming, you have to tell the computer exactly what you 475 00:21:40,360 --> 00:21:41,330 want it to do. 476 00:21:41,330 --> 00:21:44,620 So if you want a new line, the equivalent of hitting Enter 477 00:21:44,620 --> 00:21:48,350 on the screen, you have to tell the computer to put a new line there. 478 00:21:48,350 --> 00:21:50,330 What you do not do is this. 479 00:21:50,330 --> 00:21:54,620 If I zoom out and I go into my code here, and I'll zoom in on the code-- 480 00:21:54,620 --> 00:21:58,100 if you want to put a new line, you don't do this. 481 00:21:58,100 --> 00:21:58,750 Why? 482 00:21:58,750 --> 00:22:00,680 It's just confusing for the computer. 483 00:22:00,680 --> 00:22:02,240 Like, wait a minute, is that a typo? 484 00:22:02,240 --> 00:22:03,700 Did your lines just wrap. 485 00:22:03,700 --> 00:22:05,285 Do you want to put a new line there. 486 00:22:05,285 --> 00:22:06,160 It just looks stupid. 487 00:22:06,160 --> 00:22:09,260 And it makes it less line based, the code itself. 488 00:22:09,260 --> 00:22:12,530 So humans decided years ago, if you want an actual line break, 489 00:22:12,530 --> 00:22:14,420 don't just naively hit the Enter key. 490 00:22:14,420 --> 00:22:17,190 Literally tell the computer, put a new line here. 491 00:22:17,190 --> 00:22:20,310 If you want to move two lines down, just do two of those. 492 00:22:20,310 --> 00:22:22,380 If you want three, just do three of those. 493 00:22:22,380 --> 00:22:23,730 Well, why the backslash? 494 00:22:23,730 --> 00:22:26,190 Again, these are what are called escape sequences. 495 00:22:26,190 --> 00:22:29,690 And you don't literally want an n, let alone [? an ?] n n. 496 00:22:29,690 --> 00:22:32,630 What you want is a new line, which is represented 497 00:22:32,630 --> 00:22:36,200 in code as simply backslash n. 498 00:22:36,200 --> 00:22:38,870 Now, for the mathematicians among you, what 499 00:22:38,870 --> 00:22:41,847 we're doing now by writing, using functions like printf 500 00:22:41,847 --> 00:22:44,180 is just sort of like f of x notation, if you recall that 501 00:22:44,180 --> 00:22:46,640 from high school or prior, where f is a function, 502 00:22:46,640 --> 00:22:49,280 x is an argument or an input thereto, and we're 503 00:22:49,280 --> 00:22:52,520 using parentheses in code, just like mathematicians would, 504 00:22:52,520 --> 00:22:54,360 to write functions like these. 505 00:22:54,360 --> 00:22:57,660 And the types of functions we're using right now still follow this model. 506 00:22:57,660 --> 00:22:59,340 You've got input, you want output. 507 00:22:59,340 --> 00:23:03,620 In this case, the input to printf, for instance, just like the say block, 508 00:23:03,620 --> 00:23:05,220 is what's called an argument. 509 00:23:05,220 --> 00:23:09,178 The output, though, of the function printf is what we call a side effect. 510 00:23:09,178 --> 00:23:12,470 And the easiest way to think about that is a side effect is just something that 511 00:23:12,470 --> 00:23:17,720 sort of happens on the screen, visually, [? audibly. ?] It just sort of happens. 512 00:23:17,720 --> 00:23:19,530 And there's that effect on the screen. 513 00:23:19,530 --> 00:23:22,680 And we'll contrast this with other types of outputs from functions. 514 00:23:22,680 --> 00:23:26,040 But for now, we're focusing on just this, which is reminiscent, 515 00:23:26,040 --> 00:23:27,830 of course, of what we did last week, which 516 00:23:27,830 --> 00:23:32,220 is if you type Hello, world into the white oval, use the say puzzle piece, 517 00:23:32,220 --> 00:23:37,260 you get out the side effect of the cat appearing to have said hello, world. 518 00:23:37,260 --> 00:23:41,400 Now, as for those escape sequences in C, there's bunches of them, 519 00:23:41,400 --> 00:23:44,010 but very few of them will we actually use in practice. 520 00:23:44,010 --> 00:23:45,570 Backslash n is a new line. 521 00:23:45,570 --> 00:23:49,200 Backslash r is a little more subtle and it's kind of a feature of yesteryear. 522 00:23:49,200 --> 00:23:52,920 It moves the cursor not to the new line, but to the beginning of the line. 523 00:23:52,920 --> 00:23:55,920 Kind of like an old timey typewriter, if you've seen how those work. 524 00:23:55,920 --> 00:24:00,600 Sometimes, though, you might want to print out an actual double quote. 525 00:24:00,600 --> 00:24:02,040 But there's a problem, of course. 526 00:24:02,040 --> 00:24:05,300 If this is my code here, and I'm already using double quotes 527 00:24:05,300 --> 00:24:08,490 as sort of special symbols to surround the text, 528 00:24:08,490 --> 00:24:11,840 I want printf to say it would probably be a little-- 529 00:24:11,840 --> 00:24:15,480 like if you wanted to say hello, world, with sort of finger quotes, 530 00:24:15,480 --> 00:24:19,990 why might this not be a good idea? 531 00:24:19,990 --> 00:24:24,527 If you think about this from the computer's perspective. 532 00:24:24,527 --> 00:24:26,610 Why is this probably not the right way to do this? 533 00:24:26,610 --> 00:24:27,453 Yeah? 534 00:24:27,453 --> 00:24:29,390 AUDIENCE: [INAUDIBLE]. 535 00:24:29,390 --> 00:24:30,390 DAVID J. MALAN: Exactly. 536 00:24:30,390 --> 00:24:33,557 The computer is indeed going to read your code top to bottom, left to right. 537 00:24:33,557 --> 00:24:35,880 And when it sees the first open quote, OK, that's fine. 538 00:24:35,880 --> 00:24:36,900 It understands that. 539 00:24:36,900 --> 00:24:40,150 But when it gets to the second quote, it's going to assume, oh, wait a minute. 540 00:24:40,150 --> 00:24:41,900 Maybe you only want me to say hello comma, 541 00:24:41,900 --> 00:24:44,525 and then it's going to keep reading and be like, wait a minute, 542 00:24:44,525 --> 00:24:46,040 why is there the word world here. 543 00:24:46,040 --> 00:24:48,207 And then wait a minute, now there's two more quotes. 544 00:24:48,207 --> 00:24:49,110 It's just confusing. 545 00:24:49,110 --> 00:24:49,890 It's ambiguous. 546 00:24:49,890 --> 00:24:53,280 And computers need you to be, again, very precise. 547 00:24:53,280 --> 00:24:57,510 So if you want a quotation mark to literally be displayed on the screen, 548 00:24:57,510 --> 00:25:00,410 you would escape it, so to speak, which looks a little weird 549 00:25:00,410 --> 00:25:02,280 and takes some getting into the habit of. 550 00:25:02,280 --> 00:25:04,830 But this just solves that kind of problem. 551 00:25:04,830 --> 00:25:07,410 And similarly, might you use single quotes in other contexts? 552 00:25:07,410 --> 00:25:08,220 More on that soon. 553 00:25:08,220 --> 00:25:09,928 And if you really want to bend your mind, 554 00:25:09,928 --> 00:25:13,442 how do you actually print a literal backslash, if you ever care to? 555 00:25:13,442 --> 00:25:15,150 It's not that common a character to type, 556 00:25:15,150 --> 00:25:16,858 but if you ever want it on the screen, it 557 00:25:16,858 --> 00:25:20,340 seems that we're using backslash as a special character that says, 558 00:25:20,340 --> 00:25:23,270 hey, give me a new line or give me a carriage return 559 00:25:23,270 --> 00:25:24,750 or give me a double quote. 560 00:25:24,750 --> 00:25:29,010 Weirdly, in programming, if you want to type a literal backslash on the screen, 561 00:25:29,010 --> 00:25:31,540 you literally do backslash backslash. 562 00:25:31,540 --> 00:25:33,460 But that's it for sort of weirdness for now. 563 00:25:33,460 --> 00:25:37,270 But this is to say, humans tripped over these same problems years ago. 564 00:25:37,270 --> 00:25:42,120 They came up with solutions, and now we indeed have these conventions in code. 565 00:25:42,120 --> 00:25:42,910 All right. 566 00:25:42,910 --> 00:25:45,490 So let's tease apart some other features of this 567 00:25:45,490 --> 00:25:49,240 in every program we're going to write, namely what's at the top of this file. 568 00:25:49,240 --> 00:25:53,790 So at the very top of this file, there is this cryptic looking hash include, 569 00:25:53,790 --> 00:25:57,307 or pound include standard io.h in angle bracket. 570 00:25:57,307 --> 00:25:58,390 So this is a little weird. 571 00:25:58,390 --> 00:26:00,140 We'll talk more about this next week, too. 572 00:26:00,140 --> 00:26:02,230 But this is what's called a header file. 573 00:26:02,230 --> 00:26:07,240 Any file that ends in dot h is not a source-- 574 00:26:07,240 --> 00:26:11,410 well, any file that ends in dot h is what we're going to call a header file. 575 00:26:11,410 --> 00:26:15,150 And inside of that header file is functionality that 576 00:26:15,150 --> 00:26:19,030 maybe came with the system, came with the programming language itself. 577 00:26:19,030 --> 00:26:20,890 So for instance, I'm going to do this. 578 00:26:20,890 --> 00:26:22,830 I'm going to go back to my code here and I'm 579 00:26:22,830 --> 00:26:25,230 going to make a very common mistake that you yourselves 580 00:26:25,230 --> 00:26:28,020 might make in the coming days, where I just forget that line because I don't 581 00:26:28,020 --> 00:26:30,187 even understand it in the first place so I certainly 582 00:26:30,187 --> 00:26:31,470 didn't think to type it here. 583 00:26:31,470 --> 00:26:36,340 Now, if I go back to my terminal window after clearing it and I run make hello, 584 00:26:36,340 --> 00:26:39,340 because I want to recompile it because I've changed the source code, 585 00:26:39,340 --> 00:26:41,470 I'm going to see a fairly cryptic error. 586 00:26:41,470 --> 00:26:44,620 I mean, there's more error on the green than there is code up here, 587 00:26:44,620 --> 00:26:48,460 but you'll get the hang of reading it to try to figure out what's going on. 588 00:26:48,460 --> 00:26:49,320 And I'm seeing this. 589 00:26:49,320 --> 00:26:53,130 Hello.c, line 3, character 5. 590 00:26:53,130 --> 00:26:56,250 So that just means line 3, colon, character 5. 591 00:26:56,250 --> 00:26:59,460 From left to right, it's sort of a visual cue as to where the problem is. 592 00:26:59,460 --> 00:27:03,760 Call to undeclared library function printf with type dot dot dot. 593 00:27:03,760 --> 00:27:06,790 And then the rest kind of overwhelms me visually at this point. 594 00:27:06,790 --> 00:27:08,050 But that's a hint. 595 00:27:08,050 --> 00:27:13,510 If you do not include that header file at the top of the code you've written, 596 00:27:13,510 --> 00:27:17,590 you do not have access to what's generally called a library. 597 00:27:17,590 --> 00:27:21,310 A library is a collection of code that someone else wrote for you. 598 00:27:21,310 --> 00:27:24,600 Maybe it was MIT, maybe it was the authors of the C language 599 00:27:24,600 --> 00:27:25,450 itself years ago. 600 00:27:25,450 --> 00:27:28,120 Maybe it was CS50 if we wrote some code for you. 601 00:27:28,120 --> 00:27:30,840 A library is a collection of code that someone else 602 00:27:30,840 --> 00:27:35,520 wrote for you and you access it, again, by including header files 603 00:27:35,520 --> 00:27:37,540 that those same people wrote for you. 604 00:27:37,540 --> 00:27:40,620 So if I go back to my code now-- let me clear my terminal window 605 00:27:40,620 --> 00:27:42,820 just to be less overwhelmed. 606 00:27:42,820 --> 00:27:45,910 Let me undo what I just did and put that file back. 607 00:27:45,910 --> 00:27:48,780 Can you perhaps infer, just functionally, 608 00:27:48,780 --> 00:27:53,160 what is inside of standard io.h that, again, someone else wrote? 609 00:27:53,160 --> 00:27:56,270 What must be inside? 610 00:27:56,270 --> 00:27:56,870 Printf. 611 00:27:56,870 --> 00:28:02,700 So whoever invented printf decades ago probably put that code in this file. 612 00:28:02,700 --> 00:28:05,310 And so by including it, so to speak, in my code, 613 00:28:05,310 --> 00:28:07,950 I now have access to printf functionality. 614 00:28:07,950 --> 00:28:08,730 So that's all. 615 00:28:08,730 --> 00:28:11,260 And again, C is lower level than scratch. 616 00:28:11,260 --> 00:28:13,010 It's obviously text based, which means you 617 00:28:13,010 --> 00:28:15,650 have to be a little more pedantic yourself as to what 618 00:28:15,650 --> 00:28:17,250 you want the computer to do for you. 619 00:28:17,250 --> 00:28:20,760 And if you want to use someone else's code, you indeed have to include it. 620 00:28:20,760 --> 00:28:22,850 Scratch didn't bother with this, but we indeed 621 00:28:22,850 --> 00:28:28,230 do need to do this in the context of C. As an aside, 622 00:28:28,230 --> 00:28:33,350 just to preempt some unnecessary headaches, this word is not studio.h. 623 00:28:33,350 --> 00:28:37,160 Every year, a non-zero number of people can't understand why their code is not 624 00:28:37,160 --> 00:28:39,150 working because studio.h is not found. 625 00:28:39,150 --> 00:28:42,450 It's standard io, stdio.h. 626 00:28:42,450 --> 00:28:47,060 That's one of the first frequently made mistakes otherwise. 627 00:28:47,060 --> 00:28:48,600 All right, so remember that. 628 00:28:48,600 --> 00:28:51,660 Let me undo now the unnecessary quotes I added here. 629 00:28:51,660 --> 00:28:55,620 And let me propose that we show you where you can learn more. 630 00:28:55,620 --> 00:28:58,570 So all of these libraries generally are documented. 631 00:28:58,570 --> 00:29:00,572 People wrote instructions for how to use them. 632 00:29:00,572 --> 00:29:03,280 So you don't just have to listen and pay attention only in class. 633 00:29:03,280 --> 00:29:04,655 You don't have to pull up a book. 634 00:29:04,655 --> 00:29:06,670 There tends to be online documentation as well. 635 00:29:06,670 --> 00:29:09,630 For instance, for the standard I/O header file. 636 00:29:09,630 --> 00:29:12,840 And the documentation in the world of programming for C 637 00:29:12,840 --> 00:29:16,720 specifically are called manual pages or man pages for short. 638 00:29:16,720 --> 00:29:21,060 Unfortunately, they're really written decades ago for the more comfortable 639 00:29:21,060 --> 00:29:23,980 among you, those who have an eye already for programming. 640 00:29:23,980 --> 00:29:27,810 And so what CS50 has done at this URL, manual.cs50.io, 641 00:29:27,810 --> 00:29:32,280 is we essentially have more user friendly versions of the documentation 642 00:29:32,280 --> 00:29:34,510 for this header file and others. 643 00:29:34,510 --> 00:29:37,810 So for instance, if I pull up manual.cs50.io, 644 00:29:37,810 --> 00:29:39,360 you'll see a web page like this. 645 00:29:39,360 --> 00:29:43,980 And if I just scroll quickly, you'll see a whole bunch of header files, .h files, 646 00:29:43,980 --> 00:29:46,120 and a whole bunch of functions beneath them. 647 00:29:46,120 --> 00:29:48,370 And there's only a couple of dozen or so here. 648 00:29:48,370 --> 00:29:52,270 And indeed, per this checkbox at the top frequently used in CS50, 649 00:29:52,270 --> 00:29:56,490 we have highlighted the functions that odds are over the next month and a half 650 00:29:56,490 --> 00:29:58,930 like you will probably want to use. 651 00:29:58,930 --> 00:30:01,480 If I turn off that less comfortable mode, 652 00:30:01,480 --> 00:30:05,280 there's actually hundreds of functions that come with C. 653 00:30:05,280 --> 00:30:07,510 And like no programmer knows all of these functions. 654 00:30:07,510 --> 00:30:09,750 What they do is they read the manual when 655 00:30:09,750 --> 00:30:11,860 they want to find some new piece of functionality. 656 00:30:11,860 --> 00:30:13,540 So I'm going to simplify this. 657 00:30:13,540 --> 00:30:17,052 I'm going to scroll down, though, to stdio.h, for instance here, 658 00:30:17,052 --> 00:30:19,510 and you'll see more functions that we'll eventually get to. 659 00:30:19,510 --> 00:30:22,350 But if I click on printf, you'll see hopefully 660 00:30:22,350 --> 00:30:26,680 some fairly user friendly instructions for how this thing works. 661 00:30:26,680 --> 00:30:29,820 For instance, under synopsis, you'll see that we tell you 662 00:30:29,820 --> 00:30:33,270 what header file you should include in order to use it. 663 00:30:33,270 --> 00:30:35,290 Below that is something called a prototype. 664 00:30:35,290 --> 00:30:36,310 More on that later. 665 00:30:36,310 --> 00:30:37,870 But below that is a description. 666 00:30:37,870 --> 00:30:41,700 And here is where the CS50 staff have written in layperson's terms 667 00:30:41,700 --> 00:30:45,250 explanations of how this function works, how to use it, and so forth. 668 00:30:45,250 --> 00:30:49,620 But if you'd rather see what the real world uses, you can turn off that mode 669 00:30:49,620 --> 00:30:52,300 and you'll see much more arcanely the original language. 670 00:30:52,300 --> 00:30:54,270 So in short, these are sort of training wheels 671 00:30:54,270 --> 00:30:56,800 that you can turn on and off at your leisure. 672 00:30:56,800 --> 00:31:01,210 But ultimately, this is real world documentation as well. 673 00:31:01,210 --> 00:31:03,430 So if we want to see something else, for instance, 674 00:31:03,430 --> 00:31:04,900 let me go back to the main menu. 675 00:31:04,900 --> 00:31:07,560 And as we'll see today, there are actually 676 00:31:07,560 --> 00:31:12,310 functions in a header file called cs50.h that for a few weeks, 677 00:31:12,310 --> 00:31:13,740 we're going to lean on heavily. 678 00:31:13,740 --> 00:31:16,330 Long story short, it's actually kind of hard. 679 00:31:16,330 --> 00:31:19,950 It's annoying in C to get user input, ironically, 680 00:31:19,950 --> 00:31:22,900 to get the human to type in a word or a number. 681 00:31:22,900 --> 00:31:25,920 You have to jump through some technical hoops to make that happen. 682 00:31:25,920 --> 00:31:29,427 And we'll show you how to do it like the real way in a few weeks. 683 00:31:29,427 --> 00:31:31,260 But for now, among the first training wheels 684 00:31:31,260 --> 00:31:35,920 is a CS50 library code that we wrote that will just make your life easier. 685 00:31:35,920 --> 00:31:37,830 And indeed, we're going to give you access 686 00:31:37,830 --> 00:31:42,850 to functions that simplify the process of actually getting input from the user. 687 00:31:42,850 --> 00:31:44,640 So case in point, we're going to give you 688 00:31:44,640 --> 00:31:50,400 access to functions like get_string, when you want to get a string of text 689 00:31:50,400 --> 00:31:52,120 from the user-- a string is just text. 690 00:31:52,120 --> 00:31:55,570 So if you want to get one character, one word, one sentence, one paragraph, 691 00:31:55,570 --> 00:31:57,405 you can call a function called get_string. 692 00:31:57,405 --> 00:31:59,530 We're going to give you another one called get_int. 693 00:31:59,530 --> 00:32:02,160 When you want to get an integer from the user, like 1 or 0 694 00:32:02,160 --> 00:32:05,380 or negative 1 or anything else, you can use that function as well. 695 00:32:05,380 --> 00:32:07,590 And we'll see today too there's other functions you 696 00:32:07,590 --> 00:32:09,850 can use from CS50's library. 697 00:32:09,850 --> 00:32:13,990 In a weeks' time, we'll take these away once you don't need them anymore. 698 00:32:13,990 --> 00:32:16,530 And you'll see what those library functions 699 00:32:16,530 --> 00:32:18,460 have been doing all along for you. 700 00:32:18,460 --> 00:32:20,020 But for now, let's focus on this. 701 00:32:20,020 --> 00:32:22,320 Perhaps the most useful of them, get_string, 702 00:32:22,320 --> 00:32:25,720 and solve a problem that we did already pretty easily in Scratch. 703 00:32:25,720 --> 00:32:29,560 So recall in Scratch, this was a program that used two functions. 704 00:32:29,560 --> 00:32:30,795 Three, in fact. 705 00:32:30,795 --> 00:32:32,830 Ask, to ask a question of the user. 706 00:32:32,830 --> 00:32:35,010 Say, to actually display something on the screen. 707 00:32:35,010 --> 00:32:37,810 And join, to combine the default of apple, banana. 708 00:32:37,810 --> 00:32:41,860 Or in this case, Hello, and whatever the human's answer was. 709 00:32:41,860 --> 00:32:46,000 So this made our Hello program a little more interactive last time. 710 00:32:46,000 --> 00:32:49,420 How can we actually translate this into a similar paradigm now? 711 00:32:49,420 --> 00:32:51,880 So input and output is the story, as always. 712 00:32:51,880 --> 00:32:55,210 In this case, we have arguments going into those functions. 713 00:32:55,210 --> 00:32:57,650 But now we're going to introduce not side effects, which 714 00:32:57,650 --> 00:32:59,080 is stuff that happens visually. 715 00:32:59,080 --> 00:33:02,570 We're going to revisit that blue circle called answer, 716 00:33:02,570 --> 00:33:05,960 or the blue oval called answer, that represented last week what 717 00:33:05,960 --> 00:33:08,070 we called a return value. 718 00:33:08,070 --> 00:33:10,403 And this is what many functions will actually do for us. 719 00:33:10,403 --> 00:33:13,403 They're not just going to display something presumptuously on the screen 720 00:33:13,403 --> 00:33:15,660 or play a sound or a video or something like that. 721 00:33:15,660 --> 00:33:18,470 They're going to hand you back virtually a value-- 722 00:33:18,470 --> 00:33:25,160 text or integers or sounds or images that you can then do with what you see 723 00:33:25,160 --> 00:33:25,740 fit. 724 00:33:25,740 --> 00:33:28,950 So the paradigm we'll now have is much like in Scratch. 725 00:33:28,950 --> 00:33:31,760 If the input is what's your name and the function is ask, 726 00:33:31,760 --> 00:33:34,170 and you get back a return value of answer, 727 00:33:34,170 --> 00:33:37,640 we want to actually do this now in C. So side by side, 728 00:33:37,640 --> 00:33:42,080 what code like this in Scratch is going to look like today onward is this. 729 00:33:42,080 --> 00:33:44,600 Instead of using the Ask block, you literally 730 00:33:44,600 --> 00:33:46,770 use CS50's function called get_string. 731 00:33:46,770 --> 00:33:47,425 It takes input. 732 00:33:47,425 --> 00:33:49,550 So we put the parentheses on the left and the right 733 00:33:49,550 --> 00:33:52,520 to conjure the idea of this white oval. 734 00:33:52,520 --> 00:33:55,630 Inside of that string, you can put a prompt, 735 00:33:55,630 --> 00:33:59,110 so to speak, like, what do you want the human to be asked, in this case. 736 00:33:59,110 --> 00:34:01,140 And I'm missing something still. 737 00:34:01,140 --> 00:34:04,490 Per the placeholders here, what's missing? 738 00:34:04,490 --> 00:34:06,317 So quotation marks, so literally quotation 739 00:34:06,317 --> 00:34:07,650 marks on the left and the right. 740 00:34:07,650 --> 00:34:08,909 And I'm going to be a little anal here. 741 00:34:08,909 --> 00:34:10,409 I'm going to put a space at the end. 742 00:34:10,409 --> 00:34:11,639 Because I don't want to-- 743 00:34:11,639 --> 00:34:14,699 I could, but I don't want the cursor to go to the next line. 744 00:34:14,699 --> 00:34:16,340 Hence, no backslash n. 745 00:34:16,340 --> 00:34:19,639 If I want the cursor just to sit there kind of blinking, waiting for the user 746 00:34:19,639 --> 00:34:21,960 after the question mark, I'm just going to put a space. 747 00:34:21,960 --> 00:34:23,670 So it will stay there for me. 748 00:34:23,670 --> 00:34:27,199 But this is just an aesthetic detail using the same idea as before. 749 00:34:27,199 --> 00:34:29,460 So that is the analog of this block. 750 00:34:29,460 --> 00:34:32,400 But how do I get access to the so-called return value? 751 00:34:32,400 --> 00:34:35,030 MIT just plopped it on the screen for us automatically. 752 00:34:35,030 --> 00:34:39,810 In C, we have to write a little more code to get access to that return value. 753 00:34:39,810 --> 00:34:43,110 And the way we do this is on the left hand side of this line of code, 754 00:34:43,110 --> 00:34:45,780 we come up with a name for the return value. 755 00:34:45,780 --> 00:34:47,280 You can call it anything you want. 756 00:34:47,280 --> 00:34:50,400 But answer is a nice equivalent to what MIT did. 757 00:34:50,400 --> 00:34:52,650 You could more generically call it x or y or z. 758 00:34:52,650 --> 00:34:53,940 But that's not really useful. 759 00:34:53,940 --> 00:34:56,553 And so computer scientists, unlike mathematicians, 760 00:34:56,553 --> 00:34:58,970 will tend to use variables that are a little more verbose, 761 00:34:58,970 --> 00:35:00,480 like the word "answer." 762 00:35:00,480 --> 00:35:03,540 But in C, it's, again, a little lower level. 763 00:35:03,540 --> 00:35:08,560 You have to tell the computer what type of variable this is going to be. 764 00:35:08,560 --> 00:35:11,680 So I'm kind of conflating "variable" and "return value," 765 00:35:11,680 --> 00:35:14,500 but they're being used in an intertwined way. 766 00:35:14,500 --> 00:35:19,930 The get_string function, just like the ask block, returns a value. 767 00:35:19,930 --> 00:35:21,840 If you want to do something with it, you need 768 00:35:21,840 --> 00:35:26,470 to put it in something called a variable, which is denoted in text here. 769 00:35:26,470 --> 00:35:28,500 But again, per last week, the computer doesn't 770 00:35:28,500 --> 00:35:31,570 know if it's looking at numbers or characters or images or sounds. 771 00:35:31,570 --> 00:35:35,250 You have to tell it, as the programmer, that the zeros and ones that are somehow 772 00:35:35,250 --> 00:35:37,500 involved here underneath the computer's hood 773 00:35:37,500 --> 00:35:40,440 are, in fact, to be treated as text, a.k.a. 774 00:35:40,440 --> 00:35:41,670 string. 775 00:35:41,670 --> 00:35:45,155 Now, there's one stupid subtlety still missing from this line of code. 776 00:35:45,155 --> 00:35:47,280 Does anyone know, especially if you've programmed-- 777 00:35:47,280 --> 00:35:48,670 OK, all of you have program before. 778 00:35:48,670 --> 00:35:48,935 Yes? 779 00:35:48,935 --> 00:35:49,500 AUDIENCE: Semicolon. 780 00:35:49,500 --> 00:35:50,650 DAVID J. MALAN: Semicolon. 781 00:35:50,650 --> 00:35:53,250 So one of the headaches of C and a lot of languages 782 00:35:53,250 --> 00:35:57,960 is you actually have to finish your thought explicitly so the computer knows 783 00:35:57,960 --> 00:35:59,470 that that line of code is done. 784 00:35:59,470 --> 00:36:01,150 And it's not a period, like in English. 785 00:36:01,150 --> 00:36:02,350 It's, in fact, a semicolon. 786 00:36:02,350 --> 00:36:03,850 Now, you don't use these everywhere. 787 00:36:03,850 --> 00:36:05,058 We'll see where you use them. 788 00:36:05,058 --> 00:36:08,440 But that, too, is a very common mistake, to overlook something simple. 789 00:36:08,440 --> 00:36:11,760 But again, in the coming weeks, even though this might look very cryptic, 790 00:36:11,760 --> 00:36:15,100 with muscle memory and practice, you'll start to see these things instantly, 791 00:36:15,100 --> 00:36:17,250 even if, for a few days, you sort of bang your head 792 00:36:17,250 --> 00:36:21,210 against the screen, so to speak, not seeing what 793 00:36:21,210 --> 00:36:24,160 the TFs and I much more readily see. 794 00:36:24,160 --> 00:36:25,930 So let's go ahead and do this. 795 00:36:25,930 --> 00:36:28,030 Let me go back over to VS Code here. 796 00:36:28,030 --> 00:36:29,730 Let me zoom in just a little bit. 797 00:36:29,730 --> 00:36:31,810 And let me go ahead and do this. 798 00:36:31,810 --> 00:36:34,470 I'm going to get rid of my single use of printf. 799 00:36:34,470 --> 00:36:40,600 And I'm going to say the exact same thing-- string answer equals get string, 800 00:36:40,600 --> 00:36:43,780 quote, unquote, "What's your name?" 801 00:36:43,780 --> 00:36:48,180 question mark, space, closed quote, semicolon. 802 00:36:48,180 --> 00:36:50,245 And now I want to print out that answer. 803 00:36:50,245 --> 00:36:52,870 Well, let me do this incorrectly, deliberately, for the moment. 804 00:36:52,870 --> 00:36:57,090 Let me just say printf, quote, unquote, "hello, answer," 805 00:36:57,090 --> 00:37:01,330 if I want to plug in "answer" and I want to add a new line at the end, semicolon. 806 00:37:01,330 --> 00:37:02,650 So let me try this. 807 00:37:02,650 --> 00:37:04,960 But there's multiple mistakes now in my code. 808 00:37:04,960 --> 00:37:06,460 Let's trip over them deliberately. 809 00:37:06,460 --> 00:37:09,668 Let me go down to my terminal window by clicking at the bottom of the screen. 810 00:37:09,668 --> 00:37:11,320 Let me run "make hello" again. 811 00:37:11,320 --> 00:37:12,000 Enter. 812 00:37:12,000 --> 00:37:13,950 And, oh, my god, there's even more errors now 813 00:37:13,950 --> 00:37:15,870 than there were before, but not a problem. 814 00:37:15,870 --> 00:37:17,620 Let me click on this little triangle here, 815 00:37:17,620 --> 00:37:19,870 which is just going to zoom in on the terminal window. 816 00:37:19,870 --> 00:37:21,310 So it takes up my full screen. 817 00:37:21,310 --> 00:37:24,690 And just generally, all you have to do is find a few keywords visually 818 00:37:24,690 --> 00:37:26,550 that give you a clue as to what's going on. 819 00:37:26,550 --> 00:37:29,680 Or, as before, you can always ask the CS50 Duck. 820 00:37:29,680 --> 00:37:31,740 So here's the command I ran, "make hello." 821 00:37:31,740 --> 00:37:33,850 Somehow that induced all of these errors. 822 00:37:33,850 --> 00:37:36,370 Always read them top to bottom, not bottom up. 823 00:37:36,370 --> 00:37:39,970 So from top to bottom, there's a problem on line 5, character 5-- 824 00:37:39,970 --> 00:37:42,800 use of undeclared identifier string. 825 00:37:42,800 --> 00:37:44,140 Did I mean standard in? 826 00:37:44,140 --> 00:37:46,210 No, no, no, I didn't there. 827 00:37:46,210 --> 00:37:49,390 And then, also, two errors generated. 828 00:37:49,390 --> 00:37:52,070 Too many errors [? are made. ?] What did I do wrong? 829 00:37:52,070 --> 00:37:55,760 Well, it turns out what I do need to do at the top of this file-- 830 00:37:55,760 --> 00:37:58,370 let me click the triangle to zoom back out-- 831 00:37:58,370 --> 00:38:02,000 if I want to use the get_string function to get a string, 832 00:38:02,000 --> 00:38:04,190 I actually need to include another header file, 833 00:38:04,190 --> 00:38:09,498 which is probably called "include cs50.h." 834 00:38:09,498 --> 00:38:10,790 Technically, any order is fine. 835 00:38:10,790 --> 00:38:12,998 I tend to alphabetize because I just know, therefore, 836 00:38:12,998 --> 00:38:15,350 where to look alphabetically for a certain header file. 837 00:38:15,350 --> 00:38:19,150 Now that that's in place, let me again run "make hello." 838 00:38:19,150 --> 00:38:20,240 Enter. 839 00:38:20,240 --> 00:38:22,220 And now we're back in business. 840 00:38:22,220 --> 00:38:23,180 No error message. 841 00:38:23,180 --> 00:38:26,060 So even though you might have more errors than you have code, 842 00:38:26,060 --> 00:38:28,150 odds are it's just the computer is confused. 843 00:38:28,150 --> 00:38:31,370 And it could be something simple and an easy fix like that. 844 00:38:31,370 --> 00:38:35,720 So just to be clear, standard io.h, because I'm including it, 845 00:38:35,720 --> 00:38:37,330 I can use printf. 846 00:38:37,330 --> 00:38:42,040 cs50.h, I can use get_string because the people who 847 00:38:42,040 --> 00:38:45,550 invented C and the people who invented CS50 wrote those two files, so 848 00:38:45,550 --> 00:38:47,650 to speak, respectively. 849 00:38:47,650 --> 00:38:50,990 All right, unfortunately, even though the program compiles, 850 00:38:50,990 --> 00:38:52,490 that doesn't mean it's correct. 851 00:38:52,490 --> 00:38:54,800 It just means it's syntactically valid. 852 00:38:54,800 --> 00:38:56,000 It's valid C code. 853 00:38:56,000 --> 00:38:59,080 If I go ahead and run "./hello" and hit Enter now, 854 00:38:59,080 --> 00:39:00,932 I'm going to be prompted for my name. 855 00:39:00,932 --> 00:39:01,640 So I'll type it-- 856 00:39:01,640 --> 00:39:04,940 D-A-V-I-D. And notice there's a space to the right of the question mark, 857 00:39:04,940 --> 00:39:05,750 as promised. 858 00:39:05,750 --> 00:39:06,840 Enter. 859 00:39:06,840 --> 00:39:09,840 But it just says "hello, answer," which, of course, is not the intent. 860 00:39:09,840 --> 00:39:11,820 I want it to say "hello, David." 861 00:39:11,820 --> 00:39:13,290 So how can we do this? 862 00:39:13,290 --> 00:39:16,343 Well, in Scratch, it took a couple of puzzle pieces. 863 00:39:16,343 --> 00:39:17,760 But it was pretty straightforward. 864 00:39:17,760 --> 00:39:22,050 If I wanted to say the combination of two phrases, "hello" and something else, 865 00:39:22,050 --> 00:39:25,890 I joined those two and then passed that output to the input of say. 866 00:39:25,890 --> 00:39:28,220 In C, it's going to be a little different here 867 00:39:28,220 --> 00:39:30,720 just because it's an old language and this is how it's done. 868 00:39:30,720 --> 00:39:33,390 Still use printf because that's the same thing as say. 869 00:39:33,390 --> 00:39:34,320 I got my parentheses. 870 00:39:34,320 --> 00:39:35,280 I got my semicolon. 871 00:39:35,280 --> 00:39:36,030 Good to go. 872 00:39:36,030 --> 00:39:39,325 But inside of that, this is where printf is different. 873 00:39:39,325 --> 00:39:44,130 If you want to say something followed by something else, in the world of C, 874 00:39:44,130 --> 00:39:46,230 you tend to use placeholders. 875 00:39:46,230 --> 00:39:48,890 So you don't just join things together as we 876 00:39:48,890 --> 00:39:52,280 will do in Python and other languages. 877 00:39:52,280 --> 00:39:55,590 You say to the compiler, give me the word "hello," comma, 878 00:39:55,590 --> 00:39:57,090 and then something else. 879 00:39:57,090 --> 00:40:00,420 And the percent s means, put another string here. 880 00:40:00,420 --> 00:40:03,620 It's sort of like leaving a placeholder in your code or a template 881 00:40:03,620 --> 00:40:05,880 where you'll actually plug in some values. 882 00:40:05,880 --> 00:40:09,727 Now, if this is what I want to display, I still use my quotes, as before. 883 00:40:09,727 --> 00:40:11,810 And I might, in fact, have a backslash n if I want 884 00:40:11,810 --> 00:40:13,560 to move the cursor to the next line. 885 00:40:13,560 --> 00:40:16,980 But this is where printf is a little different. 886 00:40:16,980 --> 00:40:21,510 Unlike say, which took one input, printf is kind of like join. 887 00:40:21,510 --> 00:40:24,960 It can take two or more inputs if you so choose. 888 00:40:24,960 --> 00:40:28,610 You just have to separate them with a comma. 889 00:40:28,610 --> 00:40:33,170 So much like the join block has two ovals here that are initially white-- 890 00:40:33,170 --> 00:40:37,040 apple and banana-- until we dragged and dropped answer on top of it, printf-- 891 00:40:37,040 --> 00:40:39,050 and really any function in C-- if you want 892 00:40:39,050 --> 00:40:42,180 to pass in multiple inputs, that's fine if they're supported. 893 00:40:42,180 --> 00:40:43,817 Just separate them with commas. 894 00:40:43,817 --> 00:40:45,150 There's no multiple parentheses. 895 00:40:45,150 --> 00:40:46,260 There's no multiple ovals. 896 00:40:46,260 --> 00:40:48,780 Just separate them with commas. 897 00:40:48,780 --> 00:40:51,360 And now notice a potential point of confusion. 898 00:40:51,360 --> 00:40:57,491 What's different about this comma and this one, just instinctively? 899 00:40:57,491 --> 00:40:59,280 Sort of minor detail, but important. 900 00:40:59,280 --> 00:40:59,780 Yeah? 901 00:40:59,780 --> 00:41:01,758 AUDIENCE: Inside and outside. 902 00:41:01,758 --> 00:41:03,800 DAVID J. MALAN: So one is inside, one is outside. 903 00:41:03,800 --> 00:41:07,390 So the one that's inside the quotes is literally the English grammatical comma 904 00:41:07,390 --> 00:41:08,900 that you want the human to see. 905 00:41:08,900 --> 00:41:11,680 The one out here is a C thing that's separating 906 00:41:11,680 --> 00:41:15,150 the first input to this function printf from the second. 907 00:41:15,150 --> 00:41:17,150 Strictly speaking, you don't need a space there. 908 00:41:17,150 --> 00:41:20,920 But it's a good practice, stylistically, to separate your arguments 909 00:41:20,920 --> 00:41:23,390 with single spaces, just as I've done there. 910 00:41:23,390 --> 00:41:26,180 So let me go ahead and now do something with this. 911 00:41:26,180 --> 00:41:29,060 Let me go back to my C code here. 912 00:41:29,060 --> 00:41:32,210 I'm going to clear my terminal window just to get rid of that distraction. 913 00:41:32,210 --> 00:41:35,680 And now I'm going to change answer to percent s. 914 00:41:35,680 --> 00:41:40,840 And then outside of the double quotes on line 7, I'm going to do comma "answer." 915 00:41:40,840 --> 00:41:44,630 And then, after it auto-saves, I'm going to go back to my terminal window. 916 00:41:44,630 --> 00:41:47,720 And just to make another deliberate mistake, "./hello." 917 00:41:47,720 --> 00:41:48,380 Enter. 918 00:41:48,380 --> 00:41:49,160 "What's your name? 919 00:41:49,160 --> 00:41:49,450 David." 920 00:41:49,450 --> 00:41:49,950 Enter. 921 00:41:49,950 --> 00:41:51,200 It's still broken. 922 00:41:51,200 --> 00:41:53,870 But why? 923 00:41:53,870 --> 00:41:55,200 I still have to recompile it. 924 00:41:55,200 --> 00:41:57,180 So again, you just get into the habit, when you change your code, 925 00:41:57,180 --> 00:42:00,620 you have to recompile so you get new machine code in the file "hello." 926 00:42:00,620 --> 00:42:01,720 So let's do it again. 927 00:42:01,720 --> 00:42:03,120 "make hello." 928 00:42:03,120 --> 00:42:04,730 No errors is good. 929 00:42:04,730 --> 00:42:05,510 "./hello." 930 00:42:05,510 --> 00:42:06,120 Enter. 931 00:42:06,120 --> 00:42:07,203 "What's your name?" again. 932 00:42:07,203 --> 00:42:11,220 D-A-V-I-D. And now, "hello, David." 933 00:42:11,220 --> 00:42:13,410 So again, a lot of this is still cryptic. 934 00:42:13,410 --> 00:42:16,020 But it's going to start to follow patterns like this. 935 00:42:16,020 --> 00:42:20,040 Functions like in math class, f of x, are written function name, parentheses, 936 00:42:20,040 --> 00:42:23,245 input, comma, input, comma, input, however many you have. 937 00:42:23,245 --> 00:42:24,870 They're going to follow these patterns. 938 00:42:24,870 --> 00:42:29,540 But notice, too, on lines 6 and 7, I have finished each of my thoughts 939 00:42:29,540 --> 00:42:31,343 with a semicolon. 940 00:42:31,343 --> 00:42:34,010 So what are the other commands that you can run in your terminal 941 00:42:34,010 --> 00:42:35,910 window besides something like ls? 942 00:42:35,910 --> 00:42:38,670 Well, it turns out there's a whole bunch of them. ls, of course, 943 00:42:38,670 --> 00:42:42,090 was simply short for list, which shows you the files in your current folder. 944 00:42:42,090 --> 00:42:44,960 But there's also cd for change directory, which 945 00:42:44,960 --> 00:42:48,260 is the command equivalent of double-clicking on a folder to open it 946 00:42:48,260 --> 00:42:49,730 up in a graphical environment. 947 00:42:49,730 --> 00:42:52,190 There's cp, which is short for copy, which allows 948 00:42:52,190 --> 00:42:54,910 you to make a copy of a file or folder. 949 00:42:54,910 --> 00:42:59,110 There's make dir, "mkdir," which is short for make directory, 950 00:42:59,110 --> 00:43:00,970 which is how you could make a new folder. 951 00:43:00,970 --> 00:43:03,420 There's mv, which is short for move, which 952 00:43:03,420 --> 00:43:06,720 would allow you to move one file or folder from one place to another 953 00:43:06,720 --> 00:43:09,610 or simply rename one of those to a different name. 954 00:43:09,610 --> 00:43:11,460 There's rm, which is short for remove. 955 00:43:11,460 --> 00:43:14,230 And there's "rmdir," which is short for remove directory. 956 00:43:14,230 --> 00:43:16,480 So, in fact, let's play around with a couple of these. 957 00:43:16,480 --> 00:43:18,280 Let me go back to VS Code here. 958 00:43:18,280 --> 00:43:20,160 Let me go ahead and open up my File Explorer. 959 00:43:20,160 --> 00:43:23,340 And recall that at this point I've got two files, hello.c, 960 00:43:23,340 --> 00:43:27,430 which contains my source code, and then hello, which contains my machine code, 961 00:43:27,430 --> 00:43:31,570 the executable program that I previously generated by running make. 962 00:43:31,570 --> 00:43:33,360 Well, let me go ahead and propose that I'd 963 00:43:33,360 --> 00:43:38,320 like to prepare to keep all of my files and folders very orderly. 964 00:43:38,320 --> 00:43:42,250 So for every program I write or for every problem on a problem set I write, 965 00:43:42,250 --> 00:43:46,510 maybe I want to store my relevant files in a specific folder for that problem. 966 00:43:46,510 --> 00:43:50,520 So suppose then that I want to put hello.c in a folder, otherwise known 967 00:43:50,520 --> 00:43:52,600 as a directory, called hello. 968 00:43:52,600 --> 00:43:56,560 Well, I can't do that quite yet because I already have a program called hello. 969 00:43:56,560 --> 00:43:58,540 So let me use one of those new commands. 970 00:43:58,540 --> 00:44:04,057 rm space hello will delete or remove hello from my current directory. 971 00:44:04,057 --> 00:44:05,140 So I'm going to hit Enter. 972 00:44:05,140 --> 00:44:08,410 I'm going to be prompted to confirm with y for yes or n for no. 973 00:44:08,410 --> 00:44:09,750 "Remove regular file 'hello'?" 974 00:44:09,750 --> 00:44:11,770 I'm going to hit y and enter. 975 00:44:11,770 --> 00:44:14,250 And as I hit Enter, watch the top left of my screen 976 00:44:14,250 --> 00:44:18,060 as the hello file would seem to disappear. 977 00:44:18,060 --> 00:44:19,295 Voila, it's now gone. 978 00:44:19,295 --> 00:44:21,670 So now I'm going to go ahead and use a different command. 979 00:44:21,670 --> 00:44:24,225 Let me go ahead and do mkdir for make directory. 980 00:44:24,225 --> 00:44:26,100 I'm going to call the directory itself hello. 981 00:44:26,100 --> 00:44:28,380 And watch again, at top left, what happens. 982 00:44:28,380 --> 00:44:29,220 Enter. 983 00:44:29,220 --> 00:44:32,890 Now I have not a file but a folder called hello. 984 00:44:32,890 --> 00:44:34,770 And in this GUI, the fact that it's a folder 985 00:44:34,770 --> 00:44:39,580 is indicated, one, by its icon and, two, by that little right-facing triangle, 986 00:44:39,580 --> 00:44:42,130 which means I can expand it to see what's inside. 987 00:44:42,130 --> 00:44:44,380 And in fact, if I do that, I'll see, of course, 988 00:44:44,380 --> 00:44:47,170 that nothing's in it because we literally just created it. 989 00:44:47,170 --> 00:44:51,820 All right, well, what if I want to move hello.c into the new hello folder? 990 00:44:51,820 --> 00:44:54,100 Well, I could, just like on macOS or Windows. 991 00:44:54,100 --> 00:44:58,390 I could, actually in my File Explorer, click and drag one into the other. 992 00:44:58,390 --> 00:45:01,000 But let's do this entirely within the terminal window. 993 00:45:01,000 --> 00:45:01,900 So let me do this. 994 00:45:01,900 --> 00:45:06,450 Let me move, or mv for short, my file called hello.c 995 00:45:06,450 --> 00:45:09,540 into a new destination folder, hello. 996 00:45:09,540 --> 00:45:11,942 And I can, optionally, put at slash the end of "hello" 997 00:45:11,942 --> 00:45:13,900 just to make super clear that it's a directory. 998 00:45:13,900 --> 00:45:15,430 But that's not strictly necessary. 999 00:45:15,430 --> 00:45:20,110 But if I say mv hello.c hello, with spaces in between, 1000 00:45:20,110 --> 00:45:24,550 assuming hello exists as a folder, watch what happens at top left now. 1001 00:45:24,550 --> 00:45:26,440 It's a little more subtle, but hello.c is 1002 00:45:26,440 --> 00:45:30,520 going to move inside of the hello folder right now. 1003 00:45:30,520 --> 00:45:33,080 And indeed, it's only slightly more indented. 1004 00:45:33,080 --> 00:45:35,330 But notice if I collapse the hello folder, 1005 00:45:35,330 --> 00:45:39,560 notice that it seems to be gone because hello.c is now inside of that folder. 1006 00:45:39,560 --> 00:45:41,810 Of course, if I expand that, I'll see it again. 1007 00:45:41,810 --> 00:45:44,530 If I go back to my terminal window and type ls for list, 1008 00:45:44,530 --> 00:45:47,260 now I don't see hello.c. 1009 00:45:47,260 --> 00:45:49,580 And I don't see an executable program anymore. 1010 00:45:49,580 --> 00:45:50,750 But I do see hello. 1011 00:45:50,750 --> 00:45:53,590 And the slash there just makes super clear to me, the user, 1012 00:45:53,590 --> 00:45:54,860 that it's indeed a folder. 1013 00:45:54,860 --> 00:45:56,900 So how do I change into that folder? 1014 00:45:56,900 --> 00:45:59,710 Well, I can obviously use the graphical interface at left and click 1015 00:45:59,710 --> 00:46:01,910 and expand and see what's going on. 1016 00:46:01,910 --> 00:46:05,980 But there's no direct connection between the File Explorer at top left 1017 00:46:05,980 --> 00:46:08,140 and my terminal window at bottom right. 1018 00:46:08,140 --> 00:46:12,620 Rather, those are just two different ways to explore the underlying system. 1019 00:46:12,620 --> 00:46:16,130 So if I want to change my terminal window into this new directory, 1020 00:46:16,130 --> 00:46:20,330 I can do cd for change directory, hello, and then Enter. 1021 00:46:20,330 --> 00:46:24,680 And now notice my terminal window's prompt changes slightly. 1022 00:46:24,680 --> 00:46:27,890 There's still a dollar sign, which indicates, type my commands here. 1023 00:46:27,890 --> 00:46:30,070 But before that dollar sign, just so that I 1024 00:46:30,070 --> 00:46:33,340 have a reminder, sort of breadcrumbs that visually remind me 1025 00:46:33,340 --> 00:46:37,670 what folder I am now in, I see that I'm inside of hello. 1026 00:46:37,670 --> 00:46:40,720 If I now type ls, I should see the file I 1027 00:46:40,720 --> 00:46:43,990 expect to be in there, which is indeed hello.c. 1028 00:46:43,990 --> 00:46:46,730 Now, suppose I want to try out some of those other commands. 1029 00:46:46,730 --> 00:46:49,723 And suppose I want to maybe rename this file. 1030 00:46:49,723 --> 00:46:51,890 I really want this file to be called something else. 1031 00:46:51,890 --> 00:46:57,700 So maybe I might do something like this, mv hello.c space, and now a new name 1032 00:46:57,700 --> 00:46:58,550 for the file. 1033 00:46:58,550 --> 00:47:00,070 Well, maybe I want to make-- 1034 00:47:00,070 --> 00:47:02,385 say this is an old version of my code, because I want 1035 00:47:02,385 --> 00:47:04,010 to just start fresh with something new. 1036 00:47:04,010 --> 00:47:07,930 So I could do something like this, mv hello.c old.c. 1037 00:47:07,930 --> 00:47:10,100 And watch what happens at top left. 1038 00:47:10,100 --> 00:47:13,400 hello.c, of course, gets renamed via the move command. 1039 00:47:13,400 --> 00:47:15,910 So I can use move to move a file into a folder. 1040 00:47:15,910 --> 00:47:20,270 Or I can use it to rename a file or folder, as I've just done here. 1041 00:47:20,270 --> 00:47:21,860 Now, suppose I want to undo that. 1042 00:47:21,860 --> 00:47:23,270 Well, I can't just type undo. 1043 00:47:23,270 --> 00:47:26,350 I can't just hit Control C. But I can do the opposite, in effect. 1044 00:47:26,350 --> 00:47:32,870 mv old.c hello.c will now, per top left, change it back into that file. 1045 00:47:32,870 --> 00:47:36,132 If I want to make a copy of this file, maybe as an actual backup because I'm 1046 00:47:36,132 --> 00:47:38,840 really happy with this version and I'm worried about breaking it, 1047 00:47:38,840 --> 00:47:40,850 well, I could do cp for short. 1048 00:47:40,850 --> 00:47:42,820 I can then do hello.c. 1049 00:47:42,820 --> 00:47:46,340 And then I can do something like backup.c, or any other file name. 1050 00:47:46,340 --> 00:47:48,500 I'm taking care to use the same file extension 1051 00:47:48,500 --> 00:47:52,270 so that if I do open this file later, it still opens and gets highlighted 1052 00:47:52,270 --> 00:47:53,900 and colorized in the same way. 1053 00:47:53,900 --> 00:47:55,760 But watch what happens now at top left. 1054 00:47:55,760 --> 00:48:00,080 When I type Enter, I now have two files in this hello folder. 1055 00:48:00,080 --> 00:48:03,500 And indeed, if I type ls now, I can see exactly the same. 1056 00:48:03,500 --> 00:48:06,160 So long story short, there's this whole list of commands, 1057 00:48:06,160 --> 00:48:09,663 and even more than these, that allow you to manipulate the underlying system 1058 00:48:09,663 --> 00:48:11,830 in exactly the same way that you and I have probably 1059 00:48:11,830 --> 00:48:14,800 done for years by using a mouse and pointing and clicking 1060 00:48:14,800 --> 00:48:15,660 and double-clicking. 1061 00:48:15,660 --> 00:48:18,160 But for now, let's undo all of this because I haven't really 1062 00:48:18,160 --> 00:48:19,510 written that many programs today. 1063 00:48:19,510 --> 00:48:21,218 And I'm going to keep things simple today 1064 00:48:21,218 --> 00:48:23,150 and keep everything in my same folder. 1065 00:48:23,150 --> 00:48:24,440 So let's undo all of this. 1066 00:48:24,440 --> 00:48:28,570 Let me go ahead and now remove backup.c because I don't particularly 1067 00:48:28,570 --> 00:48:29,570 care about that. 1068 00:48:29,570 --> 00:48:31,630 I'm going to be prompted to confirm as much. 1069 00:48:31,630 --> 00:48:36,280 Then let me go ahead and move hello.c out of this folder 1070 00:48:36,280 --> 00:48:38,750 and into the original folder. 1071 00:48:38,750 --> 00:48:40,510 And, conceptually, the original folder is 1072 00:48:40,510 --> 00:48:43,240 what we would call the parent folder, the folder that 1073 00:48:43,240 --> 00:48:45,200 contains this hello folder. 1074 00:48:45,200 --> 00:48:48,910 And the way you can specify the parent folder, like back up from whence 1075 00:48:48,910 --> 00:48:51,530 you came, is with dot dot. 1076 00:48:51,530 --> 00:48:55,840 So a single dot, as we've actually seen "./hello", "./a.out" 1077 00:48:55,840 --> 00:48:58,840 means execute a program in this directory, dot. 1078 00:48:58,840 --> 00:49:02,030 But dot dot refers to your parent directory. 1079 00:49:02,030 --> 00:49:05,110 So watch what happens at top left when I move this hello.c file out 1080 00:49:05,110 --> 00:49:06,140 of this folder. 1081 00:49:06,140 --> 00:49:08,350 It shifts a little bit to the left to indicate 1082 00:49:08,350 --> 00:49:10,160 that it's no longer in that folder. 1083 00:49:10,160 --> 00:49:13,240 I'm going to go ahead and type cd dot dot, which 1084 00:49:13,240 --> 00:49:15,370 will bring me back to my parent folder. 1085 00:49:15,370 --> 00:49:19,000 Or, even more useful, especially if you get confused or lost somewhere 1086 00:49:19,000 --> 00:49:21,160 within your folders, you can actually just type 1087 00:49:21,160 --> 00:49:25,870 cd and nothing, and that will whisk you back to that original folder 1088 00:49:25,870 --> 00:49:27,060 no matter where you are. 1089 00:49:27,060 --> 00:49:28,060 So it's a nice shortcut. 1090 00:49:28,060 --> 00:49:30,070 And it's a nice way of undoing any confusion 1091 00:49:30,070 --> 00:49:31,820 you might have caused for yourself. 1092 00:49:31,820 --> 00:49:37,150 Lastly, let's go ahead and get rid of the hello directory with rmdir hello, 1093 00:49:37,150 --> 00:49:37,940 Enter. 1094 00:49:37,940 --> 00:49:40,930 And that now disappears at top left, as well. 1095 00:49:40,930 --> 00:49:47,020 Now, what I was hinting at here whereby I had my hello.c file in a folder 1096 00:49:47,020 --> 00:49:50,260 and I was moving things around and renaming things and backing things up 1097 00:49:50,260 --> 00:49:52,930 isn't strictly necessary because there's actually other features 1098 00:49:52,930 --> 00:49:55,870 still inside of VS Code that you're welcome and encouraged to play around 1099 00:49:55,870 --> 00:49:56,370 with. 1100 00:49:56,370 --> 00:50:00,460 In fact, if I go to my so-called timeline at the bottom of my File 1101 00:50:00,460 --> 00:50:04,390 Explorer here, you can actually see that there's been automatic backups made 1102 00:50:04,390 --> 00:50:05,593 over time of this file. 1103 00:50:05,593 --> 00:50:07,760 So if you click, click, click through those backups, 1104 00:50:07,760 --> 00:50:10,240 you can actually see different versions of this same file 1105 00:50:10,240 --> 00:50:12,520 slightly in the past, which might save you 1106 00:50:12,520 --> 00:50:14,720 the trouble of having to manually create files. 1107 00:50:14,720 --> 00:50:18,080 And in fact, in the world of software development and industry, 1108 00:50:18,080 --> 00:50:21,430 there's actually standard tools, very similar in spirit 1109 00:50:21,430 --> 00:50:23,590 to what we've been using GitHub for, that 1110 00:50:23,590 --> 00:50:27,193 allow you manually to make different versions of your code 1111 00:50:27,193 --> 00:50:29,860 so that you can proactively keep track of all the changes you've 1112 00:50:29,860 --> 00:50:32,530 made without manually renaming things as you 1113 00:50:32,530 --> 00:50:36,130 might typically on your own Mac or PC. 1114 00:50:36,130 --> 00:50:37,900 All right, let me clear my terminal window 1115 00:50:37,900 --> 00:50:41,530 and ask if there are any questions. 1116 00:50:41,530 --> 00:50:44,556 Yes, over here. 1117 00:50:44,556 --> 00:50:49,546 AUDIENCE: What if you had a type other than [INAUDIBLE]? 1118 00:50:49,546 --> 00:50:52,058 1119 00:50:52,058 --> 00:50:53,850 DAVID J. MALAN: Yeah, really good question. 1120 00:50:53,850 --> 00:50:57,430 If we had something other than a string of text, if we had an integer, 1121 00:50:57,430 --> 00:50:58,680 would you still use percent s? 1122 00:50:58,680 --> 00:50:59,760 No, you would use something else. 1123 00:50:59,760 --> 00:51:01,640 And, indeed, percent i is what we're going to use. 1124 00:51:01,640 --> 00:51:04,670 And we're going to actually do that-- perfect segue-- to other types 1125 00:51:04,670 --> 00:51:06,090 that C actually has. 1126 00:51:06,090 --> 00:51:10,440 So up until now, we've been calling a string of text literally a string. 1127 00:51:10,440 --> 00:51:12,600 And this is common in many programming languages, 1128 00:51:12,600 --> 00:51:14,060 including Python and JavaScript. 1129 00:51:14,060 --> 00:51:16,830 "Strings" in the programming world just mean text, 1130 00:51:16,830 --> 00:51:19,290 whether it's zero or more characters thereof. 1131 00:51:19,290 --> 00:51:23,340 But C does have other data types, just a few of which we'll dabble with today 1132 00:51:23,340 --> 00:51:24,840 but you'll use more over time. 1133 00:51:24,840 --> 00:51:28,110 We've already seen string, for instance, which is indeed a string of text. 1134 00:51:28,110 --> 00:51:30,990 But let's focus, as well, on an integer. 1135 00:51:30,990 --> 00:51:32,720 As an aside, there's other types, too. 1136 00:51:32,720 --> 00:51:35,640 There's Boolean values, like true or false. 1137 00:51:35,640 --> 00:51:39,530 There's chars, which are single characters instead of full phrases 1138 00:51:39,530 --> 00:51:40,258 or sentences. 1139 00:51:40,258 --> 00:51:42,800 There's doubles and floats, which are real numbers, something 1140 00:51:42,800 --> 00:51:45,300 with a decimal point, the equivalent of fractions. 1141 00:51:45,300 --> 00:51:49,070 And there's longs, which are integers but longer integers, even 1142 00:51:49,070 --> 00:51:51,120 bigger integers than you might type by default. 1143 00:51:51,120 --> 00:51:55,200 So let's focus on an int because so many computer programs of course 1144 00:51:55,200 --> 00:51:57,520 manipulate numbers in some way. 1145 00:51:57,520 --> 00:51:59,110 So what can we do with this? 1146 00:51:59,110 --> 00:52:02,470 Well, if we want to be able to get an integer, lucky enough, 1147 00:52:02,470 --> 00:52:05,980 CS50's library comes not just with get_string but also get_int. 1148 00:52:05,980 --> 00:52:08,760 So that's going to be a third function we now use in C. 1149 00:52:08,760 --> 00:52:12,100 And we need to know what are generally called format codes. 1150 00:52:12,100 --> 00:52:16,030 So that placeholder I called before, percent s, is indeed for a string. 1151 00:52:16,030 --> 00:52:20,860 If we want to place an integer inside of something we're printing to the screen, 1152 00:52:20,860 --> 00:52:24,360 we are, in fact, going to use percent i instead. 1153 00:52:24,360 --> 00:52:28,350 So let's now actually use these building blocks, get_int and percent 1154 00:52:28,350 --> 00:52:31,623 i to actually get numbers in some way to solve a problem. 1155 00:52:31,623 --> 00:52:33,040 Well, what problem could we solve? 1156 00:52:33,040 --> 00:52:36,415 Let's introduce another concept from scratch and programming more generally 1157 00:52:36,415 --> 00:52:39,040 known as conditionals, like those proverbial forks in the road. 1158 00:52:39,040 --> 00:52:40,980 If something is true, do this. 1159 00:52:40,980 --> 00:52:42,700 Else, maybe do this other thing. 1160 00:52:42,700 --> 00:52:46,350 So in Scratch, we might have had a set of puzzle pieces that looked like this. 1161 00:52:46,350 --> 00:52:52,150 If x is less than y, then say, or have the cat say, x is less than y. 1162 00:52:52,150 --> 00:52:53,530 So sort of stupid program. 1163 00:52:53,530 --> 00:52:56,760 But it just demonstrates how we have two variables, x and y. 1164 00:52:56,760 --> 00:52:59,040 In the context of Scratch, we're comparing them 1165 00:52:59,040 --> 00:53:00,460 with a Boolean expression. 1166 00:53:00,460 --> 00:53:04,380 We're using a conditional to then conditionally say or not 1167 00:53:04,380 --> 00:53:08,340 say this phrase here, depending on whether this question has 1168 00:53:08,340 --> 00:53:11,380 an answer of true or false, yes or no. 1169 00:53:11,380 --> 00:53:14,035 In C, it doesn't look all that different. 1170 00:53:14,035 --> 00:53:15,160 It's a little more cryptic. 1171 00:53:15,160 --> 00:53:16,890 But you say literally "if." 1172 00:53:16,890 --> 00:53:20,080 You use parentheses, similar to functions. 1173 00:53:20,080 --> 00:53:23,370 But confusingly, by convention, you put a space after the word "if." 1174 00:53:23,370 --> 00:53:25,360 So you don't put spaces after function names. 1175 00:53:25,360 --> 00:53:27,780 You do put spaces after words like "if." 1176 00:53:27,780 --> 00:53:31,870 And you use the parentheses to conjure up this weird trapezoidal-like shape. 1177 00:53:31,870 --> 00:53:34,360 So there's no real keys that conjure that. 1178 00:53:34,360 --> 00:53:36,880 So C uses parentheses, like most languages. 1179 00:53:36,880 --> 00:53:39,850 And then there's these weird curly braces, which, at least in English, 1180 00:53:39,850 --> 00:53:41,410 we don't use all that often. 1181 00:53:41,410 --> 00:53:44,230 But they're there on your keyboard, English or otherwise. 1182 00:53:44,230 --> 00:53:48,040 And they essentially allow us to create this hugging shape to the puzzle piece. 1183 00:53:48,040 --> 00:53:51,330 Anything inside of those curly braces is going 1184 00:53:51,330 --> 00:53:55,350 to be equivalent to anything inside of this yellow hug that's sort 1185 00:53:55,350 --> 00:53:57,640 of grabbing one or more pieces inside. 1186 00:53:57,640 --> 00:53:58,780 So what do we put inside? 1187 00:53:58,780 --> 00:54:01,280 Well, this part is straightforward-- printf, quote, unquote, 1188 00:54:01,280 --> 00:54:04,540 "x is less than y" backslash n semicolon. 1189 00:54:04,540 --> 00:54:05,800 So nothing new here. 1190 00:54:05,800 --> 00:54:09,760 The only bit of new code is this if construct instead. 1191 00:54:09,760 --> 00:54:12,550 What if you have an if-else, so a two-way fork in the road? 1192 00:54:12,550 --> 00:54:14,350 This is what that looked like in Scratch. 1193 00:54:14,350 --> 00:54:17,370 Same question-- if x is less than y, then say x is less than y. 1194 00:54:17,370 --> 00:54:19,780 Else, say x is not less than y. 1195 00:54:19,780 --> 00:54:22,590 In C, the code is going to be set up initially 1196 00:54:22,590 --> 00:54:27,300 like this, so two sets of curly braces to represent this pair of yellow bars 1197 00:54:27,300 --> 00:54:28,860 and this pair of yellow bars. 1198 00:54:28,860 --> 00:54:31,330 And what's inside of them-- indented, no less, 1199 00:54:31,330 --> 00:54:34,200 just like our pseudocode last week-- is two printfs-- 1200 00:54:34,200 --> 00:54:37,330 x is less than y, x is not less than y. 1201 00:54:37,330 --> 00:54:38,110 So that's it. 1202 00:54:38,110 --> 00:54:41,135 So the only new stuff here really is now the else keyword, 1203 00:54:41,135 --> 00:54:43,260 which does not need parentheses because you're just 1204 00:54:43,260 --> 00:54:44,943 saying, else, do this other thing. 1205 00:54:44,943 --> 00:54:46,860 But what if it's a three-way fork in the road? 1206 00:54:46,860 --> 00:54:48,250 And we'll stop after that. 1207 00:54:48,250 --> 00:54:50,970 Here's a three-way fork in the road in Scratch. 1208 00:54:50,970 --> 00:54:53,820 If x is less than y, then say this. 1209 00:54:53,820 --> 00:54:57,430 Else, if x is greater than y, say this. 1210 00:54:57,430 --> 00:55:00,940 Else, if x equals y, then say this. 1211 00:55:00,940 --> 00:55:04,080 So this is a little more precise because now we're handling equality, not 1212 00:55:04,080 --> 00:55:06,360 just greater than or the opposite. 1213 00:55:06,360 --> 00:55:08,980 In C, it's going to look similar to before. 1214 00:55:08,980 --> 00:55:10,438 But we're adding this element here. 1215 00:55:10,438 --> 00:55:13,188 And at first glance, especially if you've never programmed before, 1216 00:55:13,188 --> 00:55:15,160 it looks like I'm an idiot and I made a typo. 1217 00:55:15,160 --> 00:55:17,510 What looks wrong? 1218 00:55:17,510 --> 00:55:20,040 There's two equal signs-- not a typo. 1219 00:55:20,040 --> 00:55:23,000 So it turns out, recall from earlier, when 1220 00:55:23,000 --> 00:55:25,410 we use the equal sign the first time around, 1221 00:55:25,410 --> 00:55:28,760 we used it in the context of getting a return value back from a function, 1222 00:55:28,760 --> 00:55:32,970 like the get_string function handed me back the user's answer. 1223 00:55:32,970 --> 00:55:36,180 So unfortunately, because humans decades ago decided, hey, 1224 00:55:36,180 --> 00:55:39,410 let's use the equal sign to assign a return 1225 00:55:39,410 --> 00:55:43,410 value from the right-hand side of a line of code to the left-hand side, 1226 00:55:43,410 --> 00:55:46,260 we sort of painted ourselves into a corner and like, oh, shoot, 1227 00:55:46,260 --> 00:55:49,280 what do we do when we actually want to test for equality 1228 00:55:49,280 --> 00:55:51,150 of two values on the left and right? 1229 00:55:51,150 --> 00:55:55,500 So what most languages, including C, do, is use double equal signs. 1230 00:55:55,500 --> 00:55:57,900 So you say double equals or equals equals or whatever. 1231 00:55:57,900 --> 00:56:00,210 But it is, in fact, syntactically correct. 1232 00:56:00,210 --> 00:56:03,210 What's inside of these three sets of curly braces? 1233 00:56:03,210 --> 00:56:07,220 Same idea-- printf, printf, printf based on what English phrase 1234 00:56:07,220 --> 00:56:09,240 you want to print out. 1235 00:56:09,240 --> 00:56:12,580 So this code, both in Scratch and C, I'll claim is correct. 1236 00:56:12,580 --> 00:56:16,290 It won't run because we still need the other stuff, the equivalent of the when 1237 00:56:16,290 --> 00:56:17,530 green, flag clicked. 1238 00:56:17,530 --> 00:56:19,690 But out of context, this code is correct. 1239 00:56:19,690 --> 00:56:22,522 But there's a subtle weakness in design. 1240 00:56:22,522 --> 00:56:24,730 And we'll talk a lot about this this week and beyond. 1241 00:56:24,730 --> 00:56:27,400 "Correctness" just means the code does what it's supposed to do. 1242 00:56:27,400 --> 00:56:29,430 Design is more subjective. 1243 00:56:29,430 --> 00:56:33,330 How well have you written your argument in an English paper, how well 1244 00:56:33,330 --> 00:56:36,030 have you written your code, is design. 1245 00:56:36,030 --> 00:56:40,020 This code is not designed as well as it could be because I'm 1246 00:56:40,020 --> 00:56:42,430 doing more work than I need to. 1247 00:56:42,430 --> 00:56:43,540 Yeah, in the back. 1248 00:56:43,540 --> 00:56:45,540 AUDIENCE: You don't need the [INAUDIBLE]. 1249 00:56:45,540 --> 00:56:47,915 DAVID J. MALAN: Yeah, I don't need the x equals equals y. 1250 00:56:47,915 --> 00:56:48,790 But why, logically? 1251 00:56:48,790 --> 00:56:53,417 AUDIENCE: Because [INAUDIBLE] [? there's no need. ?] [INAUDIBLE]. 1252 00:56:53,417 --> 00:56:55,500 DAVID J. MALAN: Exactly, that's just a math thing. 1253 00:56:55,500 --> 00:56:58,500 Either x is less than y, or it's greater than y. 1254 00:56:58,500 --> 00:57:02,110 Or the third and final option is they must be equal. 1255 00:57:02,110 --> 00:57:07,020 So it's subtle, but why would you bother wasting time writing a line of code 1256 00:57:07,020 --> 00:57:09,552 and expecting the computer to run a line of code that 1257 00:57:09,552 --> 00:57:11,760 is just going to answer a question that logically you 1258 00:57:11,760 --> 00:57:13,480 could have concluded already? 1259 00:57:13,480 --> 00:57:18,970 Because if x is not less than y and x is not greater than y, then, my god, 1260 00:57:18,970 --> 00:57:22,710 just print out x is equal to y because you know, at that point, logically 1261 00:57:22,710 --> 00:57:23,470 it's true. 1262 00:57:23,470 --> 00:57:25,620 You don't need to waste your time or the computer's 1263 00:57:25,620 --> 00:57:28,830 asking a third question unnecessarily. 1264 00:57:28,830 --> 00:57:30,415 In reality, it's not a huge deal. 1265 00:57:30,415 --> 00:57:32,790 No one's going to notice in the real world on a Mac or PC 1266 00:57:32,790 --> 00:57:34,332 that there's this extra line of code. 1267 00:57:34,332 --> 00:57:35,650 But it's a bad habit. 1268 00:57:35,650 --> 00:57:36,460 Keep it simple. 1269 00:57:36,460 --> 00:57:39,852 Don't write code that doesn't need to be there if, logically, you 1270 00:57:39,852 --> 00:57:40,810 can conclude otherwise. 1271 00:57:40,810 --> 00:57:44,290 So in fact, let's clean this up both in Scratch and in C. I can tighten this up, 1272 00:57:44,290 --> 00:57:47,800 so to speak, use less code here, less code here. 1273 00:57:47,800 --> 00:57:51,240 And honestly, if only statistically, the less code I write, the less likely 1274 00:57:51,240 --> 00:57:53,080 I am going to make mistakes. 1275 00:57:53,080 --> 00:57:56,380 So that, too, is probably a net positive overall. 1276 00:57:56,380 --> 00:57:59,900 Writing less code is generally better than writing more code, 1277 00:57:59,900 --> 00:58:02,620 not unlike English essays too, perhaps. 1278 00:58:02,620 --> 00:58:08,860 All right, questions about this feature of C, conditionals and this syntax? 1279 00:58:08,860 --> 00:58:09,856 Yeah? 1280 00:58:09,856 --> 00:58:12,648 AUDIENCE: [INAUDIBLE] 1281 00:58:12,648 --> 00:58:14,440 DAVID J. MALAN: Oh, a really good question. 1282 00:58:14,440 --> 00:58:15,523 And, yes, jumping the gun. 1283 00:58:15,523 --> 00:58:18,540 There are alternative ways to solve problems like these. 1284 00:58:18,540 --> 00:58:21,893 And the question was, to summarize, when to use "if, else, if, else" 1285 00:58:21,893 --> 00:58:23,560 versus what's called a switch statement. 1286 00:58:23,560 --> 00:58:24,700 More on those another time. 1287 00:58:24,700 --> 00:58:27,575 But this is going to be true, in general, in programming, not just C, 1288 00:58:27,575 --> 00:58:29,350 not just in Scratch, but every language. 1289 00:58:29,350 --> 00:58:34,020 There are going to be several, dozens, hundreds, an infinite number of ways 1290 00:58:34,020 --> 00:58:34,950 to solve problems. 1291 00:58:34,950 --> 00:58:36,700 Among the things we're going to teach you, 1292 00:58:36,700 --> 00:58:40,000 though, is indeed how to do things well or better than you might otherwise. 1293 00:58:40,000 --> 00:58:41,792 And we're going to introduce you eventually 1294 00:58:41,792 --> 00:58:46,800 to another feature of the language that can even simplify this code, too. 1295 00:58:46,800 --> 00:58:49,030 So for now, let's actually use this then. 1296 00:58:49,030 --> 00:58:51,640 So let me go over to VS Code again. 1297 00:58:51,640 --> 00:58:55,780 I'm going to go ahead now and clear my terminal window down here. 1298 00:58:55,780 --> 00:58:58,890 I'm going to go ahead and close the hello.c tab just so that it-- 1299 00:58:58,890 --> 00:59:00,390 we're going to create a new program. 1300 00:59:00,390 --> 00:59:03,988 And let's just do something a little simple using some operator, so to speak. 1301 00:59:03,988 --> 00:59:05,530 And I haven't used this word by name. 1302 00:59:05,530 --> 00:59:07,680 But it turns out that there's lots of operators 1303 00:59:07,680 --> 00:59:10,440 that come with C, just like a lot of operators that 1304 00:59:10,440 --> 00:59:14,890 came with Scratch, for doing assignment or less than or less than 1305 00:59:14,890 --> 00:59:17,440 or equal to, greater than, greater than or equal to, 1306 00:59:17,440 --> 00:59:19,653 actually equal to, not equal to. 1307 00:59:19,653 --> 00:59:21,320 Now, some of these are a little cryptic. 1308 00:59:21,320 --> 00:59:25,550 But there's no easily-found key on your US English keyboard, 1309 00:59:25,550 --> 00:59:28,610 at least, where you can do less than or equals or greater than or equals. 1310 00:59:28,610 --> 00:59:30,940 So what most programming languages do is you 1311 00:59:30,940 --> 00:59:34,330 don't use a special symbol where there's an angled bracket and then 1312 00:59:34,330 --> 00:59:35,420 a line below it. 1313 00:59:35,420 --> 00:59:37,100 You actually just use two characters. 1314 00:59:37,100 --> 00:59:39,910 So greater than or equal is literally this, this. 1315 00:59:39,910 --> 00:59:41,710 Less than or equal is literally this, this. 1316 00:59:41,710 --> 00:59:44,260 We already saw that equals is this, this. 1317 00:59:44,260 --> 00:59:47,283 And not equals is to use an exclamation point. 1318 00:59:47,283 --> 00:59:48,950 So this, too, is a thing in programming. 1319 00:59:48,950 --> 00:59:53,560 Using the exclamation point, pronounced bang, is how you invert, 1320 00:59:53,560 --> 00:59:55,040 logically, certain things. 1321 00:59:55,040 --> 01:00:00,320 So "bang equals" or "not equals" is how you would express exactly that idea. 1322 01:00:00,320 --> 01:00:02,920 It's just a symbol on the keyboard that some human decided, 1323 01:00:02,920 --> 01:00:05,270 let's use this one to invert the idea. 1324 01:00:05,270 --> 01:00:08,650 But we're going to need one other thing for this program, specifically 1325 01:00:08,650 --> 01:00:11,770 variables, which we've used already because, in Scratch, we 1326 01:00:11,770 --> 01:00:12,920 got one for free. 1327 01:00:12,920 --> 01:00:17,600 We had that answer variable that stored the return value of the ask block. 1328 01:00:17,600 --> 01:00:19,750 But let's consider, in general, how you can-- 1329 01:00:19,750 --> 01:00:21,680 and probably did for problem set 0-- 1330 01:00:21,680 --> 01:00:24,430 use a variable of your own, like keeping track of a counter 1331 01:00:24,430 --> 01:00:25,750 or a score or the like. 1332 01:00:25,750 --> 01:00:28,490 In Scratch, if you want to create a variable called counter, 1333 01:00:28,490 --> 01:00:31,330 you can set it equal to some initial value, like 0. 1334 01:00:31,330 --> 01:00:34,100 In C, that code is going to look similar. 1335 01:00:34,100 --> 01:00:36,100 You literally just write whatever name you 1336 01:00:36,100 --> 01:00:38,920 want to give the variable, then an equal sign, and then 1337 01:00:38,920 --> 01:00:41,210 the value you want to give that variable. 1338 01:00:41,210 --> 01:00:44,390 And because the equal sign is the assignment operator, 1339 01:00:44,390 --> 01:00:49,190 it will behave essentially right to left and copy the 0 into counter. 1340 01:00:49,190 --> 01:00:52,520 But this isn't enough for C. Remember that you, the programmer, 1341 01:00:52,520 --> 01:00:54,950 have to tell the computer, is this indeed a number? 1342 01:00:54,950 --> 01:00:55,700 Is it a letter? 1343 01:00:55,700 --> 01:00:56,480 Is it an image? 1344 01:00:56,480 --> 01:00:57,260 Is it a sound? 1345 01:00:57,260 --> 01:01:00,050 You have to tell the computer that this is an integer, 1346 01:01:00,050 --> 01:01:02,990 otherwise written as "int" for short in C. 1347 01:01:02,990 --> 01:01:08,210 But there's one other stupid detail that's missing, which is now-- 1348 01:01:08,210 --> 01:01:10,320 semicolon to finish the thought here. 1349 01:01:10,320 --> 01:01:13,800 But this then is equivalent to this in Scratch. 1350 01:01:13,800 --> 01:01:14,600 Let's do another. 1351 01:01:14,600 --> 01:01:18,780 In Scratch, if you wanted to increment the counter, that is add 1 to it, 1352 01:01:18,780 --> 01:01:20,960 you could literally use this puzzle piece here 1353 01:01:20,960 --> 01:01:22,640 and specify you want to add 1. 1354 01:01:22,640 --> 01:01:24,580 In C, it's going to look like this-- 1355 01:01:24,580 --> 01:01:27,090 counter equals counter plus 1 semicolon. 1356 01:01:27,090 --> 01:01:29,600 Now, at a glance, this seems like a paradox of sorts. 1357 01:01:29,600 --> 01:01:33,560 How can counter equal counter plus 1? 1358 01:01:33,560 --> 01:01:35,460 I can't make that math expression true. 1359 01:01:35,460 --> 01:01:37,140 But it's not math in this case. 1360 01:01:37,140 --> 01:01:38,940 The single equal sign is assignment. 1361 01:01:38,940 --> 01:01:43,190 So this means take the current value of counter, whatever it is, add 1 to it, 1362 01:01:43,190 --> 01:01:47,730 and then copy that value from right to left into the same variable, 1363 01:01:47,730 --> 01:01:51,080 thereby changing it from 1 to 2, 2 to 3, and so forth. 1364 01:01:51,080 --> 01:01:53,240 This, though, is so common in programming, 1365 01:01:53,240 --> 01:01:56,480 to be able to increment or even decrement numbers by one or two 1366 01:01:56,480 --> 01:01:58,800 or more, is that you can tighten it like this. 1367 01:01:58,800 --> 01:02:01,460 This is the exact same thing-- a little faster to type, 1368 01:02:01,460 --> 01:02:04,220 saves you keystrokes, maybe less chance for error. 1369 01:02:04,220 --> 01:02:08,050 Counter plus equals 1 semicolon is the exact same idea. 1370 01:02:08,050 --> 01:02:13,020 Better still, this is so common in C and C++ and Java that there's a third way 1371 01:02:13,020 --> 01:02:16,600 to do this, to my comment earlier about solving problems in different ways. 1372 01:02:16,600 --> 01:02:21,420 The most canonical, the most popular way is probably just to say counter++ 1373 01:02:21,420 --> 01:02:26,170 semicolon, which literally, automatically, adds 1 to that value. 1374 01:02:26,170 --> 01:02:27,190 It only works for 1. 1375 01:02:27,190 --> 01:02:29,317 If you want to do 2 or 3 or some other increment, 1376 01:02:29,317 --> 01:02:31,150 you have to use one of the other approaches. 1377 01:02:31,150 --> 01:02:33,460 But this simply does the same thing as this. 1378 01:02:33,460 --> 01:02:35,680 And if you want to invert it to negative 1, 1379 01:02:35,680 --> 01:02:38,740 you change the plus plus to a minus minus instead. 1380 01:02:38,740 --> 01:02:41,503 So again, just little things that we'll see and pick up over time. 1381 01:02:41,503 --> 01:02:43,920 Invariably, you'll have to look them up or check the notes 1382 01:02:43,920 --> 01:02:45,378 or look back at the lecture slides. 1383 01:02:45,378 --> 01:02:50,330 But in time, this will get familiar if you are not already familiar. 1384 01:02:50,330 --> 01:02:55,090 So let's consider just logically how we might implement this in code. 1385 01:02:55,090 --> 01:02:56,520 Let's go back to VS Code here. 1386 01:02:56,520 --> 01:02:58,770 And let me propose that we create a program called 1387 01:02:58,770 --> 01:03:03,340 compare.c whose purpose in life is just to compare a couple of values. 1388 01:03:03,340 --> 01:03:06,720 I'm going to go ahead and proactively, based on the previous chat, 1389 01:03:06,720 --> 01:03:09,460 include CS50's library from the get go. 1390 01:03:09,460 --> 01:03:12,360 I'm going to include standard io.h from the get go. 1391 01:03:12,360 --> 01:03:15,010 So I can use get_int and printf respectively. 1392 01:03:15,010 --> 01:03:17,670 I'm going to just, on faith, type int main(void). 1393 01:03:17,670 --> 01:03:20,080 And today, we won't explain what that does. 1394 01:03:20,080 --> 01:03:21,100 More on that to come. 1395 01:03:21,100 --> 01:03:24,130 For now, just assume it's like, when green, flag clicked. 1396 01:03:24,130 --> 01:03:26,230 But in this program, let's do a couple of things. 1397 01:03:26,230 --> 01:03:31,490 Let's declare an integer called x and assign it the return value of get_int. 1398 01:03:31,490 --> 01:03:32,740 And let's just keep it simple. 1399 01:03:32,740 --> 01:03:36,390 Let's ask the user not what's their name, but "What's x?," question mark, 1400 01:03:36,390 --> 01:03:37,540 semicolon. 1401 01:03:37,540 --> 01:03:41,130 Now, so that we have something to compare, let's do it again but with y. 1402 01:03:41,130 --> 01:03:46,188 int y equals get_int, quote, unquote, "What's y?", question mark. 1403 01:03:46,188 --> 01:03:47,980 And I'm leaving again a space just visually 1404 01:03:47,980 --> 01:03:51,750 so the cursor nudges over a bit, followed by a semicolon. 1405 01:03:51,750 --> 01:03:54,270 At this point in the story, my users will 1406 01:03:54,270 --> 01:03:56,590 be prompted for x and y respectively. 1407 01:03:56,590 --> 01:03:58,270 Let's do something with those values. 1408 01:03:58,270 --> 01:04:05,110 How about if x is less than y, then go ahead and print out, quote, unquote, 1409 01:04:05,110 --> 01:04:10,620 "x is less than y" backslash n, close quote, semicolon. 1410 01:04:10,620 --> 01:04:13,840 All right, and let me hide my terminal window for just a moment. 1411 01:04:13,840 --> 01:04:16,450 This is a 13-line program at the moment. 1412 01:04:16,450 --> 01:04:19,510 But really, it's five or six interesting lines. 1413 01:04:19,510 --> 01:04:22,570 The rest has been copy/paste from previous programs. 1414 01:04:22,570 --> 01:04:24,040 Notice a few details. 1415 01:04:24,040 --> 01:04:27,290 One, I've indeed used my curly braces here. 1416 01:04:27,290 --> 01:04:29,040 And notice, if you highlight lines, you'll 1417 01:04:29,040 --> 01:04:31,665 actually see little dots that can help you make sure, oh, there 1418 01:04:31,665 --> 01:04:33,430 are indeed four spaces there. 1419 01:04:33,430 --> 01:04:36,520 I've been indenting just like we did last week with pseudocode. 1420 01:04:36,520 --> 01:04:38,950 Strictly speaking, it's not necessary. 1421 01:04:38,950 --> 01:04:41,850 But it's going to be way easier to read your code 1422 01:04:41,850 --> 01:04:45,870 if you do at all of this whitespace, so to speak, than if you write 1423 01:04:45,870 --> 01:04:49,470 and then submit to us, as homework, a program that looks sort of godawful 1424 01:04:49,470 --> 01:04:53,502 like this, which is going to make it much, much harder for the human 1425 01:04:53,502 --> 01:04:56,710 to read it, for you to read it, your colleagues in the real world to read it. 1426 01:04:56,710 --> 01:04:58,740 But the computer is actually not going to care. 1427 01:04:58,740 --> 01:05:03,360 In fact, as an aside, one of the tools we have built into VS Code for CS50 1428 01:05:03,360 --> 01:05:05,800 is this button at top called style50. 1429 01:05:05,800 --> 01:05:08,250 This is a program that we indeed wrote that will give you 1430 01:05:08,250 --> 01:05:11,260 suggestions on how to improve the style of your code 1431 01:05:11,260 --> 01:05:15,070 so it looks like the right way that programmers would generally write it. 1432 01:05:15,070 --> 01:05:18,910 As an aside, the computer world is fraught with religious debate, 1433 01:05:18,910 --> 01:05:21,190 so to speak, as to what code should look like. 1434 01:05:21,190 --> 01:05:23,940 And people in the real world will have really stupid arguments 1435 01:05:23,940 --> 01:05:26,850 over how many spaces to use for indentation 1436 01:05:26,850 --> 01:05:29,200 and what lines code should go on and so forth. 1437 01:05:29,200 --> 01:05:31,330 Generally, in the real world or in a class, 1438 01:05:31,330 --> 01:05:34,620 there's an official style guide that someone autocratically 1439 01:05:34,620 --> 01:05:36,390 declares this is how everyone should write 1440 01:05:36,390 --> 01:05:40,630 their code so that just everyone's code in the company or course looks the same. 1441 01:05:40,630 --> 01:05:44,560 But you'll find, in the real world, reasonable people will disagree. 1442 01:05:44,560 --> 01:05:47,340 When you click style50, it will be formatted as we 1443 01:05:47,340 --> 01:05:49,120 ourselves recommend in CS50. 1444 01:05:49,120 --> 01:05:50,820 And in fact, let me zoom out here. 1445 01:05:50,820 --> 01:05:53,110 And this looks a little cryptic at first glance. 1446 01:05:53,110 --> 01:05:55,500 But on the left is the code that I just wrote and made 1447 01:05:55,500 --> 01:05:57,750 a mess of by deleting all that whitespace. 1448 01:05:57,750 --> 01:06:03,070 On the right is the way the code should look if it is well styled. 1449 01:06:03,070 --> 01:06:05,640 So whereas correctness is all about, does the code work 1450 01:06:05,640 --> 01:06:08,160 the way it's supposed to, design is about, 1451 01:06:08,160 --> 01:06:10,260 how well have you written that code? 1452 01:06:10,260 --> 01:06:11,250 Is it efficient? 1453 01:06:11,250 --> 01:06:12,570 Did you make good decisions? 1454 01:06:12,570 --> 01:06:14,540 Style is purely aesthetic. 1455 01:06:14,540 --> 01:06:15,600 Is it readable? 1456 01:06:15,600 --> 01:06:16,950 Does it follow a standard? 1457 01:06:16,950 --> 01:06:20,000 Can another human easily skim it top to bottom, left to right, 1458 01:06:20,000 --> 01:06:21,570 and understand what's going on? 1459 01:06:21,570 --> 01:06:25,620 So these green highlights are saying, please add white space there. 1460 01:06:25,620 --> 01:06:28,310 And so I can actually change my code to match. 1461 01:06:28,310 --> 01:06:30,455 On the left-hand side here, if I realize, 1462 01:06:30,455 --> 01:06:33,890 oh, my code is looking pretty ugly, watch on line 6 at left. 1463 01:06:33,890 --> 01:06:35,870 As I hit the space bar two-- 1464 01:06:35,870 --> 01:06:40,670 oops, sorry-- on the left, 1, 2, 3, 4, notice 1465 01:06:40,670 --> 01:06:44,090 that the right-hand side is starting to be happier with my code 1466 01:06:44,090 --> 01:06:46,190 by getting rid of the green indicators. 1467 01:06:46,190 --> 01:06:48,840 And I can do 1, 2, 3, 4. 1468 01:06:48,840 --> 01:06:49,730 That fixed that. 1469 01:06:49,730 --> 01:06:52,380 Over here, I can do 1, 2, 3, 4. 1470 01:06:52,380 --> 01:06:56,563 I can move this onto its own line by hitting Enter. 1471 01:06:56,563 --> 01:06:58,730 And you know what, if it's taking too long, once you 1472 01:06:58,730 --> 01:07:01,105 get into the habit of things, you can just Apply Changes. 1473 01:07:01,105 --> 01:07:03,540 It will give you the suggestions automatically. 1474 01:07:03,540 --> 01:07:04,950 And we're done and on our way. 1475 01:07:04,950 --> 01:07:09,300 But for practice's sake, I would get into the habit of doing things manually 1476 01:07:09,300 --> 01:07:11,620 until it gets boring and tedious, at which point, 1477 01:07:11,620 --> 01:07:14,470 you might as well automate the process with a single click. 1478 01:07:14,470 --> 01:07:16,690 All right, so let's actually run this code. 1479 01:07:16,690 --> 01:07:19,830 I'm going to go ahead and open my terminal window again and clear it 1480 01:07:19,830 --> 01:07:20,860 for clarity. 1481 01:07:20,860 --> 01:07:25,570 I'm going to run make compare and hope that I didn't make any mistakes. 1482 01:07:25,570 --> 01:07:27,030 I don't seem to have yet-- 1483 01:07:27,030 --> 01:07:28,540 "./compare." 1484 01:07:28,540 --> 01:07:30,220 And now notice I'm prompted for x. 1485 01:07:30,220 --> 01:07:31,200 Let's type 1. 1486 01:07:31,200 --> 01:07:33,120 For y, let's type 2. 1487 01:07:33,120 --> 01:07:33,840 Enter. 1488 01:07:33,840 --> 01:07:35,857 And x is less than y. 1489 01:07:35,857 --> 01:07:37,690 Let's do a little sanity check, so to speak. 1490 01:07:37,690 --> 01:07:39,910 Let's rerun it-- c 1491 01:07:39,910 --> 01:07:40,630 What's x? 1492 01:07:40,630 --> 01:07:43,900 Let's do 2 this time; 1 for y. 1493 01:07:43,900 --> 01:07:45,452 And this time, it said nothing. 1494 01:07:45,452 --> 01:07:47,160 So that's to be expected because I didn't 1495 01:07:47,160 --> 01:07:49,540 have a two-way or a three-way fork in the road. 1496 01:07:49,540 --> 01:07:51,810 The only time this code should say anything 1497 01:07:51,810 --> 01:07:55,162 is if, indeed, x is less than y. 1498 01:07:55,162 --> 01:07:58,120 So for those of you who might be more visual when it comes to learning, 1499 01:07:58,120 --> 01:08:01,120 here's a flow chart that represents this same exact program. 1500 01:08:01,120 --> 01:08:04,870 If you read it top to bottom, you start the program with "./compare." 1501 01:08:04,870 --> 01:08:07,240 You are then prompted for x and y. 1502 01:08:07,240 --> 01:08:09,452 And you're asked this, is x less than y? 1503 01:08:09,452 --> 01:08:11,160 And the fact that this is a diamond means 1504 01:08:11,160 --> 01:08:15,430 this is a Boolean expression, a question that the computer is asking itself. 1505 01:08:15,430 --> 01:08:19,950 If the answer to that question is true, then, quote, unquote, "x is less than y" 1506 01:08:19,950 --> 01:08:20,580 gets printed. 1507 01:08:20,580 --> 01:08:22,229 And the program stops. 1508 01:08:22,229 --> 01:08:26,710 Else, if x is not less than y, as in the second scenario, 1509 01:08:26,710 --> 01:08:29,439 the answer is, of course, false, and nothing more happens. 1510 01:08:29,439 --> 01:08:32,710 But we can build out this tree, so to speak, by adding a bit more code. 1511 01:08:32,710 --> 01:08:35,229 So let's make it look like the second Scratch example. 1512 01:08:35,229 --> 01:08:41,200 If I go back here, it's not hard to just say, else, if x is not less than y, 1513 01:08:41,200 --> 01:08:42,180 let's say that. 1514 01:08:42,180 --> 01:08:46,840 "x is not less than y" backslash n, close quote, semicolon. 1515 01:08:46,840 --> 01:08:50,020 Let me now go ahead and rerun make compare. 1516 01:08:50,020 --> 01:08:50,939 Enter. 1517 01:08:50,939 --> 01:08:52,675 "./compare," Enter. 1518 01:08:52,675 --> 01:08:54,300 And again, I'll do the second example-- 1519 01:08:54,300 --> 01:08:57,160 2, which is bigger, and 1, which is smaller. 1520 01:08:57,160 --> 01:09:01,029 And this time, I will see x is not less than y. 1521 01:09:01,029 --> 01:09:05,260 If, then, we were to look not at this flow chart but a slightly bigger one, 1522 01:09:05,260 --> 01:09:06,798 you can visualize it this way. 1523 01:09:06,798 --> 01:09:09,340 Everything in the left-hand side of this picture is the same. 1524 01:09:09,340 --> 01:09:13,899 But if it's not true that x is less than y, the answer is thus false. 1525 01:09:13,899 --> 01:09:16,899 This time we say, quote, unquote, "x is not less than y." 1526 01:09:16,899 --> 01:09:20,439 And we can do this obviously one final time just to bring the point home. 1527 01:09:20,439 --> 01:09:26,229 If I go back to my code and I even more pedantically compare these three values, 1528 01:09:26,229 --> 01:09:27,700 let me go ahead and do this. 1529 01:09:27,700 --> 01:09:31,630 So, else-- hm, I don't want an else actually. 1530 01:09:31,630 --> 01:09:34,560 So let's go ahead and do this-- 1531 01:09:34,560 --> 01:09:42,670 else if x is greater than y, let's then say "x is greater than y" in English. 1532 01:09:42,670 --> 01:09:49,560 And then, finally, have an else that says printf "x is equal to y," 1533 01:09:49,560 --> 01:09:53,162 close quote, or rather backslash n, close quote, semicolon. 1534 01:09:53,162 --> 01:09:55,120 So just to show this all on the screen at once, 1535 01:09:55,120 --> 01:09:57,760 this is identical Now to that Scratch version. 1536 01:09:57,760 --> 01:10:00,870 It's well designed because I'm not asking the equals equals question 1537 01:10:00,870 --> 01:10:02,260 unnecessarily. 1538 01:10:02,260 --> 01:10:07,210 If I go back to my terminal window here, clear the screen, run make compare, 1539 01:10:07,210 --> 01:10:10,150 Enter, and then "./compare" again. 1540 01:10:10,150 --> 01:10:10,920 Enter. 1541 01:10:10,920 --> 01:10:11,680 "What's x?" 1542 01:10:11,680 --> 01:10:12,700 Let's do 1. 1543 01:10:12,700 --> 01:10:14,950 Let's do 2. "x is less than y." 1544 01:10:14,950 --> 01:10:16,950 Let's run it again-- "./compare." 1545 01:10:16,950 --> 01:10:19,800 "What's"-- 2 and 1. 1546 01:10:19,800 --> 01:10:21,220 "x is greater than y." 1547 01:10:21,220 --> 01:10:22,930 One more time-- "./compare." 1548 01:10:22,930 --> 01:10:23,480 "What's x?" 1549 01:10:23,480 --> 01:10:23,980 1. 1550 01:10:23,980 --> 01:10:24,703 "What's y?" 1551 01:10:24,703 --> 01:10:25,510 1. 1552 01:10:25,510 --> 01:10:28,420 And now x is equal to y. 1553 01:10:28,420 --> 01:10:30,750 As an aside, if I seem to be typing fairly fast, 1554 01:10:30,750 --> 01:10:32,500 you can actually cheat with your keyboard. 1555 01:10:32,500 --> 01:10:36,210 If you go up or down, you can scroll through all of the past commands 1556 01:10:36,210 --> 01:10:37,030 that you've typed. 1557 01:10:37,030 --> 01:10:38,920 So it's actually very useful. 1558 01:10:38,920 --> 01:10:42,510 If you just hit up, it will pre-write the previous command 1559 01:10:42,510 --> 01:10:44,730 for you, at which point you can just say Enter. 1560 01:10:44,730 --> 01:10:48,490 Or there's other fancy features built into this programming environment. 1561 01:10:48,490 --> 01:10:52,418 If you do dot slash C-O-M and then get bored 1562 01:10:52,418 --> 01:10:54,210 with typing out the whole English word, you 1563 01:10:54,210 --> 01:10:57,300 can hit Tab for tab completion like in a web browser. 1564 01:10:57,300 --> 01:10:59,520 And it, too, will autocomplete if it finds 1565 01:10:59,520 --> 01:11:01,990 a file that starts with those letters. 1566 01:11:01,990 --> 01:11:04,290 So little efficiencies here. 1567 01:11:04,290 --> 01:11:07,280 Questions then on the code here? 1568 01:11:07,280 --> 01:11:07,780 Yeah? 1569 01:11:07,780 --> 01:11:09,250 AUDIENCE: I have a question about libraries. 1570 01:11:09,250 --> 01:11:09,615 DAVID J. MALAN: Sure. 1571 01:11:09,615 --> 01:11:11,407 AUDIENCE: [INAUDIBLE] is there any downside 1572 01:11:11,407 --> 01:11:13,200 to putting in all the libraries? 1573 01:11:13,200 --> 01:11:13,960 DAVID J. MALAN: A good question. 1574 01:11:13,960 --> 01:11:16,502 Is there any downside to just putting in all of the libraries 1575 01:11:16,502 --> 01:11:18,830 like we saw in the manual pages a moment ago? 1576 01:11:18,830 --> 01:11:19,620 Performance. 1577 01:11:19,620 --> 01:11:23,380 So generally speaking, C is meant to be a very efficient language, 1578 01:11:23,380 --> 01:11:25,330 so much so that, even though it's decades old, 1579 01:11:25,330 --> 01:11:28,870 still used omnipresently nowadays because it's so fast. 1580 01:11:28,870 --> 01:11:30,490 It therefore minimizes time. 1581 01:11:30,490 --> 01:11:31,720 It minimizes energy use. 1582 01:11:31,720 --> 01:11:33,400 So it's still being used heavily. 1583 01:11:33,400 --> 01:11:36,940 You would slow things down if you told the compiler, by the way, 1584 01:11:36,940 --> 01:11:40,130 give me all of these other functions that I'm never going to use. 1585 01:11:40,130 --> 01:11:43,000 So in short, just don't do that because it's unnecessary. 1586 01:11:43,000 --> 01:11:44,200 But a good question. 1587 01:11:44,200 --> 01:11:48,210 Other questions on what we've done here? 1588 01:11:48,210 --> 01:11:48,890 Yeah, in front. 1589 01:11:48,890 --> 01:11:51,920 AUDIENCE: [? Just to follow up, ?] [? why is it C? ?] 1590 01:11:51,920 --> 01:11:54,290 DAVID J. MALAN: What is it-- oh, why is C faster? 1591 01:11:54,290 --> 01:11:56,180 Why is C faster than other languages, let 1592 01:11:56,180 --> 01:11:58,550 me answer that in more detail in week 6, when 1593 01:11:58,550 --> 01:12:02,750 you'll see how much easier it is to write code in other languages 1594 01:12:02,750 --> 01:12:05,430 because someone else is doing a lot of the work for you. 1595 01:12:05,430 --> 01:12:08,240 So as an introductory course, we're teaching you bottom up, 1596 01:12:08,240 --> 01:12:09,600 like how do you write code? 1597 01:12:09,600 --> 01:12:11,340 How does the computer understand code? 1598 01:12:11,340 --> 01:12:13,680 Eventually, this kind of stuff, certainly after five, 1599 01:12:13,680 --> 01:12:16,950 six weeks of this, it's going to get tedious doing some of these things. 1600 01:12:16,950 --> 01:12:19,985 We're going to switch to another language that takes away the tedium 1601 01:12:19,985 --> 01:12:21,860 and allows us to really focus on the problems 1602 01:12:21,860 --> 01:12:25,020 to be solved once we've graduated to that point. 1603 01:12:25,020 --> 01:12:25,864 Yeah? 1604 01:12:25,864 --> 01:12:28,375 AUDIENCE: [INAUDIBLE] shortcuts? 1605 01:12:28,375 --> 01:12:29,250 DAVID J. MALAN: Sure. 1606 01:12:29,250 --> 01:12:31,960 To repeat the keyboard shortcuts, you can just go up, up, up, up, up. 1607 01:12:31,960 --> 01:12:34,290 And that will go through all of your previous commands, at which point 1608 01:12:34,290 --> 01:12:35,310 you can just hit Enter. 1609 01:12:35,310 --> 01:12:37,180 Or you can use Tab completion. 1610 01:12:37,180 --> 01:12:39,270 So you can start typing a word like "code." 1611 01:12:39,270 --> 01:12:42,450 And C-O-D tab will finish the thought. 1612 01:12:42,450 --> 01:12:46,385 Or dot slash C-O-M Tab will finish that thought just 1613 01:12:46,385 --> 01:12:47,760 to save yourself some keystrokes. 1614 01:12:47,760 --> 01:12:50,670 And clearing the screen is Control L, which 1615 01:12:50,670 --> 01:12:54,330 has no functional purpose other than keeping things neat and tidy in class. 1616 01:12:54,330 --> 01:12:55,738 So a design question. 1617 01:12:55,738 --> 01:12:57,280 So this code, I dare say, is correct. 1618 01:12:57,280 --> 01:12:58,840 Let me zoom in a little bit here. 1619 01:12:58,840 --> 01:13:03,570 Let me change the code to just do this, even though we already saw from Scratch 1620 01:13:03,570 --> 01:13:05,650 that we probably shouldn't do this. 1621 01:13:05,650 --> 01:13:10,920 Why should we not do this if, especially, I'm just more comfortable 1622 01:13:10,920 --> 01:13:14,380 asking three separate questions, like if x is less than y, 1623 01:13:14,380 --> 01:13:17,310 if x is greater than y, if x equals y, do this? 1624 01:13:17,310 --> 01:13:18,800 It's a nice world to live in. 1625 01:13:18,800 --> 01:13:19,800 Just ask your questions. 1626 01:13:19,800 --> 01:13:22,750 You don't have to worry about else, else-if, else-if, forks in the road. 1627 01:13:22,750 --> 01:13:24,125 You can just ask three questions. 1628 01:13:24,125 --> 01:13:30,380 But let's put a finger on, why is this correct, yes, but not well designed? 1629 01:13:30,380 --> 01:13:31,380 Yeah, in back again? 1630 01:13:31,380 --> 01:13:34,951 AUDIENCE: [INAUDIBLE] 1631 01:13:34,951 --> 01:13:38,665 1632 01:13:38,665 --> 01:13:40,540 DAVID J. MALAN: OK, there could be cases that 1633 01:13:40,540 --> 01:13:42,430 are potentially outside of these three. 1634 01:13:42,430 --> 01:13:44,920 Because this is relatively simple math, comparing numbers, 1635 01:13:44,920 --> 01:13:46,545 we don't have to worry about that here. 1636 01:13:46,545 --> 01:13:48,910 But, yes, in general, you might miss a scenario 1637 01:13:48,910 --> 01:13:50,685 without using a catchall like else. 1638 01:13:50,685 --> 01:13:54,670 AUDIENCE: Maybe more than one of them would be evaluated as true. 1639 01:13:54,670 --> 01:13:58,108 DAVID J. MALAN: Yeah, so maybe more than one of them could be evaluated as true-- 1640 01:13:58,108 --> 01:13:59,150 not going to happen here. 1641 01:13:59,150 --> 01:14:02,452 But, yes, you could accidentally create a situation where two things 1642 01:14:02,452 --> 01:14:04,660 print or three things print because you didn't really 1643 01:14:04,660 --> 01:14:07,620 think about the boundaries among these questions that you're asking. 1644 01:14:07,620 --> 01:14:10,610 Again, not applicable here but, in general, a good concern. 1645 01:14:10,610 --> 01:14:14,438 AUDIENCE: You're forcing the computer to have a condition that doesn't 1646 01:14:14,438 --> 01:14:15,980 need to be checked if I slow it down. 1647 01:14:15,980 --> 01:14:17,147 DAVID J. MALAN: Really good. 1648 01:14:17,147 --> 01:14:19,130 Really, what's concerning here in this example 1649 01:14:19,130 --> 01:14:21,800 is you're slowing the computer down by wasting its time, 1650 01:14:21,800 --> 01:14:24,210 having it do work that is logically unnecessary, 1651 01:14:24,210 --> 01:14:27,030 even more so than the Scratch in the first C example. 1652 01:14:27,030 --> 01:14:27,530 Why? 1653 01:14:27,530 --> 01:14:31,080 Suppose that I type in 1 for x and 1 for y. 1654 01:14:31,080 --> 01:14:34,070 Because I wrote this code top to bottom, this question 1655 01:14:34,070 --> 01:14:35,627 is going to be asked no matter what. 1656 01:14:35,627 --> 01:14:36,960 The answer is going to be false. 1657 01:14:36,960 --> 01:14:39,150 This question is going to be asked no matter what. 1658 01:14:39,150 --> 01:14:40,260 The answer is going to be false. 1659 01:14:40,260 --> 01:14:41,718 This question is going to be asked. 1660 01:14:41,718 --> 01:14:44,040 And no matter what, the answer is going to be true. 1661 01:14:44,040 --> 01:14:47,730 We're OK there because we had to ask all three questions. 1662 01:14:47,730 --> 01:14:52,260 But suppose I did the first thing, x is 1, y is 2. 1663 01:14:52,260 --> 01:14:56,450 Then this first question is going to be true because x is less than y. 1664 01:14:56,450 --> 01:14:57,270 1 is less than 2. 1665 01:14:57,270 --> 01:14:58,560 So this is going to print. 1666 01:14:58,560 --> 01:15:03,140 And yet, then I'm wasting everyone's time asking, hm, is x greater than y, 1667 01:15:03,140 --> 01:15:04,590 even though it obviously isn't. 1668 01:15:04,590 --> 01:15:05,615 Is x equal to y? 1669 01:15:05,615 --> 01:15:07,980 Hm, it obviously isn't. 1670 01:15:07,980 --> 01:15:11,970 You're doing three times as much work in that particular case. 1671 01:15:11,970 --> 01:15:13,608 It's just not good design. 1672 01:15:13,608 --> 01:15:16,150 And again, for those of you who think a little more visually, 1673 01:15:16,150 --> 01:15:18,910 we can actually make this picture to match. 1674 01:15:18,910 --> 01:15:22,450 Here is a final flowchart for bad code, bad design. 1675 01:15:22,450 --> 01:15:22,950 Why? 1676 01:15:22,950 --> 01:15:25,170 Because no matter what, when you start the program 1677 01:15:25,170 --> 01:15:28,170 and you want to stop the program, you're going through all three 1678 01:15:28,170 --> 01:15:33,000 of those darn questions no matter what, whereas the previous flowcharts got us 1679 01:15:33,000 --> 01:15:37,920 to the Stop bubble faster by taking alternative arrows based 1680 01:15:37,920 --> 01:15:39,580 on true or false answers. 1681 01:15:39,580 --> 01:15:42,670 So in short, still correct but bad design. 1682 01:15:42,670 --> 01:15:46,500 And so again, even for problem set 1, when we start writing C code, consider 1683 01:15:46,500 --> 01:15:48,540 not just getting the job done but how you 1684 01:15:48,540 --> 01:15:53,140 might get the job done better than you might otherwise. 1685 01:15:53,140 --> 01:15:57,310 All right, let's add a few other features into the mix. 1686 01:15:57,310 --> 01:16:00,038 Here we have those same data types that are supported 1687 01:16:00,038 --> 01:16:03,080 by C. Let's focus for a moment on something a little simpler, just chars, 1688 01:16:03,080 --> 01:16:04,220 single characters. 1689 01:16:04,220 --> 01:16:07,390 Unfortunately, for better or for worse, in C, the language makes 1690 01:16:07,390 --> 01:16:11,770 a distinction between strings of text, which are generally words, phrases. 1691 01:16:11,770 --> 01:16:16,518 They can, confusingly, be single characters or even zero characters 1692 01:16:16,518 --> 01:16:18,560 if you don't type anything in between the quotes. 1693 01:16:18,560 --> 01:16:19,970 But more on that another time. 1694 01:16:19,970 --> 01:16:23,710 But when you know from the get go that you only want to get a single character 1695 01:16:23,710 --> 01:16:26,930 back from the user, like "y" for yes, "n" for no, for instance, 1696 01:16:26,930 --> 01:16:31,870 which is super common in programs, you can get that using a char and CS50's own 1697 01:16:31,870 --> 01:16:33,400 function, get_char. 1698 01:16:33,400 --> 01:16:35,090 So how might we use this? 1699 01:16:35,090 --> 01:16:36,740 Well, let's go back to VS Code here. 1700 01:16:36,740 --> 01:16:38,155 I'm going to close compare.c. 1701 01:16:38,155 --> 01:16:40,520 And let's write a third program altogether. 1702 01:16:40,520 --> 01:16:42,595 Let's call this one agree.c. 1703 01:16:42,595 --> 01:16:45,220 And this is meant to represent like terms and conditions, where 1704 01:16:45,220 --> 01:16:48,140 you have to check a box yes or no or something like that. 1705 01:16:48,140 --> 01:16:51,710 In this program, I'm going to go ahead and do the following. 1706 01:16:51,710 --> 01:16:55,970 I'm going to go ahead and, as before, include cs50.h, so we've got it, 1707 01:16:55,970 --> 01:16:59,780 include standard io.h so that we've got it, int main(void) 1708 01:16:59,780 --> 01:17:01,380 because we have to do that for now. 1709 01:17:01,380 --> 01:17:02,707 More on that another time. 1710 01:17:02,707 --> 01:17:04,290 And now let's ask the user a question. 1711 01:17:04,290 --> 01:17:05,340 Do they agree? 1712 01:17:05,340 --> 01:17:10,280 So I'm going to call get_char and then pass in a prompt of, "Do you agree?", 1713 01:17:10,280 --> 01:17:13,050 question mark, with a space, semicolon. 1714 01:17:13,050 --> 01:17:17,820 But as before with get_string and get_int, those functions return a value. 1715 01:17:17,820 --> 01:17:21,480 So I want to assign that value from right to left to a variable, 1716 01:17:21,480 --> 01:17:22,945 which I could call "answer again." 1717 01:17:22,945 --> 01:17:24,820 But honestly, this program is so short, we're 1718 01:17:24,820 --> 01:17:27,480 just going to use the letter c, which is conventional. 1719 01:17:27,480 --> 01:17:31,650 So "c" for char, "i" for int, or "n" for number are very common. 1720 01:17:31,650 --> 01:17:32,580 But one more thing. 1721 01:17:32,580 --> 01:17:35,910 What's still missing for my variable here? 1722 01:17:35,910 --> 01:17:36,530 The type. 1723 01:17:36,530 --> 01:17:41,550 I need to say, this shall be a char, not an int, not a string, a single char. 1724 01:17:41,550 --> 01:17:43,050 All right, now what do I want to do? 1725 01:17:43,050 --> 01:17:44,010 I can ask a question. 1726 01:17:44,010 --> 01:17:50,480 If c equals equals lowercase y, then go ahead and print out, 1727 01:17:50,480 --> 01:17:53,660 just so we see something on the screen, "Agreed" period, backslash n, 1728 01:17:53,660 --> 01:17:55,790 as though they agreed to the terms and conditions. 1729 01:17:55,790 --> 01:18:02,130 Else, if c equals equals lowercase n, go ahead and print out, for instance, 1730 01:18:02,130 --> 01:18:05,400 "Not agreed" just so we see something on the screen. 1731 01:18:05,400 --> 01:18:07,740 So let me hide my terminal window and focus on the code. 1732 01:18:07,740 --> 01:18:10,365 There's a couple of details here that are a little interesting. 1733 01:18:10,365 --> 01:18:14,360 So, one, what did I do on line 7 and 11 that is not 1734 01:18:14,360 --> 01:18:17,940 consistent with what I've done before? 1735 01:18:17,940 --> 01:18:20,700 Subtle. 1736 01:18:20,700 --> 01:18:24,390 So I'm using apostrophes or single quotes now instead of double quotes. 1737 01:18:24,390 --> 01:18:24,890 Why? 1738 01:18:24,890 --> 01:18:25,950 It's a C thing. 1739 01:18:25,950 --> 01:18:28,830 When you're using strings, you use double quotes. 1740 01:18:28,830 --> 01:18:32,340 When you use single chars, you use single quotes. 1741 01:18:32,340 --> 01:18:34,950 So the argument to get char, that's still a string. 1742 01:18:34,950 --> 01:18:36,840 It's a whole sentence that I'm passing in. 1743 01:18:36,840 --> 01:18:39,540 So that is just like get_int, just like get_string. 1744 01:18:39,540 --> 01:18:42,620 But when I get the answer back, the return value, 1745 01:18:42,620 --> 01:18:46,340 and put it in this variable and I want to check, what is that one char, 1746 01:18:46,340 --> 01:18:48,440 I have to surround the char I'm comparing 1747 01:18:48,440 --> 01:18:53,160 against in single quotes or apostrophes, both for the y and for the n. 1748 01:18:53,160 --> 01:18:55,400 So this program is not super well designed 1749 01:18:55,400 --> 01:18:57,450 because it's not going to handle uppercase. 1750 01:18:57,450 --> 01:18:59,460 It's not going to handle weird inputs very well. 1751 01:18:59,460 --> 01:19:01,140 But let me open my terminal window. 1752 01:19:01,140 --> 01:19:03,260 Make agree, Enter. 1753 01:19:03,260 --> 01:19:06,210 The code compiles OK-- "./agree." 1754 01:19:06,210 --> 01:19:06,900 Do I agree? 1755 01:19:06,900 --> 01:19:08,730 Let's try it. y for yes. 1756 01:19:08,730 --> 01:19:10,420 OK, let's try it again-- 1757 01:19:10,420 --> 01:19:11,570 "./agree." 1758 01:19:11,570 --> 01:19:12,890 n for no. 1759 01:19:12,890 --> 01:19:13,800 "Not agreed." 1760 01:19:13,800 --> 01:19:14,910 Let's do it one more time. 1761 01:19:14,910 --> 01:19:17,480 Let's very enthusiastically say "YES" in all caps, 1762 01:19:17,480 --> 01:19:21,250 and it just kind of ignores me. 1763 01:19:21,250 --> 01:19:22,270 But why? 1764 01:19:22,270 --> 01:19:25,450 Well, this is a feature of CS50's get_char function. 1765 01:19:25,450 --> 01:19:27,480 If you tell us you want to get a char, we're 1766 01:19:27,480 --> 01:19:30,760 not going to tolerate a whole string of text from the user. 1767 01:19:30,760 --> 01:19:34,230 We're going to prompt them again and again and again until they 1768 01:19:34,230 --> 01:19:35,590 give us just one char. 1769 01:19:35,590 --> 01:19:37,750 So "YES," is three times too long. 1770 01:19:37,750 --> 01:19:41,110 So let's actually just do a single capital Y and see what happens. 1771 01:19:41,110 --> 01:19:42,000 Return. 1772 01:19:42,000 --> 01:19:44,110 The program ignores me altogether. 1773 01:19:44,110 --> 01:19:46,480 So all right, this is kind of a poorly designed program. 1774 01:19:46,480 --> 01:19:48,647 It's a little annoying that we'll just ignore humans 1775 01:19:48,647 --> 01:19:51,760 even if they type in Y or N that just happens to be uppercase. 1776 01:19:51,760 --> 01:19:52,678 So let's improve this. 1777 01:19:52,678 --> 01:19:54,720 Let me go ahead and add a couple more conditions. 1778 01:19:54,720 --> 01:20:01,750 Else if c equals equals uppercase Y, then go ahead and print out "Agreed," 1779 01:20:01,750 --> 01:20:02,710 same as before. 1780 01:20:02,710 --> 01:20:06,930 And then, down here, else if C equals equals capital N, 1781 01:20:06,930 --> 01:20:10,810 then let's go ahead and print out, again, "Not agreed." 1782 01:20:10,810 --> 01:20:12,960 So this is now more correct. 1783 01:20:12,960 --> 01:20:14,880 It's still going to ignore bogus input that 1784 01:20:14,880 --> 01:20:17,160 makes no sense, if it's just the word-- 1785 01:20:17,160 --> 01:20:19,150 if it's a different letter altogether. 1786 01:20:19,150 --> 01:20:24,820 But this, too, code, while correct in some sense, is still poorly designed. 1787 01:20:24,820 --> 01:20:26,730 Even if you've never programmed before, what 1788 01:20:26,730 --> 01:20:31,200 rubs you the wrong way about this code now? 1789 01:20:31,200 --> 01:20:31,900 Be critical. 1790 01:20:31,900 --> 01:20:32,400 Yeah? 1791 01:20:32,400 --> 01:20:36,344 AUDIENCE: [INAUDIBLE] uppercase and lowercase Y's together [INAUDIBLE]. 1792 01:20:36,344 --> 01:20:39,310 DAVID J. MALAN: Yeah, it'd be nice to just merge the lowercase 1793 01:20:39,310 --> 01:20:42,580 and the uppercase Y together, the same thing for the lowercase 1794 01:20:42,580 --> 01:20:44,510 and the uppercase N. Why? 1795 01:20:44,510 --> 01:20:48,340 If only because literally lines 9 and 12 are identical. 1796 01:20:48,340 --> 01:20:51,680 Lines 17 and 21 are identical. 1797 01:20:51,680 --> 01:20:55,490 And while not a huge deal, if I go in and I change this sentence, 1798 01:20:55,490 --> 01:20:58,003 odds are, over the course of my lifetime programming, 1799 01:20:58,003 --> 01:21:00,920 I'm going to forget to change this one even though I changed this one. 1800 01:21:00,920 --> 01:21:02,450 Or I'm going to forget to change this one and this one. 1801 01:21:02,450 --> 01:21:05,280 So you don't want the code to get out of sync potentially. 1802 01:21:05,280 --> 01:21:07,280 And you certainly don't want to repeat yourself. 1803 01:21:07,280 --> 01:21:10,460 So "don't repeat yourself" is a tenet of programming, too. 1804 01:21:10,460 --> 01:21:14,390 If you can avoid that by somehow factoring out some commonality, 1805 01:21:14,390 --> 01:21:16,840 you should do so, similar in spirit to math when 1806 01:21:16,840 --> 01:21:18,590 you factor out variables or the like. 1807 01:21:18,590 --> 01:21:20,330 So let me tighten this up, so to speak. 1808 01:21:20,330 --> 01:21:24,830 Let me get rid of what we just did so that it's a little shorter as before. 1809 01:21:24,830 --> 01:21:29,930 And let me express myself with two conditions using the following syntax. 1810 01:21:29,930 --> 01:21:35,890 I want to check if c equals equals lowercase y or c equals equals uppercase 1811 01:21:35,890 --> 01:21:40,980 Y. So you can actually use what's called a logical operator, two vertical bars, 1812 01:21:40,980 --> 01:21:43,550 which means "or." 1813 01:21:43,550 --> 01:21:48,620 And we can do this down here, or c equals equals capital N. 1814 01:21:48,620 --> 01:21:50,820 So same exact functionality. 1815 01:21:50,820 --> 01:21:53,820 But to your point, we've now eliminated, what, like another one-- 1816 01:21:53,820 --> 01:21:57,480 it was, like, 1, 4-- it's eight lines of code now are gone, 1817 01:21:57,480 --> 01:22:00,350 which is eight fewer lines that I might screw up in this program. 1818 01:22:00,350 --> 01:22:04,710 Less opportunity for mistakes or bugs, probably a good thing. 1819 01:22:04,710 --> 01:22:07,850 So now, if I run this, let me open my terminal window. 1820 01:22:07,850 --> 01:22:11,060 Let me run make agree, Enter. 1821 01:22:11,060 --> 01:22:13,110 "./agree," Enter. 1822 01:22:13,110 --> 01:22:14,010 Do I agree? 1823 01:22:14,010 --> 01:22:18,180 Capital Y. Now it seems to be handling both of those situations. 1824 01:22:18,180 --> 01:22:19,350 So just a little tighter. 1825 01:22:19,350 --> 01:22:21,240 As an aside-- we won't use it here-- 1826 01:22:21,240 --> 01:22:24,590 but if you want to say "and," which would be nonsensical, it, 1827 01:22:24,590 --> 01:22:29,960 a little confusingly, is two ampersands, means a logical "and," whereby the left 1828 01:22:29,960 --> 01:22:32,670 thing has to be true and the right thing has to be true. 1829 01:22:32,670 --> 01:22:34,573 So it's two Boolean expressions at once. 1830 01:22:34,573 --> 01:22:37,490 This one makes no logical sense, though, because a character cannot be 1831 01:22:37,490 --> 01:22:40,050 simultaneously lowercase and uppercase. 1832 01:22:40,050 --> 01:22:41,580 It's got to be one or the other. 1833 01:22:41,580 --> 01:22:43,740 So two vertical bars is logically correct. 1834 01:22:43,740 --> 01:22:48,520 That represents our notion here of "or." 1835 01:22:48,520 --> 01:22:50,730 Question? 1836 01:22:50,730 --> 01:22:52,020 No? 1837 01:22:52,020 --> 01:22:54,084 Yeah. 1838 01:22:54,084 --> 01:22:56,612 AUDIENCE: Would you not be able to write or? 1839 01:22:56,612 --> 01:22:57,570 Does it recognize that? 1840 01:22:57,570 --> 01:22:59,278 DAVID J. MALAN: You could not write "or." 1841 01:22:59,278 --> 01:23:01,810 So I'm saying "or" just because that's a little more normal. 1842 01:23:01,810 --> 01:23:03,100 But this is incorrect. 1843 01:23:03,100 --> 01:23:05,555 However-- sneak preview-- in the language of Python, 1844 01:23:05,555 --> 01:23:07,930 you actually will literally say "or," among other things, 1845 01:23:07,930 --> 01:23:10,290 which gets a little more user friendly. 1846 01:23:10,290 --> 01:23:12,515 Other questions on this here? 1847 01:23:12,515 --> 01:23:15,600 1848 01:23:15,600 --> 01:23:16,290 Searching. 1849 01:23:16,290 --> 01:23:17,030 Yes, in back. 1850 01:23:17,030 --> 01:23:18,572 AUDIENCE: Is there an easier way to-- 1851 01:23:18,572 --> 01:23:21,405 DAVID J. MALAN: Is there an easier way to handle a case sensitivity? 1852 01:23:21,405 --> 01:23:23,490 Yes, and we'll show you that next week, in fact. 1853 01:23:23,490 --> 01:23:26,150 So we can combine this code to be even tighter. 1854 01:23:26,150 --> 01:23:29,850 All right, let's do one final set of examples before taking a cookie break, 1855 01:23:29,850 --> 01:23:30,450 if we could. 1856 01:23:30,450 --> 01:23:33,078 But let's go ahead and close agree.c here. 1857 01:23:33,078 --> 01:23:34,370 Let me open my terminal window. 1858 01:23:34,370 --> 01:23:38,850 And let's go ahead and implement a virtual cat as we did last week. 1859 01:23:38,850 --> 01:23:40,687 I'm going to code up a file called cat.c. 1860 01:23:40,687 --> 01:23:43,770 And I'm going to implement this in a few different ways, the first of them 1861 01:23:43,770 --> 01:23:44,430 pretty foolish. 1862 01:23:44,430 --> 01:23:47,090 So here, I'm going to include standard io.h. 1863 01:23:47,090 --> 01:23:48,980 No need for CS50 dot yet-- 1864 01:23:48,980 --> 01:23:49,920 just yet. 1865 01:23:49,920 --> 01:23:51,590 int main(void). 1866 01:23:51,590 --> 01:23:55,190 Inside of these curly braces, let's go ahead and do printf "meow" 1867 01:23:55,190 --> 01:23:56,600 to get the cat to meow. 1868 01:23:56,600 --> 01:23:59,940 And then, to save time, I'm going to copy/paste that two more times. 1869 01:23:59,940 --> 01:24:02,970 So this cat shall meow three times in total. 1870 01:24:02,970 --> 01:24:06,000 All right, I'm going to go ahead and make the cat, so to speak. 1871 01:24:06,000 --> 01:24:08,190 All good. "./cat," Enter. 1872 01:24:08,190 --> 01:24:12,120 And it meows three times, just like our Scratch cat last time. 1873 01:24:12,120 --> 01:24:13,590 I'll stipulate, this is correct. 1874 01:24:13,590 --> 01:24:16,620 This is a really well implemented cat correctness-wise. 1875 01:24:16,620 --> 01:24:21,430 But why is it bad design intuitively, just like last week? 1876 01:24:21,430 --> 01:24:22,845 AUDIENCE: [INAUDIBLE] [? out. ?] 1877 01:24:22,845 --> 01:24:23,762 DAVID J. MALAN: Sorry? 1878 01:24:23,762 --> 01:24:25,210 AUDIENCE: Repeating the code. 1879 01:24:25,210 --> 01:24:25,490 DAVID J. MALAN: Sorry. 1880 01:24:25,490 --> 01:24:26,740 AUDIENCE: You keep repeating the code. 1881 01:24:26,740 --> 01:24:28,490 DAVID J. MALAN: I keep repeating the code. 1882 01:24:28,490 --> 01:24:31,640 I mean, I literally copied and pasted, which is your first obvious sign. 1883 01:24:31,640 --> 01:24:34,182 I'm probably doing something wrong if I'm copying and pasting 1884 01:24:34,182 --> 01:24:35,900 because I'm literally repeating myself. 1885 01:24:35,900 --> 01:24:39,440 So to spoil it, odds are a loop is probably going to be our friend here. 1886 01:24:39,440 --> 01:24:43,970 And so, in fact, in C, we have those features as well. 1887 01:24:43,970 --> 01:24:47,320 So in the world of C, we can implement some of last week's same ideas 1888 01:24:47,320 --> 01:24:48,542 in a few different ways. 1889 01:24:48,542 --> 01:24:50,000 These are a little more mechanical. 1890 01:24:50,000 --> 01:24:52,970 But suppose we want to repeat something literally three times. 1891 01:24:52,970 --> 01:24:56,607 Scratch gives us a repeat, a block with an input-- so easy. 1892 01:24:56,607 --> 01:24:59,440 C and a lot of languages, it's going to be a little more mechanical. 1893 01:24:59,440 --> 01:25:00,770 And it's going to look ugly at first. 1894 01:25:00,770 --> 01:25:02,187 It will take some getting used to. 1895 01:25:02,187 --> 01:25:05,330 But it is a paradigm you will use again and again and again. 1896 01:25:05,330 --> 01:25:09,050 This will become very rote memory before long. 1897 01:25:09,050 --> 01:25:12,525 Well, the most direct translation of this Scratch code to C 1898 01:25:12,525 --> 01:25:14,650 is probably something that looks a little something 1899 01:25:14,650 --> 01:25:16,900 like this, whereby I initialize a variable, 1900 01:25:16,900 --> 01:25:19,490 here called i, and set it equal to 3. 1901 01:25:19,490 --> 01:25:22,340 That's the code equivalent in C of putting up three fingers. 1902 01:25:22,340 --> 01:25:27,000 Then what I want to do is, while i is greater than 0, 1903 01:25:27,000 --> 01:25:30,390 that is to say while I have at least one finger up, 1904 01:25:30,390 --> 01:25:32,130 go ahead and do the following. 1905 01:25:32,130 --> 01:25:35,580 And then once I've done that, for instance say "meow" on the screen, 1906 01:25:35,580 --> 01:25:39,660 I want to go ahead and decrement i and then do this whole thing again. 1907 01:25:39,660 --> 01:25:43,192 Now, I could have called this variable "counter," for consistency with earlier. 1908 01:25:43,192 --> 01:25:46,400 But it turns out it's conventional when you've only got one variable involved 1909 01:25:46,400 --> 01:25:49,380 in your code and all it's doing is something simple like counting, 1910 01:25:49,380 --> 01:25:52,410 you can go ahead and call the variable i for integer, for instance. 1911 01:25:52,410 --> 01:25:55,440 But it would not be wrong to instead call i "counter." 1912 01:25:55,440 --> 01:26:00,120 But notice, too, that in this so-called while loop, as we'll start to call it, 1913 01:26:00,120 --> 01:26:01,440 there is this parenthetical. 1914 01:26:01,440 --> 01:26:04,440 And that parenthetical is actually itself a Boolean expression. 1915 01:26:04,440 --> 01:26:08,300 But unlike an if statement, whereby the Boolean expression is evaluated 1916 01:26:08,300 --> 01:26:12,480 just once and if the answer is true, or yes, you do that thing, 1917 01:26:12,480 --> 01:26:16,940 the Boolean expression in a while loop here in C is evaluated again 1918 01:26:16,940 --> 01:26:21,530 and again and again every time you go through the loop 1919 01:26:21,530 --> 01:26:24,120 to check if you should keep going through the loop. 1920 01:26:24,120 --> 01:26:27,870 So for instance, if the goal at hand is to say "meow," well, of course, 1921 01:26:27,870 --> 01:26:30,170 the comparable C function is going to be printf. 1922 01:26:30,170 --> 01:26:33,570 And I want to print out on the screen "meow," followed by a new line. 1923 01:26:33,570 --> 01:26:34,610 Well, what's going on? 1924 01:26:34,610 --> 01:26:36,860 Well, again, I initialize i to 3. 1925 01:26:36,860 --> 01:26:38,897 I then check, is i greater than 0? 1926 01:26:38,897 --> 01:26:42,230 And of course it is because effectively, in the computer's memory, three fingers 1927 01:26:42,230 --> 01:26:42,810 are up. 1928 01:26:42,810 --> 01:26:44,460 I go ahead and print out "meow." 1929 01:26:44,460 --> 01:26:48,020 I decrement i, which means to put down one of those fingers. 1930 01:26:48,020 --> 01:26:50,540 And then I check the Boolean expression again. 1931 01:26:50,540 --> 01:26:52,170 Is 2 greater than 0? 1932 01:26:52,170 --> 01:26:52,860 Of course it is. 1933 01:26:52,860 --> 01:26:53,910 So I print out "meow." 1934 01:26:53,910 --> 01:26:56,993 And then I decrement i, putting down one more finger. 1935 01:26:56,993 --> 01:26:58,410 Then I check the expression again. 1936 01:26:58,410 --> 01:26:59,820 Is 1 greater than 0? 1937 01:26:59,820 --> 01:27:00,690 Of course it is. 1938 01:27:00,690 --> 01:27:01,700 I print out "meow." 1939 01:27:01,700 --> 01:27:02,990 And then I decrement i. 1940 01:27:02,990 --> 01:27:04,410 And now I'm down to 0. 1941 01:27:04,410 --> 01:27:05,360 I check again. 1942 01:27:05,360 --> 01:27:07,320 Is 0 greater than 0? 1943 01:27:07,320 --> 01:27:08,340 Well, no. 1944 01:27:08,340 --> 01:27:12,360 And so the loop will automatically, by the definition of how this C code works, 1945 01:27:12,360 --> 01:27:14,750 terminate for me and proceed to any other lines 1946 01:27:14,750 --> 01:27:17,280 if there are more lines of code that I've written. 1947 01:27:17,280 --> 01:27:20,698 So how do we actually implement this then in code and get it running? 1948 01:27:20,698 --> 01:27:22,740 Well, it's going to be pretty much the same idea. 1949 01:27:22,740 --> 01:27:24,522 Let me go back to VS Code here. 1950 01:27:24,522 --> 01:27:26,480 I'm going to get rid of all of this copy/paste. 1951 01:27:26,480 --> 01:27:29,900 And inside of my main function, I'm going to do exactly what we saw-- 1952 01:27:29,900 --> 01:27:35,760 int i equals 3, semicolon. while i is greater than 0, 1953 01:27:35,760 --> 01:27:40,370 then go ahead and print out with printf "meow" backslash n. 1954 01:27:40,370 --> 01:27:42,710 And then be sure you decrement i. 1955 01:27:42,710 --> 01:27:45,620 And notice that lines 8 and 9 are not only indented, they 1956 01:27:45,620 --> 01:27:48,390 are inside of that while loop, so to speak, 1957 01:27:48,390 --> 01:27:51,380 which means they will both happen again and again 1958 01:27:51,380 --> 01:27:56,330 and again because what's happening in code here is those curly braces 1959 01:27:56,330 --> 01:28:00,380 are kind of like the yellow pieces that are hugging the other puzzle 1960 01:28:00,380 --> 01:28:01,500 pieces in Scratch. 1961 01:28:01,500 --> 01:28:03,810 It will keep doing this, this, this. 1962 01:28:03,810 --> 01:28:07,110 But every time, through that loop or cycle, 1963 01:28:07,110 --> 01:28:11,150 this Boolean expression will be checked again and again and again 1964 01:28:11,150 --> 01:28:13,740 until the answer is false, at which point 1965 01:28:13,740 --> 01:28:16,170 the computer is going to jump to the last line. 1966 01:28:16,170 --> 01:28:19,880 And if there's nothing left, that's it for the program, no more to be done. 1967 01:28:19,880 --> 01:28:24,150 So same exact idea in Scratch, even though it's a little more mechanical. 1968 01:28:24,150 --> 01:28:26,640 So that's how we might implement this. 1969 01:28:26,640 --> 01:28:30,535 And you can think of it, these variables-- this is perhaps 1970 01:28:30,535 --> 01:28:32,160 a little gratuitous, but let's do this. 1971 01:28:32,160 --> 01:28:36,470 So if you have a variable inside of a computer's memory-- 1972 01:28:36,470 --> 01:28:39,870 and that's a detail we'll get to in more detail before long-- 1973 01:28:39,870 --> 01:28:42,900 you can really think of it just as like a container that stores value. 1974 01:28:42,900 --> 01:28:44,622 So for instance, this clear plastic bowl, 1975 01:28:44,622 --> 01:28:46,080 it can be thought of as a variable. 1976 01:28:46,080 --> 01:28:47,190 It just stores values. 1977 01:28:47,190 --> 01:28:49,607 And right now, there's obviously three stress balls in it. 1978 01:28:49,607 --> 01:28:51,750 So it represents the number 3. 1979 01:28:51,750 --> 01:28:53,810 So what's really happening in code like this 1980 01:28:53,810 --> 01:28:57,360 is we've initialized i to 3, which is this bowl. 1981 01:28:57,360 --> 01:28:59,840 We're then checking the question on line 6. 1982 01:28:59,840 --> 01:29:01,340 Is i greater than 0? 1983 01:29:01,340 --> 01:29:02,370 Obviously. 1984 01:29:02,370 --> 01:29:04,380 So we proceed inside of the curly braces. 1985 01:29:04,380 --> 01:29:05,820 And we print out "meow." 1986 01:29:05,820 --> 01:29:07,310 We then decrement i. 1987 01:29:07,310 --> 01:29:11,370 So for the sake of unnecessary drama, that's decrementing the variable. 1988 01:29:11,370 --> 01:29:15,540 So what's being stored in this container now is one less. 1989 01:29:15,540 --> 01:29:17,190 We do it again, check the count. 1990 01:29:17,190 --> 01:29:18,450 Nope, 2 is greater than 0. 1991 01:29:18,450 --> 01:29:19,670 So we keep going-- "meow." 1992 01:29:19,670 --> 01:29:20,870 Decrement i. 1993 01:29:20,870 --> 01:29:21,980 Check the variable. 1994 01:29:21,980 --> 01:29:24,470 1 is greater than 0, so we print "meow." 1995 01:29:24,470 --> 01:29:25,370 Decrement i. 1996 01:29:25,370 --> 01:29:27,420 We check the condition again. 1997 01:29:27,420 --> 01:29:32,070 i is not greater than 0 because 0 is not greater than 0. 1998 01:29:32,070 --> 01:29:33,977 And so the rest of the code stops executing. 1999 01:29:33,977 --> 01:29:36,810 I'm not sure if that was any more effective than fingers on my hand. 2000 01:29:36,810 --> 01:29:37,530 But we had the bowl. 2001 01:29:37,530 --> 01:29:38,238 We had the balls. 2002 01:29:38,238 --> 01:29:39,627 So same exact idea. 2003 01:29:39,627 --> 01:29:41,210 Variables are just storing some value. 2004 01:29:41,210 --> 01:29:44,240 And incrementing and decrementing would just be adding or subtracting 2005 01:29:44,240 --> 01:29:45,583 stress balls in this case. 2006 01:29:45,583 --> 01:29:47,250 But there's other ways we could do this. 2007 01:29:47,250 --> 01:29:49,350 In fact, let me zoom in on my code here. 2008 01:29:49,350 --> 01:29:51,950 And it's not really conventional in programming 2009 01:29:51,950 --> 01:29:55,370 to count down-- nothing wrong with it, it's just not really a thing. 2010 01:29:55,370 --> 01:29:57,000 We would typically count up. 2011 01:29:57,000 --> 01:29:59,240 So we could alternatively do this-- 2012 01:29:59,240 --> 01:30:01,860 set i equal to 1 initially. 2013 01:30:01,860 --> 01:30:04,520 So we count 1, 2, 3, like a normal person. 2014 01:30:04,520 --> 01:30:06,600 And we can change our condition. 2015 01:30:06,600 --> 01:30:11,810 If I'm going to count from 1 to 3, what should my comparison 2016 01:30:11,810 --> 01:30:15,770 be in my Boolean expression here? 2017 01:30:15,770 --> 01:30:18,820 i is less than 3? 2018 01:30:18,820 --> 01:30:21,770 Less than or equal to 3, I think. 2019 01:30:21,770 --> 01:30:26,740 So if i is initialized to 1, we're going to go through this one time, two times, 2020 01:30:26,740 --> 01:30:27,850 three times. 2021 01:30:27,850 --> 01:30:29,870 i is going to eventually get incremented to 4. 2022 01:30:29,870 --> 01:30:33,200 But at that point, 4 is not less than or equal to 3. 2023 01:30:33,200 --> 01:30:35,660 So it's only going to execute a total of three times. 2024 01:30:35,660 --> 01:30:36,890 But there's still a bug in this code. 2025 01:30:36,890 --> 01:30:38,223 What other line needs to change? 2026 01:30:38,223 --> 01:30:39,270 AUDIENCE: Plus plus. 2027 01:30:39,270 --> 01:30:42,580 DAVID J. MALAN: Yeah, so line 9 needs to become plus plus. 2028 01:30:42,580 --> 01:30:44,950 So this code is just as correct. 2029 01:30:44,950 --> 01:30:47,440 And honestly, you could-- reasonable people will disagree. 2030 01:30:47,440 --> 01:30:49,570 Your TF might say do it this way and not this way. 2031 01:30:49,570 --> 01:30:51,220 But this is still correct. 2032 01:30:51,220 --> 01:30:52,870 But it's not the most conventional way. 2033 01:30:52,870 --> 01:30:56,070 As per last week, computer scientists and programmers generally, 2034 01:30:56,070 --> 01:30:59,920 actually, start counting from 0 by convention for reasons we'll soon see. 2035 01:30:59,920 --> 01:31:03,210 So the better way, the more conventional way arguably, 2036 01:31:03,210 --> 01:31:05,610 would be always start counting from 0. 2037 01:31:05,610 --> 01:31:09,370 Count up to but not through the number you care about. 2038 01:31:09,370 --> 01:31:13,720 And so this form of the code is probably the most popular way to do it. 2039 01:31:13,720 --> 01:31:19,630 Start at 0, count up to 3 but not through 3, as with less than or equals 2040 01:31:19,630 --> 01:31:20,130 than. 2041 01:31:20,130 --> 01:31:21,580 All three are correct. 2042 01:31:21,580 --> 01:31:23,822 Can't really do counting up as easily with the bowl 2043 01:31:23,822 --> 01:31:25,030 without picking up the balls. 2044 01:31:25,030 --> 01:31:26,650 But the exact same logic applies. 2045 01:31:26,650 --> 01:31:30,510 And in fact, this version of the code is so commonly 2046 01:31:30,510 --> 01:31:35,220 done that there's a different way to implement it all-- there's a similar way 2047 01:31:35,220 --> 01:31:36,790 to implement it all together. 2048 01:31:36,790 --> 01:31:38,560 In fact, this code here-- 2049 01:31:38,560 --> 01:31:40,990 same exact thing, repeating three times-- 2050 01:31:40,990 --> 01:31:44,230 because it's so commonly done that you want to initialize something to 0 2051 01:31:44,230 --> 01:31:46,720 and keep doing something until the value 3, 2052 01:31:46,720 --> 01:31:50,360 you can actually use a different preposition, for, 2053 01:31:50,360 --> 01:31:54,140 which is another keyword in C. And it looks a little more cryptic. 2054 01:31:54,140 --> 01:31:55,880 But it just tightens things up. 2055 01:31:55,880 --> 01:31:58,160 This is what's called a for loop. 2056 01:31:58,160 --> 01:32:00,320 Previous is what's called a while loop. 2057 01:32:00,320 --> 01:32:02,560 And honestly, even though it, probably to the newbie, 2058 01:32:02,560 --> 01:32:05,110 still looks just as cryptic, it's just a little tighter 2059 01:32:05,110 --> 01:32:08,480 because you're expressing all of these ideas on one line. 2060 01:32:08,480 --> 01:32:12,650 You specify the variable you want to create and initialize. 2061 01:32:12,650 --> 01:32:16,130 You specify the Boolean expression you want to check again and again. 2062 01:32:16,130 --> 01:32:19,310 You specify what increment or decrements you want to happen. 2063 01:32:19,310 --> 01:32:23,720 And confusingly, you do use semicolons here, not commas. 2064 01:32:23,720 --> 01:32:26,017 You do not put a semicolon here. 2065 01:32:26,017 --> 01:32:28,100 You, of course, don't put them after these things. 2066 01:32:28,100 --> 01:32:31,010 You generally only put them after functions thus far. 2067 01:32:31,010 --> 01:32:33,403 So we do have one semicolon here. 2068 01:32:33,403 --> 01:32:35,570 But in short, this you'll get more comfortable with. 2069 01:32:35,570 --> 01:32:38,180 This is how I, for instance, almost always write a loop. 2070 01:32:38,180 --> 01:32:41,185 But it's doing the exact same thing mechanically as this, same thing 2071 01:32:41,185 --> 01:32:44,060 as counting on your fingers, same thing as counting the stress balls. 2072 01:32:44,060 --> 01:32:48,560 There's just different ways to express the exact same idea. 2073 01:32:48,560 --> 01:32:50,253 But there are ways to screw up. 2074 01:32:50,253 --> 01:32:51,920 So in fact, let me go ahead and do this. 2075 01:32:51,920 --> 01:32:53,170 Suppose that the cat-- 2076 01:32:53,170 --> 01:32:55,172 we'd like the cat to live as long as possible. 2077 01:32:55,172 --> 01:32:57,130 And we don't want it to stop meowing after just 2078 01:32:57,130 --> 01:32:59,000 three or a finite number of times. 2079 01:32:59,000 --> 01:33:02,600 How can you do something forever, again and again and again? 2080 01:33:02,600 --> 01:33:05,060 Well, let me go back into VS Code here. 2081 01:33:05,060 --> 01:33:07,390 Let me delete all of the code from earlier. 2082 01:33:07,390 --> 01:33:10,760 And let me go ahead and say, while something is true-- 2083 01:33:10,760 --> 01:33:11,780 I'll come back to that-- 2084 01:33:11,780 --> 01:33:17,240 let's just go ahead and print out "meow" backslash n ideally forever. 2085 01:33:17,240 --> 01:33:18,770 But what do I want to put in here? 2086 01:33:18,770 --> 01:33:21,978 Well, if I want to do something forever, I could do something kind of stupid, 2087 01:33:21,978 --> 01:33:24,860 like while 1 is less than 2, which is always going to be the case, 2088 01:33:24,860 --> 01:33:27,830 or while 50 is less than 51, which is always going to be-- 2089 01:33:27,830 --> 01:33:29,720 I could just ask an arbitrary question. 2090 01:33:29,720 --> 01:33:31,670 But arbitrary-- not good in general. 2091 01:33:31,670 --> 01:33:33,710 You should have meaning behind your code. 2092 01:33:33,710 --> 01:33:38,360 So if you want the expression to be true all of the time, just say "while true," 2093 01:33:38,360 --> 01:33:40,370 because true is not changing anytime soon. 2094 01:33:40,370 --> 01:33:42,770 If it's literally true, it's always going to be true. 2095 01:33:42,770 --> 01:33:44,690 The only caveat is to use this trick. 2096 01:33:44,690 --> 01:33:48,970 For now, you will need to include the CS50 library, which for today's purposes 2097 01:33:48,970 --> 01:33:50,990 makes that possible. 2098 01:33:50,990 --> 01:33:53,000 But there's a problem, of course. 2099 01:33:53,000 --> 01:33:58,390 If the cat's going to live forever, if I do make cat, "./cat," Enter, 2100 01:33:58,390 --> 01:34:01,090 you can very quickly lose control over your terminal window. 2101 01:34:01,090 --> 01:34:03,573 And you can see the meows are flying across the screen, 2102 01:34:03,573 --> 01:34:05,740 at least based on the bottom from what we're seeing. 2103 01:34:05,740 --> 01:34:07,390 This cat will never stop meowing. 2104 01:34:07,390 --> 01:34:10,180 And this is either a feature or a bug, so 2105 01:34:10,180 --> 01:34:13,280 to speak, depending on how long the cat here should live virtually. 2106 01:34:13,280 --> 01:34:18,820 But how do you terminate a program that is out of control like this, infinitely? 2107 01:34:18,820 --> 01:34:22,870 So one of the takeaways for today is Control-C is your friend 2108 01:34:22,870 --> 01:34:25,040 for cancel or interrupt the program. 2109 01:34:25,040 --> 01:34:27,400 If you ever lose control over a program because you've 2110 01:34:27,400 --> 01:34:30,042 got intentionally or unintentionally an infinite loop, 2111 01:34:30,042 --> 01:34:31,750 you can go into your terminal window, hit 2112 01:34:31,750 --> 01:34:35,270 Control-C, sometimes multiple times if it's ignoring you. 2113 01:34:35,270 --> 01:34:38,980 And that will break out of the program and just essentially force-quit it, 2114 01:34:38,980 --> 01:34:41,300 like in Macs or PCs. 2115 01:34:41,300 --> 01:34:43,940 But let's make one improvement here still. 2116 01:34:43,940 --> 01:34:46,360 The last thing we did with our cat in Scratch 2117 01:34:46,360 --> 01:34:48,340 before now-- we'll take a break in a moment-- 2118 01:34:48,340 --> 01:34:50,410 was we defined our own functions. 2119 01:34:50,410 --> 01:34:52,360 And recall that we did that to abstract away 2120 01:34:52,360 --> 01:34:55,820 the idea of meowing because Scratch didn't come with a meow puzzle piece. 2121 01:34:55,820 --> 01:34:58,833 C definitely does not come with a meow function. 2122 01:34:58,833 --> 01:35:00,250 We have to implement it ourselves. 2123 01:35:00,250 --> 01:35:02,230 So quickly, toward the end of week 0, we did 2124 01:35:02,230 --> 01:35:05,960 this-- define a function called meow that just plays the meow sound. 2125 01:35:05,960 --> 01:35:08,710 And now we have a meow puzzle piece we can use and reuse. 2126 01:35:08,710 --> 01:35:11,128 In C, we're about to do this. 2127 01:35:11,128 --> 01:35:12,920 And this is going to look a little cryptic. 2128 01:35:12,920 --> 01:35:16,253 But it's going to lay the foundation for future weeks when we do this even more. 2129 01:35:16,253 --> 01:35:19,280 I've got a meow function, weird mentions of void. 2130 01:35:19,280 --> 01:35:22,340 That just means there's no input and there's no output for this function. 2131 01:35:22,340 --> 01:35:23,980 It just does one thing simply. 2132 01:35:23,980 --> 01:35:26,440 And that one thing is printf, "meow." 2133 01:35:26,440 --> 01:35:28,540 So how do I use this here code? 2134 01:35:28,540 --> 01:35:30,610 Here, in Scratch, is how we used it last week. 2135 01:35:30,610 --> 01:35:34,840 When the green flag is clicked, repeat three times the meow function. 2136 01:35:34,840 --> 01:35:38,310 In C, it's going to look like this-- int main(void) and all of that. 2137 01:35:38,310 --> 01:35:39,970 And I can use a for loop, a while loop. 2138 01:35:39,970 --> 01:35:42,420 I'm copying and pasting for loop version of the code. 2139 01:35:42,420 --> 01:35:43,960 Set i equal to 0. 2140 01:35:43,960 --> 01:35:45,870 Make sure it stays below 3. 2141 01:35:45,870 --> 01:35:48,660 Increment it on each iteration, or cycle. 2142 01:35:48,660 --> 01:35:50,260 And just call meow. 2143 01:35:50,260 --> 01:35:52,830 So what's nice here is that we have, fairly 2144 01:35:52,830 --> 01:35:55,050 simply, a way in C to create our own functions 2145 01:35:55,050 --> 01:35:58,140 called meow or anything else that lines up perfectly 2146 01:35:58,140 --> 01:35:59,540 with what we did in Scratch. 2147 01:35:59,540 --> 01:36:02,290 We'll take some time to get comfy with the syntax and remember it, 2148 01:36:02,290 --> 01:36:04,150 have to look it up frequently for reference. 2149 01:36:04,150 --> 01:36:06,070 But let's go ahead and actually do this. 2150 01:36:06,070 --> 01:36:09,060 If I go back to VS Code, clear my screen-- 2151 01:36:09,060 --> 01:36:11,170 let me hide my terminal window temporarily. 2152 01:36:11,170 --> 01:36:14,400 Let me go ahead and invent this meow function. 2153 01:36:14,400 --> 01:36:18,870 Per the code earlier, I'm going to go ahead and do this-- 2154 01:36:18,870 --> 01:36:22,200 void meow(void). 2155 01:36:22,200 --> 01:36:24,710 And again, the two voids mean no input, no output. 2156 01:36:24,710 --> 01:36:26,970 It just does one thing well. 2157 01:36:26,970 --> 01:36:31,170 printf, quote, unquote, "meow" backslash n. 2158 01:36:31,170 --> 01:36:33,790 And now, down here, I can use a for loop. 2159 01:36:33,790 --> 01:36:37,920 So for-- and I know this from memory-- int i equals 0; i less than 3; 2160 01:36:37,920 --> 01:36:38,800 i plus plus. 2161 01:36:38,800 --> 01:36:40,740 And then, inside of curly braces, I'm going 2162 01:36:40,740 --> 01:36:42,860 to go ahead and call the meow function. 2163 01:36:42,860 --> 01:36:46,080 Notice, when I'm creating the function up here, 2164 01:36:46,080 --> 01:36:50,170 I explicitly, pedantically, say void void, no input, no output. 2165 01:36:50,170 --> 01:36:53,760 When I use the function on line 13, you just 2166 01:36:53,760 --> 01:36:55,545 say open parentheses, close parentheses. 2167 01:36:55,545 --> 01:36:58,420 That's the equivalent of a Scratch puzzle piece without a white oval. 2168 01:36:58,420 --> 01:36:59,590 You just put nothing there. 2169 01:36:59,590 --> 01:37:01,550 You don't put the word "void." 2170 01:37:01,550 --> 01:37:02,830 So that's it. 2171 01:37:02,830 --> 01:37:04,470 Let me open my terminal window. 2172 01:37:04,470 --> 01:37:08,640 Let me run make cat to recompile-- "./cat." 2173 01:37:08,640 --> 01:37:11,380 And I think I have a working cat. 2174 01:37:11,380 --> 01:37:12,610 Now, this is correct. 2175 01:37:12,610 --> 01:37:16,000 The only thing I don't love about this version, if I hide my terminal window, 2176 01:37:16,000 --> 01:37:18,910 is that when I start writing bigger and bigger programs, 2177 01:37:18,910 --> 01:37:24,610 it'd be nice if my main function, which I told you to take on faith for today, 2178 01:37:24,610 --> 01:37:27,930 is at the top of the file, if only because literally the name "main" 2179 01:37:27,930 --> 01:37:29,680 means this is the main part of my program. 2180 01:37:29,680 --> 01:37:32,710 It'd be nice if it's the first thing I see, which is to say, 2181 01:37:32,710 --> 01:37:35,370 just to be pedantic, it's very common to put 2182 01:37:35,370 --> 01:37:38,650 any functions you write at the bottom of your file, 2183 01:37:38,650 --> 01:37:41,170 maybe alphabetically, maybe organized some other way. 2184 01:37:41,170 --> 01:37:44,690 But you put main first by convention, just like the "when the green flag 2185 01:37:44,690 --> 01:37:45,190 clicked." 2186 01:37:45,190 --> 01:37:47,565 It was the first thing you always started with last week. 2187 01:37:47,565 --> 01:37:49,090 But watch what happens now. 2188 01:37:49,090 --> 01:37:50,760 If I go into my terminal window-- 2189 01:37:50,760 --> 01:37:54,580 and Command-- or Control-J is hiding and showing it, if you are curious. 2190 01:37:54,580 --> 01:37:57,430 But probably, you'll just leave it open on your own all the time. 2191 01:37:57,430 --> 01:37:59,410 Let me do make cat again. 2192 01:37:59,410 --> 01:38:01,430 And, huh, I've screwed up somehow. 2193 01:38:01,430 --> 01:38:05,180 All I did was move the meow function from top to bottom. 2194 01:38:05,180 --> 01:38:08,840 And I'm getting "call to undeclared function 'meow,'" something, something, 2195 01:38:08,840 --> 01:38:09,630 something. 2196 01:38:09,630 --> 01:38:11,140 Well, what's going on? 2197 01:38:11,140 --> 01:38:13,175 Well, C is pretty naive and simplistic. 2198 01:38:13,175 --> 01:38:15,050 It's only going to do what you tell it to do. 2199 01:38:15,050 --> 01:38:17,810 And it's only going to do things top to bottom, left to right. 2200 01:38:17,810 --> 01:38:22,640 And unfortunately, on line 8, you are telling C, call a function called meow. 2201 01:38:22,640 --> 01:38:25,240 But that does not exist in CS50's header file. 2202 01:38:25,240 --> 01:38:27,387 That does not exist in standard io's header file. 2203 01:38:27,387 --> 01:38:29,470 It exists at the bottom of my file, at which point 2204 01:38:29,470 --> 01:38:32,900 it's too late because I'm trying to use it before it exists. 2205 01:38:32,900 --> 01:38:36,822 So I could just undo that and put this meow function at the top of the file. 2206 01:38:36,822 --> 01:38:39,280 But you're going to eventually get into a perverse scenario 2207 01:38:39,280 --> 01:38:42,290 where you can't put all of your functions above all of your functions. 2208 01:38:42,290 --> 01:38:44,420 You've got to pick a lane at some point. 2209 01:38:44,420 --> 01:38:47,650 So the solution to this, albeit a little weird-- and the one 2210 01:38:47,650 --> 01:38:54,070 time in CS50, in programming, that it is encouraged and necessary to copy/paste-- 2211 01:38:54,070 --> 01:38:58,880 is what you can do at the top of your code, above main, is just copy/paste 2212 01:38:58,880 --> 01:39:02,070 the first line of your own function. 2213 01:39:02,070 --> 01:39:04,580 This is the so-called prototype of the function. 2214 01:39:04,580 --> 01:39:07,740 And it simply describes how to use the function. 2215 01:39:07,740 --> 01:39:10,170 And funny enough, we actually saw this earlier. 2216 01:39:10,170 --> 01:39:14,720 But I kind of swept it under the rug. 2217 01:39:14,720 --> 01:39:19,190 A moment ago, or a bit ago, when we looked at standard io.h 2218 01:39:19,190 --> 01:39:22,350 and we looked at the printf function in the manual pages, 2219 01:39:22,350 --> 01:39:24,270 I highlighted the header file. 2220 01:39:24,270 --> 01:39:27,450 But I also glossed over the so-called prototype, 2221 01:39:27,450 --> 01:39:31,110 which is-- sorry-- the first line of the printf function, 2222 01:39:31,110 --> 01:39:33,900 just as this is the first line of my meow function. 2223 01:39:33,900 --> 01:39:35,160 This is like a little clue. 2224 01:39:35,160 --> 01:39:37,580 This is like saying to C, hey, there's going 2225 01:39:37,580 --> 01:39:40,800 to be a function called meow that takes no input, has no input-- 2226 01:39:40,800 --> 01:39:42,930 takes no input, has no output. 2227 01:39:42,930 --> 01:39:45,480 Just know that it exists eventually. 2228 01:39:45,480 --> 01:39:49,400 And that will satisfy the compiler because if I go back to my terminal, 2229 01:39:49,400 --> 01:39:53,270 rerun make cat, it now knows on faith, per line 4, 2230 01:39:53,270 --> 01:39:55,470 this function will eventually exist. 2231 01:39:55,470 --> 01:39:57,680 And indeed, once it gets to the bottom of my code, 2232 01:39:57,680 --> 01:40:00,270 line 14 onward, there it, in fact, is. 2233 01:40:00,270 --> 01:40:04,130 So you just copy the one-and-only first line of your function's code 2234 01:40:04,130 --> 01:40:05,760 to the top, called a prototype. 2235 01:40:05,760 --> 01:40:10,220 And now if I do "./cat," I get, finally, "meow," "meow," "meow" 2236 01:40:10,220 --> 01:40:14,110 yet again in this case. 2237 01:40:14,110 --> 01:40:16,620 Questions on these here cats? 2238 01:40:16,620 --> 01:40:19,980 2239 01:40:19,980 --> 01:40:20,530 No? 2240 01:40:20,530 --> 01:40:23,160 All right, then the last flourish before-- 2241 01:40:23,160 --> 01:40:24,220 I keep promising cookies. 2242 01:40:24,220 --> 01:40:25,360 And I promise they exist. 2243 01:40:25,360 --> 01:40:28,300 So last flourish-- just as we did in Scratch-- 2244 01:40:28,300 --> 01:40:32,010 so in Scratch, recall that we parameterized our meow function 2245 01:40:32,010 --> 01:40:36,060 by letting us tell meow how many times to meow so that we didn't need to use 2246 01:40:36,060 --> 01:40:39,510 our loop inside of our "when green flag clicked" block. 2247 01:40:39,510 --> 01:40:41,610 In other words, if I want to actually have 2248 01:40:41,610 --> 01:40:45,060 the cat meow a specific number of times, I 2249 01:40:45,060 --> 01:40:47,640 can actually go ahead and do that proactively 2250 01:40:47,640 --> 01:40:52,090 with some of my own code such as this here in Scratch. 2251 01:40:52,090 --> 01:40:55,060 When I edited my meow function last week in Scratch, 2252 01:40:55,060 --> 01:40:58,240 I specified that I want it now to take an input called n, 2253 01:40:58,240 --> 01:41:00,160 which represents some number of times. 2254 01:41:00,160 --> 01:41:03,520 And I changed my repeat block not to be 3 perpetually, 2255 01:41:03,520 --> 01:41:07,240 but to actually have n generally baked in there instead. 2256 01:41:07,240 --> 01:41:09,490 Or actually, instead of just saying play sound "meow," 2257 01:41:09,490 --> 01:41:14,230 I had a repeat block using n as the placeholder instead of a hard coded 3. 2258 01:41:14,230 --> 01:41:16,750 So how can I now use this in C? 2259 01:41:16,750 --> 01:41:20,090 In C, It's almost the same. 2260 01:41:20,090 --> 01:41:23,160 It's still void at the beginning of my function name, 2261 01:41:23,160 --> 01:41:24,690 which means no output still. 2262 01:41:24,690 --> 01:41:26,160 It only has side effects. 2263 01:41:26,160 --> 01:41:31,670 But what did change vis-Ă¡-vis the previous version of meow? 2264 01:41:31,670 --> 01:41:33,210 What has changed? 2265 01:41:33,210 --> 01:41:34,250 AUDIENCE: [INAUDIBLE] 2266 01:41:34,250 --> 01:41:35,250 DAVID J. MALAN: Exactly. 2267 01:41:35,250 --> 01:41:38,200 Instead of saying "void" a second time in parentheses, 2268 01:41:38,200 --> 01:41:43,180 it literally says "int n" inside of those parentheses, which means, in C, 2269 01:41:43,180 --> 01:41:45,670 this function called meow takes input. 2270 01:41:45,670 --> 01:41:47,920 It means the exact same thing as the pink on the left. 2271 01:41:47,920 --> 01:41:50,503 And again, this is why we keep emphasizing the Scratch blocks. 2272 01:41:50,503 --> 01:41:53,230 Like, no new ideas with a lot of these features. 2273 01:41:53,230 --> 01:41:56,410 It's just different syntax that you'll get used to over time. 2274 01:41:56,410 --> 01:42:00,100 So if I go back into VS Code here and I change this function, let's do that. 2275 01:42:00,100 --> 01:42:04,390 Let's change my prototype to be int n, where n represents some number of times. 2276 01:42:04,390 --> 01:42:08,490 Let's change the actual function on line 14 to also have int n here. 2277 01:42:08,490 --> 01:42:13,830 And let's actually move the for loop from main into the meow function 2278 01:42:13,830 --> 01:42:16,540 such that I now have my curly braces here. 2279 01:42:16,540 --> 01:42:19,740 I have my print statement inside of those curly braces. 2280 01:42:19,740 --> 01:42:23,680 And now, in main, I can get rid of all of that code. 2281 01:42:23,680 --> 01:42:26,877 Just say "meow" any number of times, like three. 2282 01:42:26,877 --> 01:42:30,210 And just like I did with Scratch, let me hit Enter an arbitrary number of times. 2283 01:42:30,210 --> 01:42:32,230 Sort of out of sight, out of mind. 2284 01:42:32,230 --> 01:42:37,120 Now the essence of my program is one real line of code-- "meow" three times-- 2285 01:42:37,120 --> 01:42:42,040 because I've abstracted away the idea of meowing and told the cat, instead, 2286 01:42:42,040 --> 01:42:47,550 exactly how many times to meow by way of that function. 2287 01:42:47,550 --> 01:42:49,622 OK, I can't keep stringing along cookies so long. 2288 01:42:49,622 --> 01:42:51,580 Let's go ahead and take a 10-minute break here. 2289 01:42:51,580 --> 01:42:55,680 And when we come back, more cats, more code. 2290 01:42:55,680 --> 01:42:57,270 All right. 2291 01:42:57,270 --> 01:42:59,460 So we are back. 2292 01:42:59,460 --> 01:43:03,443 And I want to add one final flourish to this program because now, 2293 01:43:03,443 --> 01:43:05,610 more so than a lot of the examples, now the programs 2294 01:43:05,610 --> 01:43:07,150 are starting to grow in length. 2295 01:43:07,150 --> 01:43:10,750 And indeed, soon there'll be a few dozen lines of code, which is not uncommon. 2296 01:43:10,750 --> 01:43:14,790 But let's suppose that we want to stop hard-coding 3 everywhere and actually 2297 01:43:14,790 --> 01:43:18,445 prompt the user for some number of meows here. 2298 01:43:18,445 --> 01:43:19,320 Well, let me do this. 2299 01:43:19,320 --> 01:43:24,180 In VS Code, I'm going to go ahead and get rid of this one line for now. 2300 01:43:24,180 --> 01:43:25,930 And let's do something like this. 2301 01:43:25,930 --> 01:43:28,720 Let's ask the user for an integer. 2302 01:43:28,720 --> 01:43:32,070 So int, maybe n for number, equals get_int. 2303 01:43:32,070 --> 01:43:35,730 And we'll say something like just "Number" to give a number of meows. 2304 01:43:35,730 --> 01:43:40,120 And then we'll go ahead and actually call meow, passing in not 3 this time, 2305 01:43:40,120 --> 01:43:41,130 but passing in n. 2306 01:43:41,130 --> 01:43:43,650 So we are using the return value of get_int 2307 01:43:43,650 --> 01:43:47,180 to store it in a variable called n on line 8. 2308 01:43:47,180 --> 01:43:51,220 And then we are passing n as the input, or argument, to the function 2309 01:43:51,220 --> 01:43:53,150 called meow on line 9. 2310 01:43:53,150 --> 01:43:57,860 And again, the actual implementation of meow on line 22 onward, who cares? 2311 01:43:57,860 --> 01:43:59,150 Out of sight, out of mind. 2312 01:43:59,150 --> 01:44:01,730 Once it exists, we can abstract it away mentally. 2313 01:44:01,730 --> 01:44:04,102 But I'll keep it up tight here anyway. 2314 01:44:04,102 --> 01:44:06,560 All right, so let me go ahead and open my terminal window-- 2315 01:44:06,560 --> 01:44:09,860 make cat, "./cat," "Number"-- 2316 01:44:09,860 --> 01:44:11,720 I can still type in 3, and it works. 2317 01:44:11,720 --> 01:44:14,030 Or I can go ahead and type in 5. 2318 01:44:14,030 --> 01:44:15,170 "Meow," "meow," "meow." 2319 01:44:15,170 --> 01:44:18,620 But, hm, it's not actually meowing five times. 2320 01:44:18,620 --> 01:44:20,126 Why? 2321 01:44:20,126 --> 01:44:22,950 [WHISPERS] I didn't realize this either, but there's a bug. 2322 01:44:22,950 --> 01:44:24,480 AUDIENCE: [INAUDIBLE] 2323 01:44:24,480 --> 01:44:26,140 DAVID J. MALAN: Yeah, exactly. 2324 01:44:26,140 --> 01:44:28,930 So the for loop, when I copy/pasted it before, before break, 2325 01:44:28,930 --> 01:44:32,700 I actually got lazy and I forgot to change the 3 to an n 2326 01:44:32,700 --> 01:44:38,080 so that it matches the name of the argument that's being passed into meow. 2327 01:44:38,080 --> 01:44:40,270 So that was a bug-- unintentional on my part. 2328 01:44:40,270 --> 01:44:41,610 But we have now fixed it here. 2329 01:44:41,610 --> 01:44:45,460 And now we are passing this in from main to meow. 2330 01:44:45,460 --> 01:44:51,700 So if I make cat, "./cat", and type 5 this time, I indeed get five meows. 2331 01:44:51,700 --> 01:44:55,290 But it's worth noting there's some subtleties here in my code 2332 01:44:55,290 --> 01:44:57,550 in that I've used n a couple of times. 2333 01:44:57,550 --> 01:45:02,490 So this is actually deliberate, that I've used n twice in this way, 2334 01:45:02,490 --> 01:45:04,330 to induce a bit of confusion. 2335 01:45:04,330 --> 01:45:10,360 But it turns out this n is actually not the same as this n, nor this one. 2336 01:45:10,360 --> 01:45:11,865 So what's going on here? 2337 01:45:11,865 --> 01:45:14,740 Well, it turns out, in programming, there's often this idea of scope. 2338 01:45:14,740 --> 01:45:18,720 And long story short, generally speaking, variables only 2339 01:45:18,720 --> 01:45:22,470 exist in the scope in which you create them. 2340 01:45:22,470 --> 01:45:25,450 More down to Earth, variables only exist inside 2341 01:45:25,450 --> 01:45:28,250 of the curly braces in which you define them. 2342 01:45:28,250 --> 01:45:30,940 So for instance, suppose I got a little sloppy 2343 01:45:30,940 --> 01:45:34,840 and suppose I didn't bother giving meow an input 2344 01:45:34,840 --> 01:45:40,390 and I didn't bother giving its prototype an input and I just used n on line 14 2345 01:45:40,390 --> 01:45:41,370 because, why? 2346 01:45:41,370 --> 01:45:43,880 Well, I already defined n on line 8. 2347 01:45:43,880 --> 01:45:46,510 So this is just an alternate universe in which 2348 01:45:46,510 --> 01:45:49,250 I'm not changing meow to take input. 2349 01:45:49,250 --> 01:45:54,933 I'm just using n in two different functions, in main on line 8 and 9-- 2350 01:45:54,933 --> 01:45:56,350 actually, I don't even need that-- 2351 01:45:56,350 --> 01:46:00,350 on line 8 and 9 and also again on line 14. 2352 01:46:00,350 --> 01:46:02,140 This code will not work. 2353 01:46:02,140 --> 01:46:03,890 The compiler will not like this. 2354 01:46:03,890 --> 01:46:04,390 Why? 2355 01:46:04,390 --> 01:46:07,730 Because n does not exist inside of meow. 2356 01:46:07,730 --> 01:46:08,230 Why? 2357 01:46:08,230 --> 01:46:11,170 Per the heuristic I offered, n exists only inside 2358 01:46:11,170 --> 01:46:15,320 of the curly braces in which it was defined, namely these curly braces here. 2359 01:46:15,320 --> 01:46:18,560 So n is in scope in main, so to speak. 2360 01:46:18,560 --> 01:46:20,660 But it is not in scope in meow. 2361 01:46:20,660 --> 01:46:23,170 And that's why we have to jump through these hoops 2362 01:46:23,170 --> 01:46:25,690 and use inputs and outputs and inputs and outputs 2363 01:46:25,690 --> 01:46:31,270 and pass things around among functions without sharing things across functions 2364 01:46:31,270 --> 01:46:31,970 instead. 2365 01:46:31,970 --> 01:46:37,842 Now, I could clarify this and maybe change my argument here from n to times. 2366 01:46:37,842 --> 01:46:39,550 If I want to make clear that, oh, this is 2367 01:46:39,550 --> 01:46:45,140 the number of times I want meow to be said, I don't have to use n for both. 2368 01:46:45,140 --> 01:46:48,080 But just realize that, if you do, it's just a coincidence. 2369 01:46:48,080 --> 01:46:51,790 They are not usable in two different scopes. 2370 01:46:51,790 --> 01:46:55,390 All right, let's do one other thing, though. 2371 01:46:55,390 --> 01:46:58,828 Let's not only prompt the user for the number here, 2372 01:46:58,828 --> 01:47:01,370 let's make sure that it makes sense what number they give us. 2373 01:47:01,370 --> 01:47:05,720 So if I do make cat-- just to clean things up-- "./cat," suppose I type 0, 2374 01:47:05,720 --> 01:47:07,430 OK, I suppose that's correct. 2375 01:47:07,430 --> 01:47:11,030 If I say meow 0 times and it doesn't meow at all, that's arguably correct. 2376 01:47:11,030 --> 01:47:13,250 But if I type in something like negative 5, 2377 01:47:13,250 --> 01:47:17,060 it ignores me, which I guess is better than crashing or freezing or something. 2378 01:47:17,060 --> 01:47:19,930 But ideally, it might be nice to handle this situation. 2379 01:47:19,930 --> 01:47:24,063 And if they give me a negative number, prompt them again for a positive number. 2380 01:47:24,063 --> 01:47:25,730 Prompt them again for a positive number. 2381 01:47:25,730 --> 01:47:27,410 Make the program make sense. 2382 01:47:27,410 --> 01:47:28,580 So how could we do that? 2383 01:47:28,580 --> 01:47:29,830 Well, a couple of ways. 2384 01:47:29,830 --> 01:47:33,680 If I go back into my code here, I could do this. 2385 01:47:33,680 --> 01:47:38,390 I could maybe do something like a loop or-- let's see. 2386 01:47:38,390 --> 01:47:43,520 So if I get n, so if n is less than 1, then it makes no sense. 2387 01:47:43,520 --> 01:47:46,550 So what do I want to do if n is less than 1? 2388 01:47:46,550 --> 01:47:48,430 Well, I could just prompt the user again. 2389 01:47:48,430 --> 01:47:50,120 And I say, OK, let's get n again. 2390 01:47:50,120 --> 01:47:53,840 And then I can say, if n is less than 1, what do I want to do? 2391 01:47:53,840 --> 01:47:55,850 I guess we could ask the user again. 2392 01:47:55,850 --> 01:48:00,290 And then if n is less than 1, I could just, again-- 2393 01:48:00,290 --> 01:48:03,100 I can give them three tries, four tries to get this right. 2394 01:48:03,100 --> 01:48:04,270 This is obviously stupid. 2395 01:48:04,270 --> 01:48:05,330 I'm copying and pasting. 2396 01:48:05,330 --> 01:48:06,530 I'm repeating myself. 2397 01:48:06,530 --> 01:48:07,970 There's no end in sight. 2398 01:48:07,970 --> 01:48:09,500 I can't do this forever, surely. 2399 01:48:09,500 --> 01:48:11,870 So this just feels like the wrong solution. 2400 01:48:11,870 --> 01:48:14,090 So there are different ways to solve this problem. 2401 01:48:14,090 --> 01:48:17,780 And funny enough, a while loop is not really the best way. 2402 01:48:17,780 --> 01:48:19,810 A do while loop is-- agh-- 2403 01:48:19,810 --> 01:48:21,530 a while loop is not the best way. 2404 01:48:21,530 --> 01:48:22,878 A for loop is not the best way. 2405 01:48:22,878 --> 01:48:24,670 It turns out there's one other type of loop 2406 01:48:24,670 --> 01:48:27,640 that we want to introduce that's super useful for getting 2407 01:48:27,640 --> 01:48:32,600 user input, potentially, again and again and again so that the user cooperates. 2408 01:48:32,600 --> 01:48:34,640 Specifically, what I'm going to do is this. 2409 01:48:34,640 --> 01:48:40,340 I'm going to literally say, do the following while something is true. 2410 01:48:40,340 --> 01:48:41,530 So it's more of a mouthful. 2411 01:48:41,530 --> 01:48:43,430 I'm spreading it out over multiple lines. 2412 01:48:43,430 --> 01:48:46,730 But what am I going to put inside of the do block here? 2413 01:48:46,730 --> 01:48:51,820 I'm going to say int n equals get_int and ask for that number as before, 2414 01:48:51,820 --> 01:48:53,600 closed quote, semicolon. 2415 01:48:53,600 --> 01:48:56,410 And I'm going to keep asking while-- 2416 01:48:56,410 --> 01:49:02,720 sorry, accidental Enter-- while n is less than 1, semicolon. 2417 01:49:02,720 --> 01:49:04,220 So notice the semantics of this. 2418 01:49:04,220 --> 01:49:06,060 Even though it's a little weird-looking, it 2419 01:49:06,060 --> 01:49:09,490 does read, in English, do the following. 2420 01:49:09,490 --> 01:49:11,050 Get an int stored in n. 2421 01:49:11,050 --> 01:49:14,000 And keep doing that while n is less than 1. 2422 01:49:14,000 --> 01:49:17,720 But this code as written is not quite going to work yet. 2423 01:49:17,720 --> 01:49:19,670 Let me try opening my terminal window. 2424 01:49:19,670 --> 01:49:21,410 Make cat, Enter. 2425 01:49:21,410 --> 01:49:25,363 Ugh, damn it-- "Use of undeclared identifier 'n.'" Well, 2426 01:49:25,363 --> 01:49:27,030 here's where the line number is helpful. 2427 01:49:27,030 --> 01:49:29,130 The line number is indicated here, 12. 2428 01:49:29,130 --> 01:49:30,690 And it's repeated here, 12. 2429 01:49:30,690 --> 01:49:32,800 So I clearly screwed up at line 12. 2430 01:49:32,800 --> 01:49:35,410 But there's not that much going on at line 12. 2431 01:49:35,410 --> 01:49:41,430 Why is n "undeclared" in line 12 even though I literally just declared it 2432 01:49:41,430 --> 01:49:43,669 in line 10? 2433 01:49:43,669 --> 01:49:46,847 AUDIENCE: Because it's [INAUDIBLE] inside of the [INAUDIBLE] line 2434 01:49:46,847 --> 01:49:47,935 10, not outside. 2435 01:49:47,935 --> 01:49:49,810 DAVID J. MALAN: Exactly, because I declared n 2436 01:49:49,810 --> 01:49:53,270 inside the scope of the do block, so to speak, 2437 01:49:53,270 --> 01:49:55,690 inside the curly braces on lines 9 and 11. 2438 01:49:55,690 --> 01:49:59,667 That variable n no longer exists by the time we get to line 12. 2439 01:49:59,667 --> 01:50:01,750 It'd be great if it did, but it doesn't because it 2440 01:50:01,750 --> 01:50:03,460 violates that heuristic I proposed, which 2441 01:50:03,460 --> 01:50:07,810 is that variables only exist in the scope of the curly braces in which they 2442 01:50:07,810 --> 01:50:08,880 were defined. 2443 01:50:08,880 --> 01:50:10,300 So how do I fix this? 2444 01:50:10,300 --> 01:50:16,430 Well, it turns out you can declare a variable in advance outside of one scope 2445 01:50:16,430 --> 01:50:18,950 but then define it, that is initialize it, elsewhere. 2446 01:50:18,950 --> 01:50:20,710 So the solution here is actually this. 2447 01:50:20,710 --> 01:50:25,100 Inside of the loop, just set an equal to the return value of get_int. 2448 01:50:25,100 --> 01:50:31,120 But per the heuristic, you've got to declare n, make it exist inside 2449 01:50:31,120 --> 01:50:33,852 of the outermost scope of this function. 2450 01:50:33,852 --> 01:50:34,810 So it's a little weird. 2451 01:50:34,810 --> 01:50:36,977 And we're kind of breaking this down into two steps. 2452 01:50:36,977 --> 01:50:40,130 But this is valid, recommended, correct C code. 2453 01:50:40,130 --> 01:50:43,580 You declare a variable without giving it any value initially. 2454 01:50:43,580 --> 01:50:47,260 And then, in line 11, you proceed to give it a value, 2455 01:50:47,260 --> 01:50:50,090 potentially again and again and again. 2456 01:50:50,090 --> 01:50:52,530 Now, what's useful about a do while loop? 2457 01:50:52,530 --> 01:50:56,100 So a do while loop, as the name implies, will do something no matter what. 2458 01:50:56,100 --> 01:50:59,520 But it will potentially do it again and again and again 2459 01:50:59,520 --> 01:51:06,780 while some question is true, like n being less than 1 in this case. 2460 01:51:06,780 --> 01:51:09,342 As an aside, why did we not do a while loop? 2461 01:51:09,342 --> 01:51:10,550 Well, let's think about that. 2462 01:51:10,550 --> 01:51:13,590 While n is less than 1-- 2463 01:51:13,590 --> 01:51:15,930 but wait a minute. n doesn't have a value. 2464 01:51:15,930 --> 01:51:20,360 OK, so I guess we have to go back to doing get_int, number, colon, semicolon. 2465 01:51:20,360 --> 01:51:20,860 OK. 2466 01:51:20,860 --> 01:51:24,260 But while n is less than 1, we're back to the same problem 2467 01:51:24,260 --> 01:51:26,340 where we have to repeat ourselves again. 2468 01:51:26,340 --> 01:51:29,750 So this is why for loops, while loops, not the right solution when 2469 01:51:29,750 --> 01:51:33,360 you want to do something at least once but potentially again and again. 2470 01:51:33,360 --> 01:51:37,830 So the right solution here, again, is this new and final looping construct-- 2471 01:51:37,830 --> 01:51:39,380 I'm just hitting Control-Z a lot-- 2472 01:51:39,380 --> 01:51:41,907 whereby we've done it as follows. 2473 01:51:41,907 --> 01:51:42,990 All right, let's try this. 2474 01:51:42,990 --> 01:51:45,560 Clear the screen. make cat, Enter. 2475 01:51:45,560 --> 01:51:46,580 "./cat." 2476 01:51:46,580 --> 01:51:47,910 Let's type in 5. 2477 01:51:47,910 --> 01:51:48,720 Still works. 2478 01:51:48,720 --> 01:51:49,940 Let's type in negative 5. 2479 01:51:49,940 --> 01:51:52,140 And notice it doesn't just ignore me. 2480 01:51:52,140 --> 01:51:54,780 It prompts me again and again and again. 2481 01:51:54,780 --> 01:51:58,890 Even if I type in 0, I've got to at least give it a positive integer. 2482 01:51:58,890 --> 01:52:01,280 Well, this actually seems kind of a common paradigm. 2483 01:52:01,280 --> 01:52:05,192 What if we want to prompt the user for a positive number in other programs too? 2484 01:52:05,192 --> 01:52:07,400 We're nearing the point already, even after just week 2485 01:52:07,400 --> 01:52:10,100 1, where it'd be nice to write our own reusable 2486 01:52:10,100 --> 01:52:11,970 functions that solve common problems. 2487 01:52:11,970 --> 01:52:15,763 And eventually, maybe we can put them in header files as well. 2488 01:52:15,763 --> 01:52:17,430 But for now, let's go ahead and do this. 2489 01:52:17,430 --> 01:52:19,430 I'm going to actually copy all of this code. 2490 01:52:19,430 --> 01:52:22,100 And I'm going to create one more function in this file 2491 01:52:22,100 --> 01:52:27,420 below main called get_positive_int, for integer. 2492 01:52:27,420 --> 01:52:29,570 And I'm going to specify that it doesn't need 2493 01:52:29,570 --> 01:52:32,390 any input because the only thing this function is going to do 2494 01:52:32,390 --> 01:52:34,260 is that exact same thing. 2495 01:52:34,260 --> 01:52:38,630 So notice that I've just moved my code from main into a function that's name 2496 01:52:38,630 --> 01:52:41,270 describes what it does, "get_positive_int." 2497 01:52:41,270 --> 01:52:42,708 I'm declaring n here. 2498 01:52:42,708 --> 01:52:44,000 I'm doing this again and again. 2499 01:52:44,000 --> 01:52:46,680 And I'm doing that while n is less than 1. 2500 01:52:46,680 --> 01:52:48,442 And what am I going to do up here? 2501 01:52:48,442 --> 01:52:49,650 I can do something like this. 2502 01:52:49,650 --> 01:52:52,820 Give me a variable called times for, how many times do you want to meow? 2503 01:52:52,820 --> 01:52:57,257 And just call get_positive_int semicolon. 2504 01:52:57,257 --> 01:52:59,090 So now, again, we've abstracted things away. 2505 01:52:59,090 --> 01:53:01,290 And just like in Scratch, our final example-- 2506 01:53:01,290 --> 01:53:03,720 which, recall, looked a little something like this, 2507 01:53:03,720 --> 01:53:06,740 where we just called a function to meow three times-- now 2508 01:53:06,740 --> 01:53:08,520 we're calling a function to get text. 2509 01:53:08,520 --> 01:53:11,940 If I hit Enter an arbitrary dramatic number of times, out of sight, 2510 01:53:11,940 --> 01:53:15,200 out of mind, I now have two functions in this world, get_positive_int 2511 01:53:15,200 --> 01:53:19,800 and meow that are collectively implementing this entire program. 2512 01:53:19,800 --> 01:53:21,990 But it's not quite correct. 2513 01:53:21,990 --> 01:53:24,380 There's one mistake here still. 2514 01:53:24,380 --> 01:53:29,240 Notice that get_positive_int is written slightly differently 2515 01:53:29,240 --> 01:53:31,200 from the meow function. 2516 01:53:31,200 --> 01:53:34,460 And just to be clear, too, let me copy its prototype to the top of the file 2517 01:53:34,460 --> 01:53:36,710 just so we don't make that same mistake I made earlier 2518 01:53:36,710 --> 01:53:40,340 where I didn't put the prototype at top so C didn't know what it was. 2519 01:53:40,340 --> 01:53:44,490 What is different about these two prototypes at a glance? 2520 01:53:44,490 --> 01:53:45,495 Yeah. 2521 01:53:45,495 --> 01:53:48,290 AUDIENCE: get_positive_int should be returning int. 2522 01:53:48,290 --> 01:53:50,540 DAVID J. MALAN: OK, so get_positive_int apparently-- 2523 01:53:50,540 --> 01:53:52,760 and we've not talked much about this-- apparently 2524 01:53:52,760 --> 01:53:55,410 does have an output of type integer. 2525 01:53:55,410 --> 01:53:57,720 It's supposed to return an int, hand me back an int. 2526 01:53:57,720 --> 01:53:59,160 It doesn't have any input. 2527 01:53:59,160 --> 01:54:01,080 That's what the "void" in parentheses meant. 2528 01:54:01,080 --> 01:54:03,020 No input, but yes output. 2529 01:54:03,020 --> 01:54:06,690 And meow, funny enough, is the opposite-- yes input, no output. 2530 01:54:06,690 --> 01:54:07,190 Why? 2531 01:54:07,190 --> 01:54:09,200 Because it has a side effect, the visual thing, 2532 01:54:09,200 --> 01:54:11,658 where it prints something to the screen but doesn't hand me 2533 01:54:11,658 --> 01:54:15,630 any useful value back like the ask function or the ask puzzle piece did. 2534 01:54:15,630 --> 01:54:17,690 So these are opposite in functionality, which 2535 01:54:17,690 --> 01:54:22,820 means I actually need to return an integer from this function to whatever 2536 01:54:22,820 --> 01:54:24,900 function wants to use it. 2537 01:54:24,900 --> 01:54:28,710 So if I want the assignment operator to work here on line 9, 2538 01:54:28,710 --> 01:54:31,190 I need to do what, all this time, get_int, get_string, 2539 01:54:31,190 --> 01:54:33,390 and other CS50 functions have been doing. 2540 01:54:33,390 --> 01:54:38,360 I need to, in my own function, return that value literally 2541 01:54:38,360 --> 01:54:40,260 with a new keyword called return. 2542 01:54:40,260 --> 01:54:42,150 And this is why I keep sticking out my hand. 2543 01:54:42,150 --> 01:54:46,940 When you want a function to hand you back a value, you literally use "return" 2544 01:54:46,940 --> 01:54:48,400 and then that value. 2545 01:54:48,400 --> 01:54:52,770 That's why we have "return" value as a term of art, literally the "return" 2546 01:54:52,770 --> 01:54:53,680 keyword. 2547 01:54:53,680 --> 01:54:58,480 So if I open my terminal window now, make cat, Enter-- 2548 01:54:58,480 --> 01:55:00,990 huh, I did screw up accidentally. 2549 01:55:00,990 --> 01:55:02,000 How? 2550 01:55:02,000 --> 01:55:02,500 Yeah. 2551 01:55:02,500 --> 01:55:03,780 AUDIENCE: [INAUDIBLE] 2552 01:55:03,780 --> 01:55:06,820 DAVID J. MALAN: Yeah, so on lines 9 and 10, I made a quick change. 2553 01:55:06,820 --> 01:55:08,200 I changed my variable to times. 2554 01:55:08,200 --> 01:55:09,910 But I stupidly didn't change this. 2555 01:55:09,910 --> 01:55:10,630 So that's fine. 2556 01:55:10,630 --> 01:55:13,060 That's why n was undeclared in that context. 2557 01:55:13,060 --> 01:55:15,450 Let me clear my terminal, make cat once more. 2558 01:55:15,450 --> 01:55:17,040 OK, that worked. "./cat." 2559 01:55:17,040 --> 01:55:18,270 Let's type in 5. 2560 01:55:18,270 --> 01:55:19,570 And it's still working. 2561 01:55:19,570 --> 01:55:21,977 So again, even though the code feels like it's-- sorry-- 2562 01:55:21,977 --> 01:55:24,310 even though the code is growing and growing and growing, 2563 01:55:24,310 --> 01:55:28,420 it's the exact same program we wrote super simply before break. 2564 01:55:28,420 --> 01:55:30,460 But now we're sort of modularizing it. 2565 01:55:30,460 --> 01:55:32,440 We're creating reusable functions. 2566 01:55:32,440 --> 01:55:35,160 And this is why functions like get_string exists, get_int exists. 2567 01:55:35,160 --> 01:55:36,840 Like, CS50 wrote those years ago. 2568 01:55:36,840 --> 01:55:40,140 And we realized, why are we copying and pasting these functions in all 2569 01:55:40,140 --> 01:55:41,950 of these different CS50 programs? 2570 01:55:41,950 --> 01:55:45,960 Let's factor out that functionality into a function of our own-- get_int, 2571 01:55:45,960 --> 01:55:47,020 get_string. 2572 01:55:47,020 --> 01:55:50,560 Just like here, I'm proposing to factor out this functionality, 2573 01:55:50,560 --> 01:55:54,430 get a positive integer that gives you even more precise functionality 2574 01:55:54,430 --> 01:55:58,270 so theoretically you could use and reuse it in other programs too. 2575 01:55:58,270 --> 01:56:00,120 By not even just putting it here, we could 2576 01:56:00,120 --> 01:56:05,650 go put it in a file of your own name and include it in future programs as well. 2577 01:56:05,650 --> 01:56:07,100 That's all a library is. 2578 01:56:07,100 --> 01:56:10,040 Someone realized, jeez, other people, including myself, 2579 01:56:10,040 --> 01:56:12,560 might find this function useful again and again. 2580 01:56:12,560 --> 01:56:15,860 Let's package it up in our own custom functions, 2581 01:56:15,860 --> 01:56:18,500 just like our custom meow puzzle piece last week, 2582 01:56:18,500 --> 01:56:21,350 so we can indeed use it again and again. 2583 01:56:21,350 --> 01:56:25,150 And the takeaways for now is that unlike Scratch, which was a little more user 2584 01:56:25,150 --> 01:56:29,290 friendly, in C, you have to specify if you want your functions to have inputs. 2585 01:56:29,290 --> 01:56:33,290 And you must specify if you want them to have outputs as well. 2586 01:56:33,290 --> 01:56:35,510 But more on that syntax to come. 2587 01:56:35,510 --> 01:56:37,160 So where does that bring us? 2588 01:56:37,160 --> 01:56:40,070 So after all this discussion of code, at the end of the day, 2589 01:56:40,070 --> 01:56:42,565 this is what's important in the world of programming. 2590 01:56:42,565 --> 01:56:44,440 Not surprisingly, it's like, what's important 2591 01:56:44,440 --> 01:56:47,110 when it comes to grading and evaluating the quality of code? 2592 01:56:47,110 --> 01:56:49,030 One, and first and foremost, is correctness. 2593 01:56:49,030 --> 01:56:50,600 If the code does not do what it's supposed to do, 2594 01:56:50,600 --> 01:56:52,370 what was the point of writing the code? 2595 01:56:52,370 --> 01:56:54,410 So correctness sort of goes without saying. 2596 01:56:54,410 --> 01:56:56,238 Design, again, is much more qualitative. 2597 01:56:56,238 --> 01:56:58,780 It's like getting feedback, again, on an English essay, where 2598 01:56:58,780 --> 01:57:00,170 reasonable people might disagree. 2599 01:57:00,170 --> 01:57:01,790 You can make your argument better. 2600 01:57:01,790 --> 01:57:03,530 You can structure the paper better. 2601 01:57:03,530 --> 01:57:06,760 You can structure the code better in the case of programming. 2602 01:57:06,760 --> 01:57:08,900 And style is purely aesthetic. 2603 01:57:08,900 --> 01:57:09,830 Does it look good? 2604 01:57:09,830 --> 01:57:11,570 Is it pretty printed, so to speak? 2605 01:57:11,570 --> 01:57:15,280 Can other people, colleagues future and classmates present, actually 2606 01:57:15,280 --> 01:57:16,610 read and understand it? 2607 01:57:16,610 --> 01:57:18,350 That's what we mean by style. 2608 01:57:18,350 --> 01:57:21,200 Nicely enough, within CS50's programming environment, 2609 01:57:21,200 --> 01:57:25,640 you will have tools to evaluate the quality of all three of these axes, 2610 01:57:25,640 --> 01:57:26,150 so to speak. 2611 01:57:26,150 --> 01:57:29,500 So in problem set 1 onward, you'll be introduced to a command line tool 2612 01:57:29,500 --> 01:57:32,470 that you type its name at the prompt called check50 that will check 2613 01:57:32,470 --> 01:57:34,400 for you the correctness of your code-- 2614 01:57:34,400 --> 01:57:36,440 not necessarily exhaustively. 2615 01:57:36,440 --> 01:57:39,020 There might be mistakes you've made that we don't catch, 2616 01:57:39,020 --> 01:57:40,700 which doesn't make your code correct. 2617 01:57:40,700 --> 01:57:44,150 But it is a tool for finding many of the mistakes in your code. 2618 01:57:44,150 --> 01:57:46,810 In the real world, you would have colleagues or yourself, 2619 01:57:46,810 --> 01:57:49,880 would write tests for code you wrote or someone else wrote. 2620 01:57:49,880 --> 01:57:52,100 So testing code is not just a grading thing. 2621 01:57:52,100 --> 01:57:56,540 It is a real-world thing to ensure that systems are designed correctly. 2622 01:57:56,540 --> 01:57:59,480 We saw the style50 tool in VS Code already. 2623 01:57:59,480 --> 01:58:00,830 You click the "style50" button. 2624 01:58:00,830 --> 01:58:03,880 There is now, thanks to the Duck, a "design50" button too, 2625 01:58:03,880 --> 01:58:07,540 also in that top right-hand corner, whereby once your code is correct 2626 01:58:07,540 --> 01:58:11,500 and working, like several of my programs have been, you can click "design50," 2627 01:58:11,500 --> 01:58:15,710 and the Duck will not just quack but give you qualitative advice, if it can, 2628 01:58:15,710 --> 01:58:18,967 on how you can make that code even better even before you submit. 2629 01:58:18,967 --> 01:58:21,550 And of course, there's all of us humans in the room and online 2630 01:58:21,550 --> 01:58:25,070 that you can ask these same questions of as well. 2631 01:58:25,070 --> 01:58:29,920 So let's now solve some real-world but still simple problems as opposed 2632 01:58:29,920 --> 01:58:33,470 to emphasizing small bite-size as we have thus far. 2633 01:58:33,470 --> 01:58:35,980 So the first of these programs falls into this category 2634 01:58:35,980 --> 01:58:37,100 of having side effects. 2635 01:58:37,100 --> 01:58:40,310 So let's implement one or more functions that takes an argument's inputs 2636 01:58:40,310 --> 01:58:42,920 and, as its output, produces these visual side effects. 2637 01:58:42,920 --> 01:58:46,420 We'll draw inspiration from Super Mario Brothers-- not surprisingly, perhaps, 2638 01:58:46,420 --> 01:58:49,450 here-- the original one, which was very two-dimensional, side-scroller, 2639 01:58:49,450 --> 01:58:50,060 left to right. 2640 01:58:50,060 --> 01:58:52,300 Mario or Luigi move from left to right and generally 2641 01:58:52,300 --> 01:58:56,270 have to jump over things like pyramids or other shapes on the screen. 2642 01:58:56,270 --> 01:58:59,920 So how might we go about implementing some of the screens 2643 01:58:59,920 --> 01:59:02,197 from Super Mario Brothers, albeit textually? 2644 01:59:02,197 --> 01:59:04,030 Well, we'll make it a little black and white 2645 01:59:04,030 --> 01:59:07,640 and ASCII art, so to speak, here using just our keyboard. 2646 01:59:07,640 --> 01:59:10,960 But suppose we want to write a program called mario.c 2647 01:59:10,960 --> 01:59:12,798 that just prints out four question marks. 2648 01:59:12,798 --> 01:59:15,590 It's not going to be nearly as pretty as what's on the screen here. 2649 01:59:15,590 --> 01:59:19,060 But the logic is going to be the exact same as what Nintendo presumably 2650 01:59:19,060 --> 01:59:20,420 did years ago. 2651 01:59:20,420 --> 01:59:23,210 So let me open VS Code, my terminal window. 2652 01:59:23,210 --> 01:59:25,630 Let's code a program called mario.c. 2653 01:59:25,630 --> 01:59:28,450 In mario.c, I'm going to start with some boilerplate-- 2654 01:59:28,450 --> 01:59:29,570 I know I want to print. 2655 01:59:29,570 --> 01:59:33,310 So even if I don't know how to do this yet, I'm going to include standard io.h. 2656 01:59:33,310 --> 01:59:35,770 For today's purposes, I'm going to copy/paste or type 2657 01:59:35,770 --> 01:59:38,290 out that same line again and again-- int meow(void). 2658 01:59:38,290 --> 01:59:42,890 And inside of my main function, akin to the green flag being clicked, 2659 01:59:42,890 --> 01:59:45,473 I want to go ahead and print out four question marks. 2660 01:59:45,473 --> 01:59:47,890 Well, honestly, the simplest way I can think of doing this 2661 01:59:47,890 --> 01:59:51,170 is with printf question mark, question mark, question mark, question mark. 2662 01:59:51,170 --> 01:59:54,050 Maybe a backslash n to move the cursor, and that's it. 2663 01:59:54,050 --> 01:59:55,850 So that is arguably correct. 2664 01:59:55,850 --> 01:59:59,300 So let's do make mario in the terminal, "./mario." 2665 01:59:59,300 --> 02:00:02,570 And it's not quite as pretty as the game version of it. 2666 02:00:02,570 --> 02:00:04,700 But it is, in fact, the exact same idea. 2667 02:00:04,700 --> 02:00:08,770 But here, sort of an opportunity, a stepping stone to do better design. 2668 02:00:08,770 --> 02:00:10,005 This game changes over time. 2669 02:00:10,005 --> 02:00:12,380 And not all of the screens have just four question marks. 2670 02:00:12,380 --> 02:00:14,690 It might be five, six, or even more. 2671 02:00:14,690 --> 02:00:16,630 So what's the right programming construct 2672 02:00:16,630 --> 02:00:20,890 with which we could generalize how many question marks are printing here? 2673 02:00:20,890 --> 02:00:24,437 What feature of C do we want? 2674 02:00:24,437 --> 02:00:27,020 A loop, like a for loop, a while loop, or something like that. 2675 02:00:27,020 --> 02:00:28,603 And there's different ways to do this. 2676 02:00:28,603 --> 02:00:30,820 But honestly, I've proposed earlier that we 2677 02:00:30,820 --> 02:00:34,220 get into the habit of reaching for for loops as just very conventional. 2678 02:00:34,220 --> 02:00:39,072 So let's do that. for int i equals 0; i less than 4-- 2679 02:00:39,072 --> 02:00:41,030 because that's how many I want for the moment-- 2680 02:00:41,030 --> 02:00:42,010 i++. 2681 02:00:42,010 --> 02:00:44,740 And then inside of my curly braces there, let's go ahead 2682 02:00:44,740 --> 02:00:50,270 and print out, quote, unquote, a single question mark, but no new line. 2683 02:00:50,270 --> 02:00:52,630 Let me now go ahead and make mario. 2684 02:00:52,630 --> 02:00:58,400 And can you anticipate an arguably aesthetic bug when I hit Enter? 2685 02:00:58,400 --> 02:01:02,000 It's not going to move the cursor to the next line. 2686 02:01:02,000 --> 02:01:04,130 But the solution here is a little non-obvious. 2687 02:01:04,130 --> 02:01:06,010 I don't think this helps me. 2688 02:01:06,010 --> 02:01:10,190 If I put the backslash n there and I do make mario again and "./mario," 2689 02:01:10,190 --> 02:01:12,625 what is this output going to look like instead? 2690 02:01:12,625 --> 02:01:13,500 AUDIENCE: [INAUDIBLE] 2691 02:01:13,500 --> 02:01:15,333 DAVID J. MALAN: Yeah, like a vertical column 2692 02:01:15,333 --> 02:01:18,310 of question marks, which, while nice enough, is not the goal at hand. 2693 02:01:18,310 --> 02:01:20,080 The goal is these horizontal ones. 2694 02:01:20,080 --> 02:01:24,255 So someone else, what's the fix here, if clearly putting the backslash n 2695 02:01:24,255 --> 02:01:26,596 inside of line 7 is wrong? 2696 02:01:26,596 --> 02:01:28,300 AUDIENCE: [INAUDIBLE] 2697 02:01:28,300 --> 02:01:32,240 DAVID J. MALAN: Yeah, so put it after the loop, and not after the printf line, 2698 02:01:32,240 --> 02:01:37,210 specifically after and thus outside of the loop so that after that loop is 2699 02:01:37,210 --> 02:01:41,710 finished executing three total times, it's totally fine to just print nothing 2700 02:01:41,710 --> 02:01:46,240 other than a backslash n so long as we now recompile the code, make mario, 2701 02:01:46,240 --> 02:01:47,170 "./mario." 2702 02:01:47,170 --> 02:01:49,980 And, voila, now we have four in a row. 2703 02:01:49,980 --> 02:01:51,080 It's a little generalized. 2704 02:01:51,080 --> 02:01:53,922 OK, so we've sort of plucked off a fairly easy problem. 2705 02:01:53,922 --> 02:01:55,630 Well, let's go back to the world of Mario 2706 02:01:55,630 --> 02:01:57,963 and try something that is, in fact, vertical, like this. 2707 02:01:57,963 --> 02:02:00,093 So this is another scene with three bricks here. 2708 02:02:00,093 --> 02:02:03,260 Instead of using question marks, we'll use hash symbols to represent bricks. 2709 02:02:03,260 --> 02:02:08,420 This actually is the incarnation of my mistake a moment ago. 2710 02:02:08,420 --> 02:02:11,080 So let me undo this by getting rid of that printf. 2711 02:02:11,080 --> 02:02:13,720 Let me change the inside one from a question mark 2712 02:02:13,720 --> 02:02:17,690 to a hash symbol, which looks the most similar in ASCII to a brick. 2713 02:02:17,690 --> 02:02:20,420 And let's go ahead and put a backslash n after that. 2714 02:02:20,420 --> 02:02:25,010 If I do go ahead and do make mario, "./mario", it's not that interesting. 2715 02:02:25,010 --> 02:02:28,140 But-- and it's actually not that correct because I wanted three. 2716 02:02:28,140 --> 02:02:29,400 So no big deal. 2717 02:02:29,400 --> 02:02:32,280 I can, of course, go back to my code and change the 4 to a 3. 2718 02:02:32,280 --> 02:02:35,990 Or better yet, I could use get_int or my new get_positive_int function 2719 02:02:35,990 --> 02:02:40,440 and just generalize this further so that I can print out any number of them. 2720 02:02:40,440 --> 02:02:43,550 But for now "./mario" gives me three. 2721 02:02:43,550 --> 02:02:46,260 All right, so we've plucked off the second of two problems. 2722 02:02:46,260 --> 02:02:48,630 Let's now let things escalate a bit. 2723 02:02:48,630 --> 02:02:50,940 So it turns out, once you get to World 2 and beyond, 2724 02:02:50,940 --> 02:02:52,730 there are some underground parts of Mario 2725 02:02:52,730 --> 02:02:56,580 where you actually have bigger, more solid bricks like these here. 2726 02:02:56,580 --> 02:03:00,000 And just by eyeballing it, this is a 3-by-3 grid of bricks, 2727 02:03:00,000 --> 02:03:02,490 like nine of them total, we'll conjecture. 2728 02:03:02,490 --> 02:03:04,680 So how can I go about implementing this? 2729 02:03:04,680 --> 02:03:07,370 Well, now is where the program gets a little more interesting. 2730 02:03:07,370 --> 02:03:11,930 And the not-- well, the poorly designed way to 2731 02:03:11,930 --> 02:03:19,080 do this would be like printf hash, hash, hash, backslash n, semicolon, 2732 02:03:19,080 --> 02:03:21,390 and then maybe printf, printf. 2733 02:03:21,390 --> 02:03:24,450 That's correct but not well designed. 2734 02:03:24,450 --> 02:03:26,610 So make mario, "./mario." 2735 02:03:26,610 --> 02:03:29,480 It doesn't look like a square, just because these hashes are 2736 02:03:29,480 --> 02:03:31,350 more vertical than they are horizontal. 2737 02:03:31,350 --> 02:03:33,480 But it is correct, this example. 2738 02:03:33,480 --> 02:03:34,860 But it's not very generalizable. 2739 02:03:34,860 --> 02:03:36,390 And this is literally hard coding. 2740 02:03:36,390 --> 02:03:37,110 I copy/pasted. 2741 02:03:37,110 --> 02:03:39,690 I'm just doing a lot of bad practices here. 2742 02:03:39,690 --> 02:03:41,190 So what could I do instead? 2743 02:03:41,190 --> 02:03:44,880 Well, it turns out we can combine today's ideas, including loops, 2744 02:03:44,880 --> 02:03:47,130 to do things again and again. 2745 02:03:47,130 --> 02:03:50,640 So what is this grid of bricks? 2746 02:03:50,640 --> 02:03:51,860 It's a 3-by-3. 2747 02:03:51,860 --> 02:03:56,395 So it's like a row and a row and a row. 2748 02:03:56,395 --> 02:03:58,770 And then within each row, there's column, column, column. 2749 02:03:58,770 --> 02:04:02,370 So it, too, is like an old-timey typewriter that prints one line, 2750 02:04:02,370 --> 02:04:04,740 then the next line, then the next line, and so forth. 2751 02:04:04,740 --> 02:04:07,230 So how can we conjure that in code? 2752 02:04:07,230 --> 02:04:10,800 Well, let me go ahead and do this. 2753 02:04:10,800 --> 02:04:13,380 I think a print approach would work like this. 2754 02:04:13,380 --> 02:04:17,780 For int i equals 0, i less than 3, i plus plus, 2755 02:04:17,780 --> 02:04:20,130 because I know I want to do something three times-- 2756 02:04:20,130 --> 02:04:22,050 but what do I want to do three times? 2757 02:04:22,050 --> 02:04:27,270 This loop kind of represents, in my mind's eye, row, row, row. 2758 02:04:27,270 --> 02:04:28,820 So in fact, I could be more pedantic. 2759 02:04:28,820 --> 02:04:32,600 If I want my i to mean something beyond int, I could say row 2760 02:04:32,600 --> 02:04:38,370 equals 0, row less than 3, row plus plus, just to help me think about it. 2761 02:04:38,370 --> 02:04:40,740 And then what do I want to do on each row? 2762 02:04:40,740 --> 02:04:43,050 What do I want to print? 2763 02:04:43,050 --> 02:04:45,550 Column, column, column, so brick, brick, brick. 2764 02:04:45,550 --> 02:04:48,820 So how do I print three bricks or any number of bricks? 2765 02:04:48,820 --> 02:04:53,070 Well, I could cheat and just do printf hash, hash, hash, backslash n. 2766 02:04:53,070 --> 02:04:55,120 But again, I can't generalize. 2767 02:04:55,120 --> 02:04:58,450 I can't take an input from the user and print four or five or six bricks. 2768 02:04:58,450 --> 02:05:00,730 So that's going to get me into trouble eventually. 2769 02:05:00,730 --> 02:05:02,350 So maybe I could use a loop. 2770 02:05:02,350 --> 02:05:08,650 So I could do for int i equals 0, i less than 3, i plus plus inside of my loop. 2771 02:05:08,650 --> 02:05:11,010 And then in here, I could print out one hash. 2772 02:05:11,010 --> 02:05:13,720 And that's kind of on the right direction, the right path, 2773 02:05:13,720 --> 02:05:16,980 because now I'm just using the simple building block, or brick, 2774 02:05:16,980 --> 02:05:18,700 but reusing it again and again. 2775 02:05:18,700 --> 02:05:21,880 And it's totally fine to have nested these columns in this way. 2776 02:05:21,880 --> 02:05:23,530 I used i out of habit. 2777 02:05:23,530 --> 02:05:25,000 But what would a better name be? 2778 02:05:25,000 --> 02:05:28,660 Well, maybe "column," or maybe just C-O-L, "col" for short, 2779 02:05:28,660 --> 02:05:32,370 so that my code is saying what it does for me. 2780 02:05:32,370 --> 02:05:35,320 And I don't have to use "row" or "column" explicitly. 2781 02:05:35,320 --> 02:05:36,490 I don't need to print them. 2782 02:05:36,490 --> 02:05:39,880 But I am using them as counters one after the other. 2783 02:05:39,880 --> 02:05:44,080 So let me go ahead and run make Mario, "./mario." 2784 02:05:44,080 --> 02:05:46,210 And I'm feeling good about this, but-- 2785 02:05:46,210 --> 02:05:47,350 ugh. 2786 02:05:47,350 --> 02:05:49,147 Damn it, there's nine bricks. 2787 02:05:49,147 --> 02:05:50,480 But they're not really laid out. 2788 02:05:50,480 --> 02:05:52,760 Why? 2789 02:05:52,760 --> 02:05:53,660 What's the fix? 2790 02:05:53,660 --> 02:05:54,495 Yeah. 2791 02:05:54,495 --> 02:05:56,558 AUDIENCE: You never went to a new line. 2792 02:05:56,558 --> 02:05:58,600 DAVID J. MALAN: Yeah, I never went to a new line. 2793 02:05:58,600 --> 02:06:00,770 And let me do what I think you're not going to suggest I do. 2794 02:06:00,770 --> 02:06:02,140 Let me just go to the obvious place. 2795 02:06:02,140 --> 02:06:04,348 All right, well, let's put one right after the brick. 2796 02:06:04,348 --> 02:06:07,130 But, of course, if I do make mario, "./mario," 2797 02:06:07,130 --> 02:06:08,810 I'm making the same mistake as before. 2798 02:06:08,810 --> 02:06:10,310 I'm printing out too many new lines. 2799 02:06:10,310 --> 02:06:14,890 So in between what lines do I actually want to print a new line? 2800 02:06:14,890 --> 02:06:15,850 Between, yeah? 2801 02:06:15,850 --> 02:06:16,762 AUDIENCE: 10 and 11. 2802 02:06:16,762 --> 02:06:18,220 DAVID J. MALAN: Yeah, so 10 and 11. 2803 02:06:18,220 --> 02:06:22,900 So outside of the inner loop but inside of the outer loop 2804 02:06:22,900 --> 02:06:24,280 so it happens again and again. 2805 02:06:24,280 --> 02:06:28,330 So let's just print out, as before, a single backslash n, semicolon. 2806 02:06:28,330 --> 02:06:31,600 Now let's do make mario, "./mario," Enter. 2807 02:06:31,600 --> 02:06:34,480 Ah, now it's generalized as I see fit. 2808 02:06:34,480 --> 02:06:37,470 And if I really wanted to dwell on this, I could go in 2809 02:06:37,470 --> 02:06:40,320 and I could prompt the user with get_int or with get_positive_int, 2810 02:06:40,320 --> 02:06:42,940 figure out what row and/or column should be. 2811 02:06:42,940 --> 02:06:44,980 We can make any size brick that we want. 2812 02:06:44,980 --> 02:06:47,227 But now we have a nice starting point. 2813 02:06:47,227 --> 02:06:50,310 But there's another way to think about this because I dare say, especially 2814 02:06:50,310 --> 02:06:52,140 for your first CS50 problem set, if you're 2815 02:06:52,140 --> 02:06:54,760 trying to print bricks and the world of Mario in this way, 2816 02:06:54,760 --> 02:06:58,530 it's probably not going to be obvious to come up with loops like this 2817 02:06:58,530 --> 02:07:02,340 and just magically get it working after 45 seconds in total. 2818 02:07:02,340 --> 02:07:03,970 It'll be a struggle at first. 2819 02:07:03,970 --> 02:07:06,190 But there are some patterns to follow. 2820 02:07:06,190 --> 02:07:09,030 So one, it's pretty conventional nonetheless 2821 02:07:09,030 --> 02:07:12,662 to use just i and then j and then k and then l. 2822 02:07:12,662 --> 02:07:15,120 And if you've got nested, nested, nested, nested for loops, 2823 02:07:15,120 --> 02:07:17,720 at some point nesting, you're probably writing bad code. 2824 02:07:17,720 --> 02:07:18,740 It's not well designed. 2825 02:07:18,740 --> 02:07:22,010 But one or two or maybe three nestings could be an OK thing. 2826 02:07:22,010 --> 02:07:26,210 But you cannot use and reuse i again and again. 2827 02:07:26,210 --> 02:07:26,740 Why? 2828 02:07:26,740 --> 02:07:30,520 Because if you're counting i here, but then you're changing i here 2829 02:07:30,520 --> 02:07:32,680 to do your columns left to right, you're going 2830 02:07:32,680 --> 02:07:34,460 to get all of your math out of sync. 2831 02:07:34,460 --> 02:07:38,200 So you need two separate variables. i and j are conventional. 2832 02:07:38,200 --> 02:07:40,370 Or row and column would work too. 2833 02:07:40,370 --> 02:07:43,160 But if we go back to this idea of rows and columns, 2834 02:07:43,160 --> 02:07:45,447 well, let me actually factor something out here. 2835 02:07:45,447 --> 02:07:46,780 And this might help you instead. 2836 02:07:46,780 --> 02:07:49,430 Suppose that you set out on this problem. 2837 02:07:49,430 --> 02:07:51,860 You know you want to do something three times. 2838 02:07:51,860 --> 02:07:55,580 But you don't quite understand how to print those rows. 2839 02:07:55,580 --> 02:07:59,900 Well, take a baby step, a bite out of the problem, and maybe do this. 2840 02:07:59,900 --> 02:08:03,460 Create a function with no output, just a side effect whose purpose in life 2841 02:08:03,460 --> 02:08:05,000 is to print a row. 2842 02:08:05,000 --> 02:08:06,260 And how many rows? 2843 02:08:06,260 --> 02:08:08,500 Well, maybe n for some number of rows-- 2844 02:08:08,500 --> 02:08:10,420 for some number of bricks, rather. 2845 02:08:10,420 --> 02:08:11,940 How do you print a row of bricks? 2846 02:08:11,940 --> 02:08:13,940 Well, let me just think about this in isolation. 2847 02:08:13,940 --> 02:08:15,830 How do I print a single row of bricks? 2848 02:08:15,830 --> 02:08:19,900 That's easy-- for int i equals 0, i is less than n-- 2849 02:08:19,900 --> 02:08:24,250 if I'm generalizing-- i++, and then-- whoops, i++. 2850 02:08:24,250 --> 02:08:29,470 And then, inside of my curly braces, go ahead and just print out a single hash. 2851 02:08:29,470 --> 02:08:33,890 And at the end, as you suggested, print out a single new line. 2852 02:08:33,890 --> 02:08:39,045 In other words, abstract away the idea of printing a single row. 2853 02:08:39,045 --> 02:08:41,170 And in fact, at this point in the story, especially 2854 02:08:41,170 --> 02:08:44,337 if you're struggling to get started, you don't even need to start with main. 2855 02:08:44,337 --> 02:08:47,380 Take a bite out of the problem that makes sense to you that's smaller 2856 02:08:47,380 --> 02:08:51,610 than the whole problem, printing a single row because then you can come in 2857 02:08:51,610 --> 02:08:52,310 and iterate. 2858 02:08:52,310 --> 02:08:55,820 Then you can go in and say, OK, now let's write my actual main function. 2859 02:08:55,820 --> 02:08:57,740 So int meow(void), as always. 2860 02:08:57,740 --> 02:08:58,970 And now what do I want to do? 2861 02:08:58,970 --> 02:09:01,192 I want to print out a whole bunch of rows. 2862 02:09:01,192 --> 02:09:02,900 How do I print out a whole bunch of rows? 2863 02:09:02,900 --> 02:09:07,100 Oh, my god, it's like the same idea-- for int i equals 0, i is less than, 2864 02:09:07,100 --> 02:09:10,400 let's call it 3 for now-- but we can generalize that-- i++. 2865 02:09:10,400 --> 02:09:14,520 And what do I want to do on each iteration of this loop? 2866 02:09:14,520 --> 02:09:19,090 My gosh, just print row with three bricks. 2867 02:09:19,090 --> 02:09:21,362 And then we're sort of done. 2868 02:09:21,362 --> 02:09:23,320 Again, out of sight, out of mind, this function 2869 02:09:23,320 --> 02:09:26,480 can go away and never be seen before because once print_row exists, 2870 02:09:26,480 --> 02:09:28,790 that's what it in fact does for me. 2871 02:09:28,790 --> 02:09:30,800 Now, this isn't 100% correct. 2872 02:09:30,800 --> 02:09:33,740 I still need my prototype because if I've made my own function, 2873 02:09:33,740 --> 02:09:37,537 I need to tell C in advance that it shall exist. 2874 02:09:37,537 --> 02:09:39,620 So I need to copy and paste that one line of code. 2875 02:09:39,620 --> 02:09:42,910 If I were really being pedantic, this is bad design. 2876 02:09:42,910 --> 02:09:46,103 In general, when you have the same number in multiple places in a program, 2877 02:09:46,103 --> 02:09:48,020 a programmer would call this a "magic number." 2878 02:09:48,020 --> 02:09:49,750 Like, how is that working? 2879 02:09:49,750 --> 02:09:53,210 Just honor system, that you're using the same number again and again. 2880 02:09:53,210 --> 02:09:56,390 So a better solution here, even if you're not going to take user input, 2881 02:09:56,390 --> 02:09:59,290 would be to do this-- int n equals 3. 2882 02:09:59,290 --> 02:10:01,720 And then use n here. 2883 02:10:01,720 --> 02:10:03,470 And then use n here. 2884 02:10:03,470 --> 02:10:05,450 Or you could call it anything you want. 2885 02:10:05,450 --> 02:10:10,030 But now you've specified 3 in one and only one place. 2886 02:10:10,030 --> 02:10:11,660 And we can go one step further. 2887 02:10:11,660 --> 02:10:13,990 It turns out, in C and in other languages, 2888 02:10:13,990 --> 02:10:16,270 you can protect yourself against yourself. 2889 02:10:16,270 --> 02:10:19,370 If you know that a variable should never change its value, 2890 02:10:19,370 --> 02:10:23,050 it should always stay 3 in this case, you can use what's called a constant, 2891 02:10:23,050 --> 02:10:26,360 where you can specifically say, I don't want just n to be an int. 2892 02:10:26,360 --> 02:10:30,500 I want it to be a const int, "const" for short for "constant." 2893 02:10:30,500 --> 02:10:33,830 And this means even if I try to change n in my code, 2894 02:10:33,830 --> 02:10:35,680 the compiler will not let me. 2895 02:10:35,680 --> 02:10:38,650 So I can protect myself from myself, or in the real world, 2896 02:10:38,650 --> 02:10:41,200 you can use a variable that none of your colleagues 2897 02:10:41,200 --> 02:10:46,700 can foolishly change on you without you realizing that it has happened. 2898 02:10:46,700 --> 02:10:49,702 So a lot of programming, honestly, is just not 2899 02:10:49,702 --> 02:10:52,910 trusting yourself the next morning when you've forgotten what code you wrote, 2900 02:10:52,910 --> 02:10:54,743 let alone the next month, the next year when 2901 02:10:54,743 --> 02:10:56,390 you're writing code in the real world. 2902 02:10:56,390 --> 02:11:00,520 So constants just give us a feature to defend against ourselves. 2903 02:11:00,520 --> 02:11:02,270 There's another feature that's useful too, 2904 02:11:02,270 --> 02:11:04,510 especially when you wake up the next day and you're like, oh, my god, 2905 02:11:04,510 --> 02:11:05,600 how does this code work? 2906 02:11:05,600 --> 02:11:06,440 What does it do? 2907 02:11:06,440 --> 02:11:08,040 Well, there's comments in code. 2908 02:11:08,040 --> 02:11:10,040 And some of you might have used this in Scratch. 2909 02:11:10,040 --> 02:11:12,832 You could add little yellow sticky notes in Scratch for "comments." 2910 02:11:12,832 --> 02:11:15,250 In code, you can do something like this. 2911 02:11:15,250 --> 02:11:18,720 You can, if you want to put an English reminder to yourself, 2912 02:11:18,720 --> 02:11:21,630 or if you speak some other human language-- a comment in Spanish 2913 02:11:21,630 --> 02:11:24,850 or any other human language-- you can write it with a slash 2914 02:11:24,850 --> 02:11:26,380 slash at the start of the line. 2915 02:11:26,380 --> 02:11:31,350 And then you can say something like, print n rows. 2916 02:11:31,350 --> 02:11:36,510 And then this tells you, in a comment, what those subsequent lines of code 2917 02:11:36,510 --> 02:11:37,060 are doing. 2918 02:11:37,060 --> 02:11:38,260 It's sort of a note-to-self. 2919 02:11:38,260 --> 02:11:41,110 It has no functionality for the computer's sake. 2920 02:11:41,110 --> 02:11:43,180 It just is a note to yourself. 2921 02:11:43,180 --> 02:11:46,560 Or you can say something like this, like never change n, 2922 02:11:46,560 --> 02:11:48,880 because you're making clear that it's indeed constant. 2923 02:11:48,880 --> 02:11:53,080 But that, too, is a little pedantic since const says the same. 2924 02:11:53,080 --> 02:11:56,730 But comments are notes to self to help you remember what something is doing 2925 02:11:56,730 --> 02:11:59,710 or why you did it this way. 2926 02:11:59,710 --> 02:12:06,280 Questions now on any of these Mario problems that we have solved? 2927 02:12:06,280 --> 02:12:08,900 2928 02:12:08,900 --> 02:12:10,091 No? 2929 02:12:10,091 --> 02:12:12,418 All right, so one final set of examples that 2930 02:12:12,418 --> 02:12:14,460 push the limit of what computers can actually do. 2931 02:12:14,460 --> 02:12:16,585 Thus far, we've solved every problem I've proposed. 2932 02:12:16,585 --> 02:12:18,460 But that's because I've kind of been skirting 2933 02:12:18,460 --> 02:12:19,950 some of the underlying challenges. 2934 02:12:19,950 --> 02:12:22,460 So it turns out that we have not only functions that give us 2935 02:12:22,460 --> 02:12:24,240 side effects visually on the screen. 2936 02:12:24,240 --> 02:12:26,370 We again have functions that have return values. 2937 02:12:26,370 --> 02:12:29,870 So let's focus on those and where things can go wrong. 2938 02:12:29,870 --> 02:12:31,940 And let's use a bunch of other operators as well. 2939 02:12:31,940 --> 02:12:35,190 Suffice it to say, computers got their start by being really good calculators. 2940 02:12:35,190 --> 02:12:38,510 So computers support addition, subtraction, multiplication, division, 2941 02:12:38,510 --> 02:12:42,020 remainder operators, represented by the percent sign 2942 02:12:42,020 --> 02:12:45,150 here, which says take the remainder of something over something else. 2943 02:12:45,150 --> 02:12:47,130 And there's even more operators than this. 2944 02:12:47,130 --> 02:12:49,550 So let's go ahead and implement our own calculator 2945 02:12:49,550 --> 02:12:53,340 of sorts that actually has some bugs along the way. 2946 02:12:53,340 --> 02:12:55,500 Let me go back over to VS Code here. 2947 02:12:55,500 --> 02:12:59,210 I'll close mario.c, open my terminal, and code up 2948 02:12:59,210 --> 02:13:02,180 one final file called calculator.c. 2949 02:13:02,180 --> 02:13:05,810 And in this calculator file, let's go ahead and do something super simple 2950 02:13:05,810 --> 02:13:06,630 initially. 2951 02:13:06,630 --> 02:13:09,190 Let's go ahead and include CS50.h. 2952 02:13:09,190 --> 02:13:11,700 Let's include standard io.h. 2953 02:13:11,700 --> 02:13:15,000 Let's do int meow(void), as always-- all boilerplate thus far. 2954 02:13:15,000 --> 02:13:20,010 And now let's do something more interesting-- int x equals get_int. 2955 02:13:20,010 --> 02:13:22,660 And we'll prompt the user for an x value. 2956 02:13:22,660 --> 02:13:26,730 int y-- prompt the user for a y value, as we've 2957 02:13:26,730 --> 02:13:28,630 done previously for comparing numbers. 2958 02:13:28,630 --> 02:13:30,370 And let's just do something super simple. 2959 02:13:30,370 --> 02:13:34,000 Let's give myself another variable, int z equals x plus y. 2960 02:13:34,000 --> 02:13:35,710 And then let's print out the sum. 2961 02:13:35,710 --> 02:13:38,680 So printf, quote, unquote-- 2962 02:13:38,680 --> 02:13:39,960 and I don't percent s here. 2963 02:13:39,960 --> 02:13:42,520 If I want to print out a number-- someone said it earlier-- 2964 02:13:42,520 --> 02:13:46,680 we want percent s for string but percent i for integer. 2965 02:13:46,680 --> 02:13:50,100 Backslash n, and print out the value of z. 2966 02:13:50,100 --> 02:13:52,300 So it's a little silly, this calculator. 2967 02:13:52,300 --> 02:13:53,740 It just adds two numbers together. 2968 02:13:53,740 --> 02:13:55,690 But it's going to demonstrate some points. 2969 02:13:55,690 --> 02:13:58,230 So make calculator, Enter. 2970 02:13:58,230 --> 02:14:00,730 So far, so good-- "./calculator." 2971 02:14:00,730 --> 02:14:04,750 Let's just say x is 1, y is 2, z is going to be 3. 2972 02:14:04,750 --> 02:14:07,150 This code is correct, simple though it is. 2973 02:14:07,150 --> 02:14:11,190 Is there an opportunity for marginally better design? 2974 02:14:11,190 --> 02:14:13,170 Could we tighten this up, make it shorter? 2975 02:14:13,170 --> 02:14:16,990 Fewer lines means lower probability of bugs, probably. 2976 02:14:16,990 --> 02:14:18,494 Yeah. 2977 02:14:18,494 --> 02:14:22,052 AUDIENCE: You don't need to provide a separate variable z. 2978 02:14:22,052 --> 02:14:24,760 DAVID J. MALAN: Yeah, we don't really need a separate variable z. 2979 02:14:24,760 --> 02:14:27,842 I mean, it's fine if it's clearer to you, if it's clearer to your TF, 2980 02:14:27,842 --> 02:14:29,300 if it's clearer to your colleagues. 2981 02:14:29,300 --> 02:14:32,980 But honestly, this is so relatively simple, I think we just get rid of z 2982 02:14:32,980 --> 02:14:35,780 and just say something like x plus y here, 2983 02:14:35,780 --> 02:14:38,470 which is totally reasonable as well. 2984 02:14:38,470 --> 02:14:40,520 But you don't want to take this to an extreme. 2985 02:14:40,520 --> 02:14:43,280 Heck, if we don't need z, do we really need x and y? 2986 02:14:43,280 --> 02:14:45,410 Well, we could do something like this. 2987 02:14:45,410 --> 02:14:46,790 Let me actually-- whoops-- 2988 02:14:46,790 --> 02:14:50,020 let me actually delete these lines of code and claim-- 2989 02:14:50,020 --> 02:14:53,410 we can do this all in one very pretty one-liner. 2990 02:14:53,410 --> 02:14:59,710 We could do, say, get_int x plus get_int y. 2991 02:14:59,710 --> 02:15:03,580 And notice now, like the join example last time, I'm 2992 02:15:03,580 --> 02:15:06,710 calling get_int once, get_int twice. 2993 02:15:06,710 --> 02:15:10,480 Both of them return a value, which is going to be 1 and 2 respectively 2994 02:15:10,480 --> 02:15:11,810 based on what I typed earlier. 2995 02:15:11,810 --> 02:15:13,660 Then I'm doing 1 plus 2. 2996 02:15:13,660 --> 02:15:16,360 That's going into printf as the second argument. 2997 02:15:16,360 --> 02:15:18,410 This is actually correct and will work. 2998 02:15:18,410 --> 02:15:19,510 This is just stupid. 2999 02:15:19,510 --> 02:15:20,290 Don't do this. 3000 02:15:20,290 --> 02:15:24,780 We've crossed some ill-defined line where this is just harder now to read. 3001 02:15:24,780 --> 02:15:28,850 And so even though the variables aren't strictly necessary, I would argue, 3002 02:15:28,850 --> 02:15:32,930 and I think most programmers would argue, this is just much more readable. 3003 02:15:32,930 --> 02:15:34,890 Each line is doing a little bit less work. 3004 02:15:34,890 --> 02:15:36,420 There's less chance for error. 3005 02:15:36,420 --> 02:15:38,130 It just makes a little more sense. 3006 02:15:38,130 --> 02:15:39,870 But reasonable people will disagree. 3007 02:15:39,870 --> 02:15:44,695 So therefore, this is to say, over time, too, you and your TF might disagree. 3008 02:15:44,695 --> 02:15:46,320 You and your colleagues might disagree. 3009 02:15:46,320 --> 02:15:48,830 And at that point is when the religious debates kick in 3010 02:15:48,830 --> 02:15:51,950 as to which way is the right way. 3011 02:15:51,950 --> 02:15:53,490 All right, so that's one calculator. 3012 02:15:53,490 --> 02:15:56,730 Let's do something else that maybe just doubles a number here. 3013 02:15:56,730 --> 02:16:00,435 So let me change this to just get one integer from the user. 3014 02:16:00,435 --> 02:16:01,310 Let's just call it x. 3015 02:16:01,310 --> 02:16:03,000 And let's just double it quite simply. 3016 02:16:03,000 --> 02:16:08,722 So printf, percent i, backslash n, x times 2. 3017 02:16:08,722 --> 02:16:09,930 We'll quite simply double it. 3018 02:16:09,930 --> 02:16:12,780 The star operator is indeed multiplication in this case. 3019 02:16:12,780 --> 02:16:14,880 So that's going to go ahead and double my number. 3020 02:16:14,880 --> 02:16:18,440 So make calculator again, "./calculator." 3021 02:16:18,440 --> 02:16:19,280 Enter. 3022 02:16:19,280 --> 02:16:20,720 And let's go ahead and type in 1. 3023 02:16:20,720 --> 02:16:21,590 And I get back 2. 3024 02:16:21,590 --> 02:16:22,590 Let's run it again. 3025 02:16:22,590 --> 02:16:24,497 Type in 2, I get back 4. 3026 02:16:24,497 --> 02:16:25,080 Type it again. 3027 02:16:25,080 --> 02:16:26,070 Let's type in 3. 3028 02:16:26,070 --> 02:16:28,260 I get back 6, and so forth. 3029 02:16:28,260 --> 02:16:31,530 All right, so that's not bad in this case here. 3030 02:16:31,530 --> 02:16:35,700 But what if we actually want to write a proper program here? 3031 02:16:35,700 --> 02:16:38,030 In fact, yeah, let's see. 3032 02:16:38,030 --> 02:16:40,170 This is sort of a meme that comes and goes. 3033 02:16:40,170 --> 02:16:42,420 Let me see if you recognize this. 3034 02:16:42,420 --> 02:16:44,969 I'm going to go ahead and say another variable-- not x. 3035 02:16:44,969 --> 02:16:47,700 Let's be more specific, like int dollars equals 1. 3036 02:16:47,700 --> 02:16:50,070 And then let me deliberately induce an infinite loop. 3037 02:16:50,070 --> 02:16:54,469 Sometimes it is useful to induce an infinite loop so long as you eventually 3038 02:16:54,469 --> 02:16:58,110 break out of it somehow if you don't want the program to run forever. 3039 02:16:58,110 --> 02:17:02,000 I'm going to ask the user a question asking them for a char c using get_char. 3040 02:17:02,000 --> 02:17:06,559 And I'm going to ask them, quote, unquote, "Here's percent i." 3041 02:17:06,559 --> 02:17:07,520 Period. 3042 02:17:07,520 --> 02:17:11,639 "Double it and give it to the next person?" 3043 02:17:11,639 --> 02:17:12,809 Question mark. 3044 02:17:12,809 --> 02:17:13,980 This is ringing a bell. 3045 02:17:13,980 --> 02:17:17,968 And then we can pass in to get_char the dollars value there. 3046 02:17:17,968 --> 02:17:20,010 So actually, this looks a little cryptic already. 3047 02:17:20,010 --> 02:17:21,410 I'm going to put a dollar sign in front of it 3048 02:17:21,410 --> 02:17:23,719 as though we're actually dealing with US currency. 3049 02:17:23,719 --> 02:17:24,840 And what do we want to do? 3050 02:17:24,840 --> 02:17:29,100 How about if the user says y for yes-- 3051 02:17:29,100 --> 02:17:31,020 double it and give it to the next person-- 3052 02:17:31,020 --> 02:17:32,990 then let's go ahead and do dollars. 3053 02:17:32,990 --> 02:17:34,459 And let's double "dollar." 3054 02:17:34,459 --> 02:17:37,139 So I can do dollars equals dollars times 2. 3055 02:17:37,139 --> 02:17:40,049 Or recall the trick for plus and minus. 3056 02:17:40,049 --> 02:17:45,209 I can also do times equals 2, which just doubles it in one line as well. 3057 02:17:45,209 --> 02:17:47,870 Just a little syntactic sugar, as programmers call it, 3058 02:17:47,870 --> 02:17:51,209 that just tighten up your code even though it's the exact same thing. 3059 02:17:51,209 --> 02:17:54,590 But what if the user does not type y and they want to keep the money? 3060 02:17:54,590 --> 02:17:56,240 Well, we have an else condition. 3061 02:17:56,240 --> 02:17:58,519 At that point, you don't want to keep asking, asking, 3062 02:17:58,519 --> 02:18:00,320 asking them with get_char. 3063 02:18:00,320 --> 02:18:03,299 Let's just break out of this loop instead. 3064 02:18:03,299 --> 02:18:07,080 So break is another keyword that if you're inside of a for loop, a while 3065 02:18:07,080 --> 02:18:10,280 loop, a do-while loop, you can forcibly break out of the loop 3066 02:18:10,280 --> 02:18:12,990 early if and when you want to. 3067 02:18:12,990 --> 02:18:16,607 And so this satisfies the goal of making sure that this doesn't run forever, 3068 02:18:16,607 --> 02:18:19,190 but it is going to run again and again and again while we keep 3069 02:18:19,190 --> 02:18:20,969 prompting the user with this question. 3070 02:18:20,969 --> 02:18:25,070 So let's see now what happens except, at the end, let's go ahead 3071 02:18:25,070 --> 02:18:28,139 and make sure the user knows how much money they're walking away with. 3072 02:18:28,139 --> 02:18:32,184 Here's dollar sign, percent i, backslash n, dollars. 3073 02:18:32,184 --> 02:18:35,059 So we will see, at the end of this, whatever dollar amount the person 3074 02:18:35,059 --> 02:18:36,110 ends up with. 3075 02:18:36,110 --> 02:18:38,540 Make calculator, Enter. 3076 02:18:38,540 --> 02:18:40,190 "./calculator." 3077 02:18:40,190 --> 02:18:42,450 And let me increase my terminal window size. 3078 02:18:42,450 --> 02:18:43,200 So here we go. 3079 02:18:43,200 --> 02:18:43,730 "Here's $1. 3080 02:18:43,730 --> 02:18:45,480 Double it and give it to the next person?" 3081 02:18:45,480 --> 02:18:46,230 Yes. 3082 02:18:46,230 --> 02:18:47,030 "Here's $2. 3083 02:18:47,030 --> 02:18:48,780 Double it and give it to the next person?" 3084 02:18:48,780 --> 02:18:52,219 Yes, yes, yes, yes, yes. 3085 02:18:52,219 --> 02:18:54,809 So the Instagram Reels aren't that long. 3086 02:18:54,809 --> 02:18:56,730 But if you keep doubling it again and again, 3087 02:18:56,730 --> 02:18:59,660 this is called exponentiation, which will make you quite wealthy 3088 02:18:59,660 --> 02:19:03,260 quite quickly because, notice, we're already in the thousands of dollars 3089 02:19:03,260 --> 02:19:05,040 by just saying yes and yes and yes. 3090 02:19:05,040 --> 02:19:07,400 It's an interesting societal question as to what 3091 02:19:07,400 --> 02:19:10,650 dollar amount you would keep the money and no longer double it and pass it on. 3092 02:19:10,650 --> 02:19:13,192 But for now, we'll just keep doubling it because this is just 3093 02:19:13,192 --> 02:19:17,250 getting bigger and bigger, seemingly infinitely large And the C program-- 3094 02:19:17,250 --> 02:19:21,450 but, oh, my god, apparently the Instagram Reels 3095 02:19:21,450 --> 02:19:26,240 cut off the meme too short because eventually it goes negative and then 0. 3096 02:19:26,240 --> 02:19:29,270 What's actually going on here? 3097 02:19:29,270 --> 02:19:31,290 The code is actually correct. 3098 02:19:31,290 --> 02:19:35,100 But we're bumping up against a different kind of problem. 3099 02:19:35,100 --> 02:19:38,160 Any instinct for what is actually going wrong here? 3100 02:19:38,160 --> 02:19:39,790 It's not doubling forever. 3101 02:19:39,790 --> 02:19:40,400 Yeah. 3102 02:19:40,400 --> 02:19:42,225 AUDIENCE: There's not enough bits to store. 3103 02:19:42,225 --> 02:19:45,600 DAVID J. MALAN: Yeah, there's not enough bits to store bigger and bigger numbers. 3104 02:19:45,600 --> 02:19:49,140 Recall, with 32 bits, which happens to be how big most ints are, 3105 02:19:49,140 --> 02:19:52,430 you can count as high as 4 billion if you start at 0 or roughly 3106 02:19:52,430 --> 02:19:55,220 as high as 2 billion if you want to handle negative numbers as 3107 02:19:55,220 --> 02:19:57,480 well, negative 2 billion to positive 2 billion. 3108 02:19:57,480 --> 02:20:01,850 So eventually, once I get to $2 billion, or $1 billion, it goes negative. 3109 02:20:01,850 --> 02:20:03,920 And then it just goes to 0 altogether. 3110 02:20:03,920 --> 02:20:06,560 This is because of something called integer overflow, 3111 02:20:06,560 --> 02:20:11,070 whereby if you only have a finite number of bits and you keep incrementing them, 3112 02:20:11,070 --> 02:20:14,510 incrementing them, incrementing them, eventually you can't just carry the 1 3113 02:20:14,510 --> 02:20:16,620 because there's no 33rd bit. 3114 02:20:16,620 --> 02:20:20,330 So all of the other bits wrap around from ones to zeros. 3115 02:20:20,330 --> 02:20:26,150 And it looks like all 32 of your bits are 0 because the 33rd bit was supposed 3116 02:20:26,150 --> 02:20:27,850 to be the 1, but it's not there. 3117 02:20:27,850 --> 02:20:29,340 They don't have enough memory. 3118 02:20:29,340 --> 02:20:33,890 So this is a fundamental problem with computers whereby if you count high 3119 02:20:33,890 --> 02:20:38,960 enough, things will just start to break, at least if you're using C or C++ 3120 02:20:38,960 --> 02:20:41,690 or certain other languages that don't anticipate this. 3121 02:20:41,690 --> 02:20:43,660 And there's a very real implication of this. 3122 02:20:43,660 --> 02:20:47,070 So here's a photograph of something we'll look at more in time 3123 02:20:47,070 --> 02:20:49,350 to come of memory inside of your computer 3124 02:20:49,350 --> 02:20:51,250 or phone or any electronic device. 3125 02:20:51,250 --> 02:20:54,010 Suffice it to say, there's only a finite amount of memory. 3126 02:20:54,010 --> 02:20:58,210 And if you're only using 32 bits then, or heck even three bits, 3127 02:20:58,210 --> 02:20:59,942 you will eventually overflow. 3128 02:20:59,942 --> 02:21:01,150 We used three bits last week. 3129 02:21:01,150 --> 02:21:02,025 So here's an example. 3130 02:21:02,025 --> 02:21:06,120 In binary, if you're only using three bits, per the white digits here-- 3131 02:21:06,120 --> 02:21:10,260 I've put in gray the fourth just to show you what carry we might want to have-- 3132 02:21:10,260 --> 02:21:17,183 here's 0, 1, 2, 3, 4, 5, 4, 7, just like last week. 3133 02:21:17,183 --> 02:21:19,600 And just like last week, someone said, how do we get to 8? 3134 02:21:19,600 --> 02:21:20,920 We need another bit. 3135 02:21:20,920 --> 02:21:24,310 But if that bit is grayed out because it doesn't exist, 3136 02:21:24,310 --> 02:21:29,170 we've just overflowed this tiny integer and gotten back to 0, 3137 02:21:29,170 --> 02:21:32,830 just like my money went to $0 instead. 3138 02:21:32,830 --> 02:21:35,430 So how do we actually avoid that? 3139 02:21:35,430 --> 02:21:36,760 One way to do this is this. 3140 02:21:36,760 --> 02:21:39,040 Let me hit Control-C to break out of the program. 3141 02:21:39,040 --> 02:21:40,240 Or I could just type "no." 3142 02:21:40,240 --> 02:21:43,660 Let me shrink my terminal window and clear it here. 3143 02:21:43,660 --> 02:21:45,670 I could actually do this. 3144 02:21:45,670 --> 02:21:48,682 It turns out that ints use 32 bits typically. 3145 02:21:48,682 --> 02:21:51,390 But there's another data type that was on the slide before called 3146 02:21:51,390 --> 02:21:54,390 long, which is a longer version of an int, which 3147 02:21:54,390 --> 02:21:57,330 is 64 bits, which is crazy big. 3148 02:21:57,330 --> 02:21:59,290 There's not that many dollars in the world. 3149 02:21:59,290 --> 02:22:03,010 But it's still finite, even though I can't pronounce a number that big. 3150 02:22:03,010 --> 02:22:06,420 But if we change all of our ints to longs 3151 02:22:06,420 --> 02:22:11,400 and we change our placeholder from percent i to percent li, for long int, 3152 02:22:11,400 --> 02:22:13,780 I can actually count higher and higher. 3153 02:22:13,780 --> 02:22:16,290 So case in point, let me actually go back to my terminal-- 3154 02:22:16,290 --> 02:22:18,840 make calculator, Enter. 3155 02:22:18,840 --> 02:22:20,380 Make it larger again-- 3156 02:22:20,380 --> 02:22:21,820 "./calculator." 3157 02:22:21,820 --> 02:22:24,360 And I'm just going to keep saying yes but faster this time. 3158 02:22:24,360 --> 02:22:25,990 The sequence is exactly the same. 3159 02:22:25,990 --> 02:22:28,000 But recall that once we got into the billions, 3160 02:22:28,000 --> 02:22:30,400 it started to wrap to negative and then 0. 3161 02:22:30,400 --> 02:22:31,950 This is a lot of money now. 3162 02:22:31,950 --> 02:22:33,810 Longs are indeed longer. 3163 02:22:33,810 --> 02:22:36,130 And I could do this probably all day long. 3164 02:22:36,130 --> 02:22:38,070 Oh, interesting. 3165 02:22:38,070 --> 02:22:39,780 I shouldn't have said that. 3166 02:22:39,780 --> 02:22:42,823 Can't do this all day long because eventually a long, too, will overflow. 3167 02:22:42,823 --> 02:22:45,490 [WHISPERS] I just didn't think it was going to happen that fast. 3168 02:22:45,490 --> 02:22:48,910 So a long, too, will overflow because we'll need a 65th bit, 3169 02:22:48,910 --> 02:22:51,130 but the computer has not allocated it. 3170 02:22:51,130 --> 02:22:53,800 So that, too, becomes an issue of overflow. 3171 02:22:53,800 --> 02:22:56,920 To read an excerpt, these are very real world issues. 3172 02:22:56,920 --> 02:23:01,080 And in fact, here's a photograph of a Boeing 787 years ago 3173 02:23:01,080 --> 02:23:04,840 that actually had issues beyond the most recent issues with Boeing airplanes, 3174 02:23:04,840 --> 02:23:10,260 whereby after 248 days, the Boeing 787, years ago, can 3175 02:23:10,260 --> 02:23:14,130 lose all of its electrical power due to the generator control 3176 02:23:14,130 --> 02:23:17,560 units simultaneously going into failsafe mode, whatever that means. 3177 02:23:17,560 --> 02:23:20,490 But if you dig into this, it turns out that there 3178 02:23:20,490 --> 02:23:23,790 was a software counter in these airplanes years ago 3179 02:23:23,790 --> 02:23:28,750 that would overflow after 248 days of continuous power. 3180 02:23:28,750 --> 02:23:30,240 248 days, why? 3181 02:23:30,240 --> 02:23:32,820 Well, Boeing was using a 32-bit integer. 3182 02:23:32,820 --> 02:23:36,070 And they were using it to count tenths of seconds. 3183 02:23:36,070 --> 02:23:40,600 And it turns out, if you do the math, after 248 days, 3184 02:23:40,600 --> 02:23:45,630 you have used too many tenths such that you overflow the size of a 32-bit 3185 02:23:45,630 --> 02:23:46,240 integer. 3186 02:23:46,240 --> 02:23:48,190 The plane would essentially have this integer, 3187 02:23:48,190 --> 02:23:50,560 this tiny, stupid little variable, overflow. 3188 02:23:50,560 --> 02:23:53,500 But generally speaking, when your numbers suddenly go negative or 0, 3189 02:23:53,500 --> 02:23:54,520 bad things happen. 3190 02:23:54,520 --> 02:23:58,333 The plane could literally lose its power mid-flight or on the ground. 3191 02:23:58,333 --> 02:24:01,500 And if you can believe it, anyone want to guess what Boeing's workaround was 3192 02:24:01,500 --> 02:24:03,694 till they fixed the actual software? 3193 02:24:03,694 --> 02:24:05,350 AUDIENCE: [INAUDIBLE] 3194 02:24:05,350 --> 02:24:06,050 What's that? 3195 02:24:06,050 --> 02:24:07,760 AUDIENCE: [? It's for ?] [INAUDIBLE]. 3196 02:24:07,760 --> 02:24:09,980 DAVID J. MALAN: Not even-- reboot the plane. 3197 02:24:09,980 --> 02:24:13,660 They were told, every few days, certainly every 248 days, 3198 02:24:13,660 --> 02:24:16,813 turn the power off, turn it back on, which, stupidly, is what all of us 3199 02:24:16,813 --> 02:24:19,230 have been told for years with our Macs and PCs and phones. 3200 02:24:19,230 --> 02:24:19,730 Why? 3201 02:24:19,730 --> 02:24:22,410 Because sometimes, because of bugs and software, 3202 02:24:22,410 --> 02:24:26,270 computers get into funky states, which is a colloquial way of saying 3203 02:24:26,270 --> 02:24:30,230 some programmer made a mistake and some counter overflowed or some condition 3204 02:24:30,230 --> 02:24:33,600 wasn't handled and just weird, unexpected things happen. 3205 02:24:33,600 --> 02:24:37,520 So rebooting just resets all of your variables back to their original values 3206 02:24:37,520 --> 02:24:42,342 and gives you more time, more runway in this case, no pun intended. 3207 02:24:42,342 --> 02:24:43,050 There are others. 3208 02:24:43,050 --> 02:24:46,160 In fact, one of the most famous ones from the 1980s was the original Pac-Man 3209 02:24:46,160 --> 02:24:46,680 game-- 3210 02:24:46,680 --> 02:24:49,500 only had support for 255 levels. 3211 02:24:49,500 --> 02:24:50,000 Why? 3212 02:24:50,000 --> 02:24:51,370 They were using 8 bits. 3213 02:24:51,370 --> 02:24:53,610 Recall that 8 bits gives you 256. 3214 02:24:53,610 --> 02:24:56,280 But if you start counting at 0, you can only go to 255. 3215 02:24:56,280 --> 02:24:58,460 So the crazy kids who were so good at Pac-Man 3216 02:24:58,460 --> 02:25:03,020 that they got to level 256, the makers of Pac-Man 3217 02:25:03,020 --> 02:25:06,450 did not anticipate that anyone was going to win that many levels. 3218 02:25:06,450 --> 02:25:08,740 And just weird stuff happened on the screen. 3219 02:25:08,740 --> 02:25:12,060 All of the fruit started overwriting everything because they didn't have 3220 02:25:12,060 --> 02:25:15,900 enough memory allocated to the level, nor did they have a condition that says, 3221 02:25:15,900 --> 02:25:19,710 if level equals equals 255, "you win." 3222 02:25:19,710 --> 02:25:22,960 There was just nothing handling that corner case, so to speak. 3223 02:25:22,960 --> 02:25:25,270 So these things abound even these days. 3224 02:25:25,270 --> 02:25:28,530 Thankfully, in some languages, there are better solutions 3225 02:25:28,530 --> 02:25:30,630 where you can use big integers. 3226 02:25:30,630 --> 02:25:35,380 And you'll just use 64, maybe 128, maybe 256 bits. 3227 02:25:35,380 --> 02:25:38,010 But you need to use a language or a library that 3228 02:25:38,010 --> 02:25:41,110 allows you to grow and shrink the amount of memory being used. 3229 02:25:41,110 --> 02:25:45,310 And many, if not most languages, do not do that for us. 3230 02:25:45,310 --> 02:25:49,110 So there's a few final problems to see that we've been taking for granted 3231 02:25:49,110 --> 02:25:49,870 thus far. 3232 02:25:49,870 --> 02:25:53,350 And they also involve numbers and memory. 3233 02:25:53,350 --> 02:25:55,030 So let's go back into our calculator. 3234 02:25:55,030 --> 02:25:57,150 Let's throw away all of this meme code here. 3235 02:25:57,150 --> 02:26:00,850 And instead, let's go ahead and do something simple again. 3236 02:26:00,850 --> 02:26:02,970 int x equals get_int. 3237 02:26:02,970 --> 02:26:06,300 And prompt the user for a variable x. int y equals get_int, 3238 02:26:06,300 --> 02:26:08,260 prompt the user for a variable y. 3239 02:26:08,260 --> 02:26:12,490 And this time, instead of addition, instead of doubling, let's do division. 3240 02:26:12,490 --> 02:26:16,230 So printf, quote, unquote, percent i backslash n. 3241 02:26:16,230 --> 02:26:19,060 And then plug in x divided by y. 3242 02:26:19,060 --> 02:26:21,610 So you use a single forward slash for division. 3243 02:26:21,610 --> 02:26:25,500 Let me go ahead and, make calculator down here, "./calculator." 3244 02:26:25,500 --> 02:26:31,860 And let's go ahead and do 1 divided by 3, which should, in fact, be-- 3245 02:26:31,860 --> 02:26:33,460 it's not really 0. 3246 02:26:33,460 --> 02:26:35,890 It's like 0.333. 3247 02:26:35,890 --> 02:26:36,820 Let's try this again. 3248 02:26:36,820 --> 02:26:39,540 How about "./calculator" 3 divided by 2? 3249 02:26:39,540 --> 02:26:41,440 Should be 1.5. 3250 02:26:41,440 --> 02:26:43,890 Nope, computer thinks it's 1. 3251 02:26:43,890 --> 02:26:45,310 Well, what's happening here? 3252 02:26:45,310 --> 02:26:48,790 Well, it turns out, when you're using integers in a program, 3253 02:26:48,790 --> 02:26:51,430 you are vulnerable to what's called truncation. 3254 02:26:51,430 --> 02:26:54,130 An integer plus an integer gives you an integer. 3255 02:26:54,130 --> 02:26:58,540 An integer divided by an integer, funny enough, gives you an integer. 3256 02:26:58,540 --> 02:27:04,060 So even if the answer is supposed to be 0.333 or 1.5, 3257 02:27:04,060 --> 02:27:08,040 everything in the world of integers throws away the decimal point onward. 3258 02:27:08,040 --> 02:27:11,080 And you only get the integer part of the value. 3259 02:27:11,080 --> 02:27:12,280 So it's not even rounding. 3260 02:27:12,280 --> 02:27:14,980 It's truncating everything after the decimal. 3261 02:27:14,980 --> 02:27:16,930 So this program is just not correct. 3262 02:27:16,930 --> 02:27:19,090 But there are solutions potentially. 3263 02:27:19,090 --> 02:27:21,750 For instance, if I go back into my code here 3264 02:27:21,750 --> 02:27:24,370 and I use a different format code we haven't used yet-- 3265 02:27:24,370 --> 02:27:26,710 we had s for string, i for int. 3266 02:27:26,710 --> 02:27:28,590 There's also f for float. 3267 02:27:28,590 --> 02:27:32,860 And a float was like a real number, something with a decimal point in it 3268 02:27:32,860 --> 02:27:33,480 by definition. 3269 02:27:33,480 --> 02:27:34,930 We just haven't used it yet. 3270 02:27:34,930 --> 02:27:37,360 I could tell the computer to print this as a float. 3271 02:27:37,360 --> 02:27:39,700 So let me do make calculator again. 3272 02:27:39,700 --> 02:27:42,220 And now, hm, it's specifying type double. 3273 02:27:42,220 --> 02:27:43,420 There's an error here. 3274 02:27:43,420 --> 02:27:45,780 The problem is that I can't just tell the computer 3275 02:27:45,780 --> 02:27:48,550 to format this number as a float. 3276 02:27:48,550 --> 02:27:53,160 I need to convert the number, x divided by y, to a float. 3277 02:27:53,160 --> 02:27:55,030 And I can do this in a couple of ways. 3278 02:27:55,030 --> 02:27:57,330 One, I could literally change all of this to floats 3279 02:27:57,330 --> 02:27:59,110 and just avoid the problem altogether. 3280 02:27:59,110 --> 02:28:02,290 Use float, use get_float, use percent f, and I'm done. 3281 02:28:02,290 --> 02:28:04,777 But if I want to use ints for whatever reason-- 3282 02:28:04,777 --> 02:28:06,610 because I want the user to type in integers, 3283 02:28:06,610 --> 02:28:10,930 but I want to show them real numbers with decimal points for correct math-- 3284 02:28:10,930 --> 02:28:13,990 I can do what's called casting a value. 3285 02:28:13,990 --> 02:28:17,470 I can, in parentheses-- which is a weird new use of parentheses-- 3286 02:28:17,470 --> 02:28:22,140 I can say, hey, computer, please treat the following integer as a float 3287 02:28:22,140 --> 02:28:25,810 instead, thereby avoiding truncation. 3288 02:28:25,810 --> 02:28:27,550 Do not truncate for me. 3289 02:28:27,550 --> 02:28:32,040 So if I now run make calculator again, "./calculator," 3290 02:28:32,040 --> 02:28:35,650 and type in, for instance, 1 for x, 3 for y, 3291 02:28:35,650 --> 02:28:38,620 now I get an actual floating point value. 3292 02:28:38,620 --> 02:28:39,870 I'm formatting it as such. 3293 02:28:39,870 --> 02:28:43,770 And I'm telling the computer to actually arithmetically calculate it 3294 02:28:43,770 --> 02:28:45,570 as such as well. 3295 02:28:45,570 --> 02:28:49,570 But here, too, I'm kind of cheating you of a reality. 3296 02:28:49,570 --> 02:28:52,480 It turns out-- let me clear this screen here. 3297 02:28:52,480 --> 02:28:56,220 And it turns out that there are fancy ways in printf 3298 02:28:56,220 --> 02:29:00,430 to tell it how many digits to show you, how many significant digits. 3299 02:29:00,430 --> 02:29:01,647 And the syntax is very weird. 3300 02:29:01,647 --> 02:29:02,980 I have to look it up constantly. 3301 02:29:02,980 --> 02:29:05,493 But instead of just saying percent f, you literally 3302 02:29:05,493 --> 02:29:06,910 put some numbers in between there. 3303 02:29:06,910 --> 02:29:09,960 And you say point 5. 3304 02:29:09,960 --> 02:29:12,220 And that will say-- it's weird syntax-- 3305 02:29:12,220 --> 02:29:15,880 hey, printf, format this to five digits instead. 3306 02:29:15,880 --> 02:29:20,400 So let me go ahead and do make calculator again, "./calculator." 3307 02:29:20,400 --> 02:29:22,500 And let's do 1 divided by 3. 3308 02:29:22,500 --> 02:29:25,780 And indeed, I get five significant digits there. 3309 02:29:25,780 --> 02:29:30,460 But suppose I get a little crazy and I want 50 significant digits. 3310 02:29:30,460 --> 02:29:33,310 Well, according to grade school, I should just see more 3's. 3311 02:29:33,310 --> 02:29:34,200 But watch this. 3312 02:29:34,200 --> 02:29:37,070 Make calculator, "./calculator." 3313 02:29:37,070 --> 02:29:40,320 And it turns out that whoever taught you grade-school math was kind of telling 3314 02:29:40,320 --> 02:29:43,860 you some white lies because if you really do it with a powerful Mac or PC 3315 02:29:43,860 --> 02:29:52,112 or phone, one third is actually 0.3333333334326744079-- 3316 02:29:52,112 --> 02:29:54,300 [SIGHS] who's right? 3317 02:29:54,300 --> 02:29:59,670 Mr. and Mrs. So-and-so from grade school or the internet? 3318 02:29:59,670 --> 02:30:00,905 What's going on here? 3319 02:30:00,905 --> 02:30:03,720 3320 02:30:03,720 --> 02:30:05,080 What explains this? 3321 02:30:05,080 --> 02:30:09,710 It all comes down somehow to [? weak ?] zeros and ones. 3322 02:30:09,710 --> 02:30:14,590 Why is this floating point number imprecise, so to speak? 3323 02:30:14,590 --> 02:30:15,590 What's the intuition? 3324 02:30:15,590 --> 02:30:16,090 Yeah. 3325 02:30:16,090 --> 02:30:19,213 AUDIENCE: Is this similar to what happened earlier 3326 02:30:19,213 --> 02:30:20,380 where there was an overflow? 3327 02:30:20,380 --> 02:30:22,047 DAVID J. MALAN: Yeah, similar in spirit. 3328 02:30:22,047 --> 02:30:26,290 Just as ints only use 32 bits, floats also use only 32 bits. 3329 02:30:26,290 --> 02:30:30,530 If you want more, just as int has long, floats have something called "double." 3330 02:30:30,530 --> 02:30:33,530 So I could avoid some of the problem by switching to double. 3331 02:30:33,530 --> 02:30:35,090 But that's still going to be finite. 3332 02:30:35,090 --> 02:30:38,630 And if you think about this intuitively, if you're using a finite number of bits, 3333 02:30:38,630 --> 02:30:43,330 be it 32 or 64, you can only represent literally so many patterns 3334 02:30:43,330 --> 02:30:46,340 and thus so many floating point values, so many real numbers. 3335 02:30:46,340 --> 02:30:48,880 But how many real numbers are there in the world? 3336 02:30:48,880 --> 02:30:52,248 Literally infinitely many, is the challenge of real numbers. 3337 02:30:52,248 --> 02:30:54,290 You can just keep adding numbers after the digit. 3338 02:30:54,290 --> 02:30:57,310 So how could a computer, Mac, PC, or otherwise, possibly 3339 02:30:57,310 --> 02:31:00,620 represent every floating point value super precisely 3340 02:31:00,620 --> 02:31:04,820 if there's not enough patterns to represent every number in the world? 3341 02:31:04,820 --> 02:31:08,020 Moreover, the way that computers use to represent numbers sometimes 3342 02:31:08,020 --> 02:31:10,660 do not allow them to represent numbers so precisely. 3343 02:31:10,660 --> 02:31:13,240 We can get more significant digits maybe, but not 3344 02:31:13,240 --> 02:31:16,190 100% perfection or precision. 3345 02:31:16,190 --> 02:31:21,070 So floating point precision, too, is a fundamental problem with computers 3346 02:31:21,070 --> 02:31:21,570 today. 3347 02:31:21,570 --> 02:31:24,770 And unless, again, you're using a specialized language or library that 3348 02:31:24,770 --> 02:31:28,820 understands, for scientific computing, the implications of overflow 3349 02:31:28,820 --> 02:31:32,880 or imprecision, your code will have mistakes, much like Boeing discovered, 3350 02:31:32,880 --> 02:31:35,040 much like Pac-Man discovered as well. 3351 02:31:35,040 --> 02:31:37,740 And in fact, just to end on a gloom-and-doom note, 3352 02:31:37,740 --> 02:31:40,980 it turns out there's another problem like this on the horizon already. 3353 02:31:40,980 --> 02:31:45,020 So back in my day, everyone was really worried about the Y2K problem, the Year 3354 02:31:45,020 --> 02:31:45,960 2000 problem. 3355 02:31:45,960 --> 02:31:46,460 Why? 3356 02:31:46,460 --> 02:31:48,900 Because for decades, when computers were invented, 3357 02:31:48,900 --> 02:31:51,320 most systems were using just two digits-- 3358 02:31:51,320 --> 02:31:53,940 independent of bits-- two digits to represent years. 3359 02:31:53,940 --> 02:31:54,440 Why? 3360 02:31:54,440 --> 02:31:56,820 Computers came out a few decades ago. 3361 02:31:56,820 --> 02:32:00,050 Who'd think that a computer is still going to be running decades later? 3362 02:32:00,050 --> 02:32:02,690 Turns out they were, especially in government and corporations 3363 02:32:02,690 --> 02:32:03,360 and the like. 3364 02:32:03,360 --> 02:32:06,020 But if you're only using two digits to represent years 3365 02:32:06,020 --> 02:32:09,020 and the millennium comes around and it's 1999 3366 02:32:09,020 --> 02:32:14,000 about to roll over, about to roll over, what comes after 1999? 3367 02:32:14,000 --> 02:32:16,830 Well, if you're only using two digits, ideally 2000. 3368 02:32:16,830 --> 02:32:22,080 But if you're only using two digits, the year 0 comes after the year 1999. 3369 02:32:22,080 --> 02:32:25,310 And the whole world, truly-- you can look it up nowadays on Wikipedia-- 3370 02:32:25,310 --> 02:32:28,383 was freaking out because there was so much old software in the world that 3371 02:32:28,383 --> 02:32:29,550 could have had this mistake. 3372 02:32:29,550 --> 02:32:30,210 And who knows? 3373 02:32:30,210 --> 02:32:33,620 Planes falling out of the sky, computers rebooting, freezing. 3374 02:32:33,620 --> 02:32:38,058 No one really knew because this was an unhandled situation in code. 3375 02:32:38,058 --> 02:32:40,350 So thankfully, the world actually got its act together. 3376 02:32:40,350 --> 02:32:42,360 The world did not end in the year 2000. 3377 02:32:42,360 --> 02:32:45,960 And most systems were updated in time without crazy horror stories. 3378 02:32:45,960 --> 02:32:50,030 But we're going to have this happen again because it turns out just a few 3379 02:32:50,030 --> 02:32:54,980 years from now, at this point, computers for years have been using 32-bit 3380 02:32:54,980 --> 02:32:59,400 integers to keep track of time in the sense of what time of day it is. 3381 02:32:59,400 --> 02:33:04,132 And the point in time they decided years ago was, like, hey everyone, 3382 02:33:04,132 --> 02:33:05,840 let's just keep track of how many seconds 3383 02:33:05,840 --> 02:33:09,600 have passed since January 1, 1970. 3384 02:33:09,600 --> 02:33:13,620 And we can relatively compute time any time thereafter. 3385 02:33:13,620 --> 02:33:14,317 So that's great. 3386 02:33:14,317 --> 02:33:15,900 That gives us a lot of decades' worth. 3387 02:33:15,900 --> 02:33:20,213 But 32 bits eventually maxes out at, like, 4 billion positive, or 2 billion 3388 02:33:20,213 --> 02:33:21,630 if you want negative and positive. 3389 02:33:21,630 --> 02:33:24,980 And it turns out, if you count the number of seconds between 1970 3390 02:33:24,980 --> 02:33:29,690 on up, on the day January 19, 2038, the world 3391 02:33:29,690 --> 02:33:34,220 might again end because all of these clocks are going to overflow. 3392 02:33:34,220 --> 02:33:37,200 And we're going to end up in the year 0 or negative something. 3393 02:33:37,200 --> 02:33:38,520 Now, what's the solution there? 3394 02:33:38,520 --> 02:33:40,520 I mean, my god, it's the exact same thing. 3395 02:33:40,520 --> 02:33:41,880 Stop using so few bits. 3396 02:33:41,880 --> 02:33:42,510 Use more bits. 3397 02:33:42,510 --> 02:33:45,300 But bits and memory and computers used to be expensive. 3398 02:33:45,300 --> 02:33:47,907 Nowadays, storage is so much more available. 3399 02:33:47,907 --> 02:33:50,990 But among the things we'll discuss then is how you can throw both hardware 3400 02:33:50,990 --> 02:33:52,200 and software at this problem. 3401 02:33:52,200 --> 02:33:56,760 But for now, maybe set a Google Calendar reminder for January 19, 2038. 3402 02:33:56,760 --> 02:33:59,030 And hopefully we'll see you next week. 3403 02:33:59,030 --> 02:34:00,830 [APPLAUSE] 3404 02:34:00,830 --> 02:34:04,430 3405 02:34:04,430 --> 02:34:07,780 [CLASSICAL MUSIC] 3406 02:34:07,780 --> 02:34:31,000 283723

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