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