Would you like to inspect the original subtitles? These are the user uploaded subtitles that are being translated:
0
00:00:00,000 --> 00:00:02,988
[REEL-TO-REEL PLAYER STARTING]
1
00:00:02,988 --> 00:00:05,976
[MUSIC PLAYING]
2
00:00:05,976 --> 00:01:13,350
3
00:01:13,350 --> 00:01:16,090
DAVID J. MALAN: All right, this is CS50.
4
00:01:16,090 --> 00:01:19,090
And this is week 1, wherein we continue programming,
5
00:01:19,090 --> 00:01:22,420
but we do it in a different language because recall last time, we
6
00:01:22,420 --> 00:01:25,060
focused on this graphical language called Scratch.
7
00:01:25,060 --> 00:01:28,360
But we use Scratch, not only because it's sort of fun and accessible,
8
00:01:28,360 --> 00:01:31,750
but because it allows us to explore a lot of these concepts here,
9
00:01:31,750 --> 00:01:35,810
namely functions, and conditionals, Boolean expressions, loops, variables,
10
00:01:35,810 --> 00:01:36,410
and more.
11
00:01:36,410 --> 00:01:41,050
And so, indeed, even if today's syntax, as we transition to this new language
12
00:01:41,050 --> 00:01:44,980
called C, feels a little bit cryptic, maybe a little intimidating at first,
13
00:01:44,980 --> 00:01:48,040
and you don't quite see all of the meaning of the symbols
14
00:01:48,040 --> 00:01:51,310
beyond the syntax itself, realize that the ideas are ultimately
15
00:01:51,310 --> 00:01:52,670
going to be the same.
16
00:01:52,670 --> 00:01:55,870
In fact, as we transition from what was last week--
17
00:01:55,870 --> 00:02:00,017
a Hello World program that looked a little something like this-- this week,
18
00:02:00,017 --> 00:02:02,350
of course, it's going to now look a little more cryptic.
19
00:02:02,350 --> 00:02:04,350
It's going to look a little something like this.
20
00:02:04,350 --> 00:02:06,370
And now even if you can't quite distinguish
21
00:02:06,370 --> 00:02:08,479
what all of the various symbols mean in this code,
22
00:02:08,479 --> 00:02:10,120
it turns out that at the end of the day, it's
23
00:02:10,120 --> 00:02:11,578
indeed going to do what you expect.
24
00:02:11,578 --> 00:02:14,170
It's just going to say, hello, world on the screen,
25
00:02:14,170 --> 00:02:15,370
just like we did in Scratch.
26
00:02:15,370 --> 00:02:19,610
So let's start to apply some terminology to these tokens first.
27
00:02:19,610 --> 00:02:22,332
So what we're about to see, what we're about to write henceforth,
28
00:02:22,332 --> 00:02:24,040
we're going to start calling source code.
29
00:02:24,040 --> 00:02:27,908
Code that you the human programmer write is just henceforth called source code.
30
00:02:27,908 --> 00:02:29,200
Doesn't matter if it's Scratch.
31
00:02:29,200 --> 00:02:32,370
Doesn't matter if it's C. Doesn't matter if it's Python before long.
32
00:02:32,370 --> 00:02:34,120
Source code is the general term for really
33
00:02:34,120 --> 00:02:37,330
what you and I as human programmers will ultimately write.
34
00:02:37,330 --> 00:02:42,190
Of course, computers don't understand source code, it turns out.
35
00:02:42,190 --> 00:02:46,200
Computers don't understand Scratch and Puzzle Pieces, per se, or C code
36
00:02:46,200 --> 00:02:47,200
like we're about to see.
37
00:02:47,200 --> 00:02:49,870
They only understand this, which we called what last week?
38
00:02:49,870 --> 00:02:50,650
AUDIENCE: Zeros and ones.
39
00:02:50,650 --> 00:02:51,525
DAVID J. MALAN: Yeah.
40
00:02:51,525 --> 00:02:53,080
So this is binary, zeros and ones.
41
00:02:53,080 --> 00:02:56,470
But really, it's just information represented in binary.
42
00:02:56,470 --> 00:03:00,370
And in fact, the technical term now for patterns of zeros and ones
43
00:03:00,370 --> 00:03:04,810
that a computer not only understands how to interpret as letters, or numbers,
44
00:03:04,810 --> 00:03:09,520
or colors, or images, or more, but knows how to execute as well henceforth
45
00:03:09,520 --> 00:03:12,880
is going to be called machine code to contrast it with source code.
46
00:03:12,880 --> 00:03:15,160
So whereas you and I, the humans, write source code,
47
00:03:15,160 --> 00:03:18,860
it's the computer that ultimately only understands machine code.
48
00:03:18,860 --> 00:03:21,940
And even though we won't get into the details of exactly what pattern
49
00:03:21,940 --> 00:03:27,010
of symbols means what, you'll see that in this kind of pattern of zeros
50
00:03:27,010 --> 00:03:28,600
and ones, there's going to be numbers.
51
00:03:28,600 --> 00:03:29,530
There's going to be letters.
52
00:03:29,530 --> 00:03:32,200
But there's also going to be instructions because, indeed, computers
53
00:03:32,200 --> 00:03:35,140
are really good at doing things-- addition, subtraction, moving things
54
00:03:35,140 --> 00:03:36,430
in and out of memory.
55
00:03:36,430 --> 00:03:40,720
And suffice it to say that the Macs, the PCs, the other computers of the world
56
00:03:40,720 --> 00:03:44,740
have just decided as a society what certain patterns of zeros and ones
57
00:03:44,740 --> 00:03:48,220
mean when it comes to operations as well-- so not just data,
58
00:03:48,220 --> 00:03:49,200
but instructions.
59
00:03:49,200 --> 00:03:50,950
But those patterns are not something we're
60
00:03:50,950 --> 00:03:52,575
going to focus on in a class like this.
61
00:03:52,575 --> 00:03:55,450
We're going to focus on the higher level software side of things,
62
00:03:55,450 --> 00:03:58,910
simply assuming that we need to somehow output machine code.
63
00:03:58,910 --> 00:04:02,050
So it turns out, then, that this problem we
64
00:04:02,050 --> 00:04:04,300
have to solve getting from source code to machine code
65
00:04:04,300 --> 00:04:07,120
actually fits into the same paradigm as last time.
66
00:04:07,120 --> 00:04:11,230
But the input in this case is going to be source code on the one hand.
67
00:04:11,230 --> 00:04:13,750
That's what you and I ideally will write so that we
68
00:04:13,750 --> 00:04:15,430
don't have to write zeros and ones.
69
00:04:15,430 --> 00:04:18,140
But we need to somehow output machine code
70
00:04:18,140 --> 00:04:19,990
because that's what your Macs, PCs, phones
71
00:04:19,990 --> 00:04:21,730
are actually going to understand.
72
00:04:21,730 --> 00:04:25,390
Well, it turns out there are special programs in life whose purpose is
73
00:04:25,390 --> 00:04:28,690
to do exactly this conversion-- convert the source code you
74
00:04:28,690 --> 00:04:32,320
and I write to the machine code that our phones and computers understand.
75
00:04:32,320 --> 00:04:36,050
And that type of program is going to be called a compiler.
76
00:04:36,050 --> 00:04:39,400
So indeed today, we'll introduce you to another piece of software.
77
00:04:39,400 --> 00:04:40,810
And these come in many forms.
78
00:04:40,810 --> 00:04:45,580
We'll use a popular one here that allows you to convert source code in C
79
00:04:45,580 --> 00:04:48,805
to machine code in zeros and ones.
80
00:04:48,805 --> 00:04:50,680
Now, you didn't have to do this with Scratch.
81
00:04:50,680 --> 00:04:53,513
In the world of Scratch, it was as simple as clicking the green flag
82
00:04:53,513 --> 00:04:57,280
because essentially MIT did all of the heavy lifting there figuring out
83
00:04:57,280 --> 00:05:00,760
how to convert these graphical puzzle pieces to the underlying machine code.
84
00:05:00,760 --> 00:05:04,420
But now starting today, as we begin to study programming and computer science
85
00:05:04,420 --> 00:05:06,550
proper, now that power moves to you.
86
00:05:06,550 --> 00:05:09,340
And it's up to you now to do that kind of conversion.
87
00:05:09,340 --> 00:05:12,160
But thankfully, the fact that these compilers exist
88
00:05:12,160 --> 00:05:14,320
means that you and I don't have to program
89
00:05:14,320 --> 00:05:17,500
in machine code like our ancestors once upon a time did,
90
00:05:17,500 --> 00:05:19,973
be it virtually or with physical punch cards,
91
00:05:19,973 --> 00:05:21,640
like pieces of paper with holes in them.
92
00:05:21,640 --> 00:05:25,810
You and I get to focus on our keyboard, as such.
93
00:05:25,810 --> 00:05:29,370
But it's not just going to be a matter today of writing code.
94
00:05:29,370 --> 00:05:31,120
It's going to be a matter ultimately today
95
00:05:31,120 --> 00:05:32,930
onward of writing good code as well.
96
00:05:32,930 --> 00:05:35,180
And this is the kind of thing that you don't just learn overnight.
97
00:05:35,180 --> 00:05:35,870
It takes time.
98
00:05:35,870 --> 00:05:36,620
It takes practice.
99
00:05:36,620 --> 00:05:38,650
Just like writing an essay in any subject
100
00:05:38,650 --> 00:05:41,050
might take time, and practice, and iteration over time.
101
00:05:41,050 --> 00:05:44,020
But in a programming class like CS50, we're
102
00:05:44,020 --> 00:05:48,820
going to aspire to evaluate the quality of code along these three axes,
103
00:05:48,820 --> 00:05:49,360
generally.
104
00:05:49,360 --> 00:05:51,040
Is it correct, first and foremost?
105
00:05:51,040 --> 00:05:52,810
Does the code do what it's supposed to do?
106
00:05:52,810 --> 00:05:54,460
After all, if it doesn't, well, what was the point
107
00:05:54,460 --> 00:05:55,835
of writing it in the first place?
108
00:05:55,835 --> 00:05:59,350
So it goes without saying that you want code you write to be correct.
109
00:05:59,350 --> 00:06:00,820
And it's obviously not always.
110
00:06:00,820 --> 00:06:03,340
Again, anytime your Mac, or PC, or phone has crashed,
111
00:06:03,340 --> 00:06:05,560
some human somewhere wrote buggy--
112
00:06:05,560 --> 00:06:07,030
that is code with mistakes.
113
00:06:07,030 --> 00:06:10,060
But code correctness is going to be the first and foremost goal.
114
00:06:10,060 --> 00:06:13,930
But then there's a more subjective goal see in time, a matter of design.
115
00:06:13,930 --> 00:06:16,030
And we saw a little bit of this last week
116
00:06:16,030 --> 00:06:19,510
when I proposed that we could design even scratch programs better,
117
00:06:19,510 --> 00:06:22,510
maybe by using loops instead of just by copying and pasting
118
00:06:22,510 --> 00:06:24,170
the same blocks again and again.
119
00:06:24,170 --> 00:06:26,080
So design is more subjective.
120
00:06:26,080 --> 00:06:29,830
It's more of a learned art whereby two people might ultimately
121
00:06:29,830 --> 00:06:32,882
disagree as to which version of a program is better designed.
122
00:06:32,882 --> 00:06:35,840
But we'll give you building blocks and principles over the coming weeks
123
00:06:35,840 --> 00:06:37,840
so that you can have a better sense for yourself
124
00:06:37,840 --> 00:06:40,090
if your own code is well designed.
125
00:06:40,090 --> 00:06:41,530
And why is that valuable?
126
00:06:41,530 --> 00:06:44,980
Well, the better designed your code is, often the faster it's going to run,
127
00:06:44,980 --> 00:06:47,438
the more maintainable it's going to be by you or colleagues
128
00:06:47,438 --> 00:06:49,438
if you're working with others in the real world.
129
00:06:49,438 --> 00:06:50,900
So good design is a good thing.
130
00:06:50,900 --> 00:06:54,490
It helps you communicate your ideas, just like in a typical English essay.
131
00:06:54,490 --> 00:06:57,523
And then lastly, we'll talk this week onward about style.
132
00:06:57,523 --> 00:06:59,690
And this is really just the aesthetics of your code.
133
00:06:59,690 --> 00:07:04,720
It turns out that computers often don't care how sloppy your actual code is,
134
00:07:04,720 --> 00:07:08,920
where in the world of code, it turns out that you don't really need
135
00:07:08,920 --> 00:07:10,750
to indent things in a beautiful way.
136
00:07:10,750 --> 00:07:13,150
You don't need to paginate things like might in an essay.
137
00:07:13,150 --> 00:07:16,390
The computer generally does not care, but the human does.
138
00:07:16,390 --> 00:07:17,817
The teaching assistant does.
139
00:07:17,817 --> 00:07:19,900
You will care the next day when you're just trying
140
00:07:19,900 --> 00:07:21,560
to understand what your code does.
141
00:07:21,560 --> 00:07:24,520
So we'll focus lastly on style, the aesthetics of the code
142
00:07:24,520 --> 00:07:25,520
that you're writing.
143
00:07:25,520 --> 00:07:27,280
So where are we going to write code?
144
00:07:27,280 --> 00:07:28,940
Where are we going to compile code?
145
00:07:28,940 --> 00:07:32,770
So for this class, not only with C, but the other languages we use later
146
00:07:32,770 --> 00:07:35,140
in the term, we're going to use a free text
147
00:07:35,140 --> 00:07:39,280
editor that is program called Visual Studio Code, AKA VS Code.
148
00:07:39,280 --> 00:07:43,450
It's super popular nowadays, not just for C, but for C++, and Python,
149
00:07:43,450 --> 00:07:45,970
and Java, and any number of other languages.
150
00:07:45,970 --> 00:07:49,270
It's a text editor in the sense that it lets you edit text.
151
00:07:49,270 --> 00:07:52,150
And that's all code is going to be.
152
00:07:52,150 --> 00:07:54,907
Now, strictly speaking, you could write code on paper/pencil.
153
00:07:54,907 --> 00:07:56,740
In fact, in high school if you took a class,
154
00:07:56,740 --> 00:07:59,532
you might have done that one or more times as an in-class exercise.
155
00:07:59,532 --> 00:08:02,532
You can't run it on paper, of course, but you could write it, certainly.
156
00:08:02,532 --> 00:08:04,570
You could use something like Microsoft Word,
157
00:08:04,570 --> 00:08:07,240
or Notepad.exe, or Text Edit on the Mac.
158
00:08:07,240 --> 00:08:09,340
But none of those programs are really designed
159
00:08:09,340 --> 00:08:12,190
to format the code in the best way for you,
160
00:08:12,190 --> 00:08:15,250
nor are they designed to let you compile and run the code.
161
00:08:15,250 --> 00:08:19,120
So VS Code is going to be a tool via which you can do all that
162
00:08:19,120 --> 00:08:22,240
and more-- write the code, compile the code, run the code.
163
00:08:22,240 --> 00:08:25,630
So that you all don't have to wrestle with stupid technical support
164
00:08:25,630 --> 00:08:29,110
headaches at the beginning of the course by installing this software and that
165
00:08:29,110 --> 00:08:33,070
on your Macs or PCs, we'll use a cloud-based version of VS Code
166
00:08:33,070 --> 00:08:34,780
at code.cs50.io.
167
00:08:34,780 --> 00:08:36,580
And that's going to be the exact same tool.
168
00:08:36,580 --> 00:08:38,860
And the goal, then, is by the end of the semester
169
00:08:38,860 --> 00:08:43,240
to migrate you off of that cloud-based environment to your own Mac and PC
170
00:08:43,240 --> 00:08:46,090
so that even if CS50 is the only CS class you ever take,
171
00:08:46,090 --> 00:08:50,290
you're 100% equipped to continue writing code after the class using
172
00:08:50,290 --> 00:08:54,010
not something that's even CS50-specific, but a de facto industry
173
00:08:54,010 --> 00:08:55,760
standard, at least for some time.
174
00:08:55,760 --> 00:08:59,020
So what's this program VS Code going to look like, be it on your Mac,
175
00:08:59,020 --> 00:09:00,990
PC, or initially in your browser?
176
00:09:00,990 --> 00:09:02,990
It's going to look a little something like this.
177
00:09:02,990 --> 00:09:05,657
And there's going to be several different regions to the screen.
178
00:09:05,657 --> 00:09:07,450
And pictured here is that very same code I
179
00:09:07,450 --> 00:09:10,335
keep proposing as the simplest program you can write in C.
180
00:09:10,335 --> 00:09:12,460
And what are these different regions of the screen?
181
00:09:12,460 --> 00:09:15,440
Well, there's essentially these four here.
182
00:09:15,440 --> 00:09:19,660
So first, highlighted up top is going to be one or more tabs where
183
00:09:19,660 --> 00:09:21,160
you're going to actually write code.
184
00:09:21,160 --> 00:09:23,230
So much like in Google Docs or Microsoft Word,
185
00:09:23,230 --> 00:09:24,940
you can have tabs open with files.
186
00:09:24,940 --> 00:09:28,330
Similarly in VS Code-- or, really, any programming environment--
187
00:09:28,330 --> 00:09:30,830
you generally nowadays have tabs of some sort.
188
00:09:30,830 --> 00:09:34,480
And this is going to be a tab containing a file, it seems, called hello.c.
189
00:09:34,480 --> 00:09:38,020
And that's going to be the very first file we write in just a moment.
190
00:09:38,020 --> 00:09:40,720
Down here, though, is going to be an interface that many of you
191
00:09:40,720 --> 00:09:41,920
might not know.
192
00:09:41,920 --> 00:09:44,170
This is what's called a terminal window.
193
00:09:44,170 --> 00:09:47,920
And a terminal window provides what's generally called a Command Line
194
00:09:47,920 --> 00:09:49,720
Interface, or CLI.
195
00:09:49,720 --> 00:09:53,680
And this is in contrast with a Graphical User Interface, or GUI.
196
00:09:53,680 --> 00:09:57,760
Now, you and I, every day, are using GUIs on our phones, on our PCs.
197
00:09:57,760 --> 00:10:01,420
And a GUI is literally graphical-- so menus, and buttons, and icons.
198
00:10:01,420 --> 00:10:04,060
And you generally use your finger or a trackpad
199
00:10:04,060 --> 00:10:06,380
or a mouse or something like that to interact with it.
200
00:10:06,380 --> 00:10:08,410
But it turns out that many programmers-- they're
201
00:10:08,410 --> 00:10:11,770
saying most programmers, at least over time, come to prefer,
202
00:10:11,770 --> 00:10:14,620
not a GUI, but a CLI, a Command Line Interface
203
00:10:14,620 --> 00:10:20,650
where you actually do everything somewhat arcanely via keyboard alone.
204
00:10:20,650 --> 00:10:21,250
Why?
205
00:10:21,250 --> 00:10:24,610
Well, it turns out, there's just more features built in to most computers
206
00:10:24,610 --> 00:10:26,260
if you can access them with a keyboard.
207
00:10:26,260 --> 00:10:29,530
It turns out, most of us can type faster than you can point and click.
208
00:10:29,530 --> 00:10:32,330
And so that ends up being an efficiency gain over time.
209
00:10:32,330 --> 00:10:35,140
So in time, will you get comfortable using this terminal
210
00:10:35,140 --> 00:10:39,370
window to do things like compile your code or make your program
211
00:10:39,370 --> 00:10:40,390
as well as run it.
212
00:10:40,390 --> 00:10:43,810
So you won't be in the habit initially of just double clicking icons
213
00:10:43,810 --> 00:10:45,800
like we do in our typical real world.
214
00:10:45,800 --> 00:10:47,890
You'll do it the programmer's way.
215
00:10:47,890 --> 00:10:51,820
But it's not to the exclusion of adding icons, and clickability, and more.
216
00:10:51,820 --> 00:10:53,950
On the left-hand side of VS Code, there's
217
00:10:53,950 --> 00:10:56,920
going to be a somewhat familiar File Explorer,
218
00:10:56,920 --> 00:11:00,040
some kind of hierarchical tree, like on your Mac or PC where you can
219
00:11:00,040 --> 00:11:02,110
see all of the files in your account.
220
00:11:02,110 --> 00:11:04,390
Pictured here, for instance, is just hello.c,
221
00:11:04,390 --> 00:11:06,140
which I'll create myself in a moment.
222
00:11:06,140 --> 00:11:09,343
And then far away on the left is the so-called Activity Bar,
223
00:11:09,343 --> 00:11:12,260
and this is where you just get a lot of traditional menus and buttons.
224
00:11:12,260 --> 00:11:16,250
So VS Code itself gives you both a GUI and a CLI.
225
00:11:16,250 --> 00:11:19,958
But it's within the CLI, the terminal window, the bottom region of the screen
226
00:11:19,958 --> 00:11:22,250
that we're actually going to type most of our commands.
227
00:11:22,250 --> 00:11:25,417
And in general in class, I'm going to hide all of the graphical stuff that's
228
00:11:25,417 --> 00:11:28,380
just not of all that much interest.
229
00:11:28,380 --> 00:11:30,710
So with that said, let me actually change over
230
00:11:30,710 --> 00:11:32,878
to a live version of VS Code.
231
00:11:32,878 --> 00:11:34,670
And I've indeed hidden in the Activity Bar.
232
00:11:34,670 --> 00:11:36,470
I've indeed hidden the File Explorer.
233
00:11:36,470 --> 00:11:39,380
So what I have here for visibility sake is a really big area
234
00:11:39,380 --> 00:11:42,840
for writing code and a really big terminal window at the bottom.
235
00:11:42,840 --> 00:11:45,260
You'll see in the terminal window, there's dollar sign.
236
00:11:45,260 --> 00:11:47,160
And this doesn't mean any form of currency.
237
00:11:47,160 --> 00:11:51,230
This is just the standard symbol that represents type commands here.
238
00:11:51,230 --> 00:11:53,480
So the fact that there's just dollar sign and a cursor
239
00:11:53,480 --> 00:11:55,490
means, eventually, that's where I'm going to type commands.
240
00:11:55,490 --> 00:11:58,020
But first, I'm going to actually create some code.
241
00:11:58,020 --> 00:12:02,900
So how might I program using VS Code-- be it on my Mac, PC,
242
00:12:02,900 --> 00:12:07,160
or in this cloud-based environment that you'll get set up for problem set 1--
243
00:12:07,160 --> 00:12:08,870
go about writing my first file?
244
00:12:08,870 --> 00:12:10,610
Well, perhaps the easiest way is this.
245
00:12:10,610 --> 00:12:14,090
Literally run the command code and then the name of the file
246
00:12:14,090 --> 00:12:15,200
you want to create.
247
00:12:15,200 --> 00:12:18,838
Notice that I deliberately end the file with .c in lowercase.
248
00:12:18,838 --> 00:12:21,380
Notice that I've deliberately lowercased the whole file name.
249
00:12:21,380 --> 00:12:22,672
And these are just conventions.
250
00:12:22,672 --> 00:12:24,140
You could use a capital H.
251
00:12:24,140 --> 00:12:27,260
You kind of could use a capital C. But just don't do that.
252
00:12:27,260 --> 00:12:30,260
Follow best practices so that it's consistent with what most everyone
253
00:12:30,260 --> 00:12:31,100
else would do.
254
00:12:31,100 --> 00:12:33,770
When I hit Enter, I just get an empty tab,
255
00:12:33,770 --> 00:12:35,540
just like the screenshot a moment ago.
256
00:12:35,540 --> 00:12:40,100
And it's in this tab where I can now write my very first program in C.
257
00:12:40,100 --> 00:12:42,620
Unfortunately, it's not quite as user-friendly as Scratch
258
00:12:42,620 --> 00:12:45,992
where you drag and drop a couple of puzzle pieces and, boom, it's done.
259
00:12:45,992 --> 00:12:47,450
So I'm going to do this for memory.
260
00:12:47,450 --> 00:12:49,970
But this, too, will become familiar to you over time.
261
00:12:49,970 --> 00:12:53,720
I'm going to include something called stdio.h.
262
00:12:53,720 --> 00:12:57,230
I'm going to type int main, void in parentheses.
263
00:12:57,230 --> 00:13:01,190
On a new line, I'm going to insert some curly braces, as we'll call them.
264
00:13:01,190 --> 00:13:03,830
And then I'm going to type printf, and then some
265
00:13:03,830 --> 00:13:09,200
parentheses, and then in quotes, hello, comma, world, then a backslash, then
266
00:13:09,200 --> 00:13:12,800
a lowercase n, then a close quote, and then a semicolon
267
00:13:12,800 --> 00:13:14,280
at the very end of the line.
268
00:13:14,280 --> 00:13:19,010
So all I've done is recreate, just from memory, that very first program.
269
00:13:19,010 --> 00:13:21,710
In a little bit, we'll make clear what most of this does.
270
00:13:21,710 --> 00:13:23,857
But for now, let's just actually run this thing.
271
00:13:23,857 --> 00:13:26,690
And just like I clicked the green flag last week for the first time,
272
00:13:26,690 --> 00:13:29,840
let's actually compile and run this program.
273
00:13:29,840 --> 00:13:33,967
If it were your Mac or PC and Google, or Microsoft, or someone else
274
00:13:33,967 --> 00:13:36,050
had made the software, at this point in the story,
275
00:13:36,050 --> 00:13:37,408
we'd be double clicking an icon.
276
00:13:37,408 --> 00:13:38,450
But we can't do that yet.
277
00:13:38,450 --> 00:13:39,930
This is still source code.
278
00:13:39,930 --> 00:13:42,380
So I'm going to click back down in my terminal window.
279
00:13:42,380 --> 00:13:45,650
Notice I have a second dollar sign below the first, which just
280
00:13:45,650 --> 00:13:47,880
means it's ready for a second command.
281
00:13:47,880 --> 00:13:53,000
And now the command via which to make this an actual program, to compile it
282
00:13:53,000 --> 00:13:56,990
from source code to machine code is, going to be quite simply make
283
00:13:56,990 --> 00:13:59,360
and then the name of the program I want to make.
284
00:13:59,360 --> 00:14:03,710
Slight subtlety-- I'm omitting deliberately .c because the program I
285
00:14:03,710 --> 00:14:05,870
want to make, I just want to call hello.
286
00:14:05,870 --> 00:14:07,400
Don't write make hello.c.
287
00:14:07,400 --> 00:14:08,780
Just write make hello.
288
00:14:08,780 --> 00:14:13,040
And this program make is essentially our compiler.
289
00:14:13,040 --> 00:14:15,560
Technically speaking, it's a program that automates
290
00:14:15,560 --> 00:14:17,580
the compilation of my program for me.
291
00:14:17,580 --> 00:14:20,180
But it is going to see that I've typed the word hello.
292
00:14:20,180 --> 00:14:25,100
It's going to automatically look now for a file on the hard drive called hello.c
293
00:14:25,100 --> 00:14:30,690
and convert it from source code in C to machine code in zeros and ones.
294
00:14:30,690 --> 00:14:37,170
So if I didn't make any typos, Enter, nothing seems to happen.
295
00:14:37,170 --> 00:14:38,210
And that's a good thing.
296
00:14:38,210 --> 00:14:41,862
Almost always, if nothing gets outputted on the screen, you did good.
297
00:14:41,862 --> 00:14:43,070
You didn't make any mistakes.
298
00:14:43,070 --> 00:14:43,880
You didn't get yelled at.
299
00:14:43,880 --> 00:14:45,000
There's no error messages.
300
00:14:45,000 --> 00:14:46,590
So this is actually a good thing.
301
00:14:46,590 --> 00:14:47,942
How do I now run this program?
302
00:14:47,942 --> 00:14:50,150
Well, notice I've got a third dollar sign, which just
303
00:14:50,150 --> 00:14:52,110
means I'm ready for a third command.
304
00:14:52,110 --> 00:14:55,400
And now I'm going to go ahead and run ./hello.
305
00:14:55,400 --> 00:14:58,798
And this is admittedly a little weird that you have to do dot slash.
306
00:14:58,798 --> 00:15:00,590
But for now just take on faith that this is
307
00:15:00,590 --> 00:15:04,610
how you run a program called hello In your current folder,
308
00:15:04,610 --> 00:15:07,730
in your current directory in this cloud-based environment.
309
00:15:07,730 --> 00:15:10,430
All right, crossing my fingers again, hitting Enter.
310
00:15:10,430 --> 00:15:12,110
And voila.
311
00:15:12,110 --> 00:15:15,950
My very first program in C, hello, world.
312
00:15:15,950 --> 00:15:20,480
And now let me go ahead and reveal the File Explorer that I proposed
313
00:15:20,480 --> 00:15:21,292
exists earlier.
314
00:15:21,292 --> 00:15:23,750
I'm just going to use the keyboard shortcut to reveal that.
315
00:15:23,750 --> 00:15:27,000
And generally, I keep it closed because I don't really need to constantly what
316
00:15:27,000 --> 00:15:28,250
files are in my account.
317
00:15:28,250 --> 00:15:31,820
But you'll see now in the File Explorer, similar in spirit to a Mac or PC
318
00:15:31,820 --> 00:15:35,270
but graphically a little different, here's my file, hello.c.
319
00:15:35,270 --> 00:15:37,520
It's highlighted because I have that tab open.
320
00:15:37,520 --> 00:15:40,970
But now there's a second file here called just hello.
321
00:15:40,970 --> 00:15:42,690
That's the name of my program.
322
00:15:42,690 --> 00:15:46,100
So if you were on a Mac or PC, you would ideally double click that thing.
323
00:15:46,100 --> 00:15:48,162
You can't do that in a command line environment.
324
00:15:48,162 --> 00:15:49,370
You have to run it down here.
325
00:15:49,370 --> 00:15:50,453
But that's all we've done.
326
00:15:50,453 --> 00:15:53,750
We've created a file called hello.c, and then my compiler
327
00:15:53,750 --> 00:15:56,240
made the program from that.
328
00:15:56,240 --> 00:16:00,080
Let me pause here and see if there's any questions because that's
329
00:16:00,080 --> 00:16:01,970
a lot of magical phrases.
330
00:16:01,970 --> 00:16:04,450
Yeah?
331
00:16:04,450 --> 00:16:04,950
Yeah.
332
00:16:04,950 --> 00:16:08,390
So if you're currently following along, playing along at home
333
00:16:08,390 --> 00:16:10,890
and you're getting some kind of error message, part of today
334
00:16:10,890 --> 00:16:13,950
will be for me to deliberately induce some of those error messages.
335
00:16:13,950 --> 00:16:17,070
For now let me just propose that if you literally did what I did,
336
00:16:17,070 --> 00:16:19,320
you must have made a typo somewhere.
337
00:16:19,320 --> 00:16:23,790
And notice that it's indeed standard io-- stdio.h.
338
00:16:23,790 --> 00:16:25,890
Maybe you typed studio.h?
339
00:16:25,890 --> 00:16:30,600
OK, super common mistake, I could call you out.
340
00:16:30,600 --> 00:16:32,280
It is not studio.h.
341
00:16:32,280 --> 00:16:34,560
It is stdio.h-- so common.
342
00:16:34,560 --> 00:16:37,658
But this is exactly representative of the kind of stupid headaches
343
00:16:37,658 --> 00:16:40,200
you're going to run into this week, probably for a few weeks,
344
00:16:40,200 --> 00:16:41,730
probably, honestly, for a few years.
345
00:16:41,730 --> 00:16:45,180
But you start to see past these stupid mistakes over time,
346
00:16:45,180 --> 00:16:47,610
and it just gets easier and easier because the computer is
347
00:16:47,610 --> 00:16:49,110
going to be so regimented.
348
00:16:49,110 --> 00:16:50,950
It will only do what you tell it to do.
349
00:16:50,950 --> 00:16:54,223
And if you say because it's verbally sounds like studio.h,
350
00:16:54,223 --> 00:16:55,890
it's not going to know what the file is.
351
00:16:55,890 --> 00:16:58,182
So actually, thank you for tripping over that so early.
352
00:16:58,182 --> 00:16:59,740
That's super common to happen.
353
00:16:59,740 --> 00:17:00,240
Yeah?
354
00:17:00,240 --> 00:17:02,540
AUDIENCE: Why do you have two hello files?
355
00:17:02,540 --> 00:17:03,799
DAVID J. MALAN: Why do I have to hello files?
356
00:17:03,799 --> 00:17:04,400
AUDIENCE: Yes.
357
00:17:04,400 --> 00:17:06,400
DAVID J. MALAN: So why do I have to hello files?
358
00:17:06,400 --> 00:17:09,170
One is the one I created as the human called hello.c,
359
00:17:09,170 --> 00:17:10,520
and it's pictured right here.
360
00:17:10,520 --> 00:17:15,890
But then when I ran make hello, that process compiled my source code
361
00:17:15,890 --> 00:17:17,040
into machine code.
362
00:17:17,040 --> 00:17:20,240
So this second file just called hello is the file that
363
00:17:20,240 --> 00:17:25,700
contains all of those zeros and ones that the server actually understands.
364
00:17:25,700 --> 00:17:27,200
All right, so yeah, question?
365
00:17:27,200 --> 00:17:29,710
AUDIENCE: The access to the hello [INAUDIBLE]
366
00:17:29,710 --> 00:17:31,960
DAVID J. MALAN: If you try clicking on the hello file,
367
00:17:31,960 --> 00:17:34,270
you'll see in this environment the VS Code,
368
00:17:34,270 --> 00:17:36,580
quote/unquote, The file is not displayed in the editor
369
00:17:36,580 --> 00:17:38,230
because it is either binary--
370
00:17:38,230 --> 00:17:41,437
AKA zeros and ones-- or uses an unsupported text encoding.
371
00:17:41,437 --> 00:17:42,520
In this case, it's binary.
372
00:17:42,520 --> 00:17:43,660
It's zeros and ones.
373
00:17:43,660 --> 00:17:47,680
Now, you could use software to see those zeros and ones.
374
00:17:47,680 --> 00:17:50,320
It won't be intellectually enlightening to most any human.
375
00:17:50,320 --> 00:17:53,165
So VS Code just takes the choice of not showing it to you at all.
376
00:17:53,165 --> 00:17:56,290
So that would be a common mistake too, clicking on a file you don't intend.
377
00:17:56,290 --> 00:18:00,190
But the source code is indeed going to be editable by us.
378
00:18:00,190 --> 00:18:01,900
All right, so I've written this program.
379
00:18:01,900 --> 00:18:04,780
It seems to magically work, at least with some effort
380
00:18:04,780 --> 00:18:06,700
if you get every single keystroke right.
381
00:18:06,700 --> 00:18:08,440
Well, what is it that's going on?
382
00:18:08,440 --> 00:18:09,460
And how is this working?
383
00:18:09,460 --> 00:18:13,180
Well, first of all, notice that even without my highlighting things
384
00:18:13,180 --> 00:18:17,740
or choosing buttons for menus, notice that it's already color coded.
385
00:18:17,740 --> 00:18:20,980
And yet, I wasn't highlighting along the way in Google Docs style,
386
00:18:20,980 --> 00:18:22,510
changing the color, certainly.
387
00:18:22,510 --> 00:18:25,960
Well, it turns out, what VS Code and most programming environments
388
00:18:25,960 --> 00:18:29,600
nowadays do for you automatically is syntax highlighting.
389
00:18:29,600 --> 00:18:33,850
So syntax highlighting is just this feature of typical text editors
390
00:18:33,850 --> 00:18:36,760
nowadays that analyzes the code that you've typed.
391
00:18:36,760 --> 00:18:40,000
And when it notices certain types of keystrokes,
392
00:18:40,000 --> 00:18:43,900
things that represent functions, or conditionals, or loops, or variables--
393
00:18:43,900 --> 00:18:47,570
a lot of the vocab from last week-- it just highlights it ever so differently
394
00:18:47,570 --> 00:18:48,070
for you.
395
00:18:48,070 --> 00:18:51,430
So main, for instance, which we'll soon see, is in purple here.
396
00:18:51,430 --> 00:18:53,890
Int, and void, and include are in red.
397
00:18:53,890 --> 00:18:55,630
Hello, world is in blue.
398
00:18:55,630 --> 00:18:57,390
My parentheses are in green.
399
00:18:57,390 --> 00:18:59,290
This will totally vary by programmer too.
400
00:18:59,290 --> 00:19:02,995
In fact, if you do want to change these colors for problem set 1
401
00:19:02,995 --> 00:19:04,870
for your own environment, you can poke around
402
00:19:04,870 --> 00:19:07,190
VS Code Settings via the gear icon.
403
00:19:07,190 --> 00:19:09,820
You can change to a different color theme.
404
00:19:09,820 --> 00:19:13,480
Syntax highlighting isn't some specific color scheme like it is in Scratch.
405
00:19:13,480 --> 00:19:16,485
It just generally is to each human their own preference.
406
00:19:16,485 --> 00:19:18,610
But that's all that's happening here is this notion
407
00:19:18,610 --> 00:19:20,830
of syntax highlighting at the moment.
408
00:19:20,830 --> 00:19:25,510
Well, what more is going on in this code before I run it, but rather write it?
409
00:19:25,510 --> 00:19:28,790
Well, it looks a little something like this if I take away all of the colors.
410
00:19:28,790 --> 00:19:30,550
And then just for discussion's sake, let me go ahead
411
00:19:30,550 --> 00:19:32,500
and color it a little more like Scratch.
412
00:19:32,500 --> 00:19:34,690
Recall that our very first Scratch program
413
00:19:34,690 --> 00:19:39,670
that just said hello, world on the screen had a green flag clicked icon--
414
00:19:39,670 --> 00:19:45,070
puzzle piece, roughly in orange, and then a purple say block beneath it.
415
00:19:45,070 --> 00:19:48,820
So whereas this is the C version, if we run rewind to last week,
416
00:19:48,820 --> 00:19:50,950
this was the same program in Scratch.
417
00:19:50,950 --> 00:19:53,090
But what's happening now is exactly the same.
418
00:19:53,090 --> 00:19:55,060
So if you think back to last week and you've
419
00:19:55,060 --> 00:19:58,600
got some function, like the say function in purple,
420
00:19:58,600 --> 00:20:01,270
that might take one or more arguments, like inputs that
421
00:20:01,270 --> 00:20:03,190
influences what it says on the screen.
422
00:20:03,190 --> 00:20:05,230
And then functions, recall, can sometimes
423
00:20:05,230 --> 00:20:08,480
have side effects, like the speech bubble appears on the screen.
424
00:20:08,480 --> 00:20:11,260
So last week when we used the say block and we
425
00:20:11,260 --> 00:20:13,840
passed in an argument of hello, world at left,
426
00:20:13,840 --> 00:20:17,915
we got this visual side effect on the screen that says now hello, world
427
00:20:17,915 --> 00:20:18,790
in the speech bubble.
428
00:20:18,790 --> 00:20:23,230
And that's exactly what just happened in VS Code but much, much more textually.
429
00:20:23,230 --> 00:20:25,900
And let's look a little closer now at the code itself.
430
00:20:25,900 --> 00:20:29,020
Let me wave my hand at the equivalent of when
431
00:20:29,020 --> 00:20:32,890
green flag clicked part of my code, and let's focus only
432
00:20:32,890 --> 00:20:38,350
on the say block in Scratch and the corresponding function in C.
433
00:20:38,350 --> 00:20:41,770
So if I step through this and I wanted to convert what
434
00:20:41,770 --> 00:20:44,830
we did last week with the say block to C,
435
00:20:44,830 --> 00:20:47,645
I would first use the print function-- although that's actually
436
00:20:47,645 --> 00:20:48,520
a bit of a white lie.
437
00:20:48,520 --> 00:20:50,440
It's actually the printf function.
438
00:20:50,440 --> 00:20:52,030
Printf means formatted.
439
00:20:52,030 --> 00:20:55,360
And it's just a function that allows you to format text on the screen.
440
00:20:55,360 --> 00:20:58,570
There is no say function in C. There's a printf function.
441
00:20:58,570 --> 00:21:02,650
What MIT did down the road years ago was they took what existed historically
442
00:21:02,650 --> 00:21:05,290
as printf, and they simplified it for a broader audience
443
00:21:05,290 --> 00:21:08,050
by just calling it essentially say instead.
444
00:21:08,050 --> 00:21:13,450
But notice that now if I want to convert the Scratch code at left to C code
445
00:21:13,450 --> 00:21:16,250
it right, it's the same shape.
446
00:21:16,250 --> 00:21:18,940
So MIT deliberately used this white oval,
447
00:21:18,940 --> 00:21:23,510
if only because it conjures this idea of having parentheses too.
448
00:21:23,510 --> 00:21:26,770
So on the right, if I want to pass an argument or an input
449
00:21:26,770 --> 00:21:31,240
to the printf function, I use an open parentheses and a close parentheses.
450
00:21:31,240 --> 00:21:33,700
In those parentheses, I then type whatever
451
00:21:33,700 --> 00:21:35,600
it is I want to print on the screen--
452
00:21:35,600 --> 00:21:37,460
in this case, hello, comma, world.
453
00:21:37,460 --> 00:21:39,310
But notice I've deliberately left some room
454
00:21:39,310 --> 00:21:42,160
because you need some extra keystrokes in the world of C.
455
00:21:42,160 --> 00:21:44,590
Any time you type out some text--
456
00:21:44,590 --> 00:21:49,150
otherwise known as a string of text, to use computer science jargon--
457
00:21:49,150 --> 00:21:52,100
you need to quote it, in this case with double quotes.
458
00:21:52,100 --> 00:21:54,520
Double quote at the left, double quote at the right.
459
00:21:54,520 --> 00:21:57,730
And notice too I'm going to include some slightly cryptic symbol
460
00:21:57,730 --> 00:22:01,660
here too-- backslash n, which I also typed and said verbally earlier,
461
00:22:01,660 --> 00:22:05,480
and then one last nuisance at the end of this, which is a semicolon.
462
00:22:05,480 --> 00:22:08,890
So suffice it to say, this is why we start with Scratch.
463
00:22:08,890 --> 00:22:10,960
This, drag and drop, you're good to go.
464
00:22:10,960 --> 00:22:14,680
In a language like C, printf, parentheses, double quotes, the text
465
00:22:14,680 --> 00:22:16,630
you want, backslash n, semicolon at the end.
466
00:22:16,630 --> 00:22:18,970
There's just so much syntactic overhead.
467
00:22:18,970 --> 00:22:21,290
But at the end of the day, it's just a function.
468
00:22:21,290 --> 00:22:25,180
And you'll get used to these nuisances like the parentheses, the quotes,
469
00:22:25,180 --> 00:22:27,130
the semicolon, and the like.
470
00:22:27,130 --> 00:22:31,810
But things can very easily you go wrong, and it's very easy to make mistakes,
471
00:22:31,810 --> 00:22:33,380
even with lines of code like this.
472
00:22:33,380 --> 00:22:34,190
So let me do this.
473
00:22:34,190 --> 00:22:37,070
Let me go back to VS Code where I have the exact same code.
474
00:22:37,070 --> 00:22:40,910
Notice that on line 5 is exactly that line of code.
475
00:22:40,910 --> 00:22:42,910
So this is the equivalent of the say block.
476
00:22:42,910 --> 00:22:46,090
And let's consider what mistakes I may make early on or even now
477
00:22:46,090 --> 00:22:49,930
20 years later after learning this that are quite common in general.
478
00:22:49,930 --> 00:22:52,180
Suppose I forget the semicolon there.
479
00:22:52,180 --> 00:22:53,380
So easy to do.
480
00:22:53,380 --> 00:22:54,910
You will do this eventually.
481
00:22:54,910 --> 00:22:57,970
Let's see what happens now when I go back to my terminal window
482
00:22:57,970 --> 00:22:59,920
and try to compile my code again.
483
00:22:59,920 --> 00:23:02,590
Just to keep things tidy, I'm going to clear my screen.
484
00:23:02,590 --> 00:23:05,170
But that's just for lecture's sake so that we can focus only
485
00:23:05,170 --> 00:23:06,460
on the most recent command.
486
00:23:06,460 --> 00:23:09,940
But I'm going to go ahead now and rerun make hello.
487
00:23:09,940 --> 00:23:13,690
This will ensure that my program is recompiled.
488
00:23:13,690 --> 00:23:14,950
And this is a manual process.
489
00:23:14,950 --> 00:23:16,060
I changed my code.
490
00:23:16,060 --> 00:23:18,670
The zeros and ones on the hard drive have not changed.
491
00:23:18,670 --> 00:23:21,980
I need to recompile it to output the latest machine code.
492
00:23:21,980 --> 00:23:22,580
So here we go.
493
00:23:22,580 --> 00:23:24,830
I'm going to hit Enter, crossing my fingers as before.
494
00:23:24,830 --> 00:23:29,320
But again, I remove the semicolon by accident.
495
00:23:29,320 --> 00:23:29,980
Oh, my god.
496
00:23:29,980 --> 00:23:33,700
There's more lines of errors now than there are of actual code.
497
00:23:33,700 --> 00:23:35,770
And this, too, takes some getting used to.
498
00:23:35,770 --> 00:23:38,590
The programs we're using were not necessarily written
499
00:23:38,590 --> 00:23:40,480
with the least comfortable audience in mind
500
00:23:40,480 --> 00:23:42,760
but, really, professional programmers back in the day.
501
00:23:42,760 --> 00:23:46,000
But through practice, and through experience, and through mistakes,
502
00:23:46,000 --> 00:23:47,750
you'll start to notice patterns here too.
503
00:23:47,750 --> 00:23:49,090
So here's what I typed.
504
00:23:49,090 --> 00:23:51,220
Make hello after the sign prompt.
505
00:23:51,220 --> 00:23:57,010
Now I get yelled at as follows, hello.c, colon, 5, colon, 29.
506
00:23:57,010 --> 00:23:58,420
Well, what's that referring to?
507
00:23:58,420 --> 00:24:03,460
I've screwed up somewhere-- on line 5, on the 29th character on that line.
508
00:24:03,460 --> 00:24:05,740
Generally, the specific character is not that useful
509
00:24:05,740 --> 00:24:07,448
unless you actually want to count it out.
510
00:24:07,448 --> 00:24:08,630
But line 5 is a good clue.
511
00:24:08,630 --> 00:24:09,130
Why?
512
00:24:09,130 --> 00:24:11,660
It means I screwed up somewhere on line 5 here.
513
00:24:11,660 --> 00:24:12,160
All right.
514
00:24:12,160 --> 00:24:13,360
Well, what is the error?
515
00:24:13,360 --> 00:24:16,242
Expected a semicolon after expression.
516
00:24:16,242 --> 00:24:17,950
And this error is actually pretty obvious
517
00:24:17,950 --> 00:24:20,103
now that I see it and I realize, oh, wait a minute.
518
00:24:20,103 --> 00:24:21,520
All right, here's my line of code.
519
00:24:21,520 --> 00:24:26,890
Here in sort of ASCII art, so to speak-- textual text representing graphics--
520
00:24:26,890 --> 00:24:30,550
it wants me to put in green here the semicolon at the end of that line.
521
00:24:30,550 --> 00:24:32,470
1 error generated, builtin--
522
00:24:32,470 --> 00:24:33,850
so some esoteric stuff there.
523
00:24:33,850 --> 00:24:36,340
But my program did not compile.
524
00:24:36,340 --> 00:24:39,470
When you see an error like this, it means it did not work.
525
00:24:39,470 --> 00:24:40,360
So what's the fix?
526
00:24:40,360 --> 00:24:45,470
Well, obviously, the fix is to go back up here, put the semicolon there.
527
00:24:45,470 --> 00:24:48,760
And now if I recompile my code with make hello--
528
00:24:48,760 --> 00:24:52,060
I won't clear my screen just yet just to show you the difference-- now
529
00:24:52,060 --> 00:24:52,990
it just worked.
530
00:24:52,990 --> 00:24:55,550
So we're back in business as before.
531
00:24:55,550 --> 00:24:57,910
All right, let me pause here, though, and ask if there's
532
00:24:57,910 --> 00:25:02,240
any questions about what I just did.
533
00:25:02,240 --> 00:25:04,460
These error messages will become frequent initially.
534
00:25:04,460 --> 00:25:04,960
Yeah?
535
00:25:04,960 --> 00:25:08,848
AUDIENCE: So do you need a semicolon after line or just some of them?
536
00:25:08,848 --> 00:25:10,390
DAVID J. MALAN: Really good question.
537
00:25:10,390 --> 00:25:12,960
Do you need a semicolon after every line or just some?
538
00:25:12,960 --> 00:25:14,022
It turns out, just some.
539
00:25:14,022 --> 00:25:16,980
This is something you'll learn through practice, through demonstrations
540
00:25:16,980 --> 00:25:18,240
and examples today.
541
00:25:18,240 --> 00:25:22,810
Generally, you put a semicolon after a statement, so to speak.
542
00:25:22,810 --> 00:25:25,230
And this is the technical term for this line of code.
543
00:25:25,230 --> 00:25:25,950
It's a statement.
544
00:25:25,950 --> 00:25:29,230
And think of it as it's the code equivalent of an English sentence.
545
00:25:29,230 --> 00:25:32,820
So the semicolon in code is like a period in English
546
00:25:32,820 --> 00:25:34,830
when you're done with that particular thought.
547
00:25:34,830 --> 00:25:37,650
You don't need semicolons for now anywhere else.
548
00:25:37,650 --> 00:25:39,750
And we'll see examples of where else you put them.
549
00:25:39,750 --> 00:25:42,780
But it usually is at the end of a line of code
550
00:25:42,780 --> 00:25:46,980
that isn't purely syntactic like curly braces instead.
551
00:25:46,980 --> 00:25:51,600
Other questions on the mistake I just fixed and created for myself?
552
00:25:51,600 --> 00:25:52,230
Yeah?
553
00:25:52,230 --> 00:25:55,170
AUDIENCE: [INAUDIBLE]
554
00:25:55,170 --> 00:25:56,170
DAVID J. MALAN: Correct.
555
00:25:56,170 --> 00:25:58,950
So line 5 is where the error is most likely.
556
00:25:58,950 --> 00:26:02,250
Character 29 means it's 29 characters that way.
557
00:26:02,250 --> 00:26:04,800
And then it's actually, in this case, giving me a suggestion.
558
00:26:04,800 --> 00:26:07,420
The compiler won't always know how to advise me,
559
00:26:07,420 --> 00:26:09,750
especially if I've made a real mess of my code.
560
00:26:09,750 --> 00:26:13,260
But often, it will do its best to give you the answer like this.
561
00:26:13,260 --> 00:26:14,170
Yeah?
562
00:26:14,170 --> 00:26:16,930
AUDIENCE: How come you first put code hello.c?
563
00:26:16,930 --> 00:26:21,140
DAVID J. MALAN: Ah, so how come I first typed code, space, hello.c,
564
00:26:21,140 --> 00:26:22,940
and now I'm typing make hello?
565
00:26:22,940 --> 00:26:24,180
Two different processes.
566
00:26:24,180 --> 00:26:27,350
So when I typed code, space, hello.c, that
567
00:26:27,350 --> 00:26:31,280
was because I wanted to open VS Code and create a new file called hello.c.
568
00:26:31,280 --> 00:26:34,910
It's like going to File, New in a Mac or PC.
569
00:26:34,910 --> 00:26:38,690
Thereafter, though, once the file exists and is actually open here--
570
00:26:38,690 --> 00:26:41,900
and it does autosave, you don't need to hit Command-S or Control-S all
571
00:26:41,900 --> 00:26:42,560
the time--
572
00:26:42,560 --> 00:26:46,110
I can now compile it with make hello again and again.
573
00:26:46,110 --> 00:26:50,570
So theoretically, I should never need to type code, space, hello.c
574
00:26:50,570 --> 00:26:54,020
again unless I want to create a brand-new file called the same thing.
575
00:26:54,020 --> 00:26:57,200
All right, so what about this other piece of syntax here?
576
00:26:57,200 --> 00:26:58,790
Let me clear my terminal window here.
577
00:26:58,790 --> 00:27:01,280
You can also hit Control-L just to throw everything
578
00:27:01,280 --> 00:27:03,380
away just to clean it up aesthetically.
579
00:27:03,380 --> 00:27:06,470
Suppose that I omit whatever this sequence of symbols
580
00:27:06,470 --> 00:27:09,680
is, backslash n, since I'm not really sure at first glance
581
00:27:09,680 --> 00:27:11,460
why that's even there.
582
00:27:11,460 --> 00:27:13,310
Does anyone want to conjecture, especially
583
00:27:13,310 --> 00:27:18,110
if you've never programmed before, what might happen now if I recompile
584
00:27:18,110 --> 00:27:20,450
and rerun this version of the program?
585
00:27:20,450 --> 00:27:25,130
I left the semicolon, but I took away the backslash n.
586
00:27:25,130 --> 00:27:28,390
Any instincts?
587
00:27:28,390 --> 00:27:29,920
All right, well-- yeah?
588
00:27:29,920 --> 00:27:32,470
AUDIENCE: Will the next dollar sign appear
589
00:27:32,470 --> 00:27:34,190
straight after your hello, world?
590
00:27:34,190 --> 00:27:35,190
DAVID J. MALAN: It will.
591
00:27:35,190 --> 00:27:38,740
The next dollar sign will appear right after my hello, world.
592
00:27:38,740 --> 00:27:40,564
But what makes you think that?
593
00:27:40,564 --> 00:27:43,010
AUDIENCE: Because the backslash n creates a new line?
594
00:27:43,010 --> 00:27:44,010
DAVID J. MALAN: Exactly.
595
00:27:44,010 --> 00:27:46,050
Backslash n is actually a special sequence
596
00:27:46,050 --> 00:27:48,060
of symbols that creates a new line.
597
00:27:48,060 --> 00:27:52,710
And so, to your point, if I recompile this program, make hello, Enter--
598
00:27:52,710 --> 00:27:55,420
no syntax error, so it did compile this time.
599
00:27:55,420 --> 00:27:57,180
So you don't need the backslash n.
600
00:27:57,180 --> 00:27:58,800
You do need the semicolon.
601
00:27:58,800 --> 00:28:02,730
But if you don't have the backslash n, watch what happens when I do ./hello
602
00:28:02,730 --> 00:28:03,510
this time.
603
00:28:03,510 --> 00:28:07,230
Now, indeed, I see hello, comma, world and then a weird dollar sign.
604
00:28:07,230 --> 00:28:08,460
And this is still a prompt.
605
00:28:08,460 --> 00:28:12,270
I can still type commands at it, like clear, and everything gets cleaned up.
606
00:28:12,270 --> 00:28:13,710
But it just looks kind of stupid.
607
00:28:13,710 --> 00:28:18,240
If I run it again here with ./hello, it's just not very user friendly.
608
00:28:18,240 --> 00:28:20,740
It is convention that when you're done running your program,
609
00:28:20,740 --> 00:28:22,950
you should ideally clean things up, move the cursor
610
00:28:22,950 --> 00:28:24,460
to the next line for the user.
611
00:28:24,460 --> 00:28:27,540
And so the backslash n is simply the special symbol,
612
00:28:27,540 --> 00:28:32,640
otherwise known as an escape sequence that C knows
613
00:28:32,640 --> 00:28:34,980
means move the cursor to the next line.
614
00:28:34,980 --> 00:28:39,640
In other languages, Python among them, uses this same symbology as well.
615
00:28:39,640 --> 00:28:44,850
Now, if I go back to the code here and, for instance,
616
00:28:44,850 --> 00:28:47,220
I try to do this differently.
617
00:28:47,220 --> 00:28:49,020
Suppose I don't put the backslash n.
618
00:28:49,020 --> 00:28:52,860
I just hit Enter like a normal person would in Google Docs or Microsoft Word.
619
00:28:52,860 --> 00:28:55,107
Let me go ahead and try compiling this program.
620
00:28:55,107 --> 00:28:56,940
And this, you would hope, would work, right?
621
00:28:56,940 --> 00:29:00,210
You would hope this would print out hello, world and then a blank line
622
00:29:00,210 --> 00:29:02,220
because I move the cursor to the next line.
623
00:29:02,220 --> 00:29:02,790
But no.
624
00:29:02,790 --> 00:29:07,290
If I run make hello now and try to compile that, C does not like this.
625
00:29:07,290 --> 00:29:09,690
Now I get a different error, still on line 5,
626
00:29:09,690 --> 00:29:12,240
this time starting at character 12--
627
00:29:12,240 --> 00:29:15,810
error, missing terminating double quote character and then
628
00:29:15,810 --> 00:29:17,070
some other esoteric stuff.
629
00:29:17,070 --> 00:29:19,530
And then this does not sound good-- fatal error this time,
630
00:29:19,530 --> 00:29:21,900
too many errors emitted, stopping now.
631
00:29:21,900 --> 00:29:23,470
So I really screwed up here.
632
00:29:23,470 --> 00:29:25,320
So why can't I do this?
633
00:29:25,320 --> 00:29:26,190
Just because.
634
00:29:26,190 --> 00:29:29,730
The humans who designed C decided that if you have a string of text,
635
00:29:29,730 --> 00:29:31,380
it must stay on the same line.
636
00:29:31,380 --> 00:29:32,760
It can get really long.
637
00:29:32,760 --> 00:29:36,150
It can soft wrap-- that is, without you hitting Enter.
638
00:29:36,150 --> 00:29:38,220
But you can't hit Enter to create a new line.
639
00:29:38,220 --> 00:29:42,870
If you deliberately want a new line, you have to indeed use this backslash n
640
00:29:42,870 --> 00:29:43,958
escape character.
641
00:29:43,958 --> 00:29:45,250
So let me go ahead and do this.
642
00:29:45,250 --> 00:29:46,710
Let me put it back.
643
00:29:46,710 --> 00:29:48,720
Let me go back to my terminal window.
644
00:29:48,720 --> 00:29:50,080
I'll clear the screen again.
645
00:29:50,080 --> 00:29:54,090
Let me go ahead now and do make hello to recompile to that version-- ./hello.
646
00:29:54,090 --> 00:29:54,900
And voila.
647
00:29:54,900 --> 00:29:57,780
We're back in business with hello.
648
00:29:57,780 --> 00:30:00,300
All right, so now let's tease apart some other aspects
649
00:30:00,300 --> 00:30:03,870
of this code because there's a lot going on just to get us to say hello,
650
00:30:03,870 --> 00:30:04,920
world on the screen.
651
00:30:04,920 --> 00:30:07,740
For today, we're largely going to ignore this-- int
652
00:30:07,740 --> 00:30:10,145
main(void) and these curly braces here.
653
00:30:10,145 --> 00:30:12,520
We'll come back to that before long as to why it's there.
654
00:30:12,520 --> 00:30:15,870
But for now just think of int main(void) and these curly braces
655
00:30:15,870 --> 00:30:19,180
here as really being the C equivalent of when green flag clicked.
656
00:30:19,180 --> 00:30:19,680
Why?
657
00:30:19,680 --> 00:30:20,638
You just need it there.
658
00:30:20,638 --> 00:30:22,320
That's how you get your program going.
659
00:30:22,320 --> 00:30:25,500
And main is indeed going to be some special function, but more on that
660
00:30:25,500 --> 00:30:26,340
another time.
661
00:30:26,340 --> 00:30:28,950
But why do I have this line of code here?
662
00:30:28,950 --> 00:30:33,990
The correct spelling is indeed stdio.h, S-T-D-I-O dot H.
663
00:30:33,990 --> 00:30:37,500
And they're angled brackets this time, so that's a little new.
664
00:30:37,500 --> 00:30:40,290
There's a hash and then an include keyword.
665
00:30:40,290 --> 00:30:42,123
If you don't know what something is, there's
666
00:30:42,123 --> 00:30:45,165
not really that much harm in just getting rid of it and see what happens.
667
00:30:45,165 --> 00:30:46,360
So let me delete that line.
668
00:30:46,360 --> 00:30:48,910
Let me go back to my terminal window, clear the screen,
669
00:30:48,910 --> 00:30:50,160
and then run make hello again.
670
00:30:50,160 --> 00:30:53,290
And let's try compiling this program now without that first line.
671
00:30:53,290 --> 00:30:53,790
Why?
672
00:30:53,790 --> 00:30:56,340
I don't understand it, so let's see what happens.
673
00:30:56,340 --> 00:30:58,920
All right, here's yet another error, but let's see--
674
00:30:58,920 --> 00:31:03,480
hello.c, line 5, character 5-- so it's pretty early on--
675
00:31:03,480 --> 00:31:07,920
error, implicitly declaring library function printf with type int
676
00:31:07,920 --> 00:31:09,150
and then dot, dot, dot.
677
00:31:09,150 --> 00:31:12,630
So implicitly declaring library function printf--
678
00:31:12,630 --> 00:31:14,490
so this is very cryptic sounding.
679
00:31:14,490 --> 00:31:16,920
You'll get better at understanding phrases like these.
680
00:31:16,920 --> 00:31:22,620
But apparently, I do need the include line for stdio.h.
681
00:31:22,620 --> 00:31:23,820
But why?
682
00:31:23,820 --> 00:31:27,810
Based on this symptom, what might your instinct
683
00:31:27,810 --> 00:31:33,330
be for what that first line of code is doing for us in the first place?
684
00:31:33,330 --> 00:31:35,370
Why intuitively must it be there?
685
00:31:35,370 --> 00:31:37,290
AUDIENCE: It's how the [INAUDIBLE] functions.
686
00:31:37,290 --> 00:31:38,290
DAVID J. MALAN: Exactly.
687
00:31:38,290 --> 00:31:41,350
It's like importing a library so that you can do things like print things
688
00:31:41,350 --> 00:31:42,137
out on the screen.
689
00:31:42,137 --> 00:31:45,220
Now, in Scratch, you didn't have to do this for most of the puzzle pieces.
690
00:31:45,220 --> 00:31:47,950
But you might recall that partway through week 0,
691
00:31:47,950 --> 00:31:51,640
I went to the Extensions button at the bottom left of the Scratch screen,
692
00:31:51,640 --> 00:31:54,340
and I imported some extra puzzle pieces for text
693
00:31:54,340 --> 00:31:59,170
to speech that gave us the creepy humanized voice that actually came out
694
00:31:59,170 --> 00:32:00,100
of the cat's mouth.
695
00:32:00,100 --> 00:32:02,500
Well, that was like adding a library--
696
00:32:02,500 --> 00:32:04,390
code that someone else wrote.
697
00:32:04,390 --> 00:32:06,550
In that case, it was a third party.
698
00:32:06,550 --> 00:32:08,380
But I gave myself access to it.
699
00:32:08,380 --> 00:32:09,250
Same here.
700
00:32:09,250 --> 00:32:13,900
Turns out that you don't really get printf automatically in C.
701
00:32:13,900 --> 00:32:17,560
You have to include a so-called header file that
702
00:32:17,560 --> 00:32:20,020
declares that function to exist.
703
00:32:20,020 --> 00:32:22,570
Now, the reason for this historically is just efficiency.
704
00:32:22,570 --> 00:32:26,882
Back in the day when computers were really slower and resource constrained,
705
00:32:26,882 --> 00:32:29,590
you don't want to just give yourself access to the entire kitchen
706
00:32:29,590 --> 00:32:30,610
sink of functionality.
707
00:32:30,610 --> 00:32:34,690
You only want to include only the functions you actually care about.
708
00:32:34,690 --> 00:32:39,180
Nowadays, it's a copy/paste step because you almost always
709
00:32:39,180 --> 00:32:40,930
want to print something out on the screen,
710
00:32:40,930 --> 00:32:42,680
at least when writing programs like these.
711
00:32:42,680 --> 00:32:45,760
But these so-called header files contain enough information
712
00:32:45,760 --> 00:32:50,350
about all of the functions in what's called the Standard I/O Library.
713
00:32:50,350 --> 00:32:53,450
And standard I/O just means standard Input and Output.
714
00:32:53,450 --> 00:32:54,700
And that's appropriate, right?
715
00:32:54,700 --> 00:32:57,010
Because printing is pretty basic output.
716
00:32:57,010 --> 00:32:59,920
Turns out, there's other functions for getting input from the human's
717
00:32:59,920 --> 00:33:01,310
keyboard-- more on that in a bit.
718
00:33:01,310 --> 00:33:03,970
But any time you want to print something on the screen in C,
719
00:33:03,970 --> 00:33:07,630
you indeed need to include this header file at the top of your code.
720
00:33:07,630 --> 00:33:11,350
And that's going to essentially inform the compiler, hey, compiler,
721
00:33:11,350 --> 00:33:15,980
I want to use functionality from the Standard I/O Library,
722
00:33:15,980 --> 00:33:18,320
including printf in this case.
723
00:33:18,320 --> 00:33:20,770
And if you omit the header file by accident,
724
00:33:20,770 --> 00:33:24,040
it's just not going to work because it doesn't know what printf is.
725
00:33:24,040 --> 00:33:27,970
It's some unrecognized symbol in that case.
726
00:33:27,970 --> 00:33:34,320
All right, questions, then, about this line of code, this line of code here,
727
00:33:34,320 --> 00:33:37,590
or what these header files are?
728
00:33:37,590 --> 00:33:40,890
All right, you might wonder, well, how do you know what functions exist?
729
00:33:40,890 --> 00:33:43,990
How do you know what files you might indeed want to include?
730
00:33:43,990 --> 00:33:46,620
Well, it turns out that C is a many-year-old language,
731
00:33:46,620 --> 00:33:48,720
and it has ample documentation.
732
00:33:48,720 --> 00:33:52,770
A caveat is that its documentation isn't necessarily all that user friendly.
733
00:33:52,770 --> 00:33:56,370
But what we have for the course is a simplified version
734
00:33:56,370 --> 00:34:01,680
of the official documentation for C at this URL here, manual.cs50.io.
735
00:34:01,680 --> 00:34:04,380
So in the world of C, and other languages too,
736
00:34:04,380 --> 00:34:06,150
there are what are called manual pages.
737
00:34:06,150 --> 00:34:08,820
And these are just text-based documentation
738
00:34:08,820 --> 00:34:11,010
that, honestly, is typically written in a voice
739
00:34:11,010 --> 00:34:14,560
that you have to be an experienced programmer to understand some of it.
740
00:34:14,560 --> 00:34:17,699
So what we've done in this version of the same documentation
741
00:34:17,699 --> 00:34:20,699
is we've imported all of the original official documentation,
742
00:34:20,699 --> 00:34:24,074
but we've added less comfortable translations in English
743
00:34:24,074 --> 00:34:26,699
for a lot of the functionality that you might use in class just
744
00:34:26,699 --> 00:34:27,713
to help onboard you.
745
00:34:27,713 --> 00:34:30,630
So at the end of the day, you don't need this documentation long term.
746
00:34:30,630 --> 00:34:34,320
But just to get started, we'll translate it into terminology
747
00:34:34,320 --> 00:34:36,630
that you might appreciate from a teaching assistant,
748
00:34:36,630 --> 00:34:39,969
for instance, as opposed to the original author of these documents.
749
00:34:39,969 --> 00:34:42,420
And so, for instance, if you were interested in reading up
750
00:34:42,420 --> 00:34:48,330
on what functions exist in the stdio.h file, well,
751
00:34:48,330 --> 00:34:52,830
you could go to a URL like this, or you could search for it at manual.cs50.io.
752
00:34:52,830 --> 00:34:56,350
That would show you a list of all of the available functions in that library,
753
00:34:56,350 --> 00:34:58,350
and print if indeed would be one of them.
754
00:34:58,350 --> 00:35:00,683
And then you could click further on that, reaching a URL
755
00:35:00,683 --> 00:35:03,475
like this that's going to give you all of the documentation for how
756
00:35:03,475 --> 00:35:04,110
to use printf.
757
00:35:04,110 --> 00:35:07,560
It turns out, you can do even more than just printing out hello, world.
758
00:35:07,560 --> 00:35:09,450
And we'll scratch the surface of that today.
759
00:35:09,450 --> 00:35:12,900
But it turns out that the documentation will always
760
00:35:12,900 --> 00:35:16,680
be your authoritative source ultimately for questions like, what can I do,
761
00:35:16,680 --> 00:35:18,160
and how can I do it?
762
00:35:18,160 --> 00:35:23,010
Meanwhile, it turns out that CS50 has its own library
763
00:35:23,010 --> 00:35:25,980
and accessible via header file called cs50.h.
764
00:35:25,980 --> 00:35:28,530
It turns out in C that output is actually
765
00:35:28,530 --> 00:35:30,750
pretty easy, relatively speaking, once you
766
00:35:30,750 --> 00:35:34,110
get used to all the curly braces, parentheses, quote marks, and the like.
767
00:35:34,110 --> 00:35:36,670
But input is a little more difficult.
768
00:35:36,670 --> 00:35:41,100
And if you have programmed before, input's not that hard to do in Python.
769
00:35:41,100 --> 00:35:42,540
It's not that hard to do in Java.
770
00:35:42,540 --> 00:35:46,312
It's more difficult to do in C. And we'll see why in a couple of weeks.
771
00:35:46,312 --> 00:35:48,270
But for the first couple of weeks of the class,
772
00:35:48,270 --> 00:35:50,880
we actually provide you with some training wheels,
773
00:35:50,880 --> 00:35:53,700
of sorts, whereby we have a number of functions
774
00:35:53,700 --> 00:35:56,430
that are declared in this file, cs50.h.
775
00:35:56,430 --> 00:35:59,220
It lives its documentation at a URL like this.
776
00:35:59,220 --> 00:36:01,230
And in a moment, we'll use a few of these.
777
00:36:01,230 --> 00:36:05,040
You'll see that CS50 provides you with some functions like get_char
778
00:36:05,040 --> 00:36:08,580
for get a single character from the user's keyboard,
779
00:36:08,580 --> 00:36:11,790
get_int to get an integer from the user's keyboard,
780
00:36:11,790 --> 00:36:15,450
get_string to get a sequence of text from the user's keyboard, and a bunch
781
00:36:15,450 --> 00:36:16,930
of others as well.
782
00:36:16,930 --> 00:36:19,920
So let's actually use some of these functions, how about,
783
00:36:19,920 --> 00:36:22,410
by revisiting, really, the second program we
784
00:36:22,410 --> 00:36:26,710
wrote in Scratch last time, which adds some input to the output.
785
00:36:26,710 --> 00:36:28,830
So first version of Scratch was just hello, world.
786
00:36:28,830 --> 00:36:31,200
Said the same thing every time you click the green flag.
787
00:36:31,200 --> 00:36:33,180
Version 2, recall, though, did this.
788
00:36:33,180 --> 00:36:35,190
It asked the user, what's your name?
789
00:36:35,190 --> 00:36:40,870
And then that somehow gave it back a return value, we called it.
790
00:36:40,870 --> 00:36:44,100
And we then joined hello and that name to say something a little more
791
00:36:44,100 --> 00:36:46,420
interesting on the screen.
792
00:36:46,420 --> 00:36:48,420
So what did that model look like?
793
00:36:48,420 --> 00:36:49,560
Same thing as before.
794
00:36:49,560 --> 00:36:52,680
We've got a function in the middle where function is like the code
795
00:36:52,680 --> 00:36:54,480
implementation of our algorithm.
796
00:36:54,480 --> 00:36:56,910
That takes in one or more arguments, like what is it you
797
00:36:56,910 --> 00:37:00,000
want to say on the screen ultimately?
798
00:37:00,000 --> 00:37:03,580
And return value, in this case, is going to be actually a value that comes back.
799
00:37:03,580 --> 00:37:07,660
So in the case of getting input, we can consider this ask block again,
800
00:37:07,660 --> 00:37:08,490
like last week.
801
00:37:08,490 --> 00:37:12,420
The input to it is whatever words of English you want to ask the user.
802
00:37:12,420 --> 00:37:14,670
And then it returns a value.
803
00:37:14,670 --> 00:37:17,550
And this was called by default in MIT'S world answer.
804
00:37:17,550 --> 00:37:20,460
But we'll see in C, you can call these return values anything
805
00:37:20,460 --> 00:37:22,300
you want ultimately in variables.
806
00:37:22,300 --> 00:37:24,100
But this is different from a side effect.
807
00:37:24,100 --> 00:37:27,100
A side effect is just something visual often that happens on the screen,
808
00:37:27,100 --> 00:37:28,980
like the speech bubble or hello, world.
809
00:37:28,980 --> 00:37:32,220
A return value is actually a value you get back from a function
810
00:37:32,220 --> 00:37:34,020
that you can use or reuse.
811
00:37:34,020 --> 00:37:38,400
So how do we convert this Scratch block from last week to C code this week?
812
00:37:38,400 --> 00:37:41,340
Well, if you want to ask the user for something like their name,
813
00:37:41,340 --> 00:37:42,580
you can do this.
814
00:37:42,580 --> 00:37:45,600
You use a CS50 function called get_string.
815
00:37:45,600 --> 00:37:49,950
And you use the parentheses to represent here comes the inputs there too.
816
00:37:49,950 --> 00:37:52,967
You can then put the sentence you want to ask the user--
817
00:37:52,967 --> 00:37:54,300
quote/unquote, what's your name?
818
00:37:54,300 --> 00:37:57,150
But you do indeed need the quotes literally in C.
819
00:37:57,150 --> 00:37:59,220
So I'll go ahead and add those as well.
820
00:37:59,220 --> 00:38:03,720
Subtle, but I've deliberately included a space after the question mark,
821
00:38:03,720 --> 00:38:06,840
but before the double quote, just so that the cursor
822
00:38:06,840 --> 00:38:08,998
moves one step over because, in this case,
823
00:38:08,998 --> 00:38:11,790
we're not going to get a special speech box like we did in Scratch.
824
00:38:11,790 --> 00:38:14,582
It's just going to leave the cursor where it is, so we'll see that,
825
00:38:14,582 --> 00:38:16,980
aesthetically, that just moves the blinking cursor one
826
00:38:16,980 --> 00:38:19,800
space after the sentence on the screen.
827
00:38:19,800 --> 00:38:21,930
All right, but the catch is with Scratch,
828
00:38:21,930 --> 00:38:25,140
we just automatically got back the answer from the user
829
00:38:25,140 --> 00:38:27,180
in a special variable called answer.
830
00:38:27,180 --> 00:38:30,270
In C, you're going to have to be a little more specific.
831
00:38:30,270 --> 00:38:35,780
In C, If you want to get back a return value from a function like get_string,
832
00:38:35,780 --> 00:38:40,420
you have to use an equal sign and then the name of a variable on the left.
833
00:38:40,420 --> 00:38:42,280
The choice of variables is up to you.
834
00:38:42,280 --> 00:38:44,290
I could have called this anything-- x, y, z.
835
00:38:44,290 --> 00:38:47,470
I'm going to more descriptively call it answer for parity with what
836
00:38:47,470 --> 00:38:48,880
MIT did with Scratch.
837
00:38:48,880 --> 00:38:53,090
But notice that this doesn't represent equality, per se.
838
00:38:53,090 --> 00:38:55,640
This is assignment in this case.
839
00:38:55,640 --> 00:38:58,180
So in C, when you use a single equal sign,
840
00:38:58,180 --> 00:39:01,720
that means copy the value on the right over to the value
841
00:39:01,720 --> 00:39:03,590
on the left-- from right to left.
842
00:39:03,590 --> 00:39:05,390
So what does this do for us?
843
00:39:05,390 --> 00:39:08,170
Well, if get_string is a function that prompts the user with,
844
00:39:08,170 --> 00:39:12,160
quote/unquote, what's your name, and it has I claim a return value,
845
00:39:12,160 --> 00:39:14,750
that means it hands me back some value.
846
00:39:14,750 --> 00:39:17,960
But it's up to me in C to do something with that value.
847
00:39:17,960 --> 00:39:21,520
So if I want to copy that value into a variable that I can use and reuse,
848
00:39:21,520 --> 00:39:25,300
I use an equal sign, and I invent on the left-hand side of that equal sign
849
00:39:25,300 --> 00:39:27,340
any variable name I want.
850
00:39:27,340 --> 00:39:28,450
There are certain rules.
851
00:39:28,450 --> 00:39:29,700
There are certain conventions.
852
00:39:29,700 --> 00:39:32,590
But generally if you use a single word with all lowercase,
853
00:39:32,590 --> 00:39:34,570
you're in good shape.
854
00:39:34,570 --> 00:39:37,040
But C's a little more pedantic than that.
855
00:39:37,040 --> 00:39:38,980
And those of you who have programmed before
856
00:39:38,980 --> 00:39:41,410
might not be used to this, for instance, in Python, which
857
00:39:41,410 --> 00:39:43,330
is a world we'll get to in a few weeks.
858
00:39:43,330 --> 00:39:48,670
You also have to tell C what type of value you're storing.
859
00:39:48,670 --> 00:39:54,370
So if I do want a string of text from the user-- so not an integer, not
860
00:39:54,370 --> 00:39:55,270
a single character.
861
00:39:55,270 --> 00:39:58,430
I want a whole string of text, like a phrase, a sentence, a name,
862
00:39:58,430 --> 00:39:59,270
in this case--
863
00:39:59,270 --> 00:40:04,250
I have to tell C that this variable is of type string.
864
00:40:04,250 --> 00:40:06,267
So it's a little wordy, but you get used to it.
865
00:40:06,267 --> 00:40:07,600
And you just have to be precise.
866
00:40:07,600 --> 00:40:12,760
You're informing the computer what type of value is going in this variable.
867
00:40:12,760 --> 00:40:15,040
All right, it's so close to being correct,
868
00:40:15,040 --> 00:40:19,210
but I have omitted something that's annoyingly important still.
869
00:40:19,210 --> 00:40:20,470
What's missing still?
870
00:40:20,470 --> 00:40:21,070
Yeah?
871
00:40:21,070 --> 00:40:21,970
AUDIENCE: Semicolon?
872
00:40:21,970 --> 00:40:23,178
DAVID J. MALAN: So semicolon.
873
00:40:23,178 --> 00:40:24,230
This is a statement.
874
00:40:24,230 --> 00:40:27,040
This is like a full thought, if you will.
875
00:40:27,040 --> 00:40:31,680
In Code, I do need to end it ultimately with the semicolon at the end there.
876
00:40:31,680 --> 00:40:33,430
All right, so this was more of a mouthful,
877
00:40:33,430 --> 00:40:35,720
but let's try using this in now my code.
878
00:40:35,720 --> 00:40:40,250
Let me go back to VS Code where I have version 0 of my code here.
879
00:40:40,250 --> 00:40:44,560
Let me go ahead and include one other file at the top of hello.c,
880
00:40:44,560 --> 00:40:48,790
namely include cs50.h so that I have access now
881
00:40:48,790 --> 00:40:51,370
to get_string and anything else I might want.
882
00:40:51,370 --> 00:40:56,710
Now let me go ahead and add a line of code here inside of these curly braces.
883
00:40:56,710 --> 00:40:58,390
And let me go ahead and do this--
884
00:40:58,390 --> 00:41:03,820
string answer equals get_string, quote/unquote, what's your name,
885
00:41:03,820 --> 00:41:04,847
question mark.
886
00:41:04,847 --> 00:41:07,180
I'm going to add an extra space before the double quote.
887
00:41:07,180 --> 00:41:10,430
I'm going to indeed end my thought with a semicolon.
888
00:41:10,430 --> 00:41:14,260
And now let me deliberately make a mistake, just to make a point here.
889
00:41:14,260 --> 00:41:19,840
Let me now try changing hello, world to hello, comma, answer.
890
00:41:19,840 --> 00:41:22,630
Now, perhaps, even though this is some new lines of code,
891
00:41:22,630 --> 00:41:24,520
you can see where I've errored already.
892
00:41:24,520 --> 00:41:26,980
But let me try making this program now.
893
00:41:26,980 --> 00:41:27,970
So far, so good.
894
00:41:27,970 --> 00:41:29,120
So no error messages.
895
00:41:29,120 --> 00:41:30,140
So that's a good thing.
896
00:41:30,140 --> 00:41:34,000
Let me go ahead and run ./hello, and you'll see the prompt.
897
00:41:34,000 --> 00:41:35,650
What's your name, question mark.
898
00:41:35,650 --> 00:41:37,942
And notice, the cursor is indeed one space to the right
899
00:41:37,942 --> 00:41:39,817
just because I thought it would look prettier
900
00:41:39,817 --> 00:41:42,190
to put a little blank space there as opposed to leaving
901
00:41:42,190 --> 00:41:43,600
it right after the question mark.
902
00:41:43,600 --> 00:41:44,530
Let me type my name.
903
00:41:44,530 --> 00:41:48,340
But even if you've never programmed before, I have screwed up here.
904
00:41:48,340 --> 00:41:51,240
What are we going to see on the screen when I hit Enter?
905
00:41:51,240 --> 00:41:52,240
AUDIENCE: Hello, answer.
906
00:41:52,240 --> 00:41:53,115
DAVID J. MALAN: Yeah.
907
00:41:53,115 --> 00:41:54,280
Hello, answer, most likely.
908
00:41:54,280 --> 00:41:54,730
Why?
909
00:41:54,730 --> 00:41:56,855
Because the computer is going to take me literally.
910
00:41:56,855 --> 00:41:59,020
And if I say, quote/unquote, hello, answer.
911
00:41:59,020 --> 00:42:01,750
That is the string of text followed by a new line that's
912
00:42:01,750 --> 00:42:03,260
going to be outputted to the screen.
913
00:42:03,260 --> 00:42:08,530
So we need some way of actually plugging answer into this line of code.
914
00:42:08,530 --> 00:42:10,330
It's not quite as simple as scratch where
915
00:42:10,330 --> 00:42:14,140
you could just grab a second say block and drag and drop the variable there.
916
00:42:14,140 --> 00:42:15,670
We actually need a new syntax.
917
00:42:15,670 --> 00:42:18,250
And it's going to look weird at first, but it is everywhere
918
00:42:18,250 --> 00:42:22,900
in software nowadays, especially in the world of C and certain other languages.
919
00:42:22,900 --> 00:42:27,610
So let me go ahead and propose that I solve it as follows.
920
00:42:27,610 --> 00:42:31,450
Well, back when we did this in Scratch, remember that the most elegant solution
921
00:42:31,450 --> 00:42:32,350
was this here.
922
00:42:32,350 --> 00:42:36,550
We used the say block still, which is going to be analogous to printf today.
923
00:42:36,550 --> 00:42:41,630
But I use the join puzzle piece and Scratch to combine hello, comma, space,
924
00:42:41,630 --> 00:42:43,340
and then the name of the human.
925
00:42:43,340 --> 00:42:45,790
So how do we translate this code to C?
926
00:42:45,790 --> 00:42:47,830
Well, it's going to look a little different now.
927
00:42:47,830 --> 00:42:51,700
I'm going to start with printf with some parentheses and a semicolon
928
00:42:51,700 --> 00:42:53,530
representing the say block.
929
00:42:53,530 --> 00:42:55,240
But how do I now do this joining?
930
00:42:55,240 --> 00:42:58,330
This is where the puzzle pieces don't quite translate perfectly.
931
00:42:58,330 --> 00:43:00,290
This would be the way to do this.
932
00:43:00,290 --> 00:43:03,430
You put hello, comma, and then a placeholder.
933
00:43:03,430 --> 00:43:07,810
So this is what's known as a format code in C, specifically for printf.
934
00:43:07,810 --> 00:43:11,350
And it just means this is a placeholder for a string.
935
00:43:11,350 --> 00:43:12,740
Again, a string is just text.
936
00:43:12,740 --> 00:43:17,120
So this means, hey, computer, print out literally, hello, comma, space,
937
00:43:17,120 --> 00:43:23,200
and then not literally %s. %s is treated specially to mean plug in some value
938
00:43:23,200 --> 00:43:23,903
here.
939
00:43:23,903 --> 00:43:25,570
All right, so what else do I still need?
940
00:43:25,570 --> 00:43:28,030
Well, this is still some text, so I'm still
941
00:43:28,030 --> 00:43:32,460
going to surround the whole thing with double quotes.
942
00:43:32,460 --> 00:43:35,220
I'm still going to include my backslash n just
943
00:43:35,220 --> 00:43:37,870
to keep things tidy and move the cursor to the next line.
944
00:43:37,870 --> 00:43:45,120
So the last step here in C is to somehow join the answer with that word hello.
945
00:43:45,120 --> 00:43:49,980
And the way you do this is with printf, passing it not one argument, which
946
00:43:49,980 --> 00:43:51,000
is what I keep doing.
947
00:43:51,000 --> 00:43:53,820
I keep passing it one string of text, quote/unquote.
948
00:43:53,820 --> 00:43:58,320
I'm going to now add a comma and then the name of the value that I want
949
00:43:58,320 --> 00:44:02,760
printf to go back and plug into that %s.
950
00:44:02,760 --> 00:44:04,410
And printf is just smart about this.
951
00:44:04,410 --> 00:44:09,390
If you have one %s and one additional argument after a comma, it just does--
952
00:44:09,390 --> 00:44:10,980
from right to left, it plugs it in.
953
00:44:10,980 --> 00:44:16,470
If you have two %s's and two variables after the comma, that's OK too.
954
00:44:16,470 --> 00:44:19,860
If you separate them with commas, it'll plug the first into the first %s
955
00:44:19,860 --> 00:44:22,380
and the second variable into the second %s.
956
00:44:22,380 --> 00:44:24,750
So it's just left to right, order of operations.
957
00:44:24,750 --> 00:44:30,302
It's not as pretty or as simple as this, but this is how it's done in C.
958
00:44:30,302 --> 00:44:32,760
All right, let me pause because this is a lot of symbology.
959
00:44:32,760 --> 00:44:35,080
Any questions on this technique here?
960
00:44:35,080 --> 00:44:35,580
Yeah?
961
00:44:35,580 --> 00:44:39,725
AUDIENCE: Why did you exclude the backslash n in the previous section?
962
00:44:39,725 --> 00:44:41,600
DAVID J. MALAN: Yeah, a really good question.
963
00:44:41,600 --> 00:44:45,550
Why did I exclude the backslash n a moment ago?
964
00:44:45,550 --> 00:44:48,280
Really, just my sense of aesthetics, if you will.
965
00:44:48,280 --> 00:44:49,760
No good reason beyond that.
966
00:44:49,760 --> 00:44:52,210
So if I look back at my code, you quite rightly
967
00:44:52,210 --> 00:44:54,460
notice that I didn't have a backslash n there.
968
00:44:54,460 --> 00:44:57,400
That's just because, for whatever sense of style that I have,
969
00:44:57,400 --> 00:45:00,460
I wanted the name to be typed right after the question.
970
00:45:00,460 --> 00:45:04,030
I totally could have added a backslash n there instead of a space.
971
00:45:04,030 --> 00:45:06,490
That would have just allowed me to type down here.
972
00:45:06,490 --> 00:45:07,490
Totally fine.
973
00:45:07,490 --> 00:45:09,670
Just wanted to show you something different.
974
00:45:09,670 --> 00:45:10,210
Good catch.
975
00:45:10,210 --> 00:45:10,660
Yeah?
976
00:45:10,660 --> 00:45:12,070
AUDIENCE: Can you show an example with two %s's?
977
00:45:12,070 --> 00:45:14,470
DAVID J. MALAN: Can I show an example with two %s's?
978
00:45:14,470 --> 00:45:15,250
Surely.
979
00:45:15,250 --> 00:45:17,570
So let me in VS Code do this.
980
00:45:17,570 --> 00:45:20,050
Let me clear my terminal window to clean things up.
981
00:45:20,050 --> 00:45:21,170
And let me do this.
982
00:45:21,170 --> 00:45:23,620
Instead of calling the variable answer all over the place,
983
00:45:23,620 --> 00:45:26,080
let me call it first.
984
00:45:26,080 --> 00:45:27,490
And I'll ask two questions.
985
00:45:27,490 --> 00:45:28,880
What's your first name?
986
00:45:28,880 --> 00:45:32,620
And now let me do string last equals get_string--
987
00:45:32,620 --> 00:45:35,560
whoops, capitalization matters, so let me fix my capital S
988
00:45:35,560 --> 00:45:41,720
there-- quote/unquote, What's your last name, question mark, semicolon.
989
00:45:41,720 --> 00:45:47,320
And now we'll plug in one %s and a second %s.
990
00:45:47,320 --> 00:45:52,720
And now I'm going to plug in first first and last last, coincidentally.
991
00:45:52,720 --> 00:45:55,240
And now I'm going to go back to the terminal window.
992
00:45:55,240 --> 00:46:00,280
Make hello-- crossing my fingers, all good-- ./hello.
993
00:46:00,280 --> 00:46:02,620
Here's my first question, David.
994
00:46:02,620 --> 00:46:04,240
Here's my second question, Malan.
995
00:46:04,240 --> 00:46:05,650
And again?
996
00:46:05,650 --> 00:46:06,670
Hello, David Malan.
997
00:46:06,670 --> 00:46:08,440
So it just inserts them left to right.
998
00:46:08,440 --> 00:46:10,510
All I was doing for parity with Scratch though--
999
00:46:10,510 --> 00:46:12,670
and let me go ahead and undo this again.
1000
00:46:12,670 --> 00:46:15,130
I'll go back to answer, like this.
1001
00:46:15,130 --> 00:46:17,800
I'll go back to just asking for the person's name.
1002
00:46:17,800 --> 00:46:19,300
I'm going to delete mention of last.
1003
00:46:19,300 --> 00:46:21,520
I'm going to delete mention of the second %s.
1004
00:46:21,520 --> 00:46:24,400
And now if I recompile this simpler version,
1005
00:46:24,400 --> 00:46:27,720
oh, I did screw up-- didn't intend it.
1006
00:46:27,720 --> 00:46:29,220
What did I do wrong?
1007
00:46:29,220 --> 00:46:31,353
AUDIENCE: You forgot to change first in line 7.
1008
00:46:31,353 --> 00:46:33,270
DAVID J. MALAN: Yeah, so just newbie mistakes.
1009
00:46:33,270 --> 00:46:37,800
So I changed my variable back to answer just to be consistent with week 0,
1010
00:46:37,800 --> 00:46:39,610
but I didn't change it here.
1011
00:46:39,610 --> 00:46:42,750
So I have an use of undeclared identifier first.
1012
00:46:42,750 --> 00:46:46,470
It's undeclared in the sense that I declared answer a line prior.
1013
00:46:46,470 --> 00:46:47,950
I didn't declare first.
1014
00:46:47,950 --> 00:46:51,060
So indeed, intuitively, I want to just change that to that.
1015
00:46:51,060 --> 00:46:56,740
Let me now do make hello again, ./hello, type in just my first name this time.
1016
00:46:56,740 --> 00:46:59,400
And there it is-- hello, David.
1017
00:46:59,400 --> 00:47:02,220
Questions on this then syntax with printf?
1018
00:47:02,220 --> 00:47:03,390
Yeah?
1019
00:47:03,390 --> 00:47:04,608
AUDIENCE: [INAUDIBLE]
1020
00:47:04,608 --> 00:47:06,150
DAVID J. MALAN: Ah, the placeholder--
1021
00:47:06,150 --> 00:47:09,240
I'll zoom in-- is just a single percent then an s.
1022
00:47:09,240 --> 00:47:17,370
So inside of my string here is %s, and then I have a comma outside the quotes,
1023
00:47:17,370 --> 00:47:23,400
and then the name of the variable whose value I want to plug in for that %s.
1024
00:47:23,400 --> 00:47:28,080
And now notice there's technically two commas inside
1025
00:47:28,080 --> 00:47:30,300
of these parentheses on line 7.
1026
00:47:30,300 --> 00:47:33,690
And yet, I claim that printf, at the moment,
1027
00:47:33,690 --> 00:47:37,290
is only taking in two arguments.
1028
00:47:37,290 --> 00:47:41,582
Why is there then two commas but only two arguments?
1029
00:47:41,582 --> 00:47:43,290
If there were two commas, you would think
1030
00:47:43,290 --> 00:47:45,700
there would be three arguments, right?
1031
00:47:45,700 --> 00:47:47,904
AUDIENCE: The comma is between the quotes,
1032
00:47:47,904 --> 00:47:49,700
so it counts as a comma [INAUDIBLE]
1033
00:47:49,700 --> 00:47:50,700
DAVID J. MALAN: Exactly.
1034
00:47:50,700 --> 00:47:53,160
The comma in between the quotes is just an English thing.
1035
00:47:53,160 --> 00:47:55,240
It's separating the hello from the name.
1036
00:47:55,240 --> 00:47:57,690
So that's why indeed it's not only in quotes,
1037
00:47:57,690 --> 00:48:01,710
that's also why programs like VS Code tend to syntax highlight it
1038
00:48:01,710 --> 00:48:05,580
a little differently just so that it jumps out as different to you,
1039
00:48:05,580 --> 00:48:08,790
even though, in this case, it's a little subtle-- a light blue versus white--
1040
00:48:08,790 --> 00:48:10,830
but indeed, it's trying its best.
1041
00:48:10,830 --> 00:48:13,150
Other questions now on this placeholder?
1042
00:48:13,150 --> 00:48:13,650
Yeah?
1043
00:48:13,650 --> 00:48:16,390
AUDIENCE: If you wanted to put an exclamation point at the end,
1044
00:48:16,390 --> 00:48:18,460
would you put a comma after your answer variable,
1045
00:48:18,460 --> 00:48:21,943
and would that put it [INAUDIBLE],, or would you have to add a new line?
1046
00:48:21,943 --> 00:48:23,360
DAVID J. MALAN: Ah, good question.
1047
00:48:23,360 --> 00:48:25,750
If I wanted to add an exclamation point after the name,
1048
00:48:25,750 --> 00:48:28,230
would I have to add another placeholder and so forth?
1049
00:48:28,230 --> 00:48:29,980
I could actually do that much more simply.
1050
00:48:29,980 --> 00:48:33,610
I can just put the exclamation point right after the percent sign.
1051
00:48:33,610 --> 00:48:35,830
I don't need an additional placeholder, per se.
1052
00:48:35,830 --> 00:48:40,030
If I zoom out now and run make hello again, ./hello,
1053
00:48:40,030 --> 00:48:42,280
and type in just my name-- no exclamation point--
1054
00:48:42,280 --> 00:48:45,580
now you'll see more excitedly, hello, comma, David.
1055
00:48:45,580 --> 00:48:46,510
So printf is smart.
1056
00:48:46,510 --> 00:48:51,400
It will figure out where the %s is and then go and replace it.
1057
00:48:51,400 --> 00:48:54,662
Now, let me propose that a common thing in programming
1058
00:48:54,662 --> 00:48:57,370
is that as soon as we make a decision as how to design something,
1059
00:48:57,370 --> 00:49:01,240
we often paint ourselves into a corner and regret a decision.
1060
00:49:01,240 --> 00:49:08,410
Can anyone think of a problem that arises from using %s as a placeholder
1061
00:49:08,410 --> 00:49:11,680
in this string to printf?
1062
00:49:11,680 --> 00:49:14,635
What could go wrong if we're using percent in this special way?
1063
00:49:14,635 --> 00:49:16,775
AUDIENCE: [INAUDIBLE]
1064
00:49:16,775 --> 00:49:17,650
DAVID J. MALAN: Yeah.
1065
00:49:17,650 --> 00:49:20,320
If you literally want to say, for whatever weird reason,
1066
00:49:20,320 --> 00:49:23,245
%s on the screen-- or honestly, even just a single %.
1067
00:49:23,245 --> 00:49:25,930
It turns out that a percent sign is treated
1068
00:49:25,930 --> 00:49:29,650
specially inside of printf strings.
1069
00:49:29,650 --> 00:49:31,460
So what's the solution here?
1070
00:49:31,460 --> 00:49:34,690
There's different patterns of solutions to problems like these.
1071
00:49:34,690 --> 00:49:40,990
But suppose you wanted to say, I got 100%, for instance.
1072
00:49:40,990 --> 00:49:43,480
Let me go ahead and change this completely.
1073
00:49:43,480 --> 00:49:47,290
So I got 100% on your test or whatever.
1074
00:49:47,290 --> 00:49:50,860
All right, let me go ahead and run make hello, Enter.
1075
00:49:50,860 --> 00:49:52,950
All right, so invalid conversions specifier.
1076
00:49:52,950 --> 00:49:55,450
I mean, I have no idea what this means, but it's underlining
1077
00:49:55,450 --> 00:49:57,410
the percent sign as problematic.
1078
00:49:57,410 --> 00:50:00,730
Well, it turns out that humans years ago decided, ugh, all right, damn it.
1079
00:50:00,730 --> 00:50:01,615
We already used %.
1080
00:50:01,615 --> 00:50:04,990
Well, two percent signs will mean one %, literally.
1081
00:50:04,990 --> 00:50:09,727
So now if I rerun make hello, aha, ./hello, I got 100%.
1082
00:50:09,727 --> 00:50:13,060
So there's going to be things like that, honestly, that you have to ask someone,
1083
00:50:13,060 --> 00:50:15,190
you have to Google, you have to look it up in the documentation.
1084
00:50:15,190 --> 00:50:17,840
But there's always a solution to those kinds of problems.
1085
00:50:17,840 --> 00:50:19,930
And thankfully, they don't come up all that often.
1086
00:50:19,930 --> 00:50:21,230
Yeah?
1087
00:50:21,230 --> 00:50:22,360
Oh, just pointing.
1088
00:50:22,360 --> 00:50:23,060
Other questions?
1089
00:50:23,060 --> 00:50:23,560
Yeah?
1090
00:50:23,560 --> 00:50:27,622
AUDIENCE: So if you have multiple [INAUDIBLE]
1091
00:50:27,622 --> 00:50:29,580
DAVID J. MALAN: If you have multiple variables,
1092
00:50:29,580 --> 00:50:31,380
it is in the left-right order.
1093
00:50:31,380 --> 00:50:34,187
So printf will analyze the first string of text
1094
00:50:34,187 --> 00:50:35,520
that you pass in between quotes.
1095
00:50:35,520 --> 00:50:40,290
And whatever the first % is, the first variable that's passed in after a comma
1096
00:50:40,290 --> 00:50:41,207
gets plugged in there.
1097
00:50:41,207 --> 00:50:44,290
And then the second gets plugged into the second, third, and to the third,
1098
00:50:44,290 --> 00:50:44,832
and so forth.
1099
00:50:44,832 --> 00:50:47,130
So it's just based on left to right.
1100
00:50:47,130 --> 00:50:48,220
Yeah?
1101
00:50:48,220 --> 00:50:50,760
AUDIENCE: This more of a clarification question.
1102
00:50:50,760 --> 00:50:52,453
What exactly does the %s mean?
1103
00:50:52,453 --> 00:50:54,120
DAVID J. MALAN: It's just a placeholder.
1104
00:50:54,120 --> 00:50:58,570
It's called a format code, and it just means colloquially, plug in some value
1105
00:50:58,570 --> 00:50:59,070
here.
1106
00:50:59,070 --> 00:51:04,060
And printf-- the humans who wrote printf decades ago decided to treat %s
1107
00:51:04,060 --> 00:51:04,560
special.
1108
00:51:04,560 --> 00:51:04,890
Why?
1109
00:51:04,890 --> 00:51:05,490
Just because.
1110
00:51:05,490 --> 00:51:06,900
They needed some placeholder.
1111
00:51:06,900 --> 00:51:10,110
They decided that, eh, no one's ever going to really want to type %s.
1112
00:51:10,110 --> 00:51:12,420
And if they do, they can just do %%s.
1113
00:51:12,420 --> 00:51:17,280
So they decided to implement printf in such a way that they have code that
1114
00:51:17,280 --> 00:51:20,190
analyzes whatever text comes in, looks for %s,
1115
00:51:20,190 --> 00:51:24,960
and then somehow plugs in the subsequent values into that placeholder.
1116
00:51:24,960 --> 00:51:28,390
And just the-- ah, question?
1117
00:51:28,390 --> 00:51:28,890
Sorry?
1118
00:51:28,890 --> 00:51:30,870
AUDIENCE: What if we wanted to do our initials or something?
1119
00:51:30,870 --> 00:51:33,720
DAVID J. MALAN: Ah, so what if you wanted to do a single characters,
1120
00:51:33,720 --> 00:51:38,070
like initials, like D M or D J M for first, middle, last, absolutely.
1121
00:51:38,070 --> 00:51:41,670
And that, too, is a perfect segue from the two of you to what, in general,
1122
00:51:41,670 --> 00:51:44,310
are going to be called data types in C.
1123
00:51:44,310 --> 00:51:48,135
So it turns out, in C, there's not only strings as text.
1124
00:51:48,135 --> 00:51:50,760
And we'll see in more detail over the next couple of weeks what
1125
00:51:50,760 --> 00:51:52,560
a string really is underneath the hood.
1126
00:51:52,560 --> 00:51:55,620
But strings of text are not the only thing that programs can output.
1127
00:51:55,620 --> 00:51:58,860
They can indeed output single characters, as for initials.
1128
00:51:58,860 --> 00:52:01,020
They can output integers as well.
1129
00:52:01,020 --> 00:52:03,510
Turns out that printf has different format codes
1130
00:52:03,510 --> 00:52:05,868
for all sorts of different data types.
1131
00:52:05,868 --> 00:52:08,410
And just some of the data types we'll see in the coming weeks
1132
00:52:08,410 --> 00:52:10,530
will be this list here, which you'll notice it
1133
00:52:10,530 --> 00:52:13,920
almost perfectly lines up with the CS50 functions
1134
00:52:13,920 --> 00:52:17,722
that I rattled off earlier, like get_char, get_int, get_string.
1135
00:52:17,722 --> 00:52:20,430
The reason we called those functions that is because each of them
1136
00:52:20,430 --> 00:52:23,490
is designed to return to you a different type of value.
1137
00:52:23,490 --> 00:52:26,070
We've used get_string already in this example here.
1138
00:52:26,070 --> 00:52:29,880
We'll soon see get_int, and we'll see opportunities to use others.
1139
00:52:29,880 --> 00:52:33,660
But these indeed are the menu of available data
1140
00:52:33,660 --> 00:52:35,940
types plus others-- dot, dot, dot-- that you
1141
00:52:35,940 --> 00:52:38,400
can use when writing a program in C.
1142
00:52:38,400 --> 00:52:41,430
The onus, therefore, is on you to decide in advance,
1143
00:52:41,430 --> 00:52:44,250
do I want to store an int in this variable, or a string,
1144
00:52:44,250 --> 00:52:48,420
or, heck, when writing fancier code, an image, or a sound, or a video, even.
1145
00:52:48,420 --> 00:52:51,030
Those can all be different data types, dot dot dot.
1146
00:52:51,030 --> 00:52:54,300
But for now we'll focus really on just these primitives.
1147
00:52:54,300 --> 00:52:54,988
That was a lot.
1148
00:52:54,988 --> 00:52:57,030
Let's go ahead and take a five-minute break here.
1149
00:52:57,030 --> 00:52:57,680
No cookies yet.
1150
00:52:57,680 --> 00:53:00,180
But in five minutes, we'll come back, dive into more detail.
1151
00:53:00,180 --> 00:53:02,097
On our second break today, we'll have cookies.
1152
00:53:02,097 --> 00:53:05,640
1153
00:53:05,640 --> 00:53:07,295
All right, we are back.
1154
00:53:07,295 --> 00:53:09,170
And so if you have been playing along at home
1155
00:53:09,170 --> 00:53:11,587
but hitting some bumps in the road, that's totally normal.
1156
00:53:11,587 --> 00:53:13,430
And indeed, the goals of lecture generally
1157
00:53:13,430 --> 00:53:16,395
will be to give you a sense, conceptually, of where we'll
1158
00:53:16,395 --> 00:53:18,020
be going during the course of the week.
1159
00:53:18,020 --> 00:53:20,498
But it's indeed through the hands-on labs and problem sets
1160
00:53:20,498 --> 00:53:22,790
that you'll really have an opportunity at your own pace
1161
00:53:22,790 --> 00:53:25,730
to work through some of those same bumps in the road.
1162
00:53:25,730 --> 00:53:28,880
But for today, let me give you a few more building blocks.
1163
00:53:28,880 --> 00:53:31,460
And these two will translate from Scratch initially.
1164
00:53:31,460 --> 00:53:33,860
Namely, like conditionals, like how now in C,
1165
00:53:33,860 --> 00:53:36,690
after knowing now how we can use functions--
1166
00:53:36,690 --> 00:53:39,530
at least get_string and printf--
1167
00:53:39,530 --> 00:53:43,370
and we can use variables like the string I created earlier,
1168
00:53:43,370 --> 00:53:46,490
how can I now add to the mix things like decision making and conditionals
1169
00:53:46,490 --> 00:53:47,100
at that?
1170
00:53:47,100 --> 00:53:50,780
Well, with conditionals in Scratch, we had this kind of syntax on the left.
1171
00:53:50,780 --> 00:53:55,220
Here in Scratch is how you might express if two variables, x and y,
1172
00:53:55,220 --> 00:53:56,360
have this relationship.
1173
00:53:56,360 --> 00:54:01,020
If x is less than y, then say on the screen, x is less than y.
1174
00:54:01,020 --> 00:54:03,320
Well, let me translate that to the right now in C code.
1175
00:54:03,320 --> 00:54:06,500
So in C, the corresponding code is going to look like this,
1176
00:54:06,500 --> 00:54:08,390
assuming x and y already exist--
1177
00:54:08,390 --> 00:54:09,530
more on that later.
1178
00:54:09,530 --> 00:54:13,140
And notice a pattern we're going to see again and again.
1179
00:54:13,140 --> 00:54:18,560
There is going to be parentheses around the x and less than y-- so parentheses
1180
00:54:18,560 --> 00:54:20,390
around the Boolean expression, recall.
1181
00:54:20,390 --> 00:54:23,768
The Boolean expression is the true/false, the yes/no answer,
1182
00:54:23,768 --> 00:54:26,060
a question that you're trying to ask in order to decide
1183
00:54:26,060 --> 00:54:27,680
whether or not to do something.
1184
00:54:27,680 --> 00:54:29,310
So you use parentheses there.
1185
00:54:29,310 --> 00:54:34,550
So similar in functions where we use parentheses for printf and parentheses
1186
00:54:34,550 --> 00:54:38,660
for get_string, and this is just a weird inconsistency stylistically.
1187
00:54:38,660 --> 00:54:42,860
When using the keyword if, you should, as a matter of best practice,
1188
00:54:42,860 --> 00:54:44,690
put a space after the word if.
1189
00:54:44,690 --> 00:54:49,070
When using a function like printf or get_string, you shouldn't.
1190
00:54:49,070 --> 00:54:52,400
Both will work, but you'll find that these are conventions stylistically
1191
00:54:52,400 --> 00:54:55,970
that most people adhere to-- so space when using an if here.
1192
00:54:55,970 --> 00:54:58,850
All right, now inside of the curly braces
1193
00:54:58,850 --> 00:55:02,360
is where the actual code goes that you want to execute conditionally.
1194
00:55:02,360 --> 00:55:05,270
So if you want to print out x is less than y
1195
00:55:05,270 --> 00:55:08,570
only if x is actually less than y in C, you
1196
00:55:08,570 --> 00:55:10,670
use this open curly brace-- which, up until now,
1197
00:55:10,670 --> 00:55:12,740
you've probably rarely used on your keyboard--
1198
00:55:12,740 --> 00:55:14,820
and the closed curly brace down here.
1199
00:55:14,820 --> 00:55:17,960
And those are hugging, if you will, the one or more lines
1200
00:55:17,960 --> 00:55:20,990
of code underneath the if-- very similar in spirit
1201
00:55:20,990 --> 00:55:25,050
to how the orange block here hugs the purple puzzle piece here.
1202
00:55:25,050 --> 00:55:27,050
So there's no graphics in C. It's all text.
1203
00:55:27,050 --> 00:55:31,760
So you can think of those curly braces as really representing the same idea.
1204
00:55:31,760 --> 00:55:37,460
As a side note, if you only have one line of code inside of the if
1205
00:55:37,460 --> 00:55:41,430
condition, if you will, you strictly, speaking, don't need the curly braces.
1206
00:55:41,430 --> 00:55:43,670
But as a matter of good style, do include them.
1207
00:55:43,670 --> 00:55:46,040
It will make more obvious what your intent is.
1208
00:55:46,040 --> 00:55:48,650
How about in Scratch if you wanted to express this--
1209
00:55:48,650 --> 00:55:52,700
two ways in the road that you might go, left or right, so to speak?
1210
00:55:52,700 --> 00:55:56,480
Well, if x is less than y, I want to say, x is less than y.
1211
00:55:56,480 --> 00:56:01,190
Else, I want to say the opposite, x is not less than y in this case.
1212
00:56:01,190 --> 00:56:03,710
So I'm making a decision based on that Boolean expression.
1213
00:56:03,710 --> 00:56:08,340
In C, It's almost the same, but you're adding to the mix the key word else--
1214
00:56:08,340 --> 00:56:11,210
so MIT borrowed for Scratch the same keyword there--
1215
00:56:11,210 --> 00:56:14,690
and a second pair of curly braces, open and close respectively.
1216
00:56:14,690 --> 00:56:17,150
And you might guess now what goes inside of those.
1217
00:56:17,150 --> 00:56:22,905
Well, you print out x is less than y, or you print out x is not less than y.
1218
00:56:22,905 --> 00:56:25,280
All right, what if there is a three-way fork in the road?
1219
00:56:25,280 --> 00:56:29,370
In Scratch, this actually gets a little unwieldy graphically, if you will.
1220
00:56:29,370 --> 00:56:34,490
But notice that in Scratch, this is how we could express if x is less than y,
1221
00:56:34,490 --> 00:56:36,110
say x is less than y.
1222
00:56:36,110 --> 00:56:40,760
Else if x is greater than y, say x is greater than y.
1223
00:56:40,760 --> 00:56:45,470
Else if x equals y, then say x is equal to y.
1224
00:56:45,470 --> 00:56:48,770
Now, minor inconsistency here.
1225
00:56:48,770 --> 00:56:51,980
Just a little bit ago, I claimed, in C, that an equal sign
1226
00:56:51,980 --> 00:56:54,435
represents what operation?
1227
00:56:54,435 --> 00:56:55,310
AUDIENCE: Assignment.
1228
00:56:55,310 --> 00:56:57,770
DAVID J. MALAN: Assignment from right to left.
1229
00:56:57,770 --> 00:56:59,900
Insofar as Scratch is really meant for kids,
1230
00:56:59,900 --> 00:57:03,350
and they didn't really want to get into the weeds of this kind of semantic,
1231
00:57:03,350 --> 00:57:06,360
equal sign in Scratch means equality.
1232
00:57:06,360 --> 00:57:09,050
However, we're going to need to fix this in C in just a moment.
1233
00:57:09,050 --> 00:57:11,750
In C, equal sign means assignment right to left.
1234
00:57:11,750 --> 00:57:14,210
In Scratch, it literally means what you would expect.
1235
00:57:14,210 --> 00:57:17,690
All right, let's translate this code then to C. On the right,
1236
00:57:17,690 --> 00:57:20,780
this code would correspond really to this.
1237
00:57:20,780 --> 00:57:24,110
And you can perhaps see, somewhat goofily, what the solution was,
1238
00:57:24,110 --> 00:57:28,160
not unlike the %% solution earlier when humans painted themselves into one
1239
00:57:28,160 --> 00:57:29,100
other corner.
1240
00:57:29,100 --> 00:57:32,900
You say if, you say else if, and you say else if,
1241
00:57:32,900 --> 00:57:36,620
and how did we resolve the use of a single equal sign already?
1242
00:57:36,620 --> 00:57:39,650
In C, when you want to express equality--
1243
00:57:39,650 --> 00:57:42,110
is the thing on the left equal to the thing on the right--
1244
00:57:42,110 --> 00:57:45,590
you literally use two equal signs right next to each other, no space
1245
00:57:45,590 --> 00:57:47,090
in between them.
1246
00:57:47,090 --> 00:57:50,960
But now this code would be correct on both the left and the right,
1247
00:57:50,960 --> 00:57:53,640
whether you're doing this in Scratch or C respectively.
1248
00:57:53,640 --> 00:57:58,400
But now we can nitpick our code, specifically the design thereof.
1249
00:57:58,400 --> 00:58:02,820
Logically, can anyone critique the design of this code,
1250
00:58:02,820 --> 00:58:04,280
either in Scratch or C?
1251
00:58:04,280 --> 00:58:06,200
I feel like we could do better.
1252
00:58:06,200 --> 00:58:07,576
How about in back?
1253
00:58:07,576 --> 00:58:10,908
AUDIENCE: The only option after it getting greater than or less
1254
00:58:10,908 --> 00:58:12,930
than is [INAUDIBLE].
1255
00:58:12,930 --> 00:58:13,930
DAVID J. MALAN: Perfect.
1256
00:58:13,930 --> 00:58:17,350
Logically, it's got to be the case that x is less than y,
1257
00:58:17,350 --> 00:58:22,510
or x is greater than y, or by conclusion, it's got to be equal to y.
1258
00:58:22,510 --> 00:58:24,910
So why are you wasting my time or the computer's time
1259
00:58:24,910 --> 00:58:26,170
asking a third question?
1260
00:58:26,170 --> 00:58:30,160
You don't need to ask this final else if because logically, as you note,
1261
00:58:30,160 --> 00:58:31,510
it should go without saying.
1262
00:58:31,510 --> 00:58:33,220
So it's a minor tweak.
1263
00:58:33,220 --> 00:58:37,120
You're doing extra work potentially in the cases where x equals y.
1264
00:58:37,120 --> 00:58:38,350
So we can just refine that.
1265
00:58:38,350 --> 00:58:42,280
And just like in Scratch, you could just use an else block, similarly in C,
1266
00:58:42,280 --> 00:58:47,110
could we simplify this code to just an else, a sort of catch-all logically
1267
00:58:47,110 --> 00:58:49,720
that just handles the reality that, of course, that's going
1268
00:58:49,720 --> 00:58:52,400
to be the final situation instead.
1269
00:58:52,400 --> 00:58:55,570
All right, so we have this ability now to express conditionals
1270
00:58:55,570 --> 00:58:56,770
with Boolean expressions.
1271
00:58:56,770 --> 00:58:59,030
Let's actually do something with this next here.
1272
00:58:59,030 --> 00:59:00,610
So let me go back to VS Code.
1273
00:59:00,610 --> 00:59:03,520
I've closed hello.c, and I want to create a second file
1274
00:59:03,520 --> 00:59:05,020
for the sake of some demos now.
1275
00:59:05,020 --> 00:59:09,160
Recall that you can create a new files by typing code, space, and then
1276
00:59:09,160 --> 00:59:11,440
the name of the file you want to create.
1277
00:59:11,440 --> 00:59:13,565
For instance, I might do compare.c.
1278
00:59:13,565 --> 00:59:15,940
I want to write a program that's going to start comparing
1279
00:59:15,940 --> 00:59:17,740
some values for demonstration's sake.
1280
00:59:17,740 --> 00:59:20,050
But before I do that, let me just show you
1281
00:59:20,050 --> 00:59:23,830
by opening the File Explorer at right, this is similar in spirit
1282
00:59:23,830 --> 00:59:25,180
to a Mac or PC.
1283
00:59:25,180 --> 00:59:28,750
You can go up here and click on an icon, and you can click on the plus icon,
1284
00:59:28,750 --> 00:59:30,010
and you'll get a blue box.
1285
00:59:30,010 --> 00:59:34,120
And I can type in compare.c, and I can just manually create it that way.
1286
00:59:34,120 --> 00:59:37,930
Notice that opens the tab even without my having typed code.
1287
00:59:37,930 --> 00:59:41,470
So again, on the left, you have a GUI, a Graphical User Interface,
1288
00:59:41,470 --> 00:59:42,820
albeit a simplistic one.
1289
00:59:42,820 --> 00:59:45,970
On the right and at the bottom here, you have a command line interface,
1290
00:59:45,970 --> 00:59:47,260
but they're one in the same.
1291
00:59:47,260 --> 00:59:52,090
What's nice, though, is that if I close this file accidentally, intentionally,
1292
00:59:52,090 --> 00:59:54,790
whatnot, I can reopen it without creating
1293
00:59:54,790 --> 00:59:58,930
a new one by just running that same command-- code, space, compare.c.
1294
00:59:58,930 --> 01:00:00,340
So code is a VS Code thing.
1295
01:00:00,340 --> 01:00:02,140
It's just a user-friendly shortcut.
1296
01:00:02,140 --> 01:00:05,888
But it's just creating a file or opening an existing file like that.
1297
01:00:05,888 --> 01:00:08,930
I'm going to hide the File Explorer just to make more room for code here.
1298
01:00:08,930 --> 01:00:10,222
And let's go ahead and do this.
1299
01:00:10,222 --> 01:00:14,200
Let's write a program that compares two values that the human inputs,
1300
01:00:14,200 --> 01:00:15,340
but not strings this time.
1301
01:00:15,340 --> 01:00:17,170
Let's use some actual integers.
1302
01:00:17,170 --> 01:00:20,920
All right, I'm going to go ahead and include the CS50 library's header
1303
01:00:20,920 --> 01:00:22,090
file at top--
1304
01:00:22,090 --> 01:00:23,260
cs50.h.
1305
01:00:23,260 --> 01:00:25,804
I'm going to also include stdio.h.
1306
01:00:25,804 --> 01:00:26,668
Why?
1307
01:00:26,668 --> 01:00:31,190
One gives me user-friendly input via get_string, get_int, and so forth.
1308
01:00:31,190 --> 01:00:35,560
One gives me user-friendly output via printf in the case of stdio.h.
1309
01:00:35,560 --> 01:00:39,430
Now I'm just going to blindly type this line of code, which we'll come back to
1310
01:00:39,430 --> 01:00:40,310
in future weeks.
1311
01:00:40,310 --> 01:00:42,520
But for now, that's analogous to the when
1312
01:00:42,520 --> 01:00:44,920
green flag clicked code in Scratch.
1313
01:00:44,920 --> 01:00:46,460
And now let's go ahead and do this.
1314
01:00:46,460 --> 01:00:49,210
Let me go ahead and get_int from the user
1315
01:00:49,210 --> 01:00:51,713
and ask the user, What's x, question mark.
1316
01:00:51,713 --> 01:00:53,380
I'm not going to bother with a new line.
1317
01:00:53,380 --> 01:00:56,410
I want to keep it all in one line, just for aesthetics' sake.
1318
01:00:56,410 --> 01:00:59,710
But when I get back and int, just like I get back a string,
1319
01:00:59,710 --> 01:01:01,580
I get back a return value.
1320
01:01:01,580 --> 01:01:06,040
So if I want to store the result of get_int somewhere,
1321
01:01:06,040 --> 01:01:07,927
I had better put it in a variable.
1322
01:01:07,927 --> 01:01:09,760
And I can call the variable anything I want.
1323
01:01:09,760 --> 01:01:12,790
Previously, I used answer, or first, or last.
1324
01:01:12,790 --> 01:01:14,410
Now I'm going to use x.
1325
01:01:14,410 --> 01:01:18,310
But there's still two things left to do here logically, even though we
1326
01:01:18,310 --> 01:01:19,870
haven't technically done this yet.
1327
01:01:19,870 --> 01:01:21,130
What I still need to do?
1328
01:01:21,130 --> 01:01:22,410
AUDIENCE: A semicolon.
1329
01:01:22,410 --> 01:01:24,535
DAVID J. MALAN: So I need the semicolon at the end.
1330
01:01:24,535 --> 01:01:26,010
AUDIENCE: And the int first.
1331
01:01:26,010 --> 01:01:27,885
DAVID J. MALAN: And the int at the beginning.
1332
01:01:27,885 --> 01:01:31,257
You the programmer, starting today, need to decide what you're
1333
01:01:31,257 --> 01:01:32,840
going to be storing in your variables.
1334
01:01:32,840 --> 01:01:35,750
And you just need to tell the computer that so that it knows.
1335
01:01:35,750 --> 01:01:38,990
Now, as a teaser for languages like Python, more modern languages,
1336
01:01:38,990 --> 01:01:41,240
turns out, humans realized, well, gee, this is stupid.
1337
01:01:41,240 --> 01:01:44,115
Why can't the computer just figure out that I'm putting an int there?
1338
01:01:44,115 --> 01:01:45,800
Why do I have to tell it proactively?
1339
01:01:45,800 --> 01:01:48,080
So in some languages nowadays, like Python
1340
01:01:48,080 --> 01:01:50,990
will get rid of some of this syntax, will get rid of the semicolons.
1341
01:01:50,990 --> 01:01:54,530
But for now we're looking at, really, the origins of how this all worked.
1342
01:01:54,530 --> 01:01:57,380
All right, so I've done this one line ending with semicolon.
1343
01:01:57,380 --> 01:01:58,440
Let me do one other.
1344
01:01:58,440 --> 01:02:02,390
And let me get a second int asking the user, What's y, question mark.
1345
01:02:02,390 --> 01:02:06,680
So almost identical but different responses from the user, hopefully.
1346
01:02:06,680 --> 01:02:10,490
And let me just ask simply if x is less than y,
1347
01:02:10,490 --> 01:02:14,690
in parentheses, then some curly braces, let me go ahead and print out,
1348
01:02:14,690 --> 01:02:18,950
quote/unquote, x is less than y backslash n.
1349
01:02:18,950 --> 01:02:20,600
And now just as a side note--
1350
01:02:20,600 --> 01:02:23,240
I seem to be typing fast.
1351
01:02:23,240 --> 01:02:25,610
Some of that is because VS Code is helping me.
1352
01:02:25,610 --> 01:02:29,720
Let me go back to this first line with the if, hit Enter.
1353
01:02:29,720 --> 01:02:33,630
And now I'm only on my keyboard going to type the open curly brace.
1354
01:02:33,630 --> 01:02:36,410
This is a feature of many text editors nowadays.
1355
01:02:36,410 --> 01:02:37,980
It finishes part of your thought.
1356
01:02:37,980 --> 01:02:38,480
Why?
1357
01:02:38,480 --> 01:02:40,580
Just to save yourself a keystroke to make sure
1358
01:02:40,580 --> 01:02:42,660
you don't accidentally forget the closing one.
1359
01:02:42,660 --> 01:02:45,750
So you'll notice sometimes that things are happening that you didn't type.
1360
01:02:45,750 --> 01:02:49,550
It's just VS Code or future programs you use trying to be helpful for you.
1361
01:02:49,550 --> 01:02:52,445
I'll go ahead and manually type out now printf
1362
01:02:52,445 --> 01:02:57,050
x is less than y backslash n close quote semicolon.
1363
01:02:57,050 --> 01:03:01,400
So let me go ahead now and try to run this, and we'll see--
1364
01:03:01,400 --> 01:03:02,000
let's see.
1365
01:03:02,000 --> 01:03:05,510
So make-- not hello-- but make compare because this file is
1366
01:03:05,510 --> 01:03:09,050
called compare.c, hitting Enter.
1367
01:03:09,050 --> 01:03:12,320
No output is good because it means I haven't messed up.
1368
01:03:12,320 --> 01:03:16,580
Let me ./compare instead of ./hello, Enter.
1369
01:03:16,580 --> 01:03:17,390
What's x?
1370
01:03:17,390 --> 01:03:18,410
How about 1?
1371
01:03:18,410 --> 01:03:19,040
What's y?
1372
01:03:19,040 --> 01:03:19,840
How about 2?
1373
01:03:19,840 --> 01:03:22,230
X is less than y.
1374
01:03:22,230 --> 01:03:23,387
Well, let's try it again.
1375
01:03:23,387 --> 01:03:25,220
And here, I'll save you some keystrokes too.
1376
01:03:25,220 --> 01:03:26,360
Let me clear my screen.
1377
01:03:26,360 --> 01:03:30,350
Instead of constantly typing ./this and ./that,
1378
01:03:30,350 --> 01:03:34,610
you can also use your keyboard's arrow keys in VS Code to scroll back through
1379
01:03:34,610 --> 01:03:35,310
time.
1380
01:03:35,310 --> 01:03:37,940
So if I hit Up once, there's the last command I wrote.
1381
01:03:37,940 --> 01:03:41,480
If I do it Up twice, there's the second to last command I wrote.
1382
01:03:41,480 --> 01:03:43,460
So sometimes if you see me doing things fast,
1383
01:03:43,460 --> 01:03:46,550
it's just because I'm cheating and going through my history like that.
1384
01:03:46,550 --> 01:03:51,380
All right, let me go ahead, though, and rerun ./compare, Enter.
1385
01:03:51,380 --> 01:03:52,670
Let's reverse it this time--
1386
01:03:52,670 --> 01:03:55,100
2 for x, 1 for y.
1387
01:03:55,100 --> 01:03:56,870
And now, of course, there's no output.
1388
01:03:56,870 --> 01:03:58,670
All right, well, that's logically to be expected
1389
01:03:58,670 --> 01:04:00,170
because we didn't have an else here.
1390
01:04:00,170 --> 01:04:00,980
So let's add that.
1391
01:04:00,980 --> 01:04:05,060
Else-- now let's open my curly braces, letting VS Code do one of them
1392
01:04:05,060 --> 01:04:12,350
for me-- printf, quote/unquote, x is not less than y backslash n semicolon.
1393
01:04:12,350 --> 01:04:16,430
Let me go ahead and try this again-- ./compare, Enter.
1394
01:04:16,430 --> 01:04:19,100
Again, 2 for x, 1 for y.
1395
01:04:19,100 --> 01:04:20,540
And we should see--
1396
01:04:20,540 --> 01:04:22,990
huh.
1397
01:04:22,990 --> 01:04:24,830
What did I do wrong?
1398
01:04:24,830 --> 01:04:27,050
Why am I not seeing any else output?
1399
01:04:27,050 --> 01:04:27,550
Yeah?
1400
01:04:27,550 --> 01:04:29,592
AUDIENCE: You changed your code when you rebuild.
1401
01:04:29,592 --> 01:04:30,690
You need to compile it.
1402
01:04:30,690 --> 01:04:31,290
DAVID J. MALAN: Exactly.
1403
01:04:31,290 --> 01:04:34,415
You got to get into the habit after you change your code of recompiling it.
1404
01:04:34,415 --> 01:04:36,420
Or otherwise, the zeros and ones in the server
1405
01:04:36,420 --> 01:04:39,000
are the old ones until you manually compile.
1406
01:04:39,000 --> 01:04:41,040
So let's fix this-- make compare, Enter.
1407
01:04:41,040 --> 01:04:42,030
No error messages.
1408
01:04:42,030 --> 01:04:45,420
That's good. ./compare, 2, 1.
1409
01:04:45,420 --> 01:04:47,320
And now I get back the output.
1410
01:04:47,320 --> 01:04:49,230
So x is not less than y.
1411
01:04:49,230 --> 01:04:52,390
How about if I go and add in the third condition?
1412
01:04:52,390 --> 01:04:55,650
Well, we can do this either efficiently or inefficiently.
1413
01:04:55,650 --> 01:04:57,270
Let me go ahead and refine this.
1414
01:04:57,270 --> 01:05:03,780
So else if x is greater than y, let's literally say, x is greater than y.
1415
01:05:03,780 --> 01:05:07,950
And now I could do x else if x equals equals y.
1416
01:05:07,950 --> 01:05:11,080
But I think we already claimed that that's unnecessarily inefficient.
1417
01:05:11,080 --> 01:05:12,810
So let's just have our catchall.
1418
01:05:12,810 --> 01:05:14,730
And here I'm going to say, quote/unquote,
1419
01:05:14,730 --> 01:05:19,960
x is equal to y backslash n, close quote there.
1420
01:05:19,960 --> 01:05:24,070
So I think now with this code, we've handled all three scenarios.
1421
01:05:24,070 --> 01:05:28,680
Let me go ahead and recompile it properly-- make compare, ./compare.
1422
01:05:28,680 --> 01:05:31,350
And now 1 and 2--
1423
01:05:31,350 --> 01:05:32,340
is less than y.
1424
01:05:32,340 --> 01:05:33,510
Let me run it again.
1425
01:05:33,510 --> 01:05:36,690
2 and 1-- x is greater than y.
1426
01:05:36,690 --> 01:05:41,100
And lastly, 1 and 1, and x is equal to y.
1427
01:05:41,100 --> 01:05:43,270
So for the most part, our code is getting longer.
1428
01:05:43,270 --> 01:05:45,870
We're up to 21 lines of code, though some of them
1429
01:05:45,870 --> 01:05:47,700
are just single characters on the screen.
1430
01:05:47,700 --> 01:05:49,410
Almost everything else is the same.
1431
01:05:49,410 --> 01:05:56,190
I'm using the CS50 library's header file for my get_int function, stdio.h
1432
01:05:56,190 --> 01:05:58,590
for my printf function, and the rest of this
1433
01:05:58,590 --> 01:06:01,810
is just now new syntax for conditionals as well.
1434
01:06:01,810 --> 01:06:04,350
Questions, then, on this C implementation
1435
01:06:04,350 --> 01:06:08,237
of just some basic comparisons like this?
1436
01:06:08,237 --> 01:06:08,820
Any questions?
1437
01:06:08,820 --> 01:06:09,320
Yeah?
1438
01:06:09,320 --> 01:06:12,360
AUDIENCE: Just a syntax question-- do the opening
1439
01:06:12,360 --> 01:06:14,530
brackets need to be on a separate line?
1440
01:06:14,530 --> 01:06:15,190
DAVID J. MALAN: Good question.
1441
01:06:15,190 --> 01:06:17,440
Do the opening brackets need to be on a separate line?
1442
01:06:17,440 --> 01:06:18,610
In CS50, yes.
1443
01:06:18,610 --> 01:06:21,310
What you'll see is that as part of the submission process,
1444
01:06:21,310 --> 01:06:25,540
we compare your code against a style guide, which is the norm in industry.
1445
01:06:25,540 --> 01:06:29,290
A company would have its own sense of style and how its code should look.
1446
01:06:29,290 --> 01:06:31,540
And there's generally automated tools within a company
1447
01:06:31,540 --> 01:06:35,080
that help give feedback on the code or stylize it as such.
1448
01:06:35,080 --> 01:06:38,410
There are alternative styles than what we use in the class.
1449
01:06:38,410 --> 01:06:41,500
We deliberately keep and ask that you keep
1450
01:06:41,500 --> 01:06:44,110
the curly braces on their own line, if only
1451
01:06:44,110 --> 01:06:48,430
because it rather resembles like the hugging nature of Scratch's blocks
1452
01:06:48,430 --> 01:06:51,370
and just makes clear that they're balanced, opened and closed.
1453
01:06:51,370 --> 01:06:56,020
However, another common paradigm in some languages and with some programmers
1454
01:06:56,020 --> 01:06:59,420
is to do something like this on each of them.
1455
01:06:59,420 --> 01:07:03,670
So you have the opening curly brace on the same line as here.
1456
01:07:03,670 --> 01:07:05,030
We do not recommend this.
1457
01:07:05,030 --> 01:07:07,900
This is en vogue in the JavaScript world and some others.
1458
01:07:07,900 --> 01:07:11,110
But ultimately in the real world, it's up to each individual programmer
1459
01:07:11,110 --> 01:07:13,720
and/or the company they're working for, if applicable,
1460
01:07:13,720 --> 01:07:16,210
to decide on those things.
1461
01:07:16,210 --> 01:07:18,640
All right, so beyond, then, these conditionals,
1462
01:07:18,640 --> 01:07:21,140
what if we want to do something that's maybe pretty common?
1463
01:07:21,140 --> 01:07:24,280
So almost every piece of software or website nowadays that you use
1464
01:07:24,280 --> 01:07:28,360
has you agree to some terms and conditions by typing Yes or No or just
1465
01:07:28,360 --> 01:07:30,280
Y for Yes and N for No.
1466
01:07:30,280 --> 01:07:33,195
So how could we implement some kind of agreement system?
1467
01:07:33,195 --> 01:07:34,070
Well, let me do this.
1468
01:07:34,070 --> 01:07:37,810
Let me create a new program, a third one called agree.c.
1469
01:07:37,810 --> 01:07:41,230
So I'm going to write code agree.c just to give myself a new tab.
1470
01:07:41,230 --> 01:07:44,230
I'm going to start, as always now, include cs50.h.
1471
01:07:44,230 --> 01:07:46,480
Let's include stdio.h.
1472
01:07:46,480 --> 01:07:50,770
And then let me do my int main(void)-- which, again, for today's purposes,
1473
01:07:50,770 --> 01:07:53,200
we'll take at face value is just copy/paste.
1474
01:07:53,200 --> 01:07:57,850
And if I just want to get Y or N, for instance, instead of Yes or No,
1475
01:07:57,850 --> 01:08:00,520
we can just use a simpler variable here.
1476
01:08:00,520 --> 01:08:03,800
How about just a char, a character, a single character?
1477
01:08:03,800 --> 01:08:07,120
So I can use get_char to ask the user, for instance,
1478
01:08:07,120 --> 01:08:09,760
do you agree, question mark.
1479
01:08:09,760 --> 01:08:12,880
But as before, I need to store this somewhere.
1480
01:08:12,880 --> 01:08:15,130
So I don't want a string because that's a single char.
1481
01:08:15,130 --> 01:08:16,180
I don't want an int.
1482
01:08:16,180 --> 01:08:17,380
I just want a char.
1483
01:08:17,380 --> 01:08:21,500
And it's literally C-H-A-R. And then I can call this thing anything I want.
1484
01:08:21,500 --> 01:08:25,370
It's conventional if you have a simple program with just a single variable
1485
01:08:25,370 --> 01:08:27,040
and it's of type char, call it c.
1486
01:08:27,040 --> 01:08:28,569
If it's an int, call it i.
1487
01:08:28,569 --> 01:08:29,830
If it's a string, call it s.
1488
01:08:29,830 --> 01:08:32,590
For now I'm just going to keep it simple and call it c.
1489
01:08:32,590 --> 01:08:34,370
And now I'm going to ask a question.
1490
01:08:34,370 --> 01:08:43,240
So if c equals equals, how about, quote/unquote, y, then
1491
01:08:43,240 --> 01:08:47,290
let me go ahead and print out Agreed backslash n,
1492
01:08:47,290 --> 01:08:50,380
as though they agreed to my terms and conditions.
1493
01:08:50,380 --> 01:08:51,880
Otherwise, let's see.
1494
01:08:51,880 --> 01:08:57,729
Else if the character equals equals, quote/unquote, n, then let me go ahead
1495
01:08:57,729 --> 01:09:03,609
and print out, say, Not agreed, as though they didn't, quote/unquote.
1496
01:09:03,609 --> 01:09:07,060
And let's leave it at that, I think, here initially.
1497
01:09:07,060 --> 01:09:11,830
Now, you'll notice one curiosity, one inconsistency perhaps.
1498
01:09:11,830 --> 01:09:15,760
Does anyone want to call it out, though it's somewhat subtle?
1499
01:09:15,760 --> 01:09:19,720
I've done something ever so slightly differently without explaining it yet.
1500
01:09:19,720 --> 01:09:20,380
Do you see it?
1501
01:09:20,380 --> 01:09:22,625
AUDIENCE: The single quotation mark.
1502
01:09:22,625 --> 01:09:23,500
DAVID J. MALAN: Yeah.
1503
01:09:23,500 --> 01:09:27,880
So I've suddenly used single quotation marks for my single characters
1504
01:09:27,880 --> 01:09:30,590
and double quotes for my actual strings of text.
1505
01:09:30,590 --> 01:09:34,210
This is a necessity in C. When you're dealing with strings, like strings
1506
01:09:34,210 --> 01:09:37,420
of text, like someone's name, a sentence, a paragraph, anything
1507
01:09:37,420 --> 01:09:41,380
really more than one character, you typically use double quotes.
1508
01:09:41,380 --> 01:09:42,399
And indeed, you must.
1509
01:09:42,399 --> 01:09:47,620
When dealing with deliberately single characters, like I am here for y or n,
1510
01:09:47,620 --> 01:09:49,819
you must use single quotes instead.
1511
01:09:49,819 --> 01:09:50,319
Why?
1512
01:09:50,319 --> 01:09:52,240
Because that makes sure that the computer
1513
01:09:52,240 --> 01:09:54,550
knows that it's indeed a char and not a string.
1514
01:09:54,550 --> 01:09:55,930
So double quotes are for strings.
1515
01:09:55,930 --> 01:09:57,520
Single quotes are for chars.
1516
01:09:57,520 --> 01:10:00,550
So with that said, let me go ahead and zoom out.
1517
01:10:00,550 --> 01:10:04,780
Let me go ahead in my terminal window run make agree, Enter.
1518
01:10:04,780 --> 01:10:08,770
Seems to work OK so let me go ahead and do ./agree.
1519
01:10:08,770 --> 01:10:12,250
Let me go ahead now and type in y.
1520
01:10:12,250 --> 01:10:13,090
Here we go.
1521
01:10:13,090 --> 01:10:14,980
Enter.
1522
01:10:14,980 --> 01:10:16,540
Huh.
1523
01:10:16,540 --> 01:10:17,470
Let me try that again.
1524
01:10:17,470 --> 01:10:18,580
Rerun ./agree.
1525
01:10:18,580 --> 01:10:20,170
How about no?
1526
01:10:20,170 --> 01:10:22,480
Enter.
1527
01:10:22,480 --> 01:10:25,720
Why is it not behaving as I would have expected?
1528
01:10:25,720 --> 01:10:28,480
AUDIENCE: Because you entered the capital Y and capital N.
1529
01:10:28,480 --> 01:10:29,590
DAVID J. MALAN: Yeah, I kind of cheated there,
1530
01:10:29,590 --> 01:10:32,230
and I hit the Caps Lock key just as I started typing in input.
1531
01:10:32,230 --> 01:10:32,730
Why?
1532
01:10:32,730 --> 01:10:35,950
Because I deliberately wanted to type in uppercase instead of lowercase,
1533
01:10:35,950 --> 01:10:37,540
which is kind of reasonable.
1534
01:10:37,540 --> 01:10:40,728
It's a little obnoxious if you force the user to toggle their caps lock
1535
01:10:40,728 --> 01:10:42,770
key on or off when you just need a simple answer.
1536
01:10:42,770 --> 01:10:45,310
That's not the best User Experience, or UX.
1537
01:10:45,310 --> 01:10:47,200
But it would work if I cooperated.
1538
01:10:47,200 --> 01:10:49,420
Let me run this again without caps lock--
1539
01:10:49,420 --> 01:10:52,030
y lowercase for yes.
1540
01:10:52,030 --> 01:10:55,210
Ah, that worked. n lowercase for no.
1541
01:10:55,210 --> 01:10:55,990
That worked.
1542
01:10:55,990 --> 01:10:57,910
But how could I get it to work for both?
1543
01:10:57,910 --> 01:10:59,180
Well, how about this?
1544
01:10:59,180 --> 01:11:01,400
Let me go ahead and just add two possibilities.
1545
01:11:01,400 --> 01:11:06,340
So else if c equals equals quote/unquote capital Y,
1546
01:11:06,340 --> 01:11:10,720
then also do printf agreed backslash n.
1547
01:11:10,720 --> 01:11:17,470
And down here, else if c equals equals single quote capital N,
1548
01:11:17,470 --> 01:11:20,980
then go ahead and print out, again, Not agreed.
1549
01:11:20,980 --> 01:11:23,770
This, I will claim now, is correct.
1550
01:11:23,770 --> 01:11:26,980
And I'll do make agree real fast, ./agree.
1551
01:11:26,980 --> 01:11:28,210
And I'll use capital.
1552
01:11:28,210 --> 01:11:29,170
It now works.
1553
01:11:29,170 --> 01:11:30,610
I'll use capital.
1554
01:11:30,610 --> 01:11:32,200
It again works.
1555
01:11:32,200 --> 01:11:34,510
But this is perhaps not the best design.
1556
01:11:34,510 --> 01:11:39,220
Let me hide the terminal window and pull this up on the screen all at once.
1557
01:11:39,220 --> 01:11:43,195
Why might this arguably not be the best design, even though it's correct?
1558
01:11:43,195 --> 01:11:46,250
1559
01:11:46,250 --> 01:11:49,628
There's another term of art we can toss here, like [SNIFFS] something
1560
01:11:49,628 --> 01:11:51,170
smells kind of funky about this code.
1561
01:11:51,170 --> 01:11:52,450
This is an actual term of art.
1562
01:11:52,450 --> 01:11:54,100
There's code smell here.
1563
01:11:54,100 --> 01:11:55,930
Something smells a little off.
1564
01:11:55,930 --> 01:11:56,620
Why?
1565
01:11:56,620 --> 01:11:57,894
What do you think?
1566
01:11:57,894 --> 01:12:01,846
AUDIENCE: [INAUDIBLE]
1567
01:12:01,846 --> 01:12:06,895
1568
01:12:06,895 --> 01:12:07,770
DAVID J. MALAN: Yeah.
1569
01:12:07,770 --> 01:12:09,370
There's the same output again and again.
1570
01:12:09,370 --> 01:12:10,530
I mean, I manually typed it.
1571
01:12:10,530 --> 01:12:12,905
But honestly, I might as well have just copied and pasted
1572
01:12:12,905 --> 01:12:17,080
most of my original code to do it again and again for the two capital letters.
1573
01:12:17,080 --> 01:12:23,370
So if line 10 and 14 are the same AND line 18 and 22 are the same, AND then
1574
01:12:23,370 --> 01:12:26,875
the rest of these if and else ifs are almost the same,
1575
01:12:26,875 --> 01:12:28,500
[SNIFFS] there's some code smell there.
1576
01:12:28,500 --> 01:12:29,370
It's not well designed.
1577
01:12:29,370 --> 01:12:29,820
Why?
1578
01:12:29,820 --> 01:12:32,778
Because if I want to change things now, just like last week in Scratch,
1579
01:12:32,778 --> 01:12:35,970
I might have to change my code in multiple places or copy/paste
1580
01:12:35,970 --> 01:12:37,120
is never a good thing.
1581
01:12:37,120 --> 01:12:41,280
And god forbid I want to add support for Yes and No as full words,
1582
01:12:41,280 --> 01:12:42,760
it's really going to get long.
1583
01:12:42,760 --> 01:12:44,170
So how can we solve this?
1584
01:12:44,170 --> 01:12:47,160
Well, it turns out, we can combine some of these thoughts.
1585
01:12:47,160 --> 01:12:49,470
So let me try to improve the Yeses first.
1586
01:12:49,470 --> 01:12:54,325
It turns out, if I delete that clause, I can actually or things together.
1587
01:12:54,325 --> 01:12:57,450
In Scratch, there's a couple of puzzle pieces, if you didn't discover them,
1588
01:12:57,450 --> 01:12:59,430
that literally have the word or and the word
1589
01:12:59,430 --> 01:13:02,350
and on them, which allow you to combine Boolean expressions.
1590
01:13:02,350 --> 01:13:06,600
So that either this or this is true, or this and this is true.
1591
01:13:06,600 --> 01:13:09,270
In C, you can't just say the word or.
1592
01:13:09,270 --> 01:13:12,850
You instead use two vertical bars.
1593
01:13:12,850 --> 01:13:16,260
And vertical bars together mean or, logically.
1594
01:13:16,260 --> 01:13:21,780
And so I can say, c equals equals quote/unquote capital Y, Agreed.
1595
01:13:21,780 --> 01:13:24,270
And now I can get rid of this code down here.
1596
01:13:24,270 --> 01:13:29,100
And let me go ahead and say, vertical bar twice c
1597
01:13:29,100 --> 01:13:32,340
equals quote/unquote N in all caps.
1598
01:13:32,340 --> 01:13:36,870
And now my program's roughly a third smaller, which is good.
1599
01:13:36,870 --> 01:13:38,140
There's less redundancy.
1600
01:13:38,140 --> 01:13:43,290
And if I reopen my terminal window, rerun make of agree, ./agree,
1601
01:13:43,290 --> 01:13:49,860
now I can type little y or big Y and same thing for lowercase and uppercase
1602
01:13:49,860 --> 01:13:54,090
N. Any questions then on this syntax, whereby now you can combine thoughts
1603
01:13:54,090 --> 01:13:56,407
and just tighten things up?
1604
01:13:56,407 --> 01:13:57,990
And there'll be other such tricks too.
1605
01:13:57,990 --> 01:13:58,942
Yeah?
1606
01:13:58,942 --> 01:14:01,615
AUDIENCE: Is there not a function to just ignore the case?
1607
01:14:01,615 --> 01:14:03,240
DAVID J. MALAN: A really good question.
1608
01:14:03,240 --> 01:14:06,030
Is there not a function to just ignore the case?
1609
01:14:06,030 --> 01:14:07,890
Short answer, there is.
1610
01:14:07,890 --> 01:14:10,950
And we'll see how to do that in, actually, just about a week's time.
1611
01:14:10,950 --> 01:14:13,080
And in other languages, there's even more ways
1612
01:14:13,080 --> 01:14:17,100
to just canonicalize the user's input, throwing away any space characters
1613
01:14:17,100 --> 01:14:19,890
they might have accidentally hit, forcing everything to lowercase.
1614
01:14:19,890 --> 01:14:23,372
In C, It's going to be a little more work on our part to do that.
1615
01:14:23,372 --> 01:14:26,080
But in fact, as early as next week, we'll see how we can do that.
1616
01:14:26,080 --> 01:14:29,490
But for now we're comparing indeed just these literal values.
1617
01:14:29,490 --> 01:14:30,570
Other questions?
1618
01:14:30,570 --> 01:14:33,874
AUDIENCE: So we're assuming the user's putting in what they're suggesting.
1619
01:14:33,874 --> 01:14:37,618
How do you handle if they were to put in a number?
1620
01:14:37,618 --> 01:14:39,160
DAVID J. MALAN: Really good question.
1621
01:14:39,160 --> 01:14:42,068
So we are assuming, with this program and all of my last ones,
1622
01:14:42,068 --> 01:14:45,360
that the human's cooperating and when I ask for their name, they typed in David
1623
01:14:45,360 --> 01:14:49,290
and not 123, or, in this case, they typed in a single character and not
1624
01:14:49,290 --> 01:14:50,040
a full word.
1625
01:14:50,040 --> 01:14:53,520
So this is one of the features often of using a library.
1626
01:14:53,520 --> 01:14:59,550
So for instance, if I run agree again, and I say something like sure, Enter,
1627
01:14:59,550 --> 01:15:01,330
it rejects it altogether.
1628
01:15:01,330 --> 01:15:01,830
Why?
1629
01:15:01,830 --> 01:15:05,850
Because s, u, r, e is a string of characters.
1630
01:15:05,850 --> 01:15:07,320
It's not a single character.
1631
01:15:07,320 --> 01:15:11,380
Now, I could just say something like x, which is neither y nor n, of course.
1632
01:15:11,380 --> 01:15:14,190
But it tolerates that because it's a single character.
1633
01:15:14,190 --> 01:15:17,790
But built in to CS50's library is some built-in rejections
1634
01:15:17,790 --> 01:15:19,210
of inputs that's not expected.
1635
01:15:19,210 --> 01:15:22,920
So if you use get_int and the user types in not the number 1 or 2
1636
01:15:22,920 --> 01:15:26,940
but cat, C-A-T, it will just prompt them again, prompt them again.
1637
01:15:26,940 --> 01:15:30,480
And this is where, too, if you were to do this manually in C,
1638
01:15:30,480 --> 01:15:34,068
you end up writing this much code just to check for all of these errors.
1639
01:15:34,068 --> 01:15:36,360
That's why we use these training wheels for a few weeks
1640
01:15:36,360 --> 01:15:38,190
just to make the code more robust.
1641
01:15:38,190 --> 01:15:40,500
But in a few weeks' time, we'll take the liberty away.
1642
01:15:40,500 --> 01:15:44,970
And you'll see and understand how it's indeed doing all that.
1643
01:15:44,970 --> 01:15:46,750
All right, so how about this.
1644
01:15:46,750 --> 01:15:50,640
Let's now transition to something a little more Scratch-like, literally,
1645
01:15:50,640 --> 01:15:53,290
by creating how about another program here called meow--
1646
01:15:53,290 --> 01:15:54,567
so meow.c.
1647
01:15:54,567 --> 01:15:56,650
We won't have any audio capabilities for this one.
1648
01:15:56,650 --> 01:15:57,750
We'll just rely on print.
1649
01:15:57,750 --> 01:16:00,390
And suppose that I wanted to write a program
1650
01:16:00,390 --> 01:16:03,000
and see that just simulates a cat meowing.
1651
01:16:03,000 --> 01:16:04,960
So I don't need any user input just yet.
1652
01:16:04,960 --> 01:16:06,960
So I'm just going to use stdio.h.
1653
01:16:06,960 --> 01:16:09,940
I'm going to do my usual int main(void) up here.
1654
01:16:09,940 --> 01:16:13,710
And then I'm just going to go ahead and do printf meow backslash n.
1655
01:16:13,710 --> 01:16:16,650
And let's have this cat meow three times, like last week.
1656
01:16:16,650 --> 01:16:18,870
So I'm going to do meow, meow, meow.
1657
01:16:18,870 --> 01:16:21,100
Notice as an aside whenever you highlight the lines,
1658
01:16:21,100 --> 01:16:22,350
you'll see little dots appear.
1659
01:16:22,350 --> 01:16:24,780
This is just a visual cue to you to let you figure out
1660
01:16:24,780 --> 01:16:26,460
how many spaces you've indented.
1661
01:16:26,460 --> 01:16:30,133
VS Code, like a lot of editors, will automatically indent your code for you.
1662
01:16:30,133 --> 01:16:32,550
I've not been hitting the space bar four times every time.
1663
01:16:32,550 --> 01:16:34,020
I've not even been hitting Tab.
1664
01:16:34,020 --> 01:16:38,280
However, in C, the convention is indeed to indent lines
1665
01:16:38,280 --> 01:16:40,410
where appropriate by four spaces--
1666
01:16:40,410 --> 01:16:41,933
so not three, not five.
1667
01:16:41,933 --> 01:16:44,100
And these dots help you see things so that they just
1668
01:16:44,100 --> 01:16:45,850
line up as a matter of good style.
1669
01:16:45,850 --> 01:16:48,600
All right, so this program, I'm just going to stipulate right now,
1670
01:16:48,600 --> 01:16:49,600
is indeed going to work.
1671
01:16:49,600 --> 01:16:52,560
Make meow-- which is kind of cute-- and now meow.
1672
01:16:52,560 --> 01:16:54,000
There, three times.
1673
01:16:54,000 --> 01:16:54,540
Correct.
1674
01:16:54,540 --> 01:16:55,500
It's meowing three times.
1675
01:16:55,500 --> 01:16:57,060
But of course, this is not well designed.
1676
01:16:57,060 --> 01:16:58,935
It wasn't well designed in Scratch last week.
1677
01:16:58,935 --> 01:17:00,480
Why?
1678
01:17:00,480 --> 01:17:03,130
What should I be doing differently?
1679
01:17:03,130 --> 01:17:03,630
Yeah?
1680
01:17:03,630 --> 01:17:04,120
AUDIENCE: A loop?
1681
01:17:04,120 --> 01:17:05,412
AUDIENCE: This could be a loop.
1682
01:17:05,412 --> 01:17:07,140
DAVID J. MALAN: Yeah.
1683
01:17:07,140 --> 01:17:09,310
It's a perfect opportunity for a loop.
1684
01:17:09,310 --> 01:17:09,810
Why?
1685
01:17:09,810 --> 01:17:12,810
Because if you wanted to change maybe the capitalization of these words,
1686
01:17:12,810 --> 01:17:16,260
or you wanted to change the sound to like woof for a dog or something,
1687
01:17:16,260 --> 01:17:18,390
you'd have to change it one, two, three places.
1688
01:17:18,390 --> 01:17:20,160
And that's just kind of stupid, right?
1689
01:17:20,160 --> 01:17:23,020
In code, you should ideally change things in one place.
1690
01:17:23,020 --> 01:17:24,880
So how might I do that?
1691
01:17:24,880 --> 01:17:27,120
Well, we could introduce a loop, yes.
1692
01:17:27,120 --> 01:17:30,420
But we're going to need another building block as well that we had in Scratch,
1693
01:17:30,420 --> 01:17:32,710
namely those things called variables.
1694
01:17:32,710 --> 01:17:35,070
So recall that a variable, like an algebra-- x,
1695
01:17:35,070 --> 01:17:38,520
y, z, whatever-- can store a value for you.
1696
01:17:38,520 --> 01:17:42,630
And a variable in Scratch might have looked like this.
1697
01:17:42,630 --> 01:17:45,880
You use this orange puzzle piece to set a variable of any name,
1698
01:17:45,880 --> 01:17:46,890
not just x, y, or z.
1699
01:17:46,890 --> 01:17:49,710
But you could call it something more descriptive, like counter,
1700
01:17:49,710 --> 01:17:51,840
and you can set it equal to some value.
1701
01:17:51,840 --> 01:17:56,490
In C, the way to do this is similar to spirit to some of the syntax
1702
01:17:56,490 --> 01:17:57,570
we've seen thus far.
1703
01:17:57,570 --> 01:17:59,910
You start by saying the name of the variable you want,
1704
01:17:59,910 --> 01:18:01,740
a single equal sign, and then the value.
1705
01:18:01,740 --> 01:18:05,470
You want to initialize it too, copying therefore from right to left.
1706
01:18:05,470 --> 01:18:05,970
Why?
1707
01:18:05,970 --> 01:18:09,570
Because the equal sign denotes, again, assignment from right to left.
1708
01:18:09,570 --> 01:18:10,740
This isn't enough though.
1709
01:18:10,740 --> 01:18:12,282
You might have the intuition already.
1710
01:18:12,282 --> 01:18:16,170
What's missing probably from this line of code just to create a variable?
1711
01:18:16,170 --> 01:18:16,767
AUDIENCE: Int.
1712
01:18:16,767 --> 01:18:19,350
DAVID J. MALAN: So we need int to make sure the computer knows
1713
01:18:19,350 --> 01:18:20,610
that this is indeed an int.
1714
01:18:20,610 --> 01:18:23,802
And then lastly, semicolon as well.
1715
01:18:23,802 --> 01:18:25,260
And that now completes the thought.
1716
01:18:25,260 --> 01:18:27,302
So a little more annoying than Scratch, but we're
1717
01:18:27,302 --> 01:18:28,660
starting to see patterns here.
1718
01:18:28,660 --> 01:18:30,810
So not every piece of syntax will be new.
1719
01:18:30,810 --> 01:18:33,480
All right, if you want to increment the counter by one,
1720
01:18:33,480 --> 01:18:37,480
Scratch uses the verb change, and they mean add the value to counter.
1721
01:18:37,480 --> 01:18:41,700
So if I want to increment an existing variable called counter,
1722
01:18:41,700 --> 01:18:43,930
this syntax is a little more interesting.
1723
01:18:43,930 --> 01:18:48,690
It turns out the code looks like this, which almost seems like a paradox.
1724
01:18:48,690 --> 01:18:51,990
How can counter equal counter plus 1?
1725
01:18:51,990 --> 01:18:53,160
That's not how math works.
1726
01:18:53,160 --> 01:18:56,860
But again, a single equal sign is assignment from right to left.
1727
01:18:56,860 --> 01:18:59,910
So this is saying, take whatever the value of counter is, add 1 to it,
1728
01:18:59,910 --> 01:19:03,930
and copy that value from right to left into counter itself.
1729
01:19:03,930 --> 01:19:07,530
You still need the semicolon, but I claim
1730
01:19:07,530 --> 01:19:13,330
you do not need to mention the keyword int when updating an existing variable.
1731
01:19:13,330 --> 01:19:18,060
So only when you create a variable in C do you use the word string, or the word
1732
01:19:18,060 --> 01:19:19,950
int, or any of the others we'll eventually
1733
01:19:19,950 --> 01:19:23,370
see-- only when creating it or initializing it for the first time.
1734
01:19:23,370 --> 01:19:25,780
Thereafter if you want to change it, it just exists.
1735
01:19:25,780 --> 01:19:27,060
It's the word you gave it.
1736
01:19:27,060 --> 01:19:29,950
The computer is smart enough to at least remember what type it is.
1737
01:19:29,950 --> 01:19:32,100
So this line is now complete
1738
01:19:32,100 --> 01:19:35,580
Turns out, in code, as we'll see, it's pretty common to want to add things
1739
01:19:35,580 --> 01:19:37,740
together, increment things by one.
1740
01:19:37,740 --> 01:19:40,710
So there's actually different syntax for the same idea.
1741
01:19:40,710 --> 01:19:43,290
The term of art here is syntactic sugar.
1742
01:19:43,290 --> 01:19:46,410
There's often in code many ways to do the same thing,
1743
01:19:46,410 --> 01:19:49,900
even though, at the end of the day, they do exactly the same functionality.
1744
01:19:49,900 --> 01:19:54,120
So for instance, if, after a few days of CS50, you find this a little tedious
1745
01:19:54,120 --> 01:19:57,765
to keep typing in some program, you can simplify it to just this.
1746
01:19:57,765 --> 01:19:59,340
This is the syntactic sugar.
1747
01:19:59,340 --> 01:20:03,810
You can use plus equals and only mention the variable name once on the left,
1748
01:20:03,810 --> 01:20:06,480
and it just knows that means the previous thing.
1749
01:20:06,480 --> 01:20:10,420
It's just slightly more succinct.
1750
01:20:10,420 --> 01:20:12,900
This, too, is such a common thing to add 1 to a value.
1751
01:20:12,900 --> 01:20:13,800
And it doesn't have to be 1.
1752
01:20:13,800 --> 01:20:14,800
But in this case, it is.
1753
01:20:14,800 --> 01:20:19,110
But if it is indeed 1, you can further tighten the code up to just do this,
1754
01:20:19,110 --> 01:20:20,550
counter++.
1755
01:20:20,550 --> 01:20:25,740
So any time in C you see ++, it means literally adding 1 to that particular
1756
01:20:25,740 --> 01:20:26,472
variable.
1757
01:20:26,472 --> 01:20:28,680
There's other ways to do this in the other direction.
1758
01:20:28,680 --> 01:20:31,420
If you want to subtract 1 from a variable,
1759
01:20:31,420 --> 01:20:34,890
you can use any of the previous syntax using a minus sign instead of plus,
1760
01:20:34,890 --> 01:20:38,490
or you can more succinctly do counter--.
1761
01:20:38,490 --> 01:20:42,520
This is the way a typical C programmer would do this.
1762
01:20:42,520 --> 01:20:45,210
All right, so if we have no variables, let's
1763
01:20:45,210 --> 01:20:47,500
go and solve the meowing with loop.
1764
01:20:47,500 --> 01:20:49,320
So in Scratch, we saw loops like this.
1765
01:20:49,320 --> 01:20:52,680
This, of course, had the cat meow three times.
1766
01:20:52,680 --> 01:20:54,480
How do we do this in C?
1767
01:20:54,480 --> 01:20:58,900
Now, this is where things get a little more involved code-wise.
1768
01:20:58,900 --> 01:21:01,140
but if you understand each and every line,
1769
01:21:01,140 --> 01:21:03,520
we'll follow logically what's going on.
1770
01:21:03,520 --> 01:21:07,320
So here, I claim, is one way to implement
1771
01:21:07,320 --> 01:21:12,330
a loop that iterates three times in C. And this is kind of ridiculous, right?
1772
01:21:12,330 --> 01:21:15,900
We went from two super simple puzzle pieces like this to, my god,
1773
01:21:15,900 --> 01:21:18,990
it's 1, 2, 3, 4, 5, 6 lines of code, all of which are pretty involved.
1774
01:21:18,990 --> 01:21:20,740
So that escalated quickly.
1775
01:21:20,740 --> 01:21:21,960
But what's each line doing?
1776
01:21:21,960 --> 01:21:24,120
And we'll see other ways to do this more simply.
1777
01:21:24,120 --> 01:21:28,710
So we're initializing a variable called counter to 3, just like before.
1778
01:21:28,710 --> 01:21:29,370
Why?
1779
01:21:29,370 --> 01:21:32,800
Well, what does it mean to loop or to repeat something three times?
1780
01:21:32,800 --> 01:21:35,190
Well, it's like doing something three times,
1781
01:21:35,190 --> 01:21:37,260
and then do it, and then count down, and then
1782
01:21:37,260 --> 01:21:41,080
do it, and then count down, and then do it, until you're all out of counts.
1783
01:21:41,080 --> 01:21:44,910
So this is declaring a variable called counter, setting it equal to 3.
1784
01:21:44,910 --> 01:21:50,370
Then I'm inducing a loop in C, which is similar in spirit to repeat 3,
1785
01:21:50,370 --> 01:21:52,440
but you have to do more of the math yourself.
1786
01:21:52,440 --> 01:21:54,990
So I'm asking the question in parentheses,
1787
01:21:54,990 --> 01:21:59,200
while count is greater than 0, what do I want to do?
1788
01:21:59,200 --> 01:22:04,080
Well, per the indentation inside the curly braces, I want to meow one time.
1789
01:22:04,080 --> 01:22:06,990
And then, to be clear, what's this last line of code doing?
1790
01:22:06,990 --> 01:22:12,120
If counter starts off at three, this makes it 2 by subtracting 1 from it.
1791
01:22:12,120 --> 01:22:13,320
Then what happens?
1792
01:22:13,320 --> 01:22:17,620
By nature of the loop, just like in Scratch, it knows to go back and forth.
1793
01:22:17,620 --> 01:22:21,010
even though there's a nice, pretty arrow in Scratch, and there isn't here,
1794
01:22:21,010 --> 01:22:26,310
C knows to do this again, and again, and again, constantly asking this question
1795
01:22:26,310 --> 01:22:28,870
and then updating this value at the end.
1796
01:22:28,870 --> 01:22:33,690
So if I highlight just a few of these steps, the variable starts off at 3.
1797
01:22:33,690 --> 01:22:35,100
And actually, let me simplify 2.
1798
01:22:35,100 --> 01:22:37,980
I claimed earlier that when using single variables,
1799
01:22:37,980 --> 01:22:41,280
people very often just call it i for int, or c for char,
1800
01:22:41,280 --> 01:22:43,480
or s for string unless you have multiple variables.
1801
01:22:43,480 --> 01:22:44,730
So let me tighten the code up.
1802
01:22:44,730 --> 01:22:47,220
And this already makes it look a little more tolerable.
1803
01:22:47,220 --> 01:22:50,320
Let me actually tighten it up further, add one more step.
1804
01:22:50,320 --> 01:22:52,860
So now this is about as tight, as succinct
1805
01:22:52,860 --> 01:22:54,653
as you can make this code at the moment.
1806
01:22:54,653 --> 01:22:56,320
So what's actually going to happen here?
1807
01:22:56,320 --> 01:22:59,550
Well, the first line of code executes, and that initializes i to 3.
1808
01:22:59,550 --> 01:23:00,900
Then we check the condition.
1809
01:23:00,900 --> 01:23:03,840
While i is greater than 0, is i greater than 0?
1810
01:23:03,840 --> 01:23:05,580
Well, per my three fingers, obviously.
1811
01:23:05,580 --> 01:23:07,590
So we print out meow on the screen.
1812
01:23:07,590 --> 01:23:13,110
Then we subtract 1 from i, at which point now we have 2 as the value of i.
1813
01:23:13,110 --> 01:23:15,330
Then the code goes back to the condition.
1814
01:23:15,330 --> 01:23:17,580
And notice, the condition there is in parentheses.
1815
01:23:17,580 --> 01:23:19,420
That's another Boolean expression.
1816
01:23:19,420 --> 01:23:23,340
So loops can use Boolean expressions, just like conditionals use
1817
01:23:23,340 --> 01:23:24,990
Boolean expressions to make decisions.
1818
01:23:24,990 --> 01:23:27,840
The loop, though, is deciding not whether to do this thing or that
1819
01:23:27,840 --> 01:23:31,330
but whether to do the same thing again, and again, and again.
1820
01:23:31,330 --> 01:23:34,200
And as it ticks through the code one line after the other,
1821
01:23:34,200 --> 01:23:40,450
it's ultimately going to get down to 1, and then 0, and then stop.
1822
01:23:40,450 --> 01:23:45,330
So put another way-- came with some props here-- so suppose this ball here
1823
01:23:45,330 --> 01:23:49,410
is your variable, and you initialize it to 3 with three stress balls,
1824
01:23:49,410 --> 01:23:51,570
you can do something three times, right?
1825
01:23:51,570 --> 01:23:53,320
If I want to give out three stress balls--
1826
01:23:53,320 --> 01:23:56,653
here's your chance for free stress balls without having to answer any questions.
1827
01:23:56,653 --> 01:23:57,400
OK, there we go.
1828
01:23:57,400 --> 01:24:00,180
So here we go, subtracting 1 from my variable.
1829
01:24:00,180 --> 01:24:01,830
I'm left with two.
1830
01:24:01,830 --> 01:24:02,460
Oh my god.
1831
01:24:02,460 --> 01:24:04,845
All right, don't tell Sanders.
1832
01:24:04,845 --> 01:24:07,470
[GRUNTS] Oh, I'm sorry.
1833
01:24:07,470 --> 01:24:08,080
Oh.
1834
01:24:08,080 --> 01:24:08,580
[LAUGHTER]
1835
01:24:08,580 --> 01:24:10,350
OK, that ended poorly.
1836
01:24:10,350 --> 01:24:11,070
Apologies.
1837
01:24:11,070 --> 01:24:11,570
All right.
1838
01:24:11,570 --> 01:24:13,740
But now the educational point, though, is
1839
01:24:13,740 --> 01:24:17,037
that my variable has been decrement did further to just have--
1840
01:24:17,037 --> 01:24:18,370
I'm not throwing that far again.
1841
01:24:18,370 --> 01:24:19,620
I can't do this.
1842
01:24:19,620 --> 01:24:20,143
Here we go.
1843
01:24:20,143 --> 01:24:21,060
All right, here we go.
1844
01:24:21,060 --> 01:24:22,740
And one final subtraction.
1845
01:24:22,740 --> 01:24:24,880
And now our variable is left empty.
1846
01:24:24,880 --> 01:24:28,380
So we had three stress balls there, and that's all a variable is.
1847
01:24:28,380 --> 01:24:29,475
It's some kind of storage.
1848
01:24:29,475 --> 01:24:32,100
It's actually, of course, implemented in the computer's memory.
1849
01:24:32,100 --> 01:24:35,860
But metaphorically, it's really just a bowl with some values.
1850
01:24:35,860 --> 01:24:37,800
And every time you or, in this case, subtract,
1851
01:24:37,800 --> 01:24:39,840
you're just changing the value of that variable.
1852
01:24:39,840 --> 01:24:43,830
And then the code, meanwhile, of course, in parentheses, is just checking,
1853
01:24:43,830 --> 01:24:44,610
is the bowl empty?
1854
01:24:44,610 --> 01:24:45,360
Is the bowl empty?
1855
01:24:45,360 --> 01:24:46,570
Is the bowl empty?
1856
01:24:46,570 --> 01:24:50,350
AKA, is i greater than 0 or not?
1857
01:24:50,350 --> 01:24:55,210
Any questions on how we've implemented loops in this way?
1858
01:24:55,210 --> 01:24:58,080
And I owe you a stress ball after class.
1859
01:24:58,080 --> 01:24:59,820
Questions on loops?
1860
01:24:59,820 --> 01:25:03,240
All right, so it turns out, this is kind of ugly.
1861
01:25:03,240 --> 01:25:05,580
And this really starts to take the fun out
1862
01:25:05,580 --> 01:25:09,422
of programming when you have to write out this sequence of steps.
1863
01:25:09,422 --> 01:25:11,380
So it turns out, there's other ways to do this.
1864
01:25:11,380 --> 01:25:13,110
But first, let's see, logically, how else
1865
01:25:13,110 --> 01:25:16,410
you might express this because it's a little weird that we keep using zero.
1866
01:25:16,410 --> 01:25:19,890
So the one other way to do this would be to invert the logic.
1867
01:25:19,890 --> 01:25:23,820
You could absolutely start with your variable, call it i equal to 1.
1868
01:25:23,820 --> 01:25:28,290
And then you could ask the question, is i less than or equal to 3?
1869
01:25:28,290 --> 01:25:30,210
And notice a bit of new syntax here.
1870
01:25:30,210 --> 01:25:33,330
On your typical keyboard, there is number less than
1871
01:25:33,330 --> 01:25:35,370
or equal sign or greater than or equal sign
1872
01:25:35,370 --> 01:25:37,870
like you would write in math class with 1 over the other.
1873
01:25:37,870 --> 01:25:42,390
And so in C, you use two characters, less than followed by an equal sign
1874
01:25:42,390 --> 01:25:45,360
or, if appropriate, greater than followed by in equal sign.
1875
01:25:45,360 --> 01:25:47,370
And that logically captures that idea.
1876
01:25:47,370 --> 01:25:50,580
So notice that I'm changing my questions.
1877
01:25:50,580 --> 01:25:53,910
I'm initializing i to 1, and then I'm going to increment it ultimately
1878
01:25:53,910 --> 01:25:55,830
to 2 and then 3.
1879
01:25:55,830 --> 01:25:57,930
But because I'm doing less than or equal to,
1880
01:25:57,930 --> 01:26:00,340
it's still going to go from 1, 2, 3.
1881
01:26:00,340 --> 01:26:01,530
So that works too.
1882
01:26:01,530 --> 01:26:03,810
We could similarly do this yet another way.
1883
01:26:03,810 --> 01:26:10,320
We could initialize i to 0, and then we could say, well, i is less than 3
1884
01:26:10,320 --> 01:26:11,640
and keep incrementing it.
1885
01:26:11,640 --> 01:26:14,940
And I showed this last form is actually the most canonical.
1886
01:26:14,940 --> 01:26:18,420
It might be the most human-like to think in terms of 1 to 3.
1887
01:26:18,420 --> 01:26:22,620
It might be the most stressball-like to think in terms of 3 to 0,
1888
01:26:22,620 --> 01:26:23,740
counting down.
1889
01:26:23,740 --> 01:26:26,730
But typically, the go-to syntax for most programmers
1890
01:26:26,730 --> 01:26:31,440
once you get comfortable counting from 0 is to always start counting from 0
1891
01:26:31,440 --> 01:26:35,610
and count up to less than the value you're counting up to.
1892
01:26:35,610 --> 01:26:40,043
So it would be incorrect, why, to change this to less than or equal to 3 here?
1893
01:26:40,043 --> 01:26:42,960
What would happen if I changed the less than to less than or equal to?
1894
01:26:42,960 --> 01:26:44,340
AUDIENCE: It'll only meow twice.
1895
01:26:44,340 --> 01:26:47,280
DAVID J. MALAN: Yeah, it'll meow an extra-- a fourth time, in fact, total,
1896
01:26:47,280 --> 01:26:47,780
right?
1897
01:26:47,780 --> 01:26:51,150
Because you'll start at 0, then 1, then 2, then 3.
1898
01:26:51,150 --> 01:26:53,220
And less than or equal to 3-- sorry--
1899
01:26:53,220 --> 01:26:55,420
3 will give you the fourth time.
1900
01:26:55,420 --> 01:26:58,650
So we do want indeed to be just a single less than.
1901
01:26:58,650 --> 01:27:01,198
All right, so now that we have those options,
1902
01:27:01,198 --> 01:27:02,490
let me just give you one other.
1903
01:27:02,490 --> 01:27:04,907
And this one takes a little more, getting used to as well,
1904
01:27:04,907 --> 01:27:07,210
but it's probably the more common way to write this.
1905
01:27:07,210 --> 01:27:11,590
Let me go ahead and propose that we implement this as follows.
1906
01:27:11,590 --> 01:27:13,390
Let me go back to my code here.
1907
01:27:13,390 --> 01:27:20,040
Let me go into my several printfs, getting rid of all but one of them
1908
01:27:20,040 --> 01:27:21,000
ultimately.
1909
01:27:21,000 --> 01:27:22,750
And let's implement this in code.
1910
01:27:22,750 --> 01:27:30,510
So let's do int i get 0, how about then while i is less than 3,
1911
01:27:30,510 --> 01:27:33,960
then let's go ahead and say printf quote/unquote meow--
1912
01:27:33,960 --> 01:27:36,930
melow-- meow backslash n.
1913
01:27:36,930 --> 01:27:41,310
And then we have to do i minus minus or plus plus?
1914
01:27:41,310 --> 01:27:42,237
AUDIENCE: Plus plus.
1915
01:27:42,237 --> 01:27:44,570
DAVID J. MALAN: So plus plus because we're starting at 0
1916
01:27:44,570 --> 01:27:47,120
and going up to but not through 3.
1917
01:27:47,120 --> 01:27:51,678
So let me go ahead now and make meow after clearing my terminal, ./meow,
1918
01:27:51,678 --> 01:27:52,970
and it's still just as correct.
1919
01:27:52,970 --> 01:27:55,400
But it's a little more--
1920
01:27:55,400 --> 01:27:56,730
it's a little better designed.
1921
01:27:56,730 --> 01:27:57,230
Why?
1922
01:27:57,230 --> 01:28:00,770
Because now if I want to change it from 3 to 30 times, for instance,
1923
01:28:00,770 --> 01:28:01,850
I can change it there.
1924
01:28:01,850 --> 01:28:03,770
I can recompile my code.
1925
01:28:03,770 --> 01:28:06,020
I can do ./meow, and done.
1926
01:28:06,020 --> 01:28:09,450
I don't have to copy and paste it 27 more times to get that effect.
1927
01:28:09,450 --> 01:28:13,400
And I can even change what the word is by changing it in just one location.
1928
01:28:13,400 --> 01:28:15,920
But it turns out, there's other ways to do this too.
1929
01:28:15,920 --> 01:28:20,502
And let me propose that we introduce you to what's called a for loop as well.
1930
01:28:20,502 --> 01:28:22,460
So if you want to repeat something three times,
1931
01:28:22,460 --> 01:28:25,940
you can absolutely take the while loop approach that we just saw,
1932
01:28:25,940 --> 01:28:27,500
or you can do this.
1933
01:28:27,500 --> 01:28:30,270
And this one takes a little more, getting used to,
1934
01:28:30,270 --> 01:28:34,200
but it kind of consolidates into one line all of the same logic.
1935
01:28:34,200 --> 01:28:36,830
So notice, we have the keyword for here.
1936
01:28:36,830 --> 01:28:40,730
And for is just a preposition in this case that generally implies,
1937
01:28:40,730 --> 01:28:42,110
here comes a loop.
1938
01:28:42,110 --> 01:28:46,097
Inside of parentheses here is not just a Boolean expression.
1939
01:28:46,097 --> 01:28:47,930
And this is where things get a little weird.
1940
01:28:47,930 --> 01:28:50,900
There's three things-- to the left of the semicolon,
1941
01:28:50,900 --> 01:28:54,230
in the middle of the two semicolons, and to the right of the semicolon.
1942
01:28:54,230 --> 01:28:58,198
This is really the only other context we'll see semicolons, and it's weird.
1943
01:28:58,198 --> 01:28:59,990
Normally, it's been at the end of the line.
1944
01:28:59,990 --> 01:29:02,030
Now it's two of them in the middle of the line,
1945
01:29:02,030 --> 01:29:04,920
but this is the way humans decided years ago to do it.
1946
01:29:04,920 --> 01:29:06,080
So what is this doing?
1947
01:29:06,080 --> 01:29:07,850
Almost the same thing.
1948
01:29:07,850 --> 01:29:12,320
It is going to initialize a variable called i to 0.
1949
01:29:12,320 --> 01:29:14,240
It's going to then check.
1950
01:29:14,240 --> 01:29:19,880
If it's less than 3, it's then going to do whatever's in the curly braces,
1951
01:29:19,880 --> 01:29:22,980
and it's lastly going to increment i and repeat.
1952
01:29:22,980 --> 01:29:26,240
So just highlighting those in turn, at first, i
1953
01:29:26,240 --> 01:29:28,340
is initialized to 0, just like before.
1954
01:29:28,340 --> 01:29:30,170
Then this condition is checked.
1955
01:29:30,170 --> 01:29:32,150
This is a Boolean expression.
1956
01:29:32,150 --> 01:29:34,610
Yes or no, true or false will be its answer.
1957
01:29:34,610 --> 01:29:37,970
And if i is less than 3, which it should be once it starts at 0,
1958
01:29:37,970 --> 01:29:40,550
well, then we're going to go ahead and print out meow.
1959
01:29:40,550 --> 01:29:42,350
Then i is going to get incremented.
1960
01:29:42,350 --> 01:29:43,580
So it starts at 0.
1961
01:29:43,580 --> 01:29:45,170
It goes now to 1.
1962
01:29:45,170 --> 01:29:48,150
At that point, the Boolean expression is checked again.
1963
01:29:48,150 --> 01:29:50,840
So you don't keep changing i back to 0.
1964
01:29:50,840 --> 01:29:53,210
That first step happens only once.
1965
01:29:53,210 --> 01:29:56,270
But now you repeat through those three other highlights.
1966
01:29:56,270 --> 01:29:57,770
I check if i is less than 3.
1967
01:29:57,770 --> 01:29:58,320
It is.
1968
01:29:58,320 --> 01:29:59,600
So I print out meow.
1969
01:29:59,600 --> 01:30:00,875
It then increments i.
1970
01:30:00,875 --> 01:30:03,410
I check if i, now 2, is less than 3.
1971
01:30:03,410 --> 01:30:03,980
It is.
1972
01:30:03,980 --> 01:30:05,240
I print out meow.
1973
01:30:05,240 --> 01:30:06,380
i gets incremented.
1974
01:30:06,380 --> 01:30:07,100
I now check.
1975
01:30:07,100 --> 01:30:08,120
Is i less than 3?
1976
01:30:08,120 --> 01:30:11,360
No, it's not, because 3 is not less than 3.
1977
01:30:11,360 --> 01:30:12,800
And so the whole thing stops.
1978
01:30:12,800 --> 01:30:15,950
And whatever code is below this curly brace, if any,
1979
01:30:15,950 --> 01:30:17,420
starts executing instead.
1980
01:30:17,420 --> 01:30:21,470
Just like in Scratch, you break out of the loop and the puzzle pieces
1981
01:30:21,470 --> 01:30:22,610
being hugged.
1982
01:30:22,610 --> 01:30:31,520
Questions, then, about this alternative syntax for loops, AKA, a for loop?
1983
01:30:31,520 --> 01:30:34,195
AUDIENCE: Can you explain again why it doesn't go back to 0?
1984
01:30:34,195 --> 01:30:35,570
DAVID J. MALAN: Sorry, say again?
1985
01:30:35,570 --> 01:30:37,400
AUDIENCE: Can you explain again why it doesn't reset to 0?
1986
01:30:37,400 --> 01:30:38,275
DAVID J. MALAN: Yeah.
1987
01:30:38,275 --> 01:30:40,400
Can I explain again why it doesn't reset to 0?
1988
01:30:40,400 --> 01:30:41,690
Honestly, just because.
1989
01:30:41,690 --> 01:30:43,490
This was the syntax they chose.
1990
01:30:43,490 --> 01:30:45,620
This first part before the first semicolon
1991
01:30:45,620 --> 01:30:47,660
is only executed once just because.
1992
01:30:47,660 --> 01:30:48,740
That's how it's designed.
1993
01:30:48,740 --> 01:30:51,660
Everything else cycles again and again.
1994
01:30:51,660 --> 01:30:54,277
And this is just an alternative syntax to using
1995
01:30:54,277 --> 01:30:55,610
the slightly more lines of code.
1996
01:30:55,610 --> 01:30:57,818
It was, like, six lines of code using the while loop.
1997
01:30:57,818 --> 01:30:59,387
Logically, it's the same thing.
1998
01:30:59,387 --> 01:31:01,220
Programmers, once they get more comfortable,
1999
01:31:01,220 --> 01:31:04,053
tend to prefer this because it just expresses all your same thoughts
2000
01:31:04,053 --> 01:31:05,240
more succinctly.
2001
01:31:05,240 --> 01:31:06,380
That's all.
2002
01:31:06,380 --> 01:31:06,890
Yeah?
2003
01:31:06,890 --> 01:31:07,620
AUDIENCE: That was my question.
2004
01:31:07,620 --> 01:31:08,412
DAVID J. MALAN: OK.
2005
01:31:08,412 --> 01:31:11,210
So let's just work this into my meow example.
2006
01:31:11,210 --> 01:31:12,590
Let me go back to the code here.
2007
01:31:12,590 --> 01:31:14,898
And notice, indeed, if I highlight all these lines,
2008
01:31:14,898 --> 01:31:16,190
I think we can tighten this up.
2009
01:31:16,190 --> 01:31:21,350
Let me get rid of all of those and instead do for int i equals 0.
2010
01:31:21,350 --> 01:31:22,790
And I'm saying equals.
2011
01:31:22,790 --> 01:31:24,260
Most programmers would say gets.
2012
01:31:24,260 --> 01:31:28,130
So int i gets 0 means assignment-- the word get.
2013
01:31:28,130 --> 01:31:32,360
Now I'm going to do i is less than 3 i++.
2014
01:31:32,360 --> 01:31:37,670
Now in here I'm going to do my printf quote/unquote meow backslash n.
2015
01:31:37,670 --> 01:31:39,450
And so it's indeed a little tighter.
2016
01:31:39,450 --> 01:31:41,408
I mean, two of the lines are just curly braces.
2017
01:31:41,408 --> 01:31:43,580
There's really only two juicy lines of code now.
2018
01:31:43,580 --> 01:31:47,460
Let me go ahead and do make meow, ./meow.
2019
01:31:47,460 --> 01:31:51,680
And again, we're back in business with three of them printing only.
2020
01:31:51,680 --> 01:31:54,050
All right, there's one last structure we should explore
2021
01:31:54,050 --> 01:31:56,330
just because it's sometimes useful.
2022
01:31:56,330 --> 01:31:58,010
This was a forever block.
2023
01:31:58,010 --> 01:32:00,170
And this would be a little weird in Scratch
2024
01:32:00,170 --> 01:32:02,750
to just say meow forever, or at least without waiting.
2025
01:32:02,750 --> 01:32:06,290
But there is indeed a forever block in Scratch, which means do the following,
2026
01:32:06,290 --> 01:32:07,490
forever.
2027
01:32:07,490 --> 01:32:10,485
And I proposed, I think, verbally last week at least one example
2028
01:32:10,485 --> 01:32:11,360
where this is useful.
2029
01:32:11,360 --> 01:32:13,040
Meowing forever, a little annoying.
2030
01:32:13,040 --> 01:32:14,990
But can you think of common cases where you
2031
01:32:14,990 --> 01:32:19,100
might want to write code or use a program that loops forever?
2032
01:32:19,100 --> 01:32:19,657
Yeah?
2033
01:32:19,657 --> 01:32:21,740
AUDIENCE: Playing music throughout an entire game.
2034
01:32:21,740 --> 01:32:22,970
DAVID J. MALAN: Yeah, playing music.
2035
01:32:22,970 --> 01:32:25,370
Like Spotify playlists, just repeating again and again
2036
01:32:25,370 --> 01:32:26,495
would be some kind of loop.
2037
01:32:26,495 --> 01:32:28,310
AUDIENCE: Checking for collisions.
2038
01:32:28,310 --> 01:32:29,840
DAVID J. MALAN: Checking for collisions in Scratch,
2039
01:32:29,840 --> 01:32:32,548
so seeing if something's bouncing off the wall or another sprite.
2040
01:32:32,548 --> 01:32:33,590
Yeah?
2041
01:32:33,590 --> 01:32:36,512
AUDIENCE: Oh, checking for input.
2042
01:32:36,512 --> 01:32:37,970
DAVID J. MALAN: Checking for input.
2043
01:32:37,970 --> 01:32:40,900
So yeah, get_string is essentially just waiting there forever
2044
01:32:40,900 --> 01:32:43,300
for me to type in some input until I do.
2045
01:32:43,300 --> 01:32:44,470
AUDIENCE: Checking the time.
2046
01:32:44,470 --> 01:32:45,760
DAVID J. MALAN: Checking the time and actually
2047
01:32:45,760 --> 01:32:47,860
maintaining human time, like a wall clock.
2048
01:32:47,860 --> 01:32:48,550
Behind you?
2049
01:32:48,550 --> 01:32:49,420
Is that the same?
2050
01:32:49,420 --> 01:32:50,590
AUDIENCE: I was going to say checking the time.
2051
01:32:50,590 --> 01:32:52,173
DAVID J. MALAN: OK, checking the time.
2052
01:32:52,173 --> 01:32:52,900
And one more?
2053
01:32:52,900 --> 01:32:53,995
Detecting a key press too.
2054
01:32:53,995 --> 01:32:56,620
Like in Scratch, just waiting for some kind of event to happen,
2055
01:32:56,620 --> 01:32:58,182
just like on a phone or a browser.
2056
01:32:58,182 --> 01:32:59,890
And so there's so many examples where you
2057
01:32:59,890 --> 01:33:01,510
might want to do something forever--
2058
01:33:01,510 --> 01:33:04,520
just so you've seen the corresponding C building block.
2059
01:33:04,520 --> 01:33:08,290
It's a little weird, but this is probably the most canonical way
2060
01:33:08,290 --> 01:33:11,783
to do it in C. If you want to print meow forever--
2061
01:33:11,783 --> 01:33:14,950
which would be a little crazy because it would literally print and take over
2062
01:33:14,950 --> 01:33:16,990
your computer printing forever meow--
2063
01:33:16,990 --> 01:33:18,850
you would generally do it like this.
2064
01:33:18,850 --> 01:33:19,490
Why?
2065
01:33:19,490 --> 01:33:22,810
Well, a while loop expects in parentheses a Boolean expression,
2066
01:33:22,810 --> 01:33:26,020
and a Boolean expression is, again, a yes/no, a true/false question.
2067
01:33:26,020 --> 01:33:29,620
But if you want the answer to that question always to be yes--
2068
01:33:29,620 --> 01:33:33,490
or really, always to be true, turns out in C and a lot of languages
2069
01:33:33,490 --> 01:33:35,950
will then just say true because true--
2070
01:33:35,950 --> 01:33:38,800
T-R-U-E-- is never going to change magically to false.
2071
01:33:38,800 --> 01:33:41,570
I mean, it's just a special word in the programming language.
2072
01:33:41,570 --> 01:33:45,680
So by saying while true, it just means do the following forever.
2073
01:33:45,680 --> 01:33:48,580
Another common paradigm before true and false
2074
01:33:48,580 --> 01:33:52,300
became commonplace would be to do this instead--
2075
01:33:52,300 --> 01:33:54,220
change while 1.
2076
01:33:54,220 --> 01:33:57,820
You might see in online examples and texts and the like,
2077
01:33:57,820 --> 01:33:59,770
while 1 is really the same thing.
2078
01:33:59,770 --> 01:34:04,840
Any value that is 0 is generally interpreted as false by a computer.
2079
01:34:04,840 --> 01:34:09,310
Any value that is 1 or any other non-zero value
2080
01:34:09,310 --> 01:34:11,210
is generally interpreted as true.
2081
01:34:11,210 --> 01:34:15,400
And so this, too, would have the same effect, saying while true or while 1.
2082
01:34:15,400 --> 01:34:18,700
Generally speaking, while true is perhaps a little clearer these days.
2083
01:34:18,700 --> 01:34:20,650
Now, meowing forever is not a good thing.
2084
01:34:20,650 --> 01:34:23,770
But suppose I did that by intent or by accident.
2085
01:34:23,770 --> 01:34:24,950
Well, let's try this.
2086
01:34:24,950 --> 01:34:26,570
So here I'll go into my code.
2087
01:34:26,570 --> 01:34:30,550
I'm going to get rid of for loop and change my while loop to, how about,
2088
01:34:30,550 --> 01:34:32,180
true.
2089
01:34:32,180 --> 01:34:36,100
And in this case here, well, we'll keep it-- let's do this.
2090
01:34:36,100 --> 01:34:38,230
Make meow, Enter.
2091
01:34:38,230 --> 01:34:41,840
And you'll see this, use of undeclared identifier true.
2092
01:34:41,840 --> 01:34:46,360
This is actually hinting at my mention that the old way was 0 and 1.
2093
01:34:46,360 --> 01:34:48,220
Nowadays, you could say true or false.
2094
01:34:48,220 --> 01:34:53,560
But true and false are themselves special words that you have to include.
2095
01:34:53,560 --> 01:34:56,740
And it turns out, if you want to use special Boolean values like this,
2096
01:34:56,740 --> 01:35:00,850
there's another header file we haven't seen called stdbool that essentially
2097
01:35:00,850 --> 01:35:03,640
creates true and false as keywords.
2098
01:35:03,640 --> 01:35:06,550
Alternatively, CS50 includes that same file.
2099
01:35:06,550 --> 01:35:08,980
So it's more common in CS50 is to see it like this.
2100
01:35:08,980 --> 01:35:13,360
Now if I clear my terminal window and do make meow and then ./meow and hit
2101
01:35:13,360 --> 01:35:18,970
Enter, well, unfortunately, this isn't the best thing to do infinitely when
2102
01:35:18,970 --> 01:35:21,350
you're in the cloud using a browser.
2103
01:35:21,350 --> 01:35:24,970
This is indeed a browser, just full-screened here.
2104
01:35:24,970 --> 01:35:29,462
This means I'm sending millions of meows over the internet to my computer here.
2105
01:35:29,462 --> 01:35:32,170
So this will happen to you at some point, probably not with meow.
2106
01:35:32,170 --> 01:35:34,150
But you'll lose control over your terminal window.
2107
01:35:34,150 --> 01:35:34,420
Why?
2108
01:35:34,420 --> 01:35:35,170
Because you screwed up.
2109
01:35:35,170 --> 01:35:36,250
And you have an infinite loop.
2110
01:35:36,250 --> 01:35:37,090
You didn't really intend it.
2111
01:35:37,090 --> 01:35:37,690
Or maybe you did.
2112
01:35:37,690 --> 01:35:39,232
You were curious to see what happens.
2113
01:35:39,232 --> 01:35:41,590
What do you do?
2114
01:35:41,590 --> 01:35:43,930
When does the meowing stop?
2115
01:35:43,930 --> 01:35:45,910
What recourse do we have here?
2116
01:35:45,910 --> 01:35:48,550
Well, Control-C will be your friend.
2117
01:35:48,550 --> 01:35:51,070
Sometimes you have to hit it a bunch in a cloud environment.
2118
01:35:51,070 --> 01:35:55,540
But Control-C for cancel will interrupt a program that's running.
2119
01:35:55,540 --> 01:35:58,660
And I promise that almost all of you will at some point
2120
01:35:58,660 --> 01:36:02,560
accidentally introduce an infinite loop because your math is slightly off.
2121
01:36:02,560 --> 01:36:05,680
When in doubt, click in the terminal window and hit Control-C--
2122
01:36:05,680 --> 01:36:07,060
sometimes multiple times--
2123
01:36:07,060 --> 01:36:09,545
and that will indeed cancel whatever is happening there.
2124
01:36:09,545 --> 01:36:11,170
In this case, I might have intended it.
2125
01:36:11,170 --> 01:36:14,330
But sometimes it's not, in fact, intended.
2126
01:36:14,330 --> 01:36:18,010
All right, so we've been taking for granted this whole graphical user
2127
01:36:18,010 --> 01:36:22,557
interface for some time and, indeed, the commands that I'm typing
2128
01:36:22,557 --> 01:36:23,890
and the buttons on I'm clicking.
2129
01:36:23,890 --> 01:36:25,848
And let me just give you a better sense of what
2130
01:36:25,848 --> 01:36:29,290
it is we are using underneath the hood this whole time,
2131
01:36:29,290 --> 01:36:31,630
namely an operating system called Linux.
2132
01:36:31,630 --> 01:36:34,270
So I keep alluding verbally, of course, to Macs and PCs
2133
01:36:34,270 --> 01:36:37,690
because almost all of us are running macOS or Windows on our desktops
2134
01:36:37,690 --> 01:36:38,680
or laptops nowadays.
2135
01:36:38,680 --> 01:36:40,930
But there's lots of other operating systems out there,
2136
01:36:40,930 --> 01:36:43,330
and one of the most popular one is called Linux.
2137
01:36:43,330 --> 01:36:47,680
And Linux is very often used on servers nowadays-- companies
2138
01:36:47,680 --> 01:36:51,610
that host email, companies that host websites or apps, more generally.
2139
01:36:51,610 --> 01:36:53,980
Certain computer scientists or computer science students
2140
01:36:53,980 --> 01:36:56,950
often like to brag that they run Linux just because that's a thing.
2141
01:36:56,950 --> 01:37:01,030
But it is really just an alternative to macOS or Windows
2142
01:37:01,030 --> 01:37:04,150
that provides you with both a GUI, if you want it,
2143
01:37:04,150 --> 01:37:07,480
but also an especially a command line environment.
2144
01:37:07,480 --> 01:37:12,040
Now, fun fact-- Windows and macOS do have terminal windows or the equivalent
2145
01:37:12,040 --> 01:37:12,550
thereof.
2146
01:37:12,550 --> 01:37:16,150
And eventually, you might use it on your own Mac or PC to solve some problem.
2147
01:37:16,150 --> 01:37:19,690
But Linux is really known for, along with other operating systems,
2148
01:37:19,690 --> 01:37:23,530
its command line environment, which, again, I distinguished earlier from GUI
2149
01:37:23,530 --> 01:37:26,500
as a Command Line Interface, or CLI.
2150
01:37:26,500 --> 01:37:29,450
And that refers, really, to the terminal window.
2151
01:37:29,450 --> 01:37:33,790
So if I go back to VS Code here, and let me, in fact, go ahead and close my tab
2152
01:37:33,790 --> 01:37:36,160
and focus entirely on the terminal window,
2153
01:37:36,160 --> 01:37:39,640
this terminal window is really just your command line interface
2154
01:37:39,640 --> 01:37:42,390
to your very own server in the cloud.
2155
01:37:42,390 --> 01:37:44,140
The term of art here is you each will have
2156
01:37:44,140 --> 01:37:47,530
your own container in the cloud, which is like your own computer
2157
01:37:47,530 --> 01:37:51,430
running somewhere on the internet with your own username and password
2158
01:37:51,430 --> 01:37:54,530
to which you have access and your own hard drive, if you will,
2159
01:37:54,530 --> 01:37:57,430
your own home folder that has all of your files for the class.
2160
01:37:57,430 --> 01:38:01,390
And it's only accessible to you unless you enable live sharing thereof.
2161
01:38:01,390 --> 01:38:03,880
So when you're typing commands here, it looks
2162
01:38:03,880 --> 01:38:06,400
like you're typing them, of course, on your own Mac or PC.
2163
01:38:06,400 --> 01:38:09,070
But they're actually being sent over the browser
2164
01:38:09,070 --> 01:38:13,570
to some server in the cloud where you are controlling, really,
2165
01:38:13,570 --> 01:38:15,830
your own account therein.
2166
01:38:15,830 --> 01:38:19,390
So it turns out that there are other commands that are worth knowing.
2167
01:38:19,390 --> 01:38:21,292
And we'll give you just a few of these today.
2168
01:38:21,292 --> 01:38:23,500
And over the coming weeks will you have opportunities
2169
01:38:23,500 --> 01:38:24,710
to play with others as well.
2170
01:38:24,710 --> 01:38:26,260
But these are some of the basics.
2171
01:38:26,260 --> 01:38:29,782
And they're all incredibly succinct because, indeed, for things you're
2172
01:38:29,782 --> 01:38:31,990
typing at the command line, humans generally have not
2173
01:38:31,990 --> 01:38:33,640
wanted to type out long commands.
2174
01:38:33,640 --> 01:38:35,890
So a lot of these are abbreviations here.
2175
01:38:35,890 --> 01:38:38,590
Now, perhaps the most common one I'll start with first
2176
01:38:38,590 --> 01:38:44,480
is ls, a lowercase l and a lowercase s that stands for, succinctly, list.
2177
01:38:44,480 --> 01:38:47,380
So if I go to my terminal window now where up until now,
2178
01:38:47,380 --> 01:38:51,370
I've only typed code, which is a VS Code thing for creating an opening files,
2179
01:38:51,370 --> 01:38:56,110
and make, which triggers the compilation of my code, what if I now type ls?
2180
01:38:56,110 --> 01:39:00,070
This will list all of the files in my current folder--
2181
01:39:00,070 --> 01:39:02,000
my hard drive in the cloud, if you will.
2182
01:39:02,000 --> 01:39:05,780
So if I hit Enter, you'll see a whole bunch of results.
2183
01:39:05,780 --> 01:39:07,240
Now, they're color coded too.
2184
01:39:07,240 --> 01:39:09,910
The white ones here end in .c.
2185
01:39:09,910 --> 01:39:11,980
Those are the source code files I've written
2186
01:39:11,980 --> 01:39:15,790
during class today-- agree.c, compare.c, hello.c, and meow.c.
2187
01:39:15,790 --> 01:39:19,270
And you can perhaps guess, the green ones here that just by convention
2188
01:39:19,270 --> 01:39:24,382
have an asterisk on the end to denote that they're special represent what?
2189
01:39:24,382 --> 01:39:25,340
One of the four others.
2190
01:39:25,340 --> 01:39:26,315
Yeah?
2191
01:39:26,315 --> 01:39:27,800
AUDIENCE: The machine code?
2192
01:39:27,800 --> 01:39:29,520
DAVID J. MALAN: Yeah, the machine code.
2193
01:39:29,520 --> 01:39:33,710
So those are my actual programs that are identically named minus the .c
2194
01:39:33,710 --> 01:39:34,340
extension.
2195
01:39:34,340 --> 01:39:36,830
And the asterisk means that they're executable.
2196
01:39:36,830 --> 01:39:39,582
That is in the world of macOS or Windows, you would double click.
2197
01:39:39,582 --> 01:39:41,540
But in the world of a command line environment,
2198
01:39:41,540 --> 01:39:46,280
that means you do ./ and then the name without the asterisk to execute or run
2199
01:39:46,280 --> 01:39:47,400
the code therein.
2200
01:39:47,400 --> 01:39:51,560
So if I open up my File Explorer-- and I'm hitting Command-B on my computer
2201
01:39:51,560 --> 01:39:54,990
here just as a keyboard shortcut-- you'll see the exact same thing.
2202
01:39:54,990 --> 01:39:59,210
So ls is the command line interface for listing the files in your account.
2203
01:39:59,210 --> 01:40:03,060
But here, because I'm using VS Code or any program like it,
2204
01:40:03,060 --> 01:40:06,213
I also get a graphical user interface as well.
2205
01:40:06,213 --> 01:40:07,880
So it's just two different places to be.
2206
01:40:07,880 --> 01:40:09,680
You're welcome to use whatever you're comfortable with.
2207
01:40:09,680 --> 01:40:12,260
But over time will you naturally get more comfortable
2208
01:40:12,260 --> 01:40:14,720
and capable with the terminal window alone.
2209
01:40:14,720 --> 01:40:16,773
Well, what else is on this list here?
2210
01:40:16,773 --> 01:40:19,190
Well, during the break, I saw that in at least one of you,
2211
01:40:19,190 --> 01:40:23,330
for instance, had created a file called hello instead of hello.c.
2212
01:40:23,330 --> 01:40:27,230
So you were in a situation where you did this accidentally and hit Enter.
2213
01:40:27,230 --> 01:40:30,420
And then you went ahead and typed in all of your code like this.
2214
01:40:30,420 --> 01:40:32,270
And then down in your terminal window, you
2215
01:40:32,270 --> 01:40:34,760
were trying to do make hello, Enter.
2216
01:40:34,760 --> 01:40:38,960
And this now didn't actually do anything.
2217
01:40:38,960 --> 01:40:40,820
I can't-- I'm hitting--
2218
01:40:40,820 --> 01:40:42,380
I'm trying to run the command.
2219
01:40:42,380 --> 01:40:44,690
I got permission denied, as at least one of you did.
2220
01:40:44,690 --> 01:40:45,433
Now, why is that?
2221
01:40:45,433 --> 01:40:46,850
Well, let's just do a quick check.
2222
01:40:46,850 --> 01:40:50,690
If I do ls, I see now hello, but hello has
2223
01:40:50,690 --> 01:40:53,180
no asterisk next to it, which means it's not executable.
2224
01:40:53,180 --> 01:40:53,930
That's my code.
2225
01:40:53,930 --> 01:40:54,470
Why?
2226
01:40:54,470 --> 01:40:57,540
Well, notice the top of my tab confirms, oh, I screwed up.
2227
01:40:57,540 --> 01:41:00,740
I didn't name my file hello.c, which it just has to be.
2228
01:41:00,740 --> 01:41:01,920
So what do you do?
2229
01:41:01,920 --> 01:41:05,810
Well, you could very hackishly copy this, create a new file, paste it in.
2230
01:41:05,810 --> 01:41:06,770
Or no, no, no.
2231
01:41:06,770 --> 01:41:09,890
We know how to rename things now here because that's one of our options.
2232
01:41:09,890 --> 01:41:11,100
Let me do this.
2233
01:41:11,100 --> 01:41:17,600
Let me do mv for move, hello, and then hello.c, and hit Enter.
2234
01:41:17,600 --> 01:41:20,250
You'll see the tab closes because hello no longer exists.
2235
01:41:20,250 --> 01:41:25,130
But if I now type ls, you'll see, ah, there is hello.c.
2236
01:41:25,130 --> 01:41:28,910
And if I open that file now, whew, there's all of my same code.
2237
01:41:28,910 --> 01:41:31,010
And now if I do make hello--
2238
01:41:31,010 --> 01:41:37,350
make hello-- now I do get an executable file where in the world is restored.
2239
01:41:37,350 --> 01:41:40,950
So mv, it's just a command not just for renaming, but it also turns out,
2240
01:41:40,950 --> 01:41:43,020
eventually for moving files as well.
2241
01:41:43,020 --> 01:41:45,230
You can also create directories or folders.
2242
01:41:45,230 --> 01:41:48,950
So for instance, if I go into VS Code again, and suppose
2243
01:41:48,950 --> 01:41:52,760
I hover over here and click not on the plus file icon but plus folder,
2244
01:41:52,760 --> 01:41:56,210
I can create a folder called, for instance, pset1 for problem
2245
01:41:56,210 --> 01:41:57,620
set 1 in the class.
2246
01:41:57,620 --> 01:42:00,290
And you'll see now that it's empty because all of my other files
2247
01:42:00,290 --> 01:42:02,840
are in the default folder of my account.
2248
01:42:02,840 --> 01:42:05,460
But I could also go in there like this.
2249
01:42:05,460 --> 01:42:11,060
And I could click on File, and now I can create a new file called mario.c,
2250
01:42:11,060 --> 01:42:13,430
which is one of the first problems, for instance.
2251
01:42:13,430 --> 01:42:18,960
But you'll notice now that mario.c is inside of the pset1 folder.
2252
01:42:18,960 --> 01:42:23,300
So if I zoom out and I type ls at my terminal window,
2253
01:42:23,300 --> 01:42:26,720
I won't see mario.c anywhere.
2254
01:42:26,720 --> 01:42:28,688
But I do see a pset1 folder.
2255
01:42:28,688 --> 01:42:31,730
And it's in light blue followed by a slash, which you don't have to type.
2256
01:42:31,730 --> 01:42:33,300
It just indicates that's a folder.
2257
01:42:33,300 --> 01:42:37,640
Now, I can visually at top left obviously see pwet1 contains mario.c.
2258
01:42:37,640 --> 01:42:40,610
But if I try to do something like make mario here,
2259
01:42:40,610 --> 01:42:42,800
no rule to make target mario.
2260
01:42:42,800 --> 01:42:44,510
It just doesn't seem to exist.
2261
01:42:44,510 --> 01:42:46,650
And that's because you're in the wrong directory.
2262
01:42:46,650 --> 01:42:49,010
So in a command line interface, it's not quite as simple
2263
01:42:49,010 --> 01:42:51,560
as just clicking on a folder, and voila, it opens.
2264
01:42:51,560 --> 01:42:55,250
You have to change into the directory or folder.
2265
01:42:55,250 --> 01:42:57,660
And cd is going to be the command there.
2266
01:42:57,660 --> 01:43:00,600
So if I want to actually change into that directory,
2267
01:43:00,600 --> 01:43:04,070
I can do cd, space, pset1, Enter.
2268
01:43:04,070 --> 01:43:05,960
And now you'll see my prompt changes.
2269
01:43:05,960 --> 01:43:09,200
And this is just a common convention, but it's not the only one out there.
2270
01:43:09,200 --> 01:43:12,470
Now I still have a dollar sign, which indicates where I can type commands.
2271
01:43:12,470 --> 01:43:16,520
But before it, I see a reminder constantly what folder I'm in.
2272
01:43:16,520 --> 01:43:19,550
And we put that there deliberately, like a lot of Linux users
2273
01:43:19,550 --> 01:43:23,620
do just to remind themselves where they are because unlike macOS or Windows,
2274
01:43:23,620 --> 01:43:26,120
where you have a nice, big window telling you where you are,
2275
01:43:26,120 --> 01:43:29,000
at the command line, you need to be reminded textually.
2276
01:43:29,000 --> 01:43:33,350
But now if I type ls and hit Enter, what should I see?
2277
01:43:33,350 --> 01:43:34,340
AUDIENCE: Mario.c
2278
01:43:34,340 --> 01:43:36,170
DAVID J. MALAN: Yeah, mario.c.
2279
01:43:36,170 --> 01:43:38,460
And now if I want to open it--
2280
01:43:38,460 --> 01:43:42,140
if I want to actually compile it, I can run make mario in this directory
2281
01:43:42,140 --> 01:43:43,940
once I actually type out all of the code.
2282
01:43:43,940 --> 01:43:46,050
Rest assured that in problem sets and labs,
2283
01:43:46,050 --> 01:43:48,800
we'll almost always-- certainly, in the first weeks of the class--
2284
01:43:48,800 --> 01:43:50,810
give you exactly the commands to type.
2285
01:43:50,810 --> 01:43:52,880
Odds are because it's new to many of you,
2286
01:43:52,880 --> 01:43:55,100
you will accidentally type the wrong commands.
2287
01:43:55,100 --> 01:43:56,000
No big deal.
2288
01:43:56,000 --> 01:43:58,850
Just remember that you have different ways to solve these problems.
2289
01:43:58,850 --> 01:44:00,740
You've got the graphical File Explorer, which
2290
01:44:00,740 --> 01:44:02,198
should feel a little more familiar.
2291
01:44:02,198 --> 01:44:04,940
But in time you'll start to know and, honestly,
2292
01:44:04,940 --> 01:44:08,630
probably prefer commands like these-- so cd for Change Directory,
2293
01:44:08,630 --> 01:44:14,420
cp for copy a file, ls for list, mkdir to make a directory--
2294
01:44:14,420 --> 01:44:17,630
create a new folder at the command line instead of with the button--
2295
01:44:17,630 --> 01:44:21,924
mv for move or rename, rm for--
2296
01:44:21,924 --> 01:44:22,770
AUDIENCE: Remove.
2297
01:44:22,770 --> 01:44:23,728
DAVID J. MALAN: Remove.
2298
01:44:23,728 --> 01:44:24,960
So be careful with that one.
2299
01:44:24,960 --> 01:44:26,520
Rmdir, remove directory.
2300
01:44:26,520 --> 01:44:28,860
And there's dozens, hundreds of other commands.
2301
01:44:28,860 --> 01:44:30,780
You won't need many of them, but we'll start
2302
01:44:30,780 --> 01:44:33,310
to scratch the surface all the more over time.
2303
01:44:33,310 --> 01:44:35,280
But ultimately, this command line interface
2304
01:44:35,280 --> 01:44:38,630
is going to be a more powerful mechanism, a more capable mechanism,
2305
01:44:38,630 --> 01:44:40,380
and ultimately, a more efficient mechanism
2306
01:44:40,380 --> 01:44:43,980
for writing code, running commands, solving problems, analyzing data more
2307
01:44:43,980 --> 01:44:46,050
generally, even though know there's going
2308
01:44:46,050 --> 01:44:49,680
to be some growing pains early on just because it's
2309
01:44:49,680 --> 01:44:51,880
probably so new for many of you.
2310
01:44:51,880 --> 01:44:55,020
So with that said, we have some problems still to solve,
2311
01:44:55,020 --> 01:44:56,475
but we promised cookies today.
2312
01:44:56,475 --> 01:44:58,350
So let's go ahead and take a 10-minute break.
2313
01:44:58,350 --> 01:45:00,150
Cookies are now served in the transept.
2314
01:45:00,150 --> 01:45:02,910
And we'll be back here in 10.
2315
01:45:02,910 --> 01:45:04,740
All right, we are back.
2316
01:45:04,740 --> 01:45:08,400
And up until now, each of the code examples in C we've done
2317
01:45:08,400 --> 01:45:10,740
have been designed to show one specific topic.
2318
01:45:10,740 --> 01:45:14,190
But we thought we'd try to take a step back and solve a more general problem
2319
01:45:14,190 --> 01:45:17,880
and give you a sense of when given a problem set, for instance, or just
2320
01:45:17,880 --> 01:45:20,670
a programming problem more generally, where you even begin
2321
01:45:20,670 --> 01:45:23,280
and how you go about approaching it when it's not obvious
2322
01:45:23,280 --> 01:45:25,260
what the point of the exercise is.
2323
01:45:25,260 --> 01:45:27,330
So one of my favorite games from yesteryear
2324
01:45:27,330 --> 01:45:30,510
is this one here, "Super Mario Brothers" that has come in so many
2325
01:45:30,510 --> 01:45:31,500
different forms since.
2326
01:45:31,500 --> 01:45:35,250
But in this original two-dimensional side scroller game,
2327
01:45:35,250 --> 01:45:37,450
there was a lot of artwork like this.
2328
01:45:37,450 --> 01:45:40,260
So for instance, up here in the sky were four question marks.
2329
01:45:40,260 --> 01:45:44,370
And we'll find that in C and a lot of programming languages initially,
2330
01:45:44,370 --> 01:45:48,030
it's a lot easier, a lot more accessible to focus really on black and white type
2331
01:45:48,030 --> 01:45:49,920
interactive programs textually as opposed
2332
01:45:49,920 --> 01:45:51,900
to full-fledged graphics and the like, but more
2333
01:45:51,900 --> 01:45:55,830
on the more graphical acoustic type of programs before long.
2334
01:45:55,830 --> 01:45:58,500
But for now let me go over and propose that we
2335
01:45:58,500 --> 01:46:00,720
try to just implement in ASCII art--
2336
01:46:00,720 --> 01:46:03,150
ASCII, again, being the code that maps numbers
2337
01:46:03,150 --> 01:46:08,250
to letters, at least for English, into a textual version of these for question
2338
01:46:08,250 --> 01:46:09,120
marks in the sky.
2339
01:46:09,120 --> 01:46:11,130
So for this, let me go over to VS Code.
2340
01:46:11,130 --> 01:46:13,680
I'll create my own version of mario.c that
2341
01:46:13,680 --> 01:46:16,923
will be different from the one you're challenged with in problem set 1.
2342
01:46:16,923 --> 01:46:18,840
Indeed, in problem set 1, you'll be challenged
2343
01:46:18,840 --> 01:46:22,860
to build a little something like this, albeit with hashtags
2344
01:46:22,860 --> 01:46:24,810
for ASCII art instead of graphics.
2345
01:46:24,810 --> 01:46:28,120
And in mario.c, I want to just solve this simple problem first.
2346
01:46:28,120 --> 01:46:29,710
So it's all involving output.
2347
01:46:29,710 --> 01:46:33,090
So I'll do include stdio.h so I can use printf.
2348
01:46:33,090 --> 01:46:37,043
I'll do my int main(void)-- more on why we keep doing that in future weeks.
2349
01:46:37,043 --> 01:46:39,210
And I'm just going to do something simple initially,
2350
01:46:39,210 --> 01:46:42,210
like 1, 2, 3, 4, backslash n.
2351
01:46:42,210 --> 01:46:46,530
This is about the simplest way I can implement four question
2352
01:46:46,530 --> 01:46:50,410
marks in the sky like these here using pure text like this.
2353
01:46:50,410 --> 01:46:54,180
So let me go ahead and do make mario, ./mario, and voila.
2354
01:46:54,180 --> 01:46:55,830
We have those four question marks.
2355
01:46:55,830 --> 01:46:58,830
But we've seen, of course, that there are better ways to do this.
2356
01:46:58,830 --> 01:47:03,150
And if you wanted to generalize this to be five question marks, six,
2357
01:47:03,150 --> 01:47:06,450
60 different question marks, loop was always the answer
2358
01:47:06,450 --> 01:47:08,100
for not repeating ourselves.
2359
01:47:08,100 --> 01:47:12,570
So maybe I should rewrite this a little bit more flexibly and say something
2360
01:47:12,570 --> 01:47:17,100
like this, for in i get 0, i less than 4, i++.
2361
01:47:17,100 --> 01:47:21,900
And then inside of a for loop, now I can just do a single question mark,
2362
01:47:21,900 --> 01:47:25,800
but I don't think what I've just done is correct.
2363
01:47:25,800 --> 01:47:29,280
Any one spot the aesthetic bug already?
2364
01:47:29,280 --> 01:47:34,200
Yeah, why is this wrong if I want to print the same thing?
2365
01:47:34,200 --> 01:47:34,710
Yeah?
2366
01:47:34,710 --> 01:47:38,275
AUDIENCE: The backslash n, you said to use it into [INAUDIBLE]..
2367
01:47:38,275 --> 01:47:39,150
DAVID J. MALAN: Yeah.
2368
01:47:39,150 --> 01:47:41,800
So I don't think I want a backslash n after every question mark
2369
01:47:41,800 --> 01:47:44,760
because the goal is, again, this row of question marks in the sky.
2370
01:47:44,760 --> 01:47:50,700
So if I now recompile this, make mario, ./mario, OK, it's almost there.
2371
01:47:50,700 --> 01:47:54,820
But now I have that regression to where the dollar sign is not on its own line.
2372
01:47:54,820 --> 01:47:58,265
So I think I need a new line, but I don't think I want it here
2373
01:47:58,265 --> 01:47:59,890
because that was not going to end well.
2374
01:47:59,890 --> 01:48:01,015
Where do I want to instead?
2375
01:48:01,015 --> 01:48:03,310
2376
01:48:03,310 --> 01:48:03,960
Any instinct?
2377
01:48:03,960 --> 01:48:05,610
Yeah?
2378
01:48:05,610 --> 01:48:07,380
Yeah, so outside for loop.
2379
01:48:07,380 --> 01:48:11,640
So indeed, I can just go below line 8 and above line 9, creating a new one.
2380
01:48:11,640 --> 01:48:15,273
And now it's totally fine to just print a new line like that.
2381
01:48:15,273 --> 01:48:17,190
You don't have to print anything else with it.
2382
01:48:17,190 --> 01:48:18,970
It's indeed a character unto itself.
2383
01:48:18,970 --> 01:48:21,900
So let's do make mario one last time, ./mario.
2384
01:48:21,900 --> 01:48:24,010
OK, so now we're back in business there.
2385
01:48:24,010 --> 01:48:28,020
Well, what if we wanted to do some other scene from "Mario," such as this one
2386
01:48:28,020 --> 01:48:31,380
here where there's a lot of vertical obstacles like these bricks here?
2387
01:48:31,380 --> 01:48:34,410
If I wanted to print out now a column of three bricks--
2388
01:48:34,410 --> 01:48:38,160
and I'll use hashtags for these instead of anything graphical-- well,
2389
01:48:38,160 --> 01:48:40,650
I think we're almost there, right?
2390
01:48:40,650 --> 01:48:42,240
I think I can now--
2391
01:48:42,240 --> 01:48:44,080
it's almost maybe a little easier.
2392
01:48:44,080 --> 01:48:46,342
I can go back here, change the question mark
2393
01:48:46,342 --> 01:48:49,050
to something that looks more like a brick, like this hash symbol.
2394
01:48:49,050 --> 01:48:52,890
And I think now I do want the new line character because when I now do make
2395
01:48:52,890 --> 01:48:56,368
mario, ./mario, OK, there's my wall of four.
2396
01:48:56,368 --> 01:48:56,910
Oh, but wait.
2397
01:48:56,910 --> 01:48:58,050
I didn't want four.
2398
01:48:58,050 --> 01:49:01,150
I wanted to be consistent just with this particular scene here,
2399
01:49:01,150 --> 01:49:02,320
so I just want three.
2400
01:49:02,320 --> 01:49:04,780
So I can still change it in one place.
2401
01:49:04,780 --> 01:49:06,330
And here, again, is that paradigm.
2402
01:49:06,330 --> 01:49:08,970
Even whether you're using 4 or 3, if you get
2403
01:49:08,970 --> 01:49:11,670
into the habit of starting counting from 0,
2404
01:49:11,670 --> 01:49:15,870
you go on up to but not through the value you want to count up to.
2405
01:49:15,870 --> 01:49:20,055
So that's why I'm using less than instead of less than or equal to there.
2406
01:49:20,055 --> 01:49:22,680
So this would be the common paradigm, though you could count it
2407
01:49:22,680 --> 01:49:25,360
like we saw earlier in different ways.
2408
01:49:25,360 --> 01:49:27,965
But what if things escalate one level further?
2409
01:49:27,965 --> 01:49:30,840
And when you're in the underground version of "Super Mario Brothers,"
2410
01:49:30,840 --> 01:49:32,840
there's a lot of these underground obstructions,
2411
01:49:32,840 --> 01:49:35,400
including grids of bricks like this.
2412
01:49:35,400 --> 01:49:38,400
And let me conjecture that if you slice this up, it's roughly a 3
2413
01:49:38,400 --> 01:49:43,560
by 3 grid of bricks that all interlock prettily to give us just one
2414
01:49:43,560 --> 01:49:45,400
big, large brick like this.
2415
01:49:45,400 --> 01:49:50,160
So if I want to print out a 3 by 3 grid, now things are getting a little more
2416
01:49:50,160 --> 01:49:54,510
interesting because up until now, I've printed either one row horizontally
2417
01:49:54,510 --> 01:49:56,580
or one column vertically.
2418
01:49:56,580 --> 01:49:58,380
But we haven't really seen any code where
2419
01:49:58,380 --> 01:50:02,670
I'm printing or living in two different dimensions like the game would imply.
2420
01:50:02,670 --> 01:50:05,560
But let me propose that we could do this.
2421
01:50:05,560 --> 01:50:08,640
Let me go ahead and say, all right, suppose I want to print a 3
2422
01:50:08,640 --> 01:50:10,500
by 3 grid of bricks.
2423
01:50:10,500 --> 01:50:16,590
It's really that I want to print, what, three rows of bricks.
2424
01:50:16,590 --> 01:50:18,063
A grid is three rows.
2425
01:50:18,063 --> 01:50:19,980
So if I take the high-level idea and reduce it
2426
01:50:19,980 --> 01:50:22,345
to something a little simpler, how do I do that?
2427
01:50:22,345 --> 01:50:24,720
Well, let me get rid of the printf for a moment as I did.
2428
01:50:24,720 --> 01:50:27,090
And let me just stipulate that this for loop,
2429
01:50:27,090 --> 01:50:29,230
even though it doesn't do anything useful yet,
2430
01:50:29,230 --> 01:50:33,390
will do something how many times just by design?
2431
01:50:33,390 --> 01:50:34,530
All right, three times.
2432
01:50:34,530 --> 01:50:35,850
This for loop is good to go.
2433
01:50:35,850 --> 01:50:39,390
It will do something three times by just using i to do the counting.
2434
01:50:39,390 --> 01:50:44,070
All right, well, if I want to print out now a row of three bricks all
2435
01:50:44,070 --> 01:50:46,710
on the same line, that's pretty similar to what
2436
01:50:46,710 --> 01:50:49,170
we did earlier when I just wanted to print out
2437
01:50:49,170 --> 01:50:51,090
four question marks in the sky.
2438
01:50:51,090 --> 01:50:52,960
So we've seen a solution there.
2439
01:50:52,960 --> 01:50:55,450
And I daresay we can compose one into the other.
2440
01:50:55,450 --> 01:50:58,590
So if I want to print out a row of bricks,
2441
01:50:58,590 --> 01:51:05,310
I could just do this for in i get 0 i less than 3 i++,
2442
01:51:05,310 --> 01:51:08,310
and then inside of this inner loop, if you will,
2443
01:51:08,310 --> 01:51:11,700
let me print out a single brick like this.
2444
01:51:11,700 --> 01:51:16,862
And then I don't like where this is going but, I think I've taken two ideas
2445
01:51:16,862 --> 01:51:17,820
and I've combined them.
2446
01:51:17,820 --> 01:51:23,080
But what might be problematic about lines 5 and 7 at the moment?
2447
01:51:23,080 --> 01:51:24,700
What might be bad here?
2448
01:51:24,700 --> 01:51:25,345
Yeah, in back?
2449
01:51:25,345 --> 01:51:27,665
AUDIENCE: You used the same integer i.
2450
01:51:27,665 --> 01:51:30,040
DAVID J. MALAN: Yeah, I'm using the same integer i, which
2451
01:51:30,040 --> 01:51:32,080
I feel like could get me into trouble.
2452
01:51:32,080 --> 01:51:34,480
If I'm trying to count three things here,
2453
01:51:34,480 --> 01:51:38,470
but then I'm hijacking this variable and using it inside of the loop,
2454
01:51:38,470 --> 01:51:41,560
I feel like I should avoid this collision of names.
2455
01:51:41,560 --> 01:51:43,930
And so what's a good alternative to i?
2456
01:51:43,930 --> 01:51:46,390
Well, a programmer, if nesting loops in this way,
2457
01:51:46,390 --> 01:51:47,980
would pretty commonly go with j.
2458
01:51:47,980 --> 01:51:50,975
You could certainly change this to be rows and columns
2459
01:51:50,975 --> 01:51:52,600
if you want more descriptive variables.
2460
01:51:52,600 --> 01:51:54,940
But i and j is pretty canonical.
2461
01:51:54,940 --> 01:51:59,020
So I'm going to go ahead and do this, j++ instead of i++ everywhere.
2462
01:51:59,020 --> 01:52:00,280
And let me try compiling this.
2463
01:52:00,280 --> 01:52:04,330
So make mario, Enter, ./mario.
2464
01:52:04,330 --> 01:52:06,560
OK, so a couple of things are wrong here.
2465
01:52:06,560 --> 01:52:08,480
This is not a 3 by 3 grid.
2466
01:52:08,480 --> 01:52:12,855
But if you count these things, how many did I indeed print at least?
2467
01:52:12,855 --> 01:52:14,485
You can probably just guess logically.
2468
01:52:14,485 --> 01:52:15,110
AUDIENCE: Nine.
2469
01:52:15,110 --> 01:52:17,110
DAVID J. MALAN: Yeah, there's nine hashes there.
2470
01:52:17,110 --> 01:52:18,940
Unfortunately, they're all on the same line
2471
01:52:18,940 --> 01:52:21,340
instead of on three different lines.
2472
01:52:21,340 --> 01:52:24,910
So where logically can I fix this?
2473
01:52:24,910 --> 01:52:26,535
I'm definitely printing all the bricks.
2474
01:52:26,535 --> 01:52:28,077
They're just not on the right levels.
2475
01:52:28,077 --> 01:52:28,646
Yeah?
2476
01:52:28,646 --> 01:52:31,078
AUDIENCE: If you put a new line at the first loop,
2477
01:52:31,078 --> 01:52:32,620
then you'll get three separate lines.
2478
01:52:32,620 --> 01:52:33,495
DAVID J. MALAN: Yeah.
2479
01:52:33,495 --> 01:52:36,580
So put a new line after the first loop, this inner loop, if you will,
2480
01:52:36,580 --> 01:52:38,000
the nested loop, if you will.
2481
01:52:38,000 --> 01:52:41,030
So let me go ahead and print out just a backslash n here.
2482
01:52:41,030 --> 01:52:42,073
And what's this doing?
2483
01:52:42,073 --> 01:52:43,990
Well, I think that's going to solve it by just
2484
01:52:43,990 --> 01:52:47,270
moving the cursor to the next line after you've done one row.
2485
01:52:47,270 --> 01:52:50,770
So let me go ahead and do make mario, Enter, ./mario,
2486
01:52:50,770 --> 01:52:52,070
and now we're in business.
2487
01:52:52,070 --> 01:52:54,850
So it's a very simplistic version of this same graphic,
2488
01:52:54,850 --> 01:52:57,400
but I'm leveraging two different ideas now--
2489
01:52:57,400 --> 01:52:59,350
or the same idea twice rather now.
2490
01:52:59,350 --> 01:53:03,970
I'm using one loop to control my cursor going row, by row, by row.
2491
01:53:03,970 --> 01:53:06,100
But then within that loop, I'm doing left to right,
2492
01:53:06,100 --> 01:53:08,290
dot, dot, dot, dot, dot, with printing out
2493
01:53:08,290 --> 01:53:10,960
each of these individual bricks like this.
2494
01:53:10,960 --> 01:53:13,600
Now, there's a little sloppiness here still.
2495
01:53:13,600 --> 01:53:16,630
If I want this to always be a square just because that's
2496
01:53:16,630 --> 01:53:20,800
what it looks like in the game, well, I could change it to be a 4 by 4
2497
01:53:20,800 --> 01:53:24,430
square by doing this or a 5 by 5 grid--
2498
01:53:24,430 --> 01:53:26,420
whoops-- by doing this.
2499
01:53:26,420 --> 01:53:30,010
Why is this perhaps not the best design to just keep changing the numbers when
2500
01:53:30,010 --> 01:53:33,330
I want to change the size?
2501
01:53:33,330 --> 01:53:34,440
Where could this go awry?
2502
01:53:34,440 --> 01:53:35,010
Yeah?
2503
01:53:35,010 --> 01:53:38,255
AUDIENCE: If it's a square, [INAUDIBLE]
2504
01:53:38,255 --> 01:53:39,130
DAVID J. MALAN: Yeah.
2505
01:53:39,130 --> 01:53:40,630
If it's always going to be a square and height
2506
01:53:40,630 --> 01:53:43,060
is going to be the same as width, I'm just inviting trouble here, right?
2507
01:53:43,060 --> 01:53:44,110
Eventually, I'm going to screw up.
2508
01:53:44,110 --> 01:53:45,680
I'm going to change one but not the other.
2509
01:53:45,680 --> 01:53:48,070
Then it's going to come out to be a rectangle instead of a proper square.
2510
01:53:48,070 --> 01:53:50,410
So I should probably solve this a little differently.
2511
01:53:50,410 --> 01:53:51,160
So let me do that.
2512
01:53:51,160 --> 01:53:54,700
At the top of my main function here, let me go ahead and give myself
2513
01:53:54,700 --> 01:53:59,980
a variable called maybe n for the number of bricks I want horizontally
2514
01:53:59,980 --> 01:54:01,000
and vertically.
2515
01:54:01,000 --> 01:54:03,550
And I'll just initialize that to 3 initially.
2516
01:54:03,550 --> 01:54:06,610
And instead of putting 3 here, I'll literally just use n.
2517
01:54:06,610 --> 01:54:09,100
But I'll do it in both places so that now, henceforth,
2518
01:54:09,100 --> 01:54:13,000
if I ever want to change this and change it to 4, or 5, or anything else,
2519
01:54:13,000 --> 01:54:13,845
I'm all done.
2520
01:54:13,845 --> 01:54:16,720
It's better designed because there's a lower probability of mistakes.
2521
01:54:16,720 --> 01:54:19,840
But I could technically still screw up somehow.
2522
01:54:19,840 --> 01:54:24,460
I could technically accidentally write a line of code like n++,
2523
01:54:24,460 --> 01:54:28,360
or I could just change the value of that variable even though I don't want it
2524
01:54:28,360 --> 01:54:28,985
to ever change.
2525
01:54:28,985 --> 01:54:31,693
And maybe it's because I'm a bad programmer, I copy/pasted wrong,
2526
01:54:31,693 --> 01:54:34,240
I'm working with someone who doesn't know what n represents,
2527
01:54:34,240 --> 01:54:38,440
I can defend myself and my code against human error
2528
01:54:38,440 --> 01:54:41,020
like that by going up here to line 5.
2529
01:54:41,020 --> 01:54:44,170
And instead of just declaring a simple variable like we did in Scratch,
2530
01:54:44,170 --> 01:54:47,360
I can further harden my code, so to speak,
2531
01:54:47,360 --> 01:54:50,740
by declaring it to be a constant using the keyword const.
2532
01:54:50,740 --> 01:54:53,980
Now, this is just a feature of C and some other languages
2533
01:54:53,980 --> 01:54:57,220
to protect you against yourself by proactively saying,
2534
01:54:57,220 --> 01:55:02,320
n is a constant, specifically the number 5 or, previously, the number 3.
2535
01:55:02,320 --> 01:55:05,530
You cannot accidentally write code elsewhere that changes it.
2536
01:55:05,530 --> 01:55:08,420
The computer will throw an error and catch that error.
2537
01:55:08,420 --> 01:55:12,160
So it's just a way of programming a little more defensively.
2538
01:55:12,160 --> 01:55:13,235
Some languages have this.
2539
01:55:13,235 --> 01:55:14,110
Some languages don't.
2540
01:55:14,110 --> 01:55:15,970
But in general, it's a good practice.
2541
01:55:15,970 --> 01:55:18,790
It makes your code better designed because it's just
2542
01:55:18,790 --> 01:55:22,570
as less vulnerable to mistakes by you, colleagues, or anyone else
2543
01:55:22,570 --> 01:55:23,570
using the code.
2544
01:55:23,570 --> 01:55:26,420
So let me change this back to 3 just to be our default.
2545
01:55:26,420 --> 01:55:28,580
But now I'm using n in both places.
2546
01:55:28,580 --> 01:55:33,250
And if I do make mario, ./mario, we're back to where we originally started.
2547
01:55:33,250 --> 01:55:35,560
But the code is a little more better designed.
2548
01:55:35,560 --> 01:55:37,330
And let me note this too.
2549
01:55:37,330 --> 01:55:40,720
All this time, I've been mentioning that correctness is important.
2550
01:55:40,720 --> 01:55:41,740
Design is important.
2551
01:55:41,740 --> 01:55:43,700
There is also this matter of style.
2552
01:55:43,700 --> 01:55:46,107
I've been very deliberately writing pretty code,
2553
01:55:46,107 --> 01:55:48,940
if you will-- not just the syntax highlighting, which, is automatic.
2554
01:55:48,940 --> 01:55:52,060
But notice that I keep indenting everything nicely.
2555
01:55:52,060 --> 01:55:55,450
Any time I have curly braces, like on lines 4 and 14,
2556
01:55:55,450 --> 01:55:57,400
everything is indented one level.
2557
01:55:57,400 --> 01:56:01,420
When I have additional curly braces on lines 7 and 13,
2558
01:56:01,420 --> 01:56:04,520
everything is nicely indented as well.
2559
01:56:04,520 --> 01:56:09,250
Technically speaking, the computer does not care about that kind of whitespace,
2560
01:56:09,250 --> 01:56:10,090
so to speak.
2561
01:56:10,090 --> 01:56:12,280
And you could really make a mess of things
2562
01:56:12,280 --> 01:56:15,205
like this because you have a strange sense of style
2563
01:56:15,205 --> 01:56:17,080
or just because you're being a little sloppy.
2564
01:56:17,080 --> 01:56:20,170
But this code is actually still correct.
2565
01:56:20,170 --> 01:56:23,260
If I recompile it-- let me open up my terminal window--
2566
01:56:23,260 --> 01:56:28,270
make mario, no errors, ./mario, it works perfectly fine.
2567
01:56:28,270 --> 01:56:30,910
But you can imagine just how annoying this now
2568
01:56:30,910 --> 01:56:34,693
is to read, certainly for a TA, but certainly for you the next day,
2569
01:56:34,693 --> 01:56:36,860
certainly for a colleague who has to read your code.
2570
01:56:36,860 --> 01:56:38,020
This is just bad style.
2571
01:56:38,020 --> 01:56:42,670
It still works, and it's well designed in that you're writing code
2572
01:56:42,670 --> 01:56:44,230
defensively, you're using a constant.
2573
01:56:44,230 --> 01:56:46,420
But, my god, the style is atrocious.
2574
01:56:46,420 --> 01:56:48,310
Now, you'll often find that there's tools
2575
01:56:48,310 --> 01:56:50,440
that can help you format your code for you
2576
01:56:50,440 --> 01:56:53,710
in a manner consistent with a courses or a company's style.
2577
01:56:53,710 --> 01:56:57,220
But this is the kind of muscle memory you'll want to develop over time too.
2578
01:56:57,220 --> 01:57:00,940
Take these VS Code suggestions as it's outputting lines of code for you
2579
01:57:00,940 --> 01:57:03,565
because it's trying to format your code in a readable way.
2580
01:57:03,565 --> 01:57:06,940
And, oh, my god, if and when you do have bugs in your code
2581
01:57:06,940 --> 01:57:08,717
and things aren't even indented properly,
2582
01:57:08,717 --> 01:57:11,800
there's no way you the human are going to be able to wrap your mind around
2583
01:57:11,800 --> 01:57:13,690
what's happening and where.
2584
01:57:13,690 --> 01:57:16,060
You're just making the problem harder for yourself.
2585
01:57:16,060 --> 01:57:21,190
So do get into this habit too of manifesting good style as well.
2586
01:57:21,190 --> 01:57:24,880
All right, well, let me propose that we don't only want a 3 by 3 grid.
2587
01:57:24,880 --> 01:57:26,840
We want this to be a little more dynamic.
2588
01:57:26,840 --> 01:57:32,020
So suppose we moved away from a constant to just using an integer called n.
2589
01:57:32,020 --> 01:57:35,230
And let's ask the user for the size of this grid
2590
01:57:35,230 --> 01:57:38,320
as by prompting them with get_int, as we've done before.
2591
01:57:38,320 --> 01:57:40,150
And I'll store it in n here.
2592
01:57:40,150 --> 01:57:42,880
And then I can go ahead and, more dynamically,
2593
01:57:42,880 --> 01:57:46,450
run make mario to compile it-- whoops.
2594
01:57:46,450 --> 01:57:49,930
Oh, I screwed up accidentally.
2595
01:57:49,930 --> 01:57:53,785
What is it suggesting I do, albeit cryptically?
2596
01:57:53,785 --> 01:57:56,660
AUDIENCE: You have to include the cs50.h.
2597
01:57:56,660 --> 01:57:59,930
DAVID J. MALAN: Yeah, I forgot to include the CS50 header file up top.
2598
01:57:59,930 --> 01:58:03,420
And that's why it doesn't know that get_int is, in fact, valid.
2599
01:58:03,420 --> 01:58:04,880
So that's an easy fix.
2600
01:58:04,880 --> 01:58:07,730
I'm just going to go up here and include cs50.h.
2601
01:58:07,730 --> 01:58:10,790
Now I'm going to clear my terminal and rerun make mario.
2602
01:58:10,790 --> 01:58:12,800
Now we're good-- ./mario.
2603
01:58:12,800 --> 01:58:14,550
And now notice I'm prompted for size.
2604
01:58:14,550 --> 01:58:16,490
So if I type in 3, it's the same as before.
2605
01:58:16,490 --> 01:58:20,900
If I type in 10, it's even bigger, but it happens all now automatically.
2606
01:58:20,900 --> 01:58:23,360
But there are some things that we're not detecting.
2607
01:58:23,360 --> 01:58:25,940
For instance, suppose I type in cat.
2608
01:58:25,940 --> 01:58:28,770
Well, that's handled by the get_int function, as I claimed earlier.
2609
01:58:28,770 --> 01:58:30,687
That's one of the features of using a library.
2610
01:58:30,687 --> 01:58:32,570
You don't have to deal with erroneous input.
2611
01:58:32,570 --> 01:58:36,200
But we only designed a function called get_int to get you an integer.
2612
01:58:36,200 --> 01:58:39,050
We don't know if you want it to be positive, negative, zero,
2613
01:58:39,050 --> 01:58:40,680
or some combination thereof.
2614
01:58:40,680 --> 01:58:43,940
And it's kind of weird to allow the user to type in negative 1
2615
01:58:43,940 --> 01:58:48,440
for the size of the grid or negative 3 for the size of the grid.
2616
01:58:48,440 --> 01:58:51,230
And indeed, your code does nothing, so at least it's not crashing.
2617
01:58:51,230 --> 01:58:52,730
But that's kind of stupid, right?
2618
01:58:52,730 --> 01:58:54,530
It'd be nice to force the user if they want
2619
01:58:54,530 --> 01:58:57,150
a grid to give us a positive value.
2620
01:58:57,150 --> 01:58:58,530
So how could we do this?
2621
01:58:58,530 --> 01:59:03,920
Well, I could go up here and I could say something like if n is less than 1--
2622
01:59:03,920 --> 01:59:08,190
so if it's 0 or negative, which I don't want, what could I do?
2623
01:59:08,190 --> 01:59:12,380
Well, I could say, well, prompt the user again for the size.
2624
01:59:12,380 --> 01:59:16,613
And now notice, I'm not declaring n again because once it exists,
2625
01:59:16,613 --> 01:59:18,530
you don't have to mention the data type again.
2626
01:59:18,530 --> 01:59:19,790
We said that earlier.
2627
01:59:19,790 --> 01:59:21,510
But this is kind of stupid.
2628
01:59:21,510 --> 01:59:22,010
Why?
2629
01:59:22,010 --> 01:59:25,190
Because now when you've given the user a second chance, OK, now maybe
2630
01:59:25,190 --> 01:59:29,720
I'll do-- all right, if this version of n is less than 1, well,
2631
01:59:29,720 --> 01:59:33,020
let's just go and prompt the user a third time.
2632
01:59:33,020 --> 01:59:35,240
I mean, you can see where this is stupidly going.
2633
01:59:35,240 --> 01:59:38,510
This can't be the right solution to keep typing recursively
2634
01:59:38,510 --> 01:59:39,860
the same thing again and again.
2635
01:59:39,860 --> 01:59:40,790
Where would it stop?
2636
01:59:40,790 --> 01:59:42,873
You'd have to give them a finite number of chances
2637
01:59:42,873 --> 01:59:44,810
or just make a mess of your code.
2638
01:59:44,810 --> 01:59:48,170
So what would be intuitively a better solution here?
2639
01:59:48,170 --> 01:59:49,128
AUDIENCE: A while loop.
2640
01:59:49,128 --> 01:59:50,920
DAVID J. MALAN: Yeah, so some kind of loop.
2641
01:59:50,920 --> 01:59:52,160
We've seen a while loop.
2642
01:59:52,160 --> 01:59:54,240
We've seen a for loop, so maybe one of those.
2643
01:59:54,240 --> 01:59:55,290
So let me try this.
2644
01:59:55,290 --> 01:59:58,760
Let me delete this messiness and just go back to the first question.
2645
01:59:58,760 --> 01:59:59,790
And let me do this.
2646
01:59:59,790 --> 02:00:02,780
So while n is less than 1--
2647
02:00:02,780 --> 02:00:05,190
so while the number is not what we want--
2648
02:00:05,190 --> 02:00:09,560
let's just prompt the user in a loop this time for the size again.
2649
02:00:09,560 --> 02:00:15,470
Now, here too, this is better because it's only two requests for information.
2650
02:00:15,470 --> 02:00:19,640
But clearly, lines 6 and 9 are pretty much identical other than the int.
2651
02:00:19,640 --> 02:00:23,120
And if I went in and changed the size, if I
2652
02:00:23,120 --> 02:00:26,300
add this, if I change the wording here, change it to a different language,
2653
02:00:26,300 --> 02:00:27,350
I have to change it in two places.
2654
02:00:27,350 --> 02:00:27,850
That's bad.
2655
02:00:27,850 --> 02:00:29,330
Copy/paste, bad.
2656
02:00:29,330 --> 02:00:31,040
So what might be better?
2657
02:00:31,040 --> 02:00:33,890
Well, it turns out, there's another paradigm in C
2658
02:00:33,890 --> 02:00:37,730
that you can use that gets around this problem, this duplication of code.
2659
02:00:37,730 --> 02:00:41,210
It would be much nicer if I just write the code once.
2660
02:00:41,210 --> 02:00:45,510
And I can do that using a third type of loop called a do while loop.
2661
02:00:45,510 --> 02:00:48,000
So it turns out, in C, you can do this.
2662
02:00:48,000 --> 02:00:50,210
If you want to get the value of a variable like n,
2663
02:00:50,210 --> 02:00:53,370
first just to create the variable without an initial value.
2664
02:00:53,370 --> 02:00:56,870
So int n semicolon means we don't know what value it has, yes.
2665
02:00:56,870 --> 02:00:57,590
But that's OK.
2666
02:00:57,590 --> 02:00:59,840
We're going to add a value to it eventually.
2667
02:00:59,840 --> 02:01:02,870
Then I'm going to say this, do, literally.
2668
02:01:02,870 --> 02:01:04,460
I'm going to open my curly braces.
2669
02:01:04,460 --> 02:01:05,930
And what do I want to do?
2670
02:01:05,930 --> 02:01:09,920
I want to assign to n the return value of get_int,
2671
02:01:09,920 --> 02:01:11,750
prompting the user for size.
2672
02:01:11,750 --> 02:01:14,040
Well, when do you want to do that?
2673
02:01:14,040 --> 02:01:17,900
I want to do that while n is less than 1.
2674
02:01:17,900 --> 02:01:21,410
And this code now achieves the exact same goal,
2675
02:01:21,410 --> 02:01:23,570
but by never repeating myself.
2676
02:01:23,570 --> 02:01:24,230
Why?
2677
02:01:24,230 --> 02:01:29,210
Well, notice on these lines of code now, I'm literally saying on line 6,
2678
02:01:29,210 --> 02:01:31,175
give me a variable called n of type integer.
2679
02:01:31,175 --> 02:01:33,300
It doesn't have a value initially, but that's fine.
2680
02:01:33,300 --> 02:01:34,640
You can do that.
2681
02:01:34,640 --> 02:01:36,380
Line 7 says, do the following.
2682
02:01:36,380 --> 02:01:39,890
What do you want to do? get_int, prompting the user with the word size,
2683
02:01:39,890 --> 02:01:41,660
and just store that value in n.
2684
02:01:41,660 --> 02:01:45,210
But because C code runs top to bottom, left to right,
2685
02:01:45,210 --> 02:01:49,040
now it's reasonable on line 11 to ask that question, OK, is
2686
02:01:49,040 --> 02:01:53,670
the current value of n, which it definitely got on line 8, less than 1?
2687
02:01:53,670 --> 02:01:56,420
And if the user didn't cooperate-- they typed in 0, or negative 1,
2688
02:01:56,420 --> 02:01:58,400
or negative 3-- what's going to happen?
2689
02:01:58,400 --> 02:02:02,510
It's going to go back up here and repeat, repeat, repeat everything
2690
02:02:02,510 --> 02:02:04,530
in the do while loop.
2691
02:02:04,530 --> 02:02:06,438
So a do while loop in C--
2692
02:02:06,438 --> 02:02:08,480
which is not something some other languages have.
2693
02:02:08,480 --> 02:02:10,730
Python, if you know it, does not have a do while loop.
2694
02:02:10,730 --> 02:02:13,310
This is perhaps the cleanest way to achieve this,
2695
02:02:13,310 --> 02:02:16,790
even though it's a little weird that you have to declare your variable,
2696
02:02:16,790 --> 02:02:20,570
create your variable up top, and then check it down below.
2697
02:02:20,570 --> 02:02:22,980
But otherwise, it's similar to a while loop.
2698
02:02:22,980 --> 02:02:26,150
It just flips the order in which you're asking the question.
2699
02:02:26,150 --> 02:02:28,820
Any questions on this construct?
2700
02:02:28,820 --> 02:02:30,827
And do while, in general, is super useful when
2701
02:02:30,827 --> 02:02:32,660
you want to get input from the user and make
2702
02:02:32,660 --> 02:02:35,640
sure it meets certain requirements.
2703
02:02:35,640 --> 02:02:39,530
So all right, so now that we have this building block after that interlude.
2704
02:02:39,530 --> 02:02:41,750
How can I go about cleaning up this code?
2705
02:02:41,750 --> 02:02:45,230
And then let's conclude by taking a look at things that our code can't do
2706
02:02:45,230 --> 02:02:47,720
or can't do very well or correctly.
2707
02:02:47,720 --> 02:02:50,930
Let me propose that in a final version of Mario,
2708
02:02:50,930 --> 02:02:53,520
let me just add what are called now some comments.
2709
02:02:53,520 --> 02:02:56,880
So it turns out, in code in C, you can define
2710
02:02:56,880 --> 02:02:59,173
what are called comments, which are just notes to self.
2711
02:02:59,173 --> 02:03:00,840
Some of you discovered these in Scratch.
2712
02:03:00,840 --> 02:03:02,590
There's little yellow sticky notes you can
2713
02:03:02,590 --> 02:03:04,680
use to add citations or explanations.
2714
02:03:04,680 --> 02:03:07,020
In C, there's a couple of ways to write comments.
2715
02:03:07,020 --> 02:03:09,960
And in general, comments are notes for yourself, for your TA,
2716
02:03:09,960 --> 02:03:13,860
for your colleague as to what your code is doing and why or how.
2717
02:03:13,860 --> 02:03:15,660
It's a little explanatory note in English
2718
02:03:15,660 --> 02:03:17,860
or whatever your human language might be.
2719
02:03:17,860 --> 02:03:23,220
So for instance, what I might do here in my implementation
2720
02:03:23,220 --> 02:03:27,870
of this version of mario, I might first ask myself a question like--
2721
02:03:27,870 --> 02:03:30,420
I might first make a note to self like this on a new line,
2722
02:03:30,420 --> 02:03:34,350
above this first block of code, Get size of grid.
2723
02:03:34,350 --> 02:03:38,100
It's just an explanatory remark in any terse English
2724
02:03:38,100 --> 02:03:41,820
that generally explains the next six or so lines, the next chunk
2725
02:03:41,820 --> 02:03:43,560
or block of code, if you will.
2726
02:03:43,560 --> 02:03:46,500
It would be a little excessive to comment every single line.
2727
02:03:46,500 --> 02:03:49,680
At some point, the programmer should know what individual lines of code do.
2728
02:03:49,680 --> 02:03:53,700
But it's nice to be able to glance at this comment on line 6
2729
02:03:53,700 --> 02:03:56,818
that starts with two slashes, and it gets grayed out
2730
02:03:56,818 --> 02:03:58,110
because of syntax highlighting.
2731
02:03:58,110 --> 02:03:59,070
It's not logic.
2732
02:03:59,070 --> 02:04:00,440
It's just a note to self.
2733
02:04:00,440 --> 02:04:02,190
It generally gives me a little cheat sheet
2734
02:04:02,190 --> 02:04:05,160
as to what the following lines of code should be doing and/or why.
2735
02:04:05,160 --> 02:04:07,910
And then down here, well, there's a second block of code
2736
02:04:07,910 --> 02:04:08,910
that's a bunch of lines.
2737
02:04:08,910 --> 02:04:14,130
But together, this just, what, prints grid of bricks.
2738
02:04:14,130 --> 02:04:16,350
And so it's another comment to myself that
2739
02:04:16,350 --> 02:04:18,540
just makes it a little more understandable what
2740
02:04:18,540 --> 02:04:20,880
these 20-some-odd lines of code are doing by adding
2741
02:04:20,880 --> 02:04:23,760
some English explanations thereof.
2742
02:04:23,760 --> 02:04:26,970
But now that I have these, wouldn't it be nice
2743
02:04:26,970 --> 02:04:31,140
if I could abstract these pieces of functionality away, this
2744
02:04:31,140 --> 02:04:33,600
getting of the size and this printing of the grid?
2745
02:04:33,600 --> 02:04:37,590
In other words, suppose that you didn't know where to begin with this problem.
2746
02:04:37,590 --> 02:04:39,960
And the problem at hand were literally implement
2747
02:04:39,960 --> 02:04:43,530
a program that prints a grid of bricks of some variable size--
2748
02:04:43,530 --> 02:04:46,440
3, or 4, or 5, or whatever the human types in.
2749
02:04:46,440 --> 02:04:48,810
If you have really no idea where to start,
2750
02:04:48,810 --> 02:04:51,540
comments are actually a good way of getting
2751
02:04:51,540 --> 02:04:55,680
started because comments can be an approximation of what we call last week
2752
02:04:55,680 --> 02:04:56,310
pseudocode.
2753
02:04:56,310 --> 02:05:00,360
Pseudocode is terse English that gets your point across, like for the phone
2754
02:05:00,360 --> 02:05:02,080
book searching like last time.
2755
02:05:02,080 --> 02:05:04,050
So if you didn't really know where to begin,
2756
02:05:04,050 --> 02:05:06,910
you could do something like this.
2757
02:05:06,910 --> 02:05:11,730
I could, for instance, just say, Get size of grid as my first step
2758
02:05:11,730 --> 02:05:14,610
and then Print grid of bricks as my second step.
2759
02:05:14,610 --> 02:05:16,410
And that's it for my program thus far.
2760
02:05:16,410 --> 02:05:18,690
This is now implemented in pseudocode.
2761
02:05:18,690 --> 02:05:20,910
I have some massive placeholders there.
2762
02:05:20,910 --> 02:05:22,380
I still have work to be done.
2763
02:05:22,380 --> 02:05:26,050
But at least I have a high-level solution to the problem in comments.
2764
02:05:26,050 --> 02:05:28,230
And now I can even go this far.
2765
02:05:28,230 --> 02:05:32,010
I could say, well, let's suppose that there's just a function already
2766
02:05:32,010 --> 02:05:34,650
that exists called get size.
2767
02:05:34,650 --> 02:05:36,220
I could do something like this.
2768
02:05:36,220 --> 02:05:38,790
I could do int n equals get_size.
2769
02:05:38,790 --> 02:05:41,010
And now I just have to assume for the moment
2770
02:05:41,010 --> 02:05:43,000
that some abstraction called get_size exists.
2771
02:05:43,000 --> 02:05:43,500
It doesn't.
2772
02:05:43,500 --> 02:05:45,420
This does not come with the CS50 library.
2773
02:05:45,420 --> 02:05:47,520
But I could invent it, I bet.
2774
02:05:47,520 --> 02:05:49,110
How else might I proceed?
2775
02:05:49,110 --> 02:05:51,930
Well, let's just assume for the moment that there's also
2776
02:05:51,930 --> 02:05:57,060
a function called print_grid that just prints a grid of that size n.
2777
02:05:57,060 --> 02:05:58,950
So here too is an abstraction.
2778
02:05:58,950 --> 02:06:00,330
These puzzle pieces don't exist.
2779
02:06:00,330 --> 02:06:01,800
These functions don't yet exist.
2780
02:06:01,800 --> 02:06:06,240
But in C, just like in Scratch, I can create my own functions.
2781
02:06:06,240 --> 02:06:07,600
How do I do that?
2782
02:06:07,600 --> 02:06:09,630
Well, let me go down later in the file.
2783
02:06:09,630 --> 02:06:12,810
And by convention, you generally want to leave main at the top of your code.
2784
02:06:12,810 --> 02:06:13,110
Why?
2785
02:06:13,110 --> 02:06:15,235
Because it's the main function, and it's just where
2786
02:06:15,235 --> 02:06:18,090
the human eye is going to look to see what some file of code does.
2787
02:06:18,090 --> 02:06:19,360
And let me do this.
2788
02:06:19,360 --> 02:06:23,910
I want to create a function of my own called get_size whose purpose in life
2789
02:06:23,910 --> 02:06:26,010
is to get the size that the user wants.
2790
02:06:26,010 --> 02:06:28,380
I want this function to return an integer.
2791
02:06:28,380 --> 02:06:30,420
And the syntax for doing that is this, right,
2792
02:06:30,420 --> 02:06:34,920
similar to a variable, the data type that this function returns.
2793
02:06:34,920 --> 02:06:37,450
I don't need this function to take any inputs.
2794
02:06:37,450 --> 02:06:40,500
And so I'm going to use a new keyword that we've actually been using thus
2795
02:06:40,500 --> 02:06:42,292
far-- more on it another time-- just called
2796
02:06:42,292 --> 02:06:45,810
void, which just means this get_size function does not take any inputs.
2797
02:06:45,810 --> 02:06:46,950
It does have an output.
2798
02:06:46,950 --> 02:06:48,138
It outputs an int.
2799
02:06:48,138 --> 02:06:50,430
And this is just the weird order in which you write it.
2800
02:06:50,430 --> 02:06:54,000
You write the output format, the name of the function, and then the inputs,
2801
02:06:54,000 --> 02:06:55,920
if any, inside of parentheses.
2802
02:06:55,920 --> 02:06:57,727
And now I can implement get_size.
2803
02:06:57,727 --> 02:06:59,310
But I've already implemented get_size.
2804
02:06:59,310 --> 02:07:01,140
Or at least now at this point in the story,
2805
02:07:01,140 --> 02:07:03,180
I at least know concretely what to do.
2806
02:07:03,180 --> 02:07:05,730
And I could figure out eventually, with some trial and error
2807
02:07:05,730 --> 02:07:08,040
perhaps, all right, if I declare a variable
2808
02:07:08,040 --> 02:07:12,270
and I do the following n equals get_int, prompting the user for size,
2809
02:07:12,270 --> 02:07:17,910
and I keep doing that while n is less than 1, once that block of code
2810
02:07:17,910 --> 02:07:22,830
is done, here is a new keyword in C where you can return that value n.
2811
02:07:22,830 --> 02:07:27,330
So I keep referring to these values that some functions return as return values.
2812
02:07:27,330 --> 02:07:30,870
In C, there's literally a keyword called return
2813
02:07:30,870 --> 02:07:33,930
that will hand back to any function that uses
2814
02:07:33,930 --> 02:07:36,970
that function the value in question.
2815
02:07:36,970 --> 02:07:41,220
So in a nutshell, between lines 15 and 21 now,
2816
02:07:41,220 --> 02:07:45,270
here is some code identical to our solution earlier that gets a value
2817
02:07:45,270 --> 02:07:47,280
n from the user that is positive.
2818
02:07:47,280 --> 02:07:48,720
It's 1, or 2, or higher.
2819
02:07:48,720 --> 02:07:51,180
It's not 0, or it's not less than 1.
2820
02:07:51,180 --> 02:07:56,360
And as soon as we've got that value, we hand it back as a return value.
2821
02:07:56,360 --> 02:07:58,990
Notice how I'm using this function on line 7.
2822
02:07:58,990 --> 02:08:01,630
Just like with get_int, just like with get_string,
2823
02:08:01,630 --> 02:08:04,650
I'm calling the function-- nothing in the parentheses in this case.
2824
02:08:04,650 --> 02:08:06,400
But then I'm using the assignment operator
2825
02:08:06,400 --> 02:08:09,970
to copy whatever its return value is into my variable n.
2826
02:08:09,970 --> 02:08:13,570
And so now I have a function that didn't use
2827
02:08:13,570 --> 02:08:19,090
to exist called get_size that gets me a positive integer no matter what.
2828
02:08:19,090 --> 02:08:21,710
And now for the grid, how do I do this?
2829
02:08:21,710 --> 02:08:23,860
How do I invent a function called print_grid
2830
02:08:23,860 --> 02:08:27,160
that takes a single argument, a number and prints a grid of that size?
2831
02:08:27,160 --> 02:08:29,180
Well, let's go down here.
2832
02:08:29,180 --> 02:08:32,050
I'm going to write the name of this function print_grid.
2833
02:08:32,050 --> 02:08:33,590
This function just needs to print.
2834
02:08:33,590 --> 02:08:35,440
It has a side effect, as we keep saying.
2835
02:08:35,440 --> 02:08:38,230
So I'm just going to say it has no return value.
2836
02:08:38,230 --> 02:08:39,040
It's just void.
2837
02:08:39,040 --> 02:08:40,820
It doesn't have an output, per se.
2838
02:08:40,820 --> 02:08:42,670
It's just an aesthetic side effect.
2839
02:08:42,670 --> 02:08:44,660
But it does take in an argument.
2840
02:08:44,660 --> 02:08:47,830
An argument is an input, and the syntax for this in C
2841
02:08:47,830 --> 02:08:52,337
is to name the type of the input it takes and the name of the variable.
2842
02:08:52,337 --> 02:08:53,920
And I could call this anything I want.
2843
02:08:53,920 --> 02:08:54,940
I'll call it size.
2844
02:08:54,940 --> 02:08:56,140
I could call it n.
2845
02:08:56,140 --> 02:08:58,840
And it's OK to use the same variable in different functions,
2846
02:08:58,840 --> 02:09:01,030
but I'll call it size just to be distinct.
2847
02:09:01,030 --> 02:09:03,010
And then in this function, I'm just going
2848
02:09:03,010 --> 02:09:07,210
to copy from memory the same code is before. for int i get 0,
2849
02:09:07,210 --> 02:09:09,250
i less than size--
2850
02:09:09,250 --> 02:09:18,790
instead of 3-- i++, inside of this, for int j gets 0, j is less than size j++,
2851
02:09:18,790 --> 02:09:23,500
and inside of that, print out with printf a single hash,
2852
02:09:23,500 --> 02:09:28,660
print out after that loop a single new line, and that's it.
2853
02:09:28,660 --> 02:09:30,370
Now, I did this fast, admittedly.
2854
02:09:30,370 --> 02:09:32,860
But it's the same code that I wrote earlier.
2855
02:09:32,860 --> 02:09:34,750
But now, just like I did with Scratch, let
2856
02:09:34,750 --> 02:09:36,910
me just arbitrarily hit Enter a bunch of times
2857
02:09:36,910 --> 02:09:39,190
to move the code out of sight, out of mind.
2858
02:09:39,190 --> 02:09:40,900
Now I have abstractions.
2859
02:09:40,900 --> 02:09:44,350
I have puzzle pieces that now exist called get_size and print_grid,
2860
02:09:44,350 --> 02:09:48,160
syntax for which takes some getting used to, but they now just exist.
2861
02:09:48,160 --> 02:09:50,590
Except I do need to do one thing.
2862
02:09:50,590 --> 02:09:56,260
Because C is a little naive, if I try to do make mario now and hit Enter,
2863
02:09:56,260 --> 02:09:59,500
implicit declaration of function get_size is invalid.
2864
02:09:59,500 --> 02:10:03,460
And we've seen that before when I hadn't included a file.
2865
02:10:03,460 --> 02:10:06,362
When I hadn't included CS50 library, get_int didn't work.
2866
02:10:06,362 --> 02:10:09,070
But that's not the issue here because this is not from a library.
2867
02:10:09,070 --> 02:10:10,270
I just invented this.
2868
02:10:10,270 --> 02:10:12,580
C takes you literally.
2869
02:10:12,580 --> 02:10:15,610
And if you define these functions at the bottom of your file,
2870
02:10:15,610 --> 02:10:18,910
they don't exist on line 7 or 10.
2871
02:10:18,910 --> 02:10:20,690
So I could do this.
2872
02:10:20,690 --> 02:10:23,590
I could, all right, fine, well, let me just highlight all of this,
2873
02:10:23,590 --> 02:10:26,342
cut to my clipboard, and paste it up here.
2874
02:10:26,342 --> 02:10:27,550
This would solve the problem.
2875
02:10:27,550 --> 02:10:30,280
I could just move all of those functions at the top of my file.
2876
02:10:30,280 --> 02:10:33,380
That's annoying because now main is at the bottom of the file.
2877
02:10:33,380 --> 02:10:34,930
It's going to take longer to find it.
2878
02:10:34,930 --> 02:10:36,560
That's not a clean solution.
2879
02:10:36,560 --> 02:10:39,170
So let me put it back where it was at the bottom.
2880
02:10:39,170 --> 02:10:40,730
And let me do this.
2881
02:10:40,730 --> 02:10:44,110
This is the only time in CS50 and, really in C programming
2882
02:10:44,110 --> 02:10:46,060
where copy/paste is reasonable.
2883
02:10:46,060 --> 02:10:50,320
If you copy and paste the first line of code from each function
2884
02:10:50,320 --> 02:10:55,000
and then end it with a semicolon, you can tease the compiler
2885
02:10:55,000 --> 02:10:58,270
by giving it just enough of a hint at the top of the file
2886
02:10:58,270 --> 02:11:01,010
that, OK, these functions don't exist till down later.
2887
02:11:01,010 --> 02:11:03,190
But here's a hint that they will exist.
2888
02:11:03,190 --> 02:11:07,660
This is how you can convince the compiler to trust you.
2889
02:11:07,660 --> 02:11:11,830
So those other functions can still be lower in the file, below main.
2890
02:11:11,830 --> 02:11:14,440
But now when I do make mario--
2891
02:11:14,440 --> 02:11:15,190
oh, damn it.
2892
02:11:15,190 --> 02:11:17,260
Oh, I said print instead of printf.
2893
02:11:17,260 --> 02:11:20,860
That's my bad-- printf.
2894
02:11:20,860 --> 02:11:26,665
So if I do make mario, ./mario, now I can type in 3,
2895
02:11:26,665 --> 02:11:27,790
and we're back in business.
2896
02:11:27,790 --> 02:11:30,190
Now, this was a very heavy-handed way in long way
2897
02:11:30,190 --> 02:11:32,800
to get to a much more complicated solution.
2898
02:11:32,800 --> 02:11:35,240
But this solution, in some sense, is better designed.
2899
02:11:35,240 --> 02:11:35,740
Why?
2900
02:11:35,740 --> 02:11:38,050
Because now, especially without the comments,
2901
02:11:38,050 --> 02:11:40,060
I mean, look how short my code is.
2902
02:11:40,060 --> 02:11:42,430
My main function is literally two lines of code.
2903
02:11:42,430 --> 02:11:42,940
Why?
2904
02:11:42,940 --> 02:11:46,338
Well, I factored out the juicy stuff into its own functions.
2905
02:11:46,338 --> 02:11:48,880
And now, especially if I'm working with colleagues or others,
2906
02:11:48,880 --> 02:11:52,297
you could imagine splitting up large programs into smaller parts,
2907
02:11:52,297 --> 02:11:54,380
having different people implement different parts,
2908
02:11:54,380 --> 02:11:58,750
so long as you all agree in advance on what those inputs and those outputs
2909
02:11:58,750 --> 02:12:00,410
actually are.
2910
02:12:00,410 --> 02:12:04,300
All right, so let's now consider what computers can do well and not so well.
2911
02:12:04,300 --> 02:12:07,360
C indeed supports a whole bunch of operators, mathematically,
2912
02:12:07,360 --> 02:12:10,610
via which we can do addition, and subtraction, multiplication, division,
2913
02:12:10,610 --> 02:12:14,025
and even calculate the remainder when you divide one number by another.
2914
02:12:14,025 --> 02:12:16,900
In fact, why don't we go ahead and use these in a very simple program
2915
02:12:16,900 --> 02:12:19,130
and make our very own calculator?
2916
02:12:19,130 --> 02:12:21,400
So let me go over here to VS Code.
2917
02:12:21,400 --> 02:12:25,030
Let me go ahead and create a new file called calculator.c.
2918
02:12:25,030 --> 02:12:27,550
And in this file, let's go ahead and first include
2919
02:12:27,550 --> 02:12:33,670
a couple of now familiar header files-- cs50.h as well as stdio.h.
2920
02:12:33,670 --> 02:12:37,540
Let's go ahead then and declare main with int main(void).
2921
02:12:37,540 --> 02:12:40,250
And then inside of main, let's do something relatively simple.
2922
02:12:40,250 --> 02:12:42,790
Let's declare an int and call it x, and set
2923
02:12:42,790 --> 02:12:45,670
it equal to whatever the return value is of get int,
2924
02:12:45,670 --> 02:12:48,040
prompting the user for a value for x.
2925
02:12:48,040 --> 02:12:50,240
Let's then give ourselves a second variable.
2926
02:12:50,240 --> 02:12:51,490
We'll call it, say, y.
2927
02:12:51,490 --> 02:12:55,230
Set that equal to the return value of another call to get_int,
2928
02:12:55,230 --> 02:12:57,780
prompting the user this time for that value y.
2929
02:12:57,780 --> 02:13:00,360
And then let's very simply go ahead at the very end
2930
02:13:00,360 --> 02:13:05,080
and just print out, say, the sum of x plus y, a super simple calculator.
2931
02:13:05,080 --> 02:13:08,640
So I'll use printf, quote/unquote, %i for integer,
2932
02:13:08,640 --> 02:13:10,930
backslash n to give me the new line.
2933
02:13:10,930 --> 02:13:14,640
Then I'm going to go ahead and do x plus y to indeed print out the sum.
2934
02:13:14,640 --> 02:13:16,710
Let me go down to my terminal window now.
2935
02:13:16,710 --> 02:13:20,340
Let me do make calculator in order to compile the code.
2936
02:13:20,340 --> 02:13:22,080
No error messages, so that's good.
2937
02:13:22,080 --> 02:13:23,880
Let me do ./calculator.
2938
02:13:23,880 --> 02:13:28,500
And let's do something like 2 plus 2, which, of course, should equal 4.
2939
02:13:28,500 --> 02:13:29,340
And it does.
2940
02:13:29,340 --> 02:13:33,660
But it turns out that sometimes there are going to be limitations
2941
02:13:33,660 --> 02:13:34,677
that we bump up against.
2942
02:13:34,677 --> 02:13:36,510
And let me get a little more ambitious here.
2943
02:13:36,510 --> 02:13:37,890
Let me clear my terminal window.
2944
02:13:37,890 --> 02:13:39,990
And let me go ahead and rerun calculator again.
2945
02:13:39,990 --> 02:13:47,280
And this time, let's, oh, 2 billion for x, and let's type in the same for y.
2946
02:13:47,280 --> 02:13:49,740
And, of course, now the answer of 2 billion plus 2 billion
2947
02:13:49,740 --> 02:13:52,560
should, of course, be 4 billion.
2948
02:13:52,560 --> 02:13:53,970
And yet, it's not.
2949
02:13:53,970 --> 02:13:56,790
So curiously, we see, of all things, a negative number
2950
02:13:56,790 --> 02:14:00,060
here, which suggests that somehow the plus operator doesn't quite
2951
02:14:00,060 --> 02:14:02,070
work as well as we might like.
2952
02:14:02,070 --> 02:14:04,240
Now, why might this actually be?
2953
02:14:04,240 --> 02:14:07,770
Well, it turns out that inside of your computer is, of course, memory, or RAM,
2954
02:14:07,770 --> 02:14:08,850
Random Access Memory.
2955
02:14:08,850 --> 02:14:11,160
And depending on the size of your computer and the type of computer,
2956
02:14:11,160 --> 02:14:13,410
it might very well look a little something like this--
2957
02:14:13,410 --> 02:14:15,930
a little circuit board with these black little modules on it
2958
02:14:15,930 --> 02:14:19,320
that actually contain all of the bytes of your computer's memory.
2959
02:14:19,320 --> 02:14:22,200
Unfortunately, you and I only have a finite amount
2960
02:14:22,200 --> 02:14:25,080
of this memory inside of our computers, which
2961
02:14:25,080 --> 02:14:27,250
means no matter how high we want to count,
2962
02:14:27,250 --> 02:14:29,670
there's ultimately going to be a limitation on how high we
2963
02:14:29,670 --> 02:14:32,790
can count because we only have a finite amount of memory.
2964
02:14:32,790 --> 02:14:35,800
We don't have an infinite number of zeros and ones to play with.
2965
02:14:35,800 --> 02:14:38,640
We have to actually be bounded ultimately.
2966
02:14:38,640 --> 02:14:40,072
So what's the implication of this?
2967
02:14:40,072 --> 02:14:42,030
Well, it turns out that computers typically use
2968
02:14:42,030 --> 02:14:46,110
as many as 32 bits in zeros or ones to represent something
2969
02:14:46,110 --> 02:14:48,120
like an integer, or in C, in int.
2970
02:14:48,120 --> 02:14:50,010
So for instance, the smallest number we could
2971
02:14:50,010 --> 02:14:53,830
represent using 32 ints, of course, using 32 bits, of course,
2972
02:14:53,830 --> 02:14:55,020
would be zero--
2973
02:14:55,020 --> 02:14:56,970
32 zeros like this here.
2974
02:14:56,970 --> 02:14:59,100
And the biggest number we could represent
2975
02:14:59,100 --> 02:15:03,180
is by changing all of those zeros to ones, which, in this case,
2976
02:15:03,180 --> 02:15:07,200
will ideally give us a number that equals roughly 4 billion in total.
2977
02:15:07,200 --> 02:15:15,390
It's actually 4,294,967,295 maximally if you set all 32 of those bits to ones
2978
02:15:15,390 --> 02:15:17,160
and then do out the actual math.
2979
02:15:17,160 --> 02:15:20,520
The catch, though, is that we humans and computers in general
2980
02:15:20,520 --> 02:15:24,730
also sometimes want to and need to be able to represent negative numbers.
2981
02:15:24,730 --> 02:15:28,230
So if you want to represent negative numbers as well as positive numbers
2982
02:15:28,230 --> 02:15:30,960
in 0, you can't really just start counting at 0
2983
02:15:30,960 --> 02:15:33,360
and go all the way up to roughly 4 billion.
2984
02:15:33,360 --> 02:15:35,280
You've got to split the difference and maybe
2985
02:15:35,280 --> 02:15:39,390
allocate half of those patterns of zeros and ones two negative numbers
2986
02:15:39,390 --> 02:15:41,890
and the other half roughly to positive numbers.
2987
02:15:41,890 --> 02:15:46,260
So in fact, in practice, when you're using even as many as 32 bits,
2988
02:15:46,260 --> 02:15:49,740
the highest most computers could count, certainly in a program like this in C
2989
02:15:49,740 --> 02:15:52,500
using an int, would be roughly 2 billion.
2990
02:15:52,500 --> 02:15:57,180
That is 2,147,483,647.
2991
02:15:57,180 --> 02:15:59,880
But the flip side of that is that we could also now,
2992
02:15:59,880 --> 02:16:03,420
using different patterns of bits, represent negative numbers as low
2993
02:16:03,420 --> 02:16:06,630
as negative 2 billion, give or take.
2994
02:16:06,630 --> 02:16:09,240
But the implication then, of course, is that if we only
2995
02:16:09,240 --> 02:16:13,530
have a finite number of bits and can only count so high, at some point,
2996
02:16:13,530 --> 02:16:16,360
we're going to run out of bits, so to speak.
2997
02:16:16,360 --> 02:16:20,280
In other words, we encounter what's generally known as integer overflow
2998
02:16:20,280 --> 02:16:23,080
where you want to use more bits than you have available.
2999
02:16:23,080 --> 02:16:26,767
And as a result, you overflow the available space.
3000
02:16:26,767 --> 02:16:28,600
What does this mean, in fact, in real terms?
3001
02:16:28,600 --> 02:16:30,683
Well, let's suppose that you only have three bits,
3002
02:16:30,683 --> 02:16:32,910
but I'm going to gray out a fourth bit just
3003
02:16:32,910 --> 02:16:37,080
to convey where we'd like to put an additional bit ultimately.
3004
02:16:37,080 --> 02:16:40,230
If this of course, is 0, per week 0's discussion,
3005
02:16:40,230 --> 02:16:45,360
this is 1, 2, 3, 4, 5, 6, 7.
3006
02:16:45,360 --> 02:16:50,100
Now, ideally, in binary, if you want to add one more to this value 7,
3007
02:16:50,100 --> 02:16:53,070
you're going to have to carry the 1 mathematically,
3008
02:16:53,070 --> 02:16:56,250
and that would ideally give 1000.
3009
02:16:56,250 --> 02:17:00,420
But if you don't have four bits and your computer is only sophisticated enough
3010
02:17:00,420 --> 02:17:03,270
to have three bits, not even 32, but three,
3011
02:17:03,270 --> 02:17:07,799
the implication is that you're effectively representing not 1000,
3012
02:17:07,799 --> 02:17:10,620
but rather, 000.
3013
02:17:10,620 --> 02:17:13,770
There's just no room to store that fourth bit
3014
02:17:13,770 --> 02:17:17,850
that I've grayed out here, which is to say that your integer might overflow.
3015
02:17:17,850 --> 02:17:21,540
And as soon as you get to 7, the next number once you add 1
3016
02:17:21,540 --> 02:17:24,299
is actually going to be 0, or worse, as we've seen here
3017
02:17:24,299 --> 02:17:27,129
in my code, a negative value instead.
3018
02:17:27,129 --> 02:17:30,209
So what could we do to perhaps address this kind of concern?
3019
02:17:30,209 --> 02:17:32,490
Well, C does not have just integers or ints.
3020
02:17:32,490 --> 02:17:34,559
It also has longs, which, as the name suggests,
3021
02:17:34,559 --> 02:17:38,469
are just longer integers, which means they have more bits available to them.
3022
02:17:38,469 --> 02:17:40,080
So let me go back into my code here.
3023
02:17:40,080 --> 02:17:41,430
I'll clear the terminal window.
3024
02:17:41,430 --> 02:17:43,590
And let me go ahead and change my integers to
3025
02:17:43,590 --> 02:17:47,010
literally long here, long here.
3026
02:17:47,010 --> 02:17:51,600
I'm going to have to change my function in CS50's library
3027
02:17:51,600 --> 02:17:53,228
to be not get_int, but get_long.
3028
02:17:53,228 --> 02:17:55,770
And that's indeed another function we provide in the library.
3029
02:17:55,770 --> 02:17:57,809
Let me change this get_int to get_long as well.
3030
02:17:57,809 --> 02:18:01,480
I'll keep my variable names the same, but I do need to make one other change.
3031
02:18:01,480 --> 02:18:05,190
It turns out that printf also supports other format codes--
3032
02:18:05,190 --> 02:18:09,629
so not just %i for integers or %s for strings, but also, for instance,
3033
02:18:09,629 --> 02:18:15,780
%li for a long integer, as well as %f for floating-point values with
3034
02:18:15,780 --> 02:18:16,379
decimals.
3035
02:18:16,379 --> 02:18:20,280
So with that said, let's go ahead and change my printf line to be not %i,
3036
02:18:20,280 --> 02:18:21,690
but %li.
3037
02:18:21,690 --> 02:18:26,219
Now let me go ahead and do make calculator again, Enter--
3038
02:18:26,219 --> 02:18:29,160
no apparent errors now-- ./calculator.
3039
02:18:29,160 --> 02:18:31,740
And 2 plus 2 still equals 4 as before.
3040
02:18:31,740 --> 02:18:36,910
But now if I do calculator again, and let's do 2 billion
3041
02:18:36,910 --> 02:18:41,170
again as well as 2 billion for y, previously, we
3042
02:18:41,170 --> 02:18:44,629
overflowed the size of an integer and got some weird negative number
3043
02:18:44,629 --> 02:18:47,830
because the pattern was misinterpreted, if you will, as a negative number
3044
02:18:47,830 --> 02:18:48,340
instead.
3045
02:18:48,340 --> 02:18:51,340
But a long, instead of using 32 bits, conventionally
3046
02:18:51,340 --> 02:18:55,240
uses 64 bits, which means we have more than enough spare bits
3047
02:18:55,240 --> 02:18:57,850
to go when we add 2 billion plus 2 billion.
3048
02:18:57,850 --> 02:19:01,190
And now, in fact, we get the correct answer of 4 billion,
3049
02:19:01,190 --> 02:19:04,840
which does fit inside of the size of a long.
3050
02:19:04,840 --> 02:19:07,459
Now, a long can count up quite high.
3051
02:19:07,459 --> 02:19:12,340
And, in fact, it can count as high as this, 9 quintillion.
3052
02:19:12,340 --> 02:19:14,889
And so that will give us quite a bit more runway.
3053
02:19:14,889 --> 02:19:17,837
But, of course, it too is ultimately going to be finite.
3054
02:19:17,837 --> 02:19:20,170
So if you have numbers that need to go bigger than that,
3055
02:19:20,170 --> 02:19:22,930
you might still very well have a problem.
3056
02:19:22,930 --> 02:19:25,430
Now, there's another problem that we might run into as well.
3057
02:19:25,430 --> 02:19:28,660
And we can see it in the context of even this simple calculator.
3058
02:19:28,660 --> 02:19:32,520
Computers also suffer from potentially what's called truncation,
3059
02:19:32,520 --> 02:19:35,770
where especially when you're doing math involving floating-point values-- that
3060
02:19:35,770 --> 02:19:40,420
is numbers with decimals-- you might accidentally unknowingly truncate
3061
02:19:40,420 --> 02:19:43,610
the value-- that is lose everything after the decimal point.
3062
02:19:43,610 --> 02:19:45,549
So in fact, let me go back to VS Code here.
3063
02:19:45,549 --> 02:19:46,900
I'll clear my terminal window.
3064
02:19:46,900 --> 02:19:49,630
And let's still use longs, but let's go ahead and use
3065
02:19:49,630 --> 02:19:52,520
division instead of addition here.
3066
02:19:52,520 --> 02:19:55,090
So let me change this plus to a divide operator.
3067
02:19:55,090 --> 02:19:59,020
Let me go ahead and recompile the code down here with make calculator.
3068
02:19:59,020 --> 02:20:02,620
Let me go ahead and run ./calculator, and let me go ahead and do something
3069
02:20:02,620 --> 02:20:06,370
like 1 for x and 3 for y.
3070
02:20:06,370 --> 02:20:07,547
And we'll see that--
3071
02:20:07,547 --> 02:20:08,380
well, wait a minute.
3072
02:20:08,380 --> 02:20:11,500
1 divided by 3, I learned, should be 1/3.
3073
02:20:11,500 --> 02:20:18,348
But in a floating-point value, that should 0.33333, maybe
3074
02:20:18,348 --> 02:20:20,140
with a little line over it in grade school,
3075
02:20:20,140 --> 02:20:21,890
but, really, an infinite number of threes.
3076
02:20:21,890 --> 02:20:26,140
And yet, we seem to have lost even one of those threes after the decimal point
3077
02:20:26,140 --> 02:20:30,040
because the answer is coming back here as just 0.
3078
02:20:30,040 --> 02:20:31,700
So why might that be?
3079
02:20:31,700 --> 02:20:35,740
Well, if I know that two integers, when divided one by the other,
3080
02:20:35,740 --> 02:20:38,920
is supposed to give me a fraction, a floating-point value
3081
02:20:38,920 --> 02:20:42,640
with a decimal point, I can't continue to use integers or even,
3082
02:20:42,640 --> 02:20:46,370
in this case, longs, which do not have support for decimal points.
3083
02:20:46,370 --> 02:20:51,040
So let me go ahead and change this format code here from %li to %f,
3084
02:20:51,040 --> 02:20:55,090
which is, again, going to represent a floating-point value instead of a long
3085
02:20:55,090 --> 02:20:56,560
integer or even an integer.
3086
02:20:56,560 --> 02:21:03,400
And let me go ahead further and define maybe a third variable, z, as a float
3087
02:21:03,400 --> 02:21:04,100
itself.
3088
02:21:04,100 --> 02:21:07,300
So I'll give myself a variable z equals x divided by y.
3089
02:21:07,300 --> 02:21:10,720
And now rather than print x divided by y, let's just go ahead and print z.
3090
02:21:10,720 --> 02:21:13,060
So now I'm operating in a world of floating-point values
3091
02:21:13,060 --> 02:21:17,230
because I proactively that a long or an int divided
3092
02:21:17,230 --> 02:21:20,260
by another such value, if it's meant to have a fraction,
3093
02:21:20,260 --> 02:21:24,710
needs to be stored in a floating-point value, something with a decimal point.
3094
02:21:24,710 --> 02:21:27,730
Well, let me go down to my terminal window here and rerun make
3095
02:21:27,730 --> 02:21:31,120
of calculator-- seems to work OK-- ./calculator,
3096
02:21:31,120 --> 02:21:34,180
and let's do 1 divided by 3 again.
3097
02:21:34,180 --> 02:21:36,868
And still here, we see all zeros.
3098
02:21:36,868 --> 02:21:39,910
So we do at least see a decimal point, so we've made some progress Thanks
3099
02:21:39,910 --> 02:21:41,350
to the %f and the float.
3100
02:21:41,350 --> 02:21:46,570
But it seems that we've already truncated the value 1 divided by 3.
3101
02:21:46,570 --> 02:21:48,520
So how do we actually get around this issue?
3102
02:21:48,520 --> 02:21:50,050
Well, if you the programmer know that you're
3103
02:21:50,050 --> 02:21:52,467
dealing in a world that's going to give you floating point
3104
02:21:52,467 --> 02:21:54,760
values with decimal points, you might very well
3105
02:21:54,760 --> 02:21:57,340
need to use what's called a feature known
3106
02:21:57,340 --> 02:22:02,050
as typecasting-- that is convert one data type to another by explicitly
3107
02:22:02,050 --> 02:22:04,390
telling the compiler that you want to do so.
3108
02:22:04,390 --> 02:22:05,480
Now, how do I do this?
3109
02:22:05,480 --> 02:22:07,100
Well, let's go back to my code here.
3110
02:22:07,100 --> 02:22:11,260
And if the issue fundamentally is that C is still
3111
02:22:11,260 --> 02:22:14,920
treating x and y as integers-- or technically,
3112
02:22:14,920 --> 02:22:18,310
longs with no decimal point-- and dividing one by the other,
3113
02:22:18,310 --> 02:22:22,330
therefore has no room, so to speak, for any numbers after a decimal point,
3114
02:22:22,330 --> 02:22:24,830
why don't I proactively do this?
3115
02:22:24,830 --> 02:22:28,030
Let me, using a slightly new syntax with parentheses,
3116
02:22:28,030 --> 02:22:33,910
specify that I want to convert x proactively from a long to a float.
3117
02:22:33,910 --> 02:22:39,100
Let me specify proactively that I want to convert y from a long to a float
3118
02:22:39,100 --> 02:22:39,950
as well.
3119
02:22:39,950 --> 02:22:42,910
And now let me go ahead and trust that nz
3120
02:22:42,910 --> 02:22:46,870
should be the result of dividing not a long by a long or an int by an int,
3121
02:22:46,870 --> 02:22:49,330
but rather, a float by a float.
3122
02:22:49,330 --> 02:22:52,630
Let me clear my terminal window, run make calculator again--
3123
02:22:52,630 --> 02:22:55,300
seems to work OK-- ./calculator.
3124
02:22:55,300 --> 02:23:00,760
And now 1, 3, and hopefully now we actually see
3125
02:23:00,760 --> 02:23:05,380
that my code has outputted 0.333333.
3126
02:23:05,380 --> 02:23:08,380
And I think if we kept showing more numbers after the decimal point,
3127
02:23:08,380 --> 02:23:11,710
we'd theoretically see as many of those threes as we want.
3128
02:23:11,710 --> 02:23:13,900
But there is still one more catch.
3129
02:23:13,900 --> 02:23:16,240
And especially when we're manipulating numbers
3130
02:23:16,240 --> 02:23:19,090
in this way in a computer using a finite amount of memory,
3131
02:23:19,090 --> 02:23:22,180
another challenge we might run up against-- besides integer
3132
02:23:22,180 --> 02:23:27,100
overflow, besides truncation-- is this known as floating-point imprecision.
3133
02:23:27,100 --> 02:23:31,480
Just as we can't represent as big of an integer as we want using int
3134
02:23:31,480 --> 02:23:34,060
or long alone because there is going to be an upper bound,
3135
02:23:34,060 --> 02:23:39,220
there's similarly going to be a bound on just how precise our numbers can be.
3136
02:23:39,220 --> 02:23:41,560
And indeed, let's go back to VS Code here.
3137
02:23:41,560 --> 02:23:43,430
I'll clear my terminal window yet again.
3138
02:23:43,430 --> 02:23:46,900
And this time, let me use some slightly unlikely syntax to specify that I
3139
02:23:46,900 --> 02:23:49,970
don't want to see the default number of numbers after the decimal point,
3140
02:23:49,970 --> 02:23:52,250
which %f gives us automatically.
3141
02:23:52,250 --> 02:23:57,520
Let's go ahead and show me 20 decimal point numbers after the decimal point.
3142
02:23:57,520 --> 02:24:00,700
And the weird syntax for this is to do not %f,
3143
02:24:00,700 --> 02:24:05,950
but %.20 to indicate to see that I want to see 20 digits,
3144
02:24:05,950 --> 02:24:08,440
not the default after, now, the decimal point.
3145
02:24:08,440 --> 02:24:10,390
Let me rerun make calculator.
3146
02:24:10,390 --> 02:24:12,550
Let me do ./calculator again.
3147
02:24:12,550 --> 02:24:14,890
And let's do 1, let's do 3.
3148
02:24:14,890 --> 02:24:17,560
And now this is even weirder, right?
3149
02:24:17,560 --> 02:24:20,590
From grade school, you presumably learned that 1 divided by 3
3150
02:24:20,590 --> 02:24:21,580
is, of course, 1/3.
3151
02:24:21,580 --> 02:24:26,890
But that should be 0.33333, infinitely many times, or, on paper,
3152
02:24:26,890 --> 02:24:28,180
with a little line over it.
3153
02:24:28,180 --> 02:24:31,660
But the computer is doing some weird approximation here.
3154
02:24:31,660 --> 02:24:37,480
It's a whole bunch of 3's and then 4326744079590.
3155
02:24:37,480 --> 02:24:39,380
Well, what's really happening under the hood,
3156
02:24:39,380 --> 02:24:42,100
well, again, is this issue of floating-point imprecision.
3157
02:24:42,100 --> 02:24:45,220
If you only have a finite number of bits and, in turn,
3158
02:24:45,220 --> 02:24:48,100
a finite amount of memory, the computer can really only
3159
02:24:48,100 --> 02:24:52,300
be so precise intuitively.
3160
02:24:52,300 --> 02:24:55,000
Equivalently, the computer is decided on some way
3161
02:24:55,000 --> 02:24:57,190
of representing floating-point values.
3162
02:24:57,190 --> 02:24:59,470
But the catch is, per grade school math, there's
3163
02:24:59,470 --> 02:25:02,800
an infinite number of numbers out there and an infinite number
3164
02:25:02,800 --> 02:25:06,460
of floating-point values because you can keep adding more and more digits if you
3165
02:25:06,460 --> 02:25:07,040
want.
3166
02:25:07,040 --> 02:25:10,120
So the computer, given the way it's implementing these floating point
3167
02:25:10,120 --> 02:25:14,500
values, is essentially giving us the closest approximation that it can.
3168
02:25:14,500 --> 02:25:17,740
Now, how can we go about improving the situation?
3169
02:25:17,740 --> 02:25:19,180
Well, there is one alternative.
3170
02:25:19,180 --> 02:25:21,115
Instead of using float, I can use something
3171
02:25:21,115 --> 02:25:22,990
called a double, which, as the name suggests,
3172
02:25:22,990 --> 02:25:24,760
uses twice as many bits as a float.
3173
02:25:24,760 --> 02:25:27,820
So instead of 32 typically, it will use 64.
3174
02:25:27,820 --> 02:25:30,570
And that's just like the difference between a long and an int,
3175
02:25:30,570 --> 02:25:31,570
which gave us more bits.
3176
02:25:31,570 --> 02:25:34,480
But in this case, this will be used for more precision.
3177
02:25:34,480 --> 02:25:36,850
Let's go ahead and cast x to a double.
3178
02:25:36,850 --> 02:25:38,740
Let's cast y to a double.
3179
02:25:38,740 --> 02:25:41,530
And now let's go ahead and, using the same format code--
3180
02:25:41,530 --> 02:25:45,220
%.20f is still OK for doubles.
3181
02:25:45,220 --> 02:25:46,990
Let me do make calculator.
3182
02:25:46,990 --> 02:25:48,970
Let me do ./calculator.
3183
02:25:48,970 --> 02:25:51,460
And now let me do 1 divided by 3.
3184
02:25:51,460 --> 02:25:53,770
And we still have some of that imprecision.
3185
02:25:53,770 --> 02:25:56,590
And it's even more of it if we looked at more than just 20 digits.
3186
02:25:56,590 --> 02:25:59,900
But now we have more threes after the decimal point.
3187
02:25:59,900 --> 02:26:03,640
So it's at least more, and more, and more precise, but it's not perfect.
3188
02:26:03,640 --> 02:26:06,520
But it's at least more precise.
3189
02:26:06,520 --> 02:26:08,500
So these kinds of issues, then, are going
3190
02:26:08,500 --> 02:26:10,360
to be necessary to keep in mind any time you
3191
02:26:10,360 --> 02:26:12,640
do something numerically, scientifically, at least
3192
02:26:12,640 --> 02:26:14,980
with a language C where you're going to bump up
3193
02:26:14,980 --> 02:26:18,910
against these real-world limitations of hardware and, in turn, language.
3194
02:26:18,910 --> 02:26:21,952
Now, later in the semester, we'll transition to a language called Python.
3195
02:26:21,952 --> 02:26:24,660
And that's actually going to solve at least one of these problems
3196
02:26:24,660 --> 02:26:26,950
for us by just automatically giving us more bits,
3197
02:26:26,950 --> 02:26:29,470
so to speak, as we need them, at least for integers.
3198
02:26:29,470 --> 02:26:33,140
But even the issue of floating-point imprecision is going to remain.
3199
02:26:33,140 --> 02:26:35,170
Now, just how real-world are these issues?
3200
02:26:35,170 --> 02:26:37,780
Well, back in the year 1999, we got a taste
3201
02:26:37,780 --> 02:26:40,840
of this when the world realized in the years leading up to that date
3202
02:26:40,840 --> 02:26:45,010
that it might not have been the best idea to implement computers
3203
02:26:45,010 --> 02:26:48,910
and software therein by storing gears using just two digits.
3204
02:26:48,910 --> 02:26:53,440
Like, instead of storing 1999 to represent the year 1999,
3205
02:26:53,440 --> 02:26:56,470
a lot of computers, for reasons of space and cost,
3206
02:26:56,470 --> 02:26:59,200
were in the habit of cutting a corner and just using
3207
02:26:59,200 --> 02:27:01,400
two digits to keep track of the year.
3208
02:27:01,400 --> 02:27:06,850
The problem with that is that if systems were not updated by the year 1999
3209
02:27:06,850 --> 02:27:11,560
to support the year 2000, 2001, and so forth, is that, just like before
3210
02:27:11,560 --> 02:27:14,290
with integer overflow, some computers might
3211
02:27:14,290 --> 02:27:16,990
add 1 to the year in their memory, '99.
3212
02:27:16,990 --> 02:27:19,540
It should be the year 2000, but if they're only
3213
02:27:19,540 --> 02:27:22,090
using two digits to represent years, they
3214
02:27:22,090 --> 02:27:25,330
might mistake the year-- as some systems may very well have--
3215
02:27:25,330 --> 02:27:28,390
for the year 1900 instead, taking literally
3216
02:27:28,390 --> 02:27:30,740
a big step backwards, if you will.
3217
02:27:30,740 --> 02:27:32,622
Now, you'd like to think that kind of issue
3218
02:27:32,622 --> 02:27:34,330
is behind us, especially as we understand
3219
02:27:34,330 --> 02:27:37,240
all the more about the limitations of code and computing.
3220
02:27:37,240 --> 02:27:40,390
But we're actually going to run up against this very same type of issue
3221
02:27:40,390 --> 02:27:42,160
again in just a few years.
3222
02:27:42,160 --> 02:27:48,850
On January 19 in the year 2038, we will have run out of bits in most computers
3223
02:27:48,850 --> 02:27:50,800
right now to keep track of time.
3224
02:27:50,800 --> 02:27:55,330
It turns out, years ago, humans decided to use a 32-bit integer
3225
02:27:55,330 --> 02:27:58,870
to keep track of how many seconds had elapsed over time.
3226
02:27:58,870 --> 02:28:01,090
They chose a somewhat arbitrary date in the past--
3227
02:28:01,090 --> 02:28:03,350
January 1, 1970--
3228
02:28:03,350 --> 02:28:06,860
And they just started counting seconds from there on out.
3229
02:28:06,860 --> 02:28:09,100
And so if a computer stores some number of seconds,
3230
02:28:09,100 --> 02:28:11,350
that tells the computer how many seconds have
3231
02:28:11,350 --> 02:28:14,710
passed since that particular date, January 1, 1970.
3232
02:28:14,710 --> 02:28:17,380
Unfortunately, using a 32-bit integer, as we've
3233
02:28:17,380 --> 02:28:20,480
seen, you can only count so high, at which point,
3234
02:28:20,480 --> 02:28:23,470
you overflow the size of that variable.
3235
02:28:23,470 --> 02:28:27,250
And so potentially, if we don't get ahead of this as humans, as a society,
3236
02:28:27,250 --> 02:28:32,080
as computer scientists, on the date January 19, 2038,
3237
02:28:32,080 --> 02:28:36,910
that bit might flip over, thereby overflowing the size of those integers,
3238
02:28:36,910 --> 02:28:42,460
bringing us back computationally to December 13, 1901.
3239
02:28:42,460 --> 02:28:45,970
So this is to say now, with all of this computational ability and code
3240
02:28:45,970 --> 02:28:48,560
comes a responsibility to actually write correct code.
3241
02:28:48,560 --> 02:28:50,560
Next week, we'll peel back some of these layers.
3242
02:28:50,560 --> 02:28:54,550
But for now, this was week 1, and best of luck on problem set 1.
3243
02:28:54,550 --> 02:28:57,850
[APPLAUSE]
3244
02:28:57,850 --> 02:29:01,500
[MUSIC PLAYING]
3245
02:29:01,500 --> 02:29:33,000
271453
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.