All language subtitles for lecture1(228)-720p-en

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

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