All language subtitles for Aula 1

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: 1 00:01:14,800 --> 00:01:16,100 DAVID J. All right. 2 00:01:17,080 --> 00:01:18,800 This is CS50. 3 00:01:19,400 --> 00:01:22,860 This is week one, because, of course, last week was week zero. And this is the 4 00:01:22,860 --> 00:01:26,320 week where we'll actually start programming in a much more traditional 5 00:01:26,320 --> 00:01:28,460 programming language we promised called C. 6 00:01:28,820 --> 00:01:31,660 Of course, we started with this. And hopefully by now, with problem set one, 7 00:01:31,740 --> 00:01:33,940 you've had a little bit of fun, even if you've played with it before. And the 8 00:01:33,940 --> 00:01:37,740 goals of Scratch, beyond sort of making things feel very accessible and user 9 00:01:37,740 --> 00:01:42,140 friendly, is really to elucidate some of the fundamental concepts that we'll see 10 00:01:42,140 --> 00:01:43,140 again today. 11 00:01:43,200 --> 00:01:47,800 And really, every week subsequently, like functions and conditionals and 12 00:01:47,800 --> 00:01:51,980 and variables and so much more. And in fact, among the goals of Scratch is, 13 00:01:52,040 --> 00:01:55,720 again, to kind of plant these visuals in your mind. So even as today onward 14 00:01:55,720 --> 00:01:59,240 feels all the more like a fire hose, especially when it comes to really weird 15 00:01:59,240 --> 00:02:04,940 cryptic textual syntax, the ideas are still going to be the same. So today, 16 00:02:04,940 --> 00:02:07,580 program, Hello World, becomes this instead. 17 00:02:07,820 --> 00:02:09,699 And in fact, just to color code things temporarily, 18 00:02:10,440 --> 00:02:14,200 I dare say that what I've color coded here in orange, which looks probably, to 19 00:02:14,200 --> 00:02:18,440 those of you who've never programmed, pretty cryptic, is the equivalent of the 20 00:02:18,440 --> 00:02:24,140 when green flag clicked orange puzzle piece like this. What remains is just 21 00:02:24,140 --> 00:02:27,800 line in purple with a bit of white, which is what ultimately is going to get 22 00:02:27,800 --> 00:02:29,880 screen today to say hello world on the screen. 23 00:02:30,080 --> 00:02:32,700 And of course, we had a name for something in purple. 24 00:02:32,960 --> 00:02:37,120 In fact, if we rewind to week zero, this block in purple represented what type 25 00:02:37,120 --> 00:02:38,120 of functionality? 26 00:02:41,190 --> 00:02:45,530 A function itself, an action, a verb that gets the computer to do something. 27 00:02:45,530 --> 00:02:48,770 what looked like this last week is about to look like this. Let's take away the 28 00:02:48,770 --> 00:02:52,270 color coding and focus really on what we're going to now start calling source 29 00:02:52,270 --> 00:02:54,210 code. So this is what programmers do. 30 00:02:54,680 --> 00:02:58,020 in the real world. This is what software developers, software engineers do in 31 00:02:58,020 --> 00:03:01,900 the real world. They write code that looks like this. And clearly, it's a 32 00:03:01,900 --> 00:03:05,400 English -like, but it's not English in the way you would compose an essay or an 33 00:03:05,400 --> 00:03:09,060 email. Clearly, there's some patterns and some special syntax to it that we'll 34 00:03:09,060 --> 00:03:10,200 highlight ultimately today. 35 00:03:10,460 --> 00:03:14,440 The problem is, though, that computers, of course, don't understand source code. 36 00:03:14,620 --> 00:03:19,040 They only, per last week, understand zeros and ones. That is it, the so 37 00:03:19,040 --> 00:03:20,040 binary system. 38 00:03:20,300 --> 00:03:23,800 So somehow, we've got to get what already looks cryptic into something 39 00:03:23,800 --> 00:03:27,010 looks at a glance even more cryptic than zeros and ones, the computers do 40 00:03:27,010 --> 00:03:31,070 understand. And for today's purposes, just know that built into your Macs, 41 00:03:31,210 --> 00:03:35,980 and phones, There is a built -in understanding of what these patterns 42 00:03:36,140 --> 00:03:40,400 Maybe it means a number. Maybe it means a letter. But today, maybe it means an 43 00:03:40,400 --> 00:03:44,880 instruction, like print something on the screen, or save something, or load 44 00:03:44,880 --> 00:03:48,820 something. That is to say, computers use patterns of bits not only to represent 45 00:03:48,820 --> 00:03:52,520 all the stuff we talked about last week, numbers, letters, colors, images, 46 00:03:52,660 --> 00:03:55,680 sounds, and all of that. They also use patterns of bits to represent 47 00:03:56,530 --> 00:04:00,610 fundamental functionality, print things, play things, much like those same 48 00:04:00,610 --> 00:04:01,589 scratch blocks. 49 00:04:01,590 --> 00:04:05,930 But no computer scientist really, unless they take out a paper pencil or write a 50 00:04:05,930 --> 00:04:08,930 program or use a website to convert this, can sort of read this and know 51 00:04:08,930 --> 00:04:13,070 going on. That's why we humans are actually going to use not machine code, 52 00:04:13,070 --> 00:04:15,610 is called, the zeros and ones that computers understand. 53 00:04:15,910 --> 00:04:18,750 We are going to start writing source code. And last week, you already wrote 54 00:04:18,750 --> 00:04:22,029 source code, but in the form of dragging and dropping those puzzle pieces. 55 00:04:22,560 --> 00:04:25,100 So this, too, is going to be the paradigm that sort of guides us through 56 00:04:25,100 --> 00:04:26,100 entire semester. 57 00:04:26,200 --> 00:04:28,600 Problem solving programming is really about input. 58 00:04:29,120 --> 00:04:30,120 becoming output. 59 00:04:30,180 --> 00:04:33,320 And we'll focus today then on a certain type of input becoming output. 60 00:04:33,540 --> 00:04:37,660 Someone has to get the source code that's written in a language like C into 61 00:04:37,660 --> 00:04:40,900 machine code, the zeros and ones that the computer actually understands. 62 00:04:41,220 --> 00:04:43,260 So source code today is going to be our input. 63 00:04:43,500 --> 00:04:46,860 Machine code is going to be our output. And we're going to give you today a 64 00:04:46,860 --> 00:04:52,220 special program called a compiler, whose purpose in life is to translate one to 65 00:04:52,220 --> 00:04:55,220 the other. And there's compilers for different languages in the world. We're 66 00:04:55,220 --> 00:04:58,280 going to focus on one that supports today's language, known as C. 67 00:04:58,540 --> 00:05:02,540 And here, as promised, is the programming environment we are going to 68 00:05:02,540 --> 00:05:06,440 tailored to CS50, which is to say we've pre -installed certain software that you 69 00:05:06,440 --> 00:05:09,820 might find useful during the term. But for all intents and purposes, the tool 70 00:05:09,820 --> 00:05:13,800 you will use for CS50's problem set, henceforth, is a very popular industry 71 00:05:13,800 --> 00:05:17,520 standard tool called Visual Studio Code, or VS Code for short. 72 00:05:17,720 --> 00:05:21,640 We are using a cloud -based version of it that lives at literally this URL, 73 00:05:21,640 --> 00:05:26,540 .dev. You can sign into that so long as you have a free GitHub account for which 74 00:05:26,540 --> 00:05:30,340 you signed up, presumably, already. And that will give you access to not only an 75 00:05:30,340 --> 00:05:33,940 industry standard programming environment, but again, an environment 76 00:05:33,940 --> 00:05:36,200 some CS50 -specific things pre -installed. 77 00:05:36,420 --> 00:05:40,200 And at the end of the semester, or even in the middle if you're so inclined, you 78 00:05:40,200 --> 00:05:43,640 can actually download for free VS Code onto your Mac PC. 79 00:05:43,960 --> 00:05:47,160 You can disconnect from the internet, and you can actually program on your own 80 00:05:47,160 --> 00:05:51,120 computer. Caveat, though, is that you tend to hit technical support headaches 81 00:05:51,120 --> 00:05:54,480 the very beginning of the term. So we suggest you do that later in the term 82 00:05:54,480 --> 00:05:57,180 you're already comfortable with this cloud -based environment here. 83 00:05:57,690 --> 00:06:01,710 And here it is. This is what programming shall look like, whether we're using C 84 00:06:01,710 --> 00:06:05,570 now or Python in a few weeks or JavaScript or SQL thereafter. 85 00:06:05,950 --> 00:06:09,630 So here is what is VS Code configured as follows. 86 00:06:09,910 --> 00:06:13,530 At the top right, you'll generally have one or more tabs for code, much like 87 00:06:13,530 --> 00:06:16,510 tabs in a browser. And this is where you'll write code that looks a little 88 00:06:16,510 --> 00:06:19,910 something like this. And in fact, this is exactly the code that you saw a 89 00:06:19,910 --> 00:06:24,350 ago. What VS Code does, among other things, is it actually highlights your 90 00:06:24,350 --> 00:06:26,690 for you. It colorizes it in what's generally 91 00:06:27,440 --> 00:06:28,780 in an illuminating way. 92 00:06:29,000 --> 00:06:32,400 So I did not choose to make this red. I did not choose to make this blue and 93 00:06:32,400 --> 00:06:35,880 this purple. The computer sort of automatically does that for you, as 94 00:06:35,880 --> 00:06:40,180 see, to sort of draw your attention to different ideas in the program itself. 95 00:06:40,360 --> 00:06:41,800 That all happens automatically. 96 00:06:42,160 --> 00:06:45,940 At the bottom here, you're going to use a more advanced interface today onward 97 00:06:45,940 --> 00:06:49,600 known as a command line interface in the form of a terminal window. 98 00:06:49,820 --> 00:06:53,500 So you can still use your mouse or trackpad and click and drag and do 99 00:06:53,500 --> 00:06:54,720 like that in this environment. 100 00:06:56,330 --> 00:07:00,810 Many programmers prefer that it's much more efficient, ultimately, to use your 101 00:07:00,810 --> 00:07:04,810 keyboard more often than the mouse or the trackpad. So we'll introduce you to 102 00:07:04,810 --> 00:07:06,570 that text -based terminal window there. 103 00:07:06,850 --> 00:07:09,130 Up here at top left, you'll have a file explorer. 104 00:07:09,390 --> 00:07:12,810 So what's nice about VS Code is that not only will you have textual commands 105 00:07:12,810 --> 00:07:16,590 with which you'll get comfy, you also have like a normal Mac or PC or phone 106 00:07:16,590 --> 00:07:21,830 nowadays. Like literally files and folders will visually appear to you so 107 00:07:21,830 --> 00:07:23,530 can play with or manipulate them there. 108 00:07:23,730 --> 00:07:26,830 And then lastly, this is sort of like the menu. the so -called activity bar 109 00:07:26,830 --> 00:07:31,950 just has icons for various features, including CS50's duck. So in fact, if 110 00:07:31,950 --> 00:07:35,750 poke around, you'll see ultimately a duck icon when you log in, which is your 111 00:07:35,750 --> 00:07:39,670 own CS50 -specific chat bot of which you can ask questions throughout the 112 00:07:39,670 --> 00:07:40,670 process. 113 00:07:40,910 --> 00:07:45,930 So now that we've got VS Code here, let's go ahead and actually consider 114 00:07:45,930 --> 00:07:50,030 represents. So this is generally, for jargon's sake, a graphical user 115 00:07:50,250 --> 00:07:53,470 which means buttons and icons and menus and all of that. We all take that for 116 00:07:53,470 --> 00:07:55,230 granted on almost any device nowadays. 117 00:07:55,590 --> 00:07:58,450 That's abbreviated, just so you know, as GUI, G -U -I. 118 00:07:58,770 --> 00:08:04,030 But built into VS Code, again, is what not only the terminal window by name, 119 00:08:04,030 --> 00:08:08,270 conceptually, this is a command line interface. So not a graphical user 120 00:08:08,270 --> 00:08:11,820 interface, but a command line interface. interface, whereby there aren't icons 121 00:08:11,820 --> 00:08:16,240 to click on or double click on. Rather, if you want to run a program, you use 122 00:08:16,240 --> 00:08:21,120 the command line interface, or CLI, to type the name of the program that you 123 00:08:21,120 --> 00:08:22,039 want to run. 124 00:08:22,040 --> 00:08:25,260 And so this will feel like a step backwards initially today, because we 125 00:08:25,260 --> 00:08:27,680 of tap and point and double click at things nowadays. 126 00:08:28,000 --> 00:08:32,179 But again, it's going to give us more power, more efficiency, ultimately 127 00:08:32,179 --> 00:08:33,179 this. 128 00:08:33,550 --> 00:08:37,350 So with that said, let's go ahead and actually use it for just a moment. 129 00:08:37,350 --> 00:08:40,429 class, you're welcome to follow along. But suffice it to say, we'll generally 130 00:08:40,429 --> 00:08:41,429 somewhat quickly. 131 00:08:41,549 --> 00:08:45,910 Really, you're going to learn how to program by way of the problem sets each 132 00:08:45,910 --> 00:08:49,730 week. I'll introduce and focus on the concepts, the ideas, the sort of 133 00:08:49,730 --> 00:08:50,950 primitives that will get you started. 134 00:08:51,170 --> 00:08:55,130 But only through actually doing the problem sets is the muscle memory and 135 00:08:55,130 --> 00:08:58,870 practice going to come. So not to worry if it doesn't all sort of go down easily 136 00:08:58,870 --> 00:08:59,910 the first time around. 137 00:09:00,170 --> 00:09:03,950 So here is the code that I claim is equivalent to last week's Hello World 138 00:09:03,950 --> 00:09:07,230 program, let's actually go ahead and do this in the programming environment. 139 00:09:07,550 --> 00:09:10,830 So I'm going to go ahead and switch over to VS Code itself, which is now running 140 00:09:10,830 --> 00:09:12,690 on my Mac here. It's not just a screenshot. 141 00:09:13,030 --> 00:09:16,630 And I'm going to go ahead and do the following to get started with 142 00:09:16,930 --> 00:09:20,190 I'm going to write literally in my terminal window the word code. 143 00:09:20,430 --> 00:09:23,930 And I might have to give it focus by clicking down in that quadrant of the 144 00:09:23,930 --> 00:09:27,250 screen. And then I'm going to give the name of the file that I want to. 145 00:09:27,680 --> 00:09:30,940 And in this case, I'm going to propose that we call it hello .c. 146 00:09:31,160 --> 00:09:34,040 In the world of Scratch, when you downloaded it, you might have noticed 147 00:09:34,040 --> 00:09:37,600 files are all called like SB3 or some such file extension. 148 00:09:37,900 --> 00:09:42,740 When writing code in C, you literally name the file something .c by 149 00:09:43,020 --> 00:09:45,180 But notice some other details, especially if I zoom in. 150 00:09:45,420 --> 00:09:47,180 Everything I've typed thus far is lowercase. 151 00:09:47,600 --> 00:09:48,700 There's no spaces. 152 00:09:48,980 --> 00:09:50,680 And so this is going to be important. 153 00:09:50,900 --> 00:09:52,920 And unfortunately, computers are not forgiving. 154 00:09:53,260 --> 00:09:57,100 And odds are one of the first stupid mistakes you'll do is miscapitalize 155 00:09:57,100 --> 00:10:01,200 something, misspell something, add too many spaces or the like. Not to worry. 156 00:10:01,200 --> 00:10:03,860 time, that kind of muscle memory will come with practice. 157 00:10:04,180 --> 00:10:05,180 So let me zoom out. 158 00:10:05,390 --> 00:10:09,770 Let me now just hit Enter, and you'll see at top right the Code tab that I 159 00:10:09,770 --> 00:10:12,910 promised. So I'm going to go ahead and type out this program pretty quickly, 160 00:10:12,970 --> 00:10:13,970 because I've done it before. 161 00:10:14,390 --> 00:10:20,330 Include standardio .h, int main void, and then some curly braces, as they're 162 00:10:20,330 --> 00:10:24,510 called, and then printf quote unquote hello comma world backslash end close 163 00:10:24,510 --> 00:10:25,510 quote. 164 00:10:25,679 --> 00:10:29,660 All right, so that's a lot, but that too will come in time with practice. But 165 00:10:29,660 --> 00:10:32,700 this is the exact same code that we saw just a moment ago. 166 00:10:32,940 --> 00:10:36,880 Indeed, if I zoom in, it's color coded just as in the screenshot, and thus I 167 00:10:36,880 --> 00:10:38,160 have written my first program. 168 00:10:38,540 --> 00:10:41,760 VS Code will automatically save for you, but you can also hit Control or Command 169 00:10:41,760 --> 00:10:45,160 S to ensure that it's saved. But notice what's happened at top left. 170 00:10:45,420 --> 00:10:50,380 Not only do you see my code over here, you see a visual icon, just like on a 171 00:10:50,380 --> 00:10:53,920 or PC that, yes, this file now exists in your account. 172 00:10:54,670 --> 00:10:58,410 is what you're getting with VS Code for CS50. You're getting your own sort of 173 00:10:58,410 --> 00:10:59,870 server in the cloud. 174 00:11:00,090 --> 00:11:03,650 It's called a container nowadays. So there's some virtual disk space 175 00:11:03,650 --> 00:11:07,630 in the cloud, a la iCloud or Google Drive, that's going to store all of your 176 00:11:07,630 --> 00:11:11,730 files. And at the moment, because I refreshed my account before class, I 177 00:11:11,730 --> 00:11:13,850 have one file in my own account. 178 00:11:14,250 --> 00:11:15,330 What's this? What's this? 179 00:11:15,550 --> 00:11:17,450 Well, this is like my ID number for GitHub. 180 00:11:17,670 --> 00:11:20,370 Not really a big deal. That's just randomly generated by GitHub. 181 00:11:20,920 --> 00:11:25,180 Urban Adventure is the name of my programming environment today, otherwise 182 00:11:25,180 --> 00:11:26,159 as a code space. 183 00:11:26,160 --> 00:11:29,540 This is just a GitHub thing, which is, again, one of these cloud companies. 184 00:11:29,660 --> 00:11:34,420 Instead of choosing random letters and numbers to uniquely identify all of our 185 00:11:34,420 --> 00:11:37,720 programming environments, it's popular in the tech industry nowadays to just 186 00:11:37,720 --> 00:11:41,500 together random English words that sometimes sound kind of cool. But it's 187 00:11:41,500 --> 00:11:44,560 by coincidence, not something I chose. Yours will be different. 188 00:11:45,420 --> 00:11:47,580 All right, so I've written some code. 189 00:11:47,980 --> 00:11:52,260 I created hello .c. I typed in all of that code. I confirmed visually at left 190 00:11:52,260 --> 00:11:55,920 that it was created. I'm going to hide my file explorer, henceforth, just so we 191 00:11:55,920 --> 00:11:58,500 can focus on the code. How do I actually run this program? 192 00:11:58,740 --> 00:12:02,540 Well, on a Mac or PC, we would be in the habit of opening the folder and double 193 00:12:02,540 --> 00:12:05,440 -clicking on it. Or on your phone, you would take it out and tap on an icon. 194 00:12:05,700 --> 00:12:10,040 But not here. Here, we're focusing primarily on the command line interface 195 00:12:10,040 --> 00:12:12,080 within this whole environment. 196 00:12:12,380 --> 00:12:15,500 So I'm actually going to have to introduce a few commands. 197 00:12:16,010 --> 00:12:20,110 You saw already the code command, which for our purposes is VS Code specific, 198 00:12:20,350 --> 00:12:25,390 that just creates a new file called hello .c in this case. But I need two 199 00:12:25,390 --> 00:12:27,130 commands to actually run this program. 200 00:12:27,410 --> 00:12:31,390 The first, nicely, is called make. And then I specify what program I want to 201 00:12:31,390 --> 00:12:34,410 make. And then a little weirdly, I have to type dot slash hello. 202 00:12:34,910 --> 00:12:38,850 But just to take a step back, make hello. If this is about to be my second 203 00:12:38,850 --> 00:12:42,110 command that I type, what does that step represent, perhaps? 204 00:12:43,780 --> 00:12:45,740 given what I said just a minute or so ago. 205 00:12:48,710 --> 00:12:52,810 Perfect. So make represents the compiler, so to speak, the program that 206 00:12:52,810 --> 00:12:57,570 source code to machine code. I have to do that for now manually by running make 207 00:12:57,570 --> 00:13:01,370 hello. Now, make is kind of smart. And even though I'm saying make hello, not 208 00:13:01,370 --> 00:13:04,790 make hello .c, make is smart. And it's going to say, oh, if you want to make a 209 00:13:04,790 --> 00:13:08,730 program called hello, I'm going to assume that there is somewhere in this 210 00:13:08,730 --> 00:13:13,250 a file called hello .c. So you should not type make hello .c. You just type 211 00:13:13,250 --> 00:13:17,310 hello. And then this third command, even more cryptic, what might it do? 212 00:13:18,380 --> 00:13:23,340 If this is step three of three, that's going to run the machine code. It's 213 00:13:23,340 --> 00:13:27,540 to tell the computer in this folder, sort of the dot implies this current 214 00:13:27,540 --> 00:13:31,240 folder, and dot slash just means something in this current folder, run 215 00:13:31,240 --> 00:13:32,260 program called hello. 216 00:13:32,500 --> 00:13:35,160 So that's it. There's three steps to writing a program in C. 217 00:13:35,360 --> 00:13:38,540 You create the file, as with the code command, but there are other ways to do 218 00:13:38,540 --> 00:13:41,320 that too. And you don't even have to use VS Code. You can use dozens of other 219 00:13:41,320 --> 00:13:45,220 alternative programs in the world. You run the compiler, which in this case is 220 00:13:45,220 --> 00:13:46,220 called make. 221 00:13:46,250 --> 00:13:48,270 Little white lie, make is not actually the compiler. 222 00:13:48,470 --> 00:13:53,490 But more on that next week. But make is going to trigger compilation of this 223 00:13:53,490 --> 00:13:57,790 code. And the last step three is to execute or run the program called hello. 224 00:13:58,030 --> 00:13:59,790 So let me go back to VS Code here. 225 00:14:00,350 --> 00:14:04,010 And you'll see that my code is still at the top. My terminal window is at the 226 00:14:04,010 --> 00:14:06,910 bottom. I hid my file explorer, just because it's not that interesting 227 00:14:07,190 --> 00:14:12,670 And I'm going to do what you proposed, which was m -a -k -e space hello, all 228 00:14:12,670 --> 00:14:14,530 lowercase, Enter. 229 00:14:15,310 --> 00:14:17,990 And ironically, thankfully, nothing happened. 230 00:14:18,250 --> 00:14:21,010 And that's actually a good thing in this environment. If nothing seems to 231 00:14:21,010 --> 00:14:24,510 happen, you probably did good. If anything does seem to happen on the 232 00:14:24,610 --> 00:14:26,810 you probably screwed up and you've made some mistakes. 233 00:14:27,030 --> 00:14:28,930 So seeing nothing is generally a good thing. 234 00:14:29,270 --> 00:14:33,470 But what has happened? Well, let me actually go back and open up my file 235 00:14:33,470 --> 00:14:37,990 explorer. And notice there's not only kylo .c, but there's a second file now. 236 00:14:38,660 --> 00:14:40,840 Hello, which is the name of the program. 237 00:14:41,360 --> 00:14:43,780 So hello is the program I want to run. 238 00:14:44,140 --> 00:14:47,660 I'm going to go back to my terminal here. And to run this program, I'm going 239 00:14:47,660 --> 00:14:51,540 do dot slash H -E -L -L -O. I'm going to cross my fingers, as I'll often now do. 240 00:14:51,640 --> 00:14:55,540 And voila, my very first program in C. 241 00:14:56,950 --> 00:14:58,770 How else can we see this file? 242 00:14:59,010 --> 00:15:02,410 Well, down here in my terminal window, let me zoom in, you keep seeing a dollar 243 00:15:02,410 --> 00:15:05,330 sign. That has nothing to do with currency. It's just a weird geeky 244 00:15:05,330 --> 00:15:09,330 that you're prompt at a terminal window. Like, where you type commands generally 245 00:15:09,330 --> 00:15:12,490 starts with a dollar sign. Sometimes it's a hash symbol. Sometimes it's an 246 00:15:12,490 --> 00:15:13,490 angled bracket. 247 00:15:13,530 --> 00:15:16,810 It depends on the system you're on. But dollar sign is very common. It just 248 00:15:16,810 --> 00:15:18,030 means type your commands here. 249 00:15:18,290 --> 00:15:21,310 Well, I've typed code. I've typed make. And I've typed dot slash hello. 250 00:15:21,650 --> 00:15:25,410 But I can type other things, too, and more on these later, like ls. 251 00:15:25,760 --> 00:15:29,280 which doesn't actually spell something, but is short for list, L -I -S -T. 252 00:15:30,090 --> 00:15:32,970 Programmers tend to just be as succinct as they can, so most commands are not 253 00:15:32,970 --> 00:15:38,510 full words. They're often abbreviations. If I hit Enter now, you'll see also two 254 00:15:38,510 --> 00:15:43,090 things. You'll see hello .c, and you'll see in green, just to draw attention to 255 00:15:43,090 --> 00:15:44,330 it, hello as well. 256 00:15:44,550 --> 00:15:48,930 The asterisk here just means, in the programming environment, this program is 257 00:15:48,930 --> 00:15:53,170 executable. You can actually run this by doing dot slash hello. The fact that 258 00:15:53,170 --> 00:15:56,530 this is just white here, that just means it's some text file. It's, in fact, 259 00:15:56,780 --> 00:15:57,519 source code. 260 00:15:57,520 --> 00:16:02,360 So in other words, ls lists the file in my current folder, or you can use your 261 00:16:02,360 --> 00:16:06,260 human eyes in the file explorer at top left and just look at what files exist. 262 00:16:06,580 --> 00:16:11,600 These are one and the same. One is a GUI, one is a CLI, graphical, command 263 00:16:11,720 --> 00:16:17,260 and so forth. And we'll start to take these kinds of paradigms soon for 264 00:16:17,760 --> 00:16:21,600 But let me pause here and see thus far, now that we've written our first of many 265 00:16:21,600 --> 00:16:25,860 C programs, any questions or confusion we can clear up. 266 00:16:27,210 --> 00:16:30,610 So OK, if you don't understand most of the lines of code, that's what today is 267 00:16:30,610 --> 00:16:31,429 about. Yeah? 268 00:16:31,430 --> 00:16:34,290 I don't really understand the difference between hello and hello .c. DAVID J. 269 00:16:34,370 --> 00:16:38,070 What's the difference between hello and hello .c? So hello .c is literally my 270 00:16:38,070 --> 00:16:41,570 source code. It is a file that exists somewhere in the cloud that contains all 271 00:16:41,570 --> 00:16:43,030 of the code I myself wrote. 272 00:16:43,230 --> 00:16:50,150 The hello file is the file that the compiler created for me by converting 273 00:16:50,150 --> 00:16:53,950 source code to the machine code. So inside of hello, theoretically, is a 274 00:16:53,950 --> 00:16:54,990 bunch of zeros and ones. 275 00:16:55,190 --> 00:16:56,690 We can't quite see them. 276 00:16:56,950 --> 00:16:58,790 But if I do this, let me zoom out. 277 00:16:59,200 --> 00:17:03,080 Let me click on Hello and notice that VS Code is going to yell at me. The file 278 00:17:03,080 --> 00:17:07,420 is not displayed in the text editor because it is either binary, that is 279 00:17:07,420 --> 00:17:11,480 and ones, or uses an unsupported text encoding, whatever that means. If I do 280 00:17:11,480 --> 00:17:15,339 open it anyway, but I don't recommend this, like heed these warnings, you 281 00:17:15,339 --> 00:17:18,420 see zeros and ones, but you will see sort of nonsense. 282 00:17:18,819 --> 00:17:22,660 And this is because VS Code is trying to interpret those zeros and ones 283 00:17:22,660 --> 00:17:26,420 incorrectly as ASCII text, like English text, but it's not. 284 00:17:26,829 --> 00:17:30,010 They're instructions for the computer. So as soon as you see scary red stuff 285 00:17:30,010 --> 00:17:34,130 like this, undo, close whatever tab you open, because odds are you can only 286 00:17:34,130 --> 00:17:37,650 break the program you just created. It's not a huge deal. You can recreate it, 287 00:17:37,730 --> 00:17:40,290 but that's what's inside of those files. 288 00:17:41,390 --> 00:17:46,790 Yeah? What if we don't type dot slash hello, we just type hello? DAVID MALAN - 289 00:17:46,790 --> 00:17:50,670 Really good question. What if we don't type dot slash hello, we just type 290 00:17:50,790 --> 00:17:53,630 Well, let me do this. Let me hide my file explorer again, because it's not 291 00:17:53,630 --> 00:17:54,870 interesting here on out. 292 00:17:55,340 --> 00:17:59,100 I'm going to clear my terminal window by hitting Control -L just to be neat and 293 00:17:59,100 --> 00:18:02,300 tidy in class. Or you can literally type clear, and it will clear it. But again, 294 00:18:02,360 --> 00:18:04,920 that's just to keep things tidy. Your TF might do that in section two. 295 00:18:05,340 --> 00:18:09,800 If I just type hello enter, I'm going to get this. Weirdly, bash hello command 296 00:18:09,800 --> 00:18:10,719 not found. 297 00:18:10,720 --> 00:18:14,120 So more on bash down the line. But this just means literally the command hello 298 00:18:14,120 --> 00:18:16,560 is not found because you need to tell the computer where it is. 299 00:18:16,820 --> 00:18:22,430 So dot slash hello means run the hello program that is in fact, right here. By 300 00:18:22,430 --> 00:18:28,390 contrast, you don't run .slash for code, for make, or other commands that we'll 301 00:18:28,390 --> 00:18:32,310 soon see, like ls. Because why? Those are installed in the system for 302 00:18:32,590 --> 00:18:36,110 not just in your individual folder. So that's the difference. Any programs we 303 00:18:36,110 --> 00:18:38,030 write, it'll be .slash something. 304 00:18:38,530 --> 00:18:39,530 All right. 305 00:18:39,740 --> 00:18:43,580 So let's tease apart what is actually going on here and see if we can lean 306 00:18:43,580 --> 00:18:47,580 heavily today on Scratch, especially as the syntax gets weird, perhaps a little 307 00:18:47,580 --> 00:18:49,500 overwhelming, still the same idea. 308 00:18:49,720 --> 00:18:53,100 So this last time, of course, was our Scratch program that just said hello 309 00:18:53,100 --> 00:18:57,800 world. I claim today that this is the nearest equivalent that any programmer 310 00:18:57,800 --> 00:19:02,160 could convert Scratch into C. If we color coded accordingly, indeed, this 311 00:19:02,160 --> 00:19:06,280 of lines up with when green flag clicked is the orange, and then the purple is 312 00:19:06,280 --> 00:19:07,640 just the equivalent of the say block. 313 00:19:07,900 --> 00:19:09,980 So the say block we said earlier was a function. 314 00:19:10,240 --> 00:19:13,580 So let's compare these things side by side, because there's actually some 315 00:19:13,580 --> 00:19:17,900 and reason to what MIT did with Scratch as to why these shapes look like they do 316 00:19:17,900 --> 00:19:21,780 and so forth. So in Scratch, there's a function called say. 317 00:19:22,200 --> 00:19:26,820 Recall that it takes an input, otherwise known as an argument, or a parameter is 318 00:19:26,820 --> 00:19:30,980 another name. And that's always provided in these white ovals, zero or more 319 00:19:30,980 --> 00:19:34,100 white ovals. In C, we've already seen, but let's do it a little more 320 00:19:34,100 --> 00:19:37,980 pedantically, the equivalent of say is essentially the word print. 321 00:19:38,560 --> 00:19:40,360 Why did MIT say you say? 322 00:19:40,560 --> 00:19:41,219 Just because. 323 00:19:41,220 --> 00:19:44,260 It's a little more kid -friendly. But print is the idea in our environment. 324 00:19:44,580 --> 00:19:47,280 It's actually not print. It's printf, because we're going to be able to format 325 00:19:47,280 --> 00:19:50,760 our text in interesting ways. More on that in a moment. But notice, the 326 00:19:50,760 --> 00:19:55,040 parentheses and closing parentheses here sort of conjure up the idea of that 327 00:19:55,040 --> 00:19:55,919 white oval. 328 00:19:55,920 --> 00:19:58,120 So that's kind of intentional on MIT's part. 329 00:19:58,520 --> 00:20:03,140 What, though, in C goes between these parentheses? Well, literally the input 330 00:20:03,140 --> 00:20:05,900 the argument you want to pass to the function, like hello world. 331 00:20:06,460 --> 00:20:09,460 But in C, you have to be a little more pedantic because you don't have a nice 332 00:20:09,460 --> 00:20:13,060 little graphic like this purple block with the white oval. You have to 333 00:20:13,060 --> 00:20:14,820 everything in double quotes. 334 00:20:15,080 --> 00:20:19,020 Those of you with prior programming experience, in C, you need double 335 00:20:19,120 --> 00:20:20,560 not single quotes in this context. 336 00:20:20,860 --> 00:20:25,180 And then there's this arcane detail here, backslash n, which we'll come back 337 00:20:25,180 --> 00:20:26,200 in just a moment. 338 00:20:26,400 --> 00:20:30,980 But that's essentially what's going on. Line by line, from scratch to C, there's 339 00:20:30,980 --> 00:20:34,960 kind of an equality between those two, even though they, of course, look a 340 00:20:34,960 --> 00:20:35,960 little bit different. 341 00:20:36,250 --> 00:20:40,050 Well, let's see what that backslash n is doing, just to highlight some details 342 00:20:40,050 --> 00:20:42,210 here. So let me actually zoom in a little bit here. 343 00:20:42,550 --> 00:20:47,470 And let me go up to my code. And let me just sort of recklessly delete the 344 00:20:47,470 --> 00:20:48,470 backslash n. 345 00:20:48,490 --> 00:20:52,190 I'm going to let it autosave. I'll zoom out. In my terminal window now, I'm 346 00:20:52,190 --> 00:20:58,750 going to run make hello to recompile the code from source code to machine code, 347 00:20:58,830 --> 00:21:00,270 because I changed the source code. 348 00:21:00,590 --> 00:21:02,250 Nothing seems to happen. That's good. 349 00:21:02,490 --> 00:21:05,330 Now I'm going to type dot slash hello, Enter. 350 00:21:06,040 --> 00:21:12,920 And there's a subtle bug since I made that change. What looks wrong to your 351 00:21:12,920 --> 00:21:13,920 eye now? 352 00:21:16,720 --> 00:21:20,040 Yeah, the dollar sign, our so -called prompt, is at the end of the line 353 00:21:20,040 --> 00:21:21,040 of on its new line. 354 00:21:21,300 --> 00:21:24,660 I mean, this isn't really a deal breaker. The code works, and you can 355 00:21:24,660 --> 00:21:28,000 a new command. But it just looks a little stupid. This was not the intent 356 00:21:28,000 --> 00:21:31,880 program. It's sort of good practice to move the prompt to the next line. And 357 00:21:31,880 --> 00:21:35,160 that's because the backslash n is what we're going to call an escape sequence. 358 00:21:35,360 --> 00:21:40,240 So it turns out in programming, you have to tell the computer exactly what you 359 00:21:40,240 --> 00:21:44,740 want it to do. So if you want a new line, the equivalent of hitting Enter on 360 00:21:44,740 --> 00:21:47,800 screen, you have to tell the computer computer to put a new line there. 361 00:21:48,080 --> 00:21:53,340 What you do not do is this. If I zoom out and I go into my code here, and I'll 362 00:21:53,340 --> 00:21:57,260 zoom in on the code, if you want to put a new line, you don't do this. 363 00:21:57,959 --> 00:22:01,960 Why? It's just confusing for the computer. Like, wait a minute, is that a 364 00:22:02,060 --> 00:22:03,260 Did your lines just wrap? 365 00:22:03,500 --> 00:22:07,120 Do you want to put a new line there? It just looks stupid. And it makes it less 366 00:22:07,120 --> 00:22:08,740 line -based, the code itself. 367 00:22:09,060 --> 00:22:12,720 So humans decided years ago, if you want an actual line break, don't just 368 00:22:12,720 --> 00:22:14,020 naively hit the Enter key. 369 00:22:14,280 --> 00:22:16,600 Literally tell the computer, put a new line here. 370 00:22:16,840 --> 00:22:20,620 If you want to move two lines down, just do two of those. If you want three, 371 00:22:20,860 --> 00:22:21,880 just do three of those. 372 00:22:22,120 --> 00:22:25,660 Well, why the backslash? Again, these are what are called escape sequences. 373 00:22:25,940 --> 00:22:27,560 And you don't literally want an N. 374 00:22:27,950 --> 00:22:33,270 let alone nnn, what you want is a new line which is represented in code as 375 00:22:33,270 --> 00:22:35,470 simply backslash n. 376 00:22:36,090 --> 00:22:40,930 Now, for the mathematicians among you, what we're doing now by using functions 377 00:22:40,930 --> 00:22:44,330 like printf is just sort of like f of x notation, if you recall that from high 378 00:22:44,330 --> 00:22:48,330 school or prior, where f is a function, x is an argument or an input thereto. 379 00:22:48,530 --> 00:22:52,790 And we're using parentheses in code just like mathematicians would to write 380 00:22:52,790 --> 00:22:53,790 functions like these. 381 00:22:54,030 --> 00:22:57,590 And the types of functions we're using right now still follow this model. 382 00:22:57,590 --> 00:22:58,750 got input. You want output. 383 00:22:58,950 --> 00:23:03,610 In this case, the input to printf, for instance, just like the say block, is 384 00:23:03,610 --> 00:23:04,610 what's called an argument. 385 00:23:05,570 --> 00:23:09,070 Output, though, of the function printf is what we call a side effect. 386 00:23:09,310 --> 00:23:12,270 And the easiest way to think about that is a side effect is just something that 387 00:23:12,270 --> 00:23:14,170 sort of like happens on the screen. 388 00:23:14,630 --> 00:23:18,890 Visually, audially, it just sort of happens. And there's that effect on the 389 00:23:18,890 --> 00:23:22,590 screen. And we'll contrast this with other types of outputs from functions. 390 00:23:22,590 --> 00:23:26,390 for now, we're focusing on just this, which is reminiscent, of course, of what 391 00:23:26,390 --> 00:23:30,390 we did last week, which is if you type hello world into the white oval, use the 392 00:23:30,390 --> 00:23:34,910 say. Puzzle piece, you get out the side effect of the cat appearing to have 393 00:23:34,910 --> 00:23:36,490 said, hello, world. 394 00:23:37,070 --> 00:23:41,850 Now, as for those escape sequences in C, there's bunches of them, but very few 395 00:23:41,850 --> 00:23:43,610 of them will we actually use in practice. 396 00:23:43,850 --> 00:23:44,950 Backslash n is a new line. 397 00:23:45,650 --> 00:23:48,810 Backslash r is a little more subtle, and it's kind of a feature of yesteryear. 398 00:23:48,890 --> 00:23:52,770 It moves the cursor not to the new line, but to the beginning of the line, kind 399 00:23:52,770 --> 00:23:55,350 of like an old -timey typewriter, if you've seen how those work. 400 00:23:55,910 --> 00:23:56,910 Sometimes, though. 401 00:23:57,180 --> 00:23:59,840 you might want to print out an actual double quote. 402 00:24:00,220 --> 00:24:04,340 But there's a problem, of course. If this is my code here, and I'm already 403 00:24:04,340 --> 00:24:09,080 double quotes as sort of special symbols to surround the text I want printf to 404 00:24:09,080 --> 00:24:12,760 say, it would probably be a little worse. Like, if you wanted to say, 405 00:24:12,920 --> 00:24:18,760 world, with sort of finger quotes, why might this not be a good idea, 406 00:24:18,940 --> 00:24:22,380 if you think about this from the computer's perspective? 407 00:24:24,170 --> 00:24:26,550 Why is this probably not the right way to do this? Yeah. 408 00:24:29,370 --> 00:24:32,510 Yeah, exactly. The computer is indeed going to read your code top to bottom, 409 00:24:32,590 --> 00:24:35,850 left to right. And when it sees the first open quote, OK, that's fine. It 410 00:24:35,850 --> 00:24:38,730 understands that. But when it gets to the second quote, it's going to assume, 411 00:24:38,850 --> 00:24:41,490 oh, wait a minute. Maybe you only want me to say, hello, comma. 412 00:24:41,870 --> 00:24:44,710 And then it's going to keep reading and be like, wait a minute. Why is there the 413 00:24:44,710 --> 00:24:48,270 word world here? And then, wait a minute. Now there's two more quotes. 414 00:24:48,270 --> 00:24:49,450 confusing. It's ambiguous. 415 00:24:49,730 --> 00:24:52,610 And computers need you to be, again, very precise. 416 00:24:53,070 --> 00:24:57,470 So if you want a quotation mark to literally be displayed on the screen, 417 00:24:57,470 --> 00:25:00,790 would escape it, so to speak. speak, which looks a little weird and takes 418 00:25:00,790 --> 00:25:04,390 getting into the habit of. But this just solves that kind of problem. 419 00:25:04,650 --> 00:25:07,810 And similarly, might you use single quotes in other contexts? More on that 420 00:25:07,990 --> 00:25:11,310 And if you really want to bend your mind, how do you actually print a 421 00:25:11,310 --> 00:25:15,290 backslash if you ever care to? It's not that common a character to type. But if 422 00:25:15,290 --> 00:25:18,970 you ever want it on the screen, it seems that we're using backslash as a special 423 00:25:18,970 --> 00:25:23,370 character that says, hey, give me a new line, or give me a carriage return, or 424 00:25:23,370 --> 00:25:24,370 give me a double quote. 425 00:25:24,870 --> 00:25:28,530 Weirdly, in programming, if you want to type a literal backslash, on the screen, 426 00:25:28,710 --> 00:25:32,930 you literally do backslash, backslash. But that's it for sort of weirdness for 427 00:25:32,930 --> 00:25:37,110 now. But this is to say, humans tripped over the same problems years ago. They 428 00:25:37,110 --> 00:25:38,110 came up with solutions. 429 00:25:38,170 --> 00:25:41,010 And now we indeed have these conventions in code. 430 00:25:41,650 --> 00:25:42,650 All right. 431 00:25:42,880 --> 00:25:46,400 So let's tease apart some other features of this in every program we're going to 432 00:25:46,400 --> 00:25:48,660 write, namely what's at the top of this file. 433 00:25:48,920 --> 00:25:53,680 So at the very top of this file, there is this cryptic -looking hash include or 434 00:25:53,680 --> 00:25:56,860 pound include standard IO dot h in angle brackets. 435 00:25:57,200 --> 00:26:00,160 So this is a little weird. We'll talk more about this next week, too. But this 436 00:26:00,160 --> 00:26:01,620 is what's called a header file. 437 00:26:01,920 --> 00:26:05,400 Any file that ends in dot h is not a 438 00:26:06,400 --> 00:26:10,440 Source, well, any file that ends in .h is what we're going to call a header 439 00:26:10,440 --> 00:26:15,980 file. And inside of that header file is functionality that maybe came with the 440 00:26:15,980 --> 00:26:18,140 system, came with the programming language itself. 441 00:26:18,700 --> 00:26:20,240 So for instance, I'm going to do this. 442 00:26:20,480 --> 00:26:23,820 I'm going to go back to my code here, and I'm going to make a very common 443 00:26:23,820 --> 00:26:26,760 mistake that you yourselves might make in the coming days, where I just forget 444 00:26:26,760 --> 00:26:29,620 that line, because I don't even understand it in the first place, so I 445 00:26:29,620 --> 00:26:30,760 didn't think to type it here. 446 00:26:31,360 --> 00:26:35,740 Now, if I go back to my terminal window after clearing it, and I run make hello, 447 00:26:36,000 --> 00:26:39,340 because I want to recompile it, because I've changed the source code, I'm going 448 00:26:39,340 --> 00:26:42,860 to see a fairly cryptic error. I mean, there's more error on the screen than 449 00:26:42,860 --> 00:26:44,040 there is code up here. 450 00:26:44,590 --> 00:26:47,850 But you'll get the hang of sort of reading it to try to figure out what's 451 00:26:47,850 --> 00:26:48,850 on. And I'm seeing this. 452 00:26:49,050 --> 00:26:52,430 Hello .c line 3 character 5. 453 00:26:52,770 --> 00:26:57,290 So that just means line 3 colon character 5 from left to right. It's 454 00:26:57,290 --> 00:26:59,010 visual cue as to where the problem is. 455 00:26:59,250 --> 00:27:03,830 Call to undeclared library function printf with type dot, dot, dot. And then 456 00:27:03,830 --> 00:27:06,210 rest kind of overwhelms me visually at this point. 457 00:27:06,430 --> 00:27:07,430 But that's a hint. 458 00:27:07,830 --> 00:27:12,990 If you do not include that header file at the top of the code you've written, 459 00:27:13,190 --> 00:27:16,950 you do not have access to what's generally called a library. 460 00:27:17,250 --> 00:27:21,510 A library is a collection of code that someone else wrote for you. Maybe it was 461 00:27:21,510 --> 00:27:25,590 MIT. Maybe it was the authors of the C language itself years ago. Maybe it was 462 00:27:25,590 --> 00:27:30,030 CS50 if we wrote some code for you. A library is a collection of code that 463 00:27:30,030 --> 00:27:35,070 someone else wrote for you. And you access it again by including header 464 00:27:35,070 --> 00:27:36,970 that those same people wrote for you. 465 00:27:37,230 --> 00:27:41,730 So if I go back to my code now, let me clear my terminal window just to be Less 466 00:27:41,730 --> 00:27:45,210 overwhelmed. Let me undo what I just did and put that file back. 467 00:27:45,530 --> 00:27:51,650 Can you perhaps infer, just functionally, what is inside of standard 468 00:27:51,670 --> 00:27:52,670 again, someone else wrote? 469 00:27:52,810 --> 00:27:54,070 What must be inside? 470 00:27:56,090 --> 00:28:01,900 Printf. So whoever invented printf decades ago probably put that code in 471 00:28:01,900 --> 00:28:06,180 file. And so by including it, so to speak, in my code, I now have access to 472 00:28:06,180 --> 00:28:07,320 printf functionality. 473 00:28:07,540 --> 00:28:12,200 So that's all. And again, C is lower level than Scratch. It's obviously text 474 00:28:12,200 --> 00:28:15,520 -based, which means you have to be a little more pedantic yourself as to what 475 00:28:15,520 --> 00:28:18,580 you want the computer to do for you. And if you want to use someone else's code, 476 00:28:18,900 --> 00:28:22,920 you indeed have to include it. Scratch didn't bother with this, but we indeed 477 00:28:22,920 --> 00:28:26,080 need to do this in the context of C. 478 00:28:27,040 --> 00:28:32,320 As an aside, just to preempt some unnecessary headache, this word is not 479 00:28:32,320 --> 00:28:36,980 .h. Every year, a non -zero number of people can't understand why their code's 480 00:28:36,980 --> 00:28:41,860 not working because studio .h is not found. It's standard io, s -t -d -i -o 481 00:28:42,420 --> 00:28:46,080 That's one of the first frequently made mistakes otherwise. 482 00:28:46,700 --> 00:28:50,980 All right, so remember that. Let me undo now the unnecessary quotes I added 483 00:28:50,980 --> 00:28:53,040 here. And let me propose that. 484 00:28:53,550 --> 00:28:57,610 We show you where you can learn more. So all of these libraries generally are 485 00:28:57,610 --> 00:29:00,970 documented. People wrote instructions for how to use them. So you don't just 486 00:29:00,970 --> 00:29:03,810 have to listen and pay attention only in class. You don't have to pull up a 487 00:29:03,810 --> 00:29:07,330 book. There tends to be online documentation as well, for instance, for 488 00:29:07,330 --> 00:29:09,150 standard IO header file. 489 00:29:09,430 --> 00:29:13,970 And the documentation in the world of programming for C specifically, are 490 00:29:13,970 --> 00:29:16,210 manual pages, or man pages for short. 491 00:29:16,490 --> 00:29:21,070 Unfortunately, they're really written decades ago for the more comfortable 492 00:29:21,070 --> 00:29:23,390 you, those who have an eye already for programming. 493 00:29:23,670 --> 00:29:28,550 And so what CS50 has done at this URL, manual .cs50 .io, is we essentially have 494 00:29:28,550 --> 00:29:33,610 more user -friendly versions of the documentation for this header file and 495 00:29:33,610 --> 00:29:38,430 others. So for instance, if I pull up manual .cs50 .io, you'll see a web page 496 00:29:38,430 --> 00:29:39,199 like this. 497 00:29:39,200 --> 00:29:43,300 And if I just scroll quickly, you'll see a whole bunch of header files, .h 498 00:29:43,300 --> 00:29:46,940 files, and a whole bunch of functions beneath them. And there's only a couple 499 00:29:46,940 --> 00:29:51,280 dozen or so here. And indeed, per this checkbox at the top, frequently used in 500 00:29:51,280 --> 00:29:54,880 CS50, we have sort of highlighted the functions that odds are over the next 501 00:29:54,880 --> 00:29:58,340 month and a half you will probably want to use. 502 00:29:58,600 --> 00:30:03,820 If I turn off that less comfortable mode, there's actually hundreds of 503 00:30:03,820 --> 00:30:07,660 that come with C. And no programmer knows all of these functions. What they 504 00:30:07,660 --> 00:30:11,300 is they read the manual when they want to find some new piece of functionality. 505 00:30:11,640 --> 00:30:15,100 So I'm going to simplify this. I'm going to scroll down, though, to standardio 506 00:30:15,100 --> 00:30:19,070 .h. for instance, here. And you'll see more functions that we'll eventually get 507 00:30:19,070 --> 00:30:24,210 to. But if I click on printf, you'll see, hopefully, some fairly user 508 00:30:24,210 --> 00:30:28,890 instructions for how this thing works. For instance, under synopsis, you'll see 509 00:30:28,890 --> 00:30:32,810 that we tell you what header file you should include in order to use it. 510 00:30:33,090 --> 00:30:34,690 Below that is something called a prototype. 511 00:30:35,030 --> 00:30:36,009 More on that later. 512 00:30:36,010 --> 00:30:37,330 But below that is a description. 513 00:30:37,610 --> 00:30:41,290 And here is where we, the CS50 staff, have written in layperson's terms 514 00:30:41,290 --> 00:30:44,950 explanations of how this function works, how to use it, and so forth. 515 00:30:45,290 --> 00:30:49,210 But if you'd rather see what the real world uses, you can turn off that mode, 516 00:30:49,350 --> 00:30:51,810 and you'll see much more arcanely the original language. 517 00:30:52,070 --> 00:30:55,170 So in short, these are sort of like training wheels that you can turn on and 518 00:30:55,170 --> 00:30:56,190 at your leisure. 519 00:30:56,470 --> 00:31:00,630 But ultimately, this is real world documentation as well. 520 00:31:00,970 --> 00:31:04,210 So if we want to see something else, for instance, let me go back to the main 521 00:31:04,210 --> 00:31:09,220 menu. And as we'll see today, there are actually function in a header file 522 00:31:09,220 --> 00:31:13,200 called cs50 .h that, for a few weeks, we're going to lean on heavily. 523 00:31:13,440 --> 00:31:18,260 Long story short, it's actually kind of hard. It's annoying in C to get user 524 00:31:18,260 --> 00:31:22,460 input, ironically, to get the human to type in a word or a number. 525 00:31:22,660 --> 00:31:26,100 You have to jump through some technical hoops to make that happen. And we'll 526 00:31:26,100 --> 00:31:30,500 show you how to do it the real way in a few weeks. But for now, among the first 527 00:31:30,500 --> 00:31:34,820 training wheels is a CS50 library code that we wrote that will just make your 528 00:31:34,820 --> 00:31:35,779 life easier. 529 00:31:35,780 --> 00:31:39,880 And indeed, we're going going to give you access to functions that simplify 530 00:31:39,880 --> 00:31:44,100 process of actually getting input from the user. So case in point, we're going 531 00:31:44,100 --> 00:31:49,740 to give you access to a function like getString when you want to get a string 532 00:31:49,740 --> 00:31:53,180 text from the user. String is just text. So if you want to get one character, 533 00:31:53,260 --> 00:31:57,200 one word, one sentence, one paragraph, you can call a function called 534 00:31:57,380 --> 00:31:59,940 We're going to give you another one called getInt when you want to get an 535 00:31:59,940 --> 00:32:04,000 integer from the user, like 1 or 0 or negative 1 or anything else. You can use 536 00:32:04,000 --> 00:32:07,580 that function as well. And we'll see today, too, there's other functions you 537 00:32:07,580 --> 00:32:09,320 use from CS50's library. 538 00:32:09,640 --> 00:32:13,240 In a few weeks' time, we'll take these away once you sort of don't need them 539 00:32:13,240 --> 00:32:17,450 anymore. And you'll see what those library functions have been doing all 540 00:32:17,450 --> 00:32:19,530 for you. But for now, let's focus on this. 541 00:32:19,820 --> 00:32:23,580 perhaps the most useful of them, getString, and solve a problem that we 542 00:32:23,580 --> 00:32:28,040 already pretty easily in Scratch. So recall in Scratch, this was a program 543 00:32:28,040 --> 00:32:29,040 used two functions. 544 00:32:29,160 --> 00:32:32,240 Three, in fact. Ask, to ask a question of the user. 545 00:32:32,480 --> 00:32:36,280 Say, to actually display something on the screen. And join, to combine the 546 00:32:36,280 --> 00:32:40,840 default of Apple banana, or in this case, hello, and whatever the human's 547 00:32:40,840 --> 00:32:46,240 was. So this made our hello program a little more interactive last time. How 548 00:32:46,240 --> 00:32:50,600 we actually translate this into a similar paradigm now? So input and 549 00:32:50,600 --> 00:32:54,400 the story as always. In this case, we have arguments going into those 550 00:32:54,840 --> 00:32:58,200 But now we're going to introduce not side effects, which is stuff that 551 00:32:58,200 --> 00:33:03,220 visually. We're going to revisit that blue circle called answer or the blue 552 00:33:03,220 --> 00:33:07,600 called answer that represented last week what we called a return value. 553 00:33:07,920 --> 00:33:11,300 And this is what many functions will actually do for us. They're not just 554 00:33:11,300 --> 00:33:14,720 to display something presumptuously on the screen or play a sound or a video or 555 00:33:14,720 --> 00:33:17,980 something like that. They're going to hand you back virtually a value. 556 00:33:18,590 --> 00:33:25,250 text or integers or sounds or images that you can then do with what you see 557 00:33:25,470 --> 00:33:29,790 So the paradigm we'll now have is, much like in Scratch, if the input is what's 558 00:33:29,790 --> 00:33:34,250 your name and the function is ask and you get back a return value of answer, 559 00:33:34,250 --> 00:33:35,750 want to actually do this now in C. 560 00:33:35,990 --> 00:33:40,230 So side by side, what code like this in Scratch is going to look like today 561 00:33:40,230 --> 00:33:41,610 onward is this. 562 00:33:42,040 --> 00:33:46,000 Instead of using the ask block, you literally use CS50's function called get 563 00:33:46,000 --> 00:33:47,360 string. It takes input. 564 00:33:47,560 --> 00:33:50,680 So we put the parentheses on the left and the right to kind of conjure the 565 00:33:50,680 --> 00:33:52,100 of this white oval. 566 00:33:52,540 --> 00:33:56,620 Inside of that string, you can put a prompt, so to speak. Like, what do you 567 00:33:56,620 --> 00:33:58,500 the human to be asked in this case? 568 00:33:58,840 --> 00:34:02,500 And I'm missing something still, per the placeholders here. What's missing? 569 00:34:04,360 --> 00:34:07,660 So quotation marks, so literally quotation marks on the left and the 570 00:34:07,660 --> 00:34:10,580 I'm going to be a little anal here. I'm going to put a space at the end because 571 00:34:10,580 --> 00:34:14,159 I don't want to. I could, but I don't want the cursor to go to the next line, 572 00:34:14,400 --> 00:34:18,400 hence no backslash n. If I want the cursor just to sit there kind of 573 00:34:18,520 --> 00:34:21,920 waiting for the user after the question mark, I'm just going to put a space so 574 00:34:21,920 --> 00:34:25,900 it will stay there for me. But this is just an aesthetic detail using the same 575 00:34:25,900 --> 00:34:26,900 idea as before. 576 00:34:27,060 --> 00:34:29,020 So that is the analog of this block. 577 00:34:29,260 --> 00:34:32,040 But how do I get access to the so -called return value? 578 00:34:32,280 --> 00:34:34,620 MIT just plopped it on the screen for me. for us automatically. 579 00:34:34,840 --> 00:34:39,120 In C, we have to write a little more code to get access to that return value. 580 00:34:39,520 --> 00:34:43,380 And the way we do this is on the left -hand side of this line of code, we come 581 00:34:43,380 --> 00:34:45,460 up with a name for the return value. 582 00:34:45,679 --> 00:34:49,600 You can call it anything you want, but answer is a nice equivalent to what MIT 583 00:34:49,600 --> 00:34:53,139 did. You could more generically call it x or y or z, but that's not really 584 00:34:53,139 --> 00:34:56,960 useful. And so computer scientists, unlike mathematicians, will tend to use 585 00:34:56,960 --> 00:34:59,760 variables that are a little more verbose, like the word answer. 586 00:35:00,400 --> 00:35:05,000 But in C, it's, again, a little lower level. You have to tell the computer 587 00:35:05,000 --> 00:35:07,880 type of variable this is going to be. 588 00:35:08,140 --> 00:35:12,620 So I'm kind of conflating variable and return value, but they're being used in 589 00:35:12,620 --> 00:35:13,820 an intertwined way. 590 00:35:14,100 --> 00:35:19,260 The get string function, just like the ask block, returns the value. 591 00:35:19,580 --> 00:35:22,940 If you want to do something with it, you need to put it in something called a 592 00:35:22,940 --> 00:35:25,890 variable, which is denoted in text here. 593 00:35:26,110 --> 00:35:29,410 But again, per last week, the computer doesn't know if it's looking at numbers 594 00:35:29,410 --> 00:35:33,230 or characters or images or sounds. You have to tell it as the programmer that 595 00:35:33,230 --> 00:35:36,910 the zeros and ones that are somehow involved here underneath the computer's 596 00:35:36,910 --> 00:35:39,890 are, in fact, to be treated as text, a .k .a. 597 00:35:40,250 --> 00:35:41,250 string. 598 00:35:41,410 --> 00:35:45,430 Now there's one stupid subtlety still missing from this line of code. Does 599 00:35:45,430 --> 00:35:47,870 anyone know, especially if you've programmed before? OK, all of you have 600 00:35:47,870 --> 00:35:48,870 programmed before. Yes? 601 00:35:49,870 --> 00:35:53,610 semicolon. So one of the headaches of C in a lot of languages is you actually 602 00:35:53,610 --> 00:35:58,410 have to finish your thought explicitly so the computer knows that that line of 603 00:35:58,410 --> 00:36:02,270 code is done. And it's not a period like in English. It's, in fact, a semicolon. 604 00:36:02,410 --> 00:36:03,410 Now, you don't use these everywhere. 605 00:36:03,610 --> 00:36:06,650 We'll see where you use them. But that, too, is a very common mistake to 606 00:36:06,650 --> 00:36:07,750 overlook something simple. 607 00:36:08,190 --> 00:36:11,750 But again, in the coming weeks, even though this might look very cryptic with 608 00:36:11,750 --> 00:36:15,410 muscle memory and practice, you'll start to see these things instantly, even if 609 00:36:15,410 --> 00:36:19,210 for a few days you sort of bang your head against the screen, so to speak. 610 00:36:19,210 --> 00:36:23,530 seeing what the TFs and I much more readily see. 611 00:36:23,790 --> 00:36:27,390 So let's go ahead and do this. Let me go back over to VS Code here. 612 00:36:27,590 --> 00:36:29,090 Let me zoom in just a little bit. 613 00:36:29,530 --> 00:36:31,350 And let me go ahead and do this. 614 00:36:31,610 --> 00:36:35,470 I'm going to get rid of my single use of printf. And I'm going to say the exact 615 00:36:35,470 --> 00:36:42,330 same thing. String answer equals get string quote unquote what's 616 00:36:42,330 --> 00:36:46,370 your name question mark space close quote. 617 00:36:47,669 --> 00:36:51,070 semicolon, and now I want to print out that answer. Well, let me do this 618 00:36:51,070 --> 00:36:54,590 incorrectly deliberately for the moment. Let me just say printf quote unquote 619 00:36:54,590 --> 00:37:00,030 hello answer if I want to plug in answer and I want to add a new line at the end 620 00:37:00,030 --> 00:37:01,970 semicolon. So let me try this. 621 00:37:02,410 --> 00:37:05,870 But there's multiple mistakes now in my code. Let's trip over them deliberately. 622 00:37:06,230 --> 00:37:09,030 Let me go down to my terminal window by clicking at the bottom of the screen. 623 00:37:09,190 --> 00:37:11,470 Let me run make hello again, Enter. 624 00:37:12,120 --> 00:37:15,380 And oh my god, there's even more errors now than there were before. But not a 625 00:37:15,380 --> 00:37:18,620 problem. Let me click on this little triangle here, which is just going to 626 00:37:18,620 --> 00:37:20,800 in on the terminal window so it takes up my full screen. 627 00:37:21,080 --> 00:37:24,880 And just generally, all you have to do is find a few keywords visually that 628 00:37:24,880 --> 00:37:28,900 you a clue as to what's going on. Or as before, you can always ask the CS50 629 00:37:28,900 --> 00:37:31,280 duck. So here's the command I ran, make hello. 630 00:37:31,700 --> 00:37:35,320 Somehow that induced all of these errors. Always read them top to bottom, 631 00:37:35,320 --> 00:37:40,170 bottom up. So from top to bottom, there's a problem on line 5, character 632 00:37:40,170 --> 00:37:42,190 of undeclared identifier string. 633 00:37:42,550 --> 00:37:45,570 Did I mean standard in? No, no, no. I didn't there. 634 00:37:46,010 --> 00:37:50,170 And then also, two errors generated, too many errors remitted. 635 00:37:50,390 --> 00:37:51,390 What did I do wrong? 636 00:37:51,810 --> 00:37:56,110 Well, it turns out what I do need to do at the top of this file, let me click 637 00:37:56,110 --> 00:37:57,770 the triangle to zoom back out. 638 00:37:58,130 --> 00:38:02,480 If I want to use the get string function to get a string, I actually need to 639 00:38:02,480 --> 00:38:09,360 include another header file, which is probably called include CS50 .h. 640 00:38:09,460 --> 00:38:12,220 Technically, any order is fine. I tend to alphabetize because I just know, 641 00:38:12,300 --> 00:38:14,860 therefore, where to look alphabetically for a certain header file. 642 00:38:15,080 --> 00:38:19,460 Now that that's in place, let me again run make hello, enter. 643 00:38:20,190 --> 00:38:21,850 And now we're back in business. 644 00:38:22,050 --> 00:38:23,009 No error message. 645 00:38:23,010 --> 00:38:26,870 So even though you might have more errors than you have code, odds are it's 646 00:38:26,870 --> 00:38:30,670 the computer is confused, and it could be something simple and an easy fix like 647 00:38:30,670 --> 00:38:36,330 that. So just to be clear, standardio .h, because I'm including it, I can use 648 00:38:36,330 --> 00:38:43,010 printf. CS50 .h, I can use get string, because the people who invented C and 649 00:38:43,010 --> 00:38:45,850 people who invented CS50 wrote those two files, so to speak. 650 00:38:46,950 --> 00:38:50,930 respectively. All right, unfortunately, even though the program compiles, that 651 00:38:50,930 --> 00:38:52,010 doesn't mean it's correct. 652 00:38:52,270 --> 00:38:56,850 It just means it's syntactically valid. It's valid C code. If I go ahead and run 653 00:38:56,850 --> 00:39:01,150 dot slash hello and hit Enter now, I'm going to be prompted for my name. So 654 00:39:01,150 --> 00:39:04,470 type it, D -A -V -I -D. And notice there's a space to the right of the 655 00:39:04,470 --> 00:39:05,470 mark, as promised. 656 00:39:05,630 --> 00:39:09,670 Enter. But it just says hello answer, which of course is not the intent. I 657 00:39:09,670 --> 00:39:10,670 wanted to say hello. 658 00:39:10,830 --> 00:39:15,570 David. So how can we do this? Well, in Scratch, it took a couple of puzzle 659 00:39:15,570 --> 00:39:17,210 pieces, but it was pretty straightforward. 660 00:39:17,510 --> 00:39:22,010 If I wanted to say the combination of two phrases, hello and something else, I 661 00:39:22,010 --> 00:39:25,250 joined those two and then passed that output to the input of say. 662 00:39:25,550 --> 00:39:27,430 In C, it's going to be a little different here. 663 00:39:27,850 --> 00:39:30,190 Just because it's an old language and this is how it's done. 664 00:39:30,680 --> 00:39:32,740 Still use printf, because that's the same thing as say. 665 00:39:32,980 --> 00:39:35,440 I got my parentheses. I got my semicolon. Good to go. 666 00:39:35,720 --> 00:39:38,240 But inside of that, this is where printf is different. 667 00:39:39,080 --> 00:39:44,120 If you want to say something followed by something else, in the world of C, you 668 00:39:44,120 --> 00:39:45,380 tend to use placeholders. 669 00:39:45,940 --> 00:39:49,900 So you don't just join things together, as we will do in Python and other 670 00:39:49,900 --> 00:39:51,960 languages. You say to the compiler, 671 00:39:53,300 --> 00:39:54,940 give me the word hello, comma. 672 00:39:55,480 --> 00:39:59,700 and then something else. And the %s means put another string here. 673 00:40:00,060 --> 00:40:03,860 It's sort of like leaving a placeholder in your code or a template where you'll 674 00:40:03,860 --> 00:40:05,220 actually plug in some values. 675 00:40:05,560 --> 00:40:09,060 Now, if this is what I want to display, I still use my quotes as before. 676 00:40:09,540 --> 00:40:12,520 And I might, in fact, have a backslash n if I want to move the cursor to the 677 00:40:12,520 --> 00:40:13,238 next line. 678 00:40:13,240 --> 00:40:15,140 But this is where printf is a little different. 679 00:40:15,580 --> 00:40:21,990 Unlike say, which took one input, Printf is kind of like join. It can take two 680 00:40:21,990 --> 00:40:24,250 or more input if you so choose. 681 00:40:24,530 --> 00:40:27,650 You just have to separate them with a comma. 682 00:40:28,410 --> 00:40:33,250 So much like the join block has two ovals here that are initially white, 683 00:40:33,250 --> 00:40:37,230 and banana, until we dragged and dropped answer on top of it, printf and really 684 00:40:37,230 --> 00:40:41,030 any function in C, if you want to pass in multiple inputs, that's fine. If 685 00:40:41,030 --> 00:40:44,310 they're supported, just separate them with commas. There's no multiple 686 00:40:44,310 --> 00:40:48,010 parentheses. There's no multiple ovals. Just separate them with commas. 687 00:40:48,640 --> 00:40:50,580 And now notice a potential point of confusion. 688 00:40:51,020 --> 00:40:55,520 What's different about this comma and this one, just instinctively? 689 00:40:57,340 --> 00:40:59,380 Sort of minor detail, but important. Yeah? 690 00:40:59,840 --> 00:41:00,880 Inside. DAVID J. 691 00:41:01,720 --> 00:41:05,140 So one is inside, one is outside. So the one that's inside the quotes is 692 00:41:05,140 --> 00:41:09,140 literally the English grammatical comma that you want the human to see. The one 693 00:41:09,140 --> 00:41:13,760 out here is a C thing that's separating the first input to this function printf. 694 00:41:14,120 --> 00:41:15,120 from the second. 695 00:41:15,180 --> 00:41:18,140 Strictly speaking, you don't need a space there. But it's good practice, 696 00:41:18,240 --> 00:41:22,720 stylistically, to separate your arguments with single spaces, just as 697 00:41:22,720 --> 00:41:27,920 there. So let me go ahead and now do something with this. Let me go back to 698 00:41:27,920 --> 00:41:28,718 code here. 699 00:41:28,720 --> 00:41:31,580 I'm going to clear my terminal window, just to get rid of that distraction. 700 00:41:31,920 --> 00:41:35,060 And now I'm going to change answer to %s. 701 00:41:35,500 --> 00:41:40,120 And then outside of the double quotes on line 7, I'm going to do comma, answer. 702 00:41:40,860 --> 00:41:44,120 And then after it autosaves, I'm going to go back to my terminal window. 703 00:41:44,400 --> 00:41:47,780 And just to make another deliberate mistake, dot slash hello, enter. 704 00:41:48,160 --> 00:41:50,480 What's your name? David, enter. It's still broken. 705 00:41:51,100 --> 00:41:52,100 But why? 706 00:41:53,500 --> 00:41:56,400 I still have to recompile it. So again, you just get into the habit. When you 707 00:41:56,400 --> 00:41:59,940 change your code, you have to recompile it so you get new machine code in the 708 00:41:59,940 --> 00:42:01,200 file hello. So let's do it again. 709 00:42:01,640 --> 00:42:02,640 Make hello. 710 00:42:02,880 --> 00:42:04,080 No errors is good. 711 00:42:04,280 --> 00:42:06,720 Dot slash hello, enter. What's your name again? 712 00:42:06,940 --> 00:42:10,020 D -A -V -I -D. And now, hello, comma. 713 00:42:10,380 --> 00:42:14,500 David. So again, a lot of this is still cryptic, but it's going to start to 714 00:42:14,500 --> 00:42:18,240 follow patterns like this. Functions like in math class f of x are written 715 00:42:18,240 --> 00:42:22,680 function name, parentheses, input, comma, input, comma, input, however many 716 00:42:22,680 --> 00:42:26,480 have. They're going to follow these patterns. But notice too, on line six 717 00:42:26,480 --> 00:42:31,200 seven, I have finished each of my thoughts with a semicolon. 718 00:42:31,480 --> 00:42:34,440 So what are the other commands that you can run in your terminal window besides 719 00:42:34,440 --> 00:42:38,200 something like ls? Well, it turns out there's a whole bunch of them. LS, of 720 00:42:38,200 --> 00:42:41,320 course, was simply short for list, which shows you the files in your current 721 00:42:41,320 --> 00:42:45,540 folder. But there's also CD for change directory, which is the command 722 00:42:45,540 --> 00:42:48,860 equivalent of double clicking on a folder to open it up in a graphical 723 00:42:48,860 --> 00:42:52,500 environment. There's CP, which is short for copy, which allows you to make a 724 00:42:52,500 --> 00:42:54,300 copy of a file or folder. 725 00:42:54,640 --> 00:42:59,200 There's Mkdir, M -K -D -I -R, which is short for make directory, which is how 726 00:42:59,200 --> 00:43:00,440 you could make a new folder. 727 00:43:00,700 --> 00:43:04,940 There's MV, which is short for move, which would allow you to move one file 728 00:43:04,940 --> 00:43:08,640 folder. folder from one place to another or simply rename one of those to a 729 00:43:08,640 --> 00:43:12,540 different name. There's rm, which is short for remove, and there's rmdir, 730 00:43:12,540 --> 00:43:14,120 is short for remove directory. 731 00:43:14,320 --> 00:43:16,040 So in fact, let's play around with a couple of these. 732 00:43:16,260 --> 00:43:17,720 Let me go back to VS Code here. 733 00:43:17,920 --> 00:43:21,400 Let me go ahead and open up my file explorer and recall that at this point, 734 00:43:21,400 --> 00:43:25,740 got two files, hello .c, which contains my source code, and then hello, which 735 00:43:25,740 --> 00:43:30,500 contains my machine code, the executable program that I previously generated by 736 00:43:30,500 --> 00:43:31,259 running make. 737 00:43:31,260 --> 00:43:33,660 Well, let me go ahead and propose that I'd like to 738 00:43:34,390 --> 00:43:39,450 prepare to keep all of my files and folders very orderly. So for every 739 00:43:39,450 --> 00:43:43,050 write or for every problem on a problem set I write, maybe I want to store my 740 00:43:43,050 --> 00:43:45,950 relevant files in a specific folder for that problem. 741 00:43:46,210 --> 00:43:50,530 So suppose, then, that I want to put hello .c in a folder, otherwise known as 742 00:43:50,530 --> 00:43:51,910 directory, called hello. 743 00:43:52,270 --> 00:43:56,110 Well, I can't do that quite yet because I already have a program called hello. 744 00:43:56,270 --> 00:43:58,950 So let me use one of those new commands, rm. 745 00:43:59,210 --> 00:44:04,130 space hello will delete or remove hello from my current directory. So I'm going 746 00:44:04,130 --> 00:44:08,030 to hit Enter. I'm going to be prompted to confirm with y for yes or n for no, 747 00:44:08,130 --> 00:44:12,450 remove regular file hello. I'm going to hit y and Enter. And as I hit Enter, 748 00:44:12,530 --> 00:44:16,750 watch the top left of my screen as the hello file would seem to disappear. 749 00:44:17,950 --> 00:44:19,350 Voila, it's now gone. 750 00:44:19,590 --> 00:44:22,170 So now I'm going to go ahead and use a different command. Let me go ahead and 751 00:44:22,170 --> 00:44:23,810 mkdir for make directory. 752 00:44:24,050 --> 00:44:27,450 I'm going to call the directory itself hello. And watch again at top left what 753 00:44:27,450 --> 00:44:28,670 happens. Enter. 754 00:44:29,210 --> 00:44:34,230 Now I have not a file, but a folder called hello. And in this GUI, the fact 755 00:44:34,230 --> 00:44:38,130 it's a folder is indicated, one, by its icon, and two, by that little right 756 00:44:38,130 --> 00:44:41,590 -facing triangle, which means I can expand it to see what's inside. 757 00:44:41,910 --> 00:44:45,270 And in fact, if I do that, I'll see, of course, that nothing's in it, because we 758 00:44:45,270 --> 00:44:46,710 literally just created it. 759 00:44:46,930 --> 00:44:48,610 All right, well, what if I want to move? 760 00:44:49,020 --> 00:44:53,360 Hello .c into the new Hello folder. Well, I could, just like on Mac OS or 761 00:44:53,360 --> 00:44:57,960 Windows. I could actually, in my file explorer, click and drag one into the 762 00:44:57,960 --> 00:45:00,560 other. But let's do this entirely within the terminal window. 763 00:45:00,780 --> 00:45:07,120 So let me do this. Let me move, or MV for short, my file called Hello .c into 764 00:45:07,120 --> 00:45:08,300 new destination folder. 765 00:45:09,150 --> 00:45:12,970 And I can optionally put a slash at the end of hello just to make super clear 766 00:45:12,970 --> 00:45:14,790 that it's a directory, but that's not strictly necessary. 767 00:45:15,170 --> 00:45:21,890 But if I say mv hello .c hello with spaces in between, assuming hello exists 768 00:45:21,890 --> 00:45:25,490 a folder, watch what happens at top left now. It's a little more subtle, but 769 00:45:25,490 --> 00:45:29,710 hello .c is going to move inside of the hello folder right now. 770 00:45:30,440 --> 00:45:34,380 And indeed, it's only slightly more indented. But notice if I collapse the 771 00:45:34,380 --> 00:45:38,640 folder, notice that it seems to be gone because hello .c is now inside of that 772 00:45:38,640 --> 00:45:42,360 folder. Of course, if I expand that, I'll see it again. If I go back to my 773 00:45:42,360 --> 00:45:47,670 terminal window and type ls for list, now I don't see Hello .c. And I don't 774 00:45:47,670 --> 00:45:51,470 an executable program anymore, but I do see hello. And the slash there just 775 00:45:51,470 --> 00:45:54,350 makes super clear to me, the user, that it's indeed a folder. 776 00:45:54,570 --> 00:45:56,290 So how do I change into that folder? 777 00:45:56,630 --> 00:45:59,970 Well, I can obviously use the graphical interface at left and click and expand 778 00:45:59,970 --> 00:46:03,990 and sort of see what's going on. But there's no direct connection between the 779 00:46:03,990 --> 00:46:08,510 file explorer at top left and my terminal window at bottom right. Rather, 780 00:46:08,510 --> 00:46:11,930 are just two different ways to explore the underlying system. 781 00:46:12,290 --> 00:46:16,750 So if I want to change my terminal window into this new directory, I can do 782 00:46:16,750 --> 00:46:22,430 for change directory, hello, and then enter. And now notice my terminal 783 00:46:22,430 --> 00:46:24,250 prompt changes slightly. 784 00:46:24,490 --> 00:46:27,330 There's still a dollar sign, which indicates type my commands here. 785 00:46:27,530 --> 00:46:31,930 But before that dollar sign, just so that I have a reminder, sort of 786 00:46:31,930 --> 00:46:36,970 that visually remind me what folder I am now in, I see that I'm inside of hello. 787 00:46:37,250 --> 00:46:42,170 If I now type ls, I should see the file I expect to be in there, which is indeed 788 00:46:42,170 --> 00:46:43,350 hello .c. 789 00:46:43,950 --> 00:46:47,330 Now, suppose I want to try out some of those other commands. And suppose I want 790 00:46:47,330 --> 00:46:51,510 to maybe rename this file. I really want this file to be called something else. 791 00:46:51,630 --> 00:46:57,450 So maybe I might do something like this, mv hello .c space, and now a new name 792 00:46:57,450 --> 00:46:58,368 for the file. 793 00:46:58,370 --> 00:47:02,470 Well, maybe I want to save this as an old version of my code, because I wanted 794 00:47:02,470 --> 00:47:05,950 to start fresh with something new. So I could do something like this, mv hello 795 00:47:05,950 --> 00:47:07,490 .c old .c. 796 00:47:07,770 --> 00:47:09,490 And watch what happens at top left. 797 00:47:09,920 --> 00:47:12,920 Hello .c, of course, gets renamed via the move command. 798 00:47:13,180 --> 00:47:18,020 So I can use move to move a file into a folder, or I can use it to rename a file 799 00:47:18,020 --> 00:47:19,620 or folder, as I've just done here. 800 00:47:19,980 --> 00:47:23,520 Now, suppose I want to undo that. Well, I can't just type undo. I can't just hit 801 00:47:23,520 --> 00:47:25,740 Control -C, but I can do the opposite, in effect. 802 00:47:26,100 --> 00:47:32,350 mv old .c hello .c will now, per top left, Change it back into that file. 803 00:47:32,550 --> 00:47:36,090 If I want to make a copy of this file, maybe as an actual backup, because I'm 804 00:47:36,090 --> 00:47:39,070 really happy with this version and I'm worried about breaking it, well, I could 805 00:47:39,070 --> 00:47:44,250 do cp for short. I can then do hello .c. And then I can do something like backup 806 00:47:44,250 --> 00:47:48,370 .c or any other file name. I'm taking care to use the same file extension so 807 00:47:48,370 --> 00:47:52,210 that if I do open this file later, it still opens and gets highlighted and 808 00:47:52,210 --> 00:47:56,170 colorized in the same way. But watch what happens now at top left when I type 809 00:47:56,170 --> 00:48:01,240 Enter. I now have two files in this hello folder. And indeed, if I type ls 810 00:48:01,710 --> 00:48:03,010 I can see exactly the same. 811 00:48:03,230 --> 00:48:06,790 So long story short, there's this whole list of commands, and even more than 812 00:48:06,790 --> 00:48:10,550 these, that allow you to manipulate the underlying system in exactly the same 813 00:48:10,550 --> 00:48:13,710 way that you and I have probably done for years by using a mouse and pointing 814 00:48:13,710 --> 00:48:15,270 and clicking and double clicking. 815 00:48:15,510 --> 00:48:18,570 But for now, let's undo all of this, because I haven't really written that 816 00:48:18,570 --> 00:48:21,890 programs today. And I'm going to keep things simple today and keep everything 817 00:48:21,890 --> 00:48:23,930 my same folder. So let's undo all of this. 818 00:48:24,170 --> 00:48:28,550 Let me go ahead and now remove backup .c, because I don't particularly care 819 00:48:28,550 --> 00:48:32,530 about that. I'm going to be prompted to confirm as much. Then let me go ahead 820 00:48:32,530 --> 00:48:38,570 and move hello .c out of this folder and into the original folder. And 821 00:48:38,570 --> 00:48:42,530 conceptually, the original folder is what we would call the parent folder, 822 00:48:42,530 --> 00:48:44,590 folder that contains this hello folder. 823 00:48:44,850 --> 00:48:49,110 And the way you can specify the parent folder, like back up from once you came, 824 00:48:49,350 --> 00:48:55,330 is with .dot. So a single dot, as we've actually seen, .slash hello, .slash a 825 00:48:55,330 --> 00:49:00,380 .out means execute a program in this directory, dot. But .dot refers to to 826 00:49:00,380 --> 00:49:01,380 parent directory. 827 00:49:01,700 --> 00:49:05,140 So watch what happens at top left when I move this hello .c file out of this 828 00:49:05,140 --> 00:49:06,140 folder. 829 00:49:06,520 --> 00:49:09,600 shifts a little bit to the left to indicate that it's no longer in that 830 00:49:09,800 --> 00:49:14,520 I'm going to go ahead and type cd dot dot, which will bring me back to my 831 00:49:14,520 --> 00:49:18,820 folder. Or even more useful, especially if you get confused or lost somewhere 832 00:49:18,820 --> 00:49:22,840 within your folders, you can actually just type cd and nothing, and that will 833 00:49:22,840 --> 00:49:27,460 whisk you back to that original folder no matter where you are. So it's a nice 834 00:49:27,460 --> 00:49:30,880 shortcut, and it's a nice way of undoing any confusion you might have caused for 835 00:49:30,880 --> 00:49:33,740 yourself. Lastly, let's go ahead and get rid of the hello. 836 00:49:34,340 --> 00:49:37,260 directory with rm dir hello enter. 837 00:49:37,620 --> 00:49:42,260 And that now disappears at top left as well. Now, what I was hinting at here, 838 00:49:42,360 --> 00:49:48,190 whereby I had my hello .c file in a folder and I was moving things around 839 00:49:48,190 --> 00:49:51,810 renaming things and backing things up isn't strictly necessary because there's 840 00:49:51,810 --> 00:49:54,850 actually other features still inside of VS Code that you're welcome and 841 00:49:54,850 --> 00:49:58,670 encouraged to play around with. In fact, if I go to my so -called timeline at 842 00:49:58,670 --> 00:50:02,690 the bottom of my file explorer here, you can actually see that there's been 843 00:50:02,690 --> 00:50:06,530 automatic backups made over time of this file. So if you click, click, click 844 00:50:06,530 --> 00:50:10,010 through those backups, you can actually see different versions of the same file 845 00:50:10,010 --> 00:50:13,670 slightly in the past, which might save you the trouble. of having to manually 846 00:50:13,670 --> 00:50:14,509 create files. 847 00:50:14,510 --> 00:50:18,330 And in fact, in the world of software development in industry, there's 848 00:50:18,330 --> 00:50:23,430 standard tools very similar in spirit to what we've been using GitHub for that 849 00:50:23,430 --> 00:50:27,410 allow you manually to make different versions of your code so that you can 850 00:50:27,410 --> 00:50:31,750 proactively keep track of all the changes you've made without manually 851 00:50:31,750 --> 00:50:35,110 things as you might typically on your own Mac or PC. 852 00:50:35,850 --> 00:50:39,310 All right, let me clear my terminal window and ask if there are any 853 00:50:41,170 --> 00:50:42,170 Yes, over here. 854 00:50:52,360 --> 00:50:55,600 DAVID J. Yeah, a really good question. If we had something other than a string 855 00:50:55,600 --> 00:50:59,120 of text, and we had an integer, would you still use %s? No, you would use 856 00:50:59,120 --> 00:51:01,980 something else. And indeed, %i is what we're going to use, and we're going to 857 00:51:01,980 --> 00:51:02,718 actually do that. 858 00:51:02,720 --> 00:51:05,700 Perfect segue to other types that C actually has. 859 00:51:05,940 --> 00:51:10,420 So up until now, we've been calling a string of text literally a string. And 860 00:51:10,420 --> 00:51:13,660 this is common in many programming languages, including Python and 861 00:51:14,300 --> 00:51:16,380 Strings in the programming world just mean text. 862 00:51:16,720 --> 00:51:20,960 whether it's zero or more characters thereof. But C does have other data 863 00:51:21,060 --> 00:51:24,480 just a few of which we'll dabble with today, but you'll use more over time. 864 00:51:24,700 --> 00:51:28,220 We've already seen string, for instance, which is indeed a string of text. But 865 00:51:28,220 --> 00:51:30,520 let's focus as well on an integer. 866 00:51:30,820 --> 00:51:34,840 As an aside, there's other types, too. There's Boolean values, like true or 867 00:51:34,840 --> 00:51:39,580 false. There's chars, which are single characters instead of full phrases or 868 00:51:39,580 --> 00:51:42,960 sentences. There's doubles and floats, which are real numbers, something with a 869 00:51:42,960 --> 00:51:44,680 decimal point, the equivalent of fractions. 870 00:51:45,040 --> 00:51:49,620 And there's longs. which are integers, but longer integers, even bigger 871 00:51:49,620 --> 00:51:53,440 than you might type by default. So let's focus on ints, because so many computer 872 00:51:53,440 --> 00:51:58,140 programs, of course, manipulate numbers in some way. So what can we do with 873 00:51:58,140 --> 00:52:02,740 this? Well, if we want to be able to get an integer, lucky enough, CS50's 874 00:52:02,740 --> 00:52:06,440 library comes not just with get string, but also get int. So that's going to be 875 00:52:06,440 --> 00:52:08,220 a third function we now use in C. 876 00:52:08,580 --> 00:52:12,600 And we need to know what are generally called format codes. So that placeholder 877 00:52:12,600 --> 00:52:18,840 I called before %s is indeed for a string. If we want to place an integer 878 00:52:18,840 --> 00:52:22,850 of something we're printing to the screen, We are, in fact, going to use %i 879 00:52:22,850 --> 00:52:28,610 instead. So let's now actually use these building blocks, get int and %i, to 880 00:52:28,610 --> 00:52:31,430 actually get numbers in some way to sort of solve a problem. 881 00:52:31,630 --> 00:52:34,670 Well, what problem could we solve? Let's introduce another concept from scratch 882 00:52:34,670 --> 00:52:37,870 and programming more generally known as conditionals, like those proverbial 883 00:52:37,870 --> 00:52:40,410 forks in the road. If something is true, do this. 884 00:52:40,750 --> 00:52:44,710 Else, maybe do this other thing. So in Scratch, we might have had a set of 885 00:52:44,710 --> 00:52:49,890 puzzle pieces that looked like this. If x is less than y, then say, or have the 886 00:52:49,890 --> 00:52:51,690 cat say, x is less than y. 887 00:52:51,930 --> 00:52:55,130 So it's sort of a stupid program, but it just demonstrates how we have two 888 00:52:55,130 --> 00:52:59,090 variables, x and y, in the context of Scratch. We're comparing them with a 889 00:52:59,090 --> 00:53:00,009 Boolean expression. 890 00:53:00,010 --> 00:53:05,810 We're using a conditional to then conditionally say or not say this phrase 891 00:53:05,990 --> 00:53:10,810 depending on whether this question has the answer of true or false, yes or no. 892 00:53:11,050 --> 00:53:15,530 In C, it doesn't look all that different. It's a little more cryptic, 893 00:53:15,530 --> 00:53:16,530 say literally if. 894 00:53:16,810 --> 00:53:21,590 You use parentheses, similar to functions, but confusingly, by 895 00:53:21,590 --> 00:53:25,350 put a space after the word if. So you don't put spaces after function names. 896 00:53:25,350 --> 00:53:29,670 do put spaces after words like if. And you use the parentheses to conjure up 897 00:53:29,670 --> 00:53:33,930 this weird trapezoidal -like shape. So there's no real keys that kind of 898 00:53:33,930 --> 00:53:36,190 that. So C uses parentheses, like most languages. 899 00:53:36,550 --> 00:53:39,890 And then there's these weird curly braces, which, at least in English, we 900 00:53:39,890 --> 00:53:43,630 use all that often. But they're there on your keyboard, English or otherwise. 901 00:53:43,870 --> 00:53:47,380 And they essentially allow us to create this sort hugging shape to the puzzle 902 00:53:47,380 --> 00:53:51,920 piece. Anything inside of those curly braces is going to be equivalent to 903 00:53:51,920 --> 00:53:56,540 anything inside of this yellow hug that's sort of grabbing one or more 904 00:53:56,540 --> 00:53:58,220 inside. So what do we put inside? 905 00:53:58,540 --> 00:53:59,540 Well, this part is straightforward. 906 00:53:59,620 --> 00:54:05,040 Printf, quote unquote, x is less than y, backslash n, semicolon. So nothing new 907 00:54:05,040 --> 00:54:09,100 here. The only bit of new code is this if construct instead. 908 00:54:09,440 --> 00:54:12,900 What if you have an if else, so a two -way fork in the road? This is what that 909 00:54:12,900 --> 00:54:13,900 looked like in Scratch. 910 00:54:14,220 --> 00:54:18,500 Same question. If x is less than y, then say x is less than y. Else, say x is 911 00:54:18,500 --> 00:54:19,439 not less than y. 912 00:54:19,440 --> 00:54:24,220 In C, the code is going to be set up initially like this. So two sets of 913 00:54:24,220 --> 00:54:28,480 braces to represent this pair of yellow bars and this pair of yellow bars. 914 00:54:28,700 --> 00:54:32,620 And what's inside of them, indented no less, just like our pseudocode last 915 00:54:32,740 --> 00:54:34,880 is two printfs. x is less than y. 916 00:54:35,240 --> 00:54:36,500 x is not less than y. 917 00:54:37,060 --> 00:54:40,060 So that's it. So the only new stuff here, really, is now the else. 918 00:54:40,430 --> 00:54:43,850 keyword, which does not need parentheses, because you're just saying, 919 00:54:43,850 --> 00:54:44,749 this other thing. 920 00:54:44,750 --> 00:54:47,570 But what if it's a three -way fork in the road? And we'll stop after that. 921 00:54:48,150 --> 00:54:52,710 Here's a three -way fork in the road in Scratch. If x is less than y, then say 922 00:54:52,710 --> 00:54:56,630 this. Else if x is greater than y, say this. 923 00:54:57,130 --> 00:55:00,190 Else if x equals y, then say this. 924 00:55:00,600 --> 00:55:04,020 So this is a little more precise, because now we're handling equality, not 925 00:55:04,020 --> 00:55:05,840 greater than or the opposite. 926 00:55:06,100 --> 00:55:10,060 In C, it's going to look similar to before, but we're adding this element 927 00:55:10,280 --> 00:55:13,120 And at first glance, especially if you've never programmed before, it looks 928 00:55:13,120 --> 00:55:14,560 I'm an idiot and I made a typo. 929 00:55:14,880 --> 00:55:15,880 What looks wrong? 930 00:55:17,420 --> 00:55:21,750 There's like two equal signs, like not a typo. So it turns out Recall from 931 00:55:21,750 --> 00:55:26,150 earlier, when we used the equal sign the first time around, we used it in the 932 00:55:26,150 --> 00:55:29,470 context of getting a return value back from a function, like the get string 933 00:55:29,470 --> 00:55:32,350 function handed me back the user's answer. 934 00:55:32,730 --> 00:55:36,750 So unfortunately, because humans decades ago decided, hey, let's use the equal 935 00:55:36,750 --> 00:55:42,050 sign to assign a return value from the right -hand side of a line of code to 936 00:55:42,050 --> 00:55:45,630 left -hand side, we sort of painted ourselves into a corner and were like, 937 00:55:45,630 --> 00:55:50,250 shoot. What do we do when we actually want to test for equality of two values 938 00:55:50,250 --> 00:55:54,540 the left? left and right. So what most languages, including C, do is use double 939 00:55:54,540 --> 00:55:58,080 equal signs. So you can say double equals or equals equals or whatever, but 940 00:55:58,080 --> 00:55:59,660 is, in fact, syntactically correct. 941 00:56:00,060 --> 00:56:02,700 What's inside of these three sets of curly braces? 942 00:56:02,940 --> 00:56:07,660 Same idea, printf, printf, printf, based on what English phrase you want to 943 00:56:07,660 --> 00:56:08,660 print out. 944 00:56:09,140 --> 00:56:12,000 So this code, both in Scratch and C, I'll claim is correct. 945 00:56:12,320 --> 00:56:16,100 It won't run because we still need the other stuff, the equivalent of the when 946 00:56:16,100 --> 00:56:19,080 green flag clicked. But out of context, this code is correct. 947 00:56:19,740 --> 00:56:22,440 But there's a subtle weakness in design. 948 00:56:22,840 --> 00:56:25,460 And we'll talk a lot about this this week and beyond. Correctness just means 949 00:56:25,460 --> 00:56:27,000 code does what it's supposed to do. 950 00:56:27,340 --> 00:56:32,100 Design is more subjective, like how well have you written your arguments in an 951 00:56:32,100 --> 00:56:34,780 English paper? How well have you written your code is design. 952 00:56:35,980 --> 00:56:40,900 This code is not designed as well as it could be, because I'm doing more work 953 00:56:40,900 --> 00:56:41,900 than I need to. 954 00:56:42,300 --> 00:56:43,300 Yeah, and back. 955 00:56:45,400 --> 00:56:48,080 Yeah, I don't need the x equals equals y, but why, logically? 956 00:56:54,020 --> 00:56:56,560 Exactly. That's just a math thing. Like either x is less than y. 957 00:56:57,020 --> 00:57:01,660 Or it's greater than y. Or the third and final option is they must be equal. 958 00:57:01,860 --> 00:57:02,860 So it's subtle. 959 00:57:03,000 --> 00:57:07,800 But why would you bother wasting time writing a line of code and expecting the 960 00:57:07,800 --> 00:57:10,960 computer to run a line of code that is just going to answer a question that 961 00:57:10,960 --> 00:57:12,880 logically you could have concluded already? 962 00:57:13,240 --> 00:57:18,940 Because if x is not less than y and x is not greater than y, then my god, just 963 00:57:18,940 --> 00:57:23,040 print out x is equal to y because you know at that point logically it's true. 964 00:57:23,180 --> 00:57:26,940 You don't need to waste your time or the computer's asking a third question 965 00:57:26,940 --> 00:57:31,480 unnecessarily. In reality, it's not a huge deal. No one's going to notice in 966 00:57:31,480 --> 00:57:34,880 real world on a Mac or PC that there's this extra line of code. But it's a bad 967 00:57:34,880 --> 00:57:38,740 habit. Keep it simple. Don't write code that doesn't need to be there if 968 00:57:38,740 --> 00:57:41,900 logically you can conclude otherwise. So in fact, let's clean this up both in 969 00:57:41,900 --> 00:57:46,660 Scratch and in C. I can tighten this up, so to speak, use less code here, less 970 00:57:46,660 --> 00:57:47,558 code here. 971 00:57:47,560 --> 00:57:51,480 And honestly, if only statistically, the less code I write, the less likely I am 972 00:57:51,480 --> 00:57:52,520 going to make mistakes. 973 00:57:52,840 --> 00:57:54,680 So that too is probably a net positive. 974 00:57:55,080 --> 00:57:59,960 overall. Writing less code is generally better than writing more code, not 975 00:57:59,960 --> 00:58:01,700 unlike English essays, too, perhaps. 976 00:58:02,300 --> 00:58:06,920 All right, questions about this feature of C, conditionals, and this syntax? 977 00:58:08,380 --> 00:58:09,380 Yeah. 978 00:58:13,049 --> 00:58:16,530 Oh, a really good question. And yes, jumping the gun, there are alternative 979 00:58:16,530 --> 00:58:21,150 to solve problems like these. And the question was to summarize when to use 980 00:58:21,270 --> 00:58:24,030 else, if, else versus what's called a switch statement. More on those another 981 00:58:24,030 --> 00:58:27,610 time. But this is going to be true in general in programming, not just C, not 982 00:58:27,610 --> 00:58:28,910 just in Scratch, but every language. 983 00:58:29,110 --> 00:58:31,010 There are going to be several. 984 00:58:31,720 --> 00:58:35,360 dozens, hundreds, an infinite number of ways to solve problems. Among the things 985 00:58:35,360 --> 00:58:39,040 we're going to teach you, though, is indeed how to do things well or better 986 00:58:39,040 --> 00:58:39,879 you might otherwise. 987 00:58:39,880 --> 00:58:42,480 And we're going to introduce you eventually to another feature of the 988 00:58:42,480 --> 00:58:45,380 that can even simplify this code too. 989 00:58:46,780 --> 00:58:51,100 So for now, let's actually use this then. So let me go over to VS Code 990 00:58:51,340 --> 00:58:53,660 I'm going to go ahead now and clear my terminal window. 991 00:58:54,580 --> 00:58:59,160 Down here, I'm going to go ahead and close the hello .c tab, just so that 992 00:58:59,160 --> 00:59:02,300 going to create a new program. And let's just do something a little simple using 993 00:59:02,300 --> 00:59:05,800 some operator, so to speak. And I haven't used this word by name, but it 994 00:59:05,800 --> 00:59:09,620 out that there's lots of operators that come with C, just like a lot of 995 00:59:09,620 --> 00:59:14,580 operators that came with Scratch for doing assignments or less than or less 996 00:59:14,580 --> 00:59:18,880 or equal to, greater than, greater than or equal to, actually equal to, not 997 00:59:18,880 --> 00:59:23,330 equal to. Now, some of these are a little cryptic, but There's no easily 998 00:59:23,330 --> 00:59:26,810 key on your US English keyboard, at least, where you can do less than or 999 00:59:26,810 --> 00:59:30,970 or greater than or equals. So what most programming languages do is you don't 1000 00:59:30,970 --> 00:59:35,030 use a special symbol where there's an angle bracket and then a line below it. 1001 00:59:35,090 --> 00:59:36,550 You actually just use two characters. 1002 00:59:36,790 --> 00:59:40,930 So greater than or equal is literally this this. Less than or equal is 1003 00:59:40,930 --> 00:59:43,810 this this. We already saw that equals is this this. 1004 00:59:44,270 --> 00:59:48,150 And not equals is to use an exclamation point. So this, too, is a thing in 1005 00:59:48,150 --> 00:59:53,130 programming. Using the exclamation point, pronounced bang, is how you 1006 00:59:53,130 --> 00:59:57,870 logically certain things. So bang equals or not equals is how you would express 1007 00:59:57,870 --> 00:59:59,730 exactly that idea. 1008 00:59:59,990 --> 01:00:03,610 It's just a symbol on the keyboard that some human decided, let's use this one 1009 01:00:03,610 --> 01:00:04,730 to invert the idea. 1010 01:00:04,990 --> 01:00:08,190 But we're going to need one other thing for this program, specifically 1011 01:00:08,190 --> 01:00:12,030 variables, which we've used already sort of because in Scratch we got one for 1012 01:00:12,030 --> 01:00:17,060 free. We had that answer variable that stored the return value of the ask 1013 01:00:17,300 --> 01:00:21,120 But let's consider in general how you can, and probably did for problem set 0, 1014 01:00:21,340 --> 01:00:25,140 use a variable of your own, like keeping track of a counter or a score or the 1015 01:00:25,140 --> 01:00:28,760 like. In Scratch, if you want to create a variable called counter, you can set 1016 01:00:28,760 --> 01:00:30,640 it equal to some initial value like 0. 1017 01:00:30,960 --> 01:00:33,440 In C, that code's going to look similar. 1018 01:00:33,920 --> 01:00:37,500 You literally just write whatever name you want to give the variable, then an 1019 01:00:37,500 --> 01:00:40,680 equal sign, and then the value you want to give that variable. 1020 01:00:40,900 --> 01:00:44,880 And because the equal sign is the assignment operator, it will behave 1021 01:00:44,880 --> 01:00:48,580 essentially right to left and copy the 0 into counter. 1022 01:00:48,860 --> 01:00:50,120 But this isn't enough for C. 1023 01:00:50,680 --> 01:00:54,300 Remember that you, the programmer, have to tell the computer, is this indeed a 1024 01:00:54,300 --> 01:00:56,740 number? Is it a letter? Is it an image? Is it a sound? 1025 01:00:56,960 --> 01:00:59,360 You have to tell the computer that this is an integer. 1026 01:00:59,870 --> 01:01:02,330 otherwise written as int for short in C. 1027 01:01:02,590 --> 01:01:09,030 But there's one other stupid detail that's missing, which is now semicolon 1028 01:01:09,030 --> 01:01:10,030 finish the thought here. 1029 01:01:10,130 --> 01:01:15,370 But this, then, is equivalent to this in Scratch. Let's do another. In Scratch, 1030 01:01:15,390 --> 01:01:18,970 if you wanted to increment the counter, that is, add 1 to it, you could 1031 01:01:18,970 --> 01:01:22,330 literally use this puzzle piece here and specify you want to add 1. 1032 01:01:22,570 --> 01:01:24,070 In C, it's going to look like this. 1033 01:01:24,620 --> 01:01:28,320 Counter equals counter plus 1 semicolon. Now, at a glance, this seems like a 1034 01:01:28,320 --> 01:01:32,980 paradox of sorts. Like, how can counter equal counter plus 1. 1035 01:01:33,200 --> 01:01:37,120 I can't make that math expression true, but it's not math in this case. The 1036 01:01:37,120 --> 01:01:38,360 single equal sign is assignment. 1037 01:01:38,660 --> 01:01:42,960 So this means take the current value of counter, whatever it is, add 1 to it, 1038 01:01:43,040 --> 01:01:47,860 and then copy that value from right to left into the same variable, thereby 1039 01:01:47,860 --> 01:01:50,720 changing it from 1 to 2, 2 to 3, and so forth. 1040 01:01:50,940 --> 01:01:54,680 This, though, is so common in programming, to be able to increment or 1041 01:01:54,680 --> 01:01:58,240 decrement numbers by 1 or 2 or more, is that you can tighten it like this. 1042 01:01:58,650 --> 01:02:02,270 This is the exact same thing, a little faster to type, saves you keystrokes, 1043 01:02:02,310 --> 01:02:03,870 maybe less chance for error. 1044 01:02:04,170 --> 01:02:07,350 Counter plus equals one semicolon is the exact same idea. 1045 01:02:07,790 --> 01:02:12,750 Better still, this is so common in C and C++ and Java that there's a third way 1046 01:02:12,750 --> 01:02:16,630 to do this. To my comment earlier about solving problems in different ways, the 1047 01:02:16,630 --> 01:02:21,050 most canonical, the most popular way is probably just to say counter plus plus 1048 01:02:21,050 --> 01:02:24,870 semicolon, which literally automatically adds one semicolon. 1049 01:02:25,130 --> 01:02:28,930 to that value. Only works for one. If you want to do two or three or some 1050 01:02:28,930 --> 01:02:30,530 increment, you have to use one of the other approaches. 1051 01:02:30,830 --> 01:02:32,970 But this simply does the same thing as this. 1052 01:02:33,190 --> 01:02:37,210 And if you want to invert it to negative 1, you change the plus plus to a minus 1053 01:02:37,210 --> 01:02:38,210 minus instead. 1054 01:02:38,410 --> 01:02:41,130 So again, just little things that we'll see and pick up over time. 1055 01:02:41,410 --> 01:02:44,370 Invariably, you'll have to look them up or check the notes or look back at the 1056 01:02:44,370 --> 01:02:45,049 lecture slides. 1057 01:02:45,050 --> 01:02:49,470 But in time, this will get familiar if you are not already familiar. 1058 01:02:50,130 --> 01:02:52,270 So let's consider just logically. 1059 01:02:53,230 --> 01:02:56,910 how we might implement this in code. Let's go back to VS Code here. And let 1060 01:02:56,910 --> 01:03:00,710 propose that we create a program called compare .c, whose purpose in life is 1061 01:03:00,710 --> 01:03:02,670 just to compare a couple of values. 1062 01:03:02,970 --> 01:03:07,130 I'm going to go ahead and proactively, based on the previous chat, include 1063 01:03:07,130 --> 01:03:11,990 CS50's library from the get go. I'm going to include standardio .h from the 1064 01:03:11,990 --> 01:03:14,070 go, so I can use get int and printf respectively. 1065 01:03:14,590 --> 01:03:17,170 I'm going to just on face type int main void. 1066 01:03:17,470 --> 01:03:21,370 And today, we won't explain what that does. More on that to come. For now, 1067 01:03:21,370 --> 01:03:23,500 assume it's like when green flag clicked. 1068 01:03:23,740 --> 01:03:27,040 But in this program, let's do a couple of things. Let's declare an integer 1069 01:03:27,040 --> 01:03:32,140 called x and assign it the return value of get int. And let's just keep it 1070 01:03:32,140 --> 01:03:35,940 simple. Let's ask the user not what's their name, but what's x, question mark, 1071 01:03:36,100 --> 01:03:40,300 semicolon. Now, so that we have something to compare, let's do it again, 1072 01:03:40,300 --> 01:03:40,879 with y. 1073 01:03:40,880 --> 01:03:46,480 int y equals get int, quote unquote, what's y, question mark. And I'm 1074 01:03:46,540 --> 01:03:50,480 again, a space just visually so the cursor nudges over a bit, followed by a 1075 01:03:50,480 --> 01:03:55,380 semicolon. At this point in the story, my users will be prompted for x and y, 1076 01:03:55,520 --> 01:04:00,360 respectively. Let's do something with those values. How about if x is less 1077 01:04:00,360 --> 01:04:06,820 y, then go ahead and print out, quote unquote, x is less than y, 1078 01:04:07,020 --> 01:04:09,820 backslash n, close quote, semicolon. 1079 01:04:10,300 --> 01:04:14,520 All right, and let me hide my terminal window for just a moment. This is a 13 1080 01:04:14,520 --> 01:04:19,100 -line program at the moment, but really it's like five or six interesting lines. 1081 01:04:19,260 --> 01:04:21,840 The rest has been copy -paste from previous programs. 1082 01:04:22,330 --> 01:04:23,450 Notice a few details. 1083 01:04:23,770 --> 01:04:26,990 One, I've indeed used my curly braces here. 1084 01:04:27,210 --> 01:04:30,390 And notice if you highlight lines, you'll actually see little dots that can 1085 01:04:30,390 --> 01:04:32,810 you make sure, oh, there are indeed four spaces there. 1086 01:04:33,050 --> 01:04:36,030 I've been indenting, just like we did last week with pseudocode. 1087 01:04:36,510 --> 01:04:40,830 Strictly speaking, it's not necessary, but it's going to be way easier to read 1088 01:04:40,830 --> 01:04:45,550 your code if you do add all of this white space, so to speak, than if you 1089 01:04:45,550 --> 01:04:49,470 and then submit to us as homework a program that looks sort of god awful 1090 01:04:49,470 --> 01:04:54,030 this, which is to make it much more much harder for the human to read it, for 1091 01:04:54,030 --> 01:04:57,090 you to read it, your colleagues in the real world to read it. But the computer 1092 01:04:57,090 --> 01:05:01,210 is actually not going to care. In fact, as an aside, one of the tools we have 1093 01:05:01,210 --> 01:05:05,330 built into VS Code for CS50 is this button at top called Style 50. 1094 01:05:05,610 --> 01:05:09,190 This is a program that we indeed wrote that will give you suggestions on how to 1095 01:05:09,190 --> 01:05:13,610 improve the style of your code so it looks like the right way that 1096 01:05:13,610 --> 01:05:17,510 would generally write it. As an aside, The computer world is fraught with 1097 01:05:17,510 --> 01:05:21,490 religious debate, so to speak, as to what code should look like. And people 1098 01:05:21,490 --> 01:05:25,610 the real world will have really stupid arguments over how many spaces to use 1099 01:05:25,610 --> 01:05:28,650 indentation and what lines code should go on and so forth. 1100 01:05:29,090 --> 01:05:32,790 Generally, in the real world or in a class, there's an official style guide 1101 01:05:32,790 --> 01:05:36,330 someone sort of autocratically declares, this is how everyone should write their 1102 01:05:36,330 --> 01:05:40,630 code, so that just everyone's code in the company or course looks the same. 1103 01:05:40,630 --> 01:05:41,650 you'll find in the real world, 1104 01:05:42,560 --> 01:05:43,880 reasonable people will disagree. 1105 01:05:44,180 --> 01:05:48,740 When you click style 50, it will be formatted as we ourselves recommend in 1106 01:05:48,940 --> 01:05:50,220 And in fact, let me zoom out here. 1107 01:05:50,580 --> 01:05:54,200 And this looks a little cryptic at first glance, but on the left is the code 1108 01:05:54,200 --> 01:05:57,160 that I just wrote and made a mess of by deleting all that white space. 1109 01:05:57,380 --> 01:06:02,480 On the right is the way the code should look if it is well styled. 1110 01:06:02,890 --> 01:06:06,330 So whereas correctness is all about does the code work the way it's supposed to, 1111 01:06:06,710 --> 01:06:09,930 design is about how well have you written that code? 1112 01:06:10,130 --> 01:06:11,069 Is it efficient? 1113 01:06:11,070 --> 01:06:12,090 Did you make good decisions? 1114 01:06:12,650 --> 01:06:14,030 Style is purely aesthetic. 1115 01:06:14,370 --> 01:06:15,370 Is it readable? 1116 01:06:15,410 --> 01:06:16,570 Does it follow a standard? 1117 01:06:16,790 --> 01:06:20,190 Can another human sort of easily skim it top to bottom, left to right, and 1118 01:06:20,190 --> 01:06:23,970 understand what's going on? So these green highlights are saying, please add 1119 01:06:23,970 --> 01:06:24,970 white space there. 1120 01:06:25,330 --> 01:06:28,050 And so I can actually change my code to match. 1121 01:06:28,270 --> 01:06:31,850 On the left -hand side here, if I realize, oh, my code's looking pretty 1122 01:06:32,070 --> 01:06:37,490 watch on line six at left as I hit the space bar to, whoops, sorry, on the 1123 01:06:37,790 --> 01:06:39,250 1, 2, 3, 4. 1124 01:06:39,950 --> 01:06:44,150 Notice that the right -hand side is starting to be happier with my code by 1125 01:06:44,150 --> 01:06:45,630 getting rid of the green indicators. 1126 01:06:45,990 --> 01:06:48,230 And I can do 1, 2, 3, 4. 1127 01:06:48,570 --> 01:06:51,690 That fixed that. Over here, I can do 1, 2, 3, 4. 1128 01:06:52,070 --> 01:06:55,970 I can move this onto its own line by hitting Enter. 1129 01:06:56,730 --> 01:06:59,370 And you know what? If it's taking too long, once you get into the habit of 1130 01:06:59,370 --> 01:07:02,210 things, you can just apply changes. It will give you the suggestions 1131 01:07:02,210 --> 01:07:06,550 automatically, and we're done and on our way. But for practice's sake, I would 1132 01:07:06,550 --> 01:07:10,890 get into the habit of doing things manually until it gets boring and 1133 01:07:10,890 --> 01:07:13,970 which point you might as well automate the process with a single click. 1134 01:07:14,190 --> 01:07:17,530 All right. So let's actually run this code. I'm going to go ahead and open my 1135 01:07:17,530 --> 01:07:20,210 terminal window again and clear it for clarity. 1136 01:07:20,510 --> 01:07:21,550 I'm going to run make. 1137 01:07:22,640 --> 01:07:24,960 Compare and hope that I didn't make any mistake. 1138 01:07:25,220 --> 01:07:26,560 I don't seem to have yet. 1139 01:07:26,760 --> 01:07:27,880 Dot slash compare. 1140 01:07:28,220 --> 01:07:30,580 And now notice I'm prompted. For x, let's type 1. 1141 01:07:30,940 --> 01:07:32,620 For y, let's type 2. 1142 01:07:32,820 --> 01:07:35,360 Enter. And x is less than y. 1143 01:07:35,600 --> 01:07:39,140 Let's do a little sanity check, so to speak. Let's rerun it. Dot slash 1144 01:07:39,580 --> 01:07:41,820 What's x? Let's do 2 this time. 1145 01:07:42,120 --> 01:07:43,200 1 for y. 1146 01:07:43,770 --> 01:07:45,070 And this time it said nothing. 1147 01:07:45,290 --> 01:07:48,530 So that's to be expected, because I didn't have a two -way or a three -way 1148 01:07:48,530 --> 01:07:53,910 in the road. The only time this code should say anything is if indeed x is 1149 01:07:53,910 --> 01:07:54,910 than y. 1150 01:07:55,030 --> 01:07:58,130 So for those of you who might be more visual when it comes to learning, here's 1151 01:07:58,130 --> 01:08:00,550 flow chart that represents this same exact program. 1152 01:08:00,810 --> 01:08:02,030 If you read it top to bottom. 1153 01:08:02,480 --> 01:08:04,260 You start the program with dot slash compare. 1154 01:08:04,520 --> 01:08:09,400 You are then prompted for x and y, and you're asked this. Is x less than y? 1155 01:08:09,620 --> 01:08:12,340 And the fact that this is a diamond means this is a Boolean expression, a 1156 01:08:12,340 --> 01:08:14,720 question that the computer is asking itself. 1157 01:08:15,060 --> 01:08:19,960 If the answer to that question is true, then quote unquote x is less than y gets 1158 01:08:19,960 --> 01:08:21,220 printed, and the program stops. 1159 01:08:21,939 --> 01:08:27,260 Else, if x is not less than y, as in the second scenario, the answer is, of 1160 01:08:27,260 --> 01:08:28,939 course, false, and nothing more happens. 1161 01:08:29,180 --> 01:08:33,060 But we can build out this tree, so to speak, by adding a bit more code. So 1162 01:08:33,060 --> 01:08:34,760 make it look like the second Scratch example. 1163 01:08:35,020 --> 01:08:40,859 If I go back here, it's not hard to just say, else if x is not less than y, 1164 01:08:41,000 --> 01:08:41,959 let's say that. 1165 01:08:41,960 --> 01:08:46,200 x is not less than y, backslash n, close quote, semicolon. 1166 01:08:46,520 --> 01:08:52,420 Let me now go ahead and rerun, make, compare, enter, dot slash compare, 1167 01:08:52,560 --> 01:08:56,479 And again, I'll do the second example, 2, which is bigger, and 1, which is 1168 01:08:56,479 --> 01:08:58,180 smaller. And this time, I will see. 1169 01:08:58,640 --> 01:09:00,220 x is not less than y. 1170 01:09:00,859 --> 01:09:05,220 If then we were to look not at this flow chart, but a slightly bigger one, you 1171 01:09:05,220 --> 01:09:08,020 can sort of visualize it this way. Everything in the left -hand side of 1172 01:09:08,020 --> 01:09:09,020 picture is the same. 1173 01:09:09,180 --> 01:09:14,060 But if it's not true that x is less than y, the answer is thus false. This time 1174 01:09:14,060 --> 01:09:16,240 we say, quote unquote, x is not less than y. 1175 01:09:16,540 --> 01:09:20,520 And we can do this, obviously, one final time just to bring the point home. If I 1176 01:09:20,520 --> 01:09:21,520 go back to my code. 1177 01:09:21,979 --> 01:09:25,600 And I even more pedantically compare these three values. 1178 01:09:25,840 --> 01:09:27,180 Let me go ahead and do this. 1179 01:09:27,420 --> 01:09:34,140 So else, I don't want an else, actually. So let's go ahead and do this. 1180 01:09:34,279 --> 01:09:41,279 Else if x is greater than y, let's then say x is greater than y 1181 01:09:41,279 --> 01:09:48,100 in English. And then finally have an else that says printf x is equal 1182 01:09:48,100 --> 01:09:49,100 to y. 1183 01:09:49,520 --> 01:09:53,899 close quote, or rather, backslash n, close quote, semicolon. So just to show 1184 01:09:53,899 --> 01:09:57,160 this all on the screen at once, this is identical now to that Scratch version. 1185 01:09:57,380 --> 01:10:00,340 It's well -designed, because I'm not asking the equals equals question 1186 01:10:00,340 --> 01:10:05,920 unnecessarily. If I go back to my terminal window here, clear the screen, 1187 01:10:05,920 --> 01:10:10,280 make compare, Enter, and then dot slash compare again, Enter. 1188 01:10:10,700 --> 01:10:11,980 What's x? Let's do 1. 1189 01:10:12,380 --> 01:10:13,380 Let's do 2. 1190 01:10:13,500 --> 01:10:15,340 x is less than y. Let's run it again. 1191 01:10:15,560 --> 01:10:16,560 Dot slash compare. 1192 01:10:16,760 --> 01:10:17,760 What's 2? 1193 01:10:18,280 --> 01:10:22,420 And 1, x is greater than y. Once more time, dot slash compare. 1194 01:10:22,660 --> 01:10:23,660 What's x1? 1195 01:10:23,680 --> 01:10:24,760 What's y1? 1196 01:10:25,020 --> 01:10:27,820 And now x is equal to y. 1197 01:10:28,040 --> 01:10:31,500 As an aside, if I seem to be typing fairly fast, you can actually kind of 1198 01:10:31,500 --> 01:10:35,500 with your keyboard. If you go up or down, you can scroll through all of the 1199 01:10:35,500 --> 01:10:37,320 commands that you've typed. So it's actually. 1200 01:10:37,760 --> 01:10:41,980 Excuse me, very useful. If you just hit up, it will pre -write the previous 1201 01:10:41,980 --> 01:10:44,260 command for you, at which point you can just say enter. 1202 01:10:44,500 --> 01:10:47,940 Or there's other fancy features built into this programming environment. 1203 01:10:48,200 --> 01:10:52,920 If you do dot slash S -C -O -M and then get kind of bored with typing out the 1204 01:10:52,920 --> 01:10:56,900 whole English word, you can hit tab for tab completion, like in a web browser, 1205 01:10:57,040 --> 01:11:00,940 and it, too, will autocomplete if it finds a file that starts with those 1206 01:11:00,940 --> 01:11:03,060 letters. A little efficiencies here. 1207 01:11:04,400 --> 01:11:05,400 Questions, then? 1208 01:11:06,220 --> 01:11:07,420 On the code here. Yeah. 1209 01:11:07,720 --> 01:11:08,920 I have a question about libraries. 1210 01:11:09,160 --> 01:11:12,040 Sure. Is there any downside to just putting in all of the libraries? 1211 01:11:12,860 --> 01:11:16,180 A good question. Is there any downside to just putting in all of the libraries? 1212 01:11:16,220 --> 01:11:19,160 Like we saw in the manual pages a moment ago, performance. 1213 01:11:19,460 --> 01:11:23,640 So generally speaking, C is meant to be a very efficient language, so much so 1214 01:11:23,640 --> 01:11:27,240 that even though it's decades old, it's still used omnipresently nowadays 1215 01:11:27,240 --> 01:11:28,320 because it's so fast. 1216 01:11:28,620 --> 01:11:32,460 It therefore minimizes time. It minimizes energy use. So it's still 1217 01:11:32,460 --> 01:11:36,870 heavily. you would slow things down if you told the compiler, by the way, give 1218 01:11:36,870 --> 01:11:39,470 me all of these other functions that I'm never going to use. 1219 01:11:39,890 --> 01:11:42,370 So in short, just don't do that because it's unnecessary. 1220 01:11:42,690 --> 01:11:43,690 But a good question. 1221 01:11:43,890 --> 01:11:46,810 Other questions on what we've done here? 1222 01:11:47,850 --> 01:11:48,850 Yeah, in front. 1223 01:11:48,970 --> 01:11:49,970 Just a follow -up. 1224 01:11:50,050 --> 01:11:51,050 What is it? 1225 01:11:52,250 --> 01:11:53,350 A YSC faster? 1226 01:11:53,670 --> 01:11:58,030 A YSC faster than other languages? Let me answer that in more detail in week 1227 01:11:58,030 --> 01:11:59,030 when you'll see. 1228 01:11:59,450 --> 01:12:03,730 how much easier it is to write code in other languages because someone else is 1229 01:12:03,730 --> 01:12:06,990 doing a lot of the work for you. So as an introductory course, we're sort of 1230 01:12:06,990 --> 01:12:10,110 teaching you bottom up, like how do you write code? How does the computer 1231 01:12:10,110 --> 01:12:11,110 understand code? 1232 01:12:11,190 --> 01:12:14,150 Eventually, this kind of stuff, certainly after like five, six weeks of 1233 01:12:14,230 --> 01:12:16,450 it's going to get tedious doing some of these things. 1234 01:12:16,690 --> 01:12:20,410 We're going to switch to another language that takes away the tedium and 1235 01:12:20,410 --> 01:12:23,970 us to really focus on the problems to be solved once we've sort of graduated to 1236 01:12:23,970 --> 01:12:24,709 that point. 1237 01:12:24,710 --> 01:12:25,710 Yeah? 1238 01:12:28,400 --> 01:12:31,880 Sure, to repeat the keyboard shortcuts, you can just go up, up, up, up, up, and 1239 01:12:31,880 --> 01:12:34,560 that will go through all of your previous commands, at which point you 1240 01:12:34,560 --> 01:12:35,279 hit Enter. 1241 01:12:35,280 --> 01:12:39,480 Or you can use tab completion. So you can start typing a word like code, and C 1242 01:12:39,480 --> 01:12:45,580 -O -D tab will finish the thought, or dot slash C -O -M tab will finish that 1243 01:12:45,580 --> 01:12:48,660 thought, just to save yourself some keystrokes. And clearing the screen is 1244 01:12:48,660 --> 01:12:52,860 Control -L, which has no functional purpose other than keeping things neat 1245 01:12:52,860 --> 01:12:53,860 tidy in class. 1246 01:12:54,180 --> 01:12:55,380 So a design question. 1247 01:12:55,700 --> 01:12:58,340 So this code, I dare say, is correct. Let me zoom in a little bit here. 1248 01:12:58,580 --> 01:13:03,360 Let me change the code to just do this, even though we already saw from scratch 1249 01:13:03,360 --> 01:13:05,060 that we probably shouldn't do this. 1250 01:13:05,540 --> 01:13:07,660 Why should we not do this? 1251 01:13:08,470 --> 01:13:12,670 If, especially, I'm just more comfortable asking three separate 1252 01:13:12,670 --> 01:13:17,650 if x is less than y, if x is greater than y, if x equals y, do this. It's a 1253 01:13:17,650 --> 01:13:20,690 world to live in. Just ask your questions. You don't have to worry about 1254 01:13:20,710 --> 01:13:23,950 else, if, else, if, forks in the road. You can just ask three questions. But 1255 01:13:23,950 --> 01:13:29,650 let's put a finger on why is this correct, yes, but not well -designed. 1256 01:13:30,190 --> 01:13:31,190 Yeah, and back again. 1257 01:13:38,559 --> 01:13:42,700 OK, so there could be cases that are potentially outside of these three. 1258 01:13:42,700 --> 01:13:45,580 this is relatively simple math comparing numbers, we don't have to worry about 1259 01:13:45,580 --> 01:13:49,820 that here. But yes, in general, you might miss a scenario without using a 1260 01:13:49,820 --> 01:13:50,820 -all like else. 1261 01:13:54,490 --> 01:13:58,410 Yeah, so maybe more than one of them could be evaluated as true. Not going to 1262 01:13:58,410 --> 01:14:02,390 happen here, but yes, you could accidentally create a situation where 1263 01:14:02,390 --> 01:14:05,630 print or three things print because you didn't really think about the boundaries 1264 01:14:05,630 --> 01:14:08,910 among these questions that you're asking. Again, not applicable here, but 1265 01:14:08,910 --> 01:14:09,970 general, a good concern. 1266 01:14:15,720 --> 01:14:19,300 DAVID J. Really good. Really what's concerning here in this example is 1267 01:14:19,300 --> 01:14:22,860 slowing the computer down by wasting its time having it do work that is 1268 01:14:22,860 --> 01:14:26,780 logically unnecessary, even more so than the scratch in the first C example. 1269 01:14:26,860 --> 01:14:30,520 Why? Suppose that I type in 1 for x and 1 for y. 1270 01:14:30,940 --> 01:14:34,700 Because I wrote this code top to bottom, this question is going to be asked no 1271 01:14:34,700 --> 01:14:35,398 matter what. 1272 01:14:35,400 --> 01:14:36,580 The answer is going to be false. 1273 01:14:36,880 --> 01:14:39,600 This question is going to be asked no matter what. The answer is going to be 1274 01:14:39,600 --> 01:14:43,040 false. This question is going to be asked, and no matter what, the answer is 1275 01:14:43,040 --> 01:14:47,120 going to be true. We're OK there because we had to ask all three questions. 1276 01:14:47,480 --> 01:14:51,740 But suppose I did the first thing. x is 1, y is 2. 1277 01:14:52,120 --> 01:14:56,300 Then this first question is going to be true because x is 1. is less than y, 1 1278 01:14:56,300 --> 01:14:58,080 is less than 2, so this is going to print. 1279 01:14:58,300 --> 01:15:03,260 And yet then I'm wasting everyone's time asking, is x greater than y? Even 1280 01:15:03,260 --> 01:15:05,380 though it obviously isn't. Is x equal to y? 1281 01:15:05,620 --> 01:15:11,120 It obviously isn't. You're doing three times as much work in that particular 1282 01:15:11,120 --> 01:15:13,200 case. It's just not good design. 1283 01:15:13,520 --> 01:15:16,420 And again, for those of you who think a little more visually, we can actually 1284 01:15:16,420 --> 01:15:17,420 make this picture. 1285 01:15:17,870 --> 01:15:21,870 To match, here is a final flowchart for bad code, bad design. 1286 01:15:22,170 --> 01:15:25,970 Why? Because no matter what, when you start the program and you want to stop 1287 01:15:25,970 --> 01:15:30,310 program, you're going through all three of those darn questions no matter what. 1288 01:15:30,510 --> 01:15:33,610 Whereas the previous flowchart got us to the stop. 1289 01:15:34,080 --> 01:15:39,660 Bubble faster by taking alternative arrows based on true or false answers. 1290 01:15:39,660 --> 01:15:42,140 short, still correct, but bad design. 1291 01:15:42,480 --> 01:15:46,180 And so again, even for problem set one, when we start writing C code, consider 1292 01:15:46,180 --> 01:15:50,720 not just getting the job done, but how you might get the job done better than 1293 01:15:50,720 --> 01:15:51,720 you might otherwise. 1294 01:15:52,700 --> 01:15:56,380 All right, let's add a few other features into the mix. 1295 01:15:57,200 --> 01:16:01,120 Here we have those same data types that are supported by C. Let's focus for a 1296 01:16:01,120 --> 01:16:03,740 moment on something a little simpler, just chars, single characters. 1297 01:16:04,100 --> 01:16:07,640 Unfortunately, for better or for worse in C, the language makes a distinction 1298 01:16:07,640 --> 01:16:10,980 between strings of text, which are generally words, phrases. 1299 01:16:11,600 --> 01:16:16,840 They can confusingly be single characters or even zero characters if 1300 01:16:16,840 --> 01:16:20,280 type anything in between the quotes, but more on that another time. But when you 1301 01:16:20,280 --> 01:16:23,980 know from the get -go that you only want to get a a single character back from 1302 01:16:23,980 --> 01:16:27,720 the user, like y for yes, n for no, for instance, which is super common in 1303 01:16:27,720 --> 01:16:32,840 programs, you can get that using a char, and CS50's own function, getChar. 1304 01:16:33,180 --> 01:16:36,960 So how might we use this? Well, let's go back to VS Code here. I'm going to 1305 01:16:36,960 --> 01:16:39,800 close compare .c. And let's write a third program altogether. 1306 01:16:40,260 --> 01:16:42,380 Let's call this one agree .c. 1307 01:16:42,620 --> 01:16:45,780 And this is meant to represent terms and conditions where you have to check a 1308 01:16:45,780 --> 01:16:47,700 box, yes or no, or something like that. 1309 01:16:47,920 --> 01:16:51,000 In this program, I'm going to go ahead and do the following. 1310 01:16:51,400 --> 01:16:56,160 I'm going to go ahead and, as before, include CS50 .h so we've got it, include 1311 01:16:56,160 --> 01:16:58,140 standardio .h so that we've got it. 1312 01:16:58,560 --> 01:17:02,100 Int main void, because we have to do that for now. More on that another time. 1313 01:17:02,340 --> 01:17:04,580 And now let's ask the user a question. Do they agree? 1314 01:17:05,040 --> 01:17:10,400 So I'm going to call get char and then pass in a prompt of do you agree 1315 01:17:10,400 --> 01:17:11,400 mark with a space. 1316 01:17:12,330 --> 01:17:16,870 semicolon. But as before, with get string and get int, those functions 1317 01:17:16,870 --> 01:17:21,530 value. So I want to assign that value from right to left to a variable, which 1318 01:17:21,530 --> 01:17:24,770 could call answer again. But honestly, this program's so short, I'm just going 1319 01:17:24,770 --> 01:17:26,790 to use the letter c, which is conventional. 1320 01:17:27,110 --> 01:17:32,170 So c for char, i for int, or n for number are very common. But one more 1321 01:17:32,290 --> 01:17:35,290 what's still missing for my variable here? 1322 01:17:36,010 --> 01:17:40,810 I need to say this shall be a char, not an int, not a string, a single char. 1323 01:17:41,150 --> 01:17:46,110 All right, now what do I want to do? I can ask a question. If c equals equals 1324 01:17:46,110 --> 01:17:51,270 lowercase y, then go ahead and print out, just so we see something on the 1325 01:17:51,270 --> 01:17:54,810 screen, agreed period backslash n, as though they agreed to the terms and 1326 01:17:54,810 --> 01:18:01,270 conditions. Else, if c equals equals lowercase n, go ahead and print out, for 1327 01:18:01,270 --> 01:18:03,730 instance, not agreed, just so we see something. 1328 01:18:04,270 --> 01:18:05,108 on the screen. 1329 01:18:05,110 --> 01:18:08,190 So let me hide my terminal window and focus on the code. There's a couple of 1330 01:18:08,190 --> 01:18:09,810 details here that are a little interesting. 1331 01:18:10,030 --> 01:18:15,150 So one, what did I do on line 7 and 11 that is not consistent with what I've 1332 01:18:15,150 --> 01:18:16,150 done before? 1333 01:18:18,010 --> 01:18:19,010 Subtle. 1334 01:18:20,350 --> 01:18:24,530 So I'm using apostrophes or single quotes now instead of double quotes. 1335 01:18:24,730 --> 01:18:29,250 It's a C thing. When you're using strings, you use double quotes. When you 1336 01:18:29,250 --> 01:18:31,940 single chars, You use single quotes. 1337 01:18:32,140 --> 01:18:36,040 So the argument to get char, that's still a string. It's a whole sentence 1338 01:18:36,040 --> 01:18:38,920 I'm passing in. So that is just like get in, just like get string. 1339 01:18:39,630 --> 01:18:43,570 But when I get the answer back, the return value, and put it in this 1340 01:18:43,730 --> 01:18:47,930 and I want to check what is that one char, I have to surround the char I'm 1341 01:18:47,930 --> 01:18:52,690 comparing against in single quotes or apostrophes, both for the y and for the 1342 01:18:52,910 --> 01:18:56,290 So this program is not super well designed, because it's not going to 1343 01:18:56,290 --> 01:18:59,990 uppercase. It's not going to handle weird inputs very well. But let me open 1344 01:18:59,990 --> 01:19:02,710 terminal window, make agree, Enter. 1345 01:19:03,070 --> 01:19:05,610 The code compiles OK, dot slash agree. 1346 01:19:05,930 --> 01:19:08,010 Do I agree? Let's try it. Y for yes. 1347 01:19:08,460 --> 01:19:09,940 OK. Let's try it again. 1348 01:19:10,220 --> 01:19:11,220 Dot slash agree. 1349 01:19:11,420 --> 01:19:12,420 N for no. 1350 01:19:12,760 --> 01:19:16,480 Not agreed. Let's do it one more time. Let's very enthusiastically say yes in 1351 01:19:16,480 --> 01:19:17,339 all caps. 1352 01:19:17,340 --> 01:19:20,420 And it just kind of ignores me. 1353 01:19:21,080 --> 01:19:21,898 But why? 1354 01:19:21,900 --> 01:19:24,980 Well, this is a feature of CS50's get char function. 1355 01:19:25,200 --> 01:19:28,640 If you tell us you want to get a char, we're not going to tolerate a whole 1356 01:19:28,640 --> 01:19:33,000 string of text from the user. We're going to prompt them again and again and 1357 01:19:33,000 --> 01:19:34,980 again until they give us just one char. 1358 01:19:35,320 --> 01:19:40,040 So yes is three times too long. So let's actually just do a single capital Y and 1359 01:19:40,040 --> 01:19:41,100 see what happens. Return. 1360 01:19:41,980 --> 01:19:43,440 The program ignores me altogether. 1361 01:19:43,820 --> 01:19:46,800 So all right, this is kind of a poorly designed program. It's a little annoying 1362 01:19:46,800 --> 01:19:50,660 that we'll just ignore humans, even if they type in y or n. That just happens 1363 01:19:50,660 --> 01:19:53,840 be uppercase. So let's improve this. Let me go ahead and add a couple more 1364 01:19:53,840 --> 01:20:00,120 conditions. Else if c equals equals uppercase y, then go ahead and print out 1365 01:20:00,120 --> 01:20:02,240 agreed, same as before. 1366 01:20:02,460 --> 01:20:07,980 And then down here, else if c equals equals capital N, then let's go ahead 1367 01:20:07,980 --> 01:20:12,470 print out again not Agreed. So this is now more correct. 1368 01:20:12,730 --> 01:20:16,250 It's still going to ignore bogus input that makes no sense if it's just like 1369 01:20:16,250 --> 01:20:18,290 word, if it's a different letter altogether. 1370 01:20:18,750 --> 01:20:23,910 But this to code, while correct in some sense, is still poorly designed. 1371 01:20:24,490 --> 01:20:29,170 Even if you've never programmed before, what rubs you the wrong way about this 1372 01:20:29,170 --> 01:20:30,170 code now? 1373 01:20:30,870 --> 01:20:32,010 Be critical. Yeah? 1374 01:20:36,650 --> 01:20:40,350 Yeah, it'd be nice to just merge the lowercase and the uppercase Y together. 1375 01:20:40,690 --> 01:20:44,030 The same thing for the lowercase and the uppercase N. Why? 1376 01:20:44,270 --> 01:20:47,750 If only because literally lines 9 and 12 are identical. 1377 01:20:48,250 --> 01:20:51,050 Lines 17 and 21 are identical. 1378 01:20:51,410 --> 01:20:56,170 And while not a huge deal, if I go in and I change this sentence, odds are, 1379 01:20:56,170 --> 01:20:59,570 the course of my lifetime programming, I'm going to forget to change this one, 1380 01:20:59,690 --> 01:21:02,010 even though I changed this one. Or I'm going to forget to change this one and 1381 01:21:02,010 --> 01:21:04,810 this one. So you don't want the code to get out of sync, potentially. 1382 01:21:06,250 --> 01:21:07,129 to repeat yourself. 1383 01:21:07,130 --> 01:21:11,410 So don't repeat yourself is a tenet of programming, too. If you can avoid that 1384 01:21:11,410 --> 01:21:16,070 by somehow factoring out some commonality, you should do so, similar 1385 01:21:16,070 --> 01:21:18,130 to math, when you factor out variables or the like. 1386 01:21:18,350 --> 01:21:22,410 So let me tighten this up, so to speak. Let me get rid of what we just did so 1387 01:21:22,410 --> 01:21:24,250 that it's a little shorter as before. 1388 01:21:24,490 --> 01:21:29,190 And let me express myself with two conditions using the following syntax. 1389 01:21:29,670 --> 01:21:35,920 I want to check if c equals equals lowercase y or C equals equals uppercase 1390 01:21:36,200 --> 01:21:40,480 So you can actually use what's called a logical operator, two vertical bars, 1391 01:21:40,740 --> 01:21:47,720 which means or, and we can do this down here, or C equals equals capital 1392 01:21:47,720 --> 01:21:52,440 N. So same exact functionality, but to your point, we've now eliminated what, 1393 01:21:52,520 --> 01:21:53,379 like another one? 1394 01:21:53,380 --> 01:21:57,400 It was like, what, one, four? It's like eight lines of code now are gone, which 1395 01:21:57,400 --> 01:22:01,360 is eight fewer lines that I might screw up in this program, less opportunity for 1396 01:22:01,360 --> 01:22:02,360 mistakes or bugs. 1397 01:22:02,880 --> 01:22:07,060 Probably a good thing. So now if I run this, let me open my terminal window. 1398 01:22:07,620 --> 01:22:13,380 Let me run make agree, enter, dot slash agree, enter. Do I agree? 1399 01:22:13,740 --> 01:22:14,740 Capital Y. 1400 01:22:14,920 --> 01:22:17,680 Now it seems to be handling both of those situations. 1401 01:22:17,900 --> 01:22:21,760 So just a little tighter. As an aside, we won't use it here. But if you want to 1402 01:22:21,760 --> 01:22:26,360 say and, which would be nonsensical, it, a little confusingly, is 2 ampersand, 1403 01:22:26,540 --> 01:22:27,540 means a logical. 1404 01:22:27,920 --> 01:22:32,560 and whereby the left thing has to be true and the right thing has to be true. 1405 01:22:32,560 --> 01:22:34,100 it's two Boolean expressions at once. 1406 01:22:34,360 --> 01:22:37,260 This one makes no logical sense, though, because the character cannot be 1407 01:22:37,260 --> 01:22:41,580 simultaneously lowercase and uppercase. It's got to be one or the other. So two 1408 01:22:41,580 --> 01:22:46,420 vertical bars is logically correct. That represents our notion here of or. 1409 01:22:48,440 --> 01:22:49,440 Question? 1410 01:22:50,480 --> 01:22:51,480 No? 1411 01:22:51,760 --> 01:22:52,760 Yeah. 1412 01:22:57,420 --> 01:23:01,220 You could not write or. So I'm saying or just because that's a little more 1413 01:23:01,220 --> 01:23:02,540 normal, but this is incorrect. 1414 01:23:02,900 --> 01:23:06,380 However, sneak preview, in the language of Python, you actually will literally 1415 01:23:06,380 --> 01:23:09,380 say or among other things, which gets a little more user -friendly. 1416 01:23:10,100 --> 01:23:12,220 Other questions on this here? 1417 01:23:15,580 --> 01:23:16,820 Searching? Yes, in back. 1418 01:23:18,620 --> 01:23:20,900 Is there an easier way to handle case sensitivity? 1419 01:23:21,100 --> 01:23:24,960 Yes, and we'll show you that next week, in fact. So we can combine this code to 1420 01:23:24,960 --> 01:23:25,889 be even tighter. 1421 01:23:25,890 --> 01:23:29,810 All right, let's do one final set of examples before taking a cookie break, 1422 01:23:29,810 --> 01:23:32,570 we could. But let's go ahead and close agree .c here. 1423 01:23:32,810 --> 01:23:36,010 Let me open my terminal window. And let's go ahead and implement a sort of 1424 01:23:36,010 --> 01:23:41,170 virtual cat, as we did last week. I'm going to code up a file called cat .c. 1425 01:23:41,170 --> 01:23:43,770 I'm going to implement this in a few different ways, the first of them pretty 1426 01:23:43,770 --> 01:23:48,370 foolish. So here, I'm going to include standardio .h. No need for CS50 just 1427 01:23:49,950 --> 01:23:50,990 int main void. 1428 01:23:51,550 --> 01:23:55,730 Inside of these curly braces, let's go ahead and do printf meow to get the cat 1429 01:23:55,730 --> 01:23:56,449 to meow. 1430 01:23:56,450 --> 01:24:00,270 And then to save time, I'm going to copy paste that two more times. So this cat 1431 01:24:00,270 --> 01:24:02,430 shall meow three times in total. 1432 01:24:02,750 --> 01:24:06,270 All right. I'm going to go ahead and make the cat, so to speak. All good. 1433 01:24:06,490 --> 01:24:11,330 Dot slash cat. Enter. And it meows three times, just like our scratch cat last 1434 01:24:11,330 --> 01:24:13,170 time. I'll stipulate this is correct. 1435 01:24:13,390 --> 01:24:16,210 This is a really well implemented cat, correctness wise. 1436 01:24:16,450 --> 01:24:18,830 But why is it bad design intuitively? 1437 01:24:19,710 --> 01:24:20,730 Just like last week. 1438 01:24:26,230 --> 01:24:29,910 I keep repeating the code. I mean, I literally copied and pasted, which is 1439 01:24:29,910 --> 01:24:33,530 of your first obvious sign I'm probably doing something wrong if I'm copying and 1440 01:24:33,530 --> 01:24:35,510 pasting, because I'm literally repeating myself. 1441 01:24:35,790 --> 01:24:39,130 So to spoil it, like odds are a loop is probably going to be our friend here. 1442 01:24:39,330 --> 01:24:43,490 And so in fact, in C, we have those features as well. 1443 01:24:43,750 --> 01:24:47,710 So in the world of C, we can implement some of last week's same ideas in a few 1444 01:24:47,710 --> 01:24:48,549 different ways. 1445 01:24:48,550 --> 01:24:51,330 These are a little more mechanical, but suppose we want to repeat something 1446 01:24:51,330 --> 01:24:52,510 literally three times. 1447 01:24:52,950 --> 01:24:54,090 Scratch gives us a repeat. 1448 01:24:54,590 --> 01:24:56,250 A block with an input, so easy. 1449 01:24:56,530 --> 01:24:59,630 C, in a lot of languages, is going to be a little more mechanical. And it's 1450 01:24:59,630 --> 01:25:02,450 going to look ugly at first. It will take some getting used to. But it is a 1451 01:25:02,450 --> 01:25:07,570 paradigm you will use again and again and again. This will become very rote 1452 01:25:07,570 --> 01:25:12,310 memory before long. Well, the most direct translation of this scratch code 1453 01:25:12,310 --> 01:25:15,690 is probably something that looks a little something like this, whereby I 1454 01:25:15,690 --> 01:25:19,910 initialize a variable, here called i, and set it equal to 3. That's the code 1455 01:25:19,910 --> 01:25:21,810 equivalent in C of putting up three fingers. 1456 01:25:22,210 --> 01:25:27,740 Then what I want to do is while i is greater than 0, that is to say, while I 1457 01:25:27,740 --> 01:25:32,700 have at least one finger up, go ahead and do the following. And then once I've 1458 01:25:32,700 --> 01:25:36,160 done that, for instance, say meow on the screen, I want to go ahead and 1459 01:25:36,160 --> 01:25:37,280 decrement i. 1460 01:25:37,790 --> 01:25:39,090 and then do this whole thing again. 1461 01:25:39,350 --> 01:25:42,590 Now, I could have called this variable counter for consistency with earlier. 1462 01:25:42,930 --> 01:25:46,070 But it turns out it's conventional. When you've only got one variable involved 1463 01:25:46,070 --> 01:25:49,570 in your code and all it's doing is something simple like counting, you can 1464 01:25:49,570 --> 01:25:52,770 ahead and call the variable i for integer, for instance. But it would not 1465 01:25:52,770 --> 01:25:54,750 wrong to instead call i counter. 1466 01:25:55,110 --> 01:25:59,790 But notice, too, that in this so -called while loop, as we'll start to call it, 1467 01:25:59,830 --> 01:26:03,350 there is this parenthetical. And that parenthetical is actually itself a 1468 01:26:03,350 --> 01:26:07,620 expression. But unlike an if statement, whereby the Boolean an expression is 1469 01:26:07,620 --> 01:26:11,840 evaluated just once, and if the answer is true or yes, you do that thing. 1470 01:26:12,440 --> 01:26:17,320 The Boolean expression in a while loop here in C is evaluated again and again 1471 01:26:17,320 --> 01:26:22,940 and again every time you go through the loop to check if you should keep going 1472 01:26:22,940 --> 01:26:27,220 through the loop. So for instance, if the goal at hand is to say meow, well, 1473 01:26:27,220 --> 01:26:30,940 course, the comparable C function is going to be printf. And I want to print 1474 01:26:30,940 --> 01:26:34,880 on the screen meow, followed by a new line. Well, what's going on? Well, 1475 01:26:35,000 --> 01:26:36,220 I initialize i to 3. 1476 01:26:36,540 --> 01:26:38,640 I then check, is i greater than 0? 1477 01:26:38,860 --> 01:26:41,340 And of course it is, because effectively in the computer's memory, 1478 01:26:44,360 --> 01:26:48,300 I decrement i, which means to put down one of those fingers, and then. 1479 01:26:48,730 --> 01:26:52,830 I check the Boolean expression again. Is 2 greater than 0? Of course it is. So I 1480 01:26:52,830 --> 01:26:57,330 print out meow. And then I decrement i, putting down one more finger. Then I 1481 01:26:57,330 --> 01:27:01,030 check the expression again. Is 1 greater than 0? Of course it is. I print out 1482 01:27:01,030 --> 01:27:03,850 meow. And then I decrement i. And now I'm down to 0. 1483 01:27:04,070 --> 01:27:05,070 I check again. 1484 01:27:05,170 --> 01:27:06,730 Is 0 greater than 0? 1485 01:27:06,950 --> 01:27:07,909 Well, no. 1486 01:27:07,910 --> 01:27:11,790 And so the loop will automatically, by the definition of how this C code works, 1487 01:27:12,210 --> 01:27:16,270 terminate for me and proceed to any other lines if there are more lines of 1488 01:27:16,270 --> 01:27:17,068 that I've written. 1489 01:27:17,070 --> 01:27:20,870 So how do we actually implement this then in code and get it running, well, 1490 01:27:20,870 --> 01:27:24,610 going to be pretty much the same idea. Let me go back to VS Code here. I'm 1491 01:27:24,610 --> 01:27:28,250 to get rid of all of this copy paste. And inside of my main function, I'm 1492 01:27:28,250 --> 01:27:29,450 to do exactly what we saw. 1493 01:27:29,710 --> 01:27:31,070 Int i equals 3. 1494 01:27:32,010 --> 01:27:37,990 semicolon, while i is greater than 0, then go ahead and print out with printf, 1495 01:27:38,050 --> 01:27:42,270 meow, backslash n, and then be sure you decrement i. 1496 01:27:42,490 --> 01:27:46,670 And notice that lines 8 and 9 are not only indented, they are inside of that 1497 01:27:46,670 --> 01:27:49,890 while loop, so to speak, which means they will both happen again. 1498 01:27:50,460 --> 01:27:55,940 And again and again, because what's happening in code here is those curly 1499 01:27:55,940 --> 01:28:00,620 are kind of like the yellow pieces that are hugging the other puzzle pieces in 1500 01:28:00,620 --> 01:28:03,240 Scratch. It will keep doing this, this, this. 1501 01:28:03,480 --> 01:28:08,480 But every time through that loop or cycle, this Boolean expression will be 1502 01:28:08,480 --> 01:28:13,560 checked again and again and again until the answer is false, at which point the 1503 01:28:13,560 --> 01:28:17,100 computer is going to jump to the last line. And if there's nothing left, 1504 01:28:17,100 --> 01:28:18,099 it for the program. 1505 01:28:18,100 --> 01:28:19,120 No more to be done. 1506 01:28:20,010 --> 01:28:23,390 So same exact idea in Scratch, even though it's a little more mechanical. 1507 01:28:23,850 --> 01:28:26,070 So that's how we might implement this. 1508 01:28:26,310 --> 01:28:29,330 And you can think of it sort of these variables. 1509 01:28:29,590 --> 01:28:34,130 This is perhaps a little gratuitous, but let's do this. So if you have a 1510 01:28:34,130 --> 01:28:38,330 variable inside of a computer's memory, and that's a detail we'll get to in more 1511 01:28:38,330 --> 01:28:41,830 detail before long, you can really think of it just as like a container that 1512 01:28:41,830 --> 01:28:42,648 stores value. 1513 01:28:42,650 --> 01:28:43,650 So for instance, this. 1514 01:28:43,820 --> 01:28:46,600 Clear plastic bowl can be thought of as a variable. It just stores values. 1515 01:28:46,920 --> 01:28:50,140 And right now, there's obviously three stress balls in it, so it represents the 1516 01:28:50,140 --> 01:28:51,140 number three. 1517 01:28:51,400 --> 01:28:56,040 So what's really happening in code like this is we've initialized i to three, 1518 01:28:56,140 --> 01:29:00,240 which is this ball. We're then checking the question on line six, is i greater 1519 01:29:00,240 --> 01:29:01,179 than zero? 1520 01:29:01,180 --> 01:29:05,020 Obviously. So we proceed inside of the curly braces, and we print out meow. 1521 01:29:05,460 --> 01:29:06,700 We then decrement i. 1522 01:29:07,040 --> 01:29:11,240 So for the sake of unnecessary drama, like that's decrementing the variable. 1523 01:29:11,240 --> 01:29:15,040 what's being stored in this container now is 1 less. 1524 01:29:15,280 --> 01:29:18,760 We do it again. Check the count. Nope, 2 is greater than 0, so we keep going. 1525 01:29:18,900 --> 01:29:20,240 Meow. Decrement i. 1526 01:29:20,560 --> 01:29:21,560 Check the variable. 1527 01:29:21,720 --> 01:29:23,740 1 is greater than 0, so we print meow. 1528 01:29:24,120 --> 01:29:25,099 Decrement i. 1529 01:29:25,100 --> 01:29:26,840 We check the condition again. 1530 01:29:27,140 --> 01:29:31,460 i is not greater than 0, because 0 is not greater than 0. 1531 01:29:32,080 --> 01:29:33,920 And so the rest of the code stops executing. 1532 01:29:34,240 --> 01:29:37,040 I'm not sure if that was any more effective than fingers on my hand. But 1533 01:29:37,040 --> 01:29:39,360 the ball. We had the ball. So same exact idea. 1534 01:29:39,620 --> 01:29:42,420 Variables are just storing some value. And incrementing and decrementing would 1535 01:29:42,420 --> 01:29:45,280 just be adding or subtracting stress balls in this case. 1536 01:29:45,520 --> 01:29:46,800 But there's other ways we could do this. 1537 01:29:47,020 --> 01:29:48,720 In fact, let me zoom in on my code here. 1538 01:29:49,360 --> 01:29:52,520 And it's not really conventional in programming to count down. 1539 01:29:52,740 --> 01:29:56,520 Nothing wrong with it. It's just not really a thing we would typically count 1540 01:29:56,760 --> 01:29:58,860 So we could alternatively do this. 1541 01:29:59,400 --> 01:30:04,080 Set i equal to 1 initially. So we count 1, 2, 3, like a normal person. 1542 01:30:04,300 --> 01:30:05,880 And we can change our condition. 1543 01:30:06,280 --> 01:30:12,480 If I'm going to count from 1 to 3, what should my comparison be in my Boolean 1544 01:30:12,480 --> 01:30:13,480 expression here? 1545 01:30:15,420 --> 01:30:17,080 i is less than 3? 1546 01:30:18,520 --> 01:30:24,460 Less than or equal to 3, I think. So if i is initialized to 1, we're going to go 1547 01:30:24,460 --> 01:30:26,480 through this one time, two times. 1548 01:30:26,830 --> 01:30:30,130 three times, i is going to eventually get incremented to four. But at that 1549 01:30:30,130 --> 01:30:34,250 point, four is not less than or equal to three. So it's only going to execute a 1550 01:30:34,250 --> 01:30:37,430 total of three times. But there's still a bug in this code. What other line 1551 01:30:37,430 --> 01:30:38,430 needs to change? 1552 01:30:39,050 --> 01:30:42,110 Yeah, so line 9 needs to become plus plus. 1553 01:30:42,330 --> 01:30:46,730 So this code is just as correct. And honestly, you could, reasonable people 1554 01:30:46,730 --> 01:30:50,370 disagree. Your TF might say, do it this way and not this way. But this is still 1555 01:30:50,370 --> 01:30:54,250 correct. But it's not the most conventional way. As per last week, 1556 01:30:54,250 --> 01:30:57,770 scientists and programmers generally actually start counting from 0 by 1557 01:30:57,770 --> 01:30:59,390 convention for reasons we'll soon see. 1558 01:30:59,610 --> 01:31:04,190 So the better way, the more conventional way, arguably, would be always start 1559 01:31:04,190 --> 01:31:05,190 counting from 0. 1560 01:31:05,790 --> 01:31:08,930 count up to, but not through the number you care about. 1561 01:31:09,190 --> 01:31:14,090 And so this form of the code is probably the most popular way to do it. Start at 1562 01:31:14,090 --> 01:31:20,630 0, count up to 3, but not through 3, as with less than or equals than. All three 1563 01:31:20,630 --> 01:31:21,329 are correct. 1564 01:31:21,330 --> 01:31:24,570 Can't really do counting up as easily with the ball without picking up the 1565 01:31:24,570 --> 01:31:26,270 balls, but the exact same logic applies. 1566 01:31:26,490 --> 01:31:31,530 And in fact, this version of the code is so commonly done that there's a 1567 01:31:31,530 --> 01:31:35,970 different way to implement it all. There's a similar way to implement it 1568 01:31:35,970 --> 01:31:40,490 together. In fact, this code here, same exact thing, repeating three times, 1569 01:31:40,590 --> 01:31:44,150 because it's so commonly done that you want to initialize something to 0 and 1570 01:31:44,150 --> 01:31:48,150 keep doing something until the value 3, you can actually use a different 1571 01:31:48,150 --> 01:31:51,790 preposition, 4, which is another keyword in C. 1572 01:31:52,010 --> 01:31:55,410 And it looks a little more cryptic, but it just tightens things up. 1573 01:31:55,650 --> 01:31:57,650 This is what's called a for loop. 1574 01:31:58,060 --> 01:31:59,820 Previous is what's called a while loop. 1575 01:32:00,020 --> 01:32:03,540 And honestly, even though it probably to the newbie still looks just as cryptic, 1576 01:32:03,580 --> 01:32:07,660 it's just a little tighter, because you're expressing all of these ideas on 1577 01:32:07,660 --> 01:32:12,100 line. You specify the variable you want to create and initialize. 1578 01:32:12,330 --> 01:32:15,530 You specify the Boolean expression you want to check again and again. 1579 01:32:15,770 --> 01:32:20,270 You specify what increment or decrements you want to happen. And confusingly, 1580 01:32:20,270 --> 01:32:25,490 you do use semicolons here, not commas. You do not put a semicolon here. 1581 01:32:25,830 --> 01:32:28,810 You, of course, don't put them after these things. You generally only put 1582 01:32:28,810 --> 01:32:30,370 after function thus far. 1583 01:32:30,590 --> 01:32:32,890 So we do have one semicolon here. 1584 01:32:33,190 --> 01:32:36,410 But in short, this you'll get more comfortable with. This is how I, for 1585 01:32:36,410 --> 01:32:39,430 instance, almost always write a loop. But it's doing the exact same thing 1586 01:32:39,430 --> 01:32:43,230 mechanically as this. Same thing as counting. Same thing as counting the 1587 01:32:43,230 --> 01:32:47,650 balls. There's just different ways to express the exact same idea. 1588 01:32:48,270 --> 01:32:51,430 But there are ways to screw up. So in fact, let me go ahead and do this. 1589 01:32:51,650 --> 01:32:54,810 Suppose that the cat, we'd like the cat to live as long as possible. 1590 01:32:55,150 --> 01:32:58,150 And we don't want it to stop meowing after just three or a finite number of 1591 01:32:58,150 --> 01:33:01,770 times. How can you do something forever, again and again and again? 1592 01:33:02,350 --> 01:33:04,370 Well, let me go back into VS Code here. 1593 01:33:04,790 --> 01:33:08,850 Let me delete all of the code from earlier. And let me go ahead and say 1594 01:33:09,320 --> 01:33:12,900 Something is true. I'll come back to that. Let's just go ahead and print out 1595 01:33:12,900 --> 01:33:16,380 meow backslash n, ideally forever. 1596 01:33:17,040 --> 01:33:19,940 But what do I want to put in here? Well, if I want to do something forever, I 1597 01:33:19,940 --> 01:33:23,580 could do something kind of stupid, like while 1 is less than 2, which is always 1598 01:33:23,580 --> 01:33:27,560 going to be the case, or while 50 is less than 51, which is always going to 1599 01:33:27,580 --> 01:33:31,340 I could just ask an arbitrary question, but like arbitrary, not good in general. 1600 01:33:31,460 --> 01:33:34,800 Like you should have meaning behind your code. So if you want the expression to 1601 01:33:34,800 --> 01:33:39,280 be true all of the time, just say while true, because true is not changing 1602 01:33:39,280 --> 01:33:42,860 anytime soon. If it's literally true, it's always going to be true. The only 1603 01:33:42,860 --> 01:33:44,740 caveat is to use this trick for now. 1604 01:33:45,260 --> 01:33:48,960 you will need to include the CS50 library, which, for today's purposes, 1605 01:33:48,960 --> 01:33:50,200 that possible. 1606 01:33:50,700 --> 01:33:54,680 But there's a problem, of course. If the cat's going to live forever, if I do 1607 01:33:54,680 --> 01:33:57,100 make cat dot slash cat enter. 1608 01:33:57,790 --> 01:34:00,570 Like, you can very quickly lose control over your terminal window. 1609 01:34:00,790 --> 01:34:04,090 And you can see the meows are flying across the screen, at least based on the 1610 01:34:04,090 --> 01:34:07,490 bottom from what we're seeing. Like, this cat will never stop meowing. And 1611 01:34:07,490 --> 01:34:11,790 is either a feature or a bug, so to speak, depending on how long the cat 1612 01:34:11,790 --> 01:34:12,790 should live virtually. 1613 01:34:12,930 --> 01:34:18,110 But how do you terminate a program that is out of control like this infinitely. 1614 01:34:18,510 --> 01:34:23,610 So one of the takeaways for today is Control -C is your friend for cancel or 1615 01:34:23,610 --> 01:34:24,610 interrupt the program. 1616 01:34:24,690 --> 01:34:27,910 If you ever sort of lose control over a program because you've got intentionally 1617 01:34:27,910 --> 01:34:31,530 or unintentionally an infinite loop, you can go into your terminal window, hit 1618 01:34:31,530 --> 01:34:35,830 Control -C, sometimes multiple times if it's ignoring you, and that will break 1619 01:34:35,830 --> 01:34:40,390 out of the program and just essentially force quit it, like in Mac or PCs. 1620 01:34:40,890 --> 01:34:43,310 But let's make one improvement here still. 1621 01:34:43,820 --> 01:34:47,520 The last thing we did with our cat in Scratch, before now we'll take a break 1622 01:34:47,520 --> 01:34:51,380 a moment, was we defined our own functions. And recall that we did that 1623 01:34:51,380 --> 01:34:54,820 abstract away the idea of meowing, because Scratch didn't come with a meow 1624 01:34:54,820 --> 01:34:55,639 puzzle piece. 1625 01:34:55,640 --> 01:34:58,200 C definitely does not come with a meow function. 1626 01:34:58,460 --> 01:34:59,640 We have to implement it ourselves. 1627 01:35:00,000 --> 01:35:02,240 So quickly toward the end of week 0, we did this. 1628 01:35:02,580 --> 01:35:05,480 Define a function called meow that just plays the meow sound. 1629 01:35:05,700 --> 01:35:07,960 And now we have a meow puzzle piece we can use and reuse. 1630 01:35:08,440 --> 01:35:10,660 In C, we're about to do this. 1631 01:35:10,920 --> 01:35:13,620 And this is going to look a little cryptic, but it's going to lay the 1632 01:35:13,620 --> 01:35:16,860 for future weeks when we do this even more. I've got a meow function. 1633 01:35:17,460 --> 01:35:18,720 Weird mentions of void. 1634 01:35:18,940 --> 01:35:22,180 That just means there's no input and there's no output for this function. It 1635 01:35:22,180 --> 01:35:23,340 just does one thing simply. 1636 01:35:23,720 --> 01:35:25,700 And that one thing is printf meow. 1637 01:35:26,280 --> 01:35:30,300 So how do I use this here code? Here in Scratch is how we used it last week. 1638 01:35:30,420 --> 01:35:33,400 When the green flag is clicked, repeat three times the meow. 1639 01:35:33,920 --> 01:35:38,260 function. In C, it's going to look like this, int made void and all of that. And 1640 01:35:38,260 --> 01:35:41,640 I can use a for loop, a while loop. I'm copying and pasting the for loop version 1641 01:35:41,640 --> 01:35:43,320 of the code. Set i equals 0. 1642 01:35:43,700 --> 01:35:45,420 Make sure it stays below 3. 1643 01:35:45,920 --> 01:35:48,080 Increment it on each iteration or cycle. 1644 01:35:48,520 --> 01:35:49,540 And just call meow. 1645 01:35:50,080 --> 01:35:54,540 So what's nice here is that we have fairly simply a way in C to create our 1646 01:35:54,540 --> 01:35:58,760 functions called meow or anything else that lines up perfectly with what we did 1647 01:35:58,760 --> 01:36:02,060 in Scratch. We'll take some time to get comfy with the syntax and remember it, 1648 01:36:02,080 --> 01:36:05,600 have to look it up frequently for reference. But let's go ahead and 1649 01:36:05,600 --> 01:36:08,120 this. If I go back to VS Code, clear my screen, 1650 01:36:08,880 --> 01:36:10,540 let me hide my terminal window temporarily. 1651 01:36:10,860 --> 01:36:13,580 Let me go ahead and invent this meow function. 1652 01:36:14,140 --> 01:36:17,920 Per the code earlier, I'm going to go ahead and do this. 1653 01:36:20,060 --> 01:36:21,820 void meow void. 1654 01:36:22,160 --> 01:36:26,440 And again, the two voids mean no input, no output. It just does one thing well. 1655 01:36:27,060 --> 01:36:30,720 Printf quote unquote meow backslash n. 1656 01:36:31,000 --> 01:36:34,940 And now down here, I can use a for loop. So for, and I know this from memory, 1657 01:36:35,040 --> 01:36:40,580 int i equals 0, i less than 3, i plus plus. And then inside of curly braces, 1658 01:36:40,580 --> 01:36:42,160 going to go ahead and call the meow function. 1659 01:36:42,680 --> 01:36:47,830 Notice When I'm creating the function up here, I explicitly, pedantically say 1660 01:36:47,830 --> 01:36:49,530 void, void, no input, no output. 1661 01:36:49,790 --> 01:36:54,770 When I use the function on line 13, you just say open parenthesis, close 1662 01:36:54,770 --> 01:36:57,810 parenthesis. That's the equivalent of a scratch puzzle piece without a white 1663 01:36:57,810 --> 01:37:00,770 oval. You just put nothing there. You don't put the word void. 1664 01:37:01,570 --> 01:37:03,770 So that's it. Let me open my terminal window. 1665 01:37:04,010 --> 01:37:10,370 Let me run make cat to recompile dot slash cat. And I think I have a working 1666 01:37:10,370 --> 01:37:11,980 cat. Now, this is correct. 1667 01:37:12,180 --> 01:37:16,040 The only thing I don't love about this version, if I hide my terminal window, 1668 01:37:16,040 --> 01:37:20,280 that when I start writing bigger and bigger programs, it'd be nice if my main 1669 01:37:20,280 --> 01:37:25,660 function which I told you to take on faith for today, is at the top of the 1670 01:37:25,760 --> 01:37:28,860 If only because literally the name main means this is the main part of my 1671 01:37:28,860 --> 01:37:31,100 program, it'd be nice if it's the first thing I see. 1672 01:37:31,540 --> 01:37:36,220 Which is to say, just to be pedantic, it's very common to put any functions 1673 01:37:36,220 --> 01:37:40,100 write at the bottom of your file, maybe alphabetically, maybe organized some 1674 01:37:40,100 --> 01:37:40,978 other way. 1675 01:37:40,980 --> 01:37:44,880 But you put main first by convention, just like the when the green flag 1676 01:37:44,940 --> 01:37:47,040 It was the first thing you always started with last week. 1677 01:37:47,260 --> 01:37:50,060 But watch what happens now. If I go into my terminal window. 1678 01:37:50,670 --> 01:37:54,510 And Command or Control J is hiding and showing it if you are curious, but 1679 01:37:54,510 --> 01:37:58,030 probably you'll just leave it open on your own all the time. Let me do make 1680 01:37:58,030 --> 01:37:59,030 again. 1681 01:37:59,250 --> 01:38:03,670 And huh, I've screwed up somehow. All I did was move the meow function from top 1682 01:38:03,670 --> 01:38:08,310 to bottom, and I'm getting call to undeclared function meow something, 1683 01:38:08,410 --> 01:38:09,410 something, something. 1684 01:38:09,490 --> 01:38:10,770 Well, what's going on? 1685 01:38:11,050 --> 01:38:13,230 Well, C is pretty naive and simplistic. 1686 01:38:13,490 --> 01:38:15,730 It's only going to do what you tell it to do, and it's only going to do things 1687 01:38:15,730 --> 01:38:19,990 top to bottom, left to right. And unfortunately, on line 8, you are 1688 01:38:20,670 --> 01:38:22,050 call a function called meow. 1689 01:38:22,470 --> 01:38:24,850 But that does not exist in CS50's header file. 1690 01:38:25,090 --> 01:38:28,550 That does not exist in standard IO's header file. It exists at the bottom of 1691 01:38:28,550 --> 01:38:31,910 file, at which point it's too late, because I'm trying to use it before it 1692 01:38:31,910 --> 01:38:36,490 exists. So I could just undo that and put this meow function at the top of the 1693 01:38:36,490 --> 01:38:39,470 file. But you're going to eventually get into a perverse scenario where you 1694 01:38:39,470 --> 01:38:42,830 can't put all of your functions above all of your functions. You've got to 1695 01:38:42,830 --> 01:38:47,350 a lane at some point. So the solution to this, albeit a little weird and the one 1696 01:38:47,350 --> 01:38:48,350 time 1697 01:38:48,620 --> 01:38:54,240 in CS50 and programming that it is encouraged and necessary to copy -paste 1698 01:38:54,240 --> 01:38:59,220 what you can do at the top of your code above main is just copy -paste the first 1699 01:38:59,220 --> 01:39:01,400 line of your own function. 1700 01:39:01,620 --> 01:39:06,240 This is the so -called prototype of the function, and it simply describes how to 1701 01:39:06,240 --> 01:39:07,240 use the function. 1702 01:39:07,460 --> 01:39:14,120 And funny enough, we actually saw this earlier, but I sort of swept it under 1703 01:39:14,120 --> 01:39:15,160 rug a moment ago. 1704 01:39:15,790 --> 01:39:20,150 Or a bit ago, when we looked at standardio .h and we looked at the 1705 01:39:20,150 --> 01:39:23,650 function in the manual pages, I highlighted the header file. 1706 01:39:24,060 --> 01:39:28,680 But I also glossed over the so -called prototype, which is, sorry, the first 1707 01:39:28,680 --> 01:39:33,280 line of the printf function, just as this is the first line of my meow 1708 01:39:33,560 --> 01:39:37,540 This is like a little clue. This is like saying to see, hey, there's going to be 1709 01:39:37,540 --> 01:39:42,060 a function called meow that takes no input, has no input, takes no input, has 1710 01:39:42,060 --> 01:39:44,500 output. Just know that it exists eventually. 1711 01:39:45,020 --> 01:39:47,300 And that will satisfy the compiler. 1712 01:39:47,520 --> 01:39:52,200 Because if I go back to my terminal, rerun make cat, it now knows on face, 1713 01:39:52,200 --> 01:39:54,830 line four, this function will eventually exist. 1714 01:39:55,130 --> 01:39:59,370 And indeed, once it gets to the bottom of my code line, 14 onward, there it in 1715 01:39:59,370 --> 01:40:04,210 fact is. So you just copy the one and only first line of your function's code 1716 01:40:04,210 --> 01:40:05,230 the top called the prototype. 1717 01:40:05,450 --> 01:40:11,910 And now if I do dot slash cat, I get finally, meow, meow, meow, yet again in 1718 01:40:11,910 --> 01:40:12,910 this case. 1719 01:40:14,250 --> 01:40:16,290 Questions on these here cats? 1720 01:40:19,710 --> 01:40:20,710 No? All right. 1721 01:40:21,590 --> 01:40:24,850 Last flourish before I keep promising cookies that I promise they exist. 1722 01:40:25,420 --> 01:40:29,980 So last flourish, like just as we did in Scratch. So in Scratch, recall that we 1723 01:40:29,980 --> 01:40:34,480 parameterized our meow function by letting us tell meow how many times to 1724 01:40:34,480 --> 01:40:38,820 so that we didn't need to use our loop inside of our when green flag clicked 1725 01:40:38,820 --> 01:40:43,740 block. In other words, if I want to actually have the cat meow a specific 1726 01:40:43,740 --> 01:40:48,940 of times, I can actually go ahead and do that proactively with some of my own 1727 01:40:48,940 --> 01:40:54,280 code, such as this here in Scratch. When I edited my meow function last week in 1728 01:40:54,280 --> 01:40:58,410 Scratch, I specified that I want it now to take an input called n, which 1729 01:40:58,410 --> 01:40:59,730 represents some number of times. 1730 01:40:59,930 --> 01:41:04,790 And I changed my repeat block not to be 3 perpetually, but to actually have n 1731 01:41:04,790 --> 01:41:07,090 generally baked in there instead. 1732 01:41:07,310 --> 01:41:11,210 Or actually, instead of just saying place on meow, I had a repeat block 1733 01:41:11,210 --> 01:41:13,690 as the placeholder instead of a hard -coded 3. 1734 01:41:13,990 --> 01:41:16,170 So how can I now use this in C? 1735 01:41:16,390 --> 01:41:18,930 In C, it's almost the same. 1736 01:41:19,850 --> 01:41:23,850 It's still void at the beginning of my function name, which means no output 1737 01:41:23,850 --> 01:41:25,590 still. It only has side effects. 1738 01:41:25,810 --> 01:41:29,850 But what did change vis -a -vis the previous version of meow? 1739 01:41:31,350 --> 01:41:32,630 What has changed? 1740 01:41:34,330 --> 01:41:39,070 Exactly. Instead of saying void a second time in parentheses, it literally says 1741 01:41:39,070 --> 01:41:44,270 int n inside of those parentheses, which means in C, this function called meow 1742 01:41:44,810 --> 01:41:48,050 take input. It means the exact same thing as the pink on the left. And 1743 01:41:48,130 --> 01:41:52,130 this is why we keep emphasizing the scratch blocks. No new ideas with a lot 1744 01:41:52,130 --> 01:41:52,949 these features. 1745 01:41:52,950 --> 01:41:55,870 It's just different syntax that you'll get used to over time. 1746 01:41:56,210 --> 01:41:59,670 So if I go back into VS Code here and I change this function, let's do that. 1747 01:41:59,870 --> 01:42:03,870 Let's change my prototype to be int n, where n represents some number of times. 1748 01:42:04,090 --> 01:42:08,050 Let's change the actual function on line 14 to also have int n here. 1749 01:42:08,310 --> 01:42:14,290 And let's actually move the for loop from main into the meow function, such 1750 01:42:14,290 --> 01:42:15,850 I now have my curly braces here. 1751 01:42:16,390 --> 01:42:19,310 I have my print statement inside of those curly braces. 1752 01:42:19,570 --> 01:42:24,290 And now, in main, I can get rid of all of that code, just say meow. 1753 01:42:24,840 --> 01:42:28,480 any number of times, like three, and just like I did with Scratch, let me hit 1754 01:42:28,480 --> 01:42:32,580 Enter, an arbitrary number of times, sort of out of sight, out of mind, now 1755 01:42:32,580 --> 01:42:37,220 essence of my program is like one real line of code, meow three times, because 1756 01:42:37,220 --> 01:42:43,180 I've abstracted away the idea of meowing and told the cat instead exactly how 1757 01:42:43,180 --> 01:42:45,600 many times to meow by way of that function. 1758 01:42:47,240 --> 01:42:49,500 OK, I can't keep stringing along cookies so long. 1759 01:42:49,720 --> 01:42:52,820 Let's go ahead and take a 10 minute break here. And when we come back, more 1760 01:42:52,820 --> 01:42:53,820 cats, more code. 1761 01:42:55,150 --> 01:42:56,290 DAVID J. All right. 1762 01:42:57,250 --> 01:43:03,130 So we are back and want to add one final flourish to this program because now, 1763 01:43:03,250 --> 01:43:06,570 more so than a lot of the examples, now the programs are starting to grow in 1764 01:43:06,570 --> 01:43:09,810 length. And indeed, soon there'll be a few dozen lines of code, which is not 1765 01:43:09,810 --> 01:43:14,270 uncommon. But let's suppose that we want to stop hard coding three everywhere 1766 01:43:14,270 --> 01:43:18,870 and actually prompt the user for some number of meows here. Well, let me do 1767 01:43:18,870 --> 01:43:23,940 this. In VS Code, I'm going to go ahead and Get rid of this one line for now, 1768 01:43:24,080 --> 01:43:25,500 and let's do something like this. 1769 01:43:25,740 --> 01:43:31,540 Let's ask the user for an integer. So int, maybe n for number equals get int. 1770 01:43:32,090 --> 01:43:36,170 And we'll say something like just number to give a number of meows. And then 1771 01:43:36,170 --> 01:43:40,110 we'll go ahead and actually call meow, passing in not three this time, but 1772 01:43:40,110 --> 01:43:41,089 passing in n. 1773 01:43:41,090 --> 01:43:45,730 So we are using the return value of get int to store it in a variable called n 1774 01:43:45,730 --> 01:43:50,890 on line 8. And then we are passing n as the input or argument to the function 1775 01:43:50,890 --> 01:43:56,360 called meow on line 9. And again, the actual implementation of meow on line 22 1776 01:43:56,360 --> 01:44:00,100 onward, like who cares, out of sight, out of mind, once it exists. We can sort 1777 01:44:00,100 --> 01:44:03,560 of abstract it away mentally, but I'll keep it uptight here anyway. 1778 01:44:03,880 --> 01:44:08,140 All right, so let me go ahead and open my terminal window, make cath, dot slash 1779 01:44:08,140 --> 01:44:09,260 cath, number. 1780 01:44:09,540 --> 01:44:11,040 I can still type in three and it works. 1781 01:44:11,380 --> 01:44:17,060 Or I can go ahead and type in five, meow, meow, meow, but it's not actually 1782 01:44:17,060 --> 01:44:18,500 meowing five times. Why? 1783 01:44:20,260 --> 01:44:22,420 I didn't realize this either. But there's a bug. 1784 01:44:24,240 --> 01:44:28,300 DAVID J. Yeah, exactly. So the for loop, when I copy pasted it before, before 1785 01:44:28,300 --> 01:44:32,900 break, I actually kind of got lazy and I forgot to change the three to an n so 1786 01:44:32,900 --> 01:44:37,700 that it matches the name of the argument that's being passed into meow. 1787 01:44:37,940 --> 01:44:41,820 So that was a bug, unintentional on my part, but we have now fixed it here. And 1788 01:44:41,820 --> 01:44:44,860 now we are passing this in from main to meow. 1789 01:44:45,160 --> 01:44:47,820 So if I make cat dot slash cat. 1790 01:44:48,250 --> 01:44:53,070 And type 5 this time, I indeed get 5 meows. But it's worth noting there's 1791 01:44:53,070 --> 01:44:57,130 subtleties here in my code in that I've used n a couple of times. 1792 01:44:57,390 --> 01:45:03,070 So this is actually deliberate that I've used n twice in this way to induce a 1793 01:45:03,070 --> 01:45:04,029 bit of confusion. 1794 01:45:04,030 --> 01:45:10,460 But it turns out this n It's actually not the same as this n nor this one. So 1795 01:45:10,460 --> 01:45:13,720 what's going on here? Well, it turns out in programming, there's often this idea 1796 01:45:13,720 --> 01:45:14,478 of scope. 1797 01:45:14,480 --> 01:45:21,180 And long story short, generally speaking, variables only exist in the 1798 01:45:21,180 --> 01:45:25,480 which you create them. More down to earth, variables only exist inside of 1799 01:45:25,480 --> 01:45:27,700 curly braces in which you define them. 1800 01:45:27,960 --> 01:45:32,440 So for instance, suppose I got a little floppy, and suppose I didn't bother 1801 01:45:32,440 --> 01:45:37,660 giving meow an input, and I didn't bother giving its prototype an input, 1802 01:45:37,660 --> 01:45:39,820 just used n on line 14. 1803 01:45:40,040 --> 01:45:43,100 Because why? Well, I already defined n on line 8. 1804 01:45:43,500 --> 01:45:48,460 So this is just an alternate universe in which I'm not changing meow to take 1805 01:45:48,460 --> 01:45:54,480 input. I'm just using n in two different functions. In main, on line 8 and 9. 1806 01:45:54,680 --> 01:45:57,580 Actually, I don't even need that. On line 8 and 9. 1807 01:45:58,140 --> 01:45:59,740 And also, again, on line 14. 1808 01:45:59,980 --> 01:46:03,900 This code will not work. The compiler will not like this. Why? 1809 01:46:04,160 --> 01:46:09,720 Because n does not exist inside of meow. Why? Per the heuristic I offered, n 1810 01:46:09,720 --> 01:46:13,800 exists only inside of the curly braces in which it was defined, namely these 1811 01:46:13,800 --> 01:46:14,860 curly braces here. 1812 01:46:15,080 --> 01:46:18,020 So n is in scope in main, so to speak. 1813 01:46:18,380 --> 01:46:20,000 But it is not in scope in meow. 1814 01:46:20,260 --> 01:46:24,200 And that's why we kind of have to jump through these hoops and use inputs and 1815 01:46:24,200 --> 01:46:28,780 outputs and inputs and outputs and pass things around among functions without 1816 01:46:28,780 --> 01:46:31,300 sort of sharing things across functions instead. 1817 01:46:31,620 --> 01:46:37,150 Now, I could clarify this and maybe change my argument here from n to times. 1818 01:46:37,550 --> 01:46:41,890 If I want to make clear that, oh, this is the number of times I want meow to be 1819 01:46:41,890 --> 01:46:46,850 said, I don't have to use n for both. But just realize that if you do, it's 1820 01:46:46,850 --> 01:46:47,688 a coincidence. 1821 01:46:47,690 --> 01:46:50,830 They are not usable in two different scopes. 1822 01:46:51,390 --> 01:46:58,010 All right. Let's do one other thing, though. Let's not only prompt the user 1823 01:46:58,010 --> 01:47:01,130 the number here. Let's make sure that it makes sense what number they give us. 1824 01:47:01,190 --> 01:47:04,890 So if I do make cat, just to clean things up, dot slash cat, suppose I type 1825 01:47:05,520 --> 01:47:09,420 OK, I suppose that's correct. If I say meow zero times and it doesn't meow at 1826 01:47:09,420 --> 01:47:10,460 all, that's arguably correct. 1827 01:47:10,740 --> 01:47:14,680 But if I type in something like negative 5, it ignores me, which I guess is 1828 01:47:14,680 --> 01:47:18,620 better than crashing or freezing or something. But ideally, it might be nice 1829 01:47:18,620 --> 01:47:19,620 handle this situation. 1830 01:47:19,760 --> 01:47:23,840 And if they give me a negative number, prompt them again for a positive number. 1831 01:47:23,920 --> 01:47:26,720 Prompt them again for a positive number. Make the program make sense. 1832 01:47:27,080 --> 01:47:29,200 So how could we do that? Well, a couple of ways. 1833 01:47:29,640 --> 01:47:35,360 If I go back into my code here, I could do this. I could maybe do something like 1834 01:47:35,360 --> 01:47:42,300 a loop, or let's see. So if I get n, so if n is less than 1, then 1835 01:47:42,300 --> 01:47:46,920 it makes no sense. So what do I want to do if n is less than Well, I could just 1836 01:47:46,920 --> 01:47:49,660 prompt the user again. And I'd say, OK, let's get n again. 1837 01:47:49,900 --> 01:47:54,120 And then I can say, if n is less than 1, what do I want to do? I guess we could 1838 01:47:54,120 --> 01:47:55,120 ask the user again. 1839 01:47:55,580 --> 01:48:01,340 And then if n is less than 1, I could just, again, I can give them three 1840 01:48:01,480 --> 01:48:05,080 four tries to get this right. This is obviously stupid. I'm copying and 1841 01:48:05,120 --> 01:48:06,120 I'm repeating myself. 1842 01:48:06,200 --> 01:48:07,320 There's no end in sight. 1843 01:48:07,540 --> 01:48:08,980 I can't do this forever, surely. 1844 01:48:09,240 --> 01:48:11,120 So this just feels like the wrong solution. 1845 01:48:11,710 --> 01:48:15,570 So there are different ways to solve this problem. And funny enough, a while 1846 01:48:15,570 --> 01:48:21,850 loop is not really the best way. A do while loop is not the best way. A for 1847 01:48:21,850 --> 01:48:25,130 is not the best way. It turns out there's one other type of loop that we 1848 01:48:25,130 --> 01:48:30,150 to introduce that's super useful for getting user input potentially again and 1849 01:48:30,150 --> 01:48:32,130 again and again so that the user cooperates. 1850 01:48:32,510 --> 01:48:33,950 Specifically, what I'm going to do is this. 1851 01:48:34,370 --> 01:48:39,670 I'm going to literally say do the following while something is true. 1852 01:48:40,160 --> 01:48:43,820 So it's more of a mouthful. I'm spreading it out over multiple lines. 1853 01:48:43,820 --> 01:48:48,640 am I going to put inside of the do block here? I'm going to say int n equals get 1854 01:48:48,640 --> 01:48:53,940 int and ask for that number as before, close quote semicolon. And I'm going to 1855 01:48:53,940 --> 01:49:00,900 keep asking while, sorry, accidental enter, while n is less than 1856 01:49:00,900 --> 01:49:05,200 1 semicolon. So notice the semantics of this. Even though it's a little weird 1857 01:49:05,200 --> 01:49:08,400 looking, it does read in English, do the following. 1858 01:49:08,920 --> 01:49:13,360 OK, get an int stored in n, and keep doing that while n is less than 1. 1859 01:49:13,600 --> 01:49:16,880 But this code, as written, is not quite going to work yet. 1860 01:49:17,260 --> 01:49:20,580 Let me try opening my terminal window, make cat enter. 1861 01:49:21,360 --> 01:49:24,900 Ugh, damn it. Like, use of undeclared identifier n. 1862 01:49:25,120 --> 01:49:26,480 Well, here's where the line number is helpful. 1863 01:49:26,800 --> 01:49:30,300 The line number is indicated here, 12, and it's repeated here, 12. 1864 01:49:30,540 --> 01:49:32,220 So I clearly screwed up at line 12. 1865 01:49:32,540 --> 01:49:34,660 There's not that much going on at line 12. 1866 01:49:35,220 --> 01:49:37,940 Why is n undeclared? 1867 01:49:38,620 --> 01:49:42,400 in line 12, even though I literally just declared it in line 10. 1868 01:49:48,100 --> 01:49:53,040 Exactly, because I declared n inside the scope of the do block, so to speak, 1869 01:49:53,100 --> 01:49:55,100 inside the curly braces on lines 9 and 11. 1870 01:49:55,500 --> 01:50:00,380 That variable n no longer exists by the time we get to line 12. It'd be great if 1871 01:50:00,380 --> 01:50:03,500 it did, but it doesn't, because it violates that heuristic I proposed, 1872 01:50:03,500 --> 01:50:07,860 that variables only exist in the scope of the curly braces in which they were 1873 01:50:07,860 --> 01:50:14,100 defined. So how do I fix this? Well, it turns out you can declare a variable in 1874 01:50:14,100 --> 01:50:18,300 advance. outside of one scope, but then define it, that is, initialize it 1875 01:50:18,300 --> 01:50:20,320 elsewhere. So the solution here is actually this. 1876 01:50:20,560 --> 01:50:26,460 Inside of the loop, just set n equal to the return value of get int. But per the 1877 01:50:26,460 --> 01:50:32,440 heuristic, you've got to declare n, make it exist inside of the outermost scope 1878 01:50:32,440 --> 01:50:33,440 of this function. 1879 01:50:33,660 --> 01:50:36,740 So it's a little weird, and we're kind of breaking this down into two steps, 1880 01:50:36,740 --> 01:50:38,920 this is valid, recommended, correct. 1881 01:50:39,260 --> 01:50:39,898 C code. 1882 01:50:39,900 --> 01:50:42,940 You declare a variable without giving it any value initially. 1883 01:50:43,240 --> 01:50:48,660 And then in line 11, you proceed to give it a value, potentially again and again 1884 01:50:48,660 --> 01:50:49,660 and again. 1885 01:50:49,680 --> 01:50:53,580 Now, what's useful about a do while loop? So a do while loop, as the name 1886 01:50:53,580 --> 01:50:57,720 implies, will do something no matter what. But it will potentially do it 1887 01:50:57,720 --> 01:51:04,640 and again and again while some question is true, like n being less than 1 in 1888 01:51:04,640 --> 01:51:05,640 this case. 1889 01:51:05,890 --> 01:51:10,090 All right, as an aside, why did we not do a while loop? Well, let's think about 1890 01:51:10,090 --> 01:51:15,470 that. While n is less than 1, but wait a minute, n doesn't have a value. 1891 01:51:15,690 --> 01:51:20,510 OK, so I guess we have to go back to doing get int number colon semicolon. 1892 01:51:20,570 --> 01:51:24,590 but while n is less than 1, we're back to the same problem where we have to 1893 01:51:24,590 --> 01:51:27,930 repeat ourselves again. So this is why for loops, while loops. 1894 01:51:28,330 --> 01:51:31,570 Not the right solution when you want to do something at least once, but 1895 01:51:31,570 --> 01:51:36,070 potentially again and again. So the right solution here, again, is this new 1896 01:51:36,070 --> 01:51:40,750 final looping construct. I'm just hitting Control -Z a lot, whereby we've 1897 01:51:40,750 --> 01:51:41,750 it as follows. 1898 01:51:41,790 --> 01:51:43,190 All right, let's try this. Clear the screen. 1899 01:51:43,390 --> 01:51:44,450 Make CAS. 1900 01:51:44,670 --> 01:51:46,210 Enter. Dot slash CAS. 1901 01:51:46,450 --> 01:51:47,450 Let's type in 5. 1902 01:51:47,790 --> 01:51:52,130 Still works. Let's type in negative 5. And notice, it doesn't just ignore me. 1903 01:51:52,130 --> 01:51:56,350 prompts me again and again and again. Even if I type in 0, I've got to at 1904 01:51:56,350 --> 01:51:58,110 give it a positive integer. 1905 01:51:58,550 --> 01:52:01,810 Well, this actually seems like kind of a common paradigm. Like, what if we want 1906 01:52:01,810 --> 01:52:04,950 to prompt the user for a positive number in other programs, too? 1907 01:52:05,270 --> 01:52:08,190 We're nearing the point already, even after just week one, it would be nice to 1908 01:52:08,190 --> 01:52:12,130 write our own reusable functions that solve common problems. And eventually, 1909 01:52:12,130 --> 01:52:16,810 maybe we can put them in header files as well. But for now, let's go ahead and 1910 01:52:16,810 --> 01:52:20,070 do this. I'm going to actually copy all of this code. And I'm going to create 1911 01:52:20,070 --> 01:52:26,690 one more function in this file below main called get positive int for 1912 01:52:26,950 --> 01:52:31,210 And I'm going to specify that it doesn't need any input, because the only thing 1913 01:52:31,210 --> 01:52:33,550 this function is going to do is that exact same thing. 1914 01:52:33,870 --> 01:52:38,290 So notice that I've just moved my code from main into a function that's name 1915 01:52:38,290 --> 01:52:40,710 describes what it does, get positive int. 1916 01:52:41,160 --> 01:52:42,200 I'm declaring n here. 1917 01:52:42,420 --> 01:52:43,640 I'm doing this again and again. 1918 01:52:43,860 --> 01:52:46,040 And I'm doing that while n is less than 1. 1919 01:52:46,320 --> 01:52:47,700 And what am I going to do up here? 1920 01:52:48,080 --> 01:52:51,700 I can do something like this. Give me a variable called times for how many times 1921 01:52:51,700 --> 01:52:55,780 you want to meow, and just call get positive int. 1922 01:52:56,300 --> 01:52:59,520 Let me call in. So now, again, we've abstracted things away. And just like in 1923 01:52:59,520 --> 01:53:03,210 Scratch, our final example, which we're called looked a little something like 1924 01:53:03,210 --> 01:53:07,150 this, where we just called a function to meow three times. Now we're calling a 1925 01:53:07,150 --> 01:53:11,390 function to getText. If I hit Enter an arbitrary dramatic number of times, out 1926 01:53:11,390 --> 01:53:14,850 of sight, out of mind, I now have two functions in this world, getPositiveInt 1927 01:53:14,850 --> 01:53:18,970 and meow that are collectively implementing this entire program. 1928 01:53:19,390 --> 01:53:21,050 But it's not quite correct. 1929 01:53:21,670 --> 01:53:23,590 There's one mistake here still. 1930 01:53:24,190 --> 01:53:29,810 Notice that getPositiveInt is written slightly differently from the meow 1931 01:53:29,810 --> 01:53:34,350 function. And just to be clear, too, let me copy its prototype to the top of the 1932 01:53:34,350 --> 01:53:37,270 file, just so we don't make that same mistake I made earlier where I didn't 1933 01:53:37,270 --> 01:53:39,430 the prototype at top, so C didn't know what it was. 1934 01:53:40,230 --> 01:53:43,170 What is different about these two prototypes at a glance? 1935 01:53:44,330 --> 01:53:45,330 Yeah? 1936 01:53:46,390 --> 01:53:47,390 GetPositiveInt. 1937 01:53:47,950 --> 01:53:51,710 Okay, so GetPositiveInt apparently, and we've not talked much about this, 1938 01:53:51,830 --> 01:53:53,630 apparently does have an output. 1939 01:53:54,160 --> 01:53:55,160 of type integer. 1940 01:53:55,180 --> 01:53:58,660 It's supposed to return an int, hand me back an int. It doesn't have any input. 1941 01:53:58,920 --> 01:54:00,580 That's what the void in parentheses meant. 1942 01:54:01,050 --> 01:54:06,230 No input, but yes output. And meow, funny enough, is the opposite. Yes 1943 01:54:06,230 --> 01:54:09,610 output. Why? Because it has a side effect, the visual thing, where it 1944 01:54:09,610 --> 01:54:13,350 something to the screen but doesn't hand me any useful value back like the ask 1945 01:54:13,350 --> 01:54:15,150 function or the ask puzzle piece did. 1946 01:54:15,390 --> 01:54:19,010 So these are sort of opposite in functionality, which means I actually 1947 01:54:19,010 --> 01:54:24,250 return an integer from this function to whatever function wants to use it. 1948 01:54:24,810 --> 01:54:29,370 So if I want the assignment operator to work here on line 9, I need to do what 1949 01:54:29,370 --> 01:54:33,490 all this time get int, get string, and other CS50 functions have been doing. I 1950 01:54:33,490 --> 01:54:39,090 need to, in my own function, return that value, literally with a new keyword 1951 01:54:39,090 --> 01:54:39,989 called return. 1952 01:54:39,990 --> 01:54:43,250 And this is why I keep sticking out my hand. When you want a function to hand 1953 01:54:43,250 --> 01:54:47,850 you back a value, you literally use return and then that value. 1954 01:54:48,070 --> 01:54:52,850 That's why we have return value as a term of art, literally this return 1955 01:54:53,770 --> 01:54:56,770 So if I open my terminal window now, make cat enter, 1956 01:54:57,890 --> 01:54:59,850 huh, I did screw up accidentally. 1957 01:55:00,830 --> 01:55:01,950 How? Yeah. 1958 01:55:03,430 --> 01:55:07,650 Yeah, so on lines 9 and 10, I made a quick change. I changed my variable to 1959 01:55:07,650 --> 01:55:11,370 times, but I stupidly didn't change this. So that's fine. That's why n was 1960 01:55:11,370 --> 01:55:12,510 undeclared in that context. 1961 01:55:12,870 --> 01:55:15,070 Let me clear my terminal. Make cat once more. 1962 01:55:15,270 --> 01:55:17,870 OK, that worked. Dot slash cat. Let's type in 5. 1963 01:55:18,330 --> 01:55:19,330 And it's still working. 1964 01:55:19,430 --> 01:55:24,310 So again, even though the code is kind of growing and growing and growing, it's 1965 01:55:24,310 --> 01:55:29,150 the exact same program we wrote super simply before break. But now we're sort 1966 01:55:29,150 --> 01:55:31,850 modularizing it. We're creating reusable functions. 1967 01:55:32,170 --> 01:55:35,810 And this is why functions like getStringExists, getIntExists, like CS50 1968 01:55:35,810 --> 01:55:36,810 those years ago. 1969 01:55:36,890 --> 01:55:40,290 And we realized, why are we copying and pasting these functions in all of these 1970 01:55:40,290 --> 01:55:41,510 different CS50 programs? 1971 01:55:41,730 --> 01:55:46,130 Let's factor out that functionality into a function of our own. Get int, get 1972 01:55:46,130 --> 01:55:50,070 string. Just like here, I'm proposing to factor out this functionality. 1973 01:55:50,310 --> 01:55:53,810 Get a positive integer that gives you even more precise functionality. 1974 01:55:54,090 --> 01:55:58,670 So theoretically, you could use and reuse it in other programs, too. By not 1975 01:55:58,670 --> 01:56:02,310 just putting it here, we could go put it in a file of your own name. 1976 01:56:02,730 --> 01:56:07,090 and include it in future programs as well. That's all a library is. Someone 1977 01:56:07,090 --> 01:56:10,850 realized, gee, other people, including myself, might find this function useful 1978 01:56:10,850 --> 01:56:11,970 again and again. 1979 01:56:12,210 --> 01:56:17,150 Let's package it up in our own custom function, just like our custom meow 1980 01:56:17,150 --> 01:56:20,810 piece last week, so we can indeed use it again and again. 1981 01:56:21,030 --> 01:56:24,950 And the takeaways for now is that unlike Scratch, which was a little more user 1982 01:56:24,950 --> 01:56:28,810 friendly, in C, you have to specify if you want your functions to have inputs, 1983 01:56:28,930 --> 01:56:30,970 and you must specify if you want them to have 1984 01:56:31,740 --> 01:56:32,740 outputs as well. 1985 01:56:33,080 --> 01:56:34,800 But more on that syntax to come. 1986 01:56:35,500 --> 01:56:39,620 So where does that bring us? So after all this discussion of code, at the end 1987 01:56:39,620 --> 01:56:42,080 the day, this is what's important in the world of programming. 1988 01:56:42,500 --> 01:56:45,680 Not surprisingly, it's what's important when it comes to grading and evaluating 1989 01:56:45,680 --> 01:56:46,760 the quality of code. 1990 01:56:46,980 --> 01:56:50,000 One, and first and foremost, is correctness. If the code does not do 1991 01:56:50,000 --> 01:56:52,940 supposed to do, what was the point of writing the code? So correctness sort of 1992 01:56:52,940 --> 01:56:53,940 goes without saying. 1993 01:56:54,280 --> 01:56:55,780 Design, again, is much more qualitative. 1994 01:56:56,060 --> 01:56:57,960 It's like getting feedback again on an English essay. 1995 01:56:58,410 --> 01:57:01,750 Where reasonable people might disagree, you can make your argument better. You 1996 01:57:01,750 --> 01:57:05,830 can structure the paper better. You can structure the code better in the case of 1997 01:57:05,830 --> 01:57:08,250 programming. And style is purely aesthetic. 1998 01:57:08,610 --> 01:57:12,050 Does it look good? Is it pretty printed, so to speak? Can other people, 1999 01:57:12,170 --> 01:57:16,130 colleagues, future, and classmates present actually read and understand it? 2000 01:57:16,230 --> 01:57:17,730 That's what we mean by style. 2001 01:57:18,090 --> 01:57:22,410 Nicely enough, within CS50's programming environment, you will have tools to 2002 01:57:22,410 --> 01:57:26,590 evaluate the quality of all three of these axes, so to speak. So in problem 2003 01:57:26,590 --> 01:57:30,090 one onward, you'll be introduced to a command line tool that you type its name 2004 01:57:30,090 --> 01:57:33,630 at the prompt called check 50 that will check for you the correctness of your 2005 01:57:33,630 --> 01:57:37,690 code. Not necessarily exhaustively, like there might be mistakes you've made 2006 01:57:37,690 --> 01:57:41,770 that we don't catch, which doesn't make your code correct, but it is a tool for 2007 01:57:41,770 --> 01:57:45,350 finding many of the mistakes in your code. In the real world, you would have 2008 01:57:45,350 --> 01:57:49,150 colleagues or yourself would write tests for code you wrote or someone else 2009 01:57:49,150 --> 01:57:50,150 wrote. 2010 01:57:51,250 --> 01:57:55,270 It is a real -world thing to ensure that systems are designed to work. 2011 01:57:55,910 --> 01:58:00,330 We saw the Style 50 tool in VS Code already. You click the Style 50 button. 2012 01:58:00,470 --> 01:58:04,450 There is now, thanks to the duck, a Design 50 button, too, also in that top 2013 01:58:04,450 --> 01:58:08,870 right -hand corner, whereby once your code is correct and working, like 2014 01:58:08,870 --> 01:58:12,390 of my programs have been, you can click Design 50, and the duck will not just 2015 01:58:12,390 --> 01:58:16,590 quack, but give you qualitative advice, if it can, on how you can make that code 2016 01:58:16,590 --> 01:58:20,370 even better, even before you submit. And of course, there's all of us humans in 2017 01:58:20,370 --> 01:58:23,190 the room and online that you can ask these same questions of. 2018 01:58:23,610 --> 01:58:24,610 as well. 2019 01:58:24,770 --> 01:58:29,550 So let's now solve some sort of real world but still simple problems as 2020 01:58:29,550 --> 01:58:34,350 to emphasizing small bite size as we have thus far. So the first of these 2021 01:58:34,350 --> 01:58:37,450 programs falls into this category. It's having side effects. So let's implement 2022 01:58:37,450 --> 01:58:41,210 one or more functions that takes an argument's input and as its output 2023 01:58:41,210 --> 01:58:45,280 these visual side effects. We'll draw inspiration from Super Mario Brothers, 2024 01:58:45,280 --> 01:58:48,500 surprisingly, perhaps here. The original one, which was very two -dimensional, 2025 01:58:48,640 --> 01:58:51,820 side scroller, left to right, Mario or Luigi move from left to right, and 2026 01:58:51,820 --> 01:58:55,660 generally have to jump over things like pyramids or other shapes on the screen. 2027 01:58:56,040 --> 01:59:00,720 So how might we go about implementing some of the screens from Super Mario 2028 01:59:00,720 --> 01:59:04,040 Brothers, albeit textually? Well, we'll make it a little black and white and 2029 01:59:04,040 --> 01:59:07,080 ASCII art, so to speak, here using just our keyboard. 2030 01:59:07,300 --> 01:59:08,860 But suppose we want to write a program. 2031 01:59:09,470 --> 01:59:13,350 called mario .c that just prints out four question marks. It's not going to 2032 01:59:13,350 --> 01:59:16,790 nearly as pretty as what's on the screen here, but the logic is going to be the 2033 01:59:16,790 --> 01:59:19,810 exact same as what Nintendo presumably did years ago. 2034 01:59:20,090 --> 01:59:24,530 So let me open VS Code, my terminal window. Let's code a program called 2035 01:59:24,530 --> 01:59:28,850 .c. In mario .c, I'm going to kind of start with some boilerplate. I know I 2036 01:59:28,850 --> 01:59:31,630 to print, so even if I don't know how to do this yet, I'm going to include 2037 01:59:31,630 --> 01:59:32,790 standardio .h. 2038 01:59:33,070 --> 01:59:36,690 For today's purposes, I'm going to copy, paste, or type out that same line again 2039 01:59:36,690 --> 01:59:37,750 and again, int main void. 2040 01:59:38,240 --> 01:59:43,060 And inside of my main function, akin to the green flag being clicked, I want to 2041 01:59:43,060 --> 01:59:46,640 go ahead and print out four question marks. Well, honestly, the simplest way 2042 01:59:46,640 --> 01:59:50,060 can think of doing this is with printf, question mark, question mark, question 2043 01:59:50,060 --> 01:59:53,500 mark, question mark, maybe a backslash n to move the cursor, and that's it. 2044 01:59:53,850 --> 01:59:55,290 So that is arguably correct. 2045 01:59:55,530 --> 01:59:58,730 So let's do make Mario in the terminal, dot slash Mario. 2046 01:59:58,990 --> 02:00:03,330 And it's not quite as pretty as the game version of it, but it is, in fact, the 2047 02:00:03,330 --> 02:00:04,330 exact same idea. 2048 02:00:04,490 --> 02:00:08,030 But here's sort of an opportunity, stepping stone, to do better design. 2049 02:00:08,470 --> 02:00:11,590 Like this game changes over time, and not all of the screens have just four 2050 02:00:11,590 --> 02:00:14,130 question marks. It might be five, six, or even more. 2051 02:00:14,470 --> 02:00:18,050 So what's the right programming construct with which we could generalize 2052 02:00:18,050 --> 02:00:19,590 many question marks are printing here? 2053 02:00:20,390 --> 02:00:22,150 Like what feature of C do we want? 2054 02:00:23,910 --> 02:00:27,110 Like a loop, like a for loop, a while loop, or something like that. And 2055 02:00:27,110 --> 02:00:31,130 different ways to do this. But honestly, I proposed earlier that we get into the 2056 02:00:31,130 --> 02:00:33,670 habit of reaching for for loops as just very conventional. 2057 02:00:33,970 --> 02:00:39,830 So let's do that. For int i equals 0, i less than 4, because that's how many I 2058 02:00:39,830 --> 02:00:44,030 want for the moment, i plus plus. And then inside of my curly braces there, 2059 02:00:44,130 --> 02:00:49,170 let's go ahead and print out, quote unquote, a single question mark, but no 2060 02:00:49,170 --> 02:00:50,170 line. 2061 02:00:50,190 --> 02:00:52,030 Let me now go ahead and make Mario. 2062 02:00:52,700 --> 02:00:57,860 And can you anticipate a arguably aesthetic bug when I hit Enter? 2063 02:00:58,060 --> 02:01:01,440 It's not going to move the cursor to the next line. 2064 02:01:01,700 --> 02:01:06,240 But the solution here is a little non -obvious. I don't think this helps me. 2065 02:01:06,240 --> 02:01:10,160 I put the backslash n there and I do make Mario again and dot slash Mario, 2066 02:01:10,160 --> 02:01:11,600 is this output going to look like instead? 2067 02:01:13,290 --> 02:01:17,030 Yeah, like a vertical column of question marks, which, while nice enough, is not 2068 02:01:17,030 --> 02:01:19,590 the goal at hand. The goal is these horizontal ones. 2069 02:01:19,810 --> 02:01:23,850 So someone else, what's the fix here? It's clearly putting the backslash in 2070 02:01:23,850 --> 02:01:25,570 inside of line 7 is wrong. 2071 02:01:28,070 --> 02:01:32,430 Yeah, so put it after the loop, and not after the printf line specifically. 2072 02:01:33,200 --> 02:01:37,960 after and thus outside of the loop so that after that loop is finished 2073 02:01:37,960 --> 02:01:42,640 three total times, it's totally fine to just print nothing other than a 2074 02:01:42,640 --> 02:01:46,920 backslash n so long as we now recompile the code, make Mario, dot slash Mario, 2075 02:01:47,120 --> 02:01:47,978 and voila. 2076 02:01:47,980 --> 02:01:50,700 Now we have four in a row. It's a little generalized. 2077 02:01:50,920 --> 02:01:53,760 OK, so we've sort of plucked off a fairly easy problem. 2078 02:01:54,000 --> 02:01:56,860 Well, let's go back to the world of Mario and try something that is, in 2079 02:01:56,860 --> 02:02:00,480 vertical like this. So this is another scene with three bricks here. Instead of 2080 02:02:00,480 --> 02:02:03,900 using question marks, we'll use hash symbols to represent bricks. This 2081 02:02:03,900 --> 02:02:08,020 is the incarnation of my mistake a moment ago. 2082 02:02:08,260 --> 02:02:10,400 So let me undo this by getting rid of that printf. 2083 02:02:10,920 --> 02:02:15,080 Let me change the inside one from a question mark to a hash symbol, which 2084 02:02:15,080 --> 02:02:17,220 most similar in ASCII to a brick. 2085 02:02:17,770 --> 02:02:19,890 And let's go ahead and put in backslash n after that. 2086 02:02:20,170 --> 02:02:24,710 If I do go ahead and do make Mario, dot slash Mario, it's not that interesting. 2087 02:02:24,730 --> 02:02:27,390 But, and it's actually not that correct, because I wanted three. 2088 02:02:27,850 --> 02:02:28,850 So no big deal. 2089 02:02:28,990 --> 02:02:32,450 I can, of course, go back to my code and change the four to a three. Or better 2090 02:02:32,450 --> 02:02:36,850 yet, I could use get int or my new get positive int function and just 2091 02:02:36,850 --> 02:02:41,530 this further so that I can print out any number of them. But for now, dot slash 2092 02:02:41,530 --> 02:02:42,750 Mario gives me three. 2093 02:02:43,310 --> 02:02:45,750 All right, so we've plucked off the second of two problems. 2094 02:02:46,030 --> 02:02:49,790 Let's now let things escalate a bit. So it turns out once you get to like world 2095 02:02:49,790 --> 02:02:53,550 two and beyond, there's some underground parts of Mario where you actually have 2096 02:02:53,550 --> 02:02:55,990 bigger, more solid bricks like these here. 2097 02:02:56,210 --> 02:02:59,870 And just by eyeballing it, this is like a three by three grid of bricks. Like 2098 02:02:59,870 --> 02:03:04,070 nine of them total will conjecture. So how can I go about implementing this? 2099 02:03:04,330 --> 02:03:06,770 Well, now is where the program gets a little more interesting. 2100 02:03:07,270 --> 02:03:12,690 And the poorly designed way to do this would be like, 2101 02:03:13,660 --> 02:03:20,320 printf, hash, hash, hash, backslash n, semicolon, and then maybe printf, 2102 02:03:20,360 --> 02:03:25,500 printf. That's kind of correct, but not well -designed. So make Mario, dot slash 2103 02:03:25,500 --> 02:03:29,460 Mario. It doesn't look like a square, just because these hashes are more 2104 02:03:29,460 --> 02:03:30,860 vertical than they are horizontal. 2105 02:03:31,080 --> 02:03:34,940 But it is correct, this example. But it's not very generalizable. And this is 2106 02:03:34,940 --> 02:03:38,720 literally hard coding. I copy -paste. And I'm just doing a lot of bad 2107 02:03:38,720 --> 02:03:40,580 here. So what could I do instead? 2108 02:03:40,960 --> 02:03:45,460 Well, it turns out we can combine today's ideas, including loops, to do 2109 02:03:45,460 --> 02:03:46,460 again and again. 2110 02:03:46,840 --> 02:03:50,120 So what is this grid of bricks? 2111 02:03:50,400 --> 02:03:51,400 It's a three by three. 2112 02:03:51,540 --> 02:03:55,920 So it's like a row and a row and a row. 2113 02:03:56,200 --> 02:03:58,240 And then within each row, there's column, column, column. 2114 02:03:58,540 --> 02:04:02,520 So it too is like an old timey typewriter that sort of prints one line, 2115 02:04:02,520 --> 02:04:06,460 next line, then the next line, and so forth. So how can we conjure that in 2116 02:04:07,000 --> 02:04:09,840 Well, let me go ahead and do this. 2117 02:04:10,240 --> 02:04:16,520 I think an approach would work is like this. For int i equals 0, i less than 3, 2118 02:04:16,660 --> 02:04:19,440 i plus plus, because I know I want to do something three times. 2119 02:04:19,680 --> 02:04:23,880 But what do I want to do three times? This loop kind of represents in my 2120 02:04:23,880 --> 02:04:26,360 eye rho, rho, rho. 2121 02:04:26,820 --> 02:04:30,580 So in fact, I could be more pedantic. If I want my i to mean something beyond 2122 02:04:30,580 --> 02:04:34,960 int, I could say rho equals 0, rho less than 3. 2123 02:04:35,450 --> 02:04:37,830 row plus plus, just to help me think about it. 2124 02:04:38,050 --> 02:04:40,090 And then what do I want to do on each row? 2125 02:04:40,350 --> 02:04:41,370 What do I want to print? 2126 02:04:42,490 --> 02:04:43,890 Like column, column, column. 2127 02:04:44,190 --> 02:04:45,190 So brick, brick, brick. 2128 02:04:45,270 --> 02:04:49,630 So how do I print three bricks or any number of bricks? Well, I could kind of 2129 02:04:49,630 --> 02:04:54,310 cheat and just do printf hash, hash, hash, backslash n. But again, I can't 2130 02:04:54,310 --> 02:04:57,970 generalize. I can't take an input from the user and print four or five or six 2131 02:04:57,970 --> 02:05:00,130 bricks. So that's going to get me into trouble eventually. 2132 02:05:00,730 --> 02:05:05,770 So maybe I could use a loop. So I could do like for int i equals 0, i less than 2133 02:05:05,770 --> 02:05:10,710 3, i plus plus inside of my loop. And then in here, I could print out one 2134 02:05:10,970 --> 02:05:14,290 And that's kind of on the right direction, the right path, because now 2135 02:05:14,290 --> 02:05:16,610 using the simple building block or brick. 2136 02:05:17,100 --> 02:05:20,400 but reusing it again and again. And it's totally fine to have nested these 2137 02:05:20,400 --> 02:05:21,400 columns in this way. 2138 02:05:21,600 --> 02:05:24,660 I used i out of habit, but what would a better name be? 2139 02:05:24,880 --> 02:05:29,680 Well, maybe column, or maybe just col, call for short, so that my code is sort 2140 02:05:29,680 --> 02:05:31,940 of saying what it does for me. 2141 02:05:32,160 --> 02:05:36,060 And I don't have to use row or column explicitly. I don't need to print them, 2142 02:05:36,200 --> 02:05:39,500 but I am using them as counters, one after the other. 2143 02:05:39,720 --> 02:05:43,420 So let me go ahead and run make Mario, dot slash Mario. 2144 02:05:43,800 --> 02:05:46,140 And I'm feeling good about this, but . 2145 02:05:47,100 --> 02:05:50,480 Damn it. There's nine brick, but they're not really laid out right. 2146 02:05:51,800 --> 02:05:53,660 Why? What's the fix? Yeah. 2147 02:05:56,640 --> 02:05:59,980 Yeah, I never went to a new line. And let me do what I think you're not going 2148 02:05:59,980 --> 02:06:03,020 suggest I do. Let me just go the obvious place. All right, well, let's put one 2149 02:06:03,020 --> 02:06:07,140 right after the brick. But of course, if I do make Mario, dot slash Mario, I'm 2150 02:06:07,140 --> 02:06:10,600 making the same mistake as before. I'm printing out too many new lines. So in 2151 02:06:10,600 --> 02:06:13,940 between, what lines do I actually want to print a new line? 2152 02:06:14,920 --> 02:06:15,920 Between, yeah. 2153 02:06:16,670 --> 02:06:22,710 Yeah, so 10 and 11. So outside of the inner loop, but inside of the outer 2154 02:06:22,790 --> 02:06:25,830 So it happens again and again. So let's just print out as before, single 2155 02:06:25,830 --> 02:06:32,030 backslash n, semicolon. Now let's do make Mario, dot slash Mario, enter. Ah, 2156 02:06:32,030 --> 02:06:36,030 it's generalized as I see fit. And if I really wanted to dwell on this. 2157 02:06:36,460 --> 02:06:39,900 I could go in, and I could prompt the user with get int or with get positive 2158 02:06:39,900 --> 02:06:44,120 int, figure out what row and or column should be. We can make any size brick 2159 02:06:44,120 --> 02:06:46,980 that we want. But now we have sort of a nice starting point. 2160 02:06:47,180 --> 02:06:50,420 But there's another way to think about this. Because I dare say, especially for 2161 02:06:50,420 --> 02:06:53,740 your first CS50 problem set, if you're trying to print bricks and the world of 2162 02:06:53,740 --> 02:06:57,740 Mario in this way, it's probably not going to be obvious to come up with 2163 02:06:57,740 --> 02:07:01,940 like this and just magically get it working after like 45 seconds in total. 2164 02:07:02,120 --> 02:07:03,420 It'll be a struggle at first. 2165 02:07:04,700 --> 02:07:07,640 there are some patterns to follow. So one, it's pretty conventional. 2166 02:07:07,960 --> 02:07:13,470 Nonetheless... to use just i and then j and then k and then l. And if you've got 2167 02:07:13,470 --> 02:07:16,330 nested, nested, nested, nested for loops, at some point nesting, you're 2168 02:07:16,330 --> 02:07:20,010 writing bad code. It's not well -designed. But one or two or maybe three 2169 02:07:20,010 --> 02:07:21,450 nestings could be an OK thing. 2170 02:07:21,670 --> 02:07:26,110 But you cannot use and reuse i again and again. Why? 2171 02:07:26,550 --> 02:07:30,750 Because if you're counting i here, but then you're changing i here to do your 2172 02:07:30,750 --> 02:07:34,450 columns left to right, you're going to get all of your math out of sync. So you 2173 02:07:34,450 --> 02:07:35,830 need two separate variables. 2174 02:07:36,110 --> 02:07:37,730 i and j are conventional. 2175 02:07:38,410 --> 02:07:39,750 row and column would work too. 2176 02:07:39,970 --> 02:07:44,110 But if we go back to this idea of rows and columns, well, let me actually 2177 02:07:44,110 --> 02:07:45,110 something out here. 2178 02:07:45,230 --> 02:07:46,410 And this might help you instead. 2179 02:07:46,650 --> 02:07:48,770 Suppose that you set out on this problem. 2180 02:07:49,050 --> 02:07:52,230 You know you want to do something like three times, but you don't quite 2181 02:07:52,230 --> 02:07:54,850 understand how to print those rows. 2182 02:07:55,190 --> 02:07:59,210 Well, take a baby step, a bite out of the problem, and maybe do this. 2183 02:07:59,510 --> 02:08:00,990 Create a function with no output. 2184 02:08:01,400 --> 02:08:04,300 just a side effect, whose purpose in life is to print a row. 2185 02:08:04,660 --> 02:08:05,780 And how many rows? 2186 02:08:06,100 --> 02:08:08,060 Well, maybe n for some number of bricks. 2187 02:08:10,080 --> 02:08:11,740 How do you print a row of brick? 2188 02:08:12,000 --> 02:08:13,460 Well, let me just think about this in isolation. 2189 02:08:13,700 --> 02:08:18,600 How do I print a single row of brick? That's easy. For int i equals 0, i is 2190 02:08:18,600 --> 02:08:24,280 than n, if I'm generalizing, i plus plus, and then, whoops, i plus plus, and 2191 02:08:24,280 --> 02:08:28,950 then. Inside of my curly braces, go ahead and just print out a single hash. 2192 02:08:29,290 --> 02:08:34,310 And at the end, as you suggested, print out a single new line. In other words, 2193 02:08:34,390 --> 02:08:38,450 abstract away the idea of printing a single row. 2194 02:08:38,730 --> 02:08:41,890 And in fact, at this point in the story, especially if you're struggling to get 2195 02:08:41,890 --> 02:08:45,430 started, you don't even need to start with main. Take a byte out of the 2196 02:08:45,430 --> 02:08:48,250 that makes sense to you that's smaller than the whole problem. 2197 02:08:48,700 --> 02:08:49,700 printing a single row. 2198 02:08:50,100 --> 02:08:51,840 Because then you can come in and iterate. 2199 02:08:52,100 --> 02:08:55,260 Then you can go in and say, OK, now let's write my actual main function. 2200 02:08:55,560 --> 02:08:56,980 So int main void, as always. 2201 02:08:57,480 --> 02:09:01,040 And now what do I want to do? I want to print out a whole bunch of rows. 2202 02:09:01,320 --> 02:09:04,200 How do I print out a whole bunch of rows? Oh my god, it's like the same 2203 02:09:04,200 --> 02:09:08,960 int i equals 0. i is less than, let's call it 3 for now, but we can generalize 2204 02:09:08,960 --> 02:09:09,960 that. i plus plus. 2205 02:09:10,100 --> 02:09:13,780 And what do I want to do on each iteration of this loop? 2206 02:09:14,120 --> 02:09:16,280 My gosh, just print row. 2207 02:09:16,910 --> 02:09:18,150 with three bricks. 2208 02:09:18,990 --> 02:09:20,550 And then we're sort of done. 2209 02:09:21,030 --> 02:09:24,370 Again, out of sight, out of mind. This function can go away and never be seen 2210 02:09:24,370 --> 02:09:28,290 before, because once print row exists, that's what it, in fact, does for me. 2211 02:09:28,470 --> 02:09:30,030 Now, this isn't 100 % correct. 2212 02:09:30,430 --> 02:09:34,090 I still need my prototype, because if I've made my own function, I need to 2213 02:09:34,980 --> 02:09:38,900 see in advance that it shall exist. So I need to copy and paste that one line of 2214 02:09:38,900 --> 02:09:42,140 code. If I were really being pedantic, this is bad design. 2215 02:09:42,580 --> 02:09:46,080 In general, when you have the same number in multiple places in a program, 2216 02:09:46,080 --> 02:09:50,060 programmer would call this a magic number. How is that working? You're just 2217 02:09:50,060 --> 02:09:52,620 honor system that you're using the same number again and again. 2218 02:09:52,920 --> 02:09:56,360 So a better solution here, even if you're not going to take user input, 2219 02:09:56,360 --> 02:09:57,099 to do this. 2220 02:09:57,100 --> 02:09:58,620 int n equals 3. 2221 02:09:59,240 --> 02:10:04,440 and then use n here, and then use n here, or you could call it anything you 2222 02:10:04,440 --> 02:10:08,080 want, but now you've specified three in one. 2223 02:10:08,570 --> 02:10:09,570 and only one place. 2224 02:10:09,810 --> 02:10:14,070 And we can go one step further. It turns out in C and in other languages, you 2225 02:10:14,070 --> 02:10:15,910 can protect yourself against yourself. 2226 02:10:16,130 --> 02:10:19,930 If you know that a variable should never change its value, it should always stay 2227 02:10:19,930 --> 02:10:24,030 3 in this case, you can use what's called a constant, where you can 2228 02:10:24,030 --> 02:10:29,150 say, I don't want just n to be an int. I want it to be a const int, const for 2229 02:10:29,150 --> 02:10:33,770 short for constant. And this means even if I try to change n in my code, the 2230 02:10:33,770 --> 02:10:38,010 compiler will not let me. So I can protect myself from myself or in the 2231 02:10:38,010 --> 02:10:42,230 world, you can use a variable that none of your colleagues can foolishly change 2232 02:10:42,230 --> 02:10:46,030 on you without you realizing that it has happened. 2233 02:10:46,350 --> 02:10:50,850 So a lot of programming, honestly, is just not trusting yourself the next 2234 02:10:50,850 --> 02:10:53,710 morning when you've forgotten what code you wrote, let alone the next month, the 2235 02:10:53,710 --> 02:10:57,430 next year when you're writing code in the real world. So constants just give 2236 02:10:57,430 --> 02:10:59,670 a feature to defend against ourselves. 2237 02:11:00,450 --> 02:11:02,990 There's another feature that's useful too, especially when you wake up the 2238 02:11:02,990 --> 02:11:05,850 day and you're like, oh my god, how does this code work? What does it do? 2239 02:11:06,290 --> 02:11:09,730 Well, there's comments in code. And some of you might have used this in Scratch. 2240 02:11:09,770 --> 02:11:12,370 You could add little yellow sticky notes in Scratch for comments. 2241 02:11:12,590 --> 02:11:14,550 In code, you can do something like this. 2242 02:11:15,090 --> 02:11:19,130 You can, if you want to put an English reminder to yourself, or if you speak 2243 02:11:19,130 --> 02:11:22,890 some other human language, a comment in Spanish or any other human language, you 2244 02:11:22,890 --> 02:11:27,090 can write it with a slash slash at the start of the line. And then you can say 2245 02:11:27,090 --> 02:11:29,330 something like print n. 2246 02:11:30,830 --> 02:11:36,550 And then this tells you in a comment what those subsequent lines of code are 2247 02:11:36,550 --> 02:11:40,590 doing. It's sort of a note to self. It has no functionality. For the computer's 2248 02:11:40,590 --> 02:11:42,510 sake, it just is a note to yourself. 2249 02:11:42,870 --> 02:11:47,270 Or you can say something like this, like, never change n, because you're 2250 02:11:47,270 --> 02:11:50,870 clear that it's indeed constant. But that, too, is a little pedantic, since 2251 02:11:50,870 --> 02:11:55,570 const says the same. But comments are notes to self to help you remember what 2252 02:11:55,570 --> 02:11:58,290 something is doing or why you did it this way. 2253 02:11:59,860 --> 02:12:06,140 Questions now on any of these Mario problems that we have solved? 2254 02:12:08,540 --> 02:12:09,540 No? 2255 02:12:09,840 --> 02:12:13,660 All right. So one final set of examples that puts the limit of what computers 2256 02:12:13,660 --> 02:12:16,300 can actually do. That's why we've solved every problem I proposed. 2257 02:12:16,660 --> 02:12:19,580 That's because I've kind of been skirting some of the underlying 2258 02:12:19,800 --> 02:12:23,210 So it turns out that we have not only functions that give us side effects, 2259 02:12:23,210 --> 02:12:26,350 visually on the screen, we again have functions that have return values. So 2260 02:12:26,350 --> 02:12:30,610 let's focus on those and where things can go wrong. And let's use a bunch of 2261 02:12:30,610 --> 02:12:31,730 other operators as well. 2262 02:12:31,930 --> 02:12:34,770 Suffice it to say, computers got their start by being really good calculators. 2263 02:12:34,870 --> 02:12:38,970 So computer support, addition, subtraction, multiplication, division, 2264 02:12:38,970 --> 02:12:43,750 operators represented by the percent sign here, which says take the remainder 2265 02:12:43,750 --> 02:12:47,250 something over something else. And there's even more operators than this. 2266 02:12:47,250 --> 02:12:51,590 let's go ahead and implement our own calculator of sorts that actually has 2267 02:12:51,850 --> 02:12:56,710 bugs along the way. Let me go back over to VS Code here. I'll close mario .c, 2268 02:12:56,870 --> 02:13:02,770 open my terminal, and code up one final file called calculator .c. And in this 2269 02:13:02,770 --> 02:13:05,990 calculator file, let's go ahead and do something super simple initially. 2270 02:13:06,350 --> 02:13:08,710 Let's go ahead and include cs50 .h. 2271 02:13:08,930 --> 02:13:11,290 Let's include standardio .h. 2272 02:13:11,550 --> 02:13:14,510 Let's do int main void, as always, all boilerplate thus far. 2273 02:13:14,730 --> 02:13:16,570 And now let's do something more interesting. 2274 02:13:16,830 --> 02:13:19,210 int x equals get int. 2275 02:13:19,870 --> 02:13:21,990 And we'll prompt the user for an x value. 2276 02:13:22,390 --> 02:13:27,730 int y, prompt the user for a y value, as we've done previously for comparing 2277 02:13:27,730 --> 02:13:30,930 numbers. And let's just do something super simple. Let's give myself another 2278 02:13:30,930 --> 02:13:33,350 variable, int z equals x plus y. 2279 02:13:33,670 --> 02:13:35,270 And then let's print out the sum. 2280 02:13:35,490 --> 02:13:40,730 So printf, quote unquote, and I don't want %s here. If I want to print out a 2281 02:13:40,730 --> 02:13:45,810 number, someone said it earlier, we want %s for string, but %i for integer, 2282 02:13:46,010 --> 02:13:47,450 backslash n. 2283 02:13:47,900 --> 02:13:49,520 and print out the value of z. 2284 02:13:49,800 --> 02:13:51,840 So it's a little silly, this calculator. 2285 02:13:52,100 --> 02:13:55,640 It just adds two numbers together, but it's going to demonstrate some points. 2286 02:13:55,640 --> 02:13:57,500 make calculator, enter. 2287 02:13:58,040 --> 02:14:00,020 So far, so good. Dot slash calculator. 2288 02:14:00,440 --> 02:14:06,040 Let's just say x is 1, y is 2, z is going to be 3. This code is correct, 2289 02:14:06,040 --> 02:14:09,880 though it is. Is there an opportunity for marginally better design? 2290 02:14:10,940 --> 02:14:15,420 Could we tighten this up, make it shorter? Fewer lines means lower 2291 02:14:15,420 --> 02:14:16,420 of bugs, probably? 2292 02:14:16,640 --> 02:14:17,640 Yeah. 2293 02:14:21,870 --> 02:14:24,050 Yeah, we don't really need a separate variable z. 2294 02:14:24,510 --> 02:14:28,230 I mean, it's fine if it's clearer to you, if it's clearer to your TF, if it's 2295 02:14:28,230 --> 02:14:31,690 clearer to your colleagues. But honestly, this is so relatively simple, 2296 02:14:31,690 --> 02:14:36,430 we just get rid of z and just say something like x plus y here, which is 2297 02:14:36,430 --> 02:14:37,850 reasonable as well. 2298 02:14:38,330 --> 02:14:40,050 But you don't want to take this to an extreme. 2299 02:14:40,310 --> 02:14:42,730 Heck, if we don't need z, do we really need x and y? 2300 02:14:43,070 --> 02:14:44,970 Well, we could do something like this. 2301 02:14:45,270 --> 02:14:48,770 Let me actually delete these lines of code. 2302 02:14:49,240 --> 02:14:52,580 And claim, we can do this all in one very pretty one -liner. 2303 02:14:53,040 --> 02:14:59,000 We could do, say, get int x plus get int y. 2304 02:14:59,360 --> 02:15:04,340 And notice now, kind of like the join example last time, I'm calling get int 2305 02:15:04,340 --> 02:15:05,340 twice. 2306 02:15:06,200 --> 02:15:07,820 Both of them return a value. 2307 02:15:08,400 --> 02:15:11,300 which is going to be 1 and 2, respectively, based on what I typed 2308 02:15:11,580 --> 02:15:13,160 Then I'm doing 1 plus 2. 2309 02:15:13,460 --> 02:15:17,540 That's going into printf as the second argument. This is actually correct and 2310 02:15:17,540 --> 02:15:18,920 will work. It's just stupid. 2311 02:15:19,360 --> 02:15:23,560 Don't do this. We've crossed some ill -defined line where this is just harder 2312 02:15:23,560 --> 02:15:24,560 now to read. 2313 02:15:24,600 --> 02:15:26,940 And so even though the variables aren't strictly necessary, 2314 02:15:27,820 --> 02:15:31,940 I would argue, and I think most programmers would argue, This is just 2315 02:15:31,940 --> 02:15:35,540 readable. Each line is doing a little bit less work. There's less chance for 2316 02:15:35,540 --> 02:15:39,180 error. It just makes a little more sense. But reasonable people will 2317 02:15:39,520 --> 02:15:44,020 So therefore, this is to say, over time too, like you and your TF might 2318 02:15:44,020 --> 02:15:45,660 disagree. You and your colleagues might disagree. 2319 02:15:45,920 --> 02:15:49,400 And at that point is when the sort of religious debates kick in as to which 2320 02:15:49,400 --> 02:15:50,940 is the right way. 2321 02:15:51,610 --> 02:15:52,870 All right, so that's one calculator. 2322 02:15:53,150 --> 02:15:56,250 Let's do something else that maybe just doubles a number here. 2323 02:15:56,490 --> 02:16:00,870 So let me change this to just get one integer from the user. Let's just call 2324 02:16:00,870 --> 02:16:07,650 x. And let's just double it quite simply. So printf %i backslash n x times 2325 02:16:07,650 --> 02:16:12,030 2. We'll quite simply double it. The star operator is indeed multiplication 2326 02:16:12,030 --> 02:16:15,530 this case. So that's going to go ahead and double my number. So make calculator 2327 02:16:15,530 --> 02:16:20,270 again, dot slash calculator, Enter. And let's go ahead and type in 1. 2328 02:16:20,650 --> 02:16:22,870 And I get back 2. Let's run it again. Type in 2. 2329 02:16:23,090 --> 02:16:24,090 I get back 4. 2330 02:16:24,190 --> 02:16:25,430 Type it again. Let's type in 3. 2331 02:16:25,650 --> 02:16:30,950 I get back 6, and so forth. All right, so that's not bad in this case here. 2332 02:16:31,190 --> 02:16:35,010 But what if we actually want to write a proper program here? 2333 02:16:35,370 --> 02:16:39,690 In fact, yeah, let's see. This is sort of a meme that comes and goes. 2334 02:16:39,930 --> 02:16:41,910 Let me see if you recognize this. 2335 02:16:42,170 --> 02:16:43,209 I'm going to go ahead and say. 2336 02:16:43,740 --> 02:16:46,920 Another variable, not x. Let's be more specific, like int dollars equals 1. 2337 02:16:47,240 --> 02:16:51,080 And then let me deliberately induce an infinite loop. Sometimes it is useful to 2338 02:16:51,080 --> 02:16:56,100 induce an infinite loop so long as you eventually break out of it somehow if 2339 02:16:56,100 --> 02:16:57,420 don't want the program to run forever. 2340 02:16:57,719 --> 02:17:01,320 I'm going to ask the user a question, asking them for a char c using get char. 2341 02:17:01,700 --> 02:17:06,780 And I'm going to ask them, quote unquote, here's percent i, period. 2342 02:17:07,379 --> 02:17:12,040 Double it and give it to the next person, question mark. 2343 02:17:12,650 --> 02:17:17,290 This is ringing a bell. And then we can pass in to Getchar the dollars value 2344 02:17:17,290 --> 02:17:20,209 there. So actually, this looked a little cryptic already. I'm going to put a 2345 02:17:20,209 --> 02:17:23,150 dollar sign in front of it as though we're actually dealing with US currency. 2346 02:17:23,410 --> 02:17:29,469 And what do we want to do? How about if the user says Y for yes, double it and 2347 02:17:29,469 --> 02:17:32,410 give it to the next person, then let's go ahead and do dollars. 2348 02:17:32,709 --> 02:17:37,190 And let's double dollars. So I can do dollars equals dollars times two. Or 2349 02:17:37,190 --> 02:17:40,430 recall the trick for plus and minus. I can also do. 2350 02:17:40,950 --> 02:17:45,430 times equals 2, which just doubles it in one line as well. Just a little 2351 02:17:45,430 --> 02:17:49,370 syntactic sugar, as programmers call it, that just tighten up your code, even 2352 02:17:49,370 --> 02:17:50,510 though it's the exact same thing. 2353 02:17:50,950 --> 02:17:54,250 But what if the user does not type y and they want to keep the money? 2354 02:17:54,450 --> 02:17:55,570 Well, we have an else condition. 2355 02:17:55,950 --> 02:17:59,430 At that point, you don't want to keep asking, asking, asking, asking them with 2356 02:17:59,430 --> 02:18:00,009 get char. 2357 02:18:00,010 --> 02:18:01,150 Let's just break out. 2358 02:18:01,500 --> 02:18:02,500 of this loop instead. 2359 02:18:02,940 --> 02:18:07,139 So break is another keyword that if you're inside of a for loop, a while 2360 02:18:07,139 --> 02:18:12,320 do while loop, you can forcibly break out of the loop early if and when you 2361 02:18:12,320 --> 02:18:15,940 to. And so this sort of satisfies the goal of making sure that this doesn't 2362 02:18:15,940 --> 02:18:19,000 forever, but it is going to run again and again and again while we keep 2363 02:18:19,000 --> 02:18:20,400 prompting the user with this question. 2364 02:18:20,620 --> 02:18:22,200 So let's see now what happens. 2365 02:18:23,030 --> 02:18:26,770 Except at the end, let's go ahead and make sure the user knows how much money 2366 02:18:26,770 --> 02:18:27,770 they're walking away with. 2367 02:18:28,170 --> 02:18:33,110 Here's dollar sign, percent i, backslash n, dollar. So we will see at the end of 2368 02:18:33,110 --> 02:18:35,570 this whatever dollar amount the person ends up with. 2369 02:18:36,010 --> 02:18:39,629 Make calculator, enter, dot slash calculator. 2370 02:18:39,950 --> 02:18:41,650 And let me increase my terminal window size. 2371 02:18:42,129 --> 02:18:45,490 So here we go. Here's $1. Double it and give it to the next person. Yes. 2372 02:18:46,010 --> 02:18:48,190 Here's $2. Double it and give it to the next person. 2373 02:18:48,410 --> 02:18:49,770 Yes. Yes. 2374 02:18:50,270 --> 02:18:51,270 Yes. Yes. 2375 02:18:51,549 --> 02:18:56,150 Yes. So the Instagram reels aren't that long. But if you keep doubling it again 2376 02:18:56,150 --> 02:18:59,430 and again, this is called exponentiation, which will make you 2377 02:18:59,430 --> 02:19:03,469 quite quickly. Because notice, we're already in the thousands of dollars by 2378 02:19:03,469 --> 02:19:04,610 saying yes and yes and yes. 2379 02:19:04,830 --> 02:19:08,270 It's an interesting sort of societal question as to what dollar amount you 2380 02:19:08,270 --> 02:19:11,389 keep the money and no longer double it and pass it on. But for now, we'll just 2381 02:19:11,389 --> 02:19:14,049 keep doubling it, because this is just getting bigger and bigger, seemingly 2382 02:19:14,049 --> 02:19:16,730 infinitely large in the C program. 2383 02:19:16,969 --> 02:19:19,030 But oh my god, like apparently, 2384 02:19:19,870 --> 02:19:23,770 The Instagram reels cut off the meme too short because eventually it goes 2385 02:19:23,770 --> 02:19:25,250 negative and then zero. 2386 02:19:25,570 --> 02:19:28,830 Like, what's actually going on here? 2387 02:19:29,030 --> 02:19:33,389 Like, the code is actually correct, but we're bumping up against a different 2388 02:19:33,389 --> 02:19:34,389 kind of problem. 2389 02:19:34,790 --> 02:19:38,969 Any instinct for what is actually going wrong here? It's not doubling forever? 2390 02:19:39,450 --> 02:19:40,450 Yeah. 2391 02:19:42,139 --> 02:19:46,200 Yeah, there's not enough bits to store bigger and bigger numbers. Recall with 2392 02:19:46,200 --> 02:19:50,060 bits, which happens to be how big most ints are, you can count as high as 4 2393 02:19:50,060 --> 02:19:54,120 billion if you start at 0, or roughly as high as 2 billion if you want to handle 2394 02:19:54,120 --> 02:19:57,580 negative numbers as well, negative 2 billion to positive 2 billion. So 2395 02:19:57,580 --> 02:20:02,660 eventually, once I get to $1 billion, it goes negative, and then it just goes to 2396 02:20:02,660 --> 02:20:03,660 0 altogether. 2397 02:20:03,740 --> 02:20:08,240 This is because of something called integer overflow, whereby if you only 2398 02:20:08,240 --> 02:20:11,590 finite number of bits, And you keep incrementing them, incrementing them, 2399 02:20:11,670 --> 02:20:12,670 incrementing them. 2400 02:20:12,690 --> 02:20:16,030 Eventually, you can't just carry the 1, because there's no 33rd bit. 2401 02:20:16,390 --> 02:20:22,130 So all of the other bits wrap around from 1s to 0s. And it looks like all 32 2402 02:20:22,130 --> 02:20:23,330 your bits are 0. 2403 02:20:23,950 --> 02:20:28,190 Because the 33rd bit was supposed to be the one, but it's not there. They don't 2404 02:20:28,190 --> 02:20:32,650 have enough memory. So this is a fundamental problem with computers 2405 02:20:32,650 --> 02:20:37,210 you count high enough, things will just start to break, at least if you're using 2406 02:20:37,210 --> 02:20:41,370 C or C++ or certain other languages that don't anticipate this. 2407 02:20:41,630 --> 02:20:45,530 And there's a very real implication of this. So here's a photograph of 2408 02:20:45,530 --> 02:20:49,290 we'll look at more in time to come, like of memory inside of your computer or 2409 02:20:49,290 --> 02:20:50,630 phone or any electronic device. 2410 02:20:50,950 --> 02:20:54,420 Suffice it to say, there's only a finite amount of memory. And if you're only 2411 02:20:54,420 --> 02:20:59,360 using 32 bits then, or heck, even three bits, you will eventually overflow. 2412 02:20:59,780 --> 02:21:03,340 We used three bits last week. So here's an example. In binary, if you're only 2413 02:21:03,340 --> 02:21:07,640 using three bits per the white digits here, I've put in gray the fourth just 2414 02:21:07,640 --> 02:21:09,820 show you what carry we might want to have. 2415 02:21:10,100 --> 02:21:17,100 Here's 0, 1, 2, 3, 4, 5, 6, 7, just like last week. And 2416 02:21:17,100 --> 02:21:20,280 just like last week, someone said, how do we get to 8? We need another bit. 2417 02:21:20,830 --> 02:21:25,750 But if that bit is grayed out because it doesn't exist, we've just overflowed 2418 02:21:25,750 --> 02:21:31,930 this tiny integer and gotten back to 0, just like my money went to $0 instead. 2419 02:21:32,510 --> 02:21:34,530 So how do we actually avoid that? 2420 02:21:35,130 --> 02:21:38,610 One way to do this is this. Let me hit Control -C to break out of the program, 2421 02:21:38,790 --> 02:21:41,330 or I could just type no. Let me shrink my terminal window. 2422 02:21:42,000 --> 02:21:44,960 and clear it here, I could actually do this. 2423 02:21:45,240 --> 02:21:49,940 It turns out that ints use 32 bits typically, but there's another data type 2424 02:21:49,940 --> 02:21:54,200 was on the slide before called long, which is a longer version of an int, 2425 02:21:54,200 --> 02:21:56,560 is 64 bits, which is crazy big. 2426 02:21:56,940 --> 02:22:01,260 There's not that many dollars in the world, but it's still finite, even 2427 02:22:01,260 --> 02:22:05,960 can't pronounce the number that big. But if we change all of our int to long, 2428 02:22:06,180 --> 02:22:11,720 and we change our placeholder from percent i to percent li for long int, I 2429 02:22:11,720 --> 02:22:15,340 actually count higher and higher. So case in point, let me actually go back 2430 02:22:15,340 --> 02:22:18,000 my terminal, make calculator, Enter. 2431 02:22:18,680 --> 02:22:19,680 Make it larger again. 2432 02:22:20,000 --> 02:22:21,060 Dot slash calculator. 2433 02:22:21,440 --> 02:22:24,940 And I'm just going to keep saying yes, but faster this time. The sequence is 2434 02:22:24,940 --> 02:22:28,420 exactly the same. But recall that once we got into the billions, it started to 2435 02:22:28,420 --> 02:22:29,800 wrap to negative and then zero. 2436 02:22:30,040 --> 02:22:34,280 This is a lot of money now. Like longs are indeed longer. And I could do this 2437 02:22:34,280 --> 02:22:35,420 probably all day long. 2438 02:22:35,640 --> 02:22:38,800 Oh, interesting. No, I shouldn't have said that. 2439 02:22:39,660 --> 02:22:43,820 Can't do this all day long because eventually a long two will overflow. I 2440 02:22:43,820 --> 02:22:44,880 didn't think it was going to happen that fast. 2441 02:22:45,160 --> 02:22:49,660 So a long 2 will overflow because we'll need a 65th bit, but the computer has 2442 02:22:49,660 --> 02:22:53,120 not allocated it. So that 2 becomes an issue of overflow. 2443 02:22:53,420 --> 02:22:57,460 To read an excerpt, like these are very real world issues. And in fact, here's a 2444 02:22:57,460 --> 02:22:58,740 photograph of a Boeing. 2445 02:22:59,340 --> 02:23:03,880 787 years ago that actually had issues beyond the most recent issues with 2446 02:23:03,880 --> 02:23:10,820 airplanes, whereby after 248 days, the Boeing 787 years ago can lose all 2447 02:23:10,820 --> 02:23:15,160 of its electrical power due to the generator control unit simultaneously 2448 02:23:15,160 --> 02:23:16,960 into failsafe mode, whatever that means. 2449 02:23:17,210 --> 02:23:21,850 But if you dig into this, it turns out that there was a software counter in 2450 02:23:21,850 --> 02:23:27,390 these airplanes years ago that would overflow after 248 days of continuous 2451 02:23:27,390 --> 02:23:28,390 power. 2452 02:23:28,770 --> 02:23:29,850 248 days, why? 2453 02:23:30,090 --> 02:23:34,030 Well, Boeing was using a 32 -bit integer, and they were using it to 2454 02:23:34,460 --> 02:23:35,460 tenths of seconds. 2455 02:23:35,700 --> 02:23:41,880 And it turns out if you do the math, after 248 days, you have used too many 2456 02:23:41,880 --> 02:23:46,660 tenths such that you overflow the size of a 32 -bit integer. The plane would 2457 02:23:46,660 --> 02:23:49,820 essentially have this integer, this tiny, stupid little variable overflow. 2458 02:23:50,200 --> 02:23:53,440 But generally speaking, when your numbers suddenly go negative or zero, 2459 02:23:53,440 --> 02:23:58,300 things happen. The plane could literally lose its power mid -flight or on the 2460 02:23:58,300 --> 02:24:00,980 ground. And if you can believe it, anyone want to guess what Boeing's 2461 02:24:00,980 --> 02:24:02,480 was till they fixed the actual software? 2462 02:24:05,100 --> 02:24:06,100 What's that? 2463 02:24:06,780 --> 02:24:08,220 Not even. 2464 02:24:08,480 --> 02:24:09,480 Reboot the plane. 2465 02:24:09,610 --> 02:24:14,090 Like, they were told every few days, certainly every 248 days, turn the power 2466 02:24:14,090 --> 02:24:17,510 off, turn it back on, which stupidly is what all of us have been told for years 2467 02:24:17,510 --> 02:24:19,210 with our Macs and PCs and phones. Why? 2468 02:24:19,590 --> 02:24:23,610 Because sometimes, because of bugs in software, computers get into funky 2469 02:24:23,770 --> 02:24:27,950 which is a colloquial way of saying, like, some programmer made a mistake, 2470 02:24:27,950 --> 02:24:31,650 some counter overflowed, or some condition wasn't handled, and just 2471 02:24:31,790 --> 02:24:33,050 unexpected things happen. 2472 02:24:33,290 --> 02:24:37,710 So rebooting just resets all of your variables back to their original values 2473 02:24:37,710 --> 02:24:41,990 sort of gives you more time. more runway, in this case, no pun intended. 2474 02:24:42,230 --> 02:24:45,210 There are others. In fact, one of the most famous ones from the 1980s was the 2475 02:24:45,210 --> 02:24:49,210 original Pac -Man game. Only had support for 255 levels. 2476 02:24:49,410 --> 02:24:51,030 Why? They were using 8 bits. 2477 02:24:51,290 --> 02:24:52,890 Recall that 8 bits gives you 256. 2478 02:24:53,410 --> 02:24:57,290 But if you start counting at 0, you can only go to 255. So the crazy kids who 2479 02:24:57,290 --> 02:25:03,060 were so good at Pac -Man that they got to level 256, the makers of Pac -Man did 2480 02:25:03,060 --> 02:25:07,000 not anticipate that anyone was going to win that many levels. And just weird 2481 02:25:07,000 --> 02:25:10,160 stuff happened on the screen. All of the fruit sort of started overwriting 2482 02:25:10,160 --> 02:25:14,260 everything because they didn't have enough memory allocated to the level. 2483 02:25:14,260 --> 02:25:18,860 did they have a condition that says, if level equals equals 255, you win. 2484 02:25:19,120 --> 02:25:23,020 Like, there was just nothing handling that corner case, so to speak. So these 2485 02:25:23,020 --> 02:25:24,740 things abound even these days. 2486 02:25:25,000 --> 02:25:29,600 Thankfully, in some languages, There are better solutions where you can use big 2487 02:25:29,600 --> 02:25:35,980 integers. And you'll just use 64, maybe 128, maybe 256 bits. But you need to use 2488 02:25:35,980 --> 02:25:40,120 a language or a library that allows you to grow and shrink the amount of memory 2489 02:25:40,120 --> 02:25:44,580 being used. And many, if not most, languages do not do that for us. 2490 02:25:44,940 --> 02:25:49,100 So there's a few final problems to see that we've been taking for granted thus 2491 02:25:49,100 --> 02:25:51,340 far. And they also involve... 2492 02:25:51,610 --> 02:25:52,810 numbers, and memory. 2493 02:25:53,050 --> 02:25:54,550 So let's go back into our calculator. 2494 02:25:54,750 --> 02:25:56,610 Let's throw away all of this meme code here. 2495 02:25:56,830 --> 02:26:00,430 And instead, let's go ahead and do something simple again. 2496 02:26:00,650 --> 02:26:06,090 int x equals get int and prompt the user for a variable x. int y equals get int, 2497 02:26:06,170 --> 02:26:07,610 prompt the user for a variable y. 2498 02:26:07,850 --> 02:26:11,890 And this time, instead of addition, instead of doubling, let's do division. 2499 02:26:12,090 --> 02:26:16,950 So printf, quote unquote, percent i, backslash n, and then plug in. 2500 02:26:17,280 --> 02:26:20,840 x divided by y. So you use a single forward slash for division. 2501 02:26:21,160 --> 02:26:24,840 Let me go ahead and make calculator down here, dot slash calculator. 2502 02:26:25,200 --> 02:26:31,860 And let's go ahead and do 1 divided by 3, which should in fact be, well, it's 2503 02:26:31,860 --> 02:26:35,240 not really 0, right? It's like 0 .333. 2504 02:26:35,480 --> 02:26:40,060 Let's try this again. How about dot slash calculator? 3 divided by 2 should 2505 02:26:40,060 --> 02:26:42,960 .5. Nope. Computer thinks it's 1. 2506 02:26:43,680 --> 02:26:47,800 Well, what's happening here? Well, it turns out when you're using integers in 2507 02:26:47,800 --> 02:26:50,720 program, you are vulnerable to what's called truncation. 2508 02:26:51,040 --> 02:26:55,140 An integer plus an integer gives you an integer. An integer divided by an 2509 02:26:55,140 --> 02:26:57,780 integer, funny enough, gives you an integer. 2510 02:26:58,080 --> 02:27:04,920 So even if the answer is supposed to be 0 .333 or 1 .5, everything in the world 2511 02:27:04,920 --> 02:27:09,670 of integers throws away the decimal point onward, and you only get the 2512 02:27:09,670 --> 02:27:11,750 part of the value. So it's not even rounding. 2513 02:27:11,950 --> 02:27:14,370 It's truncating everything after the decimal. 2514 02:27:14,610 --> 02:27:18,350 So this program is just not correct. But there are solutions, potentially. 2515 02:27:18,730 --> 02:27:23,090 For instance, if I go back into my code here and I use a different format code 2516 02:27:23,090 --> 02:27:28,090 we haven't used yet. We had s for string, i for int. There's also f for 2517 02:27:28,290 --> 02:27:32,740 And a float was Like a real number, something with a decimal point in it by 2518 02:27:32,740 --> 02:27:36,560 definition. We just haven't used it yet. I could tell the computer to print this 2519 02:27:36,560 --> 02:27:38,840 as a float. So let me do make calculator again. 2520 02:27:39,460 --> 02:27:42,800 And now, hmm, it's specifying type double. There's an error here. 2521 02:27:43,020 --> 02:27:47,560 The problem is that I can't just tell the computer to format this number as a 2522 02:27:47,560 --> 02:27:49,340 float. I need to convert. 2523 02:27:49,900 --> 02:27:52,720 the number x divided by y to a float. 2524 02:27:52,920 --> 02:27:56,720 And I can do this in a couple of ways. One, I could literally change all of 2525 02:27:56,720 --> 02:27:58,500 to floats and just avoid the problem altogether. 2526 02:27:58,820 --> 02:28:01,640 Use float, use get float, use %f, and I'm done. 2527 02:28:02,280 --> 02:28:05,660 But if I want to use ints for whatever reason, because I want the user to type 2528 02:28:05,660 --> 02:28:09,680 in integers, but I want to show them real numbers with decimal points for 2529 02:28:09,680 --> 02:28:13,340 correct math, I can do what's called casting a value. 2530 02:28:13,600 --> 02:28:18,140 I can, in parentheses, which is a weird new use of parentheses, I can say, hey, 2531 02:28:18,160 --> 02:28:23,500 computer, please treat the following integer as a float instead, thereby 2532 02:28:23,500 --> 02:28:29,240 avoiding truncation. Do not truncate for me. So if I now run make calculator 2533 02:28:29,240 --> 02:28:36,200 again. dot slash calculator, and type in, for instance, 1 for x, 3 for y, now 2534 02:28:36,200 --> 02:28:38,060 get an actual floating point value. 2535 02:28:38,340 --> 02:28:41,460 I'm formatting it as such, and I'm telling the computer to actually 2536 02:28:41,460 --> 02:28:44,660 arithmetically calculate it as such as well. 2537 02:28:45,360 --> 02:28:48,800 But here, too, I'm kind of cheating you of a reality. 2538 02:28:49,160 --> 02:28:54,020 It turns out, let me clear this screen here, and it turns out that there are 2539 02:28:54,020 --> 02:28:58,530 fancy ways in printf to tell it how many digits to show you, how many 2540 02:28:58,530 --> 02:28:59,790 significant digits. 2541 02:29:00,070 --> 02:29:03,330 And the syntax is very weird. I have to look it up constantly. But instead of 2542 02:29:03,330 --> 02:29:07,150 just saying percent f, you literally put some numbers in between there. And you 2543 02:29:07,150 --> 02:29:09,450 say 0 .5. 2544 02:29:09,790 --> 02:29:14,810 And that will say, it's weird syntax, hey, printf, format this to five digits 2545 02:29:14,810 --> 02:29:19,610 instead. So let me go ahead and do make calculator again, dot slash calculator. 2546 02:29:20,310 --> 02:29:23,790 And let's do 1 divided by 3. And indeed, I get 5. 2547 02:29:24,160 --> 02:29:28,960 significant digits there. But suppose I get a little crazy and I want 50 2548 02:29:28,960 --> 02:29:30,060 significant digits. 2549 02:29:30,280 --> 02:29:33,480 Well, according to grade school, I should just see more like threes. But 2550 02:29:33,480 --> 02:29:36,620 this. Make calculator dot slash calculator. 2551 02:29:36,900 --> 02:29:40,220 And it turns out that whoever taught you grade school math was kind of telling 2552 02:29:40,220 --> 02:29:43,900 you some white lies. Because if you really do it with a powerful Mac or PC 2553 02:29:43,900 --> 02:29:50,840 phone, one third is actually 0 .33333334326744079. 2554 02:29:52,380 --> 02:29:53,380 Who's right? 2555 02:29:54,200 --> 02:29:57,760 Mr. and Mrs. So -and -so from grade school or like the internet? 2556 02:29:59,500 --> 02:30:00,580 What's going on here? 2557 02:30:03,380 --> 02:30:08,000 What explains this? It all comes down somehow to weak zeros, zeros, and ones. 2558 02:30:09,440 --> 02:30:13,380 Why is this floating point number imprecise, so to speak? 2559 02:30:14,340 --> 02:30:15,740 What's the intuition? Yeah. 2560 02:30:20,230 --> 02:30:21,550 Yes, similar in spirit. 2561 02:30:21,770 --> 02:30:26,810 Just as ints only use 32 bits, floats also use only 32 bits. If you want more, 2562 02:30:26,950 --> 02:30:31,210 just as int has long, floats have something called double. So I could kind 2563 02:30:31,210 --> 02:30:34,350 avoid some of the problem by switching to double, but that's still going to be 2564 02:30:34,350 --> 02:30:37,990 finite. And if you think about this intuitively, if you're using a finite 2565 02:30:37,990 --> 02:30:43,390 of bits, be it 32 or 64, you can only represent literally so many patterns and 2566 02:30:43,390 --> 02:30:46,770 thus so many floating point values, so many real numbers. But how many real 2567 02:30:46,770 --> 02:30:47,790 numbers are there in the world? 2568 02:30:48,480 --> 02:30:52,520 Like literally infinitely many is the challenge of real numbers. You can just 2569 02:30:52,520 --> 02:30:55,940 keep adding numbers after the digits. So how could a computer, Mac PC or 2570 02:30:55,940 --> 02:31:00,740 otherwise, possibly represent every floating point value super precisely if 2571 02:31:00,740 --> 02:31:05,060 there's not enough patterns to represent every number in the world? Moreover, 2572 02:31:05,260 --> 02:31:09,060 the way that computers use to represent numbers sometimes do not allow them to 2573 02:31:09,060 --> 02:31:12,680 represent numbers so precisely. We can get more significant digits maybe, but 2574 02:31:12,680 --> 02:31:15,700 not 100 % perfection or precision. 2575 02:31:15,980 --> 02:31:21,170 So floating point precision too. is a fundamental problem with computers 2576 02:31:21,310 --> 02:31:24,610 And unless, again, you're using a specialized language or library that 2577 02:31:24,610 --> 02:31:28,810 understands for scientific computing the implications of overflow or 2578 02:31:28,810 --> 02:31:32,710 imprecision, your code will have mistakes, much like Boeing discovered, 2579 02:31:32,710 --> 02:31:34,510 like Pac -Man discovered as well. 2580 02:31:34,750 --> 02:31:38,390 And in fact, just to end on a gloom and doom note, it turns out there's another 2581 02:31:38,390 --> 02:31:40,330 problem like this on the horizon already. 2582 02:31:40,670 --> 02:31:44,770 So back in my day, everyone was really worried about the Y2K problem, the year 2583 02:31:44,770 --> 02:31:45,990 2000 problem. Why? 2584 02:31:47,150 --> 02:31:50,930 when computers were invented, most systems were using just two digits, 2585 02:31:51,110 --> 02:31:53,510 independent of bits, two digits to represent years. 2586 02:31:53,730 --> 02:31:56,210 Why? Computers came out a few decades ago. 2587 02:31:56,450 --> 02:31:59,430 Who would think that a computer is still going to be running decades later? 2588 02:31:59,710 --> 02:32:03,370 Turns out they were, especially in government and corporations and the 2589 02:32:03,370 --> 02:32:07,150 if you're only using two digits to represent years, And the millennium 2590 02:32:07,150 --> 02:32:12,030 around, and it's 1999, about to roll over, about to roll over. What comes 2591 02:32:12,030 --> 02:32:13,030 1999? 2592 02:32:13,610 --> 02:32:15,870 Well, if you're only using two digits, ideally 2000. 2593 02:32:16,390 --> 02:32:21,210 But if you're only using two digits, the year zero comes after the year 1999. 2594 02:32:21,570 --> 02:32:25,350 And the whole world, truly, you can look it up nowadays on Wikipedia, was 2595 02:32:25,350 --> 02:32:28,570 freaking out because there was so much old software in the world that could 2596 02:32:28,570 --> 02:32:32,050 had this mistake. And who knows? Planes falling out of the sky, computers 2597 02:32:32,050 --> 02:32:36,750 rebooting, freezing. No one really knew because this was an unhandled situation 2598 02:32:36,750 --> 02:32:37,729 in code. 2599 02:32:37,730 --> 02:32:41,130 So thankfully, the world actually got its act together. The world did not end 2600 02:32:41,130 --> 02:32:44,910 the year 2000, and most systems were updated in time without crazy horror 2601 02:32:44,910 --> 02:32:49,640 stories. But we're going to have this happen again, because it turns out Just 2602 02:32:49,640 --> 02:32:54,760 few years from now, at this point, computers for years have been using 32 2603 02:32:54,760 --> 02:32:59,580 integers to keep track of time, in the sense of what time of day it is. And the 2604 02:32:59,580 --> 02:33:04,640 point in time they decided years ago was, hey, everyone, let's just keep 2605 02:33:04,640 --> 02:33:08,680 of how many seconds have passed since January 1, 1970. 2606 02:33:09,100 --> 02:33:12,820 And we can relatively compute time any time thereafter. 2607 02:33:13,280 --> 02:33:16,880 So that's great. That gives us a lot of decades worth. But 32 bits eventually 2608 02:33:16,880 --> 02:33:20,780 maxes out at like 4 billion. and positive, or 2 billion if you want 2609 02:33:20,780 --> 02:33:24,920 positive. And it turns out if you count the number of seconds between 1970 on 2610 02:33:24,920 --> 02:33:31,650 up, On the day, January 19, 2038, the world might again end because all of 2611 02:33:31,650 --> 02:33:33,410 clocks are going to overflow. 2612 02:33:33,850 --> 02:33:36,610 And we're going to end up in the year zero or negative something. 2613 02:33:36,930 --> 02:33:38,010 Now, what's the solution there? 2614 02:33:38,350 --> 02:33:41,710 I mean, my god, it's the exact same thing. Like, stop using so few bits. Use 2615 02:33:41,710 --> 02:33:44,670 more bits. But bits and memory and computers used to be expensive. 2616 02:33:45,030 --> 02:33:47,170 Nowadays, storage is so much more available. 2617 02:33:47,570 --> 02:33:50,950 But among the things we'll discuss then is how you can throw both hardware and 2618 02:33:50,950 --> 02:33:54,850 software at this problem. But for now, maybe set a Google Calendar reminder for 2619 02:33:54,850 --> 02:33:58,120 January. January 19th, 2038, and hopefully we'll see you next week. 250560

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