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.