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