All language subtitles for 2024_fall_lecture1-720p-en
Afrikaans
Akan
Albanian
Amharic
Arabic
Armenian
Azerbaijani
Basque
Belarusian
Bemba
Bengali
Bihari
Bosnian
Breton
Bulgarian
Cambodian
Catalan
Cebuano
Cherokee
Chichewa
Chinese (Simplified)
Chinese (Traditional)
Corsican
Croatian
Czech
Danish
Dutch
English
Esperanto
Estonian
Ewe
Faroese
Filipino
Finnish
French
Frisian
Ga
Galician
Georgian
German
Greek
Guarani
Gujarati
Haitian Creole
Hausa
Hawaiian
Hebrew
Hindi
Hmong
Hungarian
Icelandic
Igbo
Indonesian
Interlingua
Irish
Italian
Japanese
Javanese
Kannada
Kazakh
Kinyarwanda
Kirundi
Kongo
Korean
Krio (Sierra Leone)
Kurdish
Kurdish (SoranĂ®)
Kyrgyz
Laothian
Latin
Latvian
Lingala
Lithuanian
Lozi
Luganda
Luo
Luxembourgish
Macedonian
Malagasy
Malay
Malayalam
Maltese
Maori
Marathi
Mauritian Creole
Moldavian
Mongolian
Myanmar (Burmese)
Montenegrin
Nepali
Nigerian Pidgin
Northern Sotho
Norwegian
Norwegian (Nynorsk)
Occitan
Oriya
Oromo
Pashto
Persian
Polish
Portuguese (Brazil)
Portuguese (Portugal)
Punjabi
Quechua
Romanian
Romansh
Runyakitara
Russian
Samoan
Scots Gaelic
Serbian
Serbo-Croatian
Sesotho
Setswana
Seychellois Creole
Shona
Sindhi
Sinhalese
Slovak
Slovenian
Somali
Spanish
Spanish (Latin American)
Sundanese
Swahili
Swedish
Tajik
Tamil
Tatar
Telugu
Thai
Tigrinya
Tonga
Tshiluba
Tumbuka
Turkish
Turkmen
Twi
Uighur
Ukrainian
Urdu
Uzbek
Vietnamese
Welsh
Wolof
Xhosa
Yiddish
Yoruba
Zulu
Would you like to inspect the original subtitles? These are the user uploaded subtitles that are being translated:
0
00:00:00,000 --> 00:00:02,490
[MUSIC PLAYING]
1
00:00:02,490 --> 00:01:15,240
2
00:01:15,240 --> 00:01:17,140
DAVID J. MALAN: All right.
3
00:01:17,140 --> 00:01:19,520
This is CS50.
4
00:01:19,520 --> 00:01:22,172
This is week one, because of course, last week was week zero.
5
00:01:22,172 --> 00:01:24,630
And this is the week where we'll actually start programming
6
00:01:24,630 --> 00:01:27,960
in a much more traditional way, that programming language we promised
7
00:01:27,960 --> 00:01:28,997
called C.
8
00:01:28,997 --> 00:01:30,330
Of course, we started with this.
9
00:01:30,330 --> 00:01:32,550
And hopefully by now, with problem set 1, you've had a little bit of fun,
10
00:01:32,550 --> 00:01:34,092
even if you've played with it before.
11
00:01:34,092 --> 00:01:36,360
And the goals of Scratch, beyond making things
12
00:01:36,360 --> 00:01:39,210
feel very accessible and user friendly is really
13
00:01:39,210 --> 00:01:41,850
to elucidate some of the fundamental concepts
14
00:01:41,850 --> 00:01:45,330
that we'll see again today, and really every week subsequently, like
15
00:01:45,330 --> 00:01:49,870
functions and conditionals and loops and variables and so much more.
16
00:01:49,870 --> 00:01:52,600
And in fact, among the goals of Scratch is, again,
17
00:01:52,600 --> 00:01:54,460
to plant these visuals in your mind.
18
00:01:54,460 --> 00:01:57,580
So even as today onward feels all the more like a fire hose,
19
00:01:57,580 --> 00:02:01,270
especially when it comes to really weird, cryptic textual syntax,
20
00:02:01,270 --> 00:02:04,000
the ideas are still going to be the same.
21
00:02:04,000 --> 00:02:07,960
So today, this program, Hello, world, becomes this instead.
22
00:02:07,960 --> 00:02:10,740
And in fact, just to color code things temporarily, I
23
00:02:10,740 --> 00:02:14,130
dare say that what I've color coded here in orange, which looks probably,
24
00:02:14,130 --> 00:02:16,960
to those of you who've never programmed, pretty cryptic
25
00:02:16,960 --> 00:02:22,940
is the equivalent of when green flag clicked orange puzzle piece like this.
26
00:02:22,940 --> 00:02:26,120
What remains is just one line in purple with a bit of white,
27
00:02:26,120 --> 00:02:28,510
which is what ultimately is going to get the screen today
28
00:02:28,510 --> 00:02:30,350
to say, Hello, world on the screen.
29
00:02:30,350 --> 00:02:33,230
And of course, we had a name for something in purple.
30
00:02:33,230 --> 00:02:36,280
In fact, if we rewind to week zero, this block in purple
31
00:02:36,280 --> 00:02:40,090
represented what type of functionality?
32
00:02:40,090 --> 00:02:41,665
AUDIENCE: [INAUDIBLE].
33
00:02:41,665 --> 00:02:43,540
DAVID J. MALAN: A function itself, an action,
34
00:02:43,540 --> 00:02:45,507
a verb that gets the computer to do something.
35
00:02:45,507 --> 00:02:48,090
So what looked like this last week is about to look like this.
36
00:02:48,090 --> 00:02:50,340
Let's take away the color coding and focus really
37
00:02:50,340 --> 00:02:52,870
on what we're going to now start calling source code.
38
00:02:52,870 --> 00:02:55,720
So this is what programmers do in the real world.
39
00:02:55,720 --> 00:02:58,870
This is what software developers, software engineers do in the real world.
40
00:02:58,870 --> 00:03:01,180
They write code that looks like this.
41
00:03:01,180 --> 00:03:03,533
And clearly, it's a little English-like, but it's not
42
00:03:03,533 --> 00:03:05,950
English in the way you would compose an essay or an email.
43
00:03:05,950 --> 00:03:08,670
Clearly, there's some patterns and some special syntax to it
44
00:03:08,670 --> 00:03:10,750
that will highlight ultimately today.
45
00:03:10,750 --> 00:03:14,740
The problem is, though, that computers, of course, don't understand source code.
46
00:03:14,740 --> 00:03:17,680
They only, per last week, understand zeros and ones.
47
00:03:17,680 --> 00:03:20,500
That is it, the so-called binary system.
48
00:03:20,500 --> 00:03:23,730
So somehow, we've got to get what already looks cryptic into something
49
00:03:23,730 --> 00:03:26,400
that looks at a glance even more cryptic, the zeros and ones
50
00:03:26,400 --> 00:03:27,850
that computers do understand.
51
00:03:27,850 --> 00:03:32,260
And for today's purposes, just know that built into your Macs, PCs and phones,
52
00:03:32,260 --> 00:03:36,340
there is a built in understanding of what these patterns mean.
53
00:03:36,340 --> 00:03:39,220
Maybe it means a number, maybe it means a letter.
54
00:03:39,220 --> 00:03:41,600
But today, maybe it means an instruction,
55
00:03:41,600 --> 00:03:45,770
like print something on the screen, or save something, or load something.
56
00:03:45,770 --> 00:03:48,175
That is to say, computers use patterns of bits
57
00:03:48,175 --> 00:03:50,800
not only to represent all the stuff we talked about last week--
58
00:03:50,800 --> 00:03:54,020
numbers, letters, colors, images, sounds, and all of that,
59
00:03:54,020 --> 00:03:58,130
they also use patterns of bits to represent fundamental functionality.
60
00:03:58,130 --> 00:04:01,910
Print things, play things, much like those same scratch blocks.
61
00:04:01,910 --> 00:04:05,320
But no computer scientist really, unless they take out a paper pencil
62
00:04:05,320 --> 00:04:07,690
or write a program or use a website to convert this
63
00:04:07,690 --> 00:04:09,830
can read this and know what's going on.
64
00:04:09,830 --> 00:04:13,210
That's why we humans are actually going to use not machine code, as it
65
00:04:13,210 --> 00:04:16,110
is called, the zeros and ones that computers understand,
66
00:04:16,110 --> 00:04:17,860
we are going to start writing source code.
67
00:04:17,860 --> 00:04:20,440
And last week you already wrote source code, but in the form
68
00:04:20,440 --> 00:04:22,417
of dragging and dropping those puzzle pieces.
69
00:04:22,417 --> 00:04:25,000
So this too is going to be the paradigm that sort of guides us
70
00:04:25,000 --> 00:04:26,420
through the entire semester.
71
00:04:26,420 --> 00:04:30,500
Problem solving programming is really about input becoming output.
72
00:04:30,500 --> 00:04:33,770
And we'll focus today then on a certain type of input becoming output.
73
00:04:33,770 --> 00:04:37,330
Someone has to get the source code, that's written in a language like C,
74
00:04:37,330 --> 00:04:39,550
into the machine code, the zeros and ones
75
00:04:39,550 --> 00:04:41,480
that the computer actually understands.
76
00:04:41,480 --> 00:04:43,750
So source code today is going to be our input.
77
00:04:43,750 --> 00:04:45,530
Machine code is going to be our output.
78
00:04:45,530 --> 00:04:48,220
And we're going to give you today a special program called
79
00:04:48,220 --> 00:04:52,852
a compiler, whose purpose in life is to translate one to the other.
80
00:04:52,852 --> 00:04:55,310
And there's compilers for different languages in the world.
81
00:04:55,310 --> 00:04:58,880
We're going to focus on one that supports today's language, known as C.
82
00:04:58,880 --> 00:05:01,570
And here, as promised, is the programming environment
83
00:05:01,570 --> 00:05:02,660
we are going to use.
84
00:05:02,660 --> 00:05:04,600
It's tailored to CS50, which is to say, we've
85
00:05:04,600 --> 00:05:08,360
pre-installed certain software that you might find useful during the term.
86
00:05:08,360 --> 00:05:12,010
But for all intents and purposes, the tool you will use for CS50 problem sets
87
00:05:12,010 --> 00:05:15,910
henceforth is a very popular industry standard tool called Visual Studio
88
00:05:15,910 --> 00:05:18,020
Code, or VS Code for short.
89
00:05:18,020 --> 00:05:19,990
We are using a cloud based version of it that
90
00:05:19,990 --> 00:05:22,580
lives at literally this URL, cs50.dev.
91
00:05:22,580 --> 00:05:26,740
You can sign in to that so long as you have a free GitHub account, for which
92
00:05:26,740 --> 00:05:28,400
you signed up presumably already.
93
00:05:28,400 --> 00:05:31,690
And that will give you access to not only an industry standard programming
94
00:05:31,690 --> 00:05:35,650
environment, but again, an environment that has some CS50 specific things
95
00:05:35,650 --> 00:05:36,530
pre-installed.
96
00:05:36,530 --> 00:05:38,780
And at the end of the semester, or even in the middle,
97
00:05:38,780 --> 00:05:42,520
if you so you're so inclined, you can actually download for free VS Code
98
00:05:42,520 --> 00:05:43,805
onto your Mac, PC.
99
00:05:43,805 --> 00:05:46,180
You can disconnect from the internet and you can actually
100
00:05:46,180 --> 00:05:48,140
program on your own computer.
101
00:05:48,140 --> 00:05:50,770
Caveat, though, is that you tend to hit technical support
102
00:05:50,770 --> 00:05:52,638
headaches in the very beginning of the term,
103
00:05:52,638 --> 00:05:54,430
so we suggest you do that later in the term
104
00:05:54,430 --> 00:05:57,730
once you're already comfortable with this cloud based environment here.
105
00:05:57,730 --> 00:05:58,870
And here it is.
106
00:05:58,870 --> 00:06:01,040
This is what programming shall look like,
107
00:06:01,040 --> 00:06:05,440
whether we're using C now or Python in a few weeks or JavaScript or SQL
108
00:06:05,440 --> 00:06:06,260
thereafter.
109
00:06:06,260 --> 00:06:10,250
So here is what looks-- what is VS Code configured as follows.
110
00:06:10,250 --> 00:06:13,430
At the top right, you'll generally have one or more tabs for code,
111
00:06:13,430 --> 00:06:14,597
much like tabs in a browser.
112
00:06:14,597 --> 00:06:17,763
And this is where you'll write code that looks a little something like this.
113
00:06:17,763 --> 00:06:20,690
And in fact, this is exactly the code that you saw a moment ago.
114
00:06:20,690 --> 00:06:23,530
What VS Code does, among other things, is it actually
115
00:06:23,530 --> 00:06:25,010
highlights your code for you.
116
00:06:25,010 --> 00:06:29,270
It colorizes it in what's generally an illuminating way.
117
00:06:29,270 --> 00:06:31,190
So I did not choose to make this red.
118
00:06:31,190 --> 00:06:33,350
I did not choose to make this blue and this purple.
119
00:06:33,350 --> 00:06:35,600
The computer sort of automatically does that for you,
120
00:06:35,600 --> 00:06:40,730
as we'll soon see to draw your attention to different ideas in the program itself
121
00:06:40,730 --> 00:06:42,490
that all happens automatically.
122
00:06:42,490 --> 00:06:45,790
At the bottom here, you're going to use a more advanced interface today
123
00:06:45,790 --> 00:06:49,540
onward, known as a command line interface in the form of a terminal
124
00:06:49,540 --> 00:06:50,060
window.
125
00:06:50,060 --> 00:06:52,300
So you can still use your mouse or trackpad
126
00:06:52,300 --> 00:06:55,280
and click and drag and do things like that in this environment.
127
00:06:55,280 --> 00:06:58,090
But you'll find, and many programmers prefer
128
00:06:58,090 --> 00:07:02,050
that it's much more efficient ultimately to use your keyboard more
129
00:07:02,050 --> 00:07:03,920
often than the mouse or the trackpad.
130
00:07:03,920 --> 00:07:07,220
So we'll introduce you to that text based terminal window there.
131
00:07:07,220 --> 00:07:09,620
Up here at top left, you'll have a File Explorer.
132
00:07:09,620 --> 00:07:12,070
So what's nice about VS Code is that not only will you
133
00:07:12,070 --> 00:07:14,300
have textual commands, with which you'll get comfy,
134
00:07:14,300 --> 00:07:17,145
you also have a normal Mac or PC or phone nowadays,
135
00:07:17,145 --> 00:07:21,670
like literally files and folders will visually appear to you
136
00:07:21,670 --> 00:07:23,632
so you can play with or manipulate them there.
137
00:07:23,632 --> 00:07:26,590
And then, lastly, this is sort of like the menu, the so-called activity
138
00:07:26,590 --> 00:07:31,280
bar that just has icons for various features, including CS50's duck.
139
00:07:31,280 --> 00:07:33,550
So in fact, if you poke around, you'll see ultimately
140
00:07:33,550 --> 00:07:37,450
a duck icon when you log in, which is your own CS50 specific chat
141
00:07:37,450 --> 00:07:41,020
bot of which you can ask questions throughout the process.
142
00:07:41,020 --> 00:07:44,050
So now that we've got VS Code here, let's go ahead
143
00:07:44,050 --> 00:07:46,880
and actually consider what it represents.
144
00:07:46,880 --> 00:07:50,420
So this is generally, for jargon sake, a graphical user interface,
145
00:07:50,420 --> 00:07:52,880
which means buttons and icons and menus and all of that.
146
00:07:52,880 --> 00:07:55,750
We all take that for granted on most any device nowadays.
147
00:07:55,750 --> 00:08:00,490
That's abbreviated, just so you know, as GUI, G-U-I. But built into VS Code,
148
00:08:00,490 --> 00:08:03,890
again, is what's not only the terminal window by name,
149
00:08:03,890 --> 00:08:06,795
but conceptually this is a command line interface.
150
00:08:06,795 --> 00:08:10,720
So not a graphical user interface, but a command line interface,
151
00:08:10,720 --> 00:08:14,120
whereby there aren't icons to click on or double click on.
152
00:08:14,120 --> 00:08:16,150
Rather, if you want to run a program, you
153
00:08:16,150 --> 00:08:20,830
use the command line interface, or CLI, to type the name of the program
154
00:08:20,830 --> 00:08:21,802
that you want to run.
155
00:08:21,802 --> 00:08:24,010
And so this will feel like a step backwards initially
156
00:08:24,010 --> 00:08:28,280
today, because we all tap and point and double click on things nowadays.
157
00:08:28,280 --> 00:08:31,210
But again, it's going to give us more power, more efficiency
158
00:08:31,210 --> 00:08:33,260
ultimately beyond this.
159
00:08:33,260 --> 00:08:37,120
So with that said, let's go ahead and actually use it for just a moment.
160
00:08:37,120 --> 00:08:39,020
During class, you're welcome to follow along.
161
00:08:39,020 --> 00:08:41,760
But suffice it to say, we'll generally go somewhat quickly.
162
00:08:41,760 --> 00:08:45,930
Really, you're going to learn how to program by way of the problem sets
163
00:08:45,930 --> 00:08:46,880
each week.
164
00:08:46,880 --> 00:08:48,960
I'll introduce and focus on the concepts,
165
00:08:48,960 --> 00:08:51,510
the ideas, the sort of primitives that will get you started,
166
00:08:51,510 --> 00:08:55,130
but only through actually doing the problem sets is the muscle memory
167
00:08:55,130 --> 00:08:56,550
and practice going to come.
168
00:08:56,550 --> 00:09:00,450
So not to worry if it doesn't all go down easily the first time around.
169
00:09:00,450 --> 00:09:03,650
So here is the code that I claim is equivalent to last week's
170
00:09:03,650 --> 00:09:04,920
Hello, world program.
171
00:09:04,920 --> 00:09:07,770
Let's actually go ahead and do this in the programming environment.
172
00:09:07,770 --> 00:09:09,895
So I'm going to go ahead and switch over to VS Code
173
00:09:09,895 --> 00:09:12,090
itself, which is now running on my Mac here.
174
00:09:12,090 --> 00:09:13,280
It's not just a screenshot.
175
00:09:13,280 --> 00:09:15,590
And I'm going to go ahead and do the following
176
00:09:15,590 --> 00:09:17,280
to get started with programming.
177
00:09:17,280 --> 00:09:20,820
I'm going to write literally in my terminal window, the word code,
178
00:09:20,820 --> 00:09:23,090
and I might have to give it focus by clicking down
179
00:09:23,090 --> 00:09:24,780
in that quadrant of the screen.
180
00:09:24,780 --> 00:09:28,260
And then I'm going to give the name of the file that I want to code.
181
00:09:28,260 --> 00:09:31,490
And in this case, I'm going to propose that we call it hello.c.
182
00:09:31,490 --> 00:09:33,600
In the world of Scratch, when you downloaded it,
183
00:09:33,600 --> 00:09:37,520
you might have noticed the files are all called like SB3 or some such file
184
00:09:37,520 --> 00:09:38,190
extension.
185
00:09:38,190 --> 00:09:40,430
When writing code in C, you literally name
186
00:09:40,430 --> 00:09:43,240
the file something dot C by convention.
187
00:09:43,240 --> 00:09:44,490
But notice some other details.
188
00:09:44,490 --> 00:09:47,730
Especially if I zoom in, everything I've typed thus far is lowercase.
189
00:09:47,730 --> 00:09:49,500
There's no spaces.
190
00:09:49,500 --> 00:09:51,150
And so this is going to be important.
191
00:09:51,150 --> 00:09:53,580
And unfortunately, computers are not forgiving.
192
00:09:53,580 --> 00:09:55,700
And odds are one of the first stupid mistakes
193
00:09:55,700 --> 00:09:58,890
you'll do is miscapitalize something, misspell something,
194
00:09:58,890 --> 00:10:00,335
add too many spaces or the like.
195
00:10:00,335 --> 00:10:01,310
Not to worry.
196
00:10:01,310 --> 00:10:04,470
In time, that kind of muscle memory will come with practice.
197
00:10:04,470 --> 00:10:05,550
So let me zoom out.
198
00:10:05,550 --> 00:10:08,450
Let me now just hit Enter and you'll see at top right
199
00:10:08,450 --> 00:10:10,320
the Code tab that I promised.
200
00:10:10,320 --> 00:10:13,070
So I'm going to go ahead and type out this program pretty quickly,
201
00:10:13,070 --> 00:10:14,370
because I've done it before.
202
00:10:14,370 --> 00:10:21,030
Include stdio.h, int main void, and then some curly braces, as they're called,
203
00:10:21,030 --> 00:10:22,710
and then printf quote unquote.
204
00:10:22,710 --> 00:10:26,260
Hello, comma, world, backslash n, close quote, semicolon.
205
00:10:26,260 --> 00:10:26,760
All right.
206
00:10:26,760 --> 00:10:27,510
So that's a lot.
207
00:10:27,510 --> 00:10:29,730
But that too will come in time with practice.
208
00:10:29,730 --> 00:10:33,150
But this is the exact same code that we saw just a moment ago.
209
00:10:33,150 --> 00:10:36,420
Indeed, if I zoom in, it's color coded just as in the screenshot,
210
00:10:36,420 --> 00:10:38,660
and thus I have written my first program.
211
00:10:38,660 --> 00:10:41,090
VS Code will automatically save for you, but you can also
212
00:10:41,090 --> 00:10:43,590
hit control or Command S to ensure that it's saved.
213
00:10:43,590 --> 00:10:45,720
But notice what's happened at top left.
214
00:10:45,720 --> 00:10:48,800
Not only do you see my code over here, you
215
00:10:48,800 --> 00:10:51,050
see a visual icon, just like on a Mac or PC
216
00:10:51,050 --> 00:10:54,290
that, yes, this file now exists in your account.
217
00:10:54,290 --> 00:10:57,330
And that too is what you're getting with VS Code for CS50.
218
00:10:57,330 --> 00:11:00,330
You're getting your own sort of server in the cloud.
219
00:11:00,330 --> 00:11:01,890
It's called a container nowadays.
220
00:11:01,890 --> 00:11:05,840
So there's some virtual disk space somewhere in the cloud, ala iCloud
221
00:11:05,840 --> 00:11:08,400
or Google Drive, that's going to store all of your files.
222
00:11:08,400 --> 00:11:11,490
And at the moment, because I refreshed my account before class,
223
00:11:11,490 --> 00:11:14,490
I only have one file in my own account.
224
00:11:14,490 --> 00:11:15,210
What's this?
225
00:11:15,210 --> 00:11:15,840
What's this?
226
00:11:15,840 --> 00:11:17,893
Well, this is like my ID number for GitHub.
227
00:11:17,893 --> 00:11:18,810
Not really a big deal.
228
00:11:18,810 --> 00:11:21,080
That's just randomly generated by GitHub.
229
00:11:21,080 --> 00:11:24,930
Urban Adventure is the name of my programming environment today,
230
00:11:24,930 --> 00:11:26,490
otherwise known as a code space.
231
00:11:26,490 --> 00:11:30,000
This is just a GitHub thing which is, again, one of these cloud companies.
232
00:11:30,000 --> 00:11:32,360
Instead of choosing random letters and numbers
233
00:11:32,360 --> 00:11:35,617
to uniquely identify all of our programming environments,
234
00:11:35,617 --> 00:11:37,700
it's popular in the tech industry nowadays to just
235
00:11:37,700 --> 00:11:41,310
put together random English words that sometimes sound kind of cool.
236
00:11:41,310 --> 00:11:43,560
But it's just by coincidence, not something I chose.
237
00:11:43,560 --> 00:11:45,920
Yours will be different.
238
00:11:45,920 --> 00:11:48,150
All right, so I've written some code.
239
00:11:48,150 --> 00:11:49,710
I created hello.c.
240
00:11:49,710 --> 00:11:51,210
I typed in all of that code.
241
00:11:51,210 --> 00:11:53,700
I confirmed visually at left that it was created.
242
00:11:53,700 --> 00:11:55,950
I'm going to hide my File Explorer henceforth, just so
243
00:11:55,950 --> 00:11:57,217
that we can focus on the code.
244
00:11:57,217 --> 00:11:58,675
How do I actually run this program?
245
00:11:58,675 --> 00:12:02,297
Well, on a Mac or a PC, we would be in the habit of like opening the folder
246
00:12:02,297 --> 00:12:03,380
and double clicking on it.
247
00:12:03,380 --> 00:12:06,060
Or on your phone, you would take it out and tap on an icon.
248
00:12:06,060 --> 00:12:06,960
But not here.
249
00:12:06,960 --> 00:12:10,610
Here, we're focusing primarily on the command line interface
250
00:12:10,610 --> 00:12:12,720
within this whole environment.
251
00:12:12,720 --> 00:12:16,260
So I'm actually going to have to introduce a few commands.
252
00:12:16,260 --> 00:12:19,400
You saw already the code command, which for our purposes
253
00:12:19,400 --> 00:12:24,600
is VS Code specific, that just creates a new file called hello.c in this case.
254
00:12:24,600 --> 00:12:27,720
But I need two other commands to actually run this program.
255
00:12:27,720 --> 00:12:29,960
The first nicely is called make, and then
256
00:12:29,960 --> 00:12:32,070
I specify what program I want to make.
257
00:12:32,070 --> 00:12:35,190
And then a little weirdly, I have to type dot slash hello.
258
00:12:35,190 --> 00:12:37,830
But just to take a step back, make hello.
259
00:12:37,830 --> 00:12:40,410
If this is about to be my second command that I type,
260
00:12:40,410 --> 00:12:43,790
what does that step represent, perhaps?
261
00:12:43,790 --> 00:12:45,872
Given what I said just a minute or so ago.
262
00:12:45,872 --> 00:12:48,955
AUDIENCE: That's going to translate your source code into ones and zeroes.
263
00:12:48,955 --> 00:12:49,955
DAVID J. MALAN: Perfect.
264
00:12:49,955 --> 00:12:52,630
So make represents the compiler, so to speak, the program that
265
00:12:52,630 --> 00:12:54,940
converts source code to machine code.
266
00:12:54,940 --> 00:12:58,210
I have to do that for now manually by running make hello.
267
00:12:58,210 --> 00:13:00,250
Now, make is kind of smart, and even though I'm
268
00:13:00,250 --> 00:13:04,280
saying make hello, not make hello.c, make it smart, and it's going to say,
269
00:13:04,280 --> 00:13:06,610
if you want to make a program called hello, I'm
270
00:13:06,610 --> 00:13:10,820
going to assume that there is somewhere in this folder a file called hello.c.
271
00:13:10,820 --> 00:13:12,530
So you should not type make hello.c.
272
00:13:12,530 --> 00:13:13,960
You just type make hello.
273
00:13:13,960 --> 00:13:18,500
And then this third command, even more cryptic, what might it do?
274
00:13:18,500 --> 00:13:21,200
If this is step three of three.
275
00:13:21,200 --> 00:13:23,250
That's going to run the machine code.
276
00:13:23,250 --> 00:13:25,890
It's going to tell the computer in this folder,
277
00:13:25,890 --> 00:13:29,030
the dot implies this current folder, and dot slash just
278
00:13:29,030 --> 00:13:30,870
means something in this current folder.
279
00:13:30,870 --> 00:13:32,730
Run the program called Hello.
280
00:13:32,730 --> 00:13:33,390
So that's it.
281
00:13:33,390 --> 00:13:35,580
Like there's three steps to writing a program in C.
282
00:13:35,580 --> 00:13:37,770
You create the file, as with the code command.
283
00:13:37,770 --> 00:13:39,030
But there are other ways to do that too.
284
00:13:39,030 --> 00:13:40,655
And you don't even have to use VS Code.
285
00:13:40,655 --> 00:13:43,410
You can use dozens of other alternative programs in the world.
286
00:13:43,410 --> 00:13:46,260
You run the compiler, which, in this case, is called make.
287
00:13:46,260 --> 00:13:48,860
Little white lie, make's not actually the compiler, but more
288
00:13:48,860 --> 00:13:49,770
on that next week.
289
00:13:49,770 --> 00:13:54,210
But make is going to trigger compilation of this code.
290
00:13:54,210 --> 00:13:58,290
And the last step three is to execute, or run the program called Hello.
291
00:13:58,290 --> 00:14:00,380
So let me go back to VS Code here.
292
00:14:00,380 --> 00:14:03,030
And you'll see that my code is still at the top.
293
00:14:03,030 --> 00:14:04,530
My terminal window is at the bottom.
294
00:14:04,530 --> 00:14:07,488
I hid my File Explorer, just because it's not that interesting anymore.
295
00:14:07,488 --> 00:14:12,560
And I'm going to do what you proposed, which was M-A-K-E space hello.
296
00:14:12,560 --> 00:14:14,090
All lowercase.
297
00:14:14,090 --> 00:14:15,420
Enter.
298
00:14:15,420 --> 00:14:18,132
And ironically, thankfully, nothing happened.
299
00:14:18,132 --> 00:14:20,340
And that's actually a good thing in this environment.
300
00:14:20,340 --> 00:14:22,990
If nothing seems to happen you probably did, good.
301
00:14:22,990 --> 00:14:25,920
If anything does seem to happen on the screen, you probably screwed up
302
00:14:25,920 --> 00:14:27,310
and you've made some mistake.
303
00:14:27,310 --> 00:14:29,590
So seeing nothing is generally a good thing.
304
00:14:29,590 --> 00:14:30,790
But what has happened?
305
00:14:30,790 --> 00:14:34,260
Well, let me actually go back and open up my File Explorer.
306
00:14:34,260 --> 00:14:38,710
And notice, there's not only hello.c, but there's a second file now.
307
00:14:38,710 --> 00:14:41,650
Hello, which is the name of the program.
308
00:14:41,650 --> 00:14:44,530
So Hello is the program I want to run.
309
00:14:44,530 --> 00:14:47,620
I'm going to go back to my terminal here and to run this program,
310
00:14:47,620 --> 00:14:51,040
I'm going to do dot slash H-E-L-L-O. I'm going to cross my fingers,
311
00:14:51,040 --> 00:14:57,150
as I'll often now do, and voila, my very first program in C.
312
00:14:57,150 --> 00:14:59,140
How else can we see this file?
313
00:14:59,140 --> 00:15:00,880
Well, down here in my terminal window.
314
00:15:00,880 --> 00:15:01,593
Let me zoom in.
315
00:15:01,593 --> 00:15:02,760
You keep seeing dollar sign.
316
00:15:02,760 --> 00:15:04,302
That has nothing to do with currency.
317
00:15:04,302 --> 00:15:07,380
It's just a weird, geeky convention that your prompt at a terminal
318
00:15:07,380 --> 00:15:10,750
window, like where you type commands, generally starts with a dollar sign.
319
00:15:10,750 --> 00:15:12,010
Sometimes it's a hash symbol.
320
00:15:12,010 --> 00:15:13,702
Sometimes it's an angled bracket.
321
00:15:13,702 --> 00:15:15,160
It depends on the system you're on.
322
00:15:15,160 --> 00:15:16,630
But dollar sign is very common.
323
00:15:16,630 --> 00:15:18,480
It just means type your commands here.
324
00:15:18,480 --> 00:15:21,910
Well, I've typed code, I've typed make, and I've typed dot slash hello.
325
00:15:21,910 --> 00:15:23,470
But I can type other things too.
326
00:15:23,470 --> 00:15:24,600
And more on these later.
327
00:15:24,600 --> 00:15:28,620
Like ls, which doesn't actually spell something, but is short for list,
328
00:15:28,620 --> 00:15:32,140
L-I-S-T. Programmers tend to just be as succinct as they can,
329
00:15:32,140 --> 00:15:33,760
so most commands are not full words.
330
00:15:33,760 --> 00:15:35,770
They're often abbreviations.
331
00:15:35,770 --> 00:15:39,340
If I hit Enter now, you'll see also two things.
332
00:15:39,340 --> 00:15:40,890
You'll see hello.c.
333
00:15:40,890 --> 00:15:44,770
And you'll see in green, just to draw attention to it, hello as well.
334
00:15:44,770 --> 00:15:48,310
The asterisk here just means in the programming environment,
335
00:15:48,310 --> 00:15:50,050
this program is executable.
336
00:15:50,050 --> 00:15:52,810
Like you can actually run this by doing dot slash hello.
337
00:15:52,810 --> 00:15:56,140
The fact that this is just white here, that just means it's some text file.
338
00:15:56,140 --> 00:15:57,860
It's in fact source code.
339
00:15:57,860 --> 00:16:01,700
So in other words, ls lists the file in my current folder.
340
00:16:01,700 --> 00:16:04,810
Or you can use your human eyes in the File Explorer at top left
341
00:16:04,810 --> 00:16:06,800
and just look at what files exist.
342
00:16:06,800 --> 00:16:07,930
These are one and the same.
343
00:16:07,930 --> 00:16:10,120
One is a GUI one, is a CLI.
344
00:16:10,120 --> 00:16:11,960
Graphical command line.
345
00:16:11,960 --> 00:16:12,620
And so forth.
346
00:16:12,620 --> 00:16:18,020
And we'll start to take these kinds of paradigms soon for granted.
347
00:16:18,020 --> 00:16:20,320
But let me pause here and see thus far, now
348
00:16:20,320 --> 00:16:23,980
that we've written our first of many C programs, any questions?
349
00:16:23,980 --> 00:16:27,263
Or confusion we can clear up?
350
00:16:27,263 --> 00:16:29,680
It's OK if you don't understand most of the lines of code.
351
00:16:29,680 --> 00:16:31,150
That's what today is about.
352
00:16:31,150 --> 00:16:31,996
Yeah.
353
00:16:31,996 --> 00:16:34,480
AUDIENCE: I don't fully understand the difference between hello and hello.c.
354
00:16:34,480 --> 00:16:37,147
DAVID J. MALAN: What's the difference between hello and hello.c?
355
00:16:37,147 --> 00:16:38,928
So hello.c is literally my source code.
356
00:16:38,928 --> 00:16:41,470
It is a file that exists somewhere in the cloud that contains
357
00:16:41,470 --> 00:16:43,185
all of the code I myself wrote.
358
00:16:43,185 --> 00:16:47,680
The hello file is the file that the compiler
359
00:16:47,680 --> 00:16:51,920
created for me by converting the source code to the machine code.
360
00:16:51,920 --> 00:16:55,400
So inside of hello, theoretically, is a whole bunch of zeros and ones.
361
00:16:55,400 --> 00:16:57,170
We can't quite see them.
362
00:16:57,170 --> 00:16:59,260
But if I do this, let me zoom out.
363
00:16:59,260 --> 00:17:00,700
Let me click on hello.
364
00:17:00,700 --> 00:17:02,750
And notice that VS Code is going to yell at me.
365
00:17:02,750 --> 00:17:06,220
This file-- the file is not displayed in the text editor because it is either
366
00:17:06,220 --> 00:17:06,880
binary--
367
00:17:06,880 --> 00:17:09,730
that is zeros and ones-- or uses an unsupported text
368
00:17:09,730 --> 00:17:11,089
encoding, whatever that means.
369
00:17:11,089 --> 00:17:13,609
If I do open it anyway, but I don't recommend this.
370
00:17:13,609 --> 00:17:14,990
Like heed these warnings.
371
00:17:14,990 --> 00:17:19,010
You won't see zeros and ones, but you will see sort of nonsense.
372
00:17:19,010 --> 00:17:22,450
And this is because VS Code is trying to interpret those zeros
373
00:17:22,450 --> 00:17:25,970
and ones incorrectly, as ASCII text, like English text.
374
00:17:25,970 --> 00:17:26,710
But it's not.
375
00:17:26,710 --> 00:17:28,760
They're instructions for the computer.
376
00:17:28,760 --> 00:17:31,540
So as soon as you see scary red stuff like this, like undo,
377
00:17:31,540 --> 00:17:33,880
close whatever tab you open, because odds are you
378
00:17:33,880 --> 00:17:36,145
can only break the program you just created.
379
00:17:36,145 --> 00:17:37,020
It's not a huge deal.
380
00:17:37,020 --> 00:17:38,070
You can recreate it.
381
00:17:38,070 --> 00:17:41,560
But that's what's inside of those files.
382
00:17:41,560 --> 00:17:42,570
Yeah.
383
00:17:42,570 --> 00:17:46,708
AUDIENCE: What if [? you don't ?] [INAUDIBLE]?
384
00:17:46,708 --> 00:17:48,250
DAVID J. MALAN: Really good question.
385
00:17:48,250 --> 00:17:50,820
What if we don't type dot slash hello we, just type hello.
386
00:17:50,820 --> 00:17:51,490
Well, let me do this.
387
00:17:51,490 --> 00:17:53,448
Let me hide my File Explorer again because it's
388
00:17:53,448 --> 00:17:55,440
not that interesting here on out.
389
00:17:55,440 --> 00:17:58,470
I'm going to clear my terminal window by hitting Control L,
390
00:17:58,470 --> 00:17:59,980
just to be neat and tidy in class.
391
00:17:59,980 --> 00:18:02,050
Or you can literally type clear and it will clear it.
392
00:18:02,050 --> 00:18:03,842
But again, that's just to keep things tidy.
393
00:18:03,842 --> 00:18:05,530
Your TFs might do that in section 2.
394
00:18:05,530 --> 00:18:07,598
If I just type Hello, enter.
395
00:18:07,598 --> 00:18:08,890
I'm going to get this, weirdly.
396
00:18:08,890 --> 00:18:10,870
Bash, hello, command not found.
397
00:18:10,870 --> 00:18:12,302
So more on bash down the line.
398
00:18:12,302 --> 00:18:14,010
But this just means literally the command
399
00:18:14,010 --> 00:18:16,960
hello is not found because you need to tell the computer where it is.
400
00:18:16,960 --> 00:18:22,360
So dot slash hello means run the hello program that is, in fact, right here.
401
00:18:22,360 --> 00:18:27,210
By contrast, you don't run dot slash for code, for make,
402
00:18:27,210 --> 00:18:30,180
or other commands that we'll soon see, like ls, because why?
403
00:18:30,180 --> 00:18:32,890
Those are installed in the system for everyone,
404
00:18:32,890 --> 00:18:34,578
not just in your individual folder.
405
00:18:34,578 --> 00:18:35,620
So that's the difference.
406
00:18:35,620 --> 00:18:38,970
Any programs we write, it'll be dot slash something.
407
00:18:38,970 --> 00:18:42,930
All right, so let's tease apart what is actually going on here
408
00:18:42,930 --> 00:18:45,610
and see if we can lean heavily today on Scratch,
409
00:18:45,610 --> 00:18:48,650
especially as the syntax gets weird, perhaps a little overwhelming.
410
00:18:48,650 --> 00:18:49,940
Still the same idea.
411
00:18:49,940 --> 00:18:52,540
So this last time, of course, was our Scratch program
412
00:18:52,540 --> 00:18:53,960
that just said Hello, world.
413
00:18:53,960 --> 00:18:58,270
I claim today that this is the nearest equivalent that any programmer can
414
00:18:58,270 --> 00:19:02,120
convert Scratch into C. If we color coded it accordingly, indeed,
415
00:19:02,120 --> 00:19:05,350
this sort of lines up with when green flag clicked is the orange.
416
00:19:05,350 --> 00:19:08,150
And then the purple is just the equivalent of the say block.
417
00:19:08,150 --> 00:19:10,610
So the say block, we said earlier, was a function.
418
00:19:10,610 --> 00:19:12,490
So let's compare these things side by side
419
00:19:12,490 --> 00:19:16,060
because there's actually some rhyme and reason to what MIT did with Scratch,
420
00:19:16,060 --> 00:19:19,610
as to why these shapes look like they do and so forth.
421
00:19:19,610 --> 00:19:22,460
So in Scratch, there's a function called say.
422
00:19:22,460 --> 00:19:25,840
Recall that it takes an input, otherwise known as an argument,
423
00:19:25,840 --> 00:19:27,860
or a parameter is another name.
424
00:19:27,860 --> 00:19:32,020
And that's always provided in these white ovals, zero or more white ovals.
425
00:19:32,020 --> 00:19:35,170
In C, we've already seen, but let's do it a little more pedantically,
426
00:19:35,170 --> 00:19:38,750
the equivalent say is essentially the word print.
427
00:19:38,750 --> 00:19:40,625
Why did MIT say you say?
428
00:19:40,625 --> 00:19:42,500
Just because it's a little more kid friendly.
429
00:19:42,500 --> 00:19:44,505
But print is the idea in our environment.
430
00:19:44,505 --> 00:19:46,630
It's actually not print, it's printf, because we're
431
00:19:46,630 --> 00:19:48,890
going to be able to format our text in interesting ways.
432
00:19:48,890 --> 00:19:49,932
More on that in a moment.
433
00:19:49,932 --> 00:19:52,930
But notice, the opening parentheses and closing parentheses
434
00:19:52,930 --> 00:19:56,210
here conjure up the idea of that white oval.
435
00:19:56,210 --> 00:19:58,700
So that's kind of intentional on MIT's part.
436
00:19:58,700 --> 00:20:01,460
What, though, in C goes between these parentheses?
437
00:20:01,460 --> 00:20:04,030
Well, literally the input or the argument
438
00:20:04,030 --> 00:20:06,530
you want to pass to the function, like Hello, world.
439
00:20:06,530 --> 00:20:09,010
But in C, you have to be a little more pedantic because you
440
00:20:09,010 --> 00:20:12,500
don't have a nice little graphic like this purple block with the white oval.
441
00:20:12,500 --> 00:20:15,272
You have to surround everything in double quotes.
442
00:20:15,272 --> 00:20:17,230
Those of you with prior programming experience,
443
00:20:17,230 --> 00:20:21,110
in C, you need double quotes, not single quotes in this context.
444
00:20:21,110 --> 00:20:23,290
And then there's this arcane detail here,
445
00:20:23,290 --> 00:20:26,660
backslash n, which we'll come back to in just a moment.
446
00:20:26,660 --> 00:20:30,920
But that's essentially what's going on, line by line from Scratch to C,
447
00:20:30,920 --> 00:20:33,880
there's kind of an equality between those two, even though,
448
00:20:33,880 --> 00:20:36,440
of course, look a little bit different.
449
00:20:36,440 --> 00:20:39,370
Well, let's see what that backslash n is doing, just
450
00:20:39,370 --> 00:20:40,790
to highlight some details here.
451
00:20:40,790 --> 00:20:45,200
So let me actually zoom in a little bit here and let me go up to my code.
452
00:20:45,200 --> 00:20:48,850
And let me just recklessly delete the backslash n.
453
00:20:48,850 --> 00:20:50,330
I'm going to let it auto save.
454
00:20:50,330 --> 00:20:51,070
I'll zoom out.
455
00:20:51,070 --> 00:20:55,750
In my terminal window now, I'm going to run make hello
456
00:20:55,750 --> 00:20:58,960
to recompile the code from source code to machine code,
457
00:20:58,960 --> 00:21:00,950
because I changed the source code.
458
00:21:00,950 --> 00:21:02,090
Nothing seems to happen.
459
00:21:02,090 --> 00:21:02,840
That's good.
460
00:21:02,840 --> 00:21:06,230
Now I'm going to type dot slash hello, enter.
461
00:21:06,230 --> 00:21:10,340
And there's a subtle bug.
462
00:21:10,340 --> 00:21:11,970
Since I made that change.
463
00:21:11,970 --> 00:21:14,962
What looks wrong to your eye now?
464
00:21:14,962 --> 00:21:16,545
AUDIENCE: The dollar sign [INAUDIBLE].
465
00:21:16,545 --> 00:21:19,004
DAVID J. MALAN: Yeah, the dollar sign, our so-called prompt
466
00:21:19,004 --> 00:21:21,252
is at the end of the line instead of on its new line.
467
00:21:21,252 --> 00:21:22,960
I mean, this isn't really a deal breaker.
468
00:21:22,960 --> 00:21:25,400
Like the code works, and you can still type a new command.
469
00:21:25,400 --> 00:21:26,817
But it just looks a little stupid.
470
00:21:26,817 --> 00:21:28,760
Like this was not the intent of the program.
471
00:21:28,760 --> 00:21:31,790
It's sort of good practice to move the prompt to the next line,
472
00:21:31,790 --> 00:21:33,825
and that's because the backslash n is what
473
00:21:33,825 --> 00:21:35,450
we're going to call an escape sequence.
474
00:21:35,450 --> 00:21:40,360
So it turns out in programming, you have to tell the computer exactly what you
475
00:21:40,360 --> 00:21:41,330
want it to do.
476
00:21:41,330 --> 00:21:44,620
So if you want a new line, the equivalent of hitting Enter
477
00:21:44,620 --> 00:21:48,350
on the screen, you have to tell the computer to put a new line there.
478
00:21:48,350 --> 00:21:50,330
What you do not do is this.
479
00:21:50,330 --> 00:21:54,620
If I zoom out and I go into my code here, and I'll zoom in on the code--
480
00:21:54,620 --> 00:21:58,100
if you want to put a new line, you don't do this.
481
00:21:58,100 --> 00:21:58,750
Why?
482
00:21:58,750 --> 00:22:00,680
It's just confusing for the computer.
483
00:22:00,680 --> 00:22:02,240
Like, wait a minute, is that a typo?
484
00:22:02,240 --> 00:22:03,700
Did your lines just wrap.
485
00:22:03,700 --> 00:22:05,285
Do you want to put a new line there.
486
00:22:05,285 --> 00:22:06,160
It just looks stupid.
487
00:22:06,160 --> 00:22:09,260
And it makes it less line based, the code itself.
488
00:22:09,260 --> 00:22:12,530
So humans decided years ago, if you want an actual line break,
489
00:22:12,530 --> 00:22:14,420
don't just naively hit the Enter key.
490
00:22:14,420 --> 00:22:17,190
Literally tell the computer, put a new line here.
491
00:22:17,190 --> 00:22:20,310
If you want to move two lines down, just do two of those.
492
00:22:20,310 --> 00:22:22,380
If you want three, just do three of those.
493
00:22:22,380 --> 00:22:23,730
Well, why the backslash?
494
00:22:23,730 --> 00:22:26,190
Again, these are what are called escape sequences.
495
00:22:26,190 --> 00:22:29,690
And you don't literally want an n, let alone [? an ?] n n.
496
00:22:29,690 --> 00:22:32,630
What you want is a new line, which is represented
497
00:22:32,630 --> 00:22:36,200
in code as simply backslash n.
498
00:22:36,200 --> 00:22:38,870
Now, for the mathematicians among you, what
499
00:22:38,870 --> 00:22:41,847
we're doing now by writing, using functions like printf
500
00:22:41,847 --> 00:22:44,180
is just sort of like f of x notation, if you recall that
501
00:22:44,180 --> 00:22:46,640
from high school or prior, where f is a function,
502
00:22:46,640 --> 00:22:49,280
x is an argument or an input thereto, and we're
503
00:22:49,280 --> 00:22:52,520
using parentheses in code, just like mathematicians would,
504
00:22:52,520 --> 00:22:54,360
to write functions like these.
505
00:22:54,360 --> 00:22:57,660
And the types of functions we're using right now still follow this model.
506
00:22:57,660 --> 00:22:59,340
You've got input, you want output.
507
00:22:59,340 --> 00:23:03,620
In this case, the input to printf, for instance, just like the say block,
508
00:23:03,620 --> 00:23:05,220
is what's called an argument.
509
00:23:05,220 --> 00:23:09,178
The output, though, of the function printf is what we call a side effect.
510
00:23:09,178 --> 00:23:12,470
And the easiest way to think about that is a side effect is just something that
511
00:23:12,470 --> 00:23:17,720
sort of happens on the screen, visually, [? audibly. ?] It just sort of happens.
512
00:23:17,720 --> 00:23:19,530
And there's that effect on the screen.
513
00:23:19,530 --> 00:23:22,680
And we'll contrast this with other types of outputs from functions.
514
00:23:22,680 --> 00:23:26,040
But for now, we're focusing on just this, which is reminiscent,
515
00:23:26,040 --> 00:23:27,830
of course, of what we did last week, which
516
00:23:27,830 --> 00:23:32,220
is if you type Hello, world into the white oval, use the say puzzle piece,
517
00:23:32,220 --> 00:23:37,260
you get out the side effect of the cat appearing to have said hello, world.
518
00:23:37,260 --> 00:23:41,400
Now, as for those escape sequences in C, there's bunches of them,
519
00:23:41,400 --> 00:23:44,010
but very few of them will we actually use in practice.
520
00:23:44,010 --> 00:23:45,570
Backslash n is a new line.
521
00:23:45,570 --> 00:23:49,200
Backslash r is a little more subtle and it's kind of a feature of yesteryear.
522
00:23:49,200 --> 00:23:52,920
It moves the cursor not to the new line, but to the beginning of the line.
523
00:23:52,920 --> 00:23:55,920
Kind of like an old timey typewriter, if you've seen how those work.
524
00:23:55,920 --> 00:24:00,600
Sometimes, though, you might want to print out an actual double quote.
525
00:24:00,600 --> 00:24:02,040
But there's a problem, of course.
526
00:24:02,040 --> 00:24:05,300
If this is my code here, and I'm already using double quotes
527
00:24:05,300 --> 00:24:08,490
as sort of special symbols to surround the text,
528
00:24:08,490 --> 00:24:11,840
I want printf to say it would probably be a little--
529
00:24:11,840 --> 00:24:15,480
like if you wanted to say hello, world, with sort of finger quotes,
530
00:24:15,480 --> 00:24:19,990
why might this not be a good idea?
531
00:24:19,990 --> 00:24:24,527
If you think about this from the computer's perspective.
532
00:24:24,527 --> 00:24:26,610
Why is this probably not the right way to do this?
533
00:24:26,610 --> 00:24:27,453
Yeah?
534
00:24:27,453 --> 00:24:29,390
AUDIENCE: [INAUDIBLE].
535
00:24:29,390 --> 00:24:30,390
DAVID J. MALAN: Exactly.
536
00:24:30,390 --> 00:24:33,557
The computer is indeed going to read your code top to bottom, left to right.
537
00:24:33,557 --> 00:24:35,880
And when it sees the first open quote, OK, that's fine.
538
00:24:35,880 --> 00:24:36,900
It understands that.
539
00:24:36,900 --> 00:24:40,150
But when it gets to the second quote, it's going to assume, oh, wait a minute.
540
00:24:40,150 --> 00:24:41,900
Maybe you only want me to say hello comma,
541
00:24:41,900 --> 00:24:44,525
and then it's going to keep reading and be like, wait a minute,
542
00:24:44,525 --> 00:24:46,040
why is there the word world here.
543
00:24:46,040 --> 00:24:48,207
And then wait a minute, now there's two more quotes.
544
00:24:48,207 --> 00:24:49,110
It's just confusing.
545
00:24:49,110 --> 00:24:49,890
It's ambiguous.
546
00:24:49,890 --> 00:24:53,280
And computers need you to be, again, very precise.
547
00:24:53,280 --> 00:24:57,510
So if you want a quotation mark to literally be displayed on the screen,
548
00:24:57,510 --> 00:25:00,410
you would escape it, so to speak, which looks a little weird
549
00:25:00,410 --> 00:25:02,280
and takes some getting into the habit of.
550
00:25:02,280 --> 00:25:04,830
But this just solves that kind of problem.
551
00:25:04,830 --> 00:25:07,410
And similarly, might you use single quotes in other contexts?
552
00:25:07,410 --> 00:25:08,220
More on that soon.
553
00:25:08,220 --> 00:25:09,928
And if you really want to bend your mind,
554
00:25:09,928 --> 00:25:13,442
how do you actually print a literal backslash, if you ever care to?
555
00:25:13,442 --> 00:25:15,150
It's not that common a character to type,
556
00:25:15,150 --> 00:25:16,858
but if you ever want it on the screen, it
557
00:25:16,858 --> 00:25:20,340
seems that we're using backslash as a special character that says,
558
00:25:20,340 --> 00:25:23,270
hey, give me a new line or give me a carriage return
559
00:25:23,270 --> 00:25:24,750
or give me a double quote.
560
00:25:24,750 --> 00:25:29,010
Weirdly, in programming, if you want to type a literal backslash on the screen,
561
00:25:29,010 --> 00:25:31,540
you literally do backslash backslash.
562
00:25:31,540 --> 00:25:33,460
But that's it for sort of weirdness for now.
563
00:25:33,460 --> 00:25:37,270
But this is to say, humans tripped over these same problems years ago.
564
00:25:37,270 --> 00:25:42,120
They came up with solutions, and now we indeed have these conventions in code.
565
00:25:42,120 --> 00:25:42,910
All right.
566
00:25:42,910 --> 00:25:45,490
So let's tease apart some other features of this
567
00:25:45,490 --> 00:25:49,240
in every program we're going to write, namely what's at the top of this file.
568
00:25:49,240 --> 00:25:53,790
So at the very top of this file, there is this cryptic looking hash include,
569
00:25:53,790 --> 00:25:57,307
or pound include standard io.h in angle bracket.
570
00:25:57,307 --> 00:25:58,390
So this is a little weird.
571
00:25:58,390 --> 00:26:00,140
We'll talk more about this next week, too.
572
00:26:00,140 --> 00:26:02,230
But this is what's called a header file.
573
00:26:02,230 --> 00:26:07,240
Any file that ends in dot h is not a source--
574
00:26:07,240 --> 00:26:11,410
well, any file that ends in dot h is what we're going to call a header file.
575
00:26:11,410 --> 00:26:15,150
And inside of that header file is functionality that
576
00:26:15,150 --> 00:26:19,030
maybe came with the system, came with the programming language itself.
577
00:26:19,030 --> 00:26:20,890
So for instance, I'm going to do this.
578
00:26:20,890 --> 00:26:22,830
I'm going to go back to my code here and I'm
579
00:26:22,830 --> 00:26:25,230
going to make a very common mistake that you yourselves
580
00:26:25,230 --> 00:26:28,020
might make in the coming days, where I just forget that line because I don't
581
00:26:28,020 --> 00:26:30,187
even understand it in the first place so I certainly
582
00:26:30,187 --> 00:26:31,470
didn't think to type it here.
583
00:26:31,470 --> 00:26:36,340
Now, if I go back to my terminal window after clearing it and I run make hello,
584
00:26:36,340 --> 00:26:39,340
because I want to recompile it because I've changed the source code,
585
00:26:39,340 --> 00:26:41,470
I'm going to see a fairly cryptic error.
586
00:26:41,470 --> 00:26:44,620
I mean, there's more error on the green than there is code up here,
587
00:26:44,620 --> 00:26:48,460
but you'll get the hang of reading it to try to figure out what's going on.
588
00:26:48,460 --> 00:26:49,320
And I'm seeing this.
589
00:26:49,320 --> 00:26:53,130
Hello.c, line 3, character 5.
590
00:26:53,130 --> 00:26:56,250
So that just means line 3, colon, character 5.
591
00:26:56,250 --> 00:26:59,460
From left to right, it's sort of a visual cue as to where the problem is.
592
00:26:59,460 --> 00:27:03,760
Call to undeclared library function printf with type dot dot dot.
593
00:27:03,760 --> 00:27:06,790
And then the rest kind of overwhelms me visually at this point.
594
00:27:06,790 --> 00:27:08,050
But that's a hint.
595
00:27:08,050 --> 00:27:13,510
If you do not include that header file at the top of the code you've written,
596
00:27:13,510 --> 00:27:17,590
you do not have access to what's generally called a library.
597
00:27:17,590 --> 00:27:21,310
A library is a collection of code that someone else wrote for you.
598
00:27:21,310 --> 00:27:24,600
Maybe it was MIT, maybe it was the authors of the C language
599
00:27:24,600 --> 00:27:25,450
itself years ago.
600
00:27:25,450 --> 00:27:28,120
Maybe it was CS50 if we wrote some code for you.
601
00:27:28,120 --> 00:27:30,840
A library is a collection of code that someone else
602
00:27:30,840 --> 00:27:35,520
wrote for you and you access it, again, by including header files
603
00:27:35,520 --> 00:27:37,540
that those same people wrote for you.
604
00:27:37,540 --> 00:27:40,620
So if I go back to my code now-- let me clear my terminal window
605
00:27:40,620 --> 00:27:42,820
just to be less overwhelmed.
606
00:27:42,820 --> 00:27:45,910
Let me undo what I just did and put that file back.
607
00:27:45,910 --> 00:27:48,780
Can you perhaps infer, just functionally,
608
00:27:48,780 --> 00:27:53,160
what is inside of standard io.h that, again, someone else wrote?
609
00:27:53,160 --> 00:27:56,270
What must be inside?
610
00:27:56,270 --> 00:27:56,870
Printf.
611
00:27:56,870 --> 00:28:02,700
So whoever invented printf decades ago probably put that code in this file.
612
00:28:02,700 --> 00:28:05,310
And so by including it, so to speak, in my code,
613
00:28:05,310 --> 00:28:07,950
I now have access to printf functionality.
614
00:28:07,950 --> 00:28:08,730
So that's all.
615
00:28:08,730 --> 00:28:11,260
And again, C is lower level than scratch.
616
00:28:11,260 --> 00:28:13,010
It's obviously text based, which means you
617
00:28:13,010 --> 00:28:15,650
have to be a little more pedantic yourself as to what
618
00:28:15,650 --> 00:28:17,250
you want the computer to do for you.
619
00:28:17,250 --> 00:28:20,760
And if you want to use someone else's code, you indeed have to include it.
620
00:28:20,760 --> 00:28:22,850
Scratch didn't bother with this, but we indeed
621
00:28:22,850 --> 00:28:28,230
do need to do this in the context of C. As an aside,
622
00:28:28,230 --> 00:28:33,350
just to preempt some unnecessary headaches, this word is not studio.h.
623
00:28:33,350 --> 00:28:37,160
Every year, a non-zero number of people can't understand why their code is not
624
00:28:37,160 --> 00:28:39,150
working because studio.h is not found.
625
00:28:39,150 --> 00:28:42,450
It's standard io, stdio.h.
626
00:28:42,450 --> 00:28:47,060
That's one of the first frequently made mistakes otherwise.
627
00:28:47,060 --> 00:28:48,600
All right, so remember that.
628
00:28:48,600 --> 00:28:51,660
Let me undo now the unnecessary quotes I added here.
629
00:28:51,660 --> 00:28:55,620
And let me propose that we show you where you can learn more.
630
00:28:55,620 --> 00:28:58,570
So all of these libraries generally are documented.
631
00:28:58,570 --> 00:29:00,572
People wrote instructions for how to use them.
632
00:29:00,572 --> 00:29:03,280
So you don't just have to listen and pay attention only in class.
633
00:29:03,280 --> 00:29:04,655
You don't have to pull up a book.
634
00:29:04,655 --> 00:29:06,670
There tends to be online documentation as well.
635
00:29:06,670 --> 00:29:09,630
For instance, for the standard I/O header file.
636
00:29:09,630 --> 00:29:12,840
And the documentation in the world of programming for C
637
00:29:12,840 --> 00:29:16,720
specifically are called manual pages or man pages for short.
638
00:29:16,720 --> 00:29:21,060
Unfortunately, they're really written decades ago for the more comfortable
639
00:29:21,060 --> 00:29:23,980
among you, those who have an eye already for programming.
640
00:29:23,980 --> 00:29:27,810
And so what CS50 has done at this URL, manual.cs50.io,
641
00:29:27,810 --> 00:29:32,280
is we essentially have more user friendly versions of the documentation
642
00:29:32,280 --> 00:29:34,510
for this header file and others.
643
00:29:34,510 --> 00:29:37,810
So for instance, if I pull up manual.cs50.io,
644
00:29:37,810 --> 00:29:39,360
you'll see a web page like this.
645
00:29:39,360 --> 00:29:43,980
And if I just scroll quickly, you'll see a whole bunch of header files, .h files,
646
00:29:43,980 --> 00:29:46,120
and a whole bunch of functions beneath them.
647
00:29:46,120 --> 00:29:48,370
And there's only a couple of dozen or so here.
648
00:29:48,370 --> 00:29:52,270
And indeed, per this checkbox at the top frequently used in CS50,
649
00:29:52,270 --> 00:29:56,490
we have highlighted the functions that odds are over the next month and a half
650
00:29:56,490 --> 00:29:58,930
like you will probably want to use.
651
00:29:58,930 --> 00:30:01,480
If I turn off that less comfortable mode,
652
00:30:01,480 --> 00:30:05,280
there's actually hundreds of functions that come with C.
653
00:30:05,280 --> 00:30:07,510
And like no programmer knows all of these functions.
654
00:30:07,510 --> 00:30:09,750
What they do is they read the manual when
655
00:30:09,750 --> 00:30:11,860
they want to find some new piece of functionality.
656
00:30:11,860 --> 00:30:13,540
So I'm going to simplify this.
657
00:30:13,540 --> 00:30:17,052
I'm going to scroll down, though, to stdio.h, for instance here,
658
00:30:17,052 --> 00:30:19,510
and you'll see more functions that we'll eventually get to.
659
00:30:19,510 --> 00:30:22,350
But if I click on printf, you'll see hopefully
660
00:30:22,350 --> 00:30:26,680
some fairly user friendly instructions for how this thing works.
661
00:30:26,680 --> 00:30:29,820
For instance, under synopsis, you'll see that we tell you
662
00:30:29,820 --> 00:30:33,270
what header file you should include in order to use it.
663
00:30:33,270 --> 00:30:35,290
Below that is something called a prototype.
664
00:30:35,290 --> 00:30:36,310
More on that later.
665
00:30:36,310 --> 00:30:37,870
But below that is a description.
666
00:30:37,870 --> 00:30:41,700
And here is where the CS50 staff have written in layperson's terms
667
00:30:41,700 --> 00:30:45,250
explanations of how this function works, how to use it, and so forth.
668
00:30:45,250 --> 00:30:49,620
But if you'd rather see what the real world uses, you can turn off that mode
669
00:30:49,620 --> 00:30:52,300
and you'll see much more arcanely the original language.
670
00:30:52,300 --> 00:30:54,270
So in short, these are sort of training wheels
671
00:30:54,270 --> 00:30:56,800
that you can turn on and off at your leisure.
672
00:30:56,800 --> 00:31:01,210
But ultimately, this is real world documentation as well.
673
00:31:01,210 --> 00:31:03,430
So if we want to see something else, for instance,
674
00:31:03,430 --> 00:31:04,900
let me go back to the main menu.
675
00:31:04,900 --> 00:31:07,560
And as we'll see today, there are actually
676
00:31:07,560 --> 00:31:12,310
functions in a header file called cs50.h that for a few weeks,
677
00:31:12,310 --> 00:31:13,740
we're going to lean on heavily.
678
00:31:13,740 --> 00:31:16,330
Long story short, it's actually kind of hard.
679
00:31:16,330 --> 00:31:19,950
It's annoying in C to get user input, ironically,
680
00:31:19,950 --> 00:31:22,900
to get the human to type in a word or a number.
681
00:31:22,900 --> 00:31:25,920
You have to jump through some technical hoops to make that happen.
682
00:31:25,920 --> 00:31:29,427
And we'll show you how to do it like the real way in a few weeks.
683
00:31:29,427 --> 00:31:31,260
But for now, among the first training wheels
684
00:31:31,260 --> 00:31:35,920
is a CS50 library code that we wrote that will just make your life easier.
685
00:31:35,920 --> 00:31:37,830
And indeed, we're going to give you access
686
00:31:37,830 --> 00:31:42,850
to functions that simplify the process of actually getting input from the user.
687
00:31:42,850 --> 00:31:44,640
So case in point, we're going to give you
688
00:31:44,640 --> 00:31:50,400
access to functions like get_string, when you want to get a string of text
689
00:31:50,400 --> 00:31:52,120
from the user-- a string is just text.
690
00:31:52,120 --> 00:31:55,570
So if you want to get one character, one word, one sentence, one paragraph,
691
00:31:55,570 --> 00:31:57,405
you can call a function called get_string.
692
00:31:57,405 --> 00:31:59,530
We're going to give you another one called get_int.
693
00:31:59,530 --> 00:32:02,160
When you want to get an integer from the user, like 1 or 0
694
00:32:02,160 --> 00:32:05,380
or negative 1 or anything else, you can use that function as well.
695
00:32:05,380 --> 00:32:07,590
And we'll see today too there's other functions you
696
00:32:07,590 --> 00:32:09,850
can use from CS50's library.
697
00:32:09,850 --> 00:32:13,990
In a weeks' time, we'll take these away once you don't need them anymore.
698
00:32:13,990 --> 00:32:16,530
And you'll see what those library functions
699
00:32:16,530 --> 00:32:18,460
have been doing all along for you.
700
00:32:18,460 --> 00:32:20,020
But for now, let's focus on this.
701
00:32:20,020 --> 00:32:22,320
Perhaps the most useful of them, get_string,
702
00:32:22,320 --> 00:32:25,720
and solve a problem that we did already pretty easily in Scratch.
703
00:32:25,720 --> 00:32:29,560
So recall in Scratch, this was a program that used two functions.
704
00:32:29,560 --> 00:32:30,795
Three, in fact.
705
00:32:30,795 --> 00:32:32,830
Ask, to ask a question of the user.
706
00:32:32,830 --> 00:32:35,010
Say, to actually display something on the screen.
707
00:32:35,010 --> 00:32:37,810
And join, to combine the default of apple, banana.
708
00:32:37,810 --> 00:32:41,860
Or in this case, Hello, and whatever the human's answer was.
709
00:32:41,860 --> 00:32:46,000
So this made our Hello program a little more interactive last time.
710
00:32:46,000 --> 00:32:49,420
How can we actually translate this into a similar paradigm now?
711
00:32:49,420 --> 00:32:51,880
So input and output is the story, as always.
712
00:32:51,880 --> 00:32:55,210
In this case, we have arguments going into those functions.
713
00:32:55,210 --> 00:32:57,650
But now we're going to introduce not side effects, which
714
00:32:57,650 --> 00:32:59,080
is stuff that happens visually.
715
00:32:59,080 --> 00:33:02,570
We're going to revisit that blue circle called answer,
716
00:33:02,570 --> 00:33:05,960
or the blue oval called answer, that represented last week what
717
00:33:05,960 --> 00:33:08,070
we called a return value.
718
00:33:08,070 --> 00:33:10,403
And this is what many functions will actually do for us.
719
00:33:10,403 --> 00:33:13,403
They're not just going to display something presumptuously on the screen
720
00:33:13,403 --> 00:33:15,660
or play a sound or a video or something like that.
721
00:33:15,660 --> 00:33:18,470
They're going to hand you back virtually a value--
722
00:33:18,470 --> 00:33:25,160
text or integers or sounds or images that you can then do with what you see
723
00:33:25,160 --> 00:33:25,740
fit.
724
00:33:25,740 --> 00:33:28,950
So the paradigm we'll now have is much like in Scratch.
725
00:33:28,950 --> 00:33:31,760
If the input is what's your name and the function is ask,
726
00:33:31,760 --> 00:33:34,170
and you get back a return value of answer,
727
00:33:34,170 --> 00:33:37,640
we want to actually do this now in C. So side by side,
728
00:33:37,640 --> 00:33:42,080
what code like this in Scratch is going to look like today onward is this.
729
00:33:42,080 --> 00:33:44,600
Instead of using the Ask block, you literally
730
00:33:44,600 --> 00:33:46,770
use CS50's function called get_string.
731
00:33:46,770 --> 00:33:47,425
It takes input.
732
00:33:47,425 --> 00:33:49,550
So we put the parentheses on the left and the right
733
00:33:49,550 --> 00:33:52,520
to conjure the idea of this white oval.
734
00:33:52,520 --> 00:33:55,630
Inside of that string, you can put a prompt,
735
00:33:55,630 --> 00:33:59,110
so to speak, like, what do you want the human to be asked, in this case.
736
00:33:59,110 --> 00:34:01,140
And I'm missing something still.
737
00:34:01,140 --> 00:34:04,490
Per the placeholders here, what's missing?
738
00:34:04,490 --> 00:34:06,317
So quotation marks, so literally quotation
739
00:34:06,317 --> 00:34:07,650
marks on the left and the right.
740
00:34:07,650 --> 00:34:08,909
And I'm going to be a little anal here.
741
00:34:08,909 --> 00:34:10,409
I'm going to put a space at the end.
742
00:34:10,409 --> 00:34:11,639
Because I don't want to--
743
00:34:11,639 --> 00:34:14,699
I could, but I don't want the cursor to go to the next line.
744
00:34:14,699 --> 00:34:16,340
Hence, no backslash n.
745
00:34:16,340 --> 00:34:19,639
If I want the cursor just to sit there kind of blinking, waiting for the user
746
00:34:19,639 --> 00:34:21,960
after the question mark, I'm just going to put a space.
747
00:34:21,960 --> 00:34:23,670
So it will stay there for me.
748
00:34:23,670 --> 00:34:27,199
But this is just an aesthetic detail using the same idea as before.
749
00:34:27,199 --> 00:34:29,460
So that is the analog of this block.
750
00:34:29,460 --> 00:34:32,400
But how do I get access to the so-called return value?
751
00:34:32,400 --> 00:34:35,030
MIT just plopped it on the screen for us automatically.
752
00:34:35,030 --> 00:34:39,810
In C, we have to write a little more code to get access to that return value.
753
00:34:39,810 --> 00:34:43,110
And the way we do this is on the left hand side of this line of code,
754
00:34:43,110 --> 00:34:45,780
we come up with a name for the return value.
755
00:34:45,780 --> 00:34:47,280
You can call it anything you want.
756
00:34:47,280 --> 00:34:50,400
But answer is a nice equivalent to what MIT did.
757
00:34:50,400 --> 00:34:52,650
You could more generically call it x or y or z.
758
00:34:52,650 --> 00:34:53,940
But that's not really useful.
759
00:34:53,940 --> 00:34:56,553
And so computer scientists, unlike mathematicians,
760
00:34:56,553 --> 00:34:58,970
will tend to use variables that are a little more verbose,
761
00:34:58,970 --> 00:35:00,480
like the word "answer."
762
00:35:00,480 --> 00:35:03,540
But in C, it's, again, a little lower level.
763
00:35:03,540 --> 00:35:08,560
You have to tell the computer what type of variable this is going to be.
764
00:35:08,560 --> 00:35:11,680
So I'm kind of conflating "variable" and "return value,"
765
00:35:11,680 --> 00:35:14,500
but they're being used in an intertwined way.
766
00:35:14,500 --> 00:35:19,930
The get_string function, just like the ask block, returns a value.
767
00:35:19,930 --> 00:35:21,840
If you want to do something with it, you need
768
00:35:21,840 --> 00:35:26,470
to put it in something called a variable, which is denoted in text here.
769
00:35:26,470 --> 00:35:28,500
But again, per last week, the computer doesn't
770
00:35:28,500 --> 00:35:31,570
know if it's looking at numbers or characters or images or sounds.
771
00:35:31,570 --> 00:35:35,250
You have to tell it, as the programmer, that the zeros and ones that are somehow
772
00:35:35,250 --> 00:35:37,500
involved here underneath the computer's hood
773
00:35:37,500 --> 00:35:40,440
are, in fact, to be treated as text, a.k.a.
774
00:35:40,440 --> 00:35:41,670
string.
775
00:35:41,670 --> 00:35:45,155
Now, there's one stupid subtlety still missing from this line of code.
776
00:35:45,155 --> 00:35:47,280
Does anyone know, especially if you've programmed--
777
00:35:47,280 --> 00:35:48,670
OK, all of you have program before.
778
00:35:48,670 --> 00:35:48,935
Yes?
779
00:35:48,935 --> 00:35:49,500
AUDIENCE: Semicolon.
780
00:35:49,500 --> 00:35:50,650
DAVID J. MALAN: Semicolon.
781
00:35:50,650 --> 00:35:53,250
So one of the headaches of C and a lot of languages
782
00:35:53,250 --> 00:35:57,960
is you actually have to finish your thought explicitly so the computer knows
783
00:35:57,960 --> 00:35:59,470
that that line of code is done.
784
00:35:59,470 --> 00:36:01,150
And it's not a period, like in English.
785
00:36:01,150 --> 00:36:02,350
It's, in fact, a semicolon.
786
00:36:02,350 --> 00:36:03,850
Now, you don't use these everywhere.
787
00:36:03,850 --> 00:36:05,058
We'll see where you use them.
788
00:36:05,058 --> 00:36:08,440
But that, too, is a very common mistake, to overlook something simple.
789
00:36:08,440 --> 00:36:11,760
But again, in the coming weeks, even though this might look very cryptic,
790
00:36:11,760 --> 00:36:15,100
with muscle memory and practice, you'll start to see these things instantly,
791
00:36:15,100 --> 00:36:17,250
even if, for a few days, you sort of bang your head
792
00:36:17,250 --> 00:36:21,210
against the screen, so to speak, not seeing what
793
00:36:21,210 --> 00:36:24,160
the TFs and I much more readily see.
794
00:36:24,160 --> 00:36:25,930
So let's go ahead and do this.
795
00:36:25,930 --> 00:36:28,030
Let me go back over to VS Code here.
796
00:36:28,030 --> 00:36:29,730
Let me zoom in just a little bit.
797
00:36:29,730 --> 00:36:31,810
And let me go ahead and do this.
798
00:36:31,810 --> 00:36:34,470
I'm going to get rid of my single use of printf.
799
00:36:34,470 --> 00:36:40,600
And I'm going to say the exact same thing-- string answer equals get string,
800
00:36:40,600 --> 00:36:43,780
quote, unquote, "What's your name?"
801
00:36:43,780 --> 00:36:48,180
question mark, space, closed quote, semicolon.
802
00:36:48,180 --> 00:36:50,245
And now I want to print out that answer.
803
00:36:50,245 --> 00:36:52,870
Well, let me do this incorrectly, deliberately, for the moment.
804
00:36:52,870 --> 00:36:57,090
Let me just say printf, quote, unquote, "hello, answer,"
805
00:36:57,090 --> 00:37:01,330
if I want to plug in "answer" and I want to add a new line at the end, semicolon.
806
00:37:01,330 --> 00:37:02,650
So let me try this.
807
00:37:02,650 --> 00:37:04,960
But there's multiple mistakes now in my code.
808
00:37:04,960 --> 00:37:06,460
Let's trip over them deliberately.
809
00:37:06,460 --> 00:37:09,668
Let me go down to my terminal window by clicking at the bottom of the screen.
810
00:37:09,668 --> 00:37:11,320
Let me run "make hello" again.
811
00:37:11,320 --> 00:37:12,000
Enter.
812
00:37:12,000 --> 00:37:13,950
And, oh, my god, there's even more errors now
813
00:37:13,950 --> 00:37:15,870
than there were before, but not a problem.
814
00:37:15,870 --> 00:37:17,620
Let me click on this little triangle here,
815
00:37:17,620 --> 00:37:19,870
which is just going to zoom in on the terminal window.
816
00:37:19,870 --> 00:37:21,310
So it takes up my full screen.
817
00:37:21,310 --> 00:37:24,690
And just generally, all you have to do is find a few keywords visually
818
00:37:24,690 --> 00:37:26,550
that give you a clue as to what's going on.
819
00:37:26,550 --> 00:37:29,680
Or, as before, you can always ask the CS50 Duck.
820
00:37:29,680 --> 00:37:31,740
So here's the command I ran, "make hello."
821
00:37:31,740 --> 00:37:33,850
Somehow that induced all of these errors.
822
00:37:33,850 --> 00:37:36,370
Always read them top to bottom, not bottom up.
823
00:37:36,370 --> 00:37:39,970
So from top to bottom, there's a problem on line 5, character 5--
824
00:37:39,970 --> 00:37:42,800
use of undeclared identifier string.
825
00:37:42,800 --> 00:37:44,140
Did I mean standard in?
826
00:37:44,140 --> 00:37:46,210
No, no, no, I didn't there.
827
00:37:46,210 --> 00:37:49,390
And then, also, two errors generated.
828
00:37:49,390 --> 00:37:52,070
Too many errors [? are made. ?] What did I do wrong?
829
00:37:52,070 --> 00:37:55,760
Well, it turns out what I do need to do at the top of this file--
830
00:37:55,760 --> 00:37:58,370
let me click the triangle to zoom back out--
831
00:37:58,370 --> 00:38:02,000
if I want to use the get_string function to get a string,
832
00:38:02,000 --> 00:38:04,190
I actually need to include another header file,
833
00:38:04,190 --> 00:38:09,498
which is probably called "include cs50.h."
834
00:38:09,498 --> 00:38:10,790
Technically, any order is fine.
835
00:38:10,790 --> 00:38:12,998
I tend to alphabetize because I just know, therefore,
836
00:38:12,998 --> 00:38:15,350
where to look alphabetically for a certain header file.
837
00:38:15,350 --> 00:38:19,150
Now that that's in place, let me again run "make hello."
838
00:38:19,150 --> 00:38:20,240
Enter.
839
00:38:20,240 --> 00:38:22,220
And now we're back in business.
840
00:38:22,220 --> 00:38:23,180
No error message.
841
00:38:23,180 --> 00:38:26,060
So even though you might have more errors than you have code,
842
00:38:26,060 --> 00:38:28,150
odds are it's just the computer is confused.
843
00:38:28,150 --> 00:38:31,370
And it could be something simple and an easy fix like that.
844
00:38:31,370 --> 00:38:35,720
So just to be clear, standard io.h, because I'm including it,
845
00:38:35,720 --> 00:38:37,330
I can use printf.
846
00:38:37,330 --> 00:38:42,040
cs50.h, I can use get_string because the people who
847
00:38:42,040 --> 00:38:45,550
invented C and the people who invented CS50 wrote those two files, so
848
00:38:45,550 --> 00:38:47,650
to speak, respectively.
849
00:38:47,650 --> 00:38:50,990
All right, unfortunately, even though the program compiles,
850
00:38:50,990 --> 00:38:52,490
that doesn't mean it's correct.
851
00:38:52,490 --> 00:38:54,800
It just means it's syntactically valid.
852
00:38:54,800 --> 00:38:56,000
It's valid C code.
853
00:38:56,000 --> 00:38:59,080
If I go ahead and run "./hello" and hit Enter now,
854
00:38:59,080 --> 00:39:00,932
I'm going to be prompted for my name.
855
00:39:00,932 --> 00:39:01,640
So I'll type it--
856
00:39:01,640 --> 00:39:04,940
D-A-V-I-D. And notice there's a space to the right of the question mark,
857
00:39:04,940 --> 00:39:05,750
as promised.
858
00:39:05,750 --> 00:39:06,840
Enter.
859
00:39:06,840 --> 00:39:09,840
But it just says "hello, answer," which, of course, is not the intent.
860
00:39:09,840 --> 00:39:11,820
I want it to say "hello, David."
861
00:39:11,820 --> 00:39:13,290
So how can we do this?
862
00:39:13,290 --> 00:39:16,343
Well, in Scratch, it took a couple of puzzle pieces.
863
00:39:16,343 --> 00:39:17,760
But it was pretty straightforward.
864
00:39:17,760 --> 00:39:22,050
If I wanted to say the combination of two phrases, "hello" and something else,
865
00:39:22,050 --> 00:39:25,890
I joined those two and then passed that output to the input of say.
866
00:39:25,890 --> 00:39:28,220
In C, it's going to be a little different here
867
00:39:28,220 --> 00:39:30,720
just because it's an old language and this is how it's done.
868
00:39:30,720 --> 00:39:33,390
Still use printf because that's the same thing as say.
869
00:39:33,390 --> 00:39:34,320
I got my parentheses.
870
00:39:34,320 --> 00:39:35,280
I got my semicolon.
871
00:39:35,280 --> 00:39:36,030
Good to go.
872
00:39:36,030 --> 00:39:39,325
But inside of that, this is where printf is different.
873
00:39:39,325 --> 00:39:44,130
If you want to say something followed by something else, in the world of C,
874
00:39:44,130 --> 00:39:46,230
you tend to use placeholders.
875
00:39:46,230 --> 00:39:48,890
So you don't just join things together as we
876
00:39:48,890 --> 00:39:52,280
will do in Python and other languages.
877
00:39:52,280 --> 00:39:55,590
You say to the compiler, give me the word "hello," comma,
878
00:39:55,590 --> 00:39:57,090
and then something else.
879
00:39:57,090 --> 00:40:00,420
And the percent s means, put another string here.
880
00:40:00,420 --> 00:40:03,620
It's sort of like leaving a placeholder in your code or a template
881
00:40:03,620 --> 00:40:05,880
where you'll actually plug in some values.
882
00:40:05,880 --> 00:40:09,727
Now, if this is what I want to display, I still use my quotes, as before.
883
00:40:09,727 --> 00:40:11,810
And I might, in fact, have a backslash n if I want
884
00:40:11,810 --> 00:40:13,560
to move the cursor to the next line.
885
00:40:13,560 --> 00:40:16,980
But this is where printf is a little different.
886
00:40:16,980 --> 00:40:21,510
Unlike say, which took one input, printf is kind of like join.
887
00:40:21,510 --> 00:40:24,960
It can take two or more inputs if you so choose.
888
00:40:24,960 --> 00:40:28,610
You just have to separate them with a comma.
889
00:40:28,610 --> 00:40:33,170
So much like the join block has two ovals here that are initially white--
890
00:40:33,170 --> 00:40:37,040
apple and banana-- until we dragged and dropped answer on top of it, printf--
891
00:40:37,040 --> 00:40:39,050
and really any function in C-- if you want
892
00:40:39,050 --> 00:40:42,180
to pass in multiple inputs, that's fine if they're supported.
893
00:40:42,180 --> 00:40:43,817
Just separate them with commas.
894
00:40:43,817 --> 00:40:45,150
There's no multiple parentheses.
895
00:40:45,150 --> 00:40:46,260
There's no multiple ovals.
896
00:40:46,260 --> 00:40:48,780
Just separate them with commas.
897
00:40:48,780 --> 00:40:51,360
And now notice a potential point of confusion.
898
00:40:51,360 --> 00:40:57,491
What's different about this comma and this one, just instinctively?
899
00:40:57,491 --> 00:40:59,280
Sort of minor detail, but important.
900
00:40:59,280 --> 00:40:59,780
Yeah?
901
00:40:59,780 --> 00:41:01,758
AUDIENCE: Inside and outside.
902
00:41:01,758 --> 00:41:03,800
DAVID J. MALAN: So one is inside, one is outside.
903
00:41:03,800 --> 00:41:07,390
So the one that's inside the quotes is literally the English grammatical comma
904
00:41:07,390 --> 00:41:08,900
that you want the human to see.
905
00:41:08,900 --> 00:41:11,680
The one out here is a C thing that's separating
906
00:41:11,680 --> 00:41:15,150
the first input to this function printf from the second.
907
00:41:15,150 --> 00:41:17,150
Strictly speaking, you don't need a space there.
908
00:41:17,150 --> 00:41:20,920
But it's a good practice, stylistically, to separate your arguments
909
00:41:20,920 --> 00:41:23,390
with single spaces, just as I've done there.
910
00:41:23,390 --> 00:41:26,180
So let me go ahead and now do something with this.
911
00:41:26,180 --> 00:41:29,060
Let me go back to my C code here.
912
00:41:29,060 --> 00:41:32,210
I'm going to clear my terminal window just to get rid of that distraction.
913
00:41:32,210 --> 00:41:35,680
And now I'm going to change answer to percent s.
914
00:41:35,680 --> 00:41:40,840
And then outside of the double quotes on line 7, I'm going to do comma "answer."
915
00:41:40,840 --> 00:41:44,630
And then, after it auto-saves, I'm going to go back to my terminal window.
916
00:41:44,630 --> 00:41:47,720
And just to make another deliberate mistake, "./hello."
917
00:41:47,720 --> 00:41:48,380
Enter.
918
00:41:48,380 --> 00:41:49,160
"What's your name?
919
00:41:49,160 --> 00:41:49,450
David."
920
00:41:49,450 --> 00:41:49,950
Enter.
921
00:41:49,950 --> 00:41:51,200
It's still broken.
922
00:41:51,200 --> 00:41:53,870
But why?
923
00:41:53,870 --> 00:41:55,200
I still have to recompile it.
924
00:41:55,200 --> 00:41:57,180
So again, you just get into the habit, when you change your code,
925
00:41:57,180 --> 00:42:00,620
you have to recompile so you get new machine code in the file "hello."
926
00:42:00,620 --> 00:42:01,720
So let's do it again.
927
00:42:01,720 --> 00:42:03,120
"make hello."
928
00:42:03,120 --> 00:42:04,730
No errors is good.
929
00:42:04,730 --> 00:42:05,510
"./hello."
930
00:42:05,510 --> 00:42:06,120
Enter.
931
00:42:06,120 --> 00:42:07,203
"What's your name?" again.
932
00:42:07,203 --> 00:42:11,220
D-A-V-I-D. And now, "hello, David."
933
00:42:11,220 --> 00:42:13,410
So again, a lot of this is still cryptic.
934
00:42:13,410 --> 00:42:16,020
But it's going to start to follow patterns like this.
935
00:42:16,020 --> 00:42:20,040
Functions like in math class, f of x, are written function name, parentheses,
936
00:42:20,040 --> 00:42:23,245
input, comma, input, comma, input, however many you have.
937
00:42:23,245 --> 00:42:24,870
They're going to follow these patterns.
938
00:42:24,870 --> 00:42:29,540
But notice, too, on lines 6 and 7, I have finished each of my thoughts
939
00:42:29,540 --> 00:42:31,343
with a semicolon.
940
00:42:31,343 --> 00:42:34,010
So what are the other commands that you can run in your terminal
941
00:42:34,010 --> 00:42:35,910
window besides something like ls?
942
00:42:35,910 --> 00:42:38,670
Well, it turns out there's a whole bunch of them. ls, of course,
943
00:42:38,670 --> 00:42:42,090
was simply short for list, which shows you the files in your current folder.
944
00:42:42,090 --> 00:42:44,960
But there's also cd for change directory, which
945
00:42:44,960 --> 00:42:48,260
is the command equivalent of double-clicking on a folder to open it
946
00:42:48,260 --> 00:42:49,730
up in a graphical environment.
947
00:42:49,730 --> 00:42:52,190
There's cp, which is short for copy, which allows
948
00:42:52,190 --> 00:42:54,910
you to make a copy of a file or folder.
949
00:42:54,910 --> 00:42:59,110
There's make dir, "mkdir," which is short for make directory,
950
00:42:59,110 --> 00:43:00,970
which is how you could make a new folder.
951
00:43:00,970 --> 00:43:03,420
There's mv, which is short for move, which
952
00:43:03,420 --> 00:43:06,720
would allow you to move one file or folder from one place to another
953
00:43:06,720 --> 00:43:09,610
or simply rename one of those to a different name.
954
00:43:09,610 --> 00:43:11,460
There's rm, which is short for remove.
955
00:43:11,460 --> 00:43:14,230
And there's "rmdir," which is short for remove directory.
956
00:43:14,230 --> 00:43:16,480
So, in fact, let's play around with a couple of these.
957
00:43:16,480 --> 00:43:18,280
Let me go back to VS Code here.
958
00:43:18,280 --> 00:43:20,160
Let me go ahead and open up my File Explorer.
959
00:43:20,160 --> 00:43:23,340
And recall that at this point I've got two files, hello.c,
960
00:43:23,340 --> 00:43:27,430
which contains my source code, and then hello, which contains my machine code,
961
00:43:27,430 --> 00:43:31,570
the executable program that I previously generated by running make.
962
00:43:31,570 --> 00:43:33,360
Well, let me go ahead and propose that I'd
963
00:43:33,360 --> 00:43:38,320
like to prepare to keep all of my files and folders very orderly.
964
00:43:38,320 --> 00:43:42,250
So for every program I write or for every problem on a problem set I write,
965
00:43:42,250 --> 00:43:46,510
maybe I want to store my relevant files in a specific folder for that problem.
966
00:43:46,510 --> 00:43:50,520
So suppose then that I want to put hello.c in a folder, otherwise known
967
00:43:50,520 --> 00:43:52,600
as a directory, called hello.
968
00:43:52,600 --> 00:43:56,560
Well, I can't do that quite yet because I already have a program called hello.
969
00:43:56,560 --> 00:43:58,540
So let me use one of those new commands.
970
00:43:58,540 --> 00:44:04,057
rm space hello will delete or remove hello from my current directory.
971
00:44:04,057 --> 00:44:05,140
So I'm going to hit Enter.
972
00:44:05,140 --> 00:44:08,410
I'm going to be prompted to confirm with y for yes or n for no.
973
00:44:08,410 --> 00:44:09,750
"Remove regular file 'hello'?"
974
00:44:09,750 --> 00:44:11,770
I'm going to hit y and enter.
975
00:44:11,770 --> 00:44:14,250
And as I hit Enter, watch the top left of my screen
976
00:44:14,250 --> 00:44:18,060
as the hello file would seem to disappear.
977
00:44:18,060 --> 00:44:19,295
Voila, it's now gone.
978
00:44:19,295 --> 00:44:21,670
So now I'm going to go ahead and use a different command.
979
00:44:21,670 --> 00:44:24,225
Let me go ahead and do mkdir for make directory.
980
00:44:24,225 --> 00:44:26,100
I'm going to call the directory itself hello.
981
00:44:26,100 --> 00:44:28,380
And watch again, at top left, what happens.
982
00:44:28,380 --> 00:44:29,220
Enter.
983
00:44:29,220 --> 00:44:32,890
Now I have not a file but a folder called hello.
984
00:44:32,890 --> 00:44:34,770
And in this GUI, the fact that it's a folder
985
00:44:34,770 --> 00:44:39,580
is indicated, one, by its icon and, two, by that little right-facing triangle,
986
00:44:39,580 --> 00:44:42,130
which means I can expand it to see what's inside.
987
00:44:42,130 --> 00:44:44,380
And in fact, if I do that, I'll see, of course,
988
00:44:44,380 --> 00:44:47,170
that nothing's in it because we literally just created it.
989
00:44:47,170 --> 00:44:51,820
All right, well, what if I want to move hello.c into the new hello folder?
990
00:44:51,820 --> 00:44:54,100
Well, I could, just like on macOS or Windows.
991
00:44:54,100 --> 00:44:58,390
I could, actually in my File Explorer, click and drag one into the other.
992
00:44:58,390 --> 00:45:01,000
But let's do this entirely within the terminal window.
993
00:45:01,000 --> 00:45:01,900
So let me do this.
994
00:45:01,900 --> 00:45:06,450
Let me move, or mv for short, my file called hello.c
995
00:45:06,450 --> 00:45:09,540
into a new destination folder, hello.
996
00:45:09,540 --> 00:45:11,942
And I can, optionally, put at slash the end of "hello"
997
00:45:11,942 --> 00:45:13,900
just to make super clear that it's a directory.
998
00:45:13,900 --> 00:45:15,430
But that's not strictly necessary.
999
00:45:15,430 --> 00:45:20,110
But if I say mv hello.c hello, with spaces in between,
1000
00:45:20,110 --> 00:45:24,550
assuming hello exists as a folder, watch what happens at top left now.
1001
00:45:24,550 --> 00:45:26,440
It's a little more subtle, but hello.c is
1002
00:45:26,440 --> 00:45:30,520
going to move inside of the hello folder right now.
1003
00:45:30,520 --> 00:45:33,080
And indeed, it's only slightly more indented.
1004
00:45:33,080 --> 00:45:35,330
But notice if I collapse the hello folder,
1005
00:45:35,330 --> 00:45:39,560
notice that it seems to be gone because hello.c is now inside of that folder.
1006
00:45:39,560 --> 00:45:41,810
Of course, if I expand that, I'll see it again.
1007
00:45:41,810 --> 00:45:44,530
If I go back to my terminal window and type ls for list,
1008
00:45:44,530 --> 00:45:47,260
now I don't see hello.c.
1009
00:45:47,260 --> 00:45:49,580
And I don't see an executable program anymore.
1010
00:45:49,580 --> 00:45:50,750
But I do see hello.
1011
00:45:50,750 --> 00:45:53,590
And the slash there just makes super clear to me, the user,
1012
00:45:53,590 --> 00:45:54,860
that it's indeed a folder.
1013
00:45:54,860 --> 00:45:56,900
So how do I change into that folder?
1014
00:45:56,900 --> 00:45:59,710
Well, I can obviously use the graphical interface at left and click
1015
00:45:59,710 --> 00:46:01,910
and expand and see what's going on.
1016
00:46:01,910 --> 00:46:05,980
But there's no direct connection between the File Explorer at top left
1017
00:46:05,980 --> 00:46:08,140
and my terminal window at bottom right.
1018
00:46:08,140 --> 00:46:12,620
Rather, those are just two different ways to explore the underlying system.
1019
00:46:12,620 --> 00:46:16,130
So if I want to change my terminal window into this new directory,
1020
00:46:16,130 --> 00:46:20,330
I can do cd for change directory, hello, and then Enter.
1021
00:46:20,330 --> 00:46:24,680
And now notice my terminal window's prompt changes slightly.
1022
00:46:24,680 --> 00:46:27,890
There's still a dollar sign, which indicates, type my commands here.
1023
00:46:27,890 --> 00:46:30,070
But before that dollar sign, just so that I
1024
00:46:30,070 --> 00:46:33,340
have a reminder, sort of breadcrumbs that visually remind me
1025
00:46:33,340 --> 00:46:37,670
what folder I am now in, I see that I'm inside of hello.
1026
00:46:37,670 --> 00:46:40,720
If I now type ls, I should see the file I
1027
00:46:40,720 --> 00:46:43,990
expect to be in there, which is indeed hello.c.
1028
00:46:43,990 --> 00:46:46,730
Now, suppose I want to try out some of those other commands.
1029
00:46:46,730 --> 00:46:49,723
And suppose I want to maybe rename this file.
1030
00:46:49,723 --> 00:46:51,890
I really want this file to be called something else.
1031
00:46:51,890 --> 00:46:57,700
So maybe I might do something like this, mv hello.c space, and now a new name
1032
00:46:57,700 --> 00:46:58,550
for the file.
1033
00:46:58,550 --> 00:47:00,070
Well, maybe I want to make--
1034
00:47:00,070 --> 00:47:02,385
say this is an old version of my code, because I want
1035
00:47:02,385 --> 00:47:04,010
to just start fresh with something new.
1036
00:47:04,010 --> 00:47:07,930
So I could do something like this, mv hello.c old.c.
1037
00:47:07,930 --> 00:47:10,100
And watch what happens at top left.
1038
00:47:10,100 --> 00:47:13,400
hello.c, of course, gets renamed via the move command.
1039
00:47:13,400 --> 00:47:15,910
So I can use move to move a file into a folder.
1040
00:47:15,910 --> 00:47:20,270
Or I can use it to rename a file or folder, as I've just done here.
1041
00:47:20,270 --> 00:47:21,860
Now, suppose I want to undo that.
1042
00:47:21,860 --> 00:47:23,270
Well, I can't just type undo.
1043
00:47:23,270 --> 00:47:26,350
I can't just hit Control C. But I can do the opposite, in effect.
1044
00:47:26,350 --> 00:47:32,870
mv old.c hello.c will now, per top left, change it back into that file.
1045
00:47:32,870 --> 00:47:36,132
If I want to make a copy of this file, maybe as an actual backup because I'm
1046
00:47:36,132 --> 00:47:38,840
really happy with this version and I'm worried about breaking it,
1047
00:47:38,840 --> 00:47:40,850
well, I could do cp for short.
1048
00:47:40,850 --> 00:47:42,820
I can then do hello.c.
1049
00:47:42,820 --> 00:47:46,340
And then I can do something like backup.c, or any other file name.
1050
00:47:46,340 --> 00:47:48,500
I'm taking care to use the same file extension
1051
00:47:48,500 --> 00:47:52,270
so that if I do open this file later, it still opens and gets highlighted
1052
00:47:52,270 --> 00:47:53,900
and colorized in the same way.
1053
00:47:53,900 --> 00:47:55,760
But watch what happens now at top left.
1054
00:47:55,760 --> 00:48:00,080
When I type Enter, I now have two files in this hello folder.
1055
00:48:00,080 --> 00:48:03,500
And indeed, if I type ls now, I can see exactly the same.
1056
00:48:03,500 --> 00:48:06,160
So long story short, there's this whole list of commands,
1057
00:48:06,160 --> 00:48:09,663
and even more than these, that allow you to manipulate the underlying system
1058
00:48:09,663 --> 00:48:11,830
in exactly the same way that you and I have probably
1059
00:48:11,830 --> 00:48:14,800
done for years by using a mouse and pointing and clicking
1060
00:48:14,800 --> 00:48:15,660
and double-clicking.
1061
00:48:15,660 --> 00:48:18,160
But for now, let's undo all of this because I haven't really
1062
00:48:18,160 --> 00:48:19,510
written that many programs today.
1063
00:48:19,510 --> 00:48:21,218
And I'm going to keep things simple today
1064
00:48:21,218 --> 00:48:23,150
and keep everything in my same folder.
1065
00:48:23,150 --> 00:48:24,440
So let's undo all of this.
1066
00:48:24,440 --> 00:48:28,570
Let me go ahead and now remove backup.c because I don't particularly
1067
00:48:28,570 --> 00:48:29,570
care about that.
1068
00:48:29,570 --> 00:48:31,630
I'm going to be prompted to confirm as much.
1069
00:48:31,630 --> 00:48:36,280
Then let me go ahead and move hello.c out of this folder
1070
00:48:36,280 --> 00:48:38,750
and into the original folder.
1071
00:48:38,750 --> 00:48:40,510
And, conceptually, the original folder is
1072
00:48:40,510 --> 00:48:43,240
what we would call the parent folder, the folder that
1073
00:48:43,240 --> 00:48:45,200
contains this hello folder.
1074
00:48:45,200 --> 00:48:48,910
And the way you can specify the parent folder, like back up from whence
1075
00:48:48,910 --> 00:48:51,530
you came, is with dot dot.
1076
00:48:51,530 --> 00:48:55,840
So a single dot, as we've actually seen "./hello", "./a.out"
1077
00:48:55,840 --> 00:48:58,840
means execute a program in this directory, dot.
1078
00:48:58,840 --> 00:49:02,030
But dot dot refers to your parent directory.
1079
00:49:02,030 --> 00:49:05,110
So watch what happens at top left when I move this hello.c file out
1080
00:49:05,110 --> 00:49:06,140
of this folder.
1081
00:49:06,140 --> 00:49:08,350
It shifts a little bit to the left to indicate
1082
00:49:08,350 --> 00:49:10,160
that it's no longer in that folder.
1083
00:49:10,160 --> 00:49:13,240
I'm going to go ahead and type cd dot dot, which
1084
00:49:13,240 --> 00:49:15,370
will bring me back to my parent folder.
1085
00:49:15,370 --> 00:49:19,000
Or, even more useful, especially if you get confused or lost somewhere
1086
00:49:19,000 --> 00:49:21,160
within your folders, you can actually just type
1087
00:49:21,160 --> 00:49:25,870
cd and nothing, and that will whisk you back to that original folder
1088
00:49:25,870 --> 00:49:27,060
no matter where you are.
1089
00:49:27,060 --> 00:49:28,060
So it's a nice shortcut.
1090
00:49:28,060 --> 00:49:30,070
And it's a nice way of undoing any confusion
1091
00:49:30,070 --> 00:49:31,820
you might have caused for yourself.
1092
00:49:31,820 --> 00:49:37,150
Lastly, let's go ahead and get rid of the hello directory with rmdir hello,
1093
00:49:37,150 --> 00:49:37,940
Enter.
1094
00:49:37,940 --> 00:49:40,930
And that now disappears at top left, as well.
1095
00:49:40,930 --> 00:49:47,020
Now, what I was hinting at here whereby I had my hello.c file in a folder
1096
00:49:47,020 --> 00:49:50,260
and I was moving things around and renaming things and backing things up
1097
00:49:50,260 --> 00:49:52,930
isn't strictly necessary because there's actually other features
1098
00:49:52,930 --> 00:49:55,870
still inside of VS Code that you're welcome and encouraged to play around
1099
00:49:55,870 --> 00:49:56,370
with.
1100
00:49:56,370 --> 00:50:00,460
In fact, if I go to my so-called timeline at the bottom of my File
1101
00:50:00,460 --> 00:50:04,390
Explorer here, you can actually see that there's been automatic backups made
1102
00:50:04,390 --> 00:50:05,593
over time of this file.
1103
00:50:05,593 --> 00:50:07,760
So if you click, click, click through those backups,
1104
00:50:07,760 --> 00:50:10,240
you can actually see different versions of this same file
1105
00:50:10,240 --> 00:50:12,520
slightly in the past, which might save you
1106
00:50:12,520 --> 00:50:14,720
the trouble of having to manually create files.
1107
00:50:14,720 --> 00:50:18,080
And in fact, in the world of software development and industry,
1108
00:50:18,080 --> 00:50:21,430
there's actually standard tools, very similar in spirit
1109
00:50:21,430 --> 00:50:23,590
to what we've been using GitHub for, that
1110
00:50:23,590 --> 00:50:27,193
allow you manually to make different versions of your code
1111
00:50:27,193 --> 00:50:29,860
so that you can proactively keep track of all the changes you've
1112
00:50:29,860 --> 00:50:32,530
made without manually renaming things as you
1113
00:50:32,530 --> 00:50:36,130
might typically on your own Mac or PC.
1114
00:50:36,130 --> 00:50:37,900
All right, let me clear my terminal window
1115
00:50:37,900 --> 00:50:41,530
and ask if there are any questions.
1116
00:50:41,530 --> 00:50:44,556
Yes, over here.
1117
00:50:44,556 --> 00:50:49,546
AUDIENCE: What if you had a type other than [INAUDIBLE]?
1118
00:50:49,546 --> 00:50:52,058
1119
00:50:52,058 --> 00:50:53,850
DAVID J. MALAN: Yeah, really good question.
1120
00:50:53,850 --> 00:50:57,430
If we had something other than a string of text, if we had an integer,
1121
00:50:57,430 --> 00:50:58,680
would you still use percent s?
1122
00:50:58,680 --> 00:50:59,760
No, you would use something else.
1123
00:50:59,760 --> 00:51:01,640
And, indeed, percent i is what we're going to use.
1124
00:51:01,640 --> 00:51:04,670
And we're going to actually do that-- perfect segue-- to other types
1125
00:51:04,670 --> 00:51:06,090
that C actually has.
1126
00:51:06,090 --> 00:51:10,440
So up until now, we've been calling a string of text literally a string.
1127
00:51:10,440 --> 00:51:12,600
And this is common in many programming languages,
1128
00:51:12,600 --> 00:51:14,060
including Python and JavaScript.
1129
00:51:14,060 --> 00:51:16,830
"Strings" in the programming world just mean text,
1130
00:51:16,830 --> 00:51:19,290
whether it's zero or more characters thereof.
1131
00:51:19,290 --> 00:51:23,340
But C does have other data types, just a few of which we'll dabble with today
1132
00:51:23,340 --> 00:51:24,840
but you'll use more over time.
1133
00:51:24,840 --> 00:51:28,110
We've already seen string, for instance, which is indeed a string of text.
1134
00:51:28,110 --> 00:51:30,990
But let's focus, as well, on an integer.
1135
00:51:30,990 --> 00:51:32,720
As an aside, there's other types, too.
1136
00:51:32,720 --> 00:51:35,640
There's Boolean values, like true or false.
1137
00:51:35,640 --> 00:51:39,530
There's chars, which are single characters instead of full phrases
1138
00:51:39,530 --> 00:51:40,258
or sentences.
1139
00:51:40,258 --> 00:51:42,800
There's doubles and floats, which are real numbers, something
1140
00:51:42,800 --> 00:51:45,300
with a decimal point, the equivalent of fractions.
1141
00:51:45,300 --> 00:51:49,070
And there's longs, which are integers but longer integers, even
1142
00:51:49,070 --> 00:51:51,120
bigger integers than you might type by default.
1143
00:51:51,120 --> 00:51:55,200
So let's focus on an int because so many computer programs of course
1144
00:51:55,200 --> 00:51:57,520
manipulate numbers in some way.
1145
00:51:57,520 --> 00:51:59,110
So what can we do with this?
1146
00:51:59,110 --> 00:52:02,470
Well, if we want to be able to get an integer, lucky enough,
1147
00:52:02,470 --> 00:52:05,980
CS50's library comes not just with get_string but also get_int.
1148
00:52:05,980 --> 00:52:08,760
So that's going to be a third function we now use in C.
1149
00:52:08,760 --> 00:52:12,100
And we need to know what are generally called format codes.
1150
00:52:12,100 --> 00:52:16,030
So that placeholder I called before, percent s, is indeed for a string.
1151
00:52:16,030 --> 00:52:20,860
If we want to place an integer inside of something we're printing to the screen,
1152
00:52:20,860 --> 00:52:24,360
we are, in fact, going to use percent i instead.
1153
00:52:24,360 --> 00:52:28,350
So let's now actually use these building blocks, get_int and percent
1154
00:52:28,350 --> 00:52:31,623
i to actually get numbers in some way to solve a problem.
1155
00:52:31,623 --> 00:52:33,040
Well, what problem could we solve?
1156
00:52:33,040 --> 00:52:36,415
Let's introduce another concept from scratch and programming more generally
1157
00:52:36,415 --> 00:52:39,040
known as conditionals, like those proverbial forks in the road.
1158
00:52:39,040 --> 00:52:40,980
If something is true, do this.
1159
00:52:40,980 --> 00:52:42,700
Else, maybe do this other thing.
1160
00:52:42,700 --> 00:52:46,350
So in Scratch, we might have had a set of puzzle pieces that looked like this.
1161
00:52:46,350 --> 00:52:52,150
If x is less than y, then say, or have the cat say, x is less than y.
1162
00:52:52,150 --> 00:52:53,530
So sort of stupid program.
1163
00:52:53,530 --> 00:52:56,760
But it just demonstrates how we have two variables, x and y.
1164
00:52:56,760 --> 00:52:59,040
In the context of Scratch, we're comparing them
1165
00:52:59,040 --> 00:53:00,460
with a Boolean expression.
1166
00:53:00,460 --> 00:53:04,380
We're using a conditional to then conditionally say or not
1167
00:53:04,380 --> 00:53:08,340
say this phrase here, depending on whether this question has
1168
00:53:08,340 --> 00:53:11,380
an answer of true or false, yes or no.
1169
00:53:11,380 --> 00:53:14,035
In C, it doesn't look all that different.
1170
00:53:14,035 --> 00:53:15,160
It's a little more cryptic.
1171
00:53:15,160 --> 00:53:16,890
But you say literally "if."
1172
00:53:16,890 --> 00:53:20,080
You use parentheses, similar to functions.
1173
00:53:20,080 --> 00:53:23,370
But confusingly, by convention, you put a space after the word "if."
1174
00:53:23,370 --> 00:53:25,360
So you don't put spaces after function names.
1175
00:53:25,360 --> 00:53:27,780
You do put spaces after words like "if."
1176
00:53:27,780 --> 00:53:31,870
And you use the parentheses to conjure up this weird trapezoidal-like shape.
1177
00:53:31,870 --> 00:53:34,360
So there's no real keys that conjure that.
1178
00:53:34,360 --> 00:53:36,880
So C uses parentheses, like most languages.
1179
00:53:36,880 --> 00:53:39,850
And then there's these weird curly braces, which, at least in English,
1180
00:53:39,850 --> 00:53:41,410
we don't use all that often.
1181
00:53:41,410 --> 00:53:44,230
But they're there on your keyboard, English or otherwise.
1182
00:53:44,230 --> 00:53:48,040
And they essentially allow us to create this hugging shape to the puzzle piece.
1183
00:53:48,040 --> 00:53:51,330
Anything inside of those curly braces is going
1184
00:53:51,330 --> 00:53:55,350
to be equivalent to anything inside of this yellow hug that's sort
1185
00:53:55,350 --> 00:53:57,640
of grabbing one or more pieces inside.
1186
00:53:57,640 --> 00:53:58,780
So what do we put inside?
1187
00:53:58,780 --> 00:54:01,280
Well, this part is straightforward-- printf, quote, unquote,
1188
00:54:01,280 --> 00:54:04,540
"x is less than y" backslash n semicolon.
1189
00:54:04,540 --> 00:54:05,800
So nothing new here.
1190
00:54:05,800 --> 00:54:09,760
The only bit of new code is this if construct instead.
1191
00:54:09,760 --> 00:54:12,550
What if you have an if-else, so a two-way fork in the road?
1192
00:54:12,550 --> 00:54:14,350
This is what that looked like in Scratch.
1193
00:54:14,350 --> 00:54:17,370
Same question-- if x is less than y, then say x is less than y.
1194
00:54:17,370 --> 00:54:19,780
Else, say x is not less than y.
1195
00:54:19,780 --> 00:54:22,590
In C, the code is going to be set up initially
1196
00:54:22,590 --> 00:54:27,300
like this, so two sets of curly braces to represent this pair of yellow bars
1197
00:54:27,300 --> 00:54:28,860
and this pair of yellow bars.
1198
00:54:28,860 --> 00:54:31,330
And what's inside of them-- indented, no less,
1199
00:54:31,330 --> 00:54:34,200
just like our pseudocode last week-- is two printfs--
1200
00:54:34,200 --> 00:54:37,330
x is less than y, x is not less than y.
1201
00:54:37,330 --> 00:54:38,110
So that's it.
1202
00:54:38,110 --> 00:54:41,135
So the only new stuff here really is now the else keyword,
1203
00:54:41,135 --> 00:54:43,260
which does not need parentheses because you're just
1204
00:54:43,260 --> 00:54:44,943
saying, else, do this other thing.
1205
00:54:44,943 --> 00:54:46,860
But what if it's a three-way fork in the road?
1206
00:54:46,860 --> 00:54:48,250
And we'll stop after that.
1207
00:54:48,250 --> 00:54:50,970
Here's a three-way fork in the road in Scratch.
1208
00:54:50,970 --> 00:54:53,820
If x is less than y, then say this.
1209
00:54:53,820 --> 00:54:57,430
Else, if x is greater than y, say this.
1210
00:54:57,430 --> 00:55:00,940
Else, if x equals y, then say this.
1211
00:55:00,940 --> 00:55:04,080
So this is a little more precise because now we're handling equality, not
1212
00:55:04,080 --> 00:55:06,360
just greater than or the opposite.
1213
00:55:06,360 --> 00:55:08,980
In C, it's going to look similar to before.
1214
00:55:08,980 --> 00:55:10,438
But we're adding this element here.
1215
00:55:10,438 --> 00:55:13,188
And at first glance, especially if you've never programmed before,
1216
00:55:13,188 --> 00:55:15,160
it looks like I'm an idiot and I made a typo.
1217
00:55:15,160 --> 00:55:17,510
What looks wrong?
1218
00:55:17,510 --> 00:55:20,040
There's two equal signs-- not a typo.
1219
00:55:20,040 --> 00:55:23,000
So it turns out, recall from earlier, when
1220
00:55:23,000 --> 00:55:25,410
we use the equal sign the first time around,
1221
00:55:25,410 --> 00:55:28,760
we used it in the context of getting a return value back from a function,
1222
00:55:28,760 --> 00:55:32,970
like the get_string function handed me back the user's answer.
1223
00:55:32,970 --> 00:55:36,180
So unfortunately, because humans decades ago decided, hey,
1224
00:55:36,180 --> 00:55:39,410
let's use the equal sign to assign a return
1225
00:55:39,410 --> 00:55:43,410
value from the right-hand side of a line of code to the left-hand side,
1226
00:55:43,410 --> 00:55:46,260
we sort of painted ourselves into a corner and like, oh, shoot,
1227
00:55:46,260 --> 00:55:49,280
what do we do when we actually want to test for equality
1228
00:55:49,280 --> 00:55:51,150
of two values on the left and right?
1229
00:55:51,150 --> 00:55:55,500
So what most languages, including C, do, is use double equal signs.
1230
00:55:55,500 --> 00:55:57,900
So you say double equals or equals equals or whatever.
1231
00:55:57,900 --> 00:56:00,210
But it is, in fact, syntactically correct.
1232
00:56:00,210 --> 00:56:03,210
What's inside of these three sets of curly braces?
1233
00:56:03,210 --> 00:56:07,220
Same idea-- printf, printf, printf based on what English phrase
1234
00:56:07,220 --> 00:56:09,240
you want to print out.
1235
00:56:09,240 --> 00:56:12,580
So this code, both in Scratch and C, I'll claim is correct.
1236
00:56:12,580 --> 00:56:16,290
It won't run because we still need the other stuff, the equivalent of the when
1237
00:56:16,290 --> 00:56:17,530
green, flag clicked.
1238
00:56:17,530 --> 00:56:19,690
But out of context, this code is correct.
1239
00:56:19,690 --> 00:56:22,522
But there's a subtle weakness in design.
1240
00:56:22,522 --> 00:56:24,730
And we'll talk a lot about this this week and beyond.
1241
00:56:24,730 --> 00:56:27,400
"Correctness" just means the code does what it's supposed to do.
1242
00:56:27,400 --> 00:56:29,430
Design is more subjective.
1243
00:56:29,430 --> 00:56:33,330
How well have you written your argument in an English paper, how well
1244
00:56:33,330 --> 00:56:36,030
have you written your code, is design.
1245
00:56:36,030 --> 00:56:40,020
This code is not designed as well as it could be because I'm
1246
00:56:40,020 --> 00:56:42,430
doing more work than I need to.
1247
00:56:42,430 --> 00:56:43,540
Yeah, in the back.
1248
00:56:43,540 --> 00:56:45,540
AUDIENCE: You don't need the [INAUDIBLE].
1249
00:56:45,540 --> 00:56:47,915
DAVID J. MALAN: Yeah, I don't need the x equals equals y.
1250
00:56:47,915 --> 00:56:48,790
But why, logically?
1251
00:56:48,790 --> 00:56:53,417
AUDIENCE: Because [INAUDIBLE] [? there's no need. ?] [INAUDIBLE].
1252
00:56:53,417 --> 00:56:55,500
DAVID J. MALAN: Exactly, that's just a math thing.
1253
00:56:55,500 --> 00:56:58,500
Either x is less than y, or it's greater than y.
1254
00:56:58,500 --> 00:57:02,110
Or the third and final option is they must be equal.
1255
00:57:02,110 --> 00:57:07,020
So it's subtle, but why would you bother wasting time writing a line of code
1256
00:57:07,020 --> 00:57:09,552
and expecting the computer to run a line of code that
1257
00:57:09,552 --> 00:57:11,760
is just going to answer a question that logically you
1258
00:57:11,760 --> 00:57:13,480
could have concluded already?
1259
00:57:13,480 --> 00:57:18,970
Because if x is not less than y and x is not greater than y, then, my god,
1260
00:57:18,970 --> 00:57:22,710
just print out x is equal to y because you know, at that point, logically
1261
00:57:22,710 --> 00:57:23,470
it's true.
1262
00:57:23,470 --> 00:57:25,620
You don't need to waste your time or the computer's
1263
00:57:25,620 --> 00:57:28,830
asking a third question unnecessarily.
1264
00:57:28,830 --> 00:57:30,415
In reality, it's not a huge deal.
1265
00:57:30,415 --> 00:57:32,790
No one's going to notice in the real world on a Mac or PC
1266
00:57:32,790 --> 00:57:34,332
that there's this extra line of code.
1267
00:57:34,332 --> 00:57:35,650
But it's a bad habit.
1268
00:57:35,650 --> 00:57:36,460
Keep it simple.
1269
00:57:36,460 --> 00:57:39,852
Don't write code that doesn't need to be there if, logically, you
1270
00:57:39,852 --> 00:57:40,810
can conclude otherwise.
1271
00:57:40,810 --> 00:57:44,290
So in fact, let's clean this up both in Scratch and in C. I can tighten this up,
1272
00:57:44,290 --> 00:57:47,800
so to speak, use less code here, less code here.
1273
00:57:47,800 --> 00:57:51,240
And honestly, if only statistically, the less code I write, the less likely
1274
00:57:51,240 --> 00:57:53,080
I am going to make mistakes.
1275
00:57:53,080 --> 00:57:56,380
So that, too, is probably a net positive overall.
1276
00:57:56,380 --> 00:57:59,900
Writing less code is generally better than writing more code,
1277
00:57:59,900 --> 00:58:02,620
not unlike English essays too, perhaps.
1278
00:58:02,620 --> 00:58:08,860
All right, questions about this feature of C, conditionals and this syntax?
1279
00:58:08,860 --> 00:58:09,856
Yeah?
1280
00:58:09,856 --> 00:58:12,648
AUDIENCE: [INAUDIBLE]
1281
00:58:12,648 --> 00:58:14,440
DAVID J. MALAN: Oh, a really good question.
1282
00:58:14,440 --> 00:58:15,523
And, yes, jumping the gun.
1283
00:58:15,523 --> 00:58:18,540
There are alternative ways to solve problems like these.
1284
00:58:18,540 --> 00:58:21,893
And the question was, to summarize, when to use "if, else, if, else"
1285
00:58:21,893 --> 00:58:23,560
versus what's called a switch statement.
1286
00:58:23,560 --> 00:58:24,700
More on those another time.
1287
00:58:24,700 --> 00:58:27,575
But this is going to be true, in general, in programming, not just C,
1288
00:58:27,575 --> 00:58:29,350
not just in Scratch, but every language.
1289
00:58:29,350 --> 00:58:34,020
There are going to be several, dozens, hundreds, an infinite number of ways
1290
00:58:34,020 --> 00:58:34,950
to solve problems.
1291
00:58:34,950 --> 00:58:36,700
Among the things we're going to teach you,
1292
00:58:36,700 --> 00:58:40,000
though, is indeed how to do things well or better than you might otherwise.
1293
00:58:40,000 --> 00:58:41,792
And we're going to introduce you eventually
1294
00:58:41,792 --> 00:58:46,800
to another feature of the language that can even simplify this code, too.
1295
00:58:46,800 --> 00:58:49,030
So for now, let's actually use this then.
1296
00:58:49,030 --> 00:58:51,640
So let me go over to VS Code again.
1297
00:58:51,640 --> 00:58:55,780
I'm going to go ahead now and clear my terminal window down here.
1298
00:58:55,780 --> 00:58:58,890
I'm going to go ahead and close the hello.c tab just so that it--
1299
00:58:58,890 --> 00:59:00,390
we're going to create a new program.
1300
00:59:00,390 --> 00:59:03,988
And let's just do something a little simple using some operator, so to speak.
1301
00:59:03,988 --> 00:59:05,530
And I haven't used this word by name.
1302
00:59:05,530 --> 00:59:07,680
But it turns out that there's lots of operators
1303
00:59:07,680 --> 00:59:10,440
that come with C, just like a lot of operators that
1304
00:59:10,440 --> 00:59:14,890
came with Scratch, for doing assignment or less than or less than
1305
00:59:14,890 --> 00:59:17,440
or equal to, greater than, greater than or equal to,
1306
00:59:17,440 --> 00:59:19,653
actually equal to, not equal to.
1307
00:59:19,653 --> 00:59:21,320
Now, some of these are a little cryptic.
1308
00:59:21,320 --> 00:59:25,550
But there's no easily-found key on your US English keyboard,
1309
00:59:25,550 --> 00:59:28,610
at least, where you can do less than or equals or greater than or equals.
1310
00:59:28,610 --> 00:59:30,940
So what most programming languages do is you
1311
00:59:30,940 --> 00:59:34,330
don't use a special symbol where there's an angled bracket and then
1312
00:59:34,330 --> 00:59:35,420
a line below it.
1313
00:59:35,420 --> 00:59:37,100
You actually just use two characters.
1314
00:59:37,100 --> 00:59:39,910
So greater than or equal is literally this, this.
1315
00:59:39,910 --> 00:59:41,710
Less than or equal is literally this, this.
1316
00:59:41,710 --> 00:59:44,260
We already saw that equals is this, this.
1317
00:59:44,260 --> 00:59:47,283
And not equals is to use an exclamation point.
1318
00:59:47,283 --> 00:59:48,950
So this, too, is a thing in programming.
1319
00:59:48,950 --> 00:59:53,560
Using the exclamation point, pronounced bang, is how you invert,
1320
00:59:53,560 --> 00:59:55,040
logically, certain things.
1321
00:59:55,040 --> 01:00:00,320
So "bang equals" or "not equals" is how you would express exactly that idea.
1322
01:00:00,320 --> 01:00:02,920
It's just a symbol on the keyboard that some human decided,
1323
01:00:02,920 --> 01:00:05,270
let's use this one to invert the idea.
1324
01:00:05,270 --> 01:00:08,650
But we're going to need one other thing for this program, specifically
1325
01:00:08,650 --> 01:00:11,770
variables, which we've used already because, in Scratch, we
1326
01:00:11,770 --> 01:00:12,920
got one for free.
1327
01:00:12,920 --> 01:00:17,600
We had that answer variable that stored the return value of the ask block.
1328
01:00:17,600 --> 01:00:19,750
But let's consider, in general, how you can--
1329
01:00:19,750 --> 01:00:21,680
and probably did for problem set 0--
1330
01:00:21,680 --> 01:00:24,430
use a variable of your own, like keeping track of a counter
1331
01:00:24,430 --> 01:00:25,750
or a score or the like.
1332
01:00:25,750 --> 01:00:28,490
In Scratch, if you want to create a variable called counter,
1333
01:00:28,490 --> 01:00:31,330
you can set it equal to some initial value, like 0.
1334
01:00:31,330 --> 01:00:34,100
In C, that code is going to look similar.
1335
01:00:34,100 --> 01:00:36,100
You literally just write whatever name you
1336
01:00:36,100 --> 01:00:38,920
want to give the variable, then an equal sign, and then
1337
01:00:38,920 --> 01:00:41,210
the value you want to give that variable.
1338
01:00:41,210 --> 01:00:44,390
And because the equal sign is the assignment operator,
1339
01:00:44,390 --> 01:00:49,190
it will behave essentially right to left and copy the 0 into counter.
1340
01:00:49,190 --> 01:00:52,520
But this isn't enough for C. Remember that you, the programmer,
1341
01:00:52,520 --> 01:00:54,950
have to tell the computer, is this indeed a number?
1342
01:00:54,950 --> 01:00:55,700
Is it a letter?
1343
01:00:55,700 --> 01:00:56,480
Is it an image?
1344
01:00:56,480 --> 01:00:57,260
Is it a sound?
1345
01:00:57,260 --> 01:01:00,050
You have to tell the computer that this is an integer,
1346
01:01:00,050 --> 01:01:02,990
otherwise written as "int" for short in C.
1347
01:01:02,990 --> 01:01:08,210
But there's one other stupid detail that's missing, which is now--
1348
01:01:08,210 --> 01:01:10,320
semicolon to finish the thought here.
1349
01:01:10,320 --> 01:01:13,800
But this then is equivalent to this in Scratch.
1350
01:01:13,800 --> 01:01:14,600
Let's do another.
1351
01:01:14,600 --> 01:01:18,780
In Scratch, if you wanted to increment the counter, that is add 1 to it,
1352
01:01:18,780 --> 01:01:20,960
you could literally use this puzzle piece here
1353
01:01:20,960 --> 01:01:22,640
and specify you want to add 1.
1354
01:01:22,640 --> 01:01:24,580
In C, it's going to look like this--
1355
01:01:24,580 --> 01:01:27,090
counter equals counter plus 1 semicolon.
1356
01:01:27,090 --> 01:01:29,600
Now, at a glance, this seems like a paradox of sorts.
1357
01:01:29,600 --> 01:01:33,560
How can counter equal counter plus 1?
1358
01:01:33,560 --> 01:01:35,460
I can't make that math expression true.
1359
01:01:35,460 --> 01:01:37,140
But it's not math in this case.
1360
01:01:37,140 --> 01:01:38,940
The single equal sign is assignment.
1361
01:01:38,940 --> 01:01:43,190
So this means take the current value of counter, whatever it is, add 1 to it,
1362
01:01:43,190 --> 01:01:47,730
and then copy that value from right to left into the same variable,
1363
01:01:47,730 --> 01:01:51,080
thereby changing it from 1 to 2, 2 to 3, and so forth.
1364
01:01:51,080 --> 01:01:53,240
This, though, is so common in programming,
1365
01:01:53,240 --> 01:01:56,480
to be able to increment or even decrement numbers by one or two
1366
01:01:56,480 --> 01:01:58,800
or more, is that you can tighten it like this.
1367
01:01:58,800 --> 01:02:01,460
This is the exact same thing-- a little faster to type,
1368
01:02:01,460 --> 01:02:04,220
saves you keystrokes, maybe less chance for error.
1369
01:02:04,220 --> 01:02:08,050
Counter plus equals 1 semicolon is the exact same idea.
1370
01:02:08,050 --> 01:02:13,020
Better still, this is so common in C and C++ and Java that there's a third way
1371
01:02:13,020 --> 01:02:16,600
to do this, to my comment earlier about solving problems in different ways.
1372
01:02:16,600 --> 01:02:21,420
The most canonical, the most popular way is probably just to say counter++
1373
01:02:21,420 --> 01:02:26,170
semicolon, which literally, automatically, adds 1 to that value.
1374
01:02:26,170 --> 01:02:27,190
It only works for 1.
1375
01:02:27,190 --> 01:02:29,317
If you want to do 2 or 3 or some other increment,
1376
01:02:29,317 --> 01:02:31,150
you have to use one of the other approaches.
1377
01:02:31,150 --> 01:02:33,460
But this simply does the same thing as this.
1378
01:02:33,460 --> 01:02:35,680
And if you want to invert it to negative 1,
1379
01:02:35,680 --> 01:02:38,740
you change the plus plus to a minus minus instead.
1380
01:02:38,740 --> 01:02:41,503
So again, just little things that we'll see and pick up over time.
1381
01:02:41,503 --> 01:02:43,920
Invariably, you'll have to look them up or check the notes
1382
01:02:43,920 --> 01:02:45,378
or look back at the lecture slides.
1383
01:02:45,378 --> 01:02:50,330
But in time, this will get familiar if you are not already familiar.
1384
01:02:50,330 --> 01:02:55,090
So let's consider just logically how we might implement this in code.
1385
01:02:55,090 --> 01:02:56,520
Let's go back to VS Code here.
1386
01:02:56,520 --> 01:02:58,770
And let me propose that we create a program called
1387
01:02:58,770 --> 01:03:03,340
compare.c whose purpose in life is just to compare a couple of values.
1388
01:03:03,340 --> 01:03:06,720
I'm going to go ahead and proactively, based on the previous chat,
1389
01:03:06,720 --> 01:03:09,460
include CS50's library from the get go.
1390
01:03:09,460 --> 01:03:12,360
I'm going to include standard io.h from the get go.
1391
01:03:12,360 --> 01:03:15,010
So I can use get_int and printf respectively.
1392
01:03:15,010 --> 01:03:17,670
I'm going to just, on faith, type int main(void).
1393
01:03:17,670 --> 01:03:20,080
And today, we won't explain what that does.
1394
01:03:20,080 --> 01:03:21,100
More on that to come.
1395
01:03:21,100 --> 01:03:24,130
For now, just assume it's like, when green, flag clicked.
1396
01:03:24,130 --> 01:03:26,230
But in this program, let's do a couple of things.
1397
01:03:26,230 --> 01:03:31,490
Let's declare an integer called x and assign it the return value of get_int.
1398
01:03:31,490 --> 01:03:32,740
And let's just keep it simple.
1399
01:03:32,740 --> 01:03:36,390
Let's ask the user not what's their name, but "What's x?," question mark,
1400
01:03:36,390 --> 01:03:37,540
semicolon.
1401
01:03:37,540 --> 01:03:41,130
Now, so that we have something to compare, let's do it again but with y.
1402
01:03:41,130 --> 01:03:46,188
int y equals get_int, quote, unquote, "What's y?", question mark.
1403
01:03:46,188 --> 01:03:47,980
And I'm leaving again a space just visually
1404
01:03:47,980 --> 01:03:51,750
so the cursor nudges over a bit, followed by a semicolon.
1405
01:03:51,750 --> 01:03:54,270
At this point in the story, my users will
1406
01:03:54,270 --> 01:03:56,590
be prompted for x and y respectively.
1407
01:03:56,590 --> 01:03:58,270
Let's do something with those values.
1408
01:03:58,270 --> 01:04:05,110
How about if x is less than y, then go ahead and print out, quote, unquote,
1409
01:04:05,110 --> 01:04:10,620
"x is less than y" backslash n, close quote, semicolon.
1410
01:04:10,620 --> 01:04:13,840
All right, and let me hide my terminal window for just a moment.
1411
01:04:13,840 --> 01:04:16,450
This is a 13-line program at the moment.
1412
01:04:16,450 --> 01:04:19,510
But really, it's five or six interesting lines.
1413
01:04:19,510 --> 01:04:22,570
The rest has been copy/paste from previous programs.
1414
01:04:22,570 --> 01:04:24,040
Notice a few details.
1415
01:04:24,040 --> 01:04:27,290
One, I've indeed used my curly braces here.
1416
01:04:27,290 --> 01:04:29,040
And notice, if you highlight lines, you'll
1417
01:04:29,040 --> 01:04:31,665
actually see little dots that can help you make sure, oh, there
1418
01:04:31,665 --> 01:04:33,430
are indeed four spaces there.
1419
01:04:33,430 --> 01:04:36,520
I've been indenting just like we did last week with pseudocode.
1420
01:04:36,520 --> 01:04:38,950
Strictly speaking, it's not necessary.
1421
01:04:38,950 --> 01:04:41,850
But it's going to be way easier to read your code
1422
01:04:41,850 --> 01:04:45,870
if you do at all of this whitespace, so to speak, than if you write
1423
01:04:45,870 --> 01:04:49,470
and then submit to us, as homework, a program that looks sort of godawful
1424
01:04:49,470 --> 01:04:53,502
like this, which is going to make it much, much harder for the human
1425
01:04:53,502 --> 01:04:56,710
to read it, for you to read it, your colleagues in the real world to read it.
1426
01:04:56,710 --> 01:04:58,740
But the computer is actually not going to care.
1427
01:04:58,740 --> 01:05:03,360
In fact, as an aside, one of the tools we have built into VS Code for CS50
1428
01:05:03,360 --> 01:05:05,800
is this button at top called style50.
1429
01:05:05,800 --> 01:05:08,250
This is a program that we indeed wrote that will give you
1430
01:05:08,250 --> 01:05:11,260
suggestions on how to improve the style of your code
1431
01:05:11,260 --> 01:05:15,070
so it looks like the right way that programmers would generally write it.
1432
01:05:15,070 --> 01:05:18,910
As an aside, the computer world is fraught with religious debate,
1433
01:05:18,910 --> 01:05:21,190
so to speak, as to what code should look like.
1434
01:05:21,190 --> 01:05:23,940
And people in the real world will have really stupid arguments
1435
01:05:23,940 --> 01:05:26,850
over how many spaces to use for indentation
1436
01:05:26,850 --> 01:05:29,200
and what lines code should go on and so forth.
1437
01:05:29,200 --> 01:05:31,330
Generally, in the real world or in a class,
1438
01:05:31,330 --> 01:05:34,620
there's an official style guide that someone autocratically
1439
01:05:34,620 --> 01:05:36,390
declares this is how everyone should write
1440
01:05:36,390 --> 01:05:40,630
their code so that just everyone's code in the company or course looks the same.
1441
01:05:40,630 --> 01:05:44,560
But you'll find, in the real world, reasonable people will disagree.
1442
01:05:44,560 --> 01:05:47,340
When you click style50, it will be formatted as we
1443
01:05:47,340 --> 01:05:49,120
ourselves recommend in CS50.
1444
01:05:49,120 --> 01:05:50,820
And in fact, let me zoom out here.
1445
01:05:50,820 --> 01:05:53,110
And this looks a little cryptic at first glance.
1446
01:05:53,110 --> 01:05:55,500
But on the left is the code that I just wrote and made
1447
01:05:55,500 --> 01:05:57,750
a mess of by deleting all that whitespace.
1448
01:05:57,750 --> 01:06:03,070
On the right is the way the code should look if it is well styled.
1449
01:06:03,070 --> 01:06:05,640
So whereas correctness is all about, does the code work
1450
01:06:05,640 --> 01:06:08,160
the way it's supposed to, design is about,
1451
01:06:08,160 --> 01:06:10,260
how well have you written that code?
1452
01:06:10,260 --> 01:06:11,250
Is it efficient?
1453
01:06:11,250 --> 01:06:12,570
Did you make good decisions?
1454
01:06:12,570 --> 01:06:14,540
Style is purely aesthetic.
1455
01:06:14,540 --> 01:06:15,600
Is it readable?
1456
01:06:15,600 --> 01:06:16,950
Does it follow a standard?
1457
01:06:16,950 --> 01:06:20,000
Can another human easily skim it top to bottom, left to right,
1458
01:06:20,000 --> 01:06:21,570
and understand what's going on?
1459
01:06:21,570 --> 01:06:25,620
So these green highlights are saying, please add white space there.
1460
01:06:25,620 --> 01:06:28,310
And so I can actually change my code to match.
1461
01:06:28,310 --> 01:06:30,455
On the left-hand side here, if I realize,
1462
01:06:30,455 --> 01:06:33,890
oh, my code is looking pretty ugly, watch on line 6 at left.
1463
01:06:33,890 --> 01:06:35,870
As I hit the space bar two--
1464
01:06:35,870 --> 01:06:40,670
oops, sorry-- on the left, 1, 2, 3, 4, notice
1465
01:06:40,670 --> 01:06:44,090
that the right-hand side is starting to be happier with my code
1466
01:06:44,090 --> 01:06:46,190
by getting rid of the green indicators.
1467
01:06:46,190 --> 01:06:48,840
And I can do 1, 2, 3, 4.
1468
01:06:48,840 --> 01:06:49,730
That fixed that.
1469
01:06:49,730 --> 01:06:52,380
Over here, I can do 1, 2, 3, 4.
1470
01:06:52,380 --> 01:06:56,563
I can move this onto its own line by hitting Enter.
1471
01:06:56,563 --> 01:06:58,730
And you know what, if it's taking too long, once you
1472
01:06:58,730 --> 01:07:01,105
get into the habit of things, you can just Apply Changes.
1473
01:07:01,105 --> 01:07:03,540
It will give you the suggestions automatically.
1474
01:07:03,540 --> 01:07:04,950
And we're done and on our way.
1475
01:07:04,950 --> 01:07:09,300
But for practice's sake, I would get into the habit of doing things manually
1476
01:07:09,300 --> 01:07:11,620
until it gets boring and tedious, at which point,
1477
01:07:11,620 --> 01:07:14,470
you might as well automate the process with a single click.
1478
01:07:14,470 --> 01:07:16,690
All right, so let's actually run this code.
1479
01:07:16,690 --> 01:07:19,830
I'm going to go ahead and open my terminal window again and clear it
1480
01:07:19,830 --> 01:07:20,860
for clarity.
1481
01:07:20,860 --> 01:07:25,570
I'm going to run make compare and hope that I didn't make any mistakes.
1482
01:07:25,570 --> 01:07:27,030
I don't seem to have yet--
1483
01:07:27,030 --> 01:07:28,540
"./compare."
1484
01:07:28,540 --> 01:07:30,220
And now notice I'm prompted for x.
1485
01:07:30,220 --> 01:07:31,200
Let's type 1.
1486
01:07:31,200 --> 01:07:33,120
For y, let's type 2.
1487
01:07:33,120 --> 01:07:33,840
Enter.
1488
01:07:33,840 --> 01:07:35,857
And x is less than y.
1489
01:07:35,857 --> 01:07:37,690
Let's do a little sanity check, so to speak.
1490
01:07:37,690 --> 01:07:39,910
Let's rerun it-- c
1491
01:07:39,910 --> 01:07:40,630
What's x?
1492
01:07:40,630 --> 01:07:43,900
Let's do 2 this time; 1 for y.
1493
01:07:43,900 --> 01:07:45,452
And this time, it said nothing.
1494
01:07:45,452 --> 01:07:47,160
So that's to be expected because I didn't
1495
01:07:47,160 --> 01:07:49,540
have a two-way or a three-way fork in the road.
1496
01:07:49,540 --> 01:07:51,810
The only time this code should say anything
1497
01:07:51,810 --> 01:07:55,162
is if, indeed, x is less than y.
1498
01:07:55,162 --> 01:07:58,120
So for those of you who might be more visual when it comes to learning,
1499
01:07:58,120 --> 01:08:01,120
here's a flow chart that represents this same exact program.
1500
01:08:01,120 --> 01:08:04,870
If you read it top to bottom, you start the program with "./compare."
1501
01:08:04,870 --> 01:08:07,240
You are then prompted for x and y.
1502
01:08:07,240 --> 01:08:09,452
And you're asked this, is x less than y?
1503
01:08:09,452 --> 01:08:11,160
And the fact that this is a diamond means
1504
01:08:11,160 --> 01:08:15,430
this is a Boolean expression, a question that the computer is asking itself.
1505
01:08:15,430 --> 01:08:19,950
If the answer to that question is true, then, quote, unquote, "x is less than y"
1506
01:08:19,950 --> 01:08:20,580
gets printed.
1507
01:08:20,580 --> 01:08:22,229
And the program stops.
1508
01:08:22,229 --> 01:08:26,710
Else, if x is not less than y, as in the second scenario,
1509
01:08:26,710 --> 01:08:29,439
the answer is, of course, false, and nothing more happens.
1510
01:08:29,439 --> 01:08:32,710
But we can build out this tree, so to speak, by adding a bit more code.
1511
01:08:32,710 --> 01:08:35,229
So let's make it look like the second Scratch example.
1512
01:08:35,229 --> 01:08:41,200
If I go back here, it's not hard to just say, else, if x is not less than y,
1513
01:08:41,200 --> 01:08:42,180
let's say that.
1514
01:08:42,180 --> 01:08:46,840
"x is not less than y" backslash n, close quote, semicolon.
1515
01:08:46,840 --> 01:08:50,020
Let me now go ahead and rerun make compare.
1516
01:08:50,020 --> 01:08:50,939
Enter.
1517
01:08:50,939 --> 01:08:52,675
"./compare," Enter.
1518
01:08:52,675 --> 01:08:54,300
And again, I'll do the second example--
1519
01:08:54,300 --> 01:08:57,160
2, which is bigger, and 1, which is smaller.
1520
01:08:57,160 --> 01:09:01,029
And this time, I will see x is not less than y.
1521
01:09:01,029 --> 01:09:05,260
If, then, we were to look not at this flow chart but a slightly bigger one,
1522
01:09:05,260 --> 01:09:06,798
you can visualize it this way.
1523
01:09:06,798 --> 01:09:09,340
Everything in the left-hand side of this picture is the same.
1524
01:09:09,340 --> 01:09:13,899
But if it's not true that x is less than y, the answer is thus false.
1525
01:09:13,899 --> 01:09:16,899
This time we say, quote, unquote, "x is not less than y."
1526
01:09:16,899 --> 01:09:20,439
And we can do this obviously one final time just to bring the point home.
1527
01:09:20,439 --> 01:09:26,229
If I go back to my code and I even more pedantically compare these three values,
1528
01:09:26,229 --> 01:09:27,700
let me go ahead and do this.
1529
01:09:27,700 --> 01:09:31,630
So, else-- hm, I don't want an else actually.
1530
01:09:31,630 --> 01:09:34,560
So let's go ahead and do this--
1531
01:09:34,560 --> 01:09:42,670
else if x is greater than y, let's then say "x is greater than y" in English.
1532
01:09:42,670 --> 01:09:49,560
And then, finally, have an else that says printf "x is equal to y,"
1533
01:09:49,560 --> 01:09:53,162
close quote, or rather backslash n, close quote, semicolon.
1534
01:09:53,162 --> 01:09:55,120
So just to show this all on the screen at once,
1535
01:09:55,120 --> 01:09:57,760
this is identical Now to that Scratch version.
1536
01:09:57,760 --> 01:10:00,870
It's well designed because I'm not asking the equals equals question
1537
01:10:00,870 --> 01:10:02,260
unnecessarily.
1538
01:10:02,260 --> 01:10:07,210
If I go back to my terminal window here, clear the screen, run make compare,
1539
01:10:07,210 --> 01:10:10,150
Enter, and then "./compare" again.
1540
01:10:10,150 --> 01:10:10,920
Enter.
1541
01:10:10,920 --> 01:10:11,680
"What's x?"
1542
01:10:11,680 --> 01:10:12,700
Let's do 1.
1543
01:10:12,700 --> 01:10:14,950
Let's do 2. "x is less than y."
1544
01:10:14,950 --> 01:10:16,950
Let's run it again-- "./compare."
1545
01:10:16,950 --> 01:10:19,800
"What's"-- 2 and 1.
1546
01:10:19,800 --> 01:10:21,220
"x is greater than y."
1547
01:10:21,220 --> 01:10:22,930
One more time-- "./compare."
1548
01:10:22,930 --> 01:10:23,480
"What's x?"
1549
01:10:23,480 --> 01:10:23,980
1.
1550
01:10:23,980 --> 01:10:24,703
"What's y?"
1551
01:10:24,703 --> 01:10:25,510
1.
1552
01:10:25,510 --> 01:10:28,420
And now x is equal to y.
1553
01:10:28,420 --> 01:10:30,750
As an aside, if I seem to be typing fairly fast,
1554
01:10:30,750 --> 01:10:32,500
you can actually cheat with your keyboard.
1555
01:10:32,500 --> 01:10:36,210
If you go up or down, you can scroll through all of the past commands
1556
01:10:36,210 --> 01:10:37,030
that you've typed.
1557
01:10:37,030 --> 01:10:38,920
So it's actually very useful.
1558
01:10:38,920 --> 01:10:42,510
If you just hit up, it will pre-write the previous command
1559
01:10:42,510 --> 01:10:44,730
for you, at which point you can just say Enter.
1560
01:10:44,730 --> 01:10:48,490
Or there's other fancy features built into this programming environment.
1561
01:10:48,490 --> 01:10:52,418
If you do dot slash C-O-M and then get bored
1562
01:10:52,418 --> 01:10:54,210
with typing out the whole English word, you
1563
01:10:54,210 --> 01:10:57,300
can hit Tab for tab completion like in a web browser.
1564
01:10:57,300 --> 01:10:59,520
And it, too, will autocomplete if it finds
1565
01:10:59,520 --> 01:11:01,990
a file that starts with those letters.
1566
01:11:01,990 --> 01:11:04,290
So little efficiencies here.
1567
01:11:04,290 --> 01:11:07,280
Questions then on the code here?
1568
01:11:07,280 --> 01:11:07,780
Yeah?
1569
01:11:07,780 --> 01:11:09,250
AUDIENCE: I have a question about libraries.
1570
01:11:09,250 --> 01:11:09,615
DAVID J. MALAN: Sure.
1571
01:11:09,615 --> 01:11:11,407
AUDIENCE: [INAUDIBLE] is there any downside
1572
01:11:11,407 --> 01:11:13,200
to putting in all the libraries?
1573
01:11:13,200 --> 01:11:13,960
DAVID J. MALAN: A good question.
1574
01:11:13,960 --> 01:11:16,502
Is there any downside to just putting in all of the libraries
1575
01:11:16,502 --> 01:11:18,830
like we saw in the manual pages a moment ago?
1576
01:11:18,830 --> 01:11:19,620
Performance.
1577
01:11:19,620 --> 01:11:23,380
So generally speaking, C is meant to be a very efficient language,
1578
01:11:23,380 --> 01:11:25,330
so much so that, even though it's decades old,
1579
01:11:25,330 --> 01:11:28,870
still used omnipresently nowadays because it's so fast.
1580
01:11:28,870 --> 01:11:30,490
It therefore minimizes time.
1581
01:11:30,490 --> 01:11:31,720
It minimizes energy use.
1582
01:11:31,720 --> 01:11:33,400
So it's still being used heavily.
1583
01:11:33,400 --> 01:11:36,940
You would slow things down if you told the compiler, by the way,
1584
01:11:36,940 --> 01:11:40,130
give me all of these other functions that I'm never going to use.
1585
01:11:40,130 --> 01:11:43,000
So in short, just don't do that because it's unnecessary.
1586
01:11:43,000 --> 01:11:44,200
But a good question.
1587
01:11:44,200 --> 01:11:48,210
Other questions on what we've done here?
1588
01:11:48,210 --> 01:11:48,890
Yeah, in front.
1589
01:11:48,890 --> 01:11:51,920
AUDIENCE: [? Just to follow up, ?] [? why is it C? ?]
1590
01:11:51,920 --> 01:11:54,290
DAVID J. MALAN: What is it-- oh, why is C faster?
1591
01:11:54,290 --> 01:11:56,180
Why is C faster than other languages, let
1592
01:11:56,180 --> 01:11:58,550
me answer that in more detail in week 6, when
1593
01:11:58,550 --> 01:12:02,750
you'll see how much easier it is to write code in other languages
1594
01:12:02,750 --> 01:12:05,430
because someone else is doing a lot of the work for you.
1595
01:12:05,430 --> 01:12:08,240
So as an introductory course, we're teaching you bottom up,
1596
01:12:08,240 --> 01:12:09,600
like how do you write code?
1597
01:12:09,600 --> 01:12:11,340
How does the computer understand code?
1598
01:12:11,340 --> 01:12:13,680
Eventually, this kind of stuff, certainly after five,
1599
01:12:13,680 --> 01:12:16,950
six weeks of this, it's going to get tedious doing some of these things.
1600
01:12:16,950 --> 01:12:19,985
We're going to switch to another language that takes away the tedium
1601
01:12:19,985 --> 01:12:21,860
and allows us to really focus on the problems
1602
01:12:21,860 --> 01:12:25,020
to be solved once we've graduated to that point.
1603
01:12:25,020 --> 01:12:25,864
Yeah?
1604
01:12:25,864 --> 01:12:28,375
AUDIENCE: [INAUDIBLE] shortcuts?
1605
01:12:28,375 --> 01:12:29,250
DAVID J. MALAN: Sure.
1606
01:12:29,250 --> 01:12:31,960
To repeat the keyboard shortcuts, you can just go up, up, up, up, up.
1607
01:12:31,960 --> 01:12:34,290
And that will go through all of your previous commands, at which point
1608
01:12:34,290 --> 01:12:35,310
you can just hit Enter.
1609
01:12:35,310 --> 01:12:37,180
Or you can use Tab completion.
1610
01:12:37,180 --> 01:12:39,270
So you can start typing a word like "code."
1611
01:12:39,270 --> 01:12:42,450
And C-O-D tab will finish the thought.
1612
01:12:42,450 --> 01:12:46,385
Or dot slash C-O-M Tab will finish that thought just
1613
01:12:46,385 --> 01:12:47,760
to save yourself some keystrokes.
1614
01:12:47,760 --> 01:12:50,670
And clearing the screen is Control L, which
1615
01:12:50,670 --> 01:12:54,330
has no functional purpose other than keeping things neat and tidy in class.
1616
01:12:54,330 --> 01:12:55,738
So a design question.
1617
01:12:55,738 --> 01:12:57,280
So this code, I dare say, is correct.
1618
01:12:57,280 --> 01:12:58,840
Let me zoom in a little bit here.
1619
01:12:58,840 --> 01:13:03,570
Let me change the code to just do this, even though we already saw from Scratch
1620
01:13:03,570 --> 01:13:05,650
that we probably shouldn't do this.
1621
01:13:05,650 --> 01:13:10,920
Why should we not do this if, especially, I'm just more comfortable
1622
01:13:10,920 --> 01:13:14,380
asking three separate questions, like if x is less than y,
1623
01:13:14,380 --> 01:13:17,310
if x is greater than y, if x equals y, do this?
1624
01:13:17,310 --> 01:13:18,800
It's a nice world to live in.
1625
01:13:18,800 --> 01:13:19,800
Just ask your questions.
1626
01:13:19,800 --> 01:13:22,750
You don't have to worry about else, else-if, else-if, forks in the road.
1627
01:13:22,750 --> 01:13:24,125
You can just ask three questions.
1628
01:13:24,125 --> 01:13:30,380
But let's put a finger on, why is this correct, yes, but not well designed?
1629
01:13:30,380 --> 01:13:31,380
Yeah, in back again?
1630
01:13:31,380 --> 01:13:34,951
AUDIENCE: [INAUDIBLE]
1631
01:13:34,951 --> 01:13:38,665
1632
01:13:38,665 --> 01:13:40,540
DAVID J. MALAN: OK, there could be cases that
1633
01:13:40,540 --> 01:13:42,430
are potentially outside of these three.
1634
01:13:42,430 --> 01:13:44,920
Because this is relatively simple math, comparing numbers,
1635
01:13:44,920 --> 01:13:46,545
we don't have to worry about that here.
1636
01:13:46,545 --> 01:13:48,910
But, yes, in general, you might miss a scenario
1637
01:13:48,910 --> 01:13:50,685
without using a catchall like else.
1638
01:13:50,685 --> 01:13:54,670
AUDIENCE: Maybe more than one of them would be evaluated as true.
1639
01:13:54,670 --> 01:13:58,108
DAVID J. MALAN: Yeah, so maybe more than one of them could be evaluated as true--
1640
01:13:58,108 --> 01:13:59,150
not going to happen here.
1641
01:13:59,150 --> 01:14:02,452
But, yes, you could accidentally create a situation where two things
1642
01:14:02,452 --> 01:14:04,660
print or three things print because you didn't really
1643
01:14:04,660 --> 01:14:07,620
think about the boundaries among these questions that you're asking.
1644
01:14:07,620 --> 01:14:10,610
Again, not applicable here but, in general, a good concern.
1645
01:14:10,610 --> 01:14:14,438
AUDIENCE: You're forcing the computer to have a condition that doesn't
1646
01:14:14,438 --> 01:14:15,980
need to be checked if I slow it down.
1647
01:14:15,980 --> 01:14:17,147
DAVID J. MALAN: Really good.
1648
01:14:17,147 --> 01:14:19,130
Really, what's concerning here in this example
1649
01:14:19,130 --> 01:14:21,800
is you're slowing the computer down by wasting its time,
1650
01:14:21,800 --> 01:14:24,210
having it do work that is logically unnecessary,
1651
01:14:24,210 --> 01:14:27,030
even more so than the Scratch in the first C example.
1652
01:14:27,030 --> 01:14:27,530
Why?
1653
01:14:27,530 --> 01:14:31,080
Suppose that I type in 1 for x and 1 for y.
1654
01:14:31,080 --> 01:14:34,070
Because I wrote this code top to bottom, this question
1655
01:14:34,070 --> 01:14:35,627
is going to be asked no matter what.
1656
01:14:35,627 --> 01:14:36,960
The answer is going to be false.
1657
01:14:36,960 --> 01:14:39,150
This question is going to be asked no matter what.
1658
01:14:39,150 --> 01:14:40,260
The answer is going to be false.
1659
01:14:40,260 --> 01:14:41,718
This question is going to be asked.
1660
01:14:41,718 --> 01:14:44,040
And no matter what, the answer is going to be true.
1661
01:14:44,040 --> 01:14:47,730
We're OK there because we had to ask all three questions.
1662
01:14:47,730 --> 01:14:52,260
But suppose I did the first thing, x is 1, y is 2.
1663
01:14:52,260 --> 01:14:56,450
Then this first question is going to be true because x is less than y.
1664
01:14:56,450 --> 01:14:57,270
1 is less than 2.
1665
01:14:57,270 --> 01:14:58,560
So this is going to print.
1666
01:14:58,560 --> 01:15:03,140
And yet, then I'm wasting everyone's time asking, hm, is x greater than y,
1667
01:15:03,140 --> 01:15:04,590
even though it obviously isn't.
1668
01:15:04,590 --> 01:15:05,615
Is x equal to y?
1669
01:15:05,615 --> 01:15:07,980
Hm, it obviously isn't.
1670
01:15:07,980 --> 01:15:11,970
You're doing three times as much work in that particular case.
1671
01:15:11,970 --> 01:15:13,608
It's just not good design.
1672
01:15:13,608 --> 01:15:16,150
And again, for those of you who think a little more visually,
1673
01:15:16,150 --> 01:15:18,910
we can actually make this picture to match.
1674
01:15:18,910 --> 01:15:22,450
Here is a final flowchart for bad code, bad design.
1675
01:15:22,450 --> 01:15:22,950
Why?
1676
01:15:22,950 --> 01:15:25,170
Because no matter what, when you start the program
1677
01:15:25,170 --> 01:15:28,170
and you want to stop the program, you're going through all three
1678
01:15:28,170 --> 01:15:33,000
of those darn questions no matter what, whereas the previous flowcharts got us
1679
01:15:33,000 --> 01:15:37,920
to the Stop bubble faster by taking alternative arrows based
1680
01:15:37,920 --> 01:15:39,580
on true or false answers.
1681
01:15:39,580 --> 01:15:42,670
So in short, still correct but bad design.
1682
01:15:42,670 --> 01:15:46,500
And so again, even for problem set 1, when we start writing C code, consider
1683
01:15:46,500 --> 01:15:48,540
not just getting the job done but how you
1684
01:15:48,540 --> 01:15:53,140
might get the job done better than you might otherwise.
1685
01:15:53,140 --> 01:15:57,310
All right, let's add a few other features into the mix.
1686
01:15:57,310 --> 01:16:00,038
Here we have those same data types that are supported
1687
01:16:00,038 --> 01:16:03,080
by C. Let's focus for a moment on something a little simpler, just chars,
1688
01:16:03,080 --> 01:16:04,220
single characters.
1689
01:16:04,220 --> 01:16:07,390
Unfortunately, for better or for worse, in C, the language makes
1690
01:16:07,390 --> 01:16:11,770
a distinction between strings of text, which are generally words, phrases.
1691
01:16:11,770 --> 01:16:16,518
They can, confusingly, be single characters or even zero characters
1692
01:16:16,518 --> 01:16:18,560
if you don't type anything in between the quotes.
1693
01:16:18,560 --> 01:16:19,970
But more on that another time.
1694
01:16:19,970 --> 01:16:23,710
But when you know from the get go that you only want to get a single character
1695
01:16:23,710 --> 01:16:26,930
back from the user, like "y" for yes, "n" for no, for instance,
1696
01:16:26,930 --> 01:16:31,870
which is super common in programs, you can get that using a char and CS50's own
1697
01:16:31,870 --> 01:16:33,400
function, get_char.
1698
01:16:33,400 --> 01:16:35,090
So how might we use this?
1699
01:16:35,090 --> 01:16:36,740
Well, let's go back to VS Code here.
1700
01:16:36,740 --> 01:16:38,155
I'm going to close compare.c.
1701
01:16:38,155 --> 01:16:40,520
And let's write a third program altogether.
1702
01:16:40,520 --> 01:16:42,595
Let's call this one agree.c.
1703
01:16:42,595 --> 01:16:45,220
And this is meant to represent like terms and conditions, where
1704
01:16:45,220 --> 01:16:48,140
you have to check a box yes or no or something like that.
1705
01:16:48,140 --> 01:16:51,710
In this program, I'm going to go ahead and do the following.
1706
01:16:51,710 --> 01:16:55,970
I'm going to go ahead and, as before, include cs50.h, so we've got it,
1707
01:16:55,970 --> 01:16:59,780
include standard io.h so that we've got it, int main(void)
1708
01:16:59,780 --> 01:17:01,380
because we have to do that for now.
1709
01:17:01,380 --> 01:17:02,707
More on that another time.
1710
01:17:02,707 --> 01:17:04,290
And now let's ask the user a question.
1711
01:17:04,290 --> 01:17:05,340
Do they agree?
1712
01:17:05,340 --> 01:17:10,280
So I'm going to call get_char and then pass in a prompt of, "Do you agree?",
1713
01:17:10,280 --> 01:17:13,050
question mark, with a space, semicolon.
1714
01:17:13,050 --> 01:17:17,820
But as before with get_string and get_int, those functions return a value.
1715
01:17:17,820 --> 01:17:21,480
So I want to assign that value from right to left to a variable,
1716
01:17:21,480 --> 01:17:22,945
which I could call "answer again."
1717
01:17:22,945 --> 01:17:24,820
But honestly, this program is so short, we're
1718
01:17:24,820 --> 01:17:27,480
just going to use the letter c, which is conventional.
1719
01:17:27,480 --> 01:17:31,650
So "c" for char, "i" for int, or "n" for number are very common.
1720
01:17:31,650 --> 01:17:32,580
But one more thing.
1721
01:17:32,580 --> 01:17:35,910
What's still missing for my variable here?
1722
01:17:35,910 --> 01:17:36,530
The type.
1723
01:17:36,530 --> 01:17:41,550
I need to say, this shall be a char, not an int, not a string, a single char.
1724
01:17:41,550 --> 01:17:43,050
All right, now what do I want to do?
1725
01:17:43,050 --> 01:17:44,010
I can ask a question.
1726
01:17:44,010 --> 01:17:50,480
If c equals equals lowercase y, then go ahead and print out,
1727
01:17:50,480 --> 01:17:53,660
just so we see something on the screen, "Agreed" period, backslash n,
1728
01:17:53,660 --> 01:17:55,790
as though they agreed to the terms and conditions.
1729
01:17:55,790 --> 01:18:02,130
Else, if c equals equals lowercase n, go ahead and print out, for instance,
1730
01:18:02,130 --> 01:18:05,400
"Not agreed" just so we see something on the screen.
1731
01:18:05,400 --> 01:18:07,740
So let me hide my terminal window and focus on the code.
1732
01:18:07,740 --> 01:18:10,365
There's a couple of details here that are a little interesting.
1733
01:18:10,365 --> 01:18:14,360
So, one, what did I do on line 7 and 11 that is not
1734
01:18:14,360 --> 01:18:17,940
consistent with what I've done before?
1735
01:18:17,940 --> 01:18:20,700
Subtle.
1736
01:18:20,700 --> 01:18:24,390
So I'm using apostrophes or single quotes now instead of double quotes.
1737
01:18:24,390 --> 01:18:24,890
Why?
1738
01:18:24,890 --> 01:18:25,950
It's a C thing.
1739
01:18:25,950 --> 01:18:28,830
When you're using strings, you use double quotes.
1740
01:18:28,830 --> 01:18:32,340
When you use single chars, you use single quotes.
1741
01:18:32,340 --> 01:18:34,950
So the argument to get char, that's still a string.
1742
01:18:34,950 --> 01:18:36,840
It's a whole sentence that I'm passing in.
1743
01:18:36,840 --> 01:18:39,540
So that is just like get_int, just like get_string.
1744
01:18:39,540 --> 01:18:42,620
But when I get the answer back, the return value,
1745
01:18:42,620 --> 01:18:46,340
and put it in this variable and I want to check, what is that one char,
1746
01:18:46,340 --> 01:18:48,440
I have to surround the char I'm comparing
1747
01:18:48,440 --> 01:18:53,160
against in single quotes or apostrophes, both for the y and for the n.
1748
01:18:53,160 --> 01:18:55,400
So this program is not super well designed
1749
01:18:55,400 --> 01:18:57,450
because it's not going to handle uppercase.
1750
01:18:57,450 --> 01:18:59,460
It's not going to handle weird inputs very well.
1751
01:18:59,460 --> 01:19:01,140
But let me open my terminal window.
1752
01:19:01,140 --> 01:19:03,260
Make agree, Enter.
1753
01:19:03,260 --> 01:19:06,210
The code compiles OK-- "./agree."
1754
01:19:06,210 --> 01:19:06,900
Do I agree?
1755
01:19:06,900 --> 01:19:08,730
Let's try it. y for yes.
1756
01:19:08,730 --> 01:19:10,420
OK, let's try it again--
1757
01:19:10,420 --> 01:19:11,570
"./agree."
1758
01:19:11,570 --> 01:19:12,890
n for no.
1759
01:19:12,890 --> 01:19:13,800
"Not agreed."
1760
01:19:13,800 --> 01:19:14,910
Let's do it one more time.
1761
01:19:14,910 --> 01:19:17,480
Let's very enthusiastically say "YES" in all caps,
1762
01:19:17,480 --> 01:19:21,250
and it just kind of ignores me.
1763
01:19:21,250 --> 01:19:22,270
But why?
1764
01:19:22,270 --> 01:19:25,450
Well, this is a feature of CS50's get_char function.
1765
01:19:25,450 --> 01:19:27,480
If you tell us you want to get a char, we're
1766
01:19:27,480 --> 01:19:30,760
not going to tolerate a whole string of text from the user.
1767
01:19:30,760 --> 01:19:34,230
We're going to prompt them again and again and again until they
1768
01:19:34,230 --> 01:19:35,590
give us just one char.
1769
01:19:35,590 --> 01:19:37,750
So "YES," is three times too long.
1770
01:19:37,750 --> 01:19:41,110
So let's actually just do a single capital Y and see what happens.
1771
01:19:41,110 --> 01:19:42,000
Return.
1772
01:19:42,000 --> 01:19:44,110
The program ignores me altogether.
1773
01:19:44,110 --> 01:19:46,480
So all right, this is kind of a poorly designed program.
1774
01:19:46,480 --> 01:19:48,647
It's a little annoying that we'll just ignore humans
1775
01:19:48,647 --> 01:19:51,760
even if they type in Y or N that just happens to be uppercase.
1776
01:19:51,760 --> 01:19:52,678
So let's improve this.
1777
01:19:52,678 --> 01:19:54,720
Let me go ahead and add a couple more conditions.
1778
01:19:54,720 --> 01:20:01,750
Else if c equals equals uppercase Y, then go ahead and print out "Agreed,"
1779
01:20:01,750 --> 01:20:02,710
same as before.
1780
01:20:02,710 --> 01:20:06,930
And then, down here, else if C equals equals capital N,
1781
01:20:06,930 --> 01:20:10,810
then let's go ahead and print out, again, "Not agreed."
1782
01:20:10,810 --> 01:20:12,960
So this is now more correct.
1783
01:20:12,960 --> 01:20:14,880
It's still going to ignore bogus input that
1784
01:20:14,880 --> 01:20:17,160
makes no sense, if it's just the word--
1785
01:20:17,160 --> 01:20:19,150
if it's a different letter altogether.
1786
01:20:19,150 --> 01:20:24,820
But this, too, code, while correct in some sense, is still poorly designed.
1787
01:20:24,820 --> 01:20:26,730
Even if you've never programmed before, what
1788
01:20:26,730 --> 01:20:31,200
rubs you the wrong way about this code now?
1789
01:20:31,200 --> 01:20:31,900
Be critical.
1790
01:20:31,900 --> 01:20:32,400
Yeah?
1791
01:20:32,400 --> 01:20:36,344
AUDIENCE: [INAUDIBLE] uppercase and lowercase Y's together [INAUDIBLE].
1792
01:20:36,344 --> 01:20:39,310
DAVID J. MALAN: Yeah, it'd be nice to just merge the lowercase
1793
01:20:39,310 --> 01:20:42,580
and the uppercase Y together, the same thing for the lowercase
1794
01:20:42,580 --> 01:20:44,510
and the uppercase N. Why?
1795
01:20:44,510 --> 01:20:48,340
If only because literally lines 9 and 12 are identical.
1796
01:20:48,340 --> 01:20:51,680
Lines 17 and 21 are identical.
1797
01:20:51,680 --> 01:20:55,490
And while not a huge deal, if I go in and I change this sentence,
1798
01:20:55,490 --> 01:20:58,003
odds are, over the course of my lifetime programming,
1799
01:20:58,003 --> 01:21:00,920
I'm going to forget to change this one even though I changed this one.
1800
01:21:00,920 --> 01:21:02,450
Or I'm going to forget to change this one and this one.
1801
01:21:02,450 --> 01:21:05,280
So you don't want the code to get out of sync potentially.
1802
01:21:05,280 --> 01:21:07,280
And you certainly don't want to repeat yourself.
1803
01:21:07,280 --> 01:21:10,460
So "don't repeat yourself" is a tenet of programming, too.
1804
01:21:10,460 --> 01:21:14,390
If you can avoid that by somehow factoring out some commonality,
1805
01:21:14,390 --> 01:21:16,840
you should do so, similar in spirit to math when
1806
01:21:16,840 --> 01:21:18,590
you factor out variables or the like.
1807
01:21:18,590 --> 01:21:20,330
So let me tighten this up, so to speak.
1808
01:21:20,330 --> 01:21:24,830
Let me get rid of what we just did so that it's a little shorter as before.
1809
01:21:24,830 --> 01:21:29,930
And let me express myself with two conditions using the following syntax.
1810
01:21:29,930 --> 01:21:35,890
I want to check if c equals equals lowercase y or c equals equals uppercase
1811
01:21:35,890 --> 01:21:40,980
Y. So you can actually use what's called a logical operator, two vertical bars,
1812
01:21:40,980 --> 01:21:43,550
which means "or."
1813
01:21:43,550 --> 01:21:48,620
And we can do this down here, or c equals equals capital N.
1814
01:21:48,620 --> 01:21:50,820
So same exact functionality.
1815
01:21:50,820 --> 01:21:53,820
But to your point, we've now eliminated, what, like another one--
1816
01:21:53,820 --> 01:21:57,480
it was, like, 1, 4-- it's eight lines of code now are gone,
1817
01:21:57,480 --> 01:22:00,350
which is eight fewer lines that I might screw up in this program.
1818
01:22:00,350 --> 01:22:04,710
Less opportunity for mistakes or bugs, probably a good thing.
1819
01:22:04,710 --> 01:22:07,850
So now, if I run this, let me open my terminal window.
1820
01:22:07,850 --> 01:22:11,060
Let me run make agree, Enter.
1821
01:22:11,060 --> 01:22:13,110
"./agree," Enter.
1822
01:22:13,110 --> 01:22:14,010
Do I agree?
1823
01:22:14,010 --> 01:22:18,180
Capital Y. Now it seems to be handling both of those situations.
1824
01:22:18,180 --> 01:22:19,350
So just a little tighter.
1825
01:22:19,350 --> 01:22:21,240
As an aside-- we won't use it here--
1826
01:22:21,240 --> 01:22:24,590
but if you want to say "and," which would be nonsensical, it,
1827
01:22:24,590 --> 01:22:29,960
a little confusingly, is two ampersands, means a logical "and," whereby the left
1828
01:22:29,960 --> 01:22:32,670
thing has to be true and the right thing has to be true.
1829
01:22:32,670 --> 01:22:34,573
So it's two Boolean expressions at once.
1830
01:22:34,573 --> 01:22:37,490
This one makes no logical sense, though, because a character cannot be
1831
01:22:37,490 --> 01:22:40,050
simultaneously lowercase and uppercase.
1832
01:22:40,050 --> 01:22:41,580
It's got to be one or the other.
1833
01:22:41,580 --> 01:22:43,740
So two vertical bars is logically correct.
1834
01:22:43,740 --> 01:22:48,520
That represents our notion here of "or."
1835
01:22:48,520 --> 01:22:50,730
Question?
1836
01:22:50,730 --> 01:22:52,020
No?
1837
01:22:52,020 --> 01:22:54,084
Yeah.
1838
01:22:54,084 --> 01:22:56,612
AUDIENCE: Would you not be able to write or?
1839
01:22:56,612 --> 01:22:57,570
Does it recognize that?
1840
01:22:57,570 --> 01:22:59,278
DAVID J. MALAN: You could not write "or."
1841
01:22:59,278 --> 01:23:01,810
So I'm saying "or" just because that's a little more normal.
1842
01:23:01,810 --> 01:23:03,100
But this is incorrect.
1843
01:23:03,100 --> 01:23:05,555
However-- sneak preview-- in the language of Python,
1844
01:23:05,555 --> 01:23:07,930
you actually will literally say "or," among other things,
1845
01:23:07,930 --> 01:23:10,290
which gets a little more user friendly.
1846
01:23:10,290 --> 01:23:12,515
Other questions on this here?
1847
01:23:12,515 --> 01:23:15,600
1848
01:23:15,600 --> 01:23:16,290
Searching.
1849
01:23:16,290 --> 01:23:17,030
Yes, in back.
1850
01:23:17,030 --> 01:23:18,572
AUDIENCE: Is there an easier way to--
1851
01:23:18,572 --> 01:23:21,405
DAVID J. MALAN: Is there an easier way to handle a case sensitivity?
1852
01:23:21,405 --> 01:23:23,490
Yes, and we'll show you that next week, in fact.
1853
01:23:23,490 --> 01:23:26,150
So we can combine this code to be even tighter.
1854
01:23:26,150 --> 01:23:29,850
All right, let's do one final set of examples before taking a cookie break,
1855
01:23:29,850 --> 01:23:30,450
if we could.
1856
01:23:30,450 --> 01:23:33,078
But let's go ahead and close agree.c here.
1857
01:23:33,078 --> 01:23:34,370
Let me open my terminal window.
1858
01:23:34,370 --> 01:23:38,850
And let's go ahead and implement a virtual cat as we did last week.
1859
01:23:38,850 --> 01:23:40,687
I'm going to code up a file called cat.c.
1860
01:23:40,687 --> 01:23:43,770
And I'm going to implement this in a few different ways, the first of them
1861
01:23:43,770 --> 01:23:44,430
pretty foolish.
1862
01:23:44,430 --> 01:23:47,090
So here, I'm going to include standard io.h.
1863
01:23:47,090 --> 01:23:48,980
No need for CS50 dot yet--
1864
01:23:48,980 --> 01:23:49,920
just yet.
1865
01:23:49,920 --> 01:23:51,590
int main(void).
1866
01:23:51,590 --> 01:23:55,190
Inside of these curly braces, let's go ahead and do printf "meow"
1867
01:23:55,190 --> 01:23:56,600
to get the cat to meow.
1868
01:23:56,600 --> 01:23:59,940
And then, to save time, I'm going to copy/paste that two more times.
1869
01:23:59,940 --> 01:24:02,970
So this cat shall meow three times in total.
1870
01:24:02,970 --> 01:24:06,000
All right, I'm going to go ahead and make the cat, so to speak.
1871
01:24:06,000 --> 01:24:08,190
All good. "./cat," Enter.
1872
01:24:08,190 --> 01:24:12,120
And it meows three times, just like our Scratch cat last time.
1873
01:24:12,120 --> 01:24:13,590
I'll stipulate, this is correct.
1874
01:24:13,590 --> 01:24:16,620
This is a really well implemented cat correctness-wise.
1875
01:24:16,620 --> 01:24:21,430
But why is it bad design intuitively, just like last week?
1876
01:24:21,430 --> 01:24:22,845
AUDIENCE: [INAUDIBLE] [? out. ?]
1877
01:24:22,845 --> 01:24:23,762
DAVID J. MALAN: Sorry?
1878
01:24:23,762 --> 01:24:25,210
AUDIENCE: Repeating the code.
1879
01:24:25,210 --> 01:24:25,490
DAVID J. MALAN: Sorry.
1880
01:24:25,490 --> 01:24:26,740
AUDIENCE: You keep repeating the code.
1881
01:24:26,740 --> 01:24:28,490
DAVID J. MALAN: I keep repeating the code.
1882
01:24:28,490 --> 01:24:31,640
I mean, I literally copied and pasted, which is your first obvious sign.
1883
01:24:31,640 --> 01:24:34,182
I'm probably doing something wrong if I'm copying and pasting
1884
01:24:34,182 --> 01:24:35,900
because I'm literally repeating myself.
1885
01:24:35,900 --> 01:24:39,440
So to spoil it, odds are a loop is probably going to be our friend here.
1886
01:24:39,440 --> 01:24:43,970
And so, in fact, in C, we have those features as well.
1887
01:24:43,970 --> 01:24:47,320
So in the world of C, we can implement some of last week's same ideas
1888
01:24:47,320 --> 01:24:48,542
in a few different ways.
1889
01:24:48,542 --> 01:24:50,000
These are a little more mechanical.
1890
01:24:50,000 --> 01:24:52,970
But suppose we want to repeat something literally three times.
1891
01:24:52,970 --> 01:24:56,607
Scratch gives us a repeat, a block with an input-- so easy.
1892
01:24:56,607 --> 01:24:59,440
C and a lot of languages, it's going to be a little more mechanical.
1893
01:24:59,440 --> 01:25:00,770
And it's going to look ugly at first.
1894
01:25:00,770 --> 01:25:02,187
It will take some getting used to.
1895
01:25:02,187 --> 01:25:05,330
But it is a paradigm you will use again and again and again.
1896
01:25:05,330 --> 01:25:09,050
This will become very rote memory before long.
1897
01:25:09,050 --> 01:25:12,525
Well, the most direct translation of this Scratch code to C
1898
01:25:12,525 --> 01:25:14,650
is probably something that looks a little something
1899
01:25:14,650 --> 01:25:16,900
like this, whereby I initialize a variable,
1900
01:25:16,900 --> 01:25:19,490
here called i, and set it equal to 3.
1901
01:25:19,490 --> 01:25:22,340
That's the code equivalent in C of putting up three fingers.
1902
01:25:22,340 --> 01:25:27,000
Then what I want to do is, while i is greater than 0,
1903
01:25:27,000 --> 01:25:30,390
that is to say while I have at least one finger up,
1904
01:25:30,390 --> 01:25:32,130
go ahead and do the following.
1905
01:25:32,130 --> 01:25:35,580
And then once I've done that, for instance say "meow" on the screen,
1906
01:25:35,580 --> 01:25:39,660
I want to go ahead and decrement i and then do this whole thing again.
1907
01:25:39,660 --> 01:25:43,192
Now, I could have called this variable "counter," for consistency with earlier.
1908
01:25:43,192 --> 01:25:46,400
But it turns out it's conventional when you've only got one variable involved
1909
01:25:46,400 --> 01:25:49,380
in your code and all it's doing is something simple like counting,
1910
01:25:49,380 --> 01:25:52,410
you can go ahead and call the variable i for integer, for instance.
1911
01:25:52,410 --> 01:25:55,440
But it would not be wrong to instead call i "counter."
1912
01:25:55,440 --> 01:26:00,120
But notice, too, that in this so-called while loop, as we'll start to call it,
1913
01:26:00,120 --> 01:26:01,440
there is this parenthetical.
1914
01:26:01,440 --> 01:26:04,440
And that parenthetical is actually itself a Boolean expression.
1915
01:26:04,440 --> 01:26:08,300
But unlike an if statement, whereby the Boolean expression is evaluated
1916
01:26:08,300 --> 01:26:12,480
just once and if the answer is true, or yes, you do that thing,
1917
01:26:12,480 --> 01:26:16,940
the Boolean expression in a while loop here in C is evaluated again
1918
01:26:16,940 --> 01:26:21,530
and again and again every time you go through the loop
1919
01:26:21,530 --> 01:26:24,120
to check if you should keep going through the loop.
1920
01:26:24,120 --> 01:26:27,870
So for instance, if the goal at hand is to say "meow," well, of course,
1921
01:26:27,870 --> 01:26:30,170
the comparable C function is going to be printf.
1922
01:26:30,170 --> 01:26:33,570
And I want to print out on the screen "meow," followed by a new line.
1923
01:26:33,570 --> 01:26:34,610
Well, what's going on?
1924
01:26:34,610 --> 01:26:36,860
Well, again, I initialize i to 3.
1925
01:26:36,860 --> 01:26:38,897
I then check, is i greater than 0?
1926
01:26:38,897 --> 01:26:42,230
And of course it is because effectively, in the computer's memory, three fingers
1927
01:26:42,230 --> 01:26:42,810
are up.
1928
01:26:42,810 --> 01:26:44,460
I go ahead and print out "meow."
1929
01:26:44,460 --> 01:26:48,020
I decrement i, which means to put down one of those fingers.
1930
01:26:48,020 --> 01:26:50,540
And then I check the Boolean expression again.
1931
01:26:50,540 --> 01:26:52,170
Is 2 greater than 0?
1932
01:26:52,170 --> 01:26:52,860
Of course it is.
1933
01:26:52,860 --> 01:26:53,910
So I print out "meow."
1934
01:26:53,910 --> 01:26:56,993
And then I decrement i, putting down one more finger.
1935
01:26:56,993 --> 01:26:58,410
Then I check the expression again.
1936
01:26:58,410 --> 01:26:59,820
Is 1 greater than 0?
1937
01:26:59,820 --> 01:27:00,690
Of course it is.
1938
01:27:00,690 --> 01:27:01,700
I print out "meow."
1939
01:27:01,700 --> 01:27:02,990
And then I decrement i.
1940
01:27:02,990 --> 01:27:04,410
And now I'm down to 0.
1941
01:27:04,410 --> 01:27:05,360
I check again.
1942
01:27:05,360 --> 01:27:07,320
Is 0 greater than 0?
1943
01:27:07,320 --> 01:27:08,340
Well, no.
1944
01:27:08,340 --> 01:27:12,360
And so the loop will automatically, by the definition of how this C code works,
1945
01:27:12,360 --> 01:27:14,750
terminate for me and proceed to any other lines
1946
01:27:14,750 --> 01:27:17,280
if there are more lines of code that I've written.
1947
01:27:17,280 --> 01:27:20,698
So how do we actually implement this then in code and get it running?
1948
01:27:20,698 --> 01:27:22,740
Well, it's going to be pretty much the same idea.
1949
01:27:22,740 --> 01:27:24,522
Let me go back to VS Code here.
1950
01:27:24,522 --> 01:27:26,480
I'm going to get rid of all of this copy/paste.
1951
01:27:26,480 --> 01:27:29,900
And inside of my main function, I'm going to do exactly what we saw--
1952
01:27:29,900 --> 01:27:35,760
int i equals 3, semicolon. while i is greater than 0,
1953
01:27:35,760 --> 01:27:40,370
then go ahead and print out with printf "meow" backslash n.
1954
01:27:40,370 --> 01:27:42,710
And then be sure you decrement i.
1955
01:27:42,710 --> 01:27:45,620
And notice that lines 8 and 9 are not only indented, they
1956
01:27:45,620 --> 01:27:48,390
are inside of that while loop, so to speak,
1957
01:27:48,390 --> 01:27:51,380
which means they will both happen again and again
1958
01:27:51,380 --> 01:27:56,330
and again because what's happening in code here is those curly braces
1959
01:27:56,330 --> 01:28:00,380
are kind of like the yellow pieces that are hugging the other puzzle
1960
01:28:00,380 --> 01:28:01,500
pieces in Scratch.
1961
01:28:01,500 --> 01:28:03,810
It will keep doing this, this, this.
1962
01:28:03,810 --> 01:28:07,110
But every time, through that loop or cycle,
1963
01:28:07,110 --> 01:28:11,150
this Boolean expression will be checked again and again and again
1964
01:28:11,150 --> 01:28:13,740
until the answer is false, at which point
1965
01:28:13,740 --> 01:28:16,170
the computer is going to jump to the last line.
1966
01:28:16,170 --> 01:28:19,880
And if there's nothing left, that's it for the program, no more to be done.
1967
01:28:19,880 --> 01:28:24,150
So same exact idea in Scratch, even though it's a little more mechanical.
1968
01:28:24,150 --> 01:28:26,640
So that's how we might implement this.
1969
01:28:26,640 --> 01:28:30,535
And you can think of it, these variables-- this is perhaps
1970
01:28:30,535 --> 01:28:32,160
a little gratuitous, but let's do this.
1971
01:28:32,160 --> 01:28:36,470
So if you have a variable inside of a computer's memory--
1972
01:28:36,470 --> 01:28:39,870
and that's a detail we'll get to in more detail before long--
1973
01:28:39,870 --> 01:28:42,900
you can really think of it just as like a container that stores value.
1974
01:28:42,900 --> 01:28:44,622
So for instance, this clear plastic bowl,
1975
01:28:44,622 --> 01:28:46,080
it can be thought of as a variable.
1976
01:28:46,080 --> 01:28:47,190
It just stores values.
1977
01:28:47,190 --> 01:28:49,607
And right now, there's obviously three stress balls in it.
1978
01:28:49,607 --> 01:28:51,750
So it represents the number 3.
1979
01:28:51,750 --> 01:28:53,810
So what's really happening in code like this
1980
01:28:53,810 --> 01:28:57,360
is we've initialized i to 3, which is this bowl.
1981
01:28:57,360 --> 01:28:59,840
We're then checking the question on line 6.
1982
01:28:59,840 --> 01:29:01,340
Is i greater than 0?
1983
01:29:01,340 --> 01:29:02,370
Obviously.
1984
01:29:02,370 --> 01:29:04,380
So we proceed inside of the curly braces.
1985
01:29:04,380 --> 01:29:05,820
And we print out "meow."
1986
01:29:05,820 --> 01:29:07,310
We then decrement i.
1987
01:29:07,310 --> 01:29:11,370
So for the sake of unnecessary drama, that's decrementing the variable.
1988
01:29:11,370 --> 01:29:15,540
So what's being stored in this container now is one less.
1989
01:29:15,540 --> 01:29:17,190
We do it again, check the count.
1990
01:29:17,190 --> 01:29:18,450
Nope, 2 is greater than 0.
1991
01:29:18,450 --> 01:29:19,670
So we keep going-- "meow."
1992
01:29:19,670 --> 01:29:20,870
Decrement i.
1993
01:29:20,870 --> 01:29:21,980
Check the variable.
1994
01:29:21,980 --> 01:29:24,470
1 is greater than 0, so we print "meow."
1995
01:29:24,470 --> 01:29:25,370
Decrement i.
1996
01:29:25,370 --> 01:29:27,420
We check the condition again.
1997
01:29:27,420 --> 01:29:32,070
i is not greater than 0 because 0 is not greater than 0.
1998
01:29:32,070 --> 01:29:33,977
And so the rest of the code stops executing.
1999
01:29:33,977 --> 01:29:36,810
I'm not sure if that was any more effective than fingers on my hand.
2000
01:29:36,810 --> 01:29:37,530
But we had the bowl.
2001
01:29:37,530 --> 01:29:38,238
We had the balls.
2002
01:29:38,238 --> 01:29:39,627
So same exact idea.
2003
01:29:39,627 --> 01:29:41,210
Variables are just storing some value.
2004
01:29:41,210 --> 01:29:44,240
And incrementing and decrementing would just be adding or subtracting
2005
01:29:44,240 --> 01:29:45,583
stress balls in this case.
2006
01:29:45,583 --> 01:29:47,250
But there's other ways we could do this.
2007
01:29:47,250 --> 01:29:49,350
In fact, let me zoom in on my code here.
2008
01:29:49,350 --> 01:29:51,950
And it's not really conventional in programming
2009
01:29:51,950 --> 01:29:55,370
to count down-- nothing wrong with it, it's just not really a thing.
2010
01:29:55,370 --> 01:29:57,000
We would typically count up.
2011
01:29:57,000 --> 01:29:59,240
So we could alternatively do this--
2012
01:29:59,240 --> 01:30:01,860
set i equal to 1 initially.
2013
01:30:01,860 --> 01:30:04,520
So we count 1, 2, 3, like a normal person.
2014
01:30:04,520 --> 01:30:06,600
And we can change our condition.
2015
01:30:06,600 --> 01:30:11,810
If I'm going to count from 1 to 3, what should my comparison
2016
01:30:11,810 --> 01:30:15,770
be in my Boolean expression here?
2017
01:30:15,770 --> 01:30:18,820
i is less than 3?
2018
01:30:18,820 --> 01:30:21,770
Less than or equal to 3, I think.
2019
01:30:21,770 --> 01:30:26,740
So if i is initialized to 1, we're going to go through this one time, two times,
2020
01:30:26,740 --> 01:30:27,850
three times.
2021
01:30:27,850 --> 01:30:29,870
i is going to eventually get incremented to 4.
2022
01:30:29,870 --> 01:30:33,200
But at that point, 4 is not less than or equal to 3.
2023
01:30:33,200 --> 01:30:35,660
So it's only going to execute a total of three times.
2024
01:30:35,660 --> 01:30:36,890
But there's still a bug in this code.
2025
01:30:36,890 --> 01:30:38,223
What other line needs to change?
2026
01:30:38,223 --> 01:30:39,270
AUDIENCE: Plus plus.
2027
01:30:39,270 --> 01:30:42,580
DAVID J. MALAN: Yeah, so line 9 needs to become plus plus.
2028
01:30:42,580 --> 01:30:44,950
So this code is just as correct.
2029
01:30:44,950 --> 01:30:47,440
And honestly, you could-- reasonable people will disagree.
2030
01:30:47,440 --> 01:30:49,570
Your TF might say do it this way and not this way.
2031
01:30:49,570 --> 01:30:51,220
But this is still correct.
2032
01:30:51,220 --> 01:30:52,870
But it's not the most conventional way.
2033
01:30:52,870 --> 01:30:56,070
As per last week, computer scientists and programmers generally,
2034
01:30:56,070 --> 01:30:59,920
actually, start counting from 0 by convention for reasons we'll soon see.
2035
01:30:59,920 --> 01:31:03,210
So the better way, the more conventional way arguably,
2036
01:31:03,210 --> 01:31:05,610
would be always start counting from 0.
2037
01:31:05,610 --> 01:31:09,370
Count up to but not through the number you care about.
2038
01:31:09,370 --> 01:31:13,720
And so this form of the code is probably the most popular way to do it.
2039
01:31:13,720 --> 01:31:19,630
Start at 0, count up to 3 but not through 3, as with less than or equals
2040
01:31:19,630 --> 01:31:20,130
than.
2041
01:31:20,130 --> 01:31:21,580
All three are correct.
2042
01:31:21,580 --> 01:31:23,822
Can't really do counting up as easily with the bowl
2043
01:31:23,822 --> 01:31:25,030
without picking up the balls.
2044
01:31:25,030 --> 01:31:26,650
But the exact same logic applies.
2045
01:31:26,650 --> 01:31:30,510
And in fact, this version of the code is so commonly
2046
01:31:30,510 --> 01:31:35,220
done that there's a different way to implement it all-- there's a similar way
2047
01:31:35,220 --> 01:31:36,790
to implement it all together.
2048
01:31:36,790 --> 01:31:38,560
In fact, this code here--
2049
01:31:38,560 --> 01:31:40,990
same exact thing, repeating three times--
2050
01:31:40,990 --> 01:31:44,230
because it's so commonly done that you want to initialize something to 0
2051
01:31:44,230 --> 01:31:46,720
and keep doing something until the value 3,
2052
01:31:46,720 --> 01:31:50,360
you can actually use a different preposition, for,
2053
01:31:50,360 --> 01:31:54,140
which is another keyword in C. And it looks a little more cryptic.
2054
01:31:54,140 --> 01:31:55,880
But it just tightens things up.
2055
01:31:55,880 --> 01:31:58,160
This is what's called a for loop.
2056
01:31:58,160 --> 01:32:00,320
Previous is what's called a while loop.
2057
01:32:00,320 --> 01:32:02,560
And honestly, even though it, probably to the newbie,
2058
01:32:02,560 --> 01:32:05,110
still looks just as cryptic, it's just a little tighter
2059
01:32:05,110 --> 01:32:08,480
because you're expressing all of these ideas on one line.
2060
01:32:08,480 --> 01:32:12,650
You specify the variable you want to create and initialize.
2061
01:32:12,650 --> 01:32:16,130
You specify the Boolean expression you want to check again and again.
2062
01:32:16,130 --> 01:32:19,310
You specify what increment or decrements you want to happen.
2063
01:32:19,310 --> 01:32:23,720
And confusingly, you do use semicolons here, not commas.
2064
01:32:23,720 --> 01:32:26,017
You do not put a semicolon here.
2065
01:32:26,017 --> 01:32:28,100
You, of course, don't put them after these things.
2066
01:32:28,100 --> 01:32:31,010
You generally only put them after functions thus far.
2067
01:32:31,010 --> 01:32:33,403
So we do have one semicolon here.
2068
01:32:33,403 --> 01:32:35,570
But in short, this you'll get more comfortable with.
2069
01:32:35,570 --> 01:32:38,180
This is how I, for instance, almost always write a loop.
2070
01:32:38,180 --> 01:32:41,185
But it's doing the exact same thing mechanically as this, same thing
2071
01:32:41,185 --> 01:32:44,060
as counting on your fingers, same thing as counting the stress balls.
2072
01:32:44,060 --> 01:32:48,560
There's just different ways to express the exact same idea.
2073
01:32:48,560 --> 01:32:50,253
But there are ways to screw up.
2074
01:32:50,253 --> 01:32:51,920
So in fact, let me go ahead and do this.
2075
01:32:51,920 --> 01:32:53,170
Suppose that the cat--
2076
01:32:53,170 --> 01:32:55,172
we'd like the cat to live as long as possible.
2077
01:32:55,172 --> 01:32:57,130
And we don't want it to stop meowing after just
2078
01:32:57,130 --> 01:32:59,000
three or a finite number of times.
2079
01:32:59,000 --> 01:33:02,600
How can you do something forever, again and again and again?
2080
01:33:02,600 --> 01:33:05,060
Well, let me go back into VS Code here.
2081
01:33:05,060 --> 01:33:07,390
Let me delete all of the code from earlier.
2082
01:33:07,390 --> 01:33:10,760
And let me go ahead and say, while something is true--
2083
01:33:10,760 --> 01:33:11,780
I'll come back to that--
2084
01:33:11,780 --> 01:33:17,240
let's just go ahead and print out "meow" backslash n ideally forever.
2085
01:33:17,240 --> 01:33:18,770
But what do I want to put in here?
2086
01:33:18,770 --> 01:33:21,978
Well, if I want to do something forever, I could do something kind of stupid,
2087
01:33:21,978 --> 01:33:24,860
like while 1 is less than 2, which is always going to be the case,
2088
01:33:24,860 --> 01:33:27,830
or while 50 is less than 51, which is always going to be--
2089
01:33:27,830 --> 01:33:29,720
I could just ask an arbitrary question.
2090
01:33:29,720 --> 01:33:31,670
But arbitrary-- not good in general.
2091
01:33:31,670 --> 01:33:33,710
You should have meaning behind your code.
2092
01:33:33,710 --> 01:33:38,360
So if you want the expression to be true all of the time, just say "while true,"
2093
01:33:38,360 --> 01:33:40,370
because true is not changing anytime soon.
2094
01:33:40,370 --> 01:33:42,770
If it's literally true, it's always going to be true.
2095
01:33:42,770 --> 01:33:44,690
The only caveat is to use this trick.
2096
01:33:44,690 --> 01:33:48,970
For now, you will need to include the CS50 library, which for today's purposes
2097
01:33:48,970 --> 01:33:50,990
makes that possible.
2098
01:33:50,990 --> 01:33:53,000
But there's a problem, of course.
2099
01:33:53,000 --> 01:33:58,390
If the cat's going to live forever, if I do make cat, "./cat," Enter,
2100
01:33:58,390 --> 01:34:01,090
you can very quickly lose control over your terminal window.
2101
01:34:01,090 --> 01:34:03,573
And you can see the meows are flying across the screen,
2102
01:34:03,573 --> 01:34:05,740
at least based on the bottom from what we're seeing.
2103
01:34:05,740 --> 01:34:07,390
This cat will never stop meowing.
2104
01:34:07,390 --> 01:34:10,180
And this is either a feature or a bug, so
2105
01:34:10,180 --> 01:34:13,280
to speak, depending on how long the cat here should live virtually.
2106
01:34:13,280 --> 01:34:18,820
But how do you terminate a program that is out of control like this, infinitely?
2107
01:34:18,820 --> 01:34:22,870
So one of the takeaways for today is Control-C is your friend
2108
01:34:22,870 --> 01:34:25,040
for cancel or interrupt the program.
2109
01:34:25,040 --> 01:34:27,400
If you ever lose control over a program because you've
2110
01:34:27,400 --> 01:34:30,042
got intentionally or unintentionally an infinite loop,
2111
01:34:30,042 --> 01:34:31,750
you can go into your terminal window, hit
2112
01:34:31,750 --> 01:34:35,270
Control-C, sometimes multiple times if it's ignoring you.
2113
01:34:35,270 --> 01:34:38,980
And that will break out of the program and just essentially force-quit it,
2114
01:34:38,980 --> 01:34:41,300
like in Macs or PCs.
2115
01:34:41,300 --> 01:34:43,940
But let's make one improvement here still.
2116
01:34:43,940 --> 01:34:46,360
The last thing we did with our cat in Scratch
2117
01:34:46,360 --> 01:34:48,340
before now-- we'll take a break in a moment--
2118
01:34:48,340 --> 01:34:50,410
was we defined our own functions.
2119
01:34:50,410 --> 01:34:52,360
And recall that we did that to abstract away
2120
01:34:52,360 --> 01:34:55,820
the idea of meowing because Scratch didn't come with a meow puzzle piece.
2121
01:34:55,820 --> 01:34:58,833
C definitely does not come with a meow function.
2122
01:34:58,833 --> 01:35:00,250
We have to implement it ourselves.
2123
01:35:00,250 --> 01:35:02,230
So quickly, toward the end of week 0, we did
2124
01:35:02,230 --> 01:35:05,960
this-- define a function called meow that just plays the meow sound.
2125
01:35:05,960 --> 01:35:08,710
And now we have a meow puzzle piece we can use and reuse.
2126
01:35:08,710 --> 01:35:11,128
In C, we're about to do this.
2127
01:35:11,128 --> 01:35:12,920
And this is going to look a little cryptic.
2128
01:35:12,920 --> 01:35:16,253
But it's going to lay the foundation for future weeks when we do this even more.
2129
01:35:16,253 --> 01:35:19,280
I've got a meow function, weird mentions of void.
2130
01:35:19,280 --> 01:35:22,340
That just means there's no input and there's no output for this function.
2131
01:35:22,340 --> 01:35:23,980
It just does one thing simply.
2132
01:35:23,980 --> 01:35:26,440
And that one thing is printf, "meow."
2133
01:35:26,440 --> 01:35:28,540
So how do I use this here code?
2134
01:35:28,540 --> 01:35:30,610
Here, in Scratch, is how we used it last week.
2135
01:35:30,610 --> 01:35:34,840
When the green flag is clicked, repeat three times the meow function.
2136
01:35:34,840 --> 01:35:38,310
In C, it's going to look like this-- int main(void) and all of that.
2137
01:35:38,310 --> 01:35:39,970
And I can use a for loop, a while loop.
2138
01:35:39,970 --> 01:35:42,420
I'm copying and pasting for loop version of the code.
2139
01:35:42,420 --> 01:35:43,960
Set i equal to 0.
2140
01:35:43,960 --> 01:35:45,870
Make sure it stays below 3.
2141
01:35:45,870 --> 01:35:48,660
Increment it on each iteration, or cycle.
2142
01:35:48,660 --> 01:35:50,260
And just call meow.
2143
01:35:50,260 --> 01:35:52,830
So what's nice here is that we have, fairly
2144
01:35:52,830 --> 01:35:55,050
simply, a way in C to create our own functions
2145
01:35:55,050 --> 01:35:58,140
called meow or anything else that lines up perfectly
2146
01:35:58,140 --> 01:35:59,540
with what we did in Scratch.
2147
01:35:59,540 --> 01:36:02,290
We'll take some time to get comfy with the syntax and remember it,
2148
01:36:02,290 --> 01:36:04,150
have to look it up frequently for reference.
2149
01:36:04,150 --> 01:36:06,070
But let's go ahead and actually do this.
2150
01:36:06,070 --> 01:36:09,060
If I go back to VS Code, clear my screen--
2151
01:36:09,060 --> 01:36:11,170
let me hide my terminal window temporarily.
2152
01:36:11,170 --> 01:36:14,400
Let me go ahead and invent this meow function.
2153
01:36:14,400 --> 01:36:18,870
Per the code earlier, I'm going to go ahead and do this--
2154
01:36:18,870 --> 01:36:22,200
void meow(void).
2155
01:36:22,200 --> 01:36:24,710
And again, the two voids mean no input, no output.
2156
01:36:24,710 --> 01:36:26,970
It just does one thing well.
2157
01:36:26,970 --> 01:36:31,170
printf, quote, unquote, "meow" backslash n.
2158
01:36:31,170 --> 01:36:33,790
And now, down here, I can use a for loop.
2159
01:36:33,790 --> 01:36:37,920
So for-- and I know this from memory-- int i equals 0; i less than 3;
2160
01:36:37,920 --> 01:36:38,800
i plus plus.
2161
01:36:38,800 --> 01:36:40,740
And then, inside of curly braces, I'm going
2162
01:36:40,740 --> 01:36:42,860
to go ahead and call the meow function.
2163
01:36:42,860 --> 01:36:46,080
Notice, when I'm creating the function up here,
2164
01:36:46,080 --> 01:36:50,170
I explicitly, pedantically, say void void, no input, no output.
2165
01:36:50,170 --> 01:36:53,760
When I use the function on line 13, you just
2166
01:36:53,760 --> 01:36:55,545
say open parentheses, close parentheses.
2167
01:36:55,545 --> 01:36:58,420
That's the equivalent of a Scratch puzzle piece without a white oval.
2168
01:36:58,420 --> 01:36:59,590
You just put nothing there.
2169
01:36:59,590 --> 01:37:01,550
You don't put the word "void."
2170
01:37:01,550 --> 01:37:02,830
So that's it.
2171
01:37:02,830 --> 01:37:04,470
Let me open my terminal window.
2172
01:37:04,470 --> 01:37:08,640
Let me run make cat to recompile-- "./cat."
2173
01:37:08,640 --> 01:37:11,380
And I think I have a working cat.
2174
01:37:11,380 --> 01:37:12,610
Now, this is correct.
2175
01:37:12,610 --> 01:37:16,000
The only thing I don't love about this version, if I hide my terminal window,
2176
01:37:16,000 --> 01:37:18,910
is that when I start writing bigger and bigger programs,
2177
01:37:18,910 --> 01:37:24,610
it'd be nice if my main function, which I told you to take on faith for today,
2178
01:37:24,610 --> 01:37:27,930
is at the top of the file, if only because literally the name "main"
2179
01:37:27,930 --> 01:37:29,680
means this is the main part of my program.
2180
01:37:29,680 --> 01:37:32,710
It'd be nice if it's the first thing I see, which is to say,
2181
01:37:32,710 --> 01:37:35,370
just to be pedantic, it's very common to put
2182
01:37:35,370 --> 01:37:38,650
any functions you write at the bottom of your file,
2183
01:37:38,650 --> 01:37:41,170
maybe alphabetically, maybe organized some other way.
2184
01:37:41,170 --> 01:37:44,690
But you put main first by convention, just like the "when the green flag
2185
01:37:44,690 --> 01:37:45,190
clicked."
2186
01:37:45,190 --> 01:37:47,565
It was the first thing you always started with last week.
2187
01:37:47,565 --> 01:37:49,090
But watch what happens now.
2188
01:37:49,090 --> 01:37:50,760
If I go into my terminal window--
2189
01:37:50,760 --> 01:37:54,580
and Command-- or Control-J is hiding and showing it, if you are curious.
2190
01:37:54,580 --> 01:37:57,430
But probably, you'll just leave it open on your own all the time.
2191
01:37:57,430 --> 01:37:59,410
Let me do make cat again.
2192
01:37:59,410 --> 01:38:01,430
And, huh, I've screwed up somehow.
2193
01:38:01,430 --> 01:38:05,180
All I did was move the meow function from top to bottom.
2194
01:38:05,180 --> 01:38:08,840
And I'm getting "call to undeclared function 'meow,'" something, something,
2195
01:38:08,840 --> 01:38:09,630
something.
2196
01:38:09,630 --> 01:38:11,140
Well, what's going on?
2197
01:38:11,140 --> 01:38:13,175
Well, C is pretty naive and simplistic.
2198
01:38:13,175 --> 01:38:15,050
It's only going to do what you tell it to do.
2199
01:38:15,050 --> 01:38:17,810
And it's only going to do things top to bottom, left to right.
2200
01:38:17,810 --> 01:38:22,640
And unfortunately, on line 8, you are telling C, call a function called meow.
2201
01:38:22,640 --> 01:38:25,240
But that does not exist in CS50's header file.
2202
01:38:25,240 --> 01:38:27,387
That does not exist in standard io's header file.
2203
01:38:27,387 --> 01:38:29,470
It exists at the bottom of my file, at which point
2204
01:38:29,470 --> 01:38:32,900
it's too late because I'm trying to use it before it exists.
2205
01:38:32,900 --> 01:38:36,822
So I could just undo that and put this meow function at the top of the file.
2206
01:38:36,822 --> 01:38:39,280
But you're going to eventually get into a perverse scenario
2207
01:38:39,280 --> 01:38:42,290
where you can't put all of your functions above all of your functions.
2208
01:38:42,290 --> 01:38:44,420
You've got to pick a lane at some point.
2209
01:38:44,420 --> 01:38:47,650
So the solution to this, albeit a little weird-- and the one
2210
01:38:47,650 --> 01:38:54,070
time in CS50, in programming, that it is encouraged and necessary to copy/paste--
2211
01:38:54,070 --> 01:38:58,880
is what you can do at the top of your code, above main, is just copy/paste
2212
01:38:58,880 --> 01:39:02,070
the first line of your own function.
2213
01:39:02,070 --> 01:39:04,580
This is the so-called prototype of the function.
2214
01:39:04,580 --> 01:39:07,740
And it simply describes how to use the function.
2215
01:39:07,740 --> 01:39:10,170
And funny enough, we actually saw this earlier.
2216
01:39:10,170 --> 01:39:14,720
But I kind of swept it under the rug.
2217
01:39:14,720 --> 01:39:19,190
A moment ago, or a bit ago, when we looked at standard io.h
2218
01:39:19,190 --> 01:39:22,350
and we looked at the printf function in the manual pages,
2219
01:39:22,350 --> 01:39:24,270
I highlighted the header file.
2220
01:39:24,270 --> 01:39:27,450
But I also glossed over the so-called prototype,
2221
01:39:27,450 --> 01:39:31,110
which is-- sorry-- the first line of the printf function,
2222
01:39:31,110 --> 01:39:33,900
just as this is the first line of my meow function.
2223
01:39:33,900 --> 01:39:35,160
This is like a little clue.
2224
01:39:35,160 --> 01:39:37,580
This is like saying to C, hey, there's going
2225
01:39:37,580 --> 01:39:40,800
to be a function called meow that takes no input, has no input--
2226
01:39:40,800 --> 01:39:42,930
takes no input, has no output.
2227
01:39:42,930 --> 01:39:45,480
Just know that it exists eventually.
2228
01:39:45,480 --> 01:39:49,400
And that will satisfy the compiler because if I go back to my terminal,
2229
01:39:49,400 --> 01:39:53,270
rerun make cat, it now knows on faith, per line 4,
2230
01:39:53,270 --> 01:39:55,470
this function will eventually exist.
2231
01:39:55,470 --> 01:39:57,680
And indeed, once it gets to the bottom of my code,
2232
01:39:57,680 --> 01:40:00,270
line 14 onward, there it, in fact, is.
2233
01:40:00,270 --> 01:40:04,130
So you just copy the one-and-only first line of your function's code
2234
01:40:04,130 --> 01:40:05,760
to the top, called a prototype.
2235
01:40:05,760 --> 01:40:10,220
And now if I do "./cat," I get, finally, "meow," "meow," "meow"
2236
01:40:10,220 --> 01:40:14,110
yet again in this case.
2237
01:40:14,110 --> 01:40:16,620
Questions on these here cats?
2238
01:40:16,620 --> 01:40:19,980
2239
01:40:19,980 --> 01:40:20,530
No?
2240
01:40:20,530 --> 01:40:23,160
All right, then the last flourish before--
2241
01:40:23,160 --> 01:40:24,220
I keep promising cookies.
2242
01:40:24,220 --> 01:40:25,360
And I promise they exist.
2243
01:40:25,360 --> 01:40:28,300
So last flourish-- just as we did in Scratch--
2244
01:40:28,300 --> 01:40:32,010
so in Scratch, recall that we parameterized our meow function
2245
01:40:32,010 --> 01:40:36,060
by letting us tell meow how many times to meow so that we didn't need to use
2246
01:40:36,060 --> 01:40:39,510
our loop inside of our "when green flag clicked" block.
2247
01:40:39,510 --> 01:40:41,610
In other words, if I want to actually have
2248
01:40:41,610 --> 01:40:45,060
the cat meow a specific number of times, I
2249
01:40:45,060 --> 01:40:47,640
can actually go ahead and do that proactively
2250
01:40:47,640 --> 01:40:52,090
with some of my own code such as this here in Scratch.
2251
01:40:52,090 --> 01:40:55,060
When I edited my meow function last week in Scratch,
2252
01:40:55,060 --> 01:40:58,240
I specified that I want it now to take an input called n,
2253
01:40:58,240 --> 01:41:00,160
which represents some number of times.
2254
01:41:00,160 --> 01:41:03,520
And I changed my repeat block not to be 3 perpetually,
2255
01:41:03,520 --> 01:41:07,240
but to actually have n generally baked in there instead.
2256
01:41:07,240 --> 01:41:09,490
Or actually, instead of just saying play sound "meow,"
2257
01:41:09,490 --> 01:41:14,230
I had a repeat block using n as the placeholder instead of a hard coded 3.
2258
01:41:14,230 --> 01:41:16,750
So how can I now use this in C?
2259
01:41:16,750 --> 01:41:20,090
In C, It's almost the same.
2260
01:41:20,090 --> 01:41:23,160
It's still void at the beginning of my function name,
2261
01:41:23,160 --> 01:41:24,690
which means no output still.
2262
01:41:24,690 --> 01:41:26,160
It only has side effects.
2263
01:41:26,160 --> 01:41:31,670
But what did change vis-Ă¡-vis the previous version of meow?
2264
01:41:31,670 --> 01:41:33,210
What has changed?
2265
01:41:33,210 --> 01:41:34,250
AUDIENCE: [INAUDIBLE]
2266
01:41:34,250 --> 01:41:35,250
DAVID J. MALAN: Exactly.
2267
01:41:35,250 --> 01:41:38,200
Instead of saying "void" a second time in parentheses,
2268
01:41:38,200 --> 01:41:43,180
it literally says "int n" inside of those parentheses, which means, in C,
2269
01:41:43,180 --> 01:41:45,670
this function called meow takes input.
2270
01:41:45,670 --> 01:41:47,920
It means the exact same thing as the pink on the left.
2271
01:41:47,920 --> 01:41:50,503
And again, this is why we keep emphasizing the Scratch blocks.
2272
01:41:50,503 --> 01:41:53,230
Like, no new ideas with a lot of these features.
2273
01:41:53,230 --> 01:41:56,410
It's just different syntax that you'll get used to over time.
2274
01:41:56,410 --> 01:42:00,100
So if I go back into VS Code here and I change this function, let's do that.
2275
01:42:00,100 --> 01:42:04,390
Let's change my prototype to be int n, where n represents some number of times.
2276
01:42:04,390 --> 01:42:08,490
Let's change the actual function on line 14 to also have int n here.
2277
01:42:08,490 --> 01:42:13,830
And let's actually move the for loop from main into the meow function
2278
01:42:13,830 --> 01:42:16,540
such that I now have my curly braces here.
2279
01:42:16,540 --> 01:42:19,740
I have my print statement inside of those curly braces.
2280
01:42:19,740 --> 01:42:23,680
And now, in main, I can get rid of all of that code.
2281
01:42:23,680 --> 01:42:26,877
Just say "meow" any number of times, like three.
2282
01:42:26,877 --> 01:42:30,210
And just like I did with Scratch, let me hit Enter an arbitrary number of times.
2283
01:42:30,210 --> 01:42:32,230
Sort of out of sight, out of mind.
2284
01:42:32,230 --> 01:42:37,120
Now the essence of my program is one real line of code-- "meow" three times--
2285
01:42:37,120 --> 01:42:42,040
because I've abstracted away the idea of meowing and told the cat, instead,
2286
01:42:42,040 --> 01:42:47,550
exactly how many times to meow by way of that function.
2287
01:42:47,550 --> 01:42:49,622
OK, I can't keep stringing along cookies so long.
2288
01:42:49,622 --> 01:42:51,580
Let's go ahead and take a 10-minute break here.
2289
01:42:51,580 --> 01:42:55,680
And when we come back, more cats, more code.
2290
01:42:55,680 --> 01:42:57,270
All right.
2291
01:42:57,270 --> 01:42:59,460
So we are back.
2292
01:42:59,460 --> 01:43:03,443
And I want to add one final flourish to this program because now,
2293
01:43:03,443 --> 01:43:05,610
more so than a lot of the examples, now the programs
2294
01:43:05,610 --> 01:43:07,150
are starting to grow in length.
2295
01:43:07,150 --> 01:43:10,750
And indeed, soon there'll be a few dozen lines of code, which is not uncommon.
2296
01:43:10,750 --> 01:43:14,790
But let's suppose that we want to stop hard-coding 3 everywhere and actually
2297
01:43:14,790 --> 01:43:18,445
prompt the user for some number of meows here.
2298
01:43:18,445 --> 01:43:19,320
Well, let me do this.
2299
01:43:19,320 --> 01:43:24,180
In VS Code, I'm going to go ahead and get rid of this one line for now.
2300
01:43:24,180 --> 01:43:25,930
And let's do something like this.
2301
01:43:25,930 --> 01:43:28,720
Let's ask the user for an integer.
2302
01:43:28,720 --> 01:43:32,070
So int, maybe n for number, equals get_int.
2303
01:43:32,070 --> 01:43:35,730
And we'll say something like just "Number" to give a number of meows.
2304
01:43:35,730 --> 01:43:40,120
And then we'll go ahead and actually call meow, passing in not 3 this time,
2305
01:43:40,120 --> 01:43:41,130
but passing in n.
2306
01:43:41,130 --> 01:43:43,650
So we are using the return value of get_int
2307
01:43:43,650 --> 01:43:47,180
to store it in a variable called n on line 8.
2308
01:43:47,180 --> 01:43:51,220
And then we are passing n as the input, or argument, to the function
2309
01:43:51,220 --> 01:43:53,150
called meow on line 9.
2310
01:43:53,150 --> 01:43:57,860
And again, the actual implementation of meow on line 22 onward, who cares?
2311
01:43:57,860 --> 01:43:59,150
Out of sight, out of mind.
2312
01:43:59,150 --> 01:44:01,730
Once it exists, we can abstract it away mentally.
2313
01:44:01,730 --> 01:44:04,102
But I'll keep it up tight here anyway.
2314
01:44:04,102 --> 01:44:06,560
All right, so let me go ahead and open my terminal window--
2315
01:44:06,560 --> 01:44:09,860
make cat, "./cat," "Number"--
2316
01:44:09,860 --> 01:44:11,720
I can still type in 3, and it works.
2317
01:44:11,720 --> 01:44:14,030
Or I can go ahead and type in 5.
2318
01:44:14,030 --> 01:44:15,170
"Meow," "meow," "meow."
2319
01:44:15,170 --> 01:44:18,620
But, hm, it's not actually meowing five times.
2320
01:44:18,620 --> 01:44:20,126
Why?
2321
01:44:20,126 --> 01:44:22,950
[WHISPERS] I didn't realize this either, but there's a bug.
2322
01:44:22,950 --> 01:44:24,480
AUDIENCE: [INAUDIBLE]
2323
01:44:24,480 --> 01:44:26,140
DAVID J. MALAN: Yeah, exactly.
2324
01:44:26,140 --> 01:44:28,930
So the for loop, when I copy/pasted it before, before break,
2325
01:44:28,930 --> 01:44:32,700
I actually got lazy and I forgot to change the 3 to an n
2326
01:44:32,700 --> 01:44:38,080
so that it matches the name of the argument that's being passed into meow.
2327
01:44:38,080 --> 01:44:40,270
So that was a bug-- unintentional on my part.
2328
01:44:40,270 --> 01:44:41,610
But we have now fixed it here.
2329
01:44:41,610 --> 01:44:45,460
And now we are passing this in from main to meow.
2330
01:44:45,460 --> 01:44:51,700
So if I make cat, "./cat", and type 5 this time, I indeed get five meows.
2331
01:44:51,700 --> 01:44:55,290
But it's worth noting there's some subtleties here in my code
2332
01:44:55,290 --> 01:44:57,550
in that I've used n a couple of times.
2333
01:44:57,550 --> 01:45:02,490
So this is actually deliberate, that I've used n twice in this way,
2334
01:45:02,490 --> 01:45:04,330
to induce a bit of confusion.
2335
01:45:04,330 --> 01:45:10,360
But it turns out this n is actually not the same as this n, nor this one.
2336
01:45:10,360 --> 01:45:11,865
So what's going on here?
2337
01:45:11,865 --> 01:45:14,740
Well, it turns out, in programming, there's often this idea of scope.
2338
01:45:14,740 --> 01:45:18,720
And long story short, generally speaking, variables only
2339
01:45:18,720 --> 01:45:22,470
exist in the scope in which you create them.
2340
01:45:22,470 --> 01:45:25,450
More down to Earth, variables only exist inside
2341
01:45:25,450 --> 01:45:28,250
of the curly braces in which you define them.
2342
01:45:28,250 --> 01:45:30,940
So for instance, suppose I got a little sloppy
2343
01:45:30,940 --> 01:45:34,840
and suppose I didn't bother giving meow an input
2344
01:45:34,840 --> 01:45:40,390
and I didn't bother giving its prototype an input and I just used n on line 14
2345
01:45:40,390 --> 01:45:41,370
because, why?
2346
01:45:41,370 --> 01:45:43,880
Well, I already defined n on line 8.
2347
01:45:43,880 --> 01:45:46,510
So this is just an alternate universe in which
2348
01:45:46,510 --> 01:45:49,250
I'm not changing meow to take input.
2349
01:45:49,250 --> 01:45:54,933
I'm just using n in two different functions, in main on line 8 and 9--
2350
01:45:54,933 --> 01:45:56,350
actually, I don't even need that--
2351
01:45:56,350 --> 01:46:00,350
on line 8 and 9 and also again on line 14.
2352
01:46:00,350 --> 01:46:02,140
This code will not work.
2353
01:46:02,140 --> 01:46:03,890
The compiler will not like this.
2354
01:46:03,890 --> 01:46:04,390
Why?
2355
01:46:04,390 --> 01:46:07,730
Because n does not exist inside of meow.
2356
01:46:07,730 --> 01:46:08,230
Why?
2357
01:46:08,230 --> 01:46:11,170
Per the heuristic I offered, n exists only inside
2358
01:46:11,170 --> 01:46:15,320
of the curly braces in which it was defined, namely these curly braces here.
2359
01:46:15,320 --> 01:46:18,560
So n is in scope in main, so to speak.
2360
01:46:18,560 --> 01:46:20,660
But it is not in scope in meow.
2361
01:46:20,660 --> 01:46:23,170
And that's why we have to jump through these hoops
2362
01:46:23,170 --> 01:46:25,690
and use inputs and outputs and inputs and outputs
2363
01:46:25,690 --> 01:46:31,270
and pass things around among functions without sharing things across functions
2364
01:46:31,270 --> 01:46:31,970
instead.
2365
01:46:31,970 --> 01:46:37,842
Now, I could clarify this and maybe change my argument here from n to times.
2366
01:46:37,842 --> 01:46:39,550
If I want to make clear that, oh, this is
2367
01:46:39,550 --> 01:46:45,140
the number of times I want meow to be said, I don't have to use n for both.
2368
01:46:45,140 --> 01:46:48,080
But just realize that, if you do, it's just a coincidence.
2369
01:46:48,080 --> 01:46:51,790
They are not usable in two different scopes.
2370
01:46:51,790 --> 01:46:55,390
All right, let's do one other thing, though.
2371
01:46:55,390 --> 01:46:58,828
Let's not only prompt the user for the number here,
2372
01:46:58,828 --> 01:47:01,370
let's make sure that it makes sense what number they give us.
2373
01:47:01,370 --> 01:47:05,720
So if I do make cat-- just to clean things up-- "./cat," suppose I type 0,
2374
01:47:05,720 --> 01:47:07,430
OK, I suppose that's correct.
2375
01:47:07,430 --> 01:47:11,030
If I say meow 0 times and it doesn't meow at all, that's arguably correct.
2376
01:47:11,030 --> 01:47:13,250
But if I type in something like negative 5,
2377
01:47:13,250 --> 01:47:17,060
it ignores me, which I guess is better than crashing or freezing or something.
2378
01:47:17,060 --> 01:47:19,930
But ideally, it might be nice to handle this situation.
2379
01:47:19,930 --> 01:47:24,063
And if they give me a negative number, prompt them again for a positive number.
2380
01:47:24,063 --> 01:47:25,730
Prompt them again for a positive number.
2381
01:47:25,730 --> 01:47:27,410
Make the program make sense.
2382
01:47:27,410 --> 01:47:28,580
So how could we do that?
2383
01:47:28,580 --> 01:47:29,830
Well, a couple of ways.
2384
01:47:29,830 --> 01:47:33,680
If I go back into my code here, I could do this.
2385
01:47:33,680 --> 01:47:38,390
I could maybe do something like a loop or-- let's see.
2386
01:47:38,390 --> 01:47:43,520
So if I get n, so if n is less than 1, then it makes no sense.
2387
01:47:43,520 --> 01:47:46,550
So what do I want to do if n is less than 1?
2388
01:47:46,550 --> 01:47:48,430
Well, I could just prompt the user again.
2389
01:47:48,430 --> 01:47:50,120
And I say, OK, let's get n again.
2390
01:47:50,120 --> 01:47:53,840
And then I can say, if n is less than 1, what do I want to do?
2391
01:47:53,840 --> 01:47:55,850
I guess we could ask the user again.
2392
01:47:55,850 --> 01:48:00,290
And then if n is less than 1, I could just, again--
2393
01:48:00,290 --> 01:48:03,100
I can give them three tries, four tries to get this right.
2394
01:48:03,100 --> 01:48:04,270
This is obviously stupid.
2395
01:48:04,270 --> 01:48:05,330
I'm copying and pasting.
2396
01:48:05,330 --> 01:48:06,530
I'm repeating myself.
2397
01:48:06,530 --> 01:48:07,970
There's no end in sight.
2398
01:48:07,970 --> 01:48:09,500
I can't do this forever, surely.
2399
01:48:09,500 --> 01:48:11,870
So this just feels like the wrong solution.
2400
01:48:11,870 --> 01:48:14,090
So there are different ways to solve this problem.
2401
01:48:14,090 --> 01:48:17,780
And funny enough, a while loop is not really the best way.
2402
01:48:17,780 --> 01:48:19,810
A do while loop is-- agh--
2403
01:48:19,810 --> 01:48:21,530
a while loop is not the best way.
2404
01:48:21,530 --> 01:48:22,878
A for loop is not the best way.
2405
01:48:22,878 --> 01:48:24,670
It turns out there's one other type of loop
2406
01:48:24,670 --> 01:48:27,640
that we want to introduce that's super useful for getting
2407
01:48:27,640 --> 01:48:32,600
user input, potentially, again and again and again so that the user cooperates.
2408
01:48:32,600 --> 01:48:34,640
Specifically, what I'm going to do is this.
2409
01:48:34,640 --> 01:48:40,340
I'm going to literally say, do the following while something is true.
2410
01:48:40,340 --> 01:48:41,530
So it's more of a mouthful.
2411
01:48:41,530 --> 01:48:43,430
I'm spreading it out over multiple lines.
2412
01:48:43,430 --> 01:48:46,730
But what am I going to put inside of the do block here?
2413
01:48:46,730 --> 01:48:51,820
I'm going to say int n equals get_int and ask for that number as before,
2414
01:48:51,820 --> 01:48:53,600
closed quote, semicolon.
2415
01:48:53,600 --> 01:48:56,410
And I'm going to keep asking while--
2416
01:48:56,410 --> 01:49:02,720
sorry, accidental Enter-- while n is less than 1, semicolon.
2417
01:49:02,720 --> 01:49:04,220
So notice the semantics of this.
2418
01:49:04,220 --> 01:49:06,060
Even though it's a little weird-looking, it
2419
01:49:06,060 --> 01:49:09,490
does read, in English, do the following.
2420
01:49:09,490 --> 01:49:11,050
Get an int stored in n.
2421
01:49:11,050 --> 01:49:14,000
And keep doing that while n is less than 1.
2422
01:49:14,000 --> 01:49:17,720
But this code as written is not quite going to work yet.
2423
01:49:17,720 --> 01:49:19,670
Let me try opening my terminal window.
2424
01:49:19,670 --> 01:49:21,410
Make cat, Enter.
2425
01:49:21,410 --> 01:49:25,363
Ugh, damn it-- "Use of undeclared identifier 'n.'" Well,
2426
01:49:25,363 --> 01:49:27,030
here's where the line number is helpful.
2427
01:49:27,030 --> 01:49:29,130
The line number is indicated here, 12.
2428
01:49:29,130 --> 01:49:30,690
And it's repeated here, 12.
2429
01:49:30,690 --> 01:49:32,800
So I clearly screwed up at line 12.
2430
01:49:32,800 --> 01:49:35,410
But there's not that much going on at line 12.
2431
01:49:35,410 --> 01:49:41,430
Why is n "undeclared" in line 12 even though I literally just declared it
2432
01:49:41,430 --> 01:49:43,669
in line 10?
2433
01:49:43,669 --> 01:49:46,847
AUDIENCE: Because it's [INAUDIBLE] inside of the [INAUDIBLE] line
2434
01:49:46,847 --> 01:49:47,935
10, not outside.
2435
01:49:47,935 --> 01:49:49,810
DAVID J. MALAN: Exactly, because I declared n
2436
01:49:49,810 --> 01:49:53,270
inside the scope of the do block, so to speak,
2437
01:49:53,270 --> 01:49:55,690
inside the curly braces on lines 9 and 11.
2438
01:49:55,690 --> 01:49:59,667
That variable n no longer exists by the time we get to line 12.
2439
01:49:59,667 --> 01:50:01,750
It'd be great if it did, but it doesn't because it
2440
01:50:01,750 --> 01:50:03,460
violates that heuristic I proposed, which
2441
01:50:03,460 --> 01:50:07,810
is that variables only exist in the scope of the curly braces in which they
2442
01:50:07,810 --> 01:50:08,880
were defined.
2443
01:50:08,880 --> 01:50:10,300
So how do I fix this?
2444
01:50:10,300 --> 01:50:16,430
Well, it turns out you can declare a variable in advance outside of one scope
2445
01:50:16,430 --> 01:50:18,950
but then define it, that is initialize it, elsewhere.
2446
01:50:18,950 --> 01:50:20,710
So the solution here is actually this.
2447
01:50:20,710 --> 01:50:25,100
Inside of the loop, just set an equal to the return value of get_int.
2448
01:50:25,100 --> 01:50:31,120
But per the heuristic, you've got to declare n, make it exist inside
2449
01:50:31,120 --> 01:50:33,852
of the outermost scope of this function.
2450
01:50:33,852 --> 01:50:34,810
So it's a little weird.
2451
01:50:34,810 --> 01:50:36,977
And we're kind of breaking this down into two steps.
2452
01:50:36,977 --> 01:50:40,130
But this is valid, recommended, correct C code.
2453
01:50:40,130 --> 01:50:43,580
You declare a variable without giving it any value initially.
2454
01:50:43,580 --> 01:50:47,260
And then, in line 11, you proceed to give it a value,
2455
01:50:47,260 --> 01:50:50,090
potentially again and again and again.
2456
01:50:50,090 --> 01:50:52,530
Now, what's useful about a do while loop?
2457
01:50:52,530 --> 01:50:56,100
So a do while loop, as the name implies, will do something no matter what.
2458
01:50:56,100 --> 01:50:59,520
But it will potentially do it again and again and again
2459
01:50:59,520 --> 01:51:06,780
while some question is true, like n being less than 1 in this case.
2460
01:51:06,780 --> 01:51:09,342
As an aside, why did we not do a while loop?
2461
01:51:09,342 --> 01:51:10,550
Well, let's think about that.
2462
01:51:10,550 --> 01:51:13,590
While n is less than 1--
2463
01:51:13,590 --> 01:51:15,930
but wait a minute. n doesn't have a value.
2464
01:51:15,930 --> 01:51:20,360
OK, so I guess we have to go back to doing get_int, number, colon, semicolon.
2465
01:51:20,360 --> 01:51:20,860
OK.
2466
01:51:20,860 --> 01:51:24,260
But while n is less than 1, we're back to the same problem
2467
01:51:24,260 --> 01:51:26,340
where we have to repeat ourselves again.
2468
01:51:26,340 --> 01:51:29,750
So this is why for loops, while loops, not the right solution when
2469
01:51:29,750 --> 01:51:33,360
you want to do something at least once but potentially again and again.
2470
01:51:33,360 --> 01:51:37,830
So the right solution here, again, is this new and final looping construct--
2471
01:51:37,830 --> 01:51:39,380
I'm just hitting Control-Z a lot--
2472
01:51:39,380 --> 01:51:41,907
whereby we've done it as follows.
2473
01:51:41,907 --> 01:51:42,990
All right, let's try this.
2474
01:51:42,990 --> 01:51:45,560
Clear the screen. make cat, Enter.
2475
01:51:45,560 --> 01:51:46,580
"./cat."
2476
01:51:46,580 --> 01:51:47,910
Let's type in 5.
2477
01:51:47,910 --> 01:51:48,720
Still works.
2478
01:51:48,720 --> 01:51:49,940
Let's type in negative 5.
2479
01:51:49,940 --> 01:51:52,140
And notice it doesn't just ignore me.
2480
01:51:52,140 --> 01:51:54,780
It prompts me again and again and again.
2481
01:51:54,780 --> 01:51:58,890
Even if I type in 0, I've got to at least give it a positive integer.
2482
01:51:58,890 --> 01:52:01,280
Well, this actually seems kind of a common paradigm.
2483
01:52:01,280 --> 01:52:05,192
What if we want to prompt the user for a positive number in other programs too?
2484
01:52:05,192 --> 01:52:07,400
We're nearing the point already, even after just week
2485
01:52:07,400 --> 01:52:10,100
1, where it'd be nice to write our own reusable
2486
01:52:10,100 --> 01:52:11,970
functions that solve common problems.
2487
01:52:11,970 --> 01:52:15,763
And eventually, maybe we can put them in header files as well.
2488
01:52:15,763 --> 01:52:17,430
But for now, let's go ahead and do this.
2489
01:52:17,430 --> 01:52:19,430
I'm going to actually copy all of this code.
2490
01:52:19,430 --> 01:52:22,100
And I'm going to create one more function in this file
2491
01:52:22,100 --> 01:52:27,420
below main called get_positive_int, for integer.
2492
01:52:27,420 --> 01:52:29,570
And I'm going to specify that it doesn't need
2493
01:52:29,570 --> 01:52:32,390
any input because the only thing this function is going to do
2494
01:52:32,390 --> 01:52:34,260
is that exact same thing.
2495
01:52:34,260 --> 01:52:38,630
So notice that I've just moved my code from main into a function that's name
2496
01:52:38,630 --> 01:52:41,270
describes what it does, "get_positive_int."
2497
01:52:41,270 --> 01:52:42,708
I'm declaring n here.
2498
01:52:42,708 --> 01:52:44,000
I'm doing this again and again.
2499
01:52:44,000 --> 01:52:46,680
And I'm doing that while n is less than 1.
2500
01:52:46,680 --> 01:52:48,442
And what am I going to do up here?
2501
01:52:48,442 --> 01:52:49,650
I can do something like this.
2502
01:52:49,650 --> 01:52:52,820
Give me a variable called times for, how many times do you want to meow?
2503
01:52:52,820 --> 01:52:57,257
And just call get_positive_int semicolon.
2504
01:52:57,257 --> 01:52:59,090
So now, again, we've abstracted things away.
2505
01:52:59,090 --> 01:53:01,290
And just like in Scratch, our final example--
2506
01:53:01,290 --> 01:53:03,720
which, recall, looked a little something like this,
2507
01:53:03,720 --> 01:53:06,740
where we just called a function to meow three times-- now
2508
01:53:06,740 --> 01:53:08,520
we're calling a function to get text.
2509
01:53:08,520 --> 01:53:11,940
If I hit Enter an arbitrary dramatic number of times, out of sight,
2510
01:53:11,940 --> 01:53:15,200
out of mind, I now have two functions in this world, get_positive_int
2511
01:53:15,200 --> 01:53:19,800
and meow that are collectively implementing this entire program.
2512
01:53:19,800 --> 01:53:21,990
But it's not quite correct.
2513
01:53:21,990 --> 01:53:24,380
There's one mistake here still.
2514
01:53:24,380 --> 01:53:29,240
Notice that get_positive_int is written slightly differently
2515
01:53:29,240 --> 01:53:31,200
from the meow function.
2516
01:53:31,200 --> 01:53:34,460
And just to be clear, too, let me copy its prototype to the top of the file
2517
01:53:34,460 --> 01:53:36,710
just so we don't make that same mistake I made earlier
2518
01:53:36,710 --> 01:53:40,340
where I didn't put the prototype at top so C didn't know what it was.
2519
01:53:40,340 --> 01:53:44,490
What is different about these two prototypes at a glance?
2520
01:53:44,490 --> 01:53:45,495
Yeah.
2521
01:53:45,495 --> 01:53:48,290
AUDIENCE: get_positive_int should be returning int.
2522
01:53:48,290 --> 01:53:50,540
DAVID J. MALAN: OK, so get_positive_int apparently--
2523
01:53:50,540 --> 01:53:52,760
and we've not talked much about this-- apparently
2524
01:53:52,760 --> 01:53:55,410
does have an output of type integer.
2525
01:53:55,410 --> 01:53:57,720
It's supposed to return an int, hand me back an int.
2526
01:53:57,720 --> 01:53:59,160
It doesn't have any input.
2527
01:53:59,160 --> 01:54:01,080
That's what the "void" in parentheses meant.
2528
01:54:01,080 --> 01:54:03,020
No input, but yes output.
2529
01:54:03,020 --> 01:54:06,690
And meow, funny enough, is the opposite-- yes input, no output.
2530
01:54:06,690 --> 01:54:07,190
Why?
2531
01:54:07,190 --> 01:54:09,200
Because it has a side effect, the visual thing,
2532
01:54:09,200 --> 01:54:11,658
where it prints something to the screen but doesn't hand me
2533
01:54:11,658 --> 01:54:15,630
any useful value back like the ask function or the ask puzzle piece did.
2534
01:54:15,630 --> 01:54:17,690
So these are opposite in functionality, which
2535
01:54:17,690 --> 01:54:22,820
means I actually need to return an integer from this function to whatever
2536
01:54:22,820 --> 01:54:24,900
function wants to use it.
2537
01:54:24,900 --> 01:54:28,710
So if I want the assignment operator to work here on line 9,
2538
01:54:28,710 --> 01:54:31,190
I need to do what, all this time, get_int, get_string,
2539
01:54:31,190 --> 01:54:33,390
and other CS50 functions have been doing.
2540
01:54:33,390 --> 01:54:38,360
I need to, in my own function, return that value literally
2541
01:54:38,360 --> 01:54:40,260
with a new keyword called return.
2542
01:54:40,260 --> 01:54:42,150
And this is why I keep sticking out my hand.
2543
01:54:42,150 --> 01:54:46,940
When you want a function to hand you back a value, you literally use "return"
2544
01:54:46,940 --> 01:54:48,400
and then that value.
2545
01:54:48,400 --> 01:54:52,770
That's why we have "return" value as a term of art, literally the "return"
2546
01:54:52,770 --> 01:54:53,680
keyword.
2547
01:54:53,680 --> 01:54:58,480
So if I open my terminal window now, make cat, Enter--
2548
01:54:58,480 --> 01:55:00,990
huh, I did screw up accidentally.
2549
01:55:00,990 --> 01:55:02,000
How?
2550
01:55:02,000 --> 01:55:02,500
Yeah.
2551
01:55:02,500 --> 01:55:03,780
AUDIENCE: [INAUDIBLE]
2552
01:55:03,780 --> 01:55:06,820
DAVID J. MALAN: Yeah, so on lines 9 and 10, I made a quick change.
2553
01:55:06,820 --> 01:55:08,200
I changed my variable to times.
2554
01:55:08,200 --> 01:55:09,910
But I stupidly didn't change this.
2555
01:55:09,910 --> 01:55:10,630
So that's fine.
2556
01:55:10,630 --> 01:55:13,060
That's why n was undeclared in that context.
2557
01:55:13,060 --> 01:55:15,450
Let me clear my terminal, make cat once more.
2558
01:55:15,450 --> 01:55:17,040
OK, that worked. "./cat."
2559
01:55:17,040 --> 01:55:18,270
Let's type in 5.
2560
01:55:18,270 --> 01:55:19,570
And it's still working.
2561
01:55:19,570 --> 01:55:21,977
So again, even though the code feels like it's-- sorry--
2562
01:55:21,977 --> 01:55:24,310
even though the code is growing and growing and growing,
2563
01:55:24,310 --> 01:55:28,420
it's the exact same program we wrote super simply before break.
2564
01:55:28,420 --> 01:55:30,460
But now we're sort of modularizing it.
2565
01:55:30,460 --> 01:55:32,440
We're creating reusable functions.
2566
01:55:32,440 --> 01:55:35,160
And this is why functions like get_string exists, get_int exists.
2567
01:55:35,160 --> 01:55:36,840
Like, CS50 wrote those years ago.
2568
01:55:36,840 --> 01:55:40,140
And we realized, why are we copying and pasting these functions in all
2569
01:55:40,140 --> 01:55:41,950
of these different CS50 programs?
2570
01:55:41,950 --> 01:55:45,960
Let's factor out that functionality into a function of our own-- get_int,
2571
01:55:45,960 --> 01:55:47,020
get_string.
2572
01:55:47,020 --> 01:55:50,560
Just like here, I'm proposing to factor out this functionality,
2573
01:55:50,560 --> 01:55:54,430
get a positive integer that gives you even more precise functionality
2574
01:55:54,430 --> 01:55:58,270
so theoretically you could use and reuse it in other programs too.
2575
01:55:58,270 --> 01:56:00,120
By not even just putting it here, we could
2576
01:56:00,120 --> 01:56:05,650
go put it in a file of your own name and include it in future programs as well.
2577
01:56:05,650 --> 01:56:07,100
That's all a library is.
2578
01:56:07,100 --> 01:56:10,040
Someone realized, jeez, other people, including myself,
2579
01:56:10,040 --> 01:56:12,560
might find this function useful again and again.
2580
01:56:12,560 --> 01:56:15,860
Let's package it up in our own custom functions,
2581
01:56:15,860 --> 01:56:18,500
just like our custom meow puzzle piece last week,
2582
01:56:18,500 --> 01:56:21,350
so we can indeed use it again and again.
2583
01:56:21,350 --> 01:56:25,150
And the takeaways for now is that unlike Scratch, which was a little more user
2584
01:56:25,150 --> 01:56:29,290
friendly, in C, you have to specify if you want your functions to have inputs.
2585
01:56:29,290 --> 01:56:33,290
And you must specify if you want them to have outputs as well.
2586
01:56:33,290 --> 01:56:35,510
But more on that syntax to come.
2587
01:56:35,510 --> 01:56:37,160
So where does that bring us?
2588
01:56:37,160 --> 01:56:40,070
So after all this discussion of code, at the end of the day,
2589
01:56:40,070 --> 01:56:42,565
this is what's important in the world of programming.
2590
01:56:42,565 --> 01:56:44,440
Not surprisingly, it's like, what's important
2591
01:56:44,440 --> 01:56:47,110
when it comes to grading and evaluating the quality of code?
2592
01:56:47,110 --> 01:56:49,030
One, and first and foremost, is correctness.
2593
01:56:49,030 --> 01:56:50,600
If the code does not do what it's supposed to do,
2594
01:56:50,600 --> 01:56:52,370
what was the point of writing the code?
2595
01:56:52,370 --> 01:56:54,410
So correctness sort of goes without saying.
2596
01:56:54,410 --> 01:56:56,238
Design, again, is much more qualitative.
2597
01:56:56,238 --> 01:56:58,780
It's like getting feedback, again, on an English essay, where
2598
01:56:58,780 --> 01:57:00,170
reasonable people might disagree.
2599
01:57:00,170 --> 01:57:01,790
You can make your argument better.
2600
01:57:01,790 --> 01:57:03,530
You can structure the paper better.
2601
01:57:03,530 --> 01:57:06,760
You can structure the code better in the case of programming.
2602
01:57:06,760 --> 01:57:08,900
And style is purely aesthetic.
2603
01:57:08,900 --> 01:57:09,830
Does it look good?
2604
01:57:09,830 --> 01:57:11,570
Is it pretty printed, so to speak?
2605
01:57:11,570 --> 01:57:15,280
Can other people, colleagues future and classmates present, actually
2606
01:57:15,280 --> 01:57:16,610
read and understand it?
2607
01:57:16,610 --> 01:57:18,350
That's what we mean by style.
2608
01:57:18,350 --> 01:57:21,200
Nicely enough, within CS50's programming environment,
2609
01:57:21,200 --> 01:57:25,640
you will have tools to evaluate the quality of all three of these axes,
2610
01:57:25,640 --> 01:57:26,150
so to speak.
2611
01:57:26,150 --> 01:57:29,500
So in problem set 1 onward, you'll be introduced to a command line tool
2612
01:57:29,500 --> 01:57:32,470
that you type its name at the prompt called check50 that will check
2613
01:57:32,470 --> 01:57:34,400
for you the correctness of your code--
2614
01:57:34,400 --> 01:57:36,440
not necessarily exhaustively.
2615
01:57:36,440 --> 01:57:39,020
There might be mistakes you've made that we don't catch,
2616
01:57:39,020 --> 01:57:40,700
which doesn't make your code correct.
2617
01:57:40,700 --> 01:57:44,150
But it is a tool for finding many of the mistakes in your code.
2618
01:57:44,150 --> 01:57:46,810
In the real world, you would have colleagues or yourself,
2619
01:57:46,810 --> 01:57:49,880
would write tests for code you wrote or someone else wrote.
2620
01:57:49,880 --> 01:57:52,100
So testing code is not just a grading thing.
2621
01:57:52,100 --> 01:57:56,540
It is a real-world thing to ensure that systems are designed correctly.
2622
01:57:56,540 --> 01:57:59,480
We saw the style50 tool in VS Code already.
2623
01:57:59,480 --> 01:58:00,830
You click the "style50" button.
2624
01:58:00,830 --> 01:58:03,880
There is now, thanks to the Duck, a "design50" button too,
2625
01:58:03,880 --> 01:58:07,540
also in that top right-hand corner, whereby once your code is correct
2626
01:58:07,540 --> 01:58:11,500
and working, like several of my programs have been, you can click "design50,"
2627
01:58:11,500 --> 01:58:15,710
and the Duck will not just quack but give you qualitative advice, if it can,
2628
01:58:15,710 --> 01:58:18,967
on how you can make that code even better even before you submit.
2629
01:58:18,967 --> 01:58:21,550
And of course, there's all of us humans in the room and online
2630
01:58:21,550 --> 01:58:25,070
that you can ask these same questions of as well.
2631
01:58:25,070 --> 01:58:29,920
So let's now solve some real-world but still simple problems as opposed
2632
01:58:29,920 --> 01:58:33,470
to emphasizing small bite-size as we have thus far.
2633
01:58:33,470 --> 01:58:35,980
So the first of these programs falls into this category
2634
01:58:35,980 --> 01:58:37,100
of having side effects.
2635
01:58:37,100 --> 01:58:40,310
So let's implement one or more functions that takes an argument's inputs
2636
01:58:40,310 --> 01:58:42,920
and, as its output, produces these visual side effects.
2637
01:58:42,920 --> 01:58:46,420
We'll draw inspiration from Super Mario Brothers-- not surprisingly, perhaps,
2638
01:58:46,420 --> 01:58:49,450
here-- the original one, which was very two-dimensional, side-scroller,
2639
01:58:49,450 --> 01:58:50,060
left to right.
2640
01:58:50,060 --> 01:58:52,300
Mario or Luigi move from left to right and generally
2641
01:58:52,300 --> 01:58:56,270
have to jump over things like pyramids or other shapes on the screen.
2642
01:58:56,270 --> 01:58:59,920
So how might we go about implementing some of the screens
2643
01:58:59,920 --> 01:59:02,197
from Super Mario Brothers, albeit textually?
2644
01:59:02,197 --> 01:59:04,030
Well, we'll make it a little black and white
2645
01:59:04,030 --> 01:59:07,640
and ASCII art, so to speak, here using just our keyboard.
2646
01:59:07,640 --> 01:59:10,960
But suppose we want to write a program called mario.c
2647
01:59:10,960 --> 01:59:12,798
that just prints out four question marks.
2648
01:59:12,798 --> 01:59:15,590
It's not going to be nearly as pretty as what's on the screen here.
2649
01:59:15,590 --> 01:59:19,060
But the logic is going to be the exact same as what Nintendo presumably
2650
01:59:19,060 --> 01:59:20,420
did years ago.
2651
01:59:20,420 --> 01:59:23,210
So let me open VS Code, my terminal window.
2652
01:59:23,210 --> 01:59:25,630
Let's code a program called mario.c.
2653
01:59:25,630 --> 01:59:28,450
In mario.c, I'm going to start with some boilerplate--
2654
01:59:28,450 --> 01:59:29,570
I know I want to print.
2655
01:59:29,570 --> 01:59:33,310
So even if I don't know how to do this yet, I'm going to include standard io.h.
2656
01:59:33,310 --> 01:59:35,770
For today's purposes, I'm going to copy/paste or type
2657
01:59:35,770 --> 01:59:38,290
out that same line again and again-- int meow(void).
2658
01:59:38,290 --> 01:59:42,890
And inside of my main function, akin to the green flag being clicked,
2659
01:59:42,890 --> 01:59:45,473
I want to go ahead and print out four question marks.
2660
01:59:45,473 --> 01:59:47,890
Well, honestly, the simplest way I can think of doing this
2661
01:59:47,890 --> 01:59:51,170
is with printf question mark, question mark, question mark, question mark.
2662
01:59:51,170 --> 01:59:54,050
Maybe a backslash n to move the cursor, and that's it.
2663
01:59:54,050 --> 01:59:55,850
So that is arguably correct.
2664
01:59:55,850 --> 01:59:59,300
So let's do make mario in the terminal, "./mario."
2665
01:59:59,300 --> 02:00:02,570
And it's not quite as pretty as the game version of it.
2666
02:00:02,570 --> 02:00:04,700
But it is, in fact, the exact same idea.
2667
02:00:04,700 --> 02:00:08,770
But here, sort of an opportunity, a stepping stone to do better design.
2668
02:00:08,770 --> 02:00:10,005
This game changes over time.
2669
02:00:10,005 --> 02:00:12,380
And not all of the screens have just four question marks.
2670
02:00:12,380 --> 02:00:14,690
It might be five, six, or even more.
2671
02:00:14,690 --> 02:00:16,630
So what's the right programming construct
2672
02:00:16,630 --> 02:00:20,890
with which we could generalize how many question marks are printing here?
2673
02:00:20,890 --> 02:00:24,437
What feature of C do we want?
2674
02:00:24,437 --> 02:00:27,020
A loop, like a for loop, a while loop, or something like that.
2675
02:00:27,020 --> 02:00:28,603
And there's different ways to do this.
2676
02:00:28,603 --> 02:00:30,820
But honestly, I've proposed earlier that we
2677
02:00:30,820 --> 02:00:34,220
get into the habit of reaching for for loops as just very conventional.
2678
02:00:34,220 --> 02:00:39,072
So let's do that. for int i equals 0; i less than 4--
2679
02:00:39,072 --> 02:00:41,030
because that's how many I want for the moment--
2680
02:00:41,030 --> 02:00:42,010
i++.
2681
02:00:42,010 --> 02:00:44,740
And then inside of my curly braces there, let's go ahead
2682
02:00:44,740 --> 02:00:50,270
and print out, quote, unquote, a single question mark, but no new line.
2683
02:00:50,270 --> 02:00:52,630
Let me now go ahead and make mario.
2684
02:00:52,630 --> 02:00:58,400
And can you anticipate an arguably aesthetic bug when I hit Enter?
2685
02:00:58,400 --> 02:01:02,000
It's not going to move the cursor to the next line.
2686
02:01:02,000 --> 02:01:04,130
But the solution here is a little non-obvious.
2687
02:01:04,130 --> 02:01:06,010
I don't think this helps me.
2688
02:01:06,010 --> 02:01:10,190
If I put the backslash n there and I do make mario again and "./mario,"
2689
02:01:10,190 --> 02:01:12,625
what is this output going to look like instead?
2690
02:01:12,625 --> 02:01:13,500
AUDIENCE: [INAUDIBLE]
2691
02:01:13,500 --> 02:01:15,333
DAVID J. MALAN: Yeah, like a vertical column
2692
02:01:15,333 --> 02:01:18,310
of question marks, which, while nice enough, is not the goal at hand.
2693
02:01:18,310 --> 02:01:20,080
The goal is these horizontal ones.
2694
02:01:20,080 --> 02:01:24,255
So someone else, what's the fix here, if clearly putting the backslash n
2695
02:01:24,255 --> 02:01:26,596
inside of line 7 is wrong?
2696
02:01:26,596 --> 02:01:28,300
AUDIENCE: [INAUDIBLE]
2697
02:01:28,300 --> 02:01:32,240
DAVID J. MALAN: Yeah, so put it after the loop, and not after the printf line,
2698
02:01:32,240 --> 02:01:37,210
specifically after and thus outside of the loop so that after that loop is
2699
02:01:37,210 --> 02:01:41,710
finished executing three total times, it's totally fine to just print nothing
2700
02:01:41,710 --> 02:01:46,240
other than a backslash n so long as we now recompile the code, make mario,
2701
02:01:46,240 --> 02:01:47,170
"./mario."
2702
02:01:47,170 --> 02:01:49,980
And, voila, now we have four in a row.
2703
02:01:49,980 --> 02:01:51,080
It's a little generalized.
2704
02:01:51,080 --> 02:01:53,922
OK, so we've sort of plucked off a fairly easy problem.
2705
02:01:53,922 --> 02:01:55,630
Well, let's go back to the world of Mario
2706
02:01:55,630 --> 02:01:57,963
and try something that is, in fact, vertical, like this.
2707
02:01:57,963 --> 02:02:00,093
So this is another scene with three bricks here.
2708
02:02:00,093 --> 02:02:03,260
Instead of using question marks, we'll use hash symbols to represent bricks.
2709
02:02:03,260 --> 02:02:08,420
This actually is the incarnation of my mistake a moment ago.
2710
02:02:08,420 --> 02:02:11,080
So let me undo this by getting rid of that printf.
2711
02:02:11,080 --> 02:02:13,720
Let me change the inside one from a question mark
2712
02:02:13,720 --> 02:02:17,690
to a hash symbol, which looks the most similar in ASCII to a brick.
2713
02:02:17,690 --> 02:02:20,420
And let's go ahead and put a backslash n after that.
2714
02:02:20,420 --> 02:02:25,010
If I do go ahead and do make mario, "./mario", it's not that interesting.
2715
02:02:25,010 --> 02:02:28,140
But-- and it's actually not that correct because I wanted three.
2716
02:02:28,140 --> 02:02:29,400
So no big deal.
2717
02:02:29,400 --> 02:02:32,280
I can, of course, go back to my code and change the 4 to a 3.
2718
02:02:32,280 --> 02:02:35,990
Or better yet, I could use get_int or my new get_positive_int function
2719
02:02:35,990 --> 02:02:40,440
and just generalize this further so that I can print out any number of them.
2720
02:02:40,440 --> 02:02:43,550
But for now "./mario" gives me three.
2721
02:02:43,550 --> 02:02:46,260
All right, so we've plucked off the second of two problems.
2722
02:02:46,260 --> 02:02:48,630
Let's now let things escalate a bit.
2723
02:02:48,630 --> 02:02:50,940
So it turns out, once you get to World 2 and beyond,
2724
02:02:50,940 --> 02:02:52,730
there are some underground parts of Mario
2725
02:02:52,730 --> 02:02:56,580
where you actually have bigger, more solid bricks like these here.
2726
02:02:56,580 --> 02:03:00,000
And just by eyeballing it, this is a 3-by-3 grid of bricks,
2727
02:03:00,000 --> 02:03:02,490
like nine of them total, we'll conjecture.
2728
02:03:02,490 --> 02:03:04,680
So how can I go about implementing this?
2729
02:03:04,680 --> 02:03:07,370
Well, now is where the program gets a little more interesting.
2730
02:03:07,370 --> 02:03:11,930
And the not-- well, the poorly designed way to
2731
02:03:11,930 --> 02:03:19,080
do this would be like printf hash, hash, hash, backslash n, semicolon,
2732
02:03:19,080 --> 02:03:21,390
and then maybe printf, printf.
2733
02:03:21,390 --> 02:03:24,450
That's correct but not well designed.
2734
02:03:24,450 --> 02:03:26,610
So make mario, "./mario."
2735
02:03:26,610 --> 02:03:29,480
It doesn't look like a square, just because these hashes are
2736
02:03:29,480 --> 02:03:31,350
more vertical than they are horizontal.
2737
02:03:31,350 --> 02:03:33,480
But it is correct, this example.
2738
02:03:33,480 --> 02:03:34,860
But it's not very generalizable.
2739
02:03:34,860 --> 02:03:36,390
And this is literally hard coding.
2740
02:03:36,390 --> 02:03:37,110
I copy/pasted.
2741
02:03:37,110 --> 02:03:39,690
I'm just doing a lot of bad practices here.
2742
02:03:39,690 --> 02:03:41,190
So what could I do instead?
2743
02:03:41,190 --> 02:03:44,880
Well, it turns out we can combine today's ideas, including loops,
2744
02:03:44,880 --> 02:03:47,130
to do things again and again.
2745
02:03:47,130 --> 02:03:50,640
So what is this grid of bricks?
2746
02:03:50,640 --> 02:03:51,860
It's a 3-by-3.
2747
02:03:51,860 --> 02:03:56,395
So it's like a row and a row and a row.
2748
02:03:56,395 --> 02:03:58,770
And then within each row, there's column, column, column.
2749
02:03:58,770 --> 02:04:02,370
So it, too, is like an old-timey typewriter that prints one line,
2750
02:04:02,370 --> 02:04:04,740
then the next line, then the next line, and so forth.
2751
02:04:04,740 --> 02:04:07,230
So how can we conjure that in code?
2752
02:04:07,230 --> 02:04:10,800
Well, let me go ahead and do this.
2753
02:04:10,800 --> 02:04:13,380
I think a print approach would work like this.
2754
02:04:13,380 --> 02:04:17,780
For int i equals 0, i less than 3, i plus plus,
2755
02:04:17,780 --> 02:04:20,130
because I know I want to do something three times--
2756
02:04:20,130 --> 02:04:22,050
but what do I want to do three times?
2757
02:04:22,050 --> 02:04:27,270
This loop kind of represents, in my mind's eye, row, row, row.
2758
02:04:27,270 --> 02:04:28,820
So in fact, I could be more pedantic.
2759
02:04:28,820 --> 02:04:32,600
If I want my i to mean something beyond int, I could say row
2760
02:04:32,600 --> 02:04:38,370
equals 0, row less than 3, row plus plus, just to help me think about it.
2761
02:04:38,370 --> 02:04:40,740
And then what do I want to do on each row?
2762
02:04:40,740 --> 02:04:43,050
What do I want to print?
2763
02:04:43,050 --> 02:04:45,550
Column, column, column, so brick, brick, brick.
2764
02:04:45,550 --> 02:04:48,820
So how do I print three bricks or any number of bricks?
2765
02:04:48,820 --> 02:04:53,070
Well, I could cheat and just do printf hash, hash, hash, backslash n.
2766
02:04:53,070 --> 02:04:55,120
But again, I can't generalize.
2767
02:04:55,120 --> 02:04:58,450
I can't take an input from the user and print four or five or six bricks.
2768
02:04:58,450 --> 02:05:00,730
So that's going to get me into trouble eventually.
2769
02:05:00,730 --> 02:05:02,350
So maybe I could use a loop.
2770
02:05:02,350 --> 02:05:08,650
So I could do for int i equals 0, i less than 3, i plus plus inside of my loop.
2771
02:05:08,650 --> 02:05:11,010
And then in here, I could print out one hash.
2772
02:05:11,010 --> 02:05:13,720
And that's kind of on the right direction, the right path,
2773
02:05:13,720 --> 02:05:16,980
because now I'm just using the simple building block, or brick,
2774
02:05:16,980 --> 02:05:18,700
but reusing it again and again.
2775
02:05:18,700 --> 02:05:21,880
And it's totally fine to have nested these columns in this way.
2776
02:05:21,880 --> 02:05:23,530
I used i out of habit.
2777
02:05:23,530 --> 02:05:25,000
But what would a better name be?
2778
02:05:25,000 --> 02:05:28,660
Well, maybe "column," or maybe just C-O-L, "col" for short,
2779
02:05:28,660 --> 02:05:32,370
so that my code is saying what it does for me.
2780
02:05:32,370 --> 02:05:35,320
And I don't have to use "row" or "column" explicitly.
2781
02:05:35,320 --> 02:05:36,490
I don't need to print them.
2782
02:05:36,490 --> 02:05:39,880
But I am using them as counters one after the other.
2783
02:05:39,880 --> 02:05:44,080
So let me go ahead and run make Mario, "./mario."
2784
02:05:44,080 --> 02:05:46,210
And I'm feeling good about this, but--
2785
02:05:46,210 --> 02:05:47,350
ugh.
2786
02:05:47,350 --> 02:05:49,147
Damn it, there's nine bricks.
2787
02:05:49,147 --> 02:05:50,480
But they're not really laid out.
2788
02:05:50,480 --> 02:05:52,760
Why?
2789
02:05:52,760 --> 02:05:53,660
What's the fix?
2790
02:05:53,660 --> 02:05:54,495
Yeah.
2791
02:05:54,495 --> 02:05:56,558
AUDIENCE: You never went to a new line.
2792
02:05:56,558 --> 02:05:58,600
DAVID J. MALAN: Yeah, I never went to a new line.
2793
02:05:58,600 --> 02:06:00,770
And let me do what I think you're not going to suggest I do.
2794
02:06:00,770 --> 02:06:02,140
Let me just go to the obvious place.
2795
02:06:02,140 --> 02:06:04,348
All right, well, let's put one right after the brick.
2796
02:06:04,348 --> 02:06:07,130
But, of course, if I do make mario, "./mario,"
2797
02:06:07,130 --> 02:06:08,810
I'm making the same mistake as before.
2798
02:06:08,810 --> 02:06:10,310
I'm printing out too many new lines.
2799
02:06:10,310 --> 02:06:14,890
So in between what lines do I actually want to print a new line?
2800
02:06:14,890 --> 02:06:15,850
Between, yeah?
2801
02:06:15,850 --> 02:06:16,762
AUDIENCE: 10 and 11.
2802
02:06:16,762 --> 02:06:18,220
DAVID J. MALAN: Yeah, so 10 and 11.
2803
02:06:18,220 --> 02:06:22,900
So outside of the inner loop but inside of the outer loop
2804
02:06:22,900 --> 02:06:24,280
so it happens again and again.
2805
02:06:24,280 --> 02:06:28,330
So let's just print out, as before, a single backslash n, semicolon.
2806
02:06:28,330 --> 02:06:31,600
Now let's do make mario, "./mario," Enter.
2807
02:06:31,600 --> 02:06:34,480
Ah, now it's generalized as I see fit.
2808
02:06:34,480 --> 02:06:37,470
And if I really wanted to dwell on this, I could go in
2809
02:06:37,470 --> 02:06:40,320
and I could prompt the user with get_int or with get_positive_int,
2810
02:06:40,320 --> 02:06:42,940
figure out what row and/or column should be.
2811
02:06:42,940 --> 02:06:44,980
We can make any size brick that we want.
2812
02:06:44,980 --> 02:06:47,227
But now we have a nice starting point.
2813
02:06:47,227 --> 02:06:50,310
But there's another way to think about this because I dare say, especially
2814
02:06:50,310 --> 02:06:52,140
for your first CS50 problem set, if you're
2815
02:06:52,140 --> 02:06:54,760
trying to print bricks and the world of Mario in this way,
2816
02:06:54,760 --> 02:06:58,530
it's probably not going to be obvious to come up with loops like this
2817
02:06:58,530 --> 02:07:02,340
and just magically get it working after 45 seconds in total.
2818
02:07:02,340 --> 02:07:03,970
It'll be a struggle at first.
2819
02:07:03,970 --> 02:07:06,190
But there are some patterns to follow.
2820
02:07:06,190 --> 02:07:09,030
So one, it's pretty conventional nonetheless
2821
02:07:09,030 --> 02:07:12,662
to use just i and then j and then k and then l.
2822
02:07:12,662 --> 02:07:15,120
And if you've got nested, nested, nested, nested for loops,
2823
02:07:15,120 --> 02:07:17,720
at some point nesting, you're probably writing bad code.
2824
02:07:17,720 --> 02:07:18,740
It's not well designed.
2825
02:07:18,740 --> 02:07:22,010
But one or two or maybe three nestings could be an OK thing.
2826
02:07:22,010 --> 02:07:26,210
But you cannot use and reuse i again and again.
2827
02:07:26,210 --> 02:07:26,740
Why?
2828
02:07:26,740 --> 02:07:30,520
Because if you're counting i here, but then you're changing i here
2829
02:07:30,520 --> 02:07:32,680
to do your columns left to right, you're going
2830
02:07:32,680 --> 02:07:34,460
to get all of your math out of sync.
2831
02:07:34,460 --> 02:07:38,200
So you need two separate variables. i and j are conventional.
2832
02:07:38,200 --> 02:07:40,370
Or row and column would work too.
2833
02:07:40,370 --> 02:07:43,160
But if we go back to this idea of rows and columns,
2834
02:07:43,160 --> 02:07:45,447
well, let me actually factor something out here.
2835
02:07:45,447 --> 02:07:46,780
And this might help you instead.
2836
02:07:46,780 --> 02:07:49,430
Suppose that you set out on this problem.
2837
02:07:49,430 --> 02:07:51,860
You know you want to do something three times.
2838
02:07:51,860 --> 02:07:55,580
But you don't quite understand how to print those rows.
2839
02:07:55,580 --> 02:07:59,900
Well, take a baby step, a bite out of the problem, and maybe do this.
2840
02:07:59,900 --> 02:08:03,460
Create a function with no output, just a side effect whose purpose in life
2841
02:08:03,460 --> 02:08:05,000
is to print a row.
2842
02:08:05,000 --> 02:08:06,260
And how many rows?
2843
02:08:06,260 --> 02:08:08,500
Well, maybe n for some number of rows--
2844
02:08:08,500 --> 02:08:10,420
for some number of bricks, rather.
2845
02:08:10,420 --> 02:08:11,940
How do you print a row of bricks?
2846
02:08:11,940 --> 02:08:13,940
Well, let me just think about this in isolation.
2847
02:08:13,940 --> 02:08:15,830
How do I print a single row of bricks?
2848
02:08:15,830 --> 02:08:19,900
That's easy-- for int i equals 0, i is less than n--
2849
02:08:19,900 --> 02:08:24,250
if I'm generalizing-- i++, and then-- whoops, i++.
2850
02:08:24,250 --> 02:08:29,470
And then, inside of my curly braces, go ahead and just print out a single hash.
2851
02:08:29,470 --> 02:08:33,890
And at the end, as you suggested, print out a single new line.
2852
02:08:33,890 --> 02:08:39,045
In other words, abstract away the idea of printing a single row.
2853
02:08:39,045 --> 02:08:41,170
And in fact, at this point in the story, especially
2854
02:08:41,170 --> 02:08:44,337
if you're struggling to get started, you don't even need to start with main.
2855
02:08:44,337 --> 02:08:47,380
Take a bite out of the problem that makes sense to you that's smaller
2856
02:08:47,380 --> 02:08:51,610
than the whole problem, printing a single row because then you can come in
2857
02:08:51,610 --> 02:08:52,310
and iterate.
2858
02:08:52,310 --> 02:08:55,820
Then you can go in and say, OK, now let's write my actual main function.
2859
02:08:55,820 --> 02:08:57,740
So int meow(void), as always.
2860
02:08:57,740 --> 02:08:58,970
And now what do I want to do?
2861
02:08:58,970 --> 02:09:01,192
I want to print out a whole bunch of rows.
2862
02:09:01,192 --> 02:09:02,900
How do I print out a whole bunch of rows?
2863
02:09:02,900 --> 02:09:07,100
Oh, my god, it's like the same idea-- for int i equals 0, i is less than,
2864
02:09:07,100 --> 02:09:10,400
let's call it 3 for now-- but we can generalize that-- i++.
2865
02:09:10,400 --> 02:09:14,520
And what do I want to do on each iteration of this loop?
2866
02:09:14,520 --> 02:09:19,090
My gosh, just print row with three bricks.
2867
02:09:19,090 --> 02:09:21,362
And then we're sort of done.
2868
02:09:21,362 --> 02:09:23,320
Again, out of sight, out of mind, this function
2869
02:09:23,320 --> 02:09:26,480
can go away and never be seen before because once print_row exists,
2870
02:09:26,480 --> 02:09:28,790
that's what it in fact does for me.
2871
02:09:28,790 --> 02:09:30,800
Now, this isn't 100% correct.
2872
02:09:30,800 --> 02:09:33,740
I still need my prototype because if I've made my own function,
2873
02:09:33,740 --> 02:09:37,537
I need to tell C in advance that it shall exist.
2874
02:09:37,537 --> 02:09:39,620
So I need to copy and paste that one line of code.
2875
02:09:39,620 --> 02:09:42,910
If I were really being pedantic, this is bad design.
2876
02:09:42,910 --> 02:09:46,103
In general, when you have the same number in multiple places in a program,
2877
02:09:46,103 --> 02:09:48,020
a programmer would call this a "magic number."
2878
02:09:48,020 --> 02:09:49,750
Like, how is that working?
2879
02:09:49,750 --> 02:09:53,210
Just honor system, that you're using the same number again and again.
2880
02:09:53,210 --> 02:09:56,390
So a better solution here, even if you're not going to take user input,
2881
02:09:56,390 --> 02:09:59,290
would be to do this-- int n equals 3.
2882
02:09:59,290 --> 02:10:01,720
And then use n here.
2883
02:10:01,720 --> 02:10:03,470
And then use n here.
2884
02:10:03,470 --> 02:10:05,450
Or you could call it anything you want.
2885
02:10:05,450 --> 02:10:10,030
But now you've specified 3 in one and only one place.
2886
02:10:10,030 --> 02:10:11,660
And we can go one step further.
2887
02:10:11,660 --> 02:10:13,990
It turns out, in C and in other languages,
2888
02:10:13,990 --> 02:10:16,270
you can protect yourself against yourself.
2889
02:10:16,270 --> 02:10:19,370
If you know that a variable should never change its value,
2890
02:10:19,370 --> 02:10:23,050
it should always stay 3 in this case, you can use what's called a constant,
2891
02:10:23,050 --> 02:10:26,360
where you can specifically say, I don't want just n to be an int.
2892
02:10:26,360 --> 02:10:30,500
I want it to be a const int, "const" for short for "constant."
2893
02:10:30,500 --> 02:10:33,830
And this means even if I try to change n in my code,
2894
02:10:33,830 --> 02:10:35,680
the compiler will not let me.
2895
02:10:35,680 --> 02:10:38,650
So I can protect myself from myself, or in the real world,
2896
02:10:38,650 --> 02:10:41,200
you can use a variable that none of your colleagues
2897
02:10:41,200 --> 02:10:46,700
can foolishly change on you without you realizing that it has happened.
2898
02:10:46,700 --> 02:10:49,702
So a lot of programming, honestly, is just not
2899
02:10:49,702 --> 02:10:52,910
trusting yourself the next morning when you've forgotten what code you wrote,
2900
02:10:52,910 --> 02:10:54,743
let alone the next month, the next year when
2901
02:10:54,743 --> 02:10:56,390
you're writing code in the real world.
2902
02:10:56,390 --> 02:11:00,520
So constants just give us a feature to defend against ourselves.
2903
02:11:00,520 --> 02:11:02,270
There's another feature that's useful too,
2904
02:11:02,270 --> 02:11:04,510
especially when you wake up the next day and you're like, oh, my god,
2905
02:11:04,510 --> 02:11:05,600
how does this code work?
2906
02:11:05,600 --> 02:11:06,440
What does it do?
2907
02:11:06,440 --> 02:11:08,040
Well, there's comments in code.
2908
02:11:08,040 --> 02:11:10,040
And some of you might have used this in Scratch.
2909
02:11:10,040 --> 02:11:12,832
You could add little yellow sticky notes in Scratch for "comments."
2910
02:11:12,832 --> 02:11:15,250
In code, you can do something like this.
2911
02:11:15,250 --> 02:11:18,720
You can, if you want to put an English reminder to yourself,
2912
02:11:18,720 --> 02:11:21,630
or if you speak some other human language-- a comment in Spanish
2913
02:11:21,630 --> 02:11:24,850
or any other human language-- you can write it with a slash
2914
02:11:24,850 --> 02:11:26,380
slash at the start of the line.
2915
02:11:26,380 --> 02:11:31,350
And then you can say something like, print n rows.
2916
02:11:31,350 --> 02:11:36,510
And then this tells you, in a comment, what those subsequent lines of code
2917
02:11:36,510 --> 02:11:37,060
are doing.
2918
02:11:37,060 --> 02:11:38,260
It's sort of a note-to-self.
2919
02:11:38,260 --> 02:11:41,110
It has no functionality for the computer's sake.
2920
02:11:41,110 --> 02:11:43,180
It just is a note to yourself.
2921
02:11:43,180 --> 02:11:46,560
Or you can say something like this, like never change n,
2922
02:11:46,560 --> 02:11:48,880
because you're making clear that it's indeed constant.
2923
02:11:48,880 --> 02:11:53,080
But that, too, is a little pedantic since const says the same.
2924
02:11:53,080 --> 02:11:56,730
But comments are notes to self to help you remember what something is doing
2925
02:11:56,730 --> 02:11:59,710
or why you did it this way.
2926
02:11:59,710 --> 02:12:06,280
Questions now on any of these Mario problems that we have solved?
2927
02:12:06,280 --> 02:12:08,900
2928
02:12:08,900 --> 02:12:10,091
No?
2929
02:12:10,091 --> 02:12:12,418
All right, so one final set of examples that
2930
02:12:12,418 --> 02:12:14,460
push the limit of what computers can actually do.
2931
02:12:14,460 --> 02:12:16,585
Thus far, we've solved every problem I've proposed.
2932
02:12:16,585 --> 02:12:18,460
But that's because I've kind of been skirting
2933
02:12:18,460 --> 02:12:19,950
some of the underlying challenges.
2934
02:12:19,950 --> 02:12:22,460
So it turns out that we have not only functions that give us
2935
02:12:22,460 --> 02:12:24,240
side effects visually on the screen.
2936
02:12:24,240 --> 02:12:26,370
We again have functions that have return values.
2937
02:12:26,370 --> 02:12:29,870
So let's focus on those and where things can go wrong.
2938
02:12:29,870 --> 02:12:31,940
And let's use a bunch of other operators as well.
2939
02:12:31,940 --> 02:12:35,190
Suffice it to say, computers got their start by being really good calculators.
2940
02:12:35,190 --> 02:12:38,510
So computers support addition, subtraction, multiplication, division,
2941
02:12:38,510 --> 02:12:42,020
remainder operators, represented by the percent sign
2942
02:12:42,020 --> 02:12:45,150
here, which says take the remainder of something over something else.
2943
02:12:45,150 --> 02:12:47,130
And there's even more operators than this.
2944
02:12:47,130 --> 02:12:49,550
So let's go ahead and implement our own calculator
2945
02:12:49,550 --> 02:12:53,340
of sorts that actually has some bugs along the way.
2946
02:12:53,340 --> 02:12:55,500
Let me go back over to VS Code here.
2947
02:12:55,500 --> 02:12:59,210
I'll close mario.c, open my terminal, and code up
2948
02:12:59,210 --> 02:13:02,180
one final file called calculator.c.
2949
02:13:02,180 --> 02:13:05,810
And in this calculator file, let's go ahead and do something super simple
2950
02:13:05,810 --> 02:13:06,630
initially.
2951
02:13:06,630 --> 02:13:09,190
Let's go ahead and include CS50.h.
2952
02:13:09,190 --> 02:13:11,700
Let's include standard io.h.
2953
02:13:11,700 --> 02:13:15,000
Let's do int meow(void), as always-- all boilerplate thus far.
2954
02:13:15,000 --> 02:13:20,010
And now let's do something more interesting-- int x equals get_int.
2955
02:13:20,010 --> 02:13:22,660
And we'll prompt the user for an x value.
2956
02:13:22,660 --> 02:13:26,730
int y-- prompt the user for a y value, as we've
2957
02:13:26,730 --> 02:13:28,630
done previously for comparing numbers.
2958
02:13:28,630 --> 02:13:30,370
And let's just do something super simple.
2959
02:13:30,370 --> 02:13:34,000
Let's give myself another variable, int z equals x plus y.
2960
02:13:34,000 --> 02:13:35,710
And then let's print out the sum.
2961
02:13:35,710 --> 02:13:38,680
So printf, quote, unquote--
2962
02:13:38,680 --> 02:13:39,960
and I don't percent s here.
2963
02:13:39,960 --> 02:13:42,520
If I want to print out a number-- someone said it earlier--
2964
02:13:42,520 --> 02:13:46,680
we want percent s for string but percent i for integer.
2965
02:13:46,680 --> 02:13:50,100
Backslash n, and print out the value of z.
2966
02:13:50,100 --> 02:13:52,300
So it's a little silly, this calculator.
2967
02:13:52,300 --> 02:13:53,740
It just adds two numbers together.
2968
02:13:53,740 --> 02:13:55,690
But it's going to demonstrate some points.
2969
02:13:55,690 --> 02:13:58,230
So make calculator, Enter.
2970
02:13:58,230 --> 02:14:00,730
So far, so good-- "./calculator."
2971
02:14:00,730 --> 02:14:04,750
Let's just say x is 1, y is 2, z is going to be 3.
2972
02:14:04,750 --> 02:14:07,150
This code is correct, simple though it is.
2973
02:14:07,150 --> 02:14:11,190
Is there an opportunity for marginally better design?
2974
02:14:11,190 --> 02:14:13,170
Could we tighten this up, make it shorter?
2975
02:14:13,170 --> 02:14:16,990
Fewer lines means lower probability of bugs, probably.
2976
02:14:16,990 --> 02:14:18,494
Yeah.
2977
02:14:18,494 --> 02:14:22,052
AUDIENCE: You don't need to provide a separate variable z.
2978
02:14:22,052 --> 02:14:24,760
DAVID J. MALAN: Yeah, we don't really need a separate variable z.
2979
02:14:24,760 --> 02:14:27,842
I mean, it's fine if it's clearer to you, if it's clearer to your TF,
2980
02:14:27,842 --> 02:14:29,300
if it's clearer to your colleagues.
2981
02:14:29,300 --> 02:14:32,980
But honestly, this is so relatively simple, I think we just get rid of z
2982
02:14:32,980 --> 02:14:35,780
and just say something like x plus y here,
2983
02:14:35,780 --> 02:14:38,470
which is totally reasonable as well.
2984
02:14:38,470 --> 02:14:40,520
But you don't want to take this to an extreme.
2985
02:14:40,520 --> 02:14:43,280
Heck, if we don't need z, do we really need x and y?
2986
02:14:43,280 --> 02:14:45,410
Well, we could do something like this.
2987
02:14:45,410 --> 02:14:46,790
Let me actually-- whoops--
2988
02:14:46,790 --> 02:14:50,020
let me actually delete these lines of code and claim--
2989
02:14:50,020 --> 02:14:53,410
we can do this all in one very pretty one-liner.
2990
02:14:53,410 --> 02:14:59,710
We could do, say, get_int x plus get_int y.
2991
02:14:59,710 --> 02:15:03,580
And notice now, like the join example last time, I'm
2992
02:15:03,580 --> 02:15:06,710
calling get_int once, get_int twice.
2993
02:15:06,710 --> 02:15:10,480
Both of them return a value, which is going to be 1 and 2 respectively
2994
02:15:10,480 --> 02:15:11,810
based on what I typed earlier.
2995
02:15:11,810 --> 02:15:13,660
Then I'm doing 1 plus 2.
2996
02:15:13,660 --> 02:15:16,360
That's going into printf as the second argument.
2997
02:15:16,360 --> 02:15:18,410
This is actually correct and will work.
2998
02:15:18,410 --> 02:15:19,510
This is just stupid.
2999
02:15:19,510 --> 02:15:20,290
Don't do this.
3000
02:15:20,290 --> 02:15:24,780
We've crossed some ill-defined line where this is just harder now to read.
3001
02:15:24,780 --> 02:15:28,850
And so even though the variables aren't strictly necessary, I would argue,
3002
02:15:28,850 --> 02:15:32,930
and I think most programmers would argue, this is just much more readable.
3003
02:15:32,930 --> 02:15:34,890
Each line is doing a little bit less work.
3004
02:15:34,890 --> 02:15:36,420
There's less chance for error.
3005
02:15:36,420 --> 02:15:38,130
It just makes a little more sense.
3006
02:15:38,130 --> 02:15:39,870
But reasonable people will disagree.
3007
02:15:39,870 --> 02:15:44,695
So therefore, this is to say, over time, too, you and your TF might disagree.
3008
02:15:44,695 --> 02:15:46,320
You and your colleagues might disagree.
3009
02:15:46,320 --> 02:15:48,830
And at that point is when the religious debates kick in
3010
02:15:48,830 --> 02:15:51,950
as to which way is the right way.
3011
02:15:51,950 --> 02:15:53,490
All right, so that's one calculator.
3012
02:15:53,490 --> 02:15:56,730
Let's do something else that maybe just doubles a number here.
3013
02:15:56,730 --> 02:16:00,435
So let me change this to just get one integer from the user.
3014
02:16:00,435 --> 02:16:01,310
Let's just call it x.
3015
02:16:01,310 --> 02:16:03,000
And let's just double it quite simply.
3016
02:16:03,000 --> 02:16:08,722
So printf, percent i, backslash n, x times 2.
3017
02:16:08,722 --> 02:16:09,930
We'll quite simply double it.
3018
02:16:09,930 --> 02:16:12,780
The star operator is indeed multiplication in this case.
3019
02:16:12,780 --> 02:16:14,880
So that's going to go ahead and double my number.
3020
02:16:14,880 --> 02:16:18,440
So make calculator again, "./calculator."
3021
02:16:18,440 --> 02:16:19,280
Enter.
3022
02:16:19,280 --> 02:16:20,720
And let's go ahead and type in 1.
3023
02:16:20,720 --> 02:16:21,590
And I get back 2.
3024
02:16:21,590 --> 02:16:22,590
Let's run it again.
3025
02:16:22,590 --> 02:16:24,497
Type in 2, I get back 4.
3026
02:16:24,497 --> 02:16:25,080
Type it again.
3027
02:16:25,080 --> 02:16:26,070
Let's type in 3.
3028
02:16:26,070 --> 02:16:28,260
I get back 6, and so forth.
3029
02:16:28,260 --> 02:16:31,530
All right, so that's not bad in this case here.
3030
02:16:31,530 --> 02:16:35,700
But what if we actually want to write a proper program here?
3031
02:16:35,700 --> 02:16:38,030
In fact, yeah, let's see.
3032
02:16:38,030 --> 02:16:40,170
This is sort of a meme that comes and goes.
3033
02:16:40,170 --> 02:16:42,420
Let me see if you recognize this.
3034
02:16:42,420 --> 02:16:44,969
I'm going to go ahead and say another variable-- not x.
3035
02:16:44,969 --> 02:16:47,700
Let's be more specific, like int dollars equals 1.
3036
02:16:47,700 --> 02:16:50,070
And then let me deliberately induce an infinite loop.
3037
02:16:50,070 --> 02:16:54,469
Sometimes it is useful to induce an infinite loop so long as you eventually
3038
02:16:54,469 --> 02:16:58,110
break out of it somehow if you don't want the program to run forever.
3039
02:16:58,110 --> 02:17:02,000
I'm going to ask the user a question asking them for a char c using get_char.
3040
02:17:02,000 --> 02:17:06,559
And I'm going to ask them, quote, unquote, "Here's percent i."
3041
02:17:06,559 --> 02:17:07,520
Period.
3042
02:17:07,520 --> 02:17:11,639
"Double it and give it to the next person?"
3043
02:17:11,639 --> 02:17:12,809
Question mark.
3044
02:17:12,809 --> 02:17:13,980
This is ringing a bell.
3045
02:17:13,980 --> 02:17:17,968
And then we can pass in to get_char the dollars value there.
3046
02:17:17,968 --> 02:17:20,010
So actually, this looks a little cryptic already.
3047
02:17:20,010 --> 02:17:21,410
I'm going to put a dollar sign in front of it
3048
02:17:21,410 --> 02:17:23,719
as though we're actually dealing with US currency.
3049
02:17:23,719 --> 02:17:24,840
And what do we want to do?
3050
02:17:24,840 --> 02:17:29,100
How about if the user says y for yes--
3051
02:17:29,100 --> 02:17:31,020
double it and give it to the next person--
3052
02:17:31,020 --> 02:17:32,990
then let's go ahead and do dollars.
3053
02:17:32,990 --> 02:17:34,459
And let's double "dollar."
3054
02:17:34,459 --> 02:17:37,139
So I can do dollars equals dollars times 2.
3055
02:17:37,139 --> 02:17:40,049
Or recall the trick for plus and minus.
3056
02:17:40,049 --> 02:17:45,209
I can also do times equals 2, which just doubles it in one line as well.
3057
02:17:45,209 --> 02:17:47,870
Just a little syntactic sugar, as programmers call it,
3058
02:17:47,870 --> 02:17:51,209
that just tighten up your code even though it's the exact same thing.
3059
02:17:51,209 --> 02:17:54,590
But what if the user does not type y and they want to keep the money?
3060
02:17:54,590 --> 02:17:56,240
Well, we have an else condition.
3061
02:17:56,240 --> 02:17:58,519
At that point, you don't want to keep asking, asking,
3062
02:17:58,519 --> 02:18:00,320
asking them with get_char.
3063
02:18:00,320 --> 02:18:03,299
Let's just break out of this loop instead.
3064
02:18:03,299 --> 02:18:07,080
So break is another keyword that if you're inside of a for loop, a while
3065
02:18:07,080 --> 02:18:10,280
loop, a do-while loop, you can forcibly break out of the loop
3066
02:18:10,280 --> 02:18:12,990
early if and when you want to.
3067
02:18:12,990 --> 02:18:16,607
And so this satisfies the goal of making sure that this doesn't run forever,
3068
02:18:16,607 --> 02:18:19,190
but it is going to run again and again and again while we keep
3069
02:18:19,190 --> 02:18:20,969
prompting the user with this question.
3070
02:18:20,969 --> 02:18:25,070
So let's see now what happens except, at the end, let's go ahead
3071
02:18:25,070 --> 02:18:28,139
and make sure the user knows how much money they're walking away with.
3072
02:18:28,139 --> 02:18:32,184
Here's dollar sign, percent i, backslash n, dollars.
3073
02:18:32,184 --> 02:18:35,059
So we will see, at the end of this, whatever dollar amount the person
3074
02:18:35,059 --> 02:18:36,110
ends up with.
3075
02:18:36,110 --> 02:18:38,540
Make calculator, Enter.
3076
02:18:38,540 --> 02:18:40,190
"./calculator."
3077
02:18:40,190 --> 02:18:42,450
And let me increase my terminal window size.
3078
02:18:42,450 --> 02:18:43,200
So here we go.
3079
02:18:43,200 --> 02:18:43,730
"Here's $1.
3080
02:18:43,730 --> 02:18:45,480
Double it and give it to the next person?"
3081
02:18:45,480 --> 02:18:46,230
Yes.
3082
02:18:46,230 --> 02:18:47,030
"Here's $2.
3083
02:18:47,030 --> 02:18:48,780
Double it and give it to the next person?"
3084
02:18:48,780 --> 02:18:52,219
Yes, yes, yes, yes, yes.
3085
02:18:52,219 --> 02:18:54,809
So the Instagram Reels aren't that long.
3086
02:18:54,809 --> 02:18:56,730
But if you keep doubling it again and again,
3087
02:18:56,730 --> 02:18:59,660
this is called exponentiation, which will make you quite wealthy
3088
02:18:59,660 --> 02:19:03,260
quite quickly because, notice, we're already in the thousands of dollars
3089
02:19:03,260 --> 02:19:05,040
by just saying yes and yes and yes.
3090
02:19:05,040 --> 02:19:07,400
It's an interesting societal question as to what
3091
02:19:07,400 --> 02:19:10,650
dollar amount you would keep the money and no longer double it and pass it on.
3092
02:19:10,650 --> 02:19:13,192
But for now, we'll just keep doubling it because this is just
3093
02:19:13,192 --> 02:19:17,250
getting bigger and bigger, seemingly infinitely large And the C program--
3094
02:19:17,250 --> 02:19:21,450
but, oh, my god, apparently the Instagram Reels
3095
02:19:21,450 --> 02:19:26,240
cut off the meme too short because eventually it goes negative and then 0.
3096
02:19:26,240 --> 02:19:29,270
What's actually going on here?
3097
02:19:29,270 --> 02:19:31,290
The code is actually correct.
3098
02:19:31,290 --> 02:19:35,100
But we're bumping up against a different kind of problem.
3099
02:19:35,100 --> 02:19:38,160
Any instinct for what is actually going wrong here?
3100
02:19:38,160 --> 02:19:39,790
It's not doubling forever.
3101
02:19:39,790 --> 02:19:40,400
Yeah.
3102
02:19:40,400 --> 02:19:42,225
AUDIENCE: There's not enough bits to store.
3103
02:19:42,225 --> 02:19:45,600
DAVID J. MALAN: Yeah, there's not enough bits to store bigger and bigger numbers.
3104
02:19:45,600 --> 02:19:49,140
Recall, with 32 bits, which happens to be how big most ints are,
3105
02:19:49,140 --> 02:19:52,430
you can count as high as 4 billion if you start at 0 or roughly
3106
02:19:52,430 --> 02:19:55,220
as high as 2 billion if you want to handle negative numbers as
3107
02:19:55,220 --> 02:19:57,480
well, negative 2 billion to positive 2 billion.
3108
02:19:57,480 --> 02:20:01,850
So eventually, once I get to $2 billion, or $1 billion, it goes negative.
3109
02:20:01,850 --> 02:20:03,920
And then it just goes to 0 altogether.
3110
02:20:03,920 --> 02:20:06,560
This is because of something called integer overflow,
3111
02:20:06,560 --> 02:20:11,070
whereby if you only have a finite number of bits and you keep incrementing them,
3112
02:20:11,070 --> 02:20:14,510
incrementing them, incrementing them, eventually you can't just carry the 1
3113
02:20:14,510 --> 02:20:16,620
because there's no 33rd bit.
3114
02:20:16,620 --> 02:20:20,330
So all of the other bits wrap around from ones to zeros.
3115
02:20:20,330 --> 02:20:26,150
And it looks like all 32 of your bits are 0 because the 33rd bit was supposed
3116
02:20:26,150 --> 02:20:27,850
to be the 1, but it's not there.
3117
02:20:27,850 --> 02:20:29,340
They don't have enough memory.
3118
02:20:29,340 --> 02:20:33,890
So this is a fundamental problem with computers whereby if you count high
3119
02:20:33,890 --> 02:20:38,960
enough, things will just start to break, at least if you're using C or C++
3120
02:20:38,960 --> 02:20:41,690
or certain other languages that don't anticipate this.
3121
02:20:41,690 --> 02:20:43,660
And there's a very real implication of this.
3122
02:20:43,660 --> 02:20:47,070
So here's a photograph of something we'll look at more in time
3123
02:20:47,070 --> 02:20:49,350
to come of memory inside of your computer
3124
02:20:49,350 --> 02:20:51,250
or phone or any electronic device.
3125
02:20:51,250 --> 02:20:54,010
Suffice it to say, there's only a finite amount of memory.
3126
02:20:54,010 --> 02:20:58,210
And if you're only using 32 bits then, or heck even three bits,
3127
02:20:58,210 --> 02:20:59,942
you will eventually overflow.
3128
02:20:59,942 --> 02:21:01,150
We used three bits last week.
3129
02:21:01,150 --> 02:21:02,025
So here's an example.
3130
02:21:02,025 --> 02:21:06,120
In binary, if you're only using three bits, per the white digits here--
3131
02:21:06,120 --> 02:21:10,260
I've put in gray the fourth just to show you what carry we might want to have--
3132
02:21:10,260 --> 02:21:17,183
here's 0, 1, 2, 3, 4, 5, 4, 7, just like last week.
3133
02:21:17,183 --> 02:21:19,600
And just like last week, someone said, how do we get to 8?
3134
02:21:19,600 --> 02:21:20,920
We need another bit.
3135
02:21:20,920 --> 02:21:24,310
But if that bit is grayed out because it doesn't exist,
3136
02:21:24,310 --> 02:21:29,170
we've just overflowed this tiny integer and gotten back to 0,
3137
02:21:29,170 --> 02:21:32,830
just like my money went to $0 instead.
3138
02:21:32,830 --> 02:21:35,430
So how do we actually avoid that?
3139
02:21:35,430 --> 02:21:36,760
One way to do this is this.
3140
02:21:36,760 --> 02:21:39,040
Let me hit Control-C to break out of the program.
3141
02:21:39,040 --> 02:21:40,240
Or I could just type "no."
3142
02:21:40,240 --> 02:21:43,660
Let me shrink my terminal window and clear it here.
3143
02:21:43,660 --> 02:21:45,670
I could actually do this.
3144
02:21:45,670 --> 02:21:48,682
It turns out that ints use 32 bits typically.
3145
02:21:48,682 --> 02:21:51,390
But there's another data type that was on the slide before called
3146
02:21:51,390 --> 02:21:54,390
long, which is a longer version of an int, which
3147
02:21:54,390 --> 02:21:57,330
is 64 bits, which is crazy big.
3148
02:21:57,330 --> 02:21:59,290
There's not that many dollars in the world.
3149
02:21:59,290 --> 02:22:03,010
But it's still finite, even though I can't pronounce a number that big.
3150
02:22:03,010 --> 02:22:06,420
But if we change all of our ints to longs
3151
02:22:06,420 --> 02:22:11,400
and we change our placeholder from percent i to percent li, for long int,
3152
02:22:11,400 --> 02:22:13,780
I can actually count higher and higher.
3153
02:22:13,780 --> 02:22:16,290
So case in point, let me actually go back to my terminal--
3154
02:22:16,290 --> 02:22:18,840
make calculator, Enter.
3155
02:22:18,840 --> 02:22:20,380
Make it larger again--
3156
02:22:20,380 --> 02:22:21,820
"./calculator."
3157
02:22:21,820 --> 02:22:24,360
And I'm just going to keep saying yes but faster this time.
3158
02:22:24,360 --> 02:22:25,990
The sequence is exactly the same.
3159
02:22:25,990 --> 02:22:28,000
But recall that once we got into the billions,
3160
02:22:28,000 --> 02:22:30,400
it started to wrap to negative and then 0.
3161
02:22:30,400 --> 02:22:31,950
This is a lot of money now.
3162
02:22:31,950 --> 02:22:33,810
Longs are indeed longer.
3163
02:22:33,810 --> 02:22:36,130
And I could do this probably all day long.
3164
02:22:36,130 --> 02:22:38,070
Oh, interesting.
3165
02:22:38,070 --> 02:22:39,780
I shouldn't have said that.
3166
02:22:39,780 --> 02:22:42,823
Can't do this all day long because eventually a long, too, will overflow.
3167
02:22:42,823 --> 02:22:45,490
[WHISPERS] I just didn't think it was going to happen that fast.
3168
02:22:45,490 --> 02:22:48,910
So a long, too, will overflow because we'll need a 65th bit,
3169
02:22:48,910 --> 02:22:51,130
but the computer has not allocated it.
3170
02:22:51,130 --> 02:22:53,800
So that, too, becomes an issue of overflow.
3171
02:22:53,800 --> 02:22:56,920
To read an excerpt, these are very real world issues.
3172
02:22:56,920 --> 02:23:01,080
And in fact, here's a photograph of a Boeing 787 years ago
3173
02:23:01,080 --> 02:23:04,840
that actually had issues beyond the most recent issues with Boeing airplanes,
3174
02:23:04,840 --> 02:23:10,260
whereby after 248 days, the Boeing 787, years ago, can
3175
02:23:10,260 --> 02:23:14,130
lose all of its electrical power due to the generator control
3176
02:23:14,130 --> 02:23:17,560
units simultaneously going into failsafe mode, whatever that means.
3177
02:23:17,560 --> 02:23:20,490
But if you dig into this, it turns out that there
3178
02:23:20,490 --> 02:23:23,790
was a software counter in these airplanes years ago
3179
02:23:23,790 --> 02:23:28,750
that would overflow after 248 days of continuous power.
3180
02:23:28,750 --> 02:23:30,240
248 days, why?
3181
02:23:30,240 --> 02:23:32,820
Well, Boeing was using a 32-bit integer.
3182
02:23:32,820 --> 02:23:36,070
And they were using it to count tenths of seconds.
3183
02:23:36,070 --> 02:23:40,600
And it turns out, if you do the math, after 248 days,
3184
02:23:40,600 --> 02:23:45,630
you have used too many tenths such that you overflow the size of a 32-bit
3185
02:23:45,630 --> 02:23:46,240
integer.
3186
02:23:46,240 --> 02:23:48,190
The plane would essentially have this integer,
3187
02:23:48,190 --> 02:23:50,560
this tiny, stupid little variable, overflow.
3188
02:23:50,560 --> 02:23:53,500
But generally speaking, when your numbers suddenly go negative or 0,
3189
02:23:53,500 --> 02:23:54,520
bad things happen.
3190
02:23:54,520 --> 02:23:58,333
The plane could literally lose its power mid-flight or on the ground.
3191
02:23:58,333 --> 02:24:01,500
And if you can believe it, anyone want to guess what Boeing's workaround was
3192
02:24:01,500 --> 02:24:03,694
till they fixed the actual software?
3193
02:24:03,694 --> 02:24:05,350
AUDIENCE: [INAUDIBLE]
3194
02:24:05,350 --> 02:24:06,050
What's that?
3195
02:24:06,050 --> 02:24:07,760
AUDIENCE: [? It's for ?] [INAUDIBLE].
3196
02:24:07,760 --> 02:24:09,980
DAVID J. MALAN: Not even-- reboot the plane.
3197
02:24:09,980 --> 02:24:13,660
They were told, every few days, certainly every 248 days,
3198
02:24:13,660 --> 02:24:16,813
turn the power off, turn it back on, which, stupidly, is what all of us
3199
02:24:16,813 --> 02:24:19,230
have been told for years with our Macs and PCs and phones.
3200
02:24:19,230 --> 02:24:19,730
Why?
3201
02:24:19,730 --> 02:24:22,410
Because sometimes, because of bugs and software,
3202
02:24:22,410 --> 02:24:26,270
computers get into funky states, which is a colloquial way of saying
3203
02:24:26,270 --> 02:24:30,230
some programmer made a mistake and some counter overflowed or some condition
3204
02:24:30,230 --> 02:24:33,600
wasn't handled and just weird, unexpected things happen.
3205
02:24:33,600 --> 02:24:37,520
So rebooting just resets all of your variables back to their original values
3206
02:24:37,520 --> 02:24:42,342
and gives you more time, more runway in this case, no pun intended.
3207
02:24:42,342 --> 02:24:43,050
There are others.
3208
02:24:43,050 --> 02:24:46,160
In fact, one of the most famous ones from the 1980s was the original Pac-Man
3209
02:24:46,160 --> 02:24:46,680
game--
3210
02:24:46,680 --> 02:24:49,500
only had support for 255 levels.
3211
02:24:49,500 --> 02:24:50,000
Why?
3212
02:24:50,000 --> 02:24:51,370
They were using 8 bits.
3213
02:24:51,370 --> 02:24:53,610
Recall that 8 bits gives you 256.
3214
02:24:53,610 --> 02:24:56,280
But if you start counting at 0, you can only go to 255.
3215
02:24:56,280 --> 02:24:58,460
So the crazy kids who were so good at Pac-Man
3216
02:24:58,460 --> 02:25:03,020
that they got to level 256, the makers of Pac-Man
3217
02:25:03,020 --> 02:25:06,450
did not anticipate that anyone was going to win that many levels.
3218
02:25:06,450 --> 02:25:08,740
And just weird stuff happened on the screen.
3219
02:25:08,740 --> 02:25:12,060
All of the fruit started overwriting everything because they didn't have
3220
02:25:12,060 --> 02:25:15,900
enough memory allocated to the level, nor did they have a condition that says,
3221
02:25:15,900 --> 02:25:19,710
if level equals equals 255, "you win."
3222
02:25:19,710 --> 02:25:22,960
There was just nothing handling that corner case, so to speak.
3223
02:25:22,960 --> 02:25:25,270
So these things abound even these days.
3224
02:25:25,270 --> 02:25:28,530
Thankfully, in some languages, there are better solutions
3225
02:25:28,530 --> 02:25:30,630
where you can use big integers.
3226
02:25:30,630 --> 02:25:35,380
And you'll just use 64, maybe 128, maybe 256 bits.
3227
02:25:35,380 --> 02:25:38,010
But you need to use a language or a library that
3228
02:25:38,010 --> 02:25:41,110
allows you to grow and shrink the amount of memory being used.
3229
02:25:41,110 --> 02:25:45,310
And many, if not most languages, do not do that for us.
3230
02:25:45,310 --> 02:25:49,110
So there's a few final problems to see that we've been taking for granted
3231
02:25:49,110 --> 02:25:49,870
thus far.
3232
02:25:49,870 --> 02:25:53,350
And they also involve numbers and memory.
3233
02:25:53,350 --> 02:25:55,030
So let's go back into our calculator.
3234
02:25:55,030 --> 02:25:57,150
Let's throw away all of this meme code here.
3235
02:25:57,150 --> 02:26:00,850
And instead, let's go ahead and do something simple again.
3236
02:26:00,850 --> 02:26:02,970
int x equals get_int.
3237
02:26:02,970 --> 02:26:06,300
And prompt the user for a variable x. int y equals get_int,
3238
02:26:06,300 --> 02:26:08,260
prompt the user for a variable y.
3239
02:26:08,260 --> 02:26:12,490
And this time, instead of addition, instead of doubling, let's do division.
3240
02:26:12,490 --> 02:26:16,230
So printf, quote, unquote, percent i backslash n.
3241
02:26:16,230 --> 02:26:19,060
And then plug in x divided by y.
3242
02:26:19,060 --> 02:26:21,610
So you use a single forward slash for division.
3243
02:26:21,610 --> 02:26:25,500
Let me go ahead and, make calculator down here, "./calculator."
3244
02:26:25,500 --> 02:26:31,860
And let's go ahead and do 1 divided by 3, which should, in fact, be--
3245
02:26:31,860 --> 02:26:33,460
it's not really 0.
3246
02:26:33,460 --> 02:26:35,890
It's like 0.333.
3247
02:26:35,890 --> 02:26:36,820
Let's try this again.
3248
02:26:36,820 --> 02:26:39,540
How about "./calculator" 3 divided by 2?
3249
02:26:39,540 --> 02:26:41,440
Should be 1.5.
3250
02:26:41,440 --> 02:26:43,890
Nope, computer thinks it's 1.
3251
02:26:43,890 --> 02:26:45,310
Well, what's happening here?
3252
02:26:45,310 --> 02:26:48,790
Well, it turns out, when you're using integers in a program,
3253
02:26:48,790 --> 02:26:51,430
you are vulnerable to what's called truncation.
3254
02:26:51,430 --> 02:26:54,130
An integer plus an integer gives you an integer.
3255
02:26:54,130 --> 02:26:58,540
An integer divided by an integer, funny enough, gives you an integer.
3256
02:26:58,540 --> 02:27:04,060
So even if the answer is supposed to be 0.333 or 1.5,
3257
02:27:04,060 --> 02:27:08,040
everything in the world of integers throws away the decimal point onward.
3258
02:27:08,040 --> 02:27:11,080
And you only get the integer part of the value.
3259
02:27:11,080 --> 02:27:12,280
So it's not even rounding.
3260
02:27:12,280 --> 02:27:14,980
It's truncating everything after the decimal.
3261
02:27:14,980 --> 02:27:16,930
So this program is just not correct.
3262
02:27:16,930 --> 02:27:19,090
But there are solutions potentially.
3263
02:27:19,090 --> 02:27:21,750
For instance, if I go back into my code here
3264
02:27:21,750 --> 02:27:24,370
and I use a different format code we haven't used yet--
3265
02:27:24,370 --> 02:27:26,710
we had s for string, i for int.
3266
02:27:26,710 --> 02:27:28,590
There's also f for float.
3267
02:27:28,590 --> 02:27:32,860
And a float was like a real number, something with a decimal point in it
3268
02:27:32,860 --> 02:27:33,480
by definition.
3269
02:27:33,480 --> 02:27:34,930
We just haven't used it yet.
3270
02:27:34,930 --> 02:27:37,360
I could tell the computer to print this as a float.
3271
02:27:37,360 --> 02:27:39,700
So let me do make calculator again.
3272
02:27:39,700 --> 02:27:42,220
And now, hm, it's specifying type double.
3273
02:27:42,220 --> 02:27:43,420
There's an error here.
3274
02:27:43,420 --> 02:27:45,780
The problem is that I can't just tell the computer
3275
02:27:45,780 --> 02:27:48,550
to format this number as a float.
3276
02:27:48,550 --> 02:27:53,160
I need to convert the number, x divided by y, to a float.
3277
02:27:53,160 --> 02:27:55,030
And I can do this in a couple of ways.
3278
02:27:55,030 --> 02:27:57,330
One, I could literally change all of this to floats
3279
02:27:57,330 --> 02:27:59,110
and just avoid the problem altogether.
3280
02:27:59,110 --> 02:28:02,290
Use float, use get_float, use percent f, and I'm done.
3281
02:28:02,290 --> 02:28:04,777
But if I want to use ints for whatever reason--
3282
02:28:04,777 --> 02:28:06,610
because I want the user to type in integers,
3283
02:28:06,610 --> 02:28:10,930
but I want to show them real numbers with decimal points for correct math--
3284
02:28:10,930 --> 02:28:13,990
I can do what's called casting a value.
3285
02:28:13,990 --> 02:28:17,470
I can, in parentheses-- which is a weird new use of parentheses--
3286
02:28:17,470 --> 02:28:22,140
I can say, hey, computer, please treat the following integer as a float
3287
02:28:22,140 --> 02:28:25,810
instead, thereby avoiding truncation.
3288
02:28:25,810 --> 02:28:27,550
Do not truncate for me.
3289
02:28:27,550 --> 02:28:32,040
So if I now run make calculator again, "./calculator,"
3290
02:28:32,040 --> 02:28:35,650
and type in, for instance, 1 for x, 3 for y,
3291
02:28:35,650 --> 02:28:38,620
now I get an actual floating point value.
3292
02:28:38,620 --> 02:28:39,870
I'm formatting it as such.
3293
02:28:39,870 --> 02:28:43,770
And I'm telling the computer to actually arithmetically calculate it
3294
02:28:43,770 --> 02:28:45,570
as such as well.
3295
02:28:45,570 --> 02:28:49,570
But here, too, I'm kind of cheating you of a reality.
3296
02:28:49,570 --> 02:28:52,480
It turns out-- let me clear this screen here.
3297
02:28:52,480 --> 02:28:56,220
And it turns out that there are fancy ways in printf
3298
02:28:56,220 --> 02:29:00,430
to tell it how many digits to show you, how many significant digits.
3299
02:29:00,430 --> 02:29:01,647
And the syntax is very weird.
3300
02:29:01,647 --> 02:29:02,980
I have to look it up constantly.
3301
02:29:02,980 --> 02:29:05,493
But instead of just saying percent f, you literally
3302
02:29:05,493 --> 02:29:06,910
put some numbers in between there.
3303
02:29:06,910 --> 02:29:09,960
And you say point 5.
3304
02:29:09,960 --> 02:29:12,220
And that will say-- it's weird syntax--
3305
02:29:12,220 --> 02:29:15,880
hey, printf, format this to five digits instead.
3306
02:29:15,880 --> 02:29:20,400
So let me go ahead and do make calculator again, "./calculator."
3307
02:29:20,400 --> 02:29:22,500
And let's do 1 divided by 3.
3308
02:29:22,500 --> 02:29:25,780
And indeed, I get five significant digits there.
3309
02:29:25,780 --> 02:29:30,460
But suppose I get a little crazy and I want 50 significant digits.
3310
02:29:30,460 --> 02:29:33,310
Well, according to grade school, I should just see more 3's.
3311
02:29:33,310 --> 02:29:34,200
But watch this.
3312
02:29:34,200 --> 02:29:37,070
Make calculator, "./calculator."
3313
02:29:37,070 --> 02:29:40,320
And it turns out that whoever taught you grade-school math was kind of telling
3314
02:29:40,320 --> 02:29:43,860
you some white lies because if you really do it with a powerful Mac or PC
3315
02:29:43,860 --> 02:29:52,112
or phone, one third is actually 0.3333333334326744079--
3316
02:29:52,112 --> 02:29:54,300
[SIGHS] who's right?
3317
02:29:54,300 --> 02:29:59,670
Mr. and Mrs. So-and-so from grade school or the internet?
3318
02:29:59,670 --> 02:30:00,905
What's going on here?
3319
02:30:00,905 --> 02:30:03,720
3320
02:30:03,720 --> 02:30:05,080
What explains this?
3321
02:30:05,080 --> 02:30:09,710
It all comes down somehow to [? weak ?] zeros and ones.
3322
02:30:09,710 --> 02:30:14,590
Why is this floating point number imprecise, so to speak?
3323
02:30:14,590 --> 02:30:15,590
What's the intuition?
3324
02:30:15,590 --> 02:30:16,090
Yeah.
3325
02:30:16,090 --> 02:30:19,213
AUDIENCE: Is this similar to what happened earlier
3326
02:30:19,213 --> 02:30:20,380
where there was an overflow?
3327
02:30:20,380 --> 02:30:22,047
DAVID J. MALAN: Yeah, similar in spirit.
3328
02:30:22,047 --> 02:30:26,290
Just as ints only use 32 bits, floats also use only 32 bits.
3329
02:30:26,290 --> 02:30:30,530
If you want more, just as int has long, floats have something called "double."
3330
02:30:30,530 --> 02:30:33,530
So I could avoid some of the problem by switching to double.
3331
02:30:33,530 --> 02:30:35,090
But that's still going to be finite.
3332
02:30:35,090 --> 02:30:38,630
And if you think about this intuitively, if you're using a finite number of bits,
3333
02:30:38,630 --> 02:30:43,330
be it 32 or 64, you can only represent literally so many patterns
3334
02:30:43,330 --> 02:30:46,340
and thus so many floating point values, so many real numbers.
3335
02:30:46,340 --> 02:30:48,880
But how many real numbers are there in the world?
3336
02:30:48,880 --> 02:30:52,248
Literally infinitely many, is the challenge of real numbers.
3337
02:30:52,248 --> 02:30:54,290
You can just keep adding numbers after the digit.
3338
02:30:54,290 --> 02:30:57,310
So how could a computer, Mac, PC, or otherwise, possibly
3339
02:30:57,310 --> 02:31:00,620
represent every floating point value super precisely
3340
02:31:00,620 --> 02:31:04,820
if there's not enough patterns to represent every number in the world?
3341
02:31:04,820 --> 02:31:08,020
Moreover, the way that computers use to represent numbers sometimes
3342
02:31:08,020 --> 02:31:10,660
do not allow them to represent numbers so precisely.
3343
02:31:10,660 --> 02:31:13,240
We can get more significant digits maybe, but not
3344
02:31:13,240 --> 02:31:16,190
100% perfection or precision.
3345
02:31:16,190 --> 02:31:21,070
So floating point precision, too, is a fundamental problem with computers
3346
02:31:21,070 --> 02:31:21,570
today.
3347
02:31:21,570 --> 02:31:24,770
And unless, again, you're using a specialized language or library that
3348
02:31:24,770 --> 02:31:28,820
understands, for scientific computing, the implications of overflow
3349
02:31:28,820 --> 02:31:32,880
or imprecision, your code will have mistakes, much like Boeing discovered,
3350
02:31:32,880 --> 02:31:35,040
much like Pac-Man discovered as well.
3351
02:31:35,040 --> 02:31:37,740
And in fact, just to end on a gloom-and-doom note,
3352
02:31:37,740 --> 02:31:40,980
it turns out there's another problem like this on the horizon already.
3353
02:31:40,980 --> 02:31:45,020
So back in my day, everyone was really worried about the Y2K problem, the Year
3354
02:31:45,020 --> 02:31:45,960
2000 problem.
3355
02:31:45,960 --> 02:31:46,460
Why?
3356
02:31:46,460 --> 02:31:48,900
Because for decades, when computers were invented,
3357
02:31:48,900 --> 02:31:51,320
most systems were using just two digits--
3358
02:31:51,320 --> 02:31:53,940
independent of bits-- two digits to represent years.
3359
02:31:53,940 --> 02:31:54,440
Why?
3360
02:31:54,440 --> 02:31:56,820
Computers came out a few decades ago.
3361
02:31:56,820 --> 02:32:00,050
Who'd think that a computer is still going to be running decades later?
3362
02:32:00,050 --> 02:32:02,690
Turns out they were, especially in government and corporations
3363
02:32:02,690 --> 02:32:03,360
and the like.
3364
02:32:03,360 --> 02:32:06,020
But if you're only using two digits to represent years
3365
02:32:06,020 --> 02:32:09,020
and the millennium comes around and it's 1999
3366
02:32:09,020 --> 02:32:14,000
about to roll over, about to roll over, what comes after 1999?
3367
02:32:14,000 --> 02:32:16,830
Well, if you're only using two digits, ideally 2000.
3368
02:32:16,830 --> 02:32:22,080
But if you're only using two digits, the year 0 comes after the year 1999.
3369
02:32:22,080 --> 02:32:25,310
And the whole world, truly-- you can look it up nowadays on Wikipedia--
3370
02:32:25,310 --> 02:32:28,383
was freaking out because there was so much old software in the world that
3371
02:32:28,383 --> 02:32:29,550
could have had this mistake.
3372
02:32:29,550 --> 02:32:30,210
And who knows?
3373
02:32:30,210 --> 02:32:33,620
Planes falling out of the sky, computers rebooting, freezing.
3374
02:32:33,620 --> 02:32:38,058
No one really knew because this was an unhandled situation in code.
3375
02:32:38,058 --> 02:32:40,350
So thankfully, the world actually got its act together.
3376
02:32:40,350 --> 02:32:42,360
The world did not end in the year 2000.
3377
02:32:42,360 --> 02:32:45,960
And most systems were updated in time without crazy horror stories.
3378
02:32:45,960 --> 02:32:50,030
But we're going to have this happen again because it turns out just a few
3379
02:32:50,030 --> 02:32:54,980
years from now, at this point, computers for years have been using 32-bit
3380
02:32:54,980 --> 02:32:59,400
integers to keep track of time in the sense of what time of day it is.
3381
02:32:59,400 --> 02:33:04,132
And the point in time they decided years ago was, like, hey everyone,
3382
02:33:04,132 --> 02:33:05,840
let's just keep track of how many seconds
3383
02:33:05,840 --> 02:33:09,600
have passed since January 1, 1970.
3384
02:33:09,600 --> 02:33:13,620
And we can relatively compute time any time thereafter.
3385
02:33:13,620 --> 02:33:14,317
So that's great.
3386
02:33:14,317 --> 02:33:15,900
That gives us a lot of decades' worth.
3387
02:33:15,900 --> 02:33:20,213
But 32 bits eventually maxes out at, like, 4 billion positive, or 2 billion
3388
02:33:20,213 --> 02:33:21,630
if you want negative and positive.
3389
02:33:21,630 --> 02:33:24,980
And it turns out, if you count the number of seconds between 1970
3390
02:33:24,980 --> 02:33:29,690
on up, on the day January 19, 2038, the world
3391
02:33:29,690 --> 02:33:34,220
might again end because all of these clocks are going to overflow.
3392
02:33:34,220 --> 02:33:37,200
And we're going to end up in the year 0 or negative something.
3393
02:33:37,200 --> 02:33:38,520
Now, what's the solution there?
3394
02:33:38,520 --> 02:33:40,520
I mean, my god, it's the exact same thing.
3395
02:33:40,520 --> 02:33:41,880
Stop using so few bits.
3396
02:33:41,880 --> 02:33:42,510
Use more bits.
3397
02:33:42,510 --> 02:33:45,300
But bits and memory and computers used to be expensive.
3398
02:33:45,300 --> 02:33:47,907
Nowadays, storage is so much more available.
3399
02:33:47,907 --> 02:33:50,990
But among the things we'll discuss then is how you can throw both hardware
3400
02:33:50,990 --> 02:33:52,200
and software at this problem.
3401
02:33:52,200 --> 02:33:56,760
But for now, maybe set a Google Calendar reminder for January 19, 2038.
3402
02:33:56,760 --> 02:33:59,030
And hopefully we'll see you next week.
3403
02:33:59,030 --> 02:34:00,830
[APPLAUSE]
3404
02:34:00,830 --> 02:34:04,430
3405
02:34:04,430 --> 02:34:07,780
[CLASSICAL MUSIC]
3406
02:34:07,780 --> 02:34:31,000
283723
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.