>> [MUSIC PLAYING]
>> DAVID MALAN: All right.
Welcome back.
This is CS50, and this is Week One, Continued.
So one of the reasons we've been passing around technologies like
Google Glass is that they come with something known as an API, an
Application Programming Interface.
And what this means is that with the right files and with the right
documentation, you can actually write software for even devices like these.
>> And so what we have in mind toward semesters end is, if a project
involving, say, Google Glass might appeal, we'll see what we can do in
terms of hooking you up with some loaner hardware as well as the
publicly-accessible API so that you can actually start creating software
that runs on that same Google Glass.
>> Another device that we've been playing with of late that we thought might be
fun at semester's end is this little thing here.
It's called Leap Motion, and what you're about to see is technically an
advertisement for the device, but it does speak to what this particular
device is capable of.
And it, too, comes with an API via which you can write software to
control your own computer in a manner quite like this one-minute film here.
>> [VIDEO PLAYBACK]
>> [END VIDEO PLAYBACK]
>> So right now, this device happens to be implemented as a little USB
connector that you can plug into your computer, but I wouldn't be surprised
if before long we have these kinds of technologies in the next batch of PCs
and Macs so that you can, indeed, interact with it in
a manner like that.
In fact, what I thought I'd do, too, is I pulled up a little demonstration
program that comes with this software.
So I've put the little sensor in front of my laptop.
>> And as you can see, it already realizes that my hand is there
controlling it.
And all this application does is swimmingly little things like this.
But you can see that, indeed, I have five fingers there.
If we can get it to do all 10, you can imagine a neat piano
application or the like.
So if you'd like to come up after class today and play with that as
well, you are welcome to.
So more on that toward semester's end.
>> So a couple of administrative announcements.
One, do section by this Friday at noon at cs60.net/section.
That URL is on the course's homepage as well.
In the meantime, though, supersections will debut this Sunday.
Supersections are a one-time thing, because it takes us some time to work
out who's in which section and where.
>> So this coming Sunday, there'll be one section for those less comfortable,
one section for those more comfortable.
And those of you somewhere in between are welcome to go to
either or both or neither.
Both of these will be filmed.
They'll be in a larger auditorium than a section normally would be in.
But the goal here is to equip you with some comfort with problem set one,
with C, with the CS50 appliance, this weekend, even before you find out your
formal section assignment.
So you'll meet your TF and your smaller group of sectionmates in about
a week's time.
>> Office hours, meanwhile, have been going on.
Do take advantage of them tonight or tomorrow night if you would like.
Problem set 0 is due on Friday.
This is a day later than the regularly-scheduled Thursday.
But with problem set 1, you'll see that it includes some warm-up
exercises with which you yourself can extend your
Thursday deadline to Friday.
Problem set 1, meanwhile, will debut on the course's website this coming
Friday, if you'd like to curl up with it as I did once upon a time late
Friday night in your room.
>> So cs50.net/appliance is the place where you can get the CS50 appliance
that we started using on Monday.
We'll use it a bit more today.
But rest assured that the problem set 1 specification will walk you through
precisely the steps you need to get that up and running.
So don't worry about doing that before Pset 1 if you'd rather not.
>> All right.
So we looked on Monday at source code, but in the context of a new
programming language, namely C. And C, unlike Scratch, is not graphical.
It's not puzzle pieces.
It's more English-like syntax.
And there's a couple of steps involved in actually writing and running a
program in C, because besides source code like this, you need something
called a compiler.
And in layman's terms, what does a compiler do for us?
Yeah.
>> STUDENT: It converts the code that you write to 0s and 1s.
>> DAVID MALAN: Good.
So it converts the code that we write to 0s and 1s.
It converts so-called source code to object code, the latter of which looks
a little something like this.
And it's your CPU, the brains inside of your computer, that because of the
people who created those computers, know what those sequences
of 0s and 1s mean.
>> Maybe it means print.
Maybe it means addition.
Maybe it means subtraction.
Maybe it means display a graphic.
There are predefined patterns of bits that the world has decided mean
certain things.
But for the most part in this course, we'll work at a higher level, and
we'll take for granted that there exist things like compilers that can
make our source code function in the way we intend.
>> So the program we wrote first last week and then began to port, so to
speak, to C this past Monday, was this.
When green flag clicked, say hello.
This was, of course, written in Scratch.
And I claimed that the equivalent program in C looked a little
something like this.
>> So what I thought we'd do at first is, let's tease apart what looks, at first
glance, admittedly, as fairly arcane syntax, but you'll start to notice
patterns quite quickly.
What we'll also do today is provide you with a mental model for some
canonical, some standard constructs in programming.
And then we'll actually get our hands dirty with some examples as well.
>> So for those of you more comfortable, realize that this week and then next
week may very well be a bit of review.
But especially when the hacker edition of problem set 1 goes out on the
course's website on Friday, I do think you'll find that even as you fill in
some blanks over the next week or two, you'll begin to get ever more
challenged and encounter new and newer things.
>> So let's tease this program apart a few lines at a time.
At the very top, we have what's technically called a
preprocessor directive.
This is just a line of code that says to include the contents of a file,
called standard I/N, standard input-- or, sorry, standard I/O, standard
input/output, .h, inside of my own program.
>> So in other words, if I wrote this program with a simple text editor like
gedit, the simpler equivalent of something like Microsoft Word, that
instruction, #include stdio.h, is just going to tell the compiler, grab the
contents of that other file, stdio.h, and paste them right here.
>> Now, why do I care?
What did we claim is inside of this file called stdio.h, which is stored
somewhere on my hard drive, or in this case, somewhere in the CS50 appliance?
Someone else put it there for me.
But what's in it?
>> Yeah, so it's a declaration of a function called printf.
So printf recalls the function that displays words and characters and
numbers on the screen at my bidding.
But I didn't write it.
CS50 didn't write it.
Someone years ago wrote it, and they essentially gave us the recipe for it
in a file called stdio.h.
So that first line just gives me access to functions that someone else
wrote years ago, among which are printf.
>> Now, the next line I'm going to wave my hand at, at least until next week.
But for now, know that int main(void) is essentially the equivalent of this
yellow puzzle piece when green flag clicked.
The world, years ago, decided that if you're writing a program in the
language called C, you start your program with a line
that looks like that.
In just about a week's time, it'll make sense what int is, what void is.
But for now, just think of it as this yellow puzzle piece.
>> Now next, we have a curly brace followed by another close curly brace,
so to speak.
And we'll see these throughout programs in C, as well as
JavaScript and PHP.
And these just encapsulate related lines of code.
The open curly brace essentially says, here comes some code.
And the closed curly brace, which is angled in the other direction, just
means, that's it for the relevant code.
>> So the juicy line in this first program is the last, printf,
quote-unquote, hello world.
And I called the thing between quotes what last time?
So it's a string.
And a string is just the techie term for a sequence of
characters, a word, a phrase.
Even a single letter could be double quoted.
But it's a sequence of zero or more characters.
>> Backslash-n, though, looks a bit strange.
But it simply meant something simple to the computer.
What's backslash-n?
New line.
So that's just the special sequence of characters that the world has decided
means put a line break right there, because the compiler will actually get
confused, usually, if you, very understandably, but incorrectly, just
start hitting Enter to put new lines in your code.
You need to be a little more explicit with backslash-n.
>> And we'll see there's a few other such patterns for special characters.
For instance, if you wanted to let your mind wander to a corner case,
suppose that I wanted to print a double quote on the screen for
whatever reason, that would seem to be a little problematic, right?
Because if I put a double quote in the middle of "hello, world," for whatever
reason, why does that seem potentially problematic?
It breaks the string.
>> The compiler is just a program.
A program like a compiler is just going to read your code top to bottom,
left to right.
And if sees three double quotes instead of two, it's not going to know
if you mean that the thing to the left should be the string, or the thing to
the right, or the whole thing.
It's ambiguous, and so what a typical compiler would do is just freak out,
and give you some error message, and make you deal with the problem.
>> So given that backslash-n means a new line, what would your instincts now
start to be if you wanted to include something anomalous like a double
quote inside of this otherwise-quoted string?
Backslash-double quote.
And so we'll see this kind of pattern too.
>> If you want to do something a little strange, you'll find that the
solutions often follow a pattern, and the backslash
denotes an escape sequence.
And it just means something special that we need to represent in a
different way.
As for how do you represent a backslash, well, we'll
come back to that.
But the answer, too, is actually a bit obvious.
>> So let's now introduce some other programming constructs
that you saw in Scratch.
You've probably taken for granted already if you've already dived into
problem set 0.
But let's now introduce the syntax in C for these otherwise fairly intuitive
ideas, at least some of them.
>> So this notion of a condition or a branch, whereas previously we
represented it with code that looked like this on the left in Scratch--
if x is less than y, then say so--
instead now in C-- let me hone in on the simplest case--
we're simply going to say, if, open parenthesis, something is true-- a
Boolean expression is going to go where I have said condition--
close parenthesis, then do what's inside of those curly braces.
>> So here, too, the curly braces are kind of like Scratch's
U-shaped puzzle pieces.
Do what's inside these curly braces.
In this case, slash slash.
And notice this is a forward slash, not a backslash.
Forward slash, forward slash, for those who've programmed
before, just means--
it's just a comment.
A comment is not a line of code, per se.
It's a line of English that you, the human, have written to yourself to
perhaps remind you to do something, to explain to yourself, to explain to
someone else, what your code is doing.
It's just a descriptive comment.
>> Now, of course, we can have a two-way fork in the road just by doing this, a
three-way fork in the road by doing this, and if you continue this
pattern, you can have four-way, five-way, six-way forks in the road if
you need to handle, indeed, that many conditions.
And then notice the parallelism here--
if (condition), else if (condition), and the only one that's a little
strange is the last, which is just that else.
But again, this is identical, conceptually, to what we've done
already, even though the syntax will take a little bit getting used to.
>> Now, in this example, there are some other strange syntax.
We see printf again, open parenthesis, and close parenthesis.
And inside of there is a quoted string.
The parentheses, in the context of printf, go on the left
and right of what?
What do we describe that quoted string as more generally?
>> So it's an argument.
Any time you have a function, like printf, and then an open paren and a
close paren and something inside of it, whether it's a string, or an
integer, or anything else, the thing in between those parentheses is called
an argument.
>> And an argument just influences the function's behavior.
In this case, it's pretty clear how.
x < y is what's being passed in, so to speak, as an argument.
And printf is going to print exactly that.
Because surely, the person years ago who implemented printf had no idea
what we human successors were going to use printf for.
So that's why arguments exist, to influence behavior after a function's
been written.
>> Now, Boolean expression.
We've seen these before in Scratch.
It turns out in C you can also "or" them together, so to speak.
Two vertical bars means that this block of code, this do this, will
execute if the first condition is true or the second condition is true.
And even though you might not have done this in Scratch, you could indeed
do this in Scratch, And you can also express yourself differently--
if the first condition and the second condition are true, then do what's
inside of the curly braces.
>> And just as an aside, the reason it's a double ampersand and a double
vertical bar, we'll see eventually that a single vertical bar and a
single ampersand actually have different meaning in C. So for now,
that duplication of symbols is intentional.
>> So let's introduce, briefly, this other bit of syntax.
This doesn't quite carry over to Scratch, but I claim that I can
implement the notion of an if else, if else, if else, if else statement using
something called a switch statement.
And the only reason this really exists is to just give you, the programmer, a
slightly different way of solving some problem, even though logically it
doesn't give you any new capabilities.
>> By that I mean this.
When you say switch, and then a space, and then a pair of parentheses, inside
of which goes an expression--
and this might be a little non-obvious at first, but this is not an argument,
technically, because switch is not a function.
So for now, just assume that we're using parentheses in different places
for different reasons.
>> So switch on expression means I can put a variable inside of those
parentheses where it says expression.
And then if that variable--
suppose it's called x, and it's just an integer--
I can then enumerate in my slide here something like this.
If x is my variable, and I want to do something if x
equals 1, I can do that.
>> If I instead want to do something if x is 2, I can do that.
Else, if I want to do something else entirely, I can have a default case in
which case I do this other thing.
So in that sense, it's equivalent to an if x equals equals 1, else if else,
but I mention this now just because we'll see it again.
But for now, just know that it exists.
>> All right.
So these last couple are a little more complex at first glance, but they do
something fairly straightforward.
A for loop in C is a chunk of code that just does something again and
again and again.
And the only annoying thing about it is that is that it's a little cryptic
to express yourself in this cyclical pattern, but the world standardized on
the following way.
>> When you use a for loop, you've got a pair of parentheses again.
And notice the two semicolons in there.
Those two semicolons separate three different expressions inside of the
parentheses.
One is the so-called initializations.
One is the so-called condition.
And one is the so-called updates.
>> Looked at in the abstract, this is completely non-obvious, so let's look
at a concrete example.
In Scratch we had a repeat block.
And this block said repeat 10 times, say "hello, world." Let me claim for
now, and we'll come back to this, and this, too, will get more familiar to
you before long, the equivalent C code could be said to be this--
a for statement and a space, a pair of parentheses, notice the semicolons in
there, which separate three distinct things, the initialization, the
condition, and the update.
>> And take a guess what the first is doing.
Int i = 0.
In rough layman's terms, what is that doing for us, probably?
So yeah.
It's declaring a variable called i, and it's giving it what value?
0.
So it's creating a variable called i, storing the value 0 in it.
That's the so-called initialization.
>> All right, now I claimed before that the middle thing, i
< 10, is the condition.
So what is doing?
Well, what the for loop does when a program with a for loop is run, is
every time the computer runs through this loop, top to bottom, top to
bottom, just like you guys did when counting yourselves and sitting down,
again and again and again, the computer is going
to check that condition.
And if i is less than 10, it'll do it again.
If i is less than 10, it'll do it again.
If i is less than ten, it'll do it again.
So that seems to suggest that hopefully i is changing.
Otherwise, we'd have an infinite loop.
And indeed, i is changing, because the last thing after the semicolon there
is the somewhat cryptic syntax of i++.
But those of you who've done this before, that just means
quite simply what?
>> STUDENTS: [INTERPOSING VOICES].
>> DAVID MALAN: Add 1 to i.
Increment i.
So we saw a Scratch puzzle piece for that, actually.
It didn't look like i++, but that just means, quite simply, increment the
value i by 1 every time you do this.
So literally, you start by initializing i to 0.
You then check your condition.
Is 0 less than 10?
Yes.
We go through the loop.
>> The next thing I claim the computer's going to do is it's going
to increment i.
So i is now 1.
It checks the condition.
Is 1 less than 10?
Of course.
So does it again.
Then it increments i++ to 2.
Is 2 less than 10?
Yes.
And again and again and again.
And eventually, because of the plus-plussing, we get to i equals 10.
Is 10 less than 10?
Well, obviously not.
And that's the point at which the for loop just stops.
And if you have more code on the screen down below, the computer
proceeds to run that code instead.
>> So again, even though this is going to look and feel a little strange at
first, certainly for those of you who have never programmed before, it
literally reduces conceptually to what's otherwise a very
straightforward puzzle piece in Scratch.
>> All right, I promised that there'd be other analogs in Scratch.
There's this one too.
And we saw this briefly last time.
But remember the forever block in Scratch?
It just does something forever?
I claimed that you could implement this in this way.
And you can actually implement this in a bunch of different ways.
>> But the while loop is just a different way in C of expressing yourself.
At the end of the day, you can't do anything with a while loop that you
can't with a for loop.
So they're at the end of the day functionally the same.
But it allows you to express yourself a little differently in
the following way.
>> With the while loop, it's what's in parentheses that's checked again and
again and again.
And as soon as that expression is false, then the loop stops executing,
and the computer proceeds to run whatever other code you
have in your file.
>> But what's interesting here is that I literally typed true.
And true is a type of Boolean value, a true or false value.
So could true ever become false if I've literally
hard-coded it into my program?
So no.
It's a little strange that I did this.
But true is true.
There's no plus-plussing.
There's no use of variables in here.
So because I hard-coded while true, this loop is always going to evaluate
again and again and again.
>> So how many times is hello world going to print on the screen?
Forever.
An infinite number of times until the battery dies or some other external
event happens.
So this is probably not the best program to write, because if the user
can never quit your program, it's probably not what you intended.
>> But sometimes, programs should have an infinite loop.
For instance, if your computer has a clock on it, it certainly would be
nice if your clock it does keep updating itself forever, albeit once a
second or once a minute or something like that.
So even infinite loops do have their place.
>> All right.
Lastly, this one.
And this one is a little bit different functionally, and we'll come back to
this probably in Pset 1.
But there's another type of loop called a do while loop.
And the only difference here between a do while loop and, say, a while loop,
is that the condition is checked not before you execute the code, but after
you execute the code.
So at the top for the while loop, whereas the do while
checks it at the bottom.
>> And this just means that the while loop will typically execute more times
or fewer times than a while loop?
Potentially more times, because a do while loop is clearly saying do this,
only after which point you check if the condition inside of the
parentheses is true.
>> So we'll see this again probably in Pset 1.
If you ever want to do something at least once and then maybe some more
times, this is a good construct to use.
But a while loop, by contrast, will check its condition first.
And that's it for loops in C, do while, while, and for loops.
And again, they map pretty nicely back to Scratch, except this one doesn't
quite have the same analog in Scratch.
>> Well, how about, now, variables?
So this is how I declared a variable syntactically the other day.
I had an int, which I claimed is an integer.
I then had a variable called counter, and then a semicolon.
So what is this line of code doing?
This is, quite simply, declaring a variable--
that is, asking the computer, give me some memory, give me some bits-- in
which I can store what?
An int.
And the semicolon just means end of line of code.
>> Now, the second line is probably pretty guessable.
What is counter = 0; doing?
It's assigning 0 to counter.
And so this is the other thing that's a little annoying
versus, say, algebra.
Whereas in algebra, the equal sign means equals, here in C, the equal
sign means assignment.
So it means put what's on the right into what's on the left.
And we'll see another symbol, equals equals, when we want to actually test
for quality, somewhat annoyingly.
>> But this is a little inefficient.
It's kind of annoying that I have to declare a variable and
then give it a value.
So C actually lets us simplify this and just do it all at once.
You can declare the variable on the left.
You can still do the assignment on the right by putting that equal sign in
the middle.
So at the end of the day, these two are equivalent, but this one, frankly,
is probably the better habit to get into just because it's a little less
code, it's a little easier to read, and it just tightens up
your code, so to speak.
>> Any questions thus far on the loops, on variables, on conditions, on
Booleans, either technically or conceptually?
All right.
So now this next one gets a little more interesting.
And this is the example I put up last time that just maps a Scratch example
over to C.
>> So a function.
In layman's terms, what's a function?
Got to be bolder with your answer.
What's a function?
>> STUDENT: Does something.
>> DAVID MALAN: What's that?
>> STUDENT: Does something.
>> DAVID MALAN: Does something.
OK.
We'll start there.
So a function does something.
So it's a piece of code that's essentially implemented elsewhere that
indeed does something.
Now, what's interesting about a function is that it can take input,
and it can produce output.
And let's actually take a look at this.
>> So the man behind the curtain was deliberate a moment ago.
Here we have a table.
But suppose that this actually represents a big box.
So this is a so-called black box.
And in general, in design, in computer science, black boxes just refer to
pieces of functionality that someone has implemented, and you don't
necessarily know or care how it's implemented underneath the hood.
You just care that this black box, which we'll now start calling a
function, does something.
>> So, for instance, if this black box on the stage here represents printf, a
function, I know from previous examples that printf takes one or more
arguments, and the first of those arguments should be a string, like
"hello, world." Well, if I am the person writing the program, and I want
to use printf, I, for instance, might take a piece of blank paper here and a
black marker and write on it--
I misspelled "world"--
H-E-L-L-O.
>> So I'll take my black marker and I'll write, as big and legibly as I can on
this piece of paper, "hello, world," And now I claim this is my argument.
This is a string represented with a piece of white paper.
And my input now to the function printf is going to be this.
So I am calling printf, passing that argument as input to it.
>> And now, I don't know how the person who wrote printf did it years ago, but
I do know from its documentation that its purpose in life is to print what I
provide to it as input.
And so, even though this implementation is unbeknownst to me
underneath the hood, now I see, oh, it is done.
It has printed something on the screen.
And now control of the program, if there were more lines of code, would
have now returned to me.
And so the fact that Colton--
bless his heart, is hiding here under a table in front of all of you--
is deliberate in that I don't know and I don't care how printf is
implemented.
I just know, again, from its documentation, what it does and how I
am supposed to use it.
>> Now, recall that printf could get a little more sophisticated.
Again, we're just talking about the equivalent of Scratch's Say block.
But I also did this last time.
I wanted to make my hello program a little more dynamic and not just hard
code something like "world," and definitely not hard code something
arbitrary like D-A-V-I-D into the program.
I wanted to ask the user for his or her name, and then do something with
that string that they provide.
>> So there's something a little different here. printf, a moment ago,
did, indeed, do something, but it didn't return anything to me.
Right?
Colton did not hand me anything back, no piece of paper.
There was just a side effect.
My providing "hello, world" as an argument to Colton resulted in the
side effect of a word, some words, appearing on the screen.
>> getstring, though, is a little different. getstring is also a
function, but it returns some value.
It doesn't just have an aesthetic side effect.
It actually gives me, the person calling or using the function,
something back.
So in this case, getstring is called with getstring open
paren, close paren.
Does getstring, therefore, take any arguments or input?
No, it seems not.
Its purpose in life is just to get a string.
It needs no more detail than that.
So let me go ahead and pretend that, again, this black box is not printf,
but getstring, and let me, the person writing this program, call or use
getstring by just writing G-E-T-S-T-R-I-N-G, open paren, close
paren, getstring.
>> Now, I have no idea how the CS50 staff implemented getstring, but I know that
if I wait long enough, it will do its thing underneath the hood, maybe using
some variables, maybe using some conditions, maybe using some loops,
maybe using some functions, maybe using--
just trying to stall-- maybe using some other programming features.
But if I wait long enough-- in reality, in the computer, this happens
super fast--
if I wait long enough, this function getstring is going to get a string
from the user, who is presumably typing it out on their keyboard, and
then, when you getstring is done getting those characters from the user
and storing them into a string, that function, getstring, is going to have
ready for me some output which I am going to retrieve by way of the
assignment operator.
>> And if I go, indeed, into the output here, Obosi has generously
participated, without knowing this in advance, by writing his name onto this
variable, which is representing a string.
Now, the assignment operator means, even though this might feel a little
redundant, I actually do need to make my own copy of this.
Because on the left hand side-- whoops!--
notice that I essentially have string name on the left hand side.
So I'm also going to make my own copy of this.
And this is a bit of a white lie, because we'll see in a week or two's
time that strings are not actually what they appear to be.
>> But for now, here is the return value.
Here is my own copy of it after using the assignment operator.
And now, what do I want to do next?
We now have the second of two lines of code.
So I now want to call printf.
Let's pretend now that the black box is back again to being
printf and not getstring.
>> Printf this time is going to take how many arguments?
So look, it's like two.
There's two commas in there, but one of those commas, it's
inside of the quotes.
So the first argument is literally going to be this.
H-E-L-L-O, comma, percent s, backslash-n.
And now I'm providing not one argument, but two arguments to printf.
>> And what's printf supposed to do with these two inputs after I pass them in
as arguments?
It's supposed to take the second of them, which I called name, so the
second piece of paper I wrote out a moment ago is called name.
It's going to plug of the value inside of that variable into the placeholder,
%s, so that, again, in just a moment's time, we will see a side effect of
having called printf, whereby now we see not "hello, world," but "hello,
Obosi."
>> So a big round of applause to both of our volunteers, only one of whom knew
this would be happening.
All right.
So, perhaps, simple as that was, certainly, if you're already familiar
with such, hopefully you will never forget that particular visual of how
functions work.
>> So there's more than just getstring.
Inside of the CS50 library, there's a whole bunch of functions, all of which
are capitalized just to make clear that we wrote these functions.
Typically, in C, almost every other function you'll use is lowercase.
But we deliberately use capital letters just to make clear that these
are training wheels of sorts that we'll use for just a few weeks that
simplify the process of getting input from the user.
>> The CS50 library does not do anything that you yourselves could not do by
just using C code from an oldschool textbook.
But, again, we use them as training wheels of sorts for just a couple of
weeks so that we can get rid of the complexity that you'll soon understand
yourself of doing something as relatively straightforward as getting
input from a user.
>> So know that you'll have access to GetChar, GetDouble--
double.
What's-- and then GetFloat.
What's a float?
Let's start there.
>> STUDENT: [INAUDIBLE].
>> DAVID MALAN: Yeah.
It's a number with a decimal point.
So whereas an int is an integer, which is just a number with 0 through 9,
some number of repetitions thereof, a float is something
with a decimal point.
And a double, meanwhile, is also a number with a decimal point, but more
numbers after the decimal point, potentially.
>> So we'll get back to this before long.
But typically, each of these types of data, each of these types of variables
that a library like ours can return to you, use different numbers of bits to
store information.
Typically, a Char, which just means one character, uses 8 bits.
And that's actually consistent with our byte of volunteers last week who
came up and represented one Ascii character at a time.
So a Char is 8 bits.
>> A float happens to be 32 bits, typically.
And a double, as you might guess, is actually 64 bits, which is just more,
which means you can have bigger numbers or more precision.
But again, more on that another time.
GetLongLong, meanwhile, though stupidly named, is really just a
integer that's twice as big, twice as long, potentially, as a regular
integer, 64 bits instead of 32.
And GetString we've been using.
>> But it turns out, in the CS50 library, which is implemented, as we'll see, in
the form of the two files, one of which is called cs50.h, has two other
data types in it.
Booleans do not exist in C. You can simulate them by just using 0s and 1s
throughout your programs.
But we in the CS50 library have created the symbols "true" and "false"
to represent 1 and 0 so you don't have to hard code something
literally like 1 and 0.
But we'll see those again.
>> String, too, does not exist.
And that's why I mentioned it's a bit of a white lie for now.
But we'll peel back that layer before long.
But for now, a string is a sequence of characters.
>> Meanwhile, in C, you indeed have different data types.
Notice these are lowercase.
So the functions you saw a moment ago are functions written by CS50 that
will return to you a value that falls into one of these categories.
>> A couple cheat sheets just to plant the seed here. printf doesn't just
take %s as placeholders.
It takes %d for decimal integers, or %i would work as well.
%f is floating point values. %c is for a char, if you want to just plug one
character into a preformatted string like we've been doing, you can use %c.
>> And then, somewhat annoyingly, %lld is for a long, long decimal integer,
which just means if you need a really big number and you're using something
called a long long, which we'll come back to in a pset, you can use %lld to
tell printf, plug in a really big integer here by way of its second or
some other argument.
>> And lastly, I promised that there's a few other escape
sequences that printf supports.
We've seen backslash-n.
Backslash-r you may see.
It's sort of an old-school thing.
If you ever used a real typewriter years ago and you pulled on the crank
which not only rotated the wheel to move the lineup, it also moved the
whole thing all the way back over to the left, well, backslash-r just
essentially moves your cursor back to the start of the line
without moving it down.
But again, more on that, perhaps, in the future.
>> Backslash-quote, backslash-double quote, backslash-backslash is the
solution to the tiny little riddle I alluded to earlier.
And backslash-0 is actually quite interesting.
But we'll come back to that before long.
>> So let me go into, now, the CS50 appliance, and let's actually do a
quick warm up with one of the examples we did already and then move on to
something a little more complex.
So if I open up my program called gedit--
this is my graphical editor.
And I can do that--
let me close that window there--
by way of this icon down here, gedit, in the bottom-left
corner next to the menu.
>> I'm going to go ahead and advance, and save this example into, say, John
Harvard's folder.
John Harvard's folder is just his home directory where all of his files live
by default.
And I'm going to save this as a file called hello-0.c.
And I've chosen this name just so it lines up with the sample code on the
course's website and in the YouTube videos online.
>> So now I'm going to begin to write my first program.
Let me zoom in for legibility.
And I'm going to go ahead and say int main void, which is just like that
yellow puzzle piece that starts a program.
I have gotten into the habit over the years of opening my curly brace, then
also closing it and then going back to where I want to put my code, just
because it helps me keep everything balanced, especially as my
program gets long.
>> And now, in here, I'm going to go ahead and say, printf, quote unquote,
hello world, backslash-n, close quote, close parenthesis, semicolon.
So I'm just repeating everything we've been taking for granted thus far.
Now I'm going to zoom out.
>> And this terminal window down here, what am I allowed to do in this black
and white window?
What can I use it for?
So this is where I run commands and where I can compile things.
And I'm going to keep it simple.
I'm going to use a program called Make, which isn't
technically a compiler.
The compiler's called Clang, but we'll come back to that in a
week or two's time.
>> For now, I'm just going to type make hello-0, But those of you who were
comparing in your minds what I just typed to what I should have typed may
know already that I did something wrong here.
Now, there's clearly some errors.
Before I even look at what they are, any thoughts as to what I did wrong?
>> STUDENTS: [INTERPOSING VOICES].
>> DAVID MALAN: Yeah.
I'm missing the library's header file.
Any of these .h files are called header files, and they collectively
belong to things called libraries.
Libraries are just chunks of code that other people wrote.
So the standard [? i ?] library is a collection of files containing code
that other people wrote.
>> So I'm missing that.
So why am I getting an error?
Well, let me scroll back up in my terminal window here.
And unfortunately, in C, as in a lot of programming languages, especially
if it's all new to you, the error messages are precise, but they're also
quite cryptic.
And the error here, in red, is "implicitly declaring library function
printf with type," and then it scrolls to the next line, "int const char * ,
..." It just gets really overwhelming quickly.
>> But what you should begin to do, if, again, new to all of this, is just to
begin to look for keywords.
Clearly, I might not understand half of the words I'm seeing just yet.
You will, though, in a week's time.
But I see printf.
And that should begin, before long, to jog your memory, all right, printf.
Something's wrong with printf.
Did I spell it wrong?
No, it doesn't look like-- oh.
I can't use it unless I teach the compiler that it exists.
And so, again, go with your instincts, even if you don't actually understand
the actual error messages.
>> And indeed, the solution here is to just include it at the top of the file
like that, resaving my file with Control-S or the File menu.
And if I now go back down here, I'm going to clear this.
Control-L is just a nice way to clear the screen.
And then I'm going to type "make hello 0" Enter, and now I still see a
cryptic sequence of symbols, but we'll come back to that.
That's what Make is doing for you.
It's automating the process of taking a fairly annoying command involving
Clang, the actual compiler.
But the fact that I got no errors means that this thing should work.
>> So I'm now going to do-- let me zoom in again--
./hello-0 Enter, and indeed, I see "hello, world." So let's now enhance
this ever so slightly just to replicate the steps we intended.
I'm going to rename this with Save As to hello1.c.
And now I'm going to declare a variable called name, so string name,
and I'm going to put in it the value of quote-unquote
D-A-V-I-D close-quote semicolon.
And now I'm going to replace "world" with what placeholder for a string?
%s.
>> And now, how many arguments should printf take this time?
So two.
So I go outside of the quotes.
I type "name" after a comma.
But I've done something else wrong this time.
But let's assume that I didn't realize that yet.
Let me go up here.
>> And notice, too, I'm getting a little bored of typing "make hello 0" all the
time, "make" and all this.
So, it turns out, in Linus you can often hit the Up arrow on your
keyboard, and you can actually scroll through all of the commands that I've
executed previous to just now.
So if I do that, Up, Up, there's make hello 0.
I don't want that.
I just want to change that to hello 1 this time, Enter.
Eventually, that will save you some time.
>> All right.
Unfortunately, there's is an error.
So let me scroll up.
This looks like I really butchered this program.
I mean, my god, it's two lines of code, and its 10 lines of errors.
But look at the top one first.
Use of undeclared identifier string.
Did I mean standard i n?
No I didn't.
I meant string.
>> But where is the string variable type declared, dd we say?
So it's in the CS50 the library.
So it doesn't suffice, in these first couple of weeks, just to use
what C gives us.
I'm also going to go up here, and I could put it above or below, but I'll
just keep it alphabetical to keep things orderly.
I'm going to include cs50.h, which is pre-installed for
you on the CS50 appliance.
And it's open source, so even people on the internet can use it on their
own computers.
But it comes with the CS50 appliance.
>> So now let me go back and recompile this with make hello 1.
Damn it.
Still another error.
Let me scroll up to the first, though.
This one's a little complex.
Multi-character character constant.
That's not helping me.
But notice, Clang is at least a little bit decent, whereby with a little
green caret symbol, it's saying here is where I screwed up.
Why is it pointing, with that little green arrow, to the single quote next
to my name?
>> So this is one of the things you just get used to, especially if you've been
programming in Python, or JavaScript, or other languages where this detail
doesn't matter.
In C, it does matter.
If you are declaring a string, which is a sequence of 0 or more characters,
you actually must use double quotes.
So I actually need to change this back to open quote, close quote, with
double quotes.
Single quotes do have their place, but only when you're using individual
chars, but more on that another time.
For now, the double quotes are necessary.
>> So now, let me go back to my terminal window, make hello 1.
And who's confident?
Is this program now going to compile correctly?
OK.
So three of us think this.
All right.
Enter.
And it actually did.
So there's no errors this time, even though this program's gotten a bit
more complex.
If I now do dot slash hello 1, Enter, it's going to say "hello, David."
>> But let's do the third iteration of this, where the
program is truly dynamic.
Let me go ahead and change the file name, just for consistency with the
files you'll have available to you afterward online.
Enter.
And now I'm going to go in and not store "David" hard coded here.
What could I do to very simply improve this program?
>> I could call getstring.
It might be a little non-obvious what's about to happen, so I'm going
to actually add another line, printf, and say name, colon, close quote, just
to give the user a prompt on the screen.
And now I'm going to go here, and I'm going to use my keyboard shortcut.
I'm going to go Up, Up, and change hello 1 to hello 2, Enter.
And thankfully, I'm making progress.
>> And now I'm going to go up to dot slash hello and
change that to 2, Enter.
And now my program--
I'll zoom in-- is getting a little prettier.
Name is going to be, let's say Rob this time, Enter, hello, Rob.
We can do it again.
Name, Lauren, Enter.
Name, Joseph, Enter.
Name, let's try to be difficult, Enter.
Eh.
It's not really a bug.
So it's just a little ugly.
So maybe we could solve this in the future, not now.
>> But how would you instinctively go about addressing
that particular challenge?
It just looks stupid.
How do you avoid things looking stupid?
So we could do, OK, I heard a couple of things, a condition and a loop.
We could use, one, a condition, to check what is the length of the string
the user gave us?
And if it's 0, it's just quote unquote, they just hit Enter, then
maybe I should yell at them and prompt them again.
But how do a prompt them again?
Well, I also heard loop, and I could do that again and again and again
prompting the user for the same thing.
>> Well, let's do one other example using a different
function in the CS50 library.
Let me close this file.
Let me create a new one.
And I'll call it adder.c, just because it's easy to do simple arithmetic,
even though this will be completely underwhelming with what you could do
with any modern computer.
>> But let me go ahead now and--
I learned my lesson last time-- include cs50.h, include stdio.h, int
main void, which, for now, I'll just take on blind faith, but we'll assume
that will understand what that means before long.
And I'm going to say something like "give me an int."
>> And now, how do I get an int?
I want to ultimately declare a variable called x of type int and
store in it an integer from the user.
So that was a mouthful.
But if someone wants to propose, how do I declare an integer called x?
Int x.
>> So it really is that simple.
Give me an int.
Call it x.
Now I use the assignment operator.
And how do I store from the left a value of the user?
I don't want to call getstring, obviously, but rather getint.
Any arguments?
No.
So it's open paren, close paren immediately, and then a
semicolon ends the line.
>> Now let me do this again.
Give me another int.
This time I'll do int, let's call it y, equals getint.
And now let me do something super-simple like some math.
So printf, the sum of %d is the placeholder for an int.
And %d, period, backslash-n.
>> All right.
So that's not actually math.
But if I want to say the sum of this value plus this value equals this
other value, how many arguments into total should I be giving printf,
ultimately?
So four, right?
This string and then the three values.
So x is the first I want to be plugged in first to the %d.
y is going to be the next.
>> And now I kind of want to say z, but z doesn't exist.
But that's not a big deal.
Because what would you do instinctively, especially if you had a
graphing calculator, what do you type?
How about x plus y?
So it's not an actual variable.
It's just the sum of two other variables.
And that's perfectly legitimate.
C certainly understands simple arithmetic like this.
>> Semicolon, save.
Now let me go down here and type make adder, Enter.
No error, so that's progress too.
Type adder.
And another keyboard shortcut, if you start to get bored
with all the commands--
if you start typing a command, like dot slash ad, and that's where your
boredom kicks in, you can usually hit Tab to have the computer finish the
rest of the phrase for you if it's not ambiguous what should come after ad.
>> So let me go ahead now and you click Enter.
Give me an int, 1, 2, and thankfully, it's 3.
But as always, testing programs shouldn't reduce to
just trying it once.
Let me try a corner case, like negative 1, give me 1, and that one
checks out as well.
And I probably want to do some more rigorous testing, but I'm pretty
comfortable with where that's at.
>> Well, now let's try another program that this time uses a
bit of other syntax.
Let me create a new file.
I'll call this conditions0.c to line up with some sample code online.
And let me go ahead and do include cs50.h, include
stdio.h, in main void--
OK.
There we go.
We have our standard boilerplate.
>> And this time I'm going to say printf, "I'd like an int, please," just to
make the prompt a little more friendly.
And now I want to get an int from the user.
I'm going to call it n this time, just because n sounds like number.
getint, and now, what do I want to do with it?
Well, if n is-- and I'll zoom in--
if n is greater than 0, I want to do the following--
printf "You picked a positive number." Else, I'm going to type printf "You
picked a negative
number." All right.
So this program, even though I did it fast, looks right syntactically.
Let me try this.
Make condition 0.
Seems to run.
Condition 0, enter.
Let's give it an int of 50.
I picked a positive number.
Let's try it again.
Condition 0.
Negative 50.
I picked a negative number.
>> But now, let me pick what we'll keep calling a corner case, which is more
an interesting case that you think might give you some trouble, 0.
Now, I'm pretty sure this is one of those corner cases where zero is
neither positive nor negative, so my program, though in syntactically
correct-- it compiles, it runs-- is not logically correct.
So what's the simple fix here if I want to detect, if I want to handle n
equals 0 separately?
>> So if n equals 0, then I want to say something like printf "You picked 0."
Let me try this now.
Let me go back here, clear my window, and recompile.
Hm.
One error generate.
But I do you want to check if n equals 0.
>> So again, another stupid thing to get used to, equal sign is
the assignment operator.
So this is actually mistake in that, technically, even though the compiler
protected me from myself, we'd technically be copying 0 into n, which
is not what I want.
I want to test for equality with equals equals.
And so that now might be my better solution.
>> Let me actually resave this as, say, conditions1, to be new and improved.
So now if I recompile this, it would make conditions--
whoops-- make conditions1 dot slash conditions1, Enter, "I'd like an int,
please." I'm going to go ahead and type 50.
It's still good.
Negative 50, still good.
0, and it, indeed, detected that I picked 0.
>> So what more can I now do with this?
Well, we can certainly do increasingly complex things.
But what I'd like to propose is that we end on this note here.
If we pull up this, you'll see, perhaps, a favorite cartoon of yours
up until today you might never have understood.
And that's about the quality of laughter you should get with CS jokes.
So that's about right.
>> But more compellingly, I thought I'd give us a little teaser for Monday.
So we've started using integers.
We've referred to floats.
We've even referred to doubles, which, again, give you numbers
after decimal points.
>> But it turns out that floats and doubles, and, really, computers,
fundamentally, cannot express some values precisely.
We know from math classes that you can have any number of numbers after the
decimal point.
And you can even put a vertical bar to say these go on forever.
>> Unfortunately, you can't really do that in a computer.
And so corner cases arise.
For instance, suppose you're doing something financial.
You're doing mathematics with percentages, and
with dollars and cents.
And those cents don't necessarily line up.
Well, it turns out that fractions of pennies can start to add up when
modeled with a computer system in such a way that clever
humans can take advantage.
>> And those of you who haven't seen, I'd like to give you a 30-second teaser of
a wonderful film known as Office Space, which will paint a picture of a
problem we shall tackle first thing on Monday.
If we could raise the volume a little bit, I give you 30
seconds of Office Space.
>> [VIDEO PLAYBACK]
>> -I mean, you, you haven't been showing up and you get to keep your job.
>> -Actually, I'm being promoted.
>> -I could program a virus that'd rip that place off big time.
>> -Well, how does it work?
>> -Every time there's a bank transaction where interest is computed, and there
are thousands a day, the computer ends up with these fractions of a cent.
>> -But I'm not going to do anything illegal.
>> -Illegal?
Samir, this is America.
>> -We have to swear to God.
>> -If nobody knows about this but us, all right?
No family members, no girlfriends, nobody.
>> -Of course.
>> -Agreed.
>> -Don't worry, man.
I won't tell anyone either.
>> [END VIDEO PLAYBACK]
>> DAVID MALAN: So this, then, is CS50, that was Office Space, and it will all
make sense on Monday.
See you then.
>> NARRATOR: At the next CS50, Rob adjusts to being off the
Harvard meal plan.