All language subtitles for Aula 1

af Afrikaans
ak Akan
sq Albanian
am Amharic
ar Arabic
hy Armenian
az Azerbaijani
eu Basque
be Belarusian
bem Bemba
bn Bengali
bh Bihari
bs Bosnian
br Breton
bg Bulgarian
km Cambodian
ca Catalan
ceb Cebuano
chr Cherokee
ny Chichewa
zh-CN Chinese (Simplified)
zh-TW Chinese (Traditional)
co Corsican
hr Croatian
cs Czech
da Danish
nl Dutch
en English
eo Esperanto
et Estonian
ee Ewe
fo Faroese
tl Filipino
fi Finnish
fr French
fy Frisian
gaa Ga
gl Galician
ka Georgian
de German
el Greek
gn Guarani
gu Gujarati
ht Haitian Creole
ha Hausa
haw Hawaiian
iw Hebrew
hi Hindi
hmn Hmong
hu Hungarian
is Icelandic
ig Igbo
id Indonesian
ia Interlingua
ga Irish
it Italian
ja Japanese
jw Javanese
kn Kannada
kk Kazakh
rw Kinyarwanda
rn Kirundi
kg Kongo
ko Korean
kri Krio (Sierra Leone)
ku Kurdish
ckb Kurdish (SoranĂ®)
ky Kyrgyz
lo Laothian
la Latin
lv Latvian
ln Lingala
lt Lithuanian
loz Lozi
lg Luganda
ach Luo
lb Luxembourgish
mk Macedonian
mg Malagasy
ms Malay
ml Malayalam
mt Maltese
mi Maori
mr Marathi
mfe Mauritian Creole
mo Moldavian
mn Mongolian
my Myanmar (Burmese)
sr-ME Montenegrin
ne Nepali
pcm Nigerian Pidgin
nso Northern Sotho
no Norwegian
nn Norwegian (Nynorsk)
oc Occitan
or Oriya
om Oromo
ps Pashto
fa Persian
pl Polish
pt-BR Portuguese (Brazil)
pt Portuguese (Portugal)
pa Punjabi
qu Quechua
ro Romanian
rm Romansh
nyn Runyakitara
ru Russian
sm Samoan
gd Scots Gaelic
sr Serbian
sh Serbo-Croatian
st Sesotho
tn Setswana
crs Seychellois Creole
sn Shona
sd Sindhi
si Sinhalese
sk Slovak
sl Slovenian
so Somali
es Spanish
es-419 Spanish (Latin American)
su Sundanese
sw Swahili
sv Swedish
tg Tajik
ta Tamil
tt Tatar
te Telugu
th Thai
ti Tigrinya
to Tonga
lua Tshiluba
tum Tumbuka
tr Turkish
tk Turkmen
tw Twi
ug Uighur
uk Ukrainian
ur Urdu
uz Uzbek
vi Vietnamese
cy Welsh
wo Wolof
xh Xhosa
yi Yiddish
yo Yoruba
zu Zulu

Original subtitles

DAVID J. All right.

This is CS50.

This is week one, because, of course, last week was week zero. And this is the

week where we'll actually start programming in a much more traditional

programming language we promised called C.

Of course, we started with this. And hopefully by now, with problem set one,

you've had a little bit of fun, even if you've played with it before. And the

goals of Scratch, beyond sort of making things feel very accessible and user

friendly, is really to elucidate some of the fundamental concepts that we'll see

again today.

And really, every week subsequently, like functions and conditionals and

and variables and so much more. And in fact, among the goals of Scratch is,

again, to kind of plant these visuals in your mind. So even as today onward

feels all the more like a fire hose, especially when it comes to really weird

cryptic textual syntax, the ideas are still going to be the same. So today,

program, Hello World, becomes this instead.

And in fact, just to color code things temporarily,

I dare say that what I've color coded here in orange, which looks probably, to

those of you who've never programmed, pretty cryptic, is the equivalent of the

when green flag clicked orange puzzle piece like this. What remains is just

line in purple with a bit of white, which is what ultimately is going to get

screen today to say hello world on the screen.

And of course, we had a name for something in purple.

In fact, if we rewind to week zero, this block in purple represented what type

of functionality?

A function itself, an action, a verb that gets the computer to do something.

what looked like this last week is about to look like this. Let's take away the

color coding and focus really on what we're going to now start calling source

code. So this is what programmers do.

in the real world. This is what software developers, software engineers do in

the real world. They write code that looks like this. And clearly, it's a

English -like, but it's not English in the way you would compose an essay or an

email. Clearly, there's some patterns and some special syntax to it that we'll

highlight ultimately today.

The problem is, though, that computers, of course, don't understand source code.

They only, per last week, understand zeros and ones. That is it, the so

binary system.

So somehow, we've got to get what already looks cryptic into something

looks at a glance even more cryptic than zeros and ones, the computers do

understand. And for today's purposes, just know that built into your Macs,

and phones, There is a built -in understanding of what these patterns

Maybe it means a number. Maybe it means a letter. But today, maybe it means an

instruction, like print something on the screen, or save something, or load

something. That is to say, computers use patterns of bits not only to represent

all the stuff we talked about last week, numbers, letters, colors, images,

sounds, and all of that. They also use patterns of bits to represent

fundamental functionality, print things, play things, much like those same

scratch blocks.

But no computer scientist really, unless they take out a paper pencil or write a

program or use a website to convert this, can sort of read this and know

going on. That's why we humans are actually going to use not machine code,

is called, the zeros and ones that computers understand.

We are going to start writing source code. And last week, you already wrote

source code, but in the form of dragging and dropping those puzzle pieces.

So this, too, is going to be the paradigm that sort of guides us through

entire semester.

Problem solving programming is really about input.

becoming output.

And we'll focus today then on a certain type of input becoming output.

Someone has to get the source code that's written in a language like C into

machine code, the zeros and ones that the computer actually understands.

So source code today is going to be our input.

Machine code is going to be our output. And we're going to give you today a

special program called a compiler, whose purpose in life is to translate one to

the other. And there's compilers for different languages in the world. We're

going to focus on one that supports today's language, known as C.

And here, as promised, is the programming environment we are going to

tailored to CS50, which is to say we've pre -installed certain software that you

might find useful during the term. But for all intents and purposes, the tool

you will use for CS50's problem set, henceforth, is a very popular industry

standard tool called Visual Studio Code, or VS Code for short.

We are using a cloud -based version of it that lives at literally this URL,

.dev. You can sign into that so long as you have a free GitHub account for which

you signed up, presumably, already. And that will give you access to not only an

industry standard programming environment, but again, an environment

some CS50 -specific things pre -installed.

And at the end of the semester, or even in the middle if you're so inclined, you

can actually download for free VS Code onto your Mac PC.

You can disconnect from the internet, and you can actually program on your own

computer. Caveat, though, is that you tend to hit technical support headaches

the very beginning of the term. So we suggest you do that later in the term

you're already comfortable with this cloud -based environment here.

And here it is. This is what programming shall look like, whether we're using C

now or Python in a few weeks or JavaScript or SQL thereafter.

So here is what is VS Code configured as follows.

At the top right, you'll generally have one or more tabs for code, much like

tabs in a browser. And this is where you'll write code that looks a little

something like this. And in fact, this is exactly the code that you saw a

ago. What VS Code does, among other things, is it actually highlights your

for you. It colorizes it in what's generally

in an illuminating way.

So I did not choose to make this red. I did not choose to make this blue and

this purple. The computer sort of automatically does that for you, as

see, to sort of draw your attention to different ideas in the program itself.

That all happens automatically.

At the bottom here, you're going to use a more advanced interface today onward

known as a command line interface in the form of a terminal window.

So you can still use your mouse or trackpad and click and drag and do

like that in this environment.

Many programmers prefer that it's much more efficient, ultimately, to use your

keyboard more often than the mouse or the trackpad. So we'll introduce you to

that text -based terminal window there.

Up here at top left, you'll have a file explorer.

So what's nice about VS Code is that not only will you have textual commands

with which you'll get comfy, you also have like a normal Mac or PC or phone

nowadays. Like literally files and folders will visually appear to you so

can play with or manipulate them there.

And then lastly, this is sort of like the menu. the so -called activity bar

just has icons for various features, including CS50's duck. So in fact, if

poke around, you'll see ultimately a duck icon when you log in, which is your

own CS50 -specific chat bot of which you can ask questions throughout the

process.

So now that we've got VS Code here, let's go ahead and actually consider

represents. So this is generally, for jargon's sake, a graphical user

which means buttons and icons and menus and all of that. We all take that for

granted on almost any device nowadays.

That's abbreviated, just so you know, as GUI, G -U -I.

But built into VS Code, again, is what not only the terminal window by name,

conceptually, this is a command line interface. So not a graphical user

interface, but a command line interface. interface, whereby there aren't icons

to click on or double click on. Rather, if you want to run a program, you use

the command line interface, or CLI, to type the name of the program that you

want to run.

And so this will feel like a step backwards initially today, because we

of tap and point and double click at things nowadays.

But again, it's going to give us more power, more efficiency, ultimately

this.

So with that said, let's go ahead and actually use it for just a moment.

class, you're welcome to follow along. But suffice it to say, we'll generally

somewhat quickly.

Really, you're going to learn how to program by way of the problem sets each

week. I'll introduce and focus on the concepts, the ideas, the sort of

primitives that will get you started.

But only through actually doing the problem sets is the muscle memory and

practice going to come. So not to worry if it doesn't all sort of go down easily

the first time around.

So here is the code that I claim is equivalent to last week's Hello World

program, let's actually go ahead and do this in the programming environment.

So I'm going to go ahead and switch over to VS Code itself, which is now running

on my Mac here. It's not just a screenshot.

And I'm going to go ahead and do the following to get started with

I'm going to write literally in my terminal window the word code.

And I might have to give it focus by clicking down in that quadrant of the

screen. And then I'm going to give the name of the file that I want to.

And in this case, I'm going to propose that we call it hello .c.

In the world of Scratch, when you downloaded it, you might have noticed

files are all called like SB3 or some such file extension.

When writing code in C, you literally name the file something .c by

But notice some other details, especially if I zoom in.

Everything I've typed thus far is lowercase.

There's no spaces.

And so this is going to be important.

And unfortunately, computers are not forgiving.

And odds are one of the first stupid mistakes you'll do is miscapitalize

something, misspell something, add too many spaces or the like. Not to worry.

time, that kind of muscle memory will come with practice.

So let me zoom out.

Let me now just hit Enter, and you'll see at top right the Code tab that I

promised. So I'm going to go ahead and type out this program pretty quickly,

because I've done it before.

Include standardio .h, int main void, and then some curly braces, as they're

called, and then printf quote unquote hello comma world backslash end close

quote.

All right, so that's a lot, but that too will come in time with practice. But

this is the exact same code that we saw just a moment ago.

Indeed, if I zoom in, it's color coded just as in the screenshot, and thus I

have written my first program.

VS Code will automatically save for you, but you can also hit Control or Command

S to ensure that it's saved. But notice what's happened at top left.

Not only do you see my code over here, you see a visual icon, just like on a

or PC that, yes, this file now exists in your account.

is what you're getting with VS Code for CS50. You're getting your own sort of

server in the cloud.

It's called a container nowadays. So there's some virtual disk space

in the cloud, a la iCloud or Google Drive, that's going to store all of your

files. And at the moment, because I refreshed my account before class, I

have one file in my own account.

What's this? What's this?

Well, this is like my ID number for GitHub.

Not really a big deal. That's just randomly generated by GitHub.

Urban Adventure is the name of my programming environment today, otherwise

as a code space.

This is just a GitHub thing, which is, again, one of these cloud companies.

Instead of choosing random letters and numbers to uniquely identify all of our

programming environments, it's popular in the tech industry nowadays to just

together random English words that sometimes sound kind of cool. But it's

by coincidence, not something I chose. Yours will be different.

All right, so I've written some code.

I created hello .c. I typed in all of that code. I confirmed visually at left

that it was created. I'm going to hide my file explorer, henceforth, just so we

can focus on the code. How do I actually run this program?

Well, on a Mac or PC, we would be in the habit of opening the folder and double

-clicking on it. Or on your phone, you would take it out and tap on an icon.

But not here. Here, we're focusing primarily on the command line interface

within this whole environment.

So I'm actually going to have to introduce a few commands.

You saw already the code command, which for our purposes is VS Code specific,

that just creates a new file called hello .c in this case. But I need two

commands to actually run this program.

The first, nicely, is called make. And then I specify what program I want to

make. And then a little weirdly, I have to type dot slash hello.

But just to take a step back, make hello. If this is about to be my second

command that I type, what does that step represent, perhaps?

given what I said just a minute or so ago.

Perfect. So make represents the compiler, so to speak, the program that

source code to machine code. I have to do that for now manually by running make

hello. Now, make is kind of smart. And even though I'm saying make hello, not

make hello .c, make is smart. And it's going to say, oh, if you want to make a

program called hello, I'm going to assume that there is somewhere in this

a file called hello .c. So you should not type make hello .c. You just type

hello. And then this third command, even more cryptic, what might it do?

If this is step three of three, that's going to run the machine code. It's

to tell the computer in this folder, sort of the dot implies this current

folder, and dot slash just means something in this current folder, run

program called hello.

So that's it. There's three steps to writing a program in C.

You create the file, as with the code command, but there are other ways to do

that too. And you don't even have to use VS Code. You can use dozens of other

alternative programs in the world. You run the compiler, which in this case is

called make.

Little white lie, make is not actually the compiler.

But more on that next week. But make is going to trigger compilation of this

code. And the last step three is to execute or run the program called hello.

So let me go back to VS Code here.

And you'll see that my code is still at the top. My terminal window is at the

bottom. I hid my file explorer, just because it's not that interesting

And I'm going to do what you proposed, which was m -a -k -e space hello, all

lowercase, Enter.

And ironically, thankfully, nothing happened.

And that's actually a good thing in this environment. If nothing seems to

happen, you probably did good. If anything does seem to happen on the

you probably screwed up and you've made some mistakes.

So seeing nothing is generally a good thing.

But what has happened? Well, let me actually go back and open up my file

explorer. And notice there's not only kylo .c, but there's a second file now.

Hello, which is the name of the program.

So hello is the program I want to run.

I'm going to go back to my terminal here. And to run this program, I'm going

do dot slash H -E -L -L -O. I'm going to cross my fingers, as I'll often now do.

And voila, my very first program in C.

How else can we see this file?

Well, down here in my terminal window, let me zoom in, you keep seeing a dollar

sign. That has nothing to do with currency. It's just a weird geeky

that you're prompt at a terminal window. Like, where you type commands generally

starts with a dollar sign. Sometimes it's a hash symbol. Sometimes it's an

angled bracket.

It depends on the system you're on. But dollar sign is very common. It just

means type your commands here.

Well, I've typed code. I've typed make. And I've typed dot slash hello.

But I can type other things, too, and more on these later, like ls.

which doesn't actually spell something, but is short for list, L -I -S -T.

Programmers tend to just be as succinct as they can, so most commands are not

full words. They're often abbreviations. If I hit Enter now, you'll see also two

things. You'll see hello .c, and you'll see in green, just to draw attention to

it, hello as well.

The asterisk here just means, in the programming environment, this program is

executable. You can actually run this by doing dot slash hello. The fact that

this is just white here, that just means it's some text file. It's, in fact,

source code.

So in other words, ls lists the file in my current folder, or you can use your

human eyes in the file explorer at top left and just look at what files exist.

These are one and the same. One is a GUI, one is a CLI, graphical, command

and so forth. And we'll start to take these kinds of paradigms soon for

But let me pause here and see thus far, now that we've written our first of many

C programs, any questions or confusion we can clear up.

So OK, if you don't understand most of the lines of code, that's what today is

about. Yeah?

I don't really understand the difference between hello and hello .c. DAVID J.

What's the difference between hello and hello .c? So hello .c is literally my

source code. It is a file that exists somewhere in the cloud that contains all

of the code I myself wrote.

The hello file is the file that the compiler created for me by converting

source code to the machine code. So inside of hello, theoretically, is a

bunch of zeros and ones.

We can't quite see them.

But if I do this, let me zoom out.

Let me click on Hello and notice that VS Code is going to yell at me. The file

is not displayed in the text editor because it is either binary, that is

and ones, or uses an unsupported text encoding, whatever that means. If I do

open it anyway, but I don't recommend this, like heed these warnings, you

see zeros and ones, but you will see sort of nonsense.

And this is because VS Code is trying to interpret those zeros and ones

incorrectly as ASCII text, like English text, but it's not.

They're instructions for the computer. So as soon as you see scary red stuff

like this, undo, close whatever tab you open, because odds are you can only

break the program you just created. It's not a huge deal. You can recreate it,

but that's what's inside of those files.

Yeah? What if we don't type dot slash hello, we just type hello? DAVID MALAN -

Really good question. What if we don't type dot slash hello, we just type

Well, let me do this. Let me hide my file explorer again, because it's not

interesting here on out.

I'm going to clear my terminal window by hitting Control -L just to be neat and

tidy in class. Or you can literally type clear, and it will clear it. But again,

that's just to keep things tidy. Your TF might do that in section two.

If I just type hello enter, I'm going to get this. Weirdly, bash hello command

not found.

So more on bash down the line. But this just means literally the command hello

is not found because you need to tell the computer where it is.

So dot slash hello means run the hello program that is in fact, right here. By

contrast, you don't run .slash for code, for make, or other commands that we'll

soon see, like ls. Because why? Those are installed in the system for

not just in your individual folder. So that's the difference. Any programs we

write, it'll be .slash something.

All right.

So let's tease apart what is actually going on here and see if we can lean

heavily today on Scratch, especially as the syntax gets weird, perhaps a little

overwhelming, still the same idea.

So this last time, of course, was our Scratch program that just said hello

world. I claim today that this is the nearest equivalent that any programmer

could convert Scratch into C. If we color coded accordingly, indeed, this

of lines up with when green flag clicked is the orange, and then the purple is

just the equivalent of the say block.

So the say block we said earlier was a function.

So let's compare these things side by side, because there's actually some

and reason to what MIT did with Scratch as to why these shapes look like they do

and so forth. So in Scratch, there's a function called say.

Recall that it takes an input, otherwise known as an argument, or a parameter is

another name. And that's always provided in these white ovals, zero or more

white ovals. In C, we've already seen, but let's do it a little more

pedantically, the equivalent of say is essentially the word print.

Why did MIT say you say?

Just because.

It's a little more kid -friendly. But print is the idea in our environment.

It's actually not print. It's printf, because we're going to be able to format

our text in interesting ways. More on that in a moment. But notice, the

parentheses and closing parentheses here sort of conjure up the idea of that

white oval.

So that's kind of intentional on MIT's part.

What, though, in C goes between these parentheses? Well, literally the input

the argument you want to pass to the function, like hello world.

But in C, you have to be a little more pedantic because you don't have a nice

little graphic like this purple block with the white oval. You have to

everything in double quotes.

Those of you with prior programming experience, in C, you need double

not single quotes in this context.

And then there's this arcane detail here, backslash n, which we'll come back

in just a moment.

But that's essentially what's going on. Line by line, from scratch to C, there's

kind of an equality between those two, even though they, of course, look a

little bit different.

Well, let's see what that backslash n is doing, just to highlight some details

here. So let me actually zoom in a little bit here.

And let me go up to my code. And let me just sort of recklessly delete the

backslash n.

I'm going to let it autosave. I'll zoom out. In my terminal window now, I'm

going to run make hello to recompile the code from source code to machine code,

because I changed the source code.

Nothing seems to happen. That's good.

Now I'm going to type dot slash hello, Enter.

And there's a subtle bug since I made that change. What looks wrong to your

eye now?

Yeah, the dollar sign, our so -called prompt, is at the end of the line

of on its new line.

I mean, this isn't really a deal breaker. The code works, and you can

a new command. But it just looks a little stupid. This was not the intent

program. It's sort of good practice to move the prompt to the next line. And

that's because the backslash n is what we're going to call an escape sequence.

So it turns out in programming, you have to tell the computer exactly what you

want it to do. So if you want a new line, the equivalent of hitting Enter on

screen, you have to tell the computer computer to put a new line there.

What you do not do is this. If I zoom out and I go into my code here, and I'll

zoom in on the code, if you want to put a new line, you don't do this.

Why? It's just confusing for the computer. Like, wait a minute, is that a

Did your lines just wrap?

Do you want to put a new line there? It just looks stupid. And it makes it less

line -based, the code itself.

So humans decided years ago, if you want an actual line break, don't just

naively hit the Enter key.

Literally tell the computer, put a new line here.

If you want to move two lines down, just do two of those. If you want three,

just do three of those.

Well, why the backslash? Again, these are what are called escape sequences.

And you don't literally want an N.

let alone nnn, what you want is a new line which is represented in code as

simply backslash n.

Now, for the mathematicians among you, what we're doing now by using functions

like printf is just sort of like f of x notation, if you recall that from high

school or prior, where f is a function, x is an argument or an input thereto.

And we're using parentheses in code just like mathematicians would to write

functions like these.

And the types of functions we're using right now still follow this model.

got input. You want output.

In this case, the input to printf, for instance, just like the say block, is

what's called an argument.

Output, though, of the function printf is what we call a side effect.

And the easiest way to think about that is a side effect is just something that

sort of like happens on the screen.

Visually, audially, it just sort of happens. And there's that effect on the

screen. And we'll contrast this with other types of outputs from functions.

for now, we're focusing on just this, which is reminiscent, of course, of what

we did last week, which is if you type hello world into the white oval, use the

say. Puzzle piece, you get out the side effect of the cat appearing to have

said, hello, world.

Now, as for those escape sequences in C, there's bunches of them, but very few

of them will we actually use in practice.

Backslash n is a new line.

Backslash r is a little more subtle, and it's kind of a feature of yesteryear.

It moves the cursor not to the new line, but to the beginning of the line, kind

of like an old -timey typewriter, if you've seen how those work.

Sometimes, though.

you might want to print out an actual double quote.

But there's a problem, of course. If this is my code here, and I'm already

double quotes as sort of special symbols to surround the text I want printf to

say, it would probably be a little worse. Like, if you wanted to say,

world, with sort of finger quotes, why might this not be a good idea,

if you think about this from the computer's perspective?

Why is this probably not the right way to do this? Yeah.

Yeah, exactly. The computer is indeed going to read your code top to bottom,

left to right. And when it sees the first open quote, OK, that's fine. It

understands that. But when it gets to the second quote, it's going to assume,

oh, wait a minute. Maybe you only want me to say, hello, comma.

And then it's going to keep reading and be like, wait a minute. Why is there the

word world here? And then, wait a minute. Now there's two more quotes.

confusing. It's ambiguous.

And computers need you to be, again, very precise.

So if you want a quotation mark to literally be displayed on the screen,

would escape it, so to speak. speak, which looks a little weird and takes

getting into the habit of. But this just solves that kind of problem.

And similarly, might you use single quotes in other contexts? More on that

And if you really want to bend your mind, how do you actually print a

backslash if you ever care to? It's not that common a character to type. But if

you ever want it on the screen, it seems that we're using backslash as a special

character that says, hey, give me a new line, or give me a carriage return, or

give me a double quote.

Weirdly, in programming, if you want to type a literal backslash, on the screen,

you literally do backslash, backslash. But that's it for sort of weirdness for

now. But this is to say, humans tripped over the same problems years ago. They

came up with solutions.

And now we indeed have these conventions in code.

All right.

So let's tease apart some other features of this in every program we're going to

write, namely what's at the top of this file.

So at the very top of this file, there is this cryptic -looking hash include or

pound include standard IO dot h in angle brackets.

So this is a little weird. We'll talk more about this next week, too. But this

is what's called a header file.

Any file that ends in dot h is not a

Source, well, any file that ends in .h is what we're going to call a header

file. And inside of that header file is functionality that maybe came with the

system, came with the programming language itself.

So for instance, I'm going to do this.

I'm going to go back to my code here, and I'm going to make a very common

mistake that you yourselves might make in the coming days, where I just forget

that line, because I don't even understand it in the first place, so I

didn't think to type it here.

Now, if I go back to my terminal window after clearing it, and I run make hello,

because I want to recompile it, because I've changed the source code, I'm going

to see a fairly cryptic error. I mean, there's more error on the screen than

there is code up here.

But you'll get the hang of sort of reading it to try to figure out what's

on. And I'm seeing this.

Hello .c line 3 character 5.

So that just means line 3 colon character 5 from left to right. It's

visual cue as to where the problem is.

Call to undeclared library function printf with type dot, dot, dot. And then

rest kind of overwhelms me visually at this point.

But that's a hint.

If you do not include that header file at the top of the code you've written,

you do not have access to what's generally called a library.

A library is a collection of code that someone else wrote for you. Maybe it was

MIT. Maybe it was the authors of the C language itself years ago. Maybe it was

CS50 if we wrote some code for you. A library is a collection of code that

someone else wrote for you. And you access it again by including header

that those same people wrote for you.

So if I go back to my code now, let me clear my terminal window just to be Less

overwhelmed. Let me undo what I just did and put that file back.

Can you perhaps infer, just functionally, what is inside of standard

again, someone else wrote?

What must be inside?

Printf. So whoever invented printf decades ago probably put that code in

file. And so by including it, so to speak, in my code, I now have access to

printf functionality.

So that's all. And again, C is lower level than Scratch. It's obviously text

-based, which means you have to be a little more pedantic yourself as to what

you want the computer to do for you. And if you want to use someone else's code,

you indeed have to include it. Scratch didn't bother with this, but we indeed

need to do this in the context of C.

As an aside, just to preempt some unnecessary headache, this word is not

.h. Every year, a non -zero number of people can't understand why their code's

not working because studio .h is not found. It's standard io, s -t -d -i -o

That's one of the first frequently made mistakes otherwise.

All right, so remember that. Let me undo now the unnecessary quotes I added

here. And let me propose that.

We show you where you can learn more. So all of these libraries generally are

documented. People wrote instructions for how to use them. So you don't just

have to listen and pay attention only in class. You don't have to pull up a

book. There tends to be online documentation as well, for instance, for

standard IO header file.

And the documentation in the world of programming for C specifically, are

manual pages, or man pages for short.

Unfortunately, they're really written decades ago for the more comfortable

you, those who have an eye already for programming.

And so what CS50 has done at this URL, manual .cs50 .io, is we essentially have

more user -friendly versions of the documentation for this header file and

others. So for instance, if I pull up manual .cs50 .io, you'll see a web page

like this.

And if I just scroll quickly, you'll see a whole bunch of header files, .h

files, and a whole bunch of functions beneath them. And there's only a couple

dozen or so here. And indeed, per this checkbox at the top, frequently used in

CS50, we have sort of highlighted the functions that odds are over the next

month and a half you will probably want to use.

If I turn off that less comfortable mode, there's actually hundreds of

that come with C. And no programmer knows all of these functions. What they

is they read the manual when they want to find some new piece of functionality.

So I'm going to simplify this. I'm going to scroll down, though, to standardio

.h. for instance, here. And you'll see more functions that we'll eventually get

to. But if I click on printf, you'll see, hopefully, some fairly user

instructions for how this thing works. For instance, under synopsis, you'll see

that we tell you what header file you should include in order to use it.

Below that is something called a prototype.

More on that later.

But below that is a description.

And here is where we, the CS50 staff, have written in layperson's terms

explanations of how this function works, how to use it, and so forth.

But if you'd rather see what the real world uses, you can turn off that mode,

and you'll see much more arcanely the original language.

So in short, these are sort of like training wheels that you can turn on and

at your leisure.

But ultimately, this is real world documentation as well.

So if we want to see something else, for instance, let me go back to the main

menu. And as we'll see today, there are actually function in a header file

called cs50 .h that, for a few weeks, we're going to lean on heavily.

Long story short, it's actually kind of hard. It's annoying in C to get user

input, ironically, to get the human to type in a word or a number.

You have to jump through some technical hoops to make that happen. And we'll

show you how to do it the real way in a few weeks. But for now, among the first

training wheels is a CS50 library code that we wrote that will just make your

life easier.

And indeed, we're going going to give you access to functions that simplify

process of actually getting input from the user. So case in point, we're going

to give you access to a function like getString when you want to get a string

text from the user. String is just text. So if you want to get one character,

one word, one sentence, one paragraph, you can call a function called

We're going to give you another one called getInt when you want to get an

integer from the user, like 1 or 0 or negative 1 or anything else. You can use

that function as well. And we'll see today, too, there's other functions you

use from CS50's library.

In a few weeks' time, we'll take these away once you sort of don't need them

anymore. And you'll see what those library functions have been doing all

for you. But for now, let's focus on this.

perhaps the most useful of them, getString, and solve a problem that we

already pretty easily in Scratch. So recall in Scratch, this was a program

used two functions.

Three, in fact. Ask, to ask a question of the user.

Say, to actually display something on the screen. And join, to combine the

default of Apple banana, or in this case, hello, and whatever the human's

was. So this made our hello program a little more interactive last time. How

we actually translate this into a similar paradigm now? So input and

the story as always. In this case, we have arguments going into those

But now we're going to introduce not side effects, which is stuff that

visually. We're going to revisit that blue circle called answer or the blue

called answer that represented last week what we called a return value.

And this is what many functions will actually do for us. They're not just

to display something presumptuously on the screen or play a sound or a video or

something like that. They're going to hand you back virtually a value.

text or integers or sounds or images that you can then do with what you see

So the paradigm we'll now have is, much like in Scratch, if the input is what's

your name and the function is ask and you get back a return value of answer,

want to actually do this now in C.

So side by side, what code like this in Scratch is going to look like today

onward is this.

Instead of using the ask block, you literally use CS50's function called get

string. It takes input.

So we put the parentheses on the left and the right to kind of conjure the

of this white oval.

Inside of that string, you can put a prompt, so to speak. Like, what do you

the human to be asked in this case?

And I'm missing something still, per the placeholders here. What's missing?

So quotation marks, so literally quotation marks on the left and the

I'm going to be a little anal here. I'm going to put a space at the end because

I don't want to. I could, but I don't want the cursor to go to the next line,

hence no backslash n. If I want the cursor just to sit there kind of

waiting for the user after the question mark, I'm just going to put a space so

it will stay there for me. But this is just an aesthetic detail using the same

idea as before.

So that is the analog of this block.

But how do I get access to the so -called return value?

MIT just plopped it on the screen for me. for us automatically.

In C, we have to write a little more code to get access to that return value.

And the way we do this is on the left -hand side of this line of code, we come

up with a name for the return value.

You can call it anything you want, but answer is a nice equivalent to what MIT

did. You could more generically call it x or y or z, but that's not really

useful. And so computer scientists, unlike mathematicians, will tend to use

variables that are a little more verbose, like the word answer.

But in C, it's, again, a little lower level. You have to tell the computer

type of variable this is going to be.

So I'm kind of conflating variable and return value, but they're being used in

an intertwined way.

The get string function, just like the ask block, returns the value.

If you want to do something with it, you need to put it in something called a

variable, which is denoted in text here.

But again, per last week, the computer doesn't know if it's looking at numbers

or characters or images or sounds. You have to tell it as the programmer that

the zeros and ones that are somehow involved here underneath the computer's

are, in fact, to be treated as text, a .k .a.

string.

Now there's one stupid subtlety still missing from this line of code. Does

anyone know, especially if you've programmed before? OK, all of you have

programmed before. Yes?

semicolon. So one of the headaches of C in a lot of languages is you actually

have to finish your thought explicitly so the computer knows that that line of

code is done. And it's not a period like in English. It's, in fact, a semicolon.

Now, you don't use these everywhere.

We'll see where you use them. But that, too, is a very common mistake to

overlook something simple.

But again, in the coming weeks, even though this might look very cryptic with

muscle memory and practice, you'll start to see these things instantly, even if

for a few days you sort of bang your head against the screen, so to speak.

seeing what the TFs and I much more readily see.

So let's go ahead and do this. Let me go back over to VS Code here.

Let me zoom in just a little bit.

And let me go ahead and do this.

I'm going to get rid of my single use of printf. And I'm going to say the exact

same thing. String answer equals get string quote unquote what's

your name question mark space close quote.

semicolon, and now I want to print out that answer. Well, let me do this

incorrectly deliberately for the moment. Let me just say printf quote unquote

hello answer if I want to plug in answer and I want to add a new line at the end

semicolon. So let me try this.

But there's multiple mistakes now in my code. Let's trip over them deliberately.

Let me go down to my terminal window by clicking at the bottom of the screen.

Let me run make hello again, Enter.

And oh my god, there's even more errors now than there were before. But not a

problem. Let me click on this little triangle here, which is just going to

in on the terminal window so it takes up my full screen.

And just generally, all you have to do is find a few keywords visually that

you a clue as to what's going on. Or as before, you can always ask the CS50

duck. So here's the command I ran, make hello.

Somehow that induced all of these errors. Always read them top to bottom,

bottom up. So from top to bottom, there's a problem on line 5, character

of undeclared identifier string.

Did I mean standard in? No, no, no. I didn't there.

And then also, two errors generated, too many errors remitted.

What did I do wrong?

Well, it turns out what I do need to do at the top of this file, let me click

the triangle to zoom back out.

If I want to use the get string function to get a string, I actually need to

include another header file, which is probably called include CS50 .h.

Technically, any order is fine. I tend to alphabetize because I just know,

therefore, where to look alphabetically for a certain header file.

Now that that's in place, let me again run make hello, enter.

And now we're back in business.

No error message.

So even though you might have more errors than you have code, odds are it's

the computer is confused, and it could be something simple and an easy fix like

that. So just to be clear, standardio .h, because I'm including it, I can use

printf. CS50 .h, I can use get string, because the people who invented C and

people who invented CS50 wrote those two files, so to speak.

respectively. All right, unfortunately, even though the program compiles, that

doesn't mean it's correct.

It just means it's syntactically valid. It's valid C code. If I go ahead and run

dot slash hello and hit Enter now, I'm going to be prompted for my name. So

type it, D -A -V -I -D. And notice there's a space to the right of the

mark, as promised.

Enter. But it just says hello answer, which of course is not the intent. I

wanted to say hello.

David. So how can we do this? Well, in Scratch, it took a couple of puzzle

pieces, but it was pretty straightforward.

If I wanted to say the combination of two phrases, hello and something else, I

joined those two and then passed that output to the input of say.

In C, it's going to be a little different here.

Just because it's an old language and this is how it's done.

Still use printf, because that's the same thing as say.

I got my parentheses. I got my semicolon. Good to go.

But inside of that, this is where printf is different.

If you want to say something followed by something else, in the world of C, you

tend to use placeholders.

So you don't just join things together, as we will do in Python and other

languages. You say to the compiler,

give me the word hello, comma.

and then something else. And the %s means put another string here.

It's sort of like leaving a placeholder in your code or a template where you'll

actually plug in some values.

Now, if this is what I want to display, I still use my quotes as before.

And I might, in fact, have a backslash n if I want to move the cursor to the

next line.

But this is where printf is a little different.

Unlike say, which took one input, Printf is kind of like join. It can take two

or more input if you so choose.

You just have to separate them with a comma.

So much like the join block has two ovals here that are initially white,

and banana, until we dragged and dropped answer on top of it, printf and really

any function in C, if you want to pass in multiple inputs, that's fine. If

they're supported, just separate them with commas. There's no multiple

parentheses. There's no multiple ovals. Just separate them with commas.

And now notice a potential point of confusion.

What's different about this comma and this one, just instinctively?

Sort of minor detail, but important. Yeah?

Inside. DAVID J.

So one is inside, one is outside. So the one that's inside the quotes is

literally the English grammatical comma that you want the human to see. The one

out here is a C thing that's separating the first input to this function printf.

from the second.

Strictly speaking, you don't need a space there. But it's good practice,

stylistically, to separate your arguments with single spaces, just as

there. So let me go ahead and now do something with this. Let me go back to

code here.

I'm going to clear my terminal window, just to get rid of that distraction.

And now I'm going to change answer to %s.

And then outside of the double quotes on line 7, I'm going to do comma, answer.

And then after it autosaves, I'm going to go back to my terminal window.

And just to make another deliberate mistake, dot slash hello, enter.

What's your name? David, enter. It's still broken.

But why?

I still have to recompile it. So again, you just get into the habit. When you

change your code, you have to recompile it so you get new machine code in the

file hello. So let's do it again.

Make hello.

No errors is good.

Dot slash hello, enter. What's your name again?

D -A -V -I -D. And now, hello, comma.

David. So again, a lot of this is still cryptic, but it's going to start to

follow patterns like this. Functions like in math class f of x are written

function name, parentheses, input, comma, input, comma, input, however many

have. They're going to follow these patterns. But notice too, on line six

seven, I have finished each of my thoughts with a semicolon.

So what are the other commands that you can run in your terminal window besides

something like ls? Well, it turns out there's a whole bunch of them. LS, of

course, was simply short for list, which shows you the files in your current

folder. But there's also CD for change directory, which is the command

equivalent of double clicking on a folder to open it up in a graphical

environment. There's CP, which is short for copy, which allows you to make a

copy of a file or folder.

There's Mkdir, M -K -D -I -R, which is short for make directory, which is how

you could make a new folder.

There's MV, which is short for move, which would allow you to move one file

folder. folder from one place to another or simply rename one of those to a

different name. There's rm, which is short for remove, and there's rmdir,

is short for remove directory.

So in fact, let's play around with a couple of these.

Let me go back to VS Code here.

Let me go ahead and open up my file explorer and recall that at this point,

got two files, hello .c, which contains my source code, and then hello, which

contains my machine code, the executable program that I previously generated by

running make.

Well, let me go ahead and propose that I'd like to

prepare to keep all of my files and folders very orderly. So for every

write or for every problem on a problem set I write, maybe I want to store my

relevant files in a specific folder for that problem.

So suppose, then, that I want to put hello .c in a folder, otherwise known as

directory, called hello.

Well, I can't do that quite yet because I already have a program called hello.

So let me use one of those new commands, rm.

space hello will delete or remove hello from my current directory. So I'm going

to hit Enter. I'm going to be prompted to confirm with y for yes or n for no,

remove regular file hello. I'm going to hit y and Enter. And as I hit Enter,

watch the top left of my screen as the hello file would seem to disappear.

Voila, it's now gone.

So now I'm going to go ahead and use a different command. Let me go ahead and

mkdir for make directory.

I'm going to call the directory itself hello. And watch again at top left what

happens. Enter.

Now I have not a file, but a folder called hello. And in this GUI, the fact

it's a folder is indicated, one, by its icon, and two, by that little right

-facing triangle, which means I can expand it to see what's inside.

And in fact, if I do that, I'll see, of course, that nothing's in it, because we

literally just created it.

All right, well, what if I want to move?

Hello .c into the new Hello folder. Well, I could, just like on Mac OS or

Windows. I could actually, in my file explorer, click and drag one into the

other. But let's do this entirely within the terminal window.

So let me do this. Let me move, or MV for short, my file called Hello .c into

new destination folder.

And I can optionally put a slash at the end of hello just to make super clear

that it's a directory, but that's not strictly necessary.

But if I say mv hello .c hello with spaces in between, assuming hello exists

a folder, watch what happens at top left now. It's a little more subtle, but

hello .c is going to move inside of the hello folder right now.

And indeed, it's only slightly more indented. But notice if I collapse the

folder, notice that it seems to be gone because hello .c is now inside of that

folder. Of course, if I expand that, I'll see it again. If I go back to my

terminal window and type ls for list, now I don't see Hello .c. And I don't

an executable program anymore, but I do see hello. And the slash there just

makes super clear to me, the user, that it's indeed a folder.

So how do I change into that folder?

Well, I can obviously use the graphical interface at left and click and expand

and sort of see what's going on. But there's no direct connection between the

file explorer at top left and my terminal window at bottom right. Rather,

are just two different ways to explore the underlying system.

So if I want to change my terminal window into this new directory, I can do

for change directory, hello, and then enter. And now notice my terminal

prompt changes slightly.

There's still a dollar sign, which indicates type my commands here.

But before that dollar sign, just so that I have a reminder, sort of

that visually remind me what folder I am now in, I see that I'm inside of hello.

If I now type ls, I should see the file I expect to be in there, which is indeed

hello .c.

Now, suppose I want to try out some of those other commands. And suppose I want

to maybe rename this file. I really want this file to be called something else.

So maybe I might do something like this, mv hello .c space, and now a new name

for the file.

Well, maybe I want to save this as an old version of my code, because I wanted

to start fresh with something new. So I could do something like this, mv hello

.c old .c.

And watch what happens at top left.

Hello .c, of course, gets renamed via the move command.

So I can use move to move a file into a folder, or I can use it to rename a file

or folder, as I've just done here.

Now, suppose I want to undo that. Well, I can't just type undo. I can't just hit

Control -C, but I can do the opposite, in effect.

mv old .c hello .c will now, per top left, Change it back into that file.

If I want to make a copy of this file, maybe as an actual backup, because I'm

really happy with this version and I'm worried about breaking it, well, I could

do cp for short. I can then do hello .c. And then I can do something like backup

.c or any other file name. I'm taking care to use the same file extension so

that if I do open this file later, it still opens and gets highlighted and

colorized in the same way. But watch what happens now at top left when I type

Enter. I now have two files in this hello folder. And indeed, if I type ls

I can see exactly the same.

So long story short, there's this whole list of commands, and even more than

these, that allow you to manipulate the underlying system in exactly the same

way that you and I have probably done for years by using a mouse and pointing

and clicking and double clicking.

But for now, let's undo all of this, because I haven't really written that

programs today. And I'm going to keep things simple today and keep everything

my same folder. So let's undo all of this.

Let me go ahead and now remove backup .c, because I don't particularly care

about that. I'm going to be prompted to confirm as much. Then let me go ahead

and move hello .c out of this folder and into the original folder. And

conceptually, the original folder is what we would call the parent folder,

folder that contains this hello folder.

And the way you can specify the parent folder, like back up from once you came,

is with .dot. So a single dot, as we've actually seen, .slash hello, .slash a

.out means execute a program in this directory, dot. But .dot refers to to

parent directory.

So watch what happens at top left when I move this hello .c file out of this

folder.

shifts a little bit to the left to indicate that it's no longer in that

I'm going to go ahead and type cd dot dot, which will bring me back to my

folder. Or even more useful, especially if you get confused or lost somewhere

within your folders, you can actually just type cd and nothing, and that will

whisk you back to that original folder no matter where you are. So it's a nice

shortcut, and it's a nice way of undoing any confusion you might have caused for

yourself. Lastly, let's go ahead and get rid of the hello.

directory with rm dir hello enter.

And that now disappears at top left as well. Now, what I was hinting at here,

whereby I had my hello .c file in a folder and I was moving things around

renaming things and backing things up isn't strictly necessary because there's

actually other features still inside of VS Code that you're welcome and

encouraged to play around with. In fact, if I go to my so -called timeline at

the bottom of my file explorer here, you can actually see that there's been

automatic backups made over time of this file. So if you click, click, click

through those backups, you can actually see different versions of the same file

slightly in the past, which might save you the trouble. of having to manually

create files.

And in fact, in the world of software development in industry, there's

standard tools very similar in spirit to what we've been using GitHub for that

allow you manually to make different versions of your code so that you can

proactively keep track of all the changes you've made without manually

things as you might typically on your own Mac or PC.

All right, let me clear my terminal window and ask if there are any

Yes, over here.

DAVID J. Yeah, a really good question. If we had something other than a string

of text, and we had an integer, would you still use %s? No, you would use

something else. And indeed, %i is what we're going to use, and we're going to

actually do that.

Perfect segue to other types that C actually has.

So up until now, we've been calling a string of text literally a string. And

this is common in many programming languages, including Python and

Strings in the programming world just mean text.

whether it's zero or more characters thereof. But C does have other data

just a few of which we'll dabble with today, but you'll use more over time.

We've already seen string, for instance, which is indeed a string of text. But

let's focus as well on an integer.

As an aside, there's other types, too. There's Boolean values, like true or

false. There's chars, which are single characters instead of full phrases or

sentences. There's doubles and floats, which are real numbers, something with a

decimal point, the equivalent of fractions.

And there's longs. which are integers, but longer integers, even bigger

than you might type by default. So let's focus on ints, because so many computer

programs, of course, manipulate numbers in some way. So what can we do with

this? Well, if we want to be able to get an integer, lucky enough, CS50's

library comes not just with get string, but also get int. So that's going to be

a third function we now use in C.

And we need to know what are generally called format codes. So that placeholder

I called before %s is indeed for a string. If we want to place an integer

of something we're printing to the screen, We are, in fact, going to use %i

instead. So let's now actually use these building blocks, get int and %i, to

actually get numbers in some way to sort of solve a problem.

Well, what problem could we solve? Let's introduce another concept from scratch

and programming more generally known as conditionals, like those proverbial

forks in the road. If something is true, do this.

Else, maybe do this other thing. So in Scratch, we might have had a set of

puzzle pieces that looked like this. If x is less than y, then say, or have the

cat say, x is less than y.

So it's sort of a stupid program, but it just demonstrates how we have two

variables, x and y, in the context of Scratch. We're comparing them with a

Boolean expression.

We're using a conditional to then conditionally say or not say this phrase

depending on whether this question has the answer of true or false, yes or no.

In C, it doesn't look all that different. It's a little more cryptic,

say literally if.

You use parentheses, similar to functions, but confusingly, by

put a space after the word if. So you don't put spaces after function names.

do put spaces after words like if. And you use the parentheses to conjure up

this weird trapezoidal -like shape. So there's no real keys that kind of

that. So C uses parentheses, like most languages.

And then there's these weird curly braces, which, at least in English, we

use all that often. But they're there on your keyboard, English or otherwise.

And they essentially allow us to create this sort hugging shape to the puzzle

piece. Anything inside of those curly braces is going to be equivalent to

anything inside of this yellow hug that's sort of grabbing one or more

inside. So what do we put inside?

Well, this part is straightforward.

Printf, quote unquote, x is less than y, backslash n, semicolon. So nothing new

here. The only bit of new code is this if construct instead.

What if you have an if else, so a two -way fork in the road? This is what that

looked like in Scratch.

Same question. If x is less than y, then say x is less than y. Else, say x is

not less than y.

In C, the code is going to be set up initially like this. So two sets of

braces to represent this pair of yellow bars and this pair of yellow bars.

And what's inside of them, indented no less, just like our pseudocode last

is two printfs. x is less than y.

x is not less than y.

So that's it. So the only new stuff here, really, is now the else.

keyword, which does not need parentheses, because you're just saying,

this other thing.

But what if it's a three -way fork in the road? And we'll stop after that.

Here's a three -way fork in the road in Scratch. If x is less than y, then say

this. Else if x is greater than y, say this.

Else if x equals y, then say this.

So this is a little more precise, because now we're handling equality, not

greater than or the opposite.

In C, it's going to look similar to before, but we're adding this element

And at first glance, especially if you've never programmed before, it looks

I'm an idiot and I made a typo.

What looks wrong?

There's like two equal signs, like not a typo. So it turns out Recall from

earlier, when we used the equal sign the first time around, we used it in the

context of getting a return value back from a function, like the get string

function handed me back the user's answer.

So unfortunately, because humans decades ago decided, hey, let's use the equal

sign to assign a return value from the right -hand side of a line of code to

left -hand side, we sort of painted ourselves into a corner and were like,

shoot. What do we do when we actually want to test for equality of two values

the left? left and right. So what most languages, including C, do is use double

equal signs. So you can say double equals or equals equals or whatever, but

is, in fact, syntactically correct.

What's inside of these three sets of curly braces?

Same idea, printf, printf, printf, based on what English phrase you want to

print out.

So this code, both in Scratch and C, I'll claim is correct.

It won't run because we still need the other stuff, the equivalent of the when

green flag clicked. But out of context, this code is correct.

But there's a subtle weakness in design.

And we'll talk a lot about this this week and beyond. Correctness just means

code does what it's supposed to do.

Design is more subjective, like how well have you written your arguments in an

English paper? How well have you written your code is design.

This code is not designed as well as it could be, because I'm doing more work

than I need to.

Yeah, and back.

Yeah, I don't need the x equals equals y, but why, logically?

Exactly. That's just a math thing. Like either x is less than y.

Or it's greater than y. Or the third and final option is they must be equal.

So it's subtle.

But why would you bother wasting time writing a line of code and expecting the

computer to run a line of code that is just going to answer a question that

logically you could have concluded already?

Because if x is not less than y and x is not greater than y, then my god, just

print out x is equal to y because you know at that point logically it's true.

You don't need to waste your time or the computer's asking a third question

unnecessarily. In reality, it's not a huge deal. No one's going to notice in

real world on a Mac or PC that there's this extra line of code. But it's a bad

habit. Keep it simple. Don't write code that doesn't need to be there if

logically you can conclude otherwise. So in fact, let's clean this up both in

Scratch and in C. I can tighten this up, so to speak, use less code here, less

code here.

And honestly, if only statistically, the less code I write, the less likely I am

going to make mistakes.

So that too is probably a net positive.

overall. Writing less code is generally better than writing more code, not

unlike English essays, too, perhaps.

All right, questions about this feature of C, conditionals, and this syntax?

Yeah.

Oh, a really good question. And yes, jumping the gun, there are alternative

to solve problems like these. And the question was to summarize when to use

else, if, else versus what's called a switch statement. More on those another

time. But this is going to be true in general in programming, not just C, not

just in Scratch, but every language.

There are going to be several.

dozens, hundreds, an infinite number of ways to solve problems. Among the things

we're going to teach you, though, is indeed how to do things well or better

you might otherwise.

And we're going to introduce you eventually to another feature of the

that can even simplify this code too.

So for now, let's actually use this then. So let me go over to VS Code

I'm going to go ahead now and clear my terminal window.

Down here, I'm going to go ahead and close the hello .c tab, just so that

going to create a new program. And let's just do something a little simple using

some operator, so to speak. And I haven't used this word by name, but it

out that there's lots of operators that come with C, just like a lot of

operators that came with Scratch for doing assignments or less than or less

or equal to, greater than, greater than or equal to, actually equal to, not

equal to. Now, some of these are a little cryptic, but There's no easily

key on your US English keyboard, at least, where you can do less than or

or greater than or equals. So what most programming languages do is you don't

use a special symbol where there's an angle bracket and then a line below it.

You actually just use two characters.

So greater than or equal is literally this this. Less than or equal is

this this. We already saw that equals is this this.

And not equals is to use an exclamation point. So this, too, is a thing in

programming. Using the exclamation point, pronounced bang, is how you

logically certain things. So bang equals or not equals is how you would express

exactly that idea.

It's just a symbol on the keyboard that some human decided, let's use this one

to invert the idea.

But we're going to need one other thing for this program, specifically

variables, which we've used already sort of because in Scratch we got one for

free. We had that answer variable that stored the return value of the ask

But let's consider in general how you can, and probably did for problem set 0,

use a variable of your own, like keeping track of a counter or a score or the

like. In Scratch, if you want to create a variable called counter, you can set

it equal to some initial value like 0.

In C, that code's going to look similar.

You literally just write whatever name you want to give the variable, then an

equal sign, and then the value you want to give that variable.

And because the equal sign is the assignment operator, it will behave

essentially right to left and copy the 0 into counter.

But this isn't enough for C.

Remember that you, the programmer, have to tell the computer, is this indeed a

number? Is it a letter? Is it an image? Is it a sound?

You have to tell the computer that this is an integer.

otherwise written as int for short in C.

But there's one other stupid detail that's missing, which is now semicolon

finish the thought here.

But this, then, is equivalent to this in Scratch. Let's do another. In Scratch,

if you wanted to increment the counter, that is, add 1 to it, you could

literally use this puzzle piece here and specify you want to add 1.

In C, it's going to look like this.

Counter equals counter plus 1 semicolon. Now, at a glance, this seems like a

paradox of sorts. Like, how can counter equal counter plus 1.

I can't make that math expression true, but it's not math in this case. The

single equal sign is assignment.

So this means take the current value of counter, whatever it is, add 1 to it,

and then copy that value from right to left into the same variable, thereby

changing it from 1 to 2, 2 to 3, and so forth.

This, though, is so common in programming, to be able to increment or

decrement numbers by 1 or 2 or more, is that you can tighten it like this.

This is the exact same thing, a little faster to type, saves you keystrokes,

maybe less chance for error.

Counter plus equals one semicolon is the exact same idea.

Better still, this is so common in C and C++ and Java that there's a third way

to do this. To my comment earlier about solving problems in different ways, the

most canonical, the most popular way is probably just to say counter plus plus

semicolon, which literally automatically adds one semicolon.

to that value. Only works for one. If you want to do two or three or some

increment, you have to use one of the other approaches.

But this simply does the same thing as this.

And if you want to invert it to negative 1, you change the plus plus to a minus

minus instead.

So again, just little things that we'll see and pick up over time.

Invariably, you'll have to look them up or check the notes or look back at the

lecture slides.

But in time, this will get familiar if you are not already familiar.

So let's consider just logically.

how we might implement this in code. Let's go back to VS Code here. And let

propose that we create a program called compare .c, whose purpose in life is

just to compare a couple of values.

I'm going to go ahead and proactively, based on the previous chat, include

CS50's library from the get go. I'm going to include standardio .h from the

go, so I can use get int and printf respectively.

I'm going to just on face type int main void.

And today, we won't explain what that does. More on that to come. For now,

assume it's like when green flag clicked.

But in this program, let's do a couple of things. Let's declare an integer

called x and assign it the return value of get int. And let's just keep it

simple. Let's ask the user not what's their name, but what's x, question mark,

semicolon. Now, so that we have something to compare, let's do it again,

with y.

int y equals get int, quote unquote, what's y, question mark. And I'm

again, a space just visually so the cursor nudges over a bit, followed by a

semicolon. At this point in the story, my users will be prompted for x and y,

respectively. Let's do something with those values. How about if x is less

y, then go ahead and print out, quote unquote, x is less than y,

backslash n, close quote, semicolon.

All right, and let me hide my terminal window for just a moment. This is a 13

-line program at the moment, but really it's like five or six interesting lines.

The rest has been copy -paste from previous programs.

Notice a few details.

One, I've indeed used my curly braces here.

And notice if you highlight lines, you'll actually see little dots that can

you make sure, oh, there are indeed four spaces there.

I've been indenting, just like we did last week with pseudocode.

Strictly speaking, it's not necessary, but it's going to be way easier to read

your code if you do add all of this white space, so to speak, than if you

and then submit to us as homework a program that looks sort of god awful

this, which is to make it much more much harder for the human to read it, for

you to read it, your colleagues in the real world to read it. But the computer

is actually not going to care. In fact, as an aside, one of the tools we have

built into VS Code for CS50 is this button at top called Style 50.

This is a program that we indeed wrote that will give you suggestions on how to

improve the style of your code so it looks like the right way that

would generally write it. As an aside, The computer world is fraught with

religious debate, so to speak, as to what code should look like. And people

the real world will have really stupid arguments over how many spaces to use

indentation and what lines code should go on and so forth.

Generally, in the real world or in a class, there's an official style guide

someone sort of autocratically declares, this is how everyone should write their

code, so that just everyone's code in the company or course looks the same.

you'll find in the real world,

reasonable people will disagree.

When you click style 50, it will be formatted as we ourselves recommend in

And in fact, let me zoom out here.

And this looks a little cryptic at first glance, but on the left is the code

that I just wrote and made a mess of by deleting all that white space.

On the right is the way the code should look if it is well styled.

So whereas correctness is all about does the code work the way it's supposed to,

design is about how well have you written that code?

Is it efficient?

Did you make good decisions?

Style is purely aesthetic.

Is it readable?

Does it follow a standard?

Can another human sort of easily skim it top to bottom, left to right, and

understand what's going on? So these green highlights are saying, please add

white space there.

And so I can actually change my code to match.

On the left -hand side here, if I realize, oh, my code's looking pretty

watch on line six at left as I hit the space bar to, whoops, sorry, on the

1, 2, 3, 4.

Notice that the right -hand side is starting to be happier with my code by

getting rid of the green indicators.

And I can do 1, 2, 3, 4.

That fixed that. Over here, I can do 1, 2, 3, 4.

I can move this onto its own line by hitting Enter.

And you know what? If it's taking too long, once you get into the habit of

things, you can just apply changes. It will give you the suggestions

automatically, and we're done and on our way. But for practice's sake, I would

get into the habit of doing things manually until it gets boring and

which point you might as well automate the process with a single click.

All right. So let's actually run this code. I'm going to go ahead and open my

terminal window again and clear it for clarity.

I'm going to run make.

Compare and hope that I didn't make any mistake.

I don't seem to have yet.

Dot slash compare.

And now notice I'm prompted. For x, let's type 1.

For y, let's type 2.

Enter. And x is less than y.

Let's do a little sanity check, so to speak. Let's rerun it. Dot slash

What's x? Let's do 2 this time.

1 for y.

And this time it said nothing.

So that's to be expected, because I didn't have a two -way or a three -way

in the road. The only time this code should say anything is if indeed x is

than y.

So for those of you who might be more visual when it comes to learning, here's

flow chart that represents this same exact program.

If you read it top to bottom.

You start the program with dot slash compare.

You are then prompted for x and y, and you're asked this. Is x less than y?

And the fact that this is a diamond means this is a Boolean expression, a

question that the computer is asking itself.

If the answer to that question is true, then quote unquote x is less than y gets

printed, and the program stops.

Else, if x is not less than y, as in the second scenario, the answer is, of

course, false, and nothing more happens.

But we can build out this tree, so to speak, by adding a bit more code. So

make it look like the second Scratch example.

If I go back here, it's not hard to just say, else if x is not less than y,

let's say that.

x is not less than y, backslash n, close quote, semicolon.

Let me now go ahead and rerun, make, compare, enter, dot slash compare,

And again, I'll do the second example, 2, which is bigger, and 1, which is

smaller. And this time, I will see.

x is not less than y.

If then we were to look not at this flow chart, but a slightly bigger one, you

can sort of visualize it this way. Everything in the left -hand side of

picture is the same.

But if it's not true that x is less than y, the answer is thus false. This time

we say, quote unquote, x is not less than y.

And we can do this, obviously, one final time just to bring the point home. If I

go back to my code.

And I even more pedantically compare these three values.

Let me go ahead and do this.

So else, I don't want an else, actually. So let's go ahead and do this.

Else if x is greater than y, let's then say x is greater than y

in English. And then finally have an else that says printf x is equal

to y.

close quote, or rather, backslash n, close quote, semicolon. So just to show

this all on the screen at once, this is identical now to that Scratch version.

It's well -designed, because I'm not asking the equals equals question

unnecessarily. If I go back to my terminal window here, clear the screen,

make compare, Enter, and then dot slash compare again, Enter.

What's x? Let's do 1.

Let's do 2.

x is less than y. Let's run it again.

Dot slash compare.

What's 2?

And 1, x is greater than y. Once more time, dot slash compare.

What's x1?

What's y1?

And now x is equal to y.

As an aside, if I seem to be typing fairly fast, you can actually kind of

with your keyboard. If you go up or down, you can scroll through all of the

commands that you've typed. So it's actually.

Excuse me, very useful. If you just hit up, it will pre -write the previous

command for you, at which point you can just say enter.

Or there's other fancy features built into this programming environment.

If you do dot slash S -C -O -M and then get kind of bored with typing out the

whole English word, you can hit tab for tab completion, like in a web browser,

and it, too, will autocomplete if it finds a file that starts with those

letters. A little efficiencies here.

Questions, then?

On the code here. Yeah.

I have a question about libraries.

Sure. Is there any downside to just putting in all of the libraries?

A good question. Is there any downside to just putting in all of the libraries?

Like we saw in the manual pages a moment ago, performance.

So generally speaking, C is meant to be a very efficient language, so much so

that even though it's decades old, it's still used omnipresently nowadays

because it's so fast.

It therefore minimizes time. It minimizes energy use. So it's still

heavily. you would slow things down if you told the compiler, by the way, give

me all of these other functions that I'm never going to use.

So in short, just don't do that because it's unnecessary.

But a good question.

Other questions on what we've done here?

Yeah, in front.

Just a follow -up.

What is it?

A YSC faster?

A YSC faster than other languages? Let me answer that in more detail in week

when you'll see.

how much easier it is to write code in other languages because someone else is

doing a lot of the work for you. So as an introductory course, we're sort of

teaching you bottom up, like how do you write code? How does the computer

understand code?

Eventually, this kind of stuff, certainly after like five, six weeks of

it's going to get tedious doing some of these things.

We're going to switch to another language that takes away the tedium and

us to really focus on the problems to be solved once we've sort of graduated to

that point.

Yeah?

Sure, to repeat the keyboard shortcuts, you can just go up, up, up, up, up, and

that will go through all of your previous commands, at which point you

hit Enter.

Or you can use tab completion. So you can start typing a word like code, and C

-O -D tab will finish the thought, or dot slash C -O -M tab will finish that

thought, just to save yourself some keystrokes. And clearing the screen is

Control -L, which has no functional purpose other than keeping things neat

tidy in class.

So a design question.

So this code, I dare say, is correct. Let me zoom in a little bit here.

Let me change the code to just do this, even though we already saw from scratch

that we probably shouldn't do this.

Why should we not do this?

If, especially, I'm just more comfortable asking three separate

if x is less than y, if x is greater than y, if x equals y, do this. It's a

world to live in. Just ask your questions. You don't have to worry about

else, if, else, if, forks in the road. You can just ask three questions. But

let's put a finger on why is this correct, yes, but not well -designed.

Yeah, and back again.

OK, so there could be cases that are potentially outside of these three.

this is relatively simple math comparing numbers, we don't have to worry about

that here. But yes, in general, you might miss a scenario without using a

-all like else.

Yeah, so maybe more than one of them could be evaluated as true. Not going to

happen here, but yes, you could accidentally create a situation where

print or three things print because you didn't really think about the boundaries

among these questions that you're asking. Again, not applicable here, but

general, a good concern.

DAVID J. Really good. Really what's concerning here in this example is

slowing the computer down by wasting its time having it do work that is

logically unnecessary, even more so than the scratch in the first C example.

Why? Suppose that I type in 1 for x and 1 for y.

Because I wrote this code top to bottom, this question is going to be asked no

matter what.

The answer is going to be false.

This question is going to be asked no matter what. The answer is going to be

false. This question is going to be asked, and no matter what, the answer is

going to be true. We're OK there because we had to ask all three questions.

But suppose I did the first thing. x is 1, y is 2.

Then this first question is going to be true because x is 1. is less than y, 1

is less than 2, so this is going to print.

And yet then I'm wasting everyone's time asking, is x greater than y? Even

though it obviously isn't. Is x equal to y?

It obviously isn't. You're doing three times as much work in that particular

case. It's just not good design.

And again, for those of you who think a little more visually, we can actually

make this picture.

To match, here is a final flowchart for bad code, bad design.

Why? Because no matter what, when you start the program and you want to stop

program, you're going through all three of those darn questions no matter what.

Whereas the previous flowchart got us to the stop.

Bubble faster by taking alternative arrows based on true or false answers.

short, still correct, but bad design.

And so again, even for problem set one, when we start writing C code, consider

not just getting the job done, but how you might get the job done better than

you might otherwise.

All right, let's add a few other features into the mix.

Here we have those same data types that are supported by C. Let's focus for a

moment on something a little simpler, just chars, single characters.

Unfortunately, for better or for worse in C, the language makes a distinction

between strings of text, which are generally words, phrases.

They can confusingly be single characters or even zero characters if

type anything in between the quotes, but more on that another time. But when you

know from the get -go that you only want to get a a single character back from

the user, like y for yes, n for no, for instance, which is super common in

programs, you can get that using a char, and CS50's own function, getChar.

So how might we use this? Well, let's go back to VS Code here. I'm going to

close compare .c. And let's write a third program altogether.

Let's call this one agree .c.

And this is meant to represent terms and conditions where you have to check a

box, yes or no, or something like that.

In this program, I'm going to go ahead and do the following.

I'm going to go ahead and, as before, include CS50 .h so we've got it, include

standardio .h so that we've got it.

Int main void, because we have to do that for now. More on that another time.

And now let's ask the user a question. Do they agree?

So I'm going to call get char and then pass in a prompt of do you agree

mark with a space.

semicolon. But as before, with get string and get int, those functions

value. So I want to assign that value from right to left to a variable, which

could call answer again. But honestly, this program's so short, I'm just going

to use the letter c, which is conventional.

So c for char, i for int, or n for number are very common. But one more

what's still missing for my variable here?

I need to say this shall be a char, not an int, not a string, a single char.

All right, now what do I want to do? I can ask a question. If c equals equals

lowercase y, then go ahead and print out, just so we see something on the

screen, agreed period backslash n, as though they agreed to the terms and

conditions. Else, if c equals equals lowercase n, go ahead and print out, for

instance, not agreed, just so we see something.

on the screen.

So let me hide my terminal window and focus on the code. There's a couple of

details here that are a little interesting.

So one, what did I do on line 7 and 11 that is not consistent with what I've

done before?

Subtle.

So I'm using apostrophes or single quotes now instead of double quotes.

It's a C thing. When you're using strings, you use double quotes. When you

single chars, You use single quotes.

So the argument to get char, that's still a string. It's a whole sentence

I'm passing in. So that is just like get in, just like get string.

But when I get the answer back, the return value, and put it in this

and I want to check what is that one char, I have to surround the char I'm

comparing against in single quotes or apostrophes, both for the y and for the

So this program is not super well designed, because it's not going to

uppercase. It's not going to handle weird inputs very well. But let me open

terminal window, make agree, Enter.

The code compiles OK, dot slash agree.

Do I agree? Let's try it. Y for yes.

OK. Let's try it again.

Dot slash agree.

N for no.

Not agreed. Let's do it one more time. Let's very enthusiastically say yes in

all caps.

And it just kind of ignores me.

But why?

Well, this is a feature of CS50's get char function.

If you tell us you want to get a char, we're not going to tolerate a whole

string of text from the user. We're going to prompt them again and again and

again until they give us just one char.

So yes is three times too long. So let's actually just do a single capital Y and

see what happens. Return.

The program ignores me altogether.

So all right, this is kind of a poorly designed program. It's a little annoying

that we'll just ignore humans, even if they type in y or n. That just happens

be uppercase. So let's improve this. Let me go ahead and add a couple more

conditions. Else if c equals equals uppercase y, then go ahead and print out

agreed, same as before.

And then down here, else if c equals equals capital N, then let's go ahead

print out again not Agreed. So this is now more correct.

It's still going to ignore bogus input that makes no sense if it's just like

word, if it's a different letter altogether.

But this to code, while correct in some sense, is still poorly designed.

Even if you've never programmed before, what rubs you the wrong way about this

code now?

Be critical. Yeah?

Yeah, it'd be nice to just merge the lowercase and the uppercase Y together.

The same thing for the lowercase and the uppercase N. Why?

If only because literally lines 9 and 12 are identical.

Lines 17 and 21 are identical.

And while not a huge deal, if I go in and I change this sentence, odds are,

the course of my lifetime programming, I'm going to forget to change this one,

even though I changed this one. Or I'm going to forget to change this one and

this one. So you don't want the code to get out of sync, potentially.

to repeat yourself.

So don't repeat yourself is a tenet of programming, too. If you can avoid that

by somehow factoring out some commonality, you should do so, similar

to math, when you factor out variables or the like.

So let me tighten this up, so to speak. Let me get rid of what we just did so

that it's a little shorter as before.

And let me express myself with two conditions using the following syntax.

I want to check if c equals equals lowercase y or C equals equals uppercase

So you can actually use what's called a logical operator, two vertical bars,

which means or, and we can do this down here, or C equals equals capital

N. So same exact functionality, but to your point, we've now eliminated what,

like another one?

It was like, what, one, four? It's like eight lines of code now are gone, which

is eight fewer lines that I might screw up in this program, less opportunity for

mistakes or bugs.

Probably a good thing. So now if I run this, let me open my terminal window.

Let me run make agree, enter, dot slash agree, enter. Do I agree?

Capital Y.

Now it seems to be handling both of those situations.

So just a little tighter. As an aside, we won't use it here. But if you want to

say and, which would be nonsensical, it, a little confusingly, is 2 ampersand,

means a logical.

and whereby the left thing has to be true and the right thing has to be true.

it's two Boolean expressions at once.

This one makes no logical sense, though, because the character cannot be

simultaneously lowercase and uppercase. It's got to be one or the other. So two

vertical bars is logically correct. That represents our notion here of or.

Question?

No?

Yeah.

You could not write or. So I'm saying or just because that's a little more

normal, but this is incorrect.

However, sneak preview, in the language of Python, you actually will literally

say or among other things, which gets a little more user -friendly.

Other questions on this here?

Searching? Yes, in back.

Is there an easier way to handle case sensitivity?

Yes, and we'll show you that next week, in fact. So we can combine this code to

be even tighter.

All right, let's do one final set of examples before taking a cookie break,

we could. But let's go ahead and close agree .c here.

Let me open my terminal window. And let's go ahead and implement a sort of

virtual cat, as we did last week. I'm going to code up a file called cat .c.

I'm going to implement this in a few different ways, the first of them pretty

foolish. So here, I'm going to include standardio .h. No need for CS50 just

int main void.

Inside of these curly braces, let's go ahead and do printf meow to get the cat

to meow.

And then to save time, I'm going to copy paste that two more times. So this cat

shall meow three times in total.

All right. I'm going to go ahead and make the cat, so to speak. All good.

Dot slash cat. Enter. And it meows three times, just like our scratch cat last

time. I'll stipulate this is correct.

This is a really well implemented cat, correctness wise.

But why is it bad design intuitively?

Just like last week.

I keep repeating the code. I mean, I literally copied and pasted, which is

of your first obvious sign I'm probably doing something wrong if I'm copying and

pasting, because I'm literally repeating myself.

So to spoil it, like odds are a loop is probably going to be our friend here.

And so in fact, in C, we have those features as well.

So in the world of C, we can implement some of last week's same ideas in a few

different ways.

These are a little more mechanical, but suppose we want to repeat something

literally three times.

Scratch gives us a repeat.

A block with an input, so easy.

C, in a lot of languages, is going to be a little more mechanical. And it's

going to look ugly at first. It will take some getting used to. But it is a

paradigm you will use again and again and again. This will become very rote

memory before long. Well, the most direct translation of this scratch code

is probably something that looks a little something like this, whereby I

initialize a variable, here called i, and set it equal to 3. That's the code

equivalent in C of putting up three fingers.

Then what I want to do is while i is greater than 0, that is to say, while I

have at least one finger up, go ahead and do the following. And then once I've

done that, for instance, say meow on the screen, I want to go ahead and

decrement i.

and then do this whole thing again.

Now, I could have called this variable counter for consistency with earlier.

But it turns out it's conventional. When you've only got one variable involved

in your code and all it's doing is something simple like counting, you can

ahead and call the variable i for integer, for instance. But it would not

wrong to instead call i counter.

But notice, too, that in this so -called while loop, as we'll start to call it,

there is this parenthetical. And that parenthetical is actually itself a

expression. But unlike an if statement, whereby the Boolean an expression is

evaluated just once, and if the answer is true or yes, you do that thing.

The Boolean expression in a while loop here in C is evaluated again and again

and again every time you go through the loop to check if you should keep going

through the loop. So for instance, if the goal at hand is to say meow, well,

course, the comparable C function is going to be printf. And I want to print

on the screen meow, followed by a new line. Well, what's going on? Well,

I initialize i to 3.

I then check, is i greater than 0?

And of course it is, because effectively in the computer's memory,

I decrement i, which means to put down one of those fingers, and then.

I check the Boolean expression again. Is 2 greater than 0? Of course it is. So I

print out meow. And then I decrement i, putting down one more finger. Then I

check the expression again. Is 1 greater than 0? Of course it is. I print out

meow. And then I decrement i. And now I'm down to 0.

I check again.

Is 0 greater than 0?

Well, no.

And so the loop will automatically, by the definition of how this C code works,

terminate for me and proceed to any other lines if there are more lines of

that I've written.

So how do we actually implement this then in code and get it running, well,

going to be pretty much the same idea. Let me go back to VS Code here. I'm

to get rid of all of this copy paste. And inside of my main function, I'm

to do exactly what we saw.

Int i equals 3.

semicolon, while i is greater than 0, then go ahead and print out with printf,

meow, backslash n, and then be sure you decrement i.

And notice that lines 8 and 9 are not only indented, they are inside of that

while loop, so to speak, which means they will both happen again.

And again and again, because what's happening in code here is those curly

are kind of like the yellow pieces that are hugging the other puzzle pieces in

Scratch. It will keep doing this, this, this.

But every time through that loop or cycle, this Boolean expression will be

checked again and again and again until the answer is false, at which point the

computer is going to jump to the last line. And if there's nothing left,

it for the program.

No more to be done.

So same exact idea in Scratch, even though it's a little more mechanical.

So that's how we might implement this.

And you can think of it sort of these variables.

This is perhaps a little gratuitous, but let's do this. So if you have a

variable inside of a computer's memory, and that's a detail we'll get to in more

detail before long, you can really think of it just as like a container that

stores value.

So for instance, this.

Clear plastic bowl can be thought of as a variable. It just stores values.

And right now, there's obviously three stress balls in it, so it represents the

number three.

So what's really happening in code like this is we've initialized i to three,

which is this ball. We're then checking the question on line six, is i greater

than zero?

Obviously. So we proceed inside of the curly braces, and we print out meow.

We then decrement i.

So for the sake of unnecessary drama, like that's decrementing the variable.

what's being stored in this container now is 1 less.

We do it again. Check the count. Nope, 2 is greater than 0, so we keep going.

Meow. Decrement i.

Check the variable.

1 is greater than 0, so we print meow.

Decrement i.

We check the condition again.

i is not greater than 0, because 0 is not greater than 0.

And so the rest of the code stops executing.

I'm not sure if that was any more effective than fingers on my hand. But

the ball. We had the ball. So same exact idea.

Variables are just storing some value. And incrementing and decrementing would

just be adding or subtracting stress balls in this case.

But there's other ways we could do this.

In fact, let me zoom in on my code here.

And it's not really conventional in programming to count down.

Nothing wrong with it. It's just not really a thing we would typically count

So we could alternatively do this.

Set i equal to 1 initially. So we count 1, 2, 3, like a normal person.

And we can change our condition.

If I'm going to count from 1 to 3, what should my comparison be in my Boolean

expression here?

i is less than 3?

Less than or equal to 3, I think. So if i is initialized to 1, we're going to go

through this one time, two times.

three times, i is going to eventually get incremented to four. But at that

point, four is not less than or equal to three. So it's only going to execute a

total of three times. But there's still a bug in this code. What other line

needs to change?

Yeah, so line 9 needs to become plus plus.

So this code is just as correct. And honestly, you could, reasonable people

disagree. Your TF might say, do it this way and not this way. But this is still

correct. But it's not the most conventional way. As per last week,

scientists and programmers generally actually start counting from 0 by

convention for reasons we'll soon see.

So the better way, the more conventional way, arguably, would be always start

counting from 0.

count up to, but not through the number you care about.

And so this form of the code is probably the most popular way to do it. Start at

0, count up to 3, but not through 3, as with less than or equals than. All three

are correct.

Can't really do counting up as easily with the ball without picking up the

balls, but the exact same logic applies.

And in fact, this version of the code is so commonly done that there's a

different way to implement it all. There's a similar way to implement it

together. In fact, this code here, same exact thing, repeating three times,

because it's so commonly done that you want to initialize something to 0 and

keep doing something until the value 3, you can actually use a different

preposition, 4, which is another keyword in C.

And it looks a little more cryptic, but it just tightens things up.

This is what's called a for loop.

Previous is what's called a while loop.

And honestly, even though it probably to the newbie still looks just as cryptic,

it's just a little tighter, because you're expressing all of these ideas on

line. You specify the variable you want to create and initialize.

You specify the Boolean expression you want to check again and again.

You specify what increment or decrements you want to happen. And confusingly,

you do use semicolons here, not commas. You do not put a semicolon here.

You, of course, don't put them after these things. You generally only put

after function thus far.

So we do have one semicolon here.

But in short, this you'll get more comfortable with. This is how I, for

instance, almost always write a loop. But it's doing the exact same thing

mechanically as this. Same thing as counting. Same thing as counting the

balls. There's just different ways to express the exact same idea.

But there are ways to screw up. So in fact, let me go ahead and do this.

Suppose that the cat, we'd like the cat to live as long as possible.

And we don't want it to stop meowing after just three or a finite number of

times. How can you do something forever, again and again and again?

Well, let me go back into VS Code here.

Let me delete all of the code from earlier. And let me go ahead and say

Something is true. I'll come back to that. Let's just go ahead and print out

meow backslash n, ideally forever.

But what do I want to put in here? Well, if I want to do something forever, I

could do something kind of stupid, like while 1 is less than 2, which is always

going to be the case, or while 50 is less than 51, which is always going to

I could just ask an arbitrary question, but like arbitrary, not good in general.

Like you should have meaning behind your code. So if you want the expression to

be true all of the time, just say while true, because true is not changing

anytime soon. If it's literally true, it's always going to be true. The only

caveat is to use this trick for now.

you will need to include the CS50 library, which, for today's purposes,

that possible.

But there's a problem, of course. If the cat's going to live forever, if I do

make cat dot slash cat enter.

Like, you can very quickly lose control over your terminal window.

And you can see the meows are flying across the screen, at least based on the

bottom from what we're seeing. Like, this cat will never stop meowing. And

is either a feature or a bug, so to speak, depending on how long the cat

should live virtually.

But how do you terminate a program that is out of control like this infinitely.

So one of the takeaways for today is Control -C is your friend for cancel or

interrupt the program.

If you ever sort of lose control over a program because you've got intentionally

or unintentionally an infinite loop, you can go into your terminal window, hit

Control -C, sometimes multiple times if it's ignoring you, and that will break

out of the program and just essentially force quit it, like in Mac or PCs.

But let's make one improvement here still.

The last thing we did with our cat in Scratch, before now we'll take a break

a moment, was we defined our own functions. And recall that we did that

abstract away the idea of meowing, because Scratch didn't come with a meow

puzzle piece.

C definitely does not come with a meow function.

We have to implement it ourselves.

So quickly toward the end of week 0, we did this.

Define a function called meow that just plays the meow sound.

And now we have a meow puzzle piece we can use and reuse.

In C, we're about to do this.

And this is going to look a little cryptic, but it's going to lay the

for future weeks when we do this even more. I've got a meow function.

Weird mentions of void.

That just means there's no input and there's no output for this function. It

just does one thing simply.

And that one thing is printf meow.

So how do I use this here code? Here in Scratch is how we used it last week.

When the green flag is clicked, repeat three times the meow.

function. In C, it's going to look like this, int made void and all of that. And

I can use a for loop, a while loop. I'm copying and pasting the for loop version

of the code. Set i equals 0.

Make sure it stays below 3.

Increment it on each iteration or cycle.

And just call meow.

So what's nice here is that we have fairly simply a way in C to create our

functions called meow or anything else that lines up perfectly with what we did

in Scratch. We'll take some time to get comfy with the syntax and remember it,

have to look it up frequently for reference. But let's go ahead and

this. If I go back to VS Code, clear my screen,

let me hide my terminal window temporarily.

Let me go ahead and invent this meow function.

Per the code earlier, I'm going to go ahead and do this.

void meow void.

And again, the two voids mean no input, no output. It just does one thing well.

Printf quote unquote meow backslash n.

And now down here, I can use a for loop. So for, and I know this from memory,

int i equals 0, i less than 3, i plus plus. And then inside of curly braces,

going to go ahead and call the meow function.

Notice When I'm creating the function up here, I explicitly, pedantically say

void, void, no input, no output.

When I use the function on line 13, you just say open parenthesis, close

parenthesis. That's the equivalent of a scratch puzzle piece without a white

oval. You just put nothing there. You don't put the word void.

So that's it. Let me open my terminal window.

Let me run make cat to recompile dot slash cat. And I think I have a working

cat. Now, this is correct.

The only thing I don't love about this version, if I hide my terminal window,

that when I start writing bigger and bigger programs, it'd be nice if my main

function which I told you to take on faith for today, is at the top of the

If only because literally the name main means this is the main part of my

program, it'd be nice if it's the first thing I see.

Which is to say, just to be pedantic, it's very common to put any functions

write at the bottom of your file, maybe alphabetically, maybe organized some

other way.

But you put main first by convention, just like the when the green flag

It was the first thing you always started with last week.

But watch what happens now. If I go into my terminal window.

And Command or Control J is hiding and showing it if you are curious, but

probably you'll just leave it open on your own all the time. Let me do make

again.

And huh, I've screwed up somehow. All I did was move the meow function from top

to bottom, and I'm getting call to undeclared function meow something,

something, something.

Well, what's going on?

Well, C is pretty naive and simplistic.

It's only going to do what you tell it to do, and it's only going to do things

top to bottom, left to right. And unfortunately, on line 8, you are

call a function called meow.

But that does not exist in CS50's header file.

That does not exist in standard IO's header file. It exists at the bottom of

file, at which point it's too late, because I'm trying to use it before it

exists. So I could just undo that and put this meow function at the top of the

file. But you're going to eventually get into a perverse scenario where you

can't put all of your functions above all of your functions. You've got to

a lane at some point. So the solution to this, albeit a little weird and the one

time

in CS50 and programming that it is encouraged and necessary to copy -paste

what you can do at the top of your code above main is just copy -paste the first

line of your own function.

This is the so -called prototype of the function, and it simply describes how to

use the function.

And funny enough, we actually saw this earlier, but I sort of swept it under

rug a moment ago.

Or a bit ago, when we looked at standardio .h and we looked at the

function in the manual pages, I highlighted the header file.

But I also glossed over the so -called prototype, which is, sorry, the first

line of the printf function, just as this is the first line of my meow

This is like a little clue. This is like saying to see, hey, there's going to be

a function called meow that takes no input, has no input, takes no input, has

output. Just know that it exists eventually.

And that will satisfy the compiler.

Because if I go back to my terminal, rerun make cat, it now knows on face,

line four, this function will eventually exist.

And indeed, once it gets to the bottom of my code line, 14 onward, there it in

fact is. So you just copy the one and only first line of your function's code

the top called the prototype.

And now if I do dot slash cat, I get finally, meow, meow, meow, yet again in

this case.

Questions on these here cats?

No? All right.

Last flourish before I keep promising cookies that I promise they exist.

So last flourish, like just as we did in Scratch. So in Scratch, recall that we

parameterized our meow function by letting us tell meow how many times to

so that we didn't need to use our loop inside of our when green flag clicked

block. In other words, if I want to actually have the cat meow a specific

of times, I can actually go ahead and do that proactively with some of my own

code, such as this here in Scratch. When I edited my meow function last week in

Scratch, I specified that I want it now to take an input called n, which

represents some number of times.

And I changed my repeat block not to be 3 perpetually, but to actually have n

generally baked in there instead.

Or actually, instead of just saying place on meow, I had a repeat block

as the placeholder instead of a hard -coded 3.

So how can I now use this in C?

In C, it's almost the same.

It's still void at the beginning of my function name, which means no output

still. It only has side effects.

But what did change vis -a -vis the previous version of meow?

What has changed?

Exactly. Instead of saying void a second time in parentheses, it literally says

int n inside of those parentheses, which means in C, this function called meow

take input. It means the exact same thing as the pink on the left. And

this is why we keep emphasizing the scratch blocks. No new ideas with a lot

these features.

It's just different syntax that you'll get used to over time.

So if I go back into VS Code here and I change this function, let's do that.

Let's change my prototype to be int n, where n represents some number of times.

Let's change the actual function on line 14 to also have int n here.

And let's actually move the for loop from main into the meow function, such

I now have my curly braces here.

I have my print statement inside of those curly braces.

And now, in main, I can get rid of all of that code, just say meow.

any number of times, like three, and just like I did with Scratch, let me hit

Enter, an arbitrary number of times, sort of out of sight, out of mind, now

essence of my program is like one real line of code, meow three times, because

I've abstracted away the idea of meowing and told the cat instead exactly how

many times to meow by way of that function.

OK, I can't keep stringing along cookies so long.

Let's go ahead and take a 10 minute break here. And when we come back, more

cats, more code.

DAVID J. All right.

So we are back and want to add one final flourish to this program because now,

more so than a lot of the examples, now the programs are starting to grow in

length. And indeed, soon there'll be a few dozen lines of code, which is not

uncommon. But let's suppose that we want to stop hard coding three everywhere

and actually prompt the user for some number of meows here. Well, let me do

this. In VS Code, I'm going to go ahead and Get rid of this one line for now,

and let's do something like this.

Let's ask the user for an integer. So int, maybe n for number equals get int.

And we'll say something like just number to give a number of meows. And then

we'll go ahead and actually call meow, passing in not three this time, but

passing in n.

So we are using the return value of get int to store it in a variable called n

on line 8. And then we are passing n as the input or argument to the function

called meow on line 9. And again, the actual implementation of meow on line 22

onward, like who cares, out of sight, out of mind, once it exists. We can sort

of abstract it away mentally, but I'll keep it uptight here anyway.

All right, so let me go ahead and open my terminal window, make cath, dot slash

cath, number.

I can still type in three and it works.

Or I can go ahead and type in five, meow, meow, meow, but it's not actually

meowing five times. Why?

I didn't realize this either. But there's a bug.

DAVID J. Yeah, exactly. So the for loop, when I copy pasted it before, before

break, I actually kind of got lazy and I forgot to change the three to an n so

that it matches the name of the argument that's being passed into meow.

So that was a bug, unintentional on my part, but we have now fixed it here. And

now we are passing this in from main to meow.

So if I make cat dot slash cat.

And type 5 this time, I indeed get 5 meows. But it's worth noting there's

subtleties here in my code in that I've used n a couple of times.

So this is actually deliberate that I've used n twice in this way to induce a

bit of confusion.

But it turns out this n It's actually not the same as this n nor this one. So

what's going on here? Well, it turns out in programming, there's often this idea

of scope.

And long story short, generally speaking, variables only exist in the

which you create them. More down to earth, variables only exist inside of

curly braces in which you define them.

So for instance, suppose I got a little floppy, and suppose I didn't bother

giving meow an input, and I didn't bother giving its prototype an input,

just used n on line 14.

Because why? Well, I already defined n on line 8.

So this is just an alternate universe in which I'm not changing meow to take

input. I'm just using n in two different functions. In main, on line 8 and 9.

Actually, I don't even need that. On line 8 and 9.

And also, again, on line 14.

This code will not work. The compiler will not like this. Why?

Because n does not exist inside of meow. Why? Per the heuristic I offered, n

exists only inside of the curly braces in which it was defined, namely these

curly braces here.

So n is in scope in main, so to speak.

But it is not in scope in meow.

And that's why we kind of have to jump through these hoops and use inputs and

outputs and inputs and outputs and pass things around among functions without

sort of sharing things across functions instead.

Now, I could clarify this and maybe change my argument here from n to times.

If I want to make clear that, oh, this is the number of times I want meow to be

said, I don't have to use n for both. But just realize that if you do, it's

a coincidence.

They are not usable in two different scopes.

All right. Let's do one other thing, though. Let's not only prompt the user

the number here. Let's make sure that it makes sense what number they give us.

So if I do make cat, just to clean things up, dot slash cat, suppose I type

OK, I suppose that's correct. If I say meow zero times and it doesn't meow at

all, that's arguably correct.

But if I type in something like negative 5, it ignores me, which I guess is

better than crashing or freezing or something. But ideally, it might be nice

handle this situation.

And if they give me a negative number, prompt them again for a positive number.

Prompt them again for a positive number. Make the program make sense.

So how could we do that? Well, a couple of ways.

If I go back into my code here, I could do this. I could maybe do something like

a loop, or let's see. So if I get n, so if n is less than 1, then

it makes no sense. So what do I want to do if n is less than Well, I could just

prompt the user again. And I'd say, OK, let's get n again.

And then I can say, if n is less than 1, what do I want to do? I guess we could

ask the user again.

And then if n is less than 1, I could just, again, I can give them three

four tries to get this right. This is obviously stupid. I'm copying and

I'm repeating myself.

There's no end in sight.

I can't do this forever, surely.

So this just feels like the wrong solution.

So there are different ways to solve this problem. And funny enough, a while

loop is not really the best way. A do while loop is not the best way. A for

is not the best way. It turns out there's one other type of loop that we

to introduce that's super useful for getting user input potentially again and

again and again so that the user cooperates.

Specifically, what I'm going to do is this.

I'm going to literally say do the following while something is true.

So it's more of a mouthful. I'm spreading it out over multiple lines.

am I going to put inside of the do block here? I'm going to say int n equals get

int and ask for that number as before, close quote semicolon. And I'm going to

keep asking while, sorry, accidental enter, while n is less than

1 semicolon. So notice the semantics of this. Even though it's a little weird

looking, it does read in English, do the following.

OK, get an int stored in n, and keep doing that while n is less than 1.

But this code, as written, is not quite going to work yet.

Let me try opening my terminal window, make cat enter.

Ugh, damn it. Like, use of undeclared identifier n.

Well, here's where the line number is helpful.

The line number is indicated here, 12, and it's repeated here, 12.

So I clearly screwed up at line 12.

There's not that much going on at line 12.

Why is n undeclared?

in line 12, even though I literally just declared it in line 10.

Exactly, because I declared n inside the scope of the do block, so to speak,

inside the curly braces on lines 9 and 11.

That variable n no longer exists by the time we get to line 12. It'd be great if

it did, but it doesn't, because it violates that heuristic I proposed,

that variables only exist in the scope of the curly braces in which they were

defined. So how do I fix this? Well, it turns out you can declare a variable in

advance. outside of one scope, but then define it, that is, initialize it

elsewhere. So the solution here is actually this.

Inside of the loop, just set n equal to the return value of get int. But per the

heuristic, you've got to declare n, make it exist inside of the outermost scope

of this function.

So it's a little weird, and we're kind of breaking this down into two steps,

this is valid, recommended, correct.

C code.

You declare a variable without giving it any value initially.

And then in line 11, you proceed to give it a value, potentially again and again

and again.

Now, what's useful about a do while loop? So a do while loop, as the name

implies, will do something no matter what. But it will potentially do it

and again and again while some question is true, like n being less than 1 in

this case.

All right, as an aside, why did we not do a while loop? Well, let's think about

that. While n is less than 1, but wait a minute, n doesn't have a value.

OK, so I guess we have to go back to doing get int number colon semicolon.

but while n is less than 1, we're back to the same problem where we have to

repeat ourselves again. So this is why for loops, while loops.

Not the right solution when you want to do something at least once, but

potentially again and again. So the right solution here, again, is this new

final looping construct. I'm just hitting Control -Z a lot, whereby we've

it as follows.

All right, let's try this. Clear the screen.

Make CAS.

Enter. Dot slash CAS.

Let's type in 5.

Still works. Let's type in negative 5. And notice, it doesn't just ignore me.

prompts me again and again and again. Even if I type in 0, I've got to at

give it a positive integer.

Well, this actually seems like kind of a common paradigm. Like, what if we want

to prompt the user for a positive number in other programs, too?

We're nearing the point already, even after just week one, it would be nice to

write our own reusable functions that solve common problems. And eventually,

maybe we can put them in header files as well. But for now, let's go ahead and

do this. I'm going to actually copy all of this code. And I'm going to create

one more function in this file below main called get positive int for

And I'm going to specify that it doesn't need any input, because the only thing

this function is going to do is that exact same thing.

So notice that I've just moved my code from main into a function that's name

describes what it does, get positive int.

I'm declaring n here.

I'm doing this again and again.

And I'm doing that while n is less than 1.

And what am I going to do up here?

I can do something like this. Give me a variable called times for how many times

you want to meow, and just call get positive int.

Let me call in. So now, again, we've abstracted things away. And just like in

Scratch, our final example, which we're called looked a little something like

this, where we just called a function to meow three times. Now we're calling a

function to getText. If I hit Enter an arbitrary dramatic number of times, out

of sight, out of mind, I now have two functions in this world, getPositiveInt

and meow that are collectively implementing this entire program.

But it's not quite correct.

There's one mistake here still.

Notice that getPositiveInt is written slightly differently from the meow

function. And just to be clear, too, let me copy its prototype to the top of the

file, just so we don't make that same mistake I made earlier where I didn't

the prototype at top, so C didn't know what it was.

What is different about these two prototypes at a glance?

Yeah?

GetPositiveInt.

Okay, so GetPositiveInt apparently, and we've not talked much about this,

apparently does have an output.

of type integer.

It's supposed to return an int, hand me back an int. It doesn't have any input.

That's what the void in parentheses meant.

No input, but yes output. And meow, funny enough, is the opposite. Yes

output. Why? Because it has a side effect, the visual thing, where it

something to the screen but doesn't hand me any useful value back like the ask

function or the ask puzzle piece did.

So these are sort of opposite in functionality, which means I actually

return an integer from this function to whatever function wants to use it.

So if I want the assignment operator to work here on line 9, I need to do what

all this time get int, get string, and other CS50 functions have been doing. I

need to, in my own function, return that value, literally with a new keyword

called return.

And this is why I keep sticking out my hand. When you want a function to hand

you back a value, you literally use return and then that value.

That's why we have return value as a term of art, literally this return

So if I open my terminal window now, make cat enter,

huh, I did screw up accidentally.

How? Yeah.

Yeah, so on lines 9 and 10, I made a quick change. I changed my variable to

times, but I stupidly didn't change this. So that's fine. That's why n was

undeclared in that context.

Let me clear my terminal. Make cat once more.

OK, that worked. Dot slash cat. Let's type in 5.

And it's still working.

So again, even though the code is kind of growing and growing and growing, it's

the exact same program we wrote super simply before break. But now we're sort

modularizing it. We're creating reusable functions.

And this is why functions like getStringExists, getIntExists, like CS50

those years ago.

And we realized, why are we copying and pasting these functions in all of these

different CS50 programs?

Let's factor out that functionality into a function of our own. Get int, get

string. Just like here, I'm proposing to factor out this functionality.

Get a positive integer that gives you even more precise functionality.

So theoretically, you could use and reuse it in other programs, too. By not

just putting it here, we could go put it in a file of your own name.

and include it in future programs as well. That's all a library is. Someone

realized, gee, other people, including myself, might find this function useful

again and again.

Let's package it up in our own custom function, just like our custom meow

piece last week, so we can indeed use it again and again.

And the takeaways for now is that unlike Scratch, which was a little more user

friendly, in C, you have to specify if you want your functions to have inputs,

and you must specify if you want them to have

outputs as well.

But more on that syntax to come.

So where does that bring us? So after all this discussion of code, at the end

the day, this is what's important in the world of programming.

Not surprisingly, it's what's important when it comes to grading and evaluating

the quality of code.

One, and first and foremost, is correctness. If the code does not do

supposed to do, what was the point of writing the code? So correctness sort of

goes without saying.

Design, again, is much more qualitative.

It's like getting feedback again on an English essay.

Where reasonable people might disagree, you can make your argument better. You

can structure the paper better. You can structure the code better in the case of

programming. And style is purely aesthetic.

Does it look good? Is it pretty printed, so to speak? Can other people,

colleagues, future, and classmates present actually read and understand it?

That's what we mean by style.

Nicely enough, within CS50's programming environment, you will have tools to

evaluate the quality of all three of these axes, so to speak. So in problem

one onward, you'll be introduced to a command line tool that you type its name

at the prompt called check 50 that will check for you the correctness of your

code. Not necessarily exhaustively, like there might be mistakes you've made

that we don't catch, which doesn't make your code correct, but it is a tool for

finding many of the mistakes in your code. In the real world, you would have

colleagues or yourself would write tests for code you wrote or someone else

wrote.

It is a real -world thing to ensure that systems are designed to work.

We saw the Style 50 tool in VS Code already. You click the Style 50 button.

There is now, thanks to the duck, a Design 50 button, too, also in that top

right -hand corner, whereby once your code is correct and working, like

of my programs have been, you can click Design 50, and the duck will not just

quack, but give you qualitative advice, if it can, on how you can make that code

even better, even before you submit. And of course, there's all of us humans in

the room and online that you can ask these same questions of.

as well.

So let's now solve some sort of real world but still simple problems as

to emphasizing small bite size as we have thus far. So the first of these

programs falls into this category. It's having side effects. So let's implement

one or more functions that takes an argument's input and as its output

these visual side effects. We'll draw inspiration from Super Mario Brothers,

surprisingly, perhaps here. The original one, which was very two -dimensional,

side scroller, left to right, Mario or Luigi move from left to right, and

generally have to jump over things like pyramids or other shapes on the screen.

So how might we go about implementing some of the screens from Super Mario

Brothers, albeit textually? Well, we'll make it a little black and white and

ASCII art, so to speak, here using just our keyboard.

But suppose we want to write a program.

called mario .c that just prints out four question marks. It's not going to

nearly as pretty as what's on the screen here, but the logic is going to be the

exact same as what Nintendo presumably did years ago.

So let me open VS Code, my terminal window. Let's code a program called

.c. In mario .c, I'm going to kind of start with some boilerplate. I know I

to print, so even if I don't know how to do this yet, I'm going to include

standardio .h.

For today's purposes, I'm going to copy, paste, or type out that same line again

and again, int main void.

And inside of my main function, akin to the green flag being clicked, I want to

go ahead and print out four question marks. Well, honestly, the simplest way

can think of doing this is with printf, question mark, question mark, question

mark, question mark, maybe a backslash n to move the cursor, and that's it.

So that is arguably correct.

So let's do make Mario in the terminal, dot slash Mario.

And it's not quite as pretty as the game version of it, but it is, in fact, the

exact same idea.

But here's sort of an opportunity, stepping stone, to do better design.

Like this game changes over time, and not all of the screens have just four

question marks. It might be five, six, or even more.

So what's the right programming construct with which we could generalize

many question marks are printing here?

Like what feature of C do we want?

Like a loop, like a for loop, a while loop, or something like that. And

different ways to do this. But honestly, I proposed earlier that we get into the

habit of reaching for for loops as just very conventional.

So let's do that. For int i equals 0, i less than 4, because that's how many I

want for the moment, i plus plus. And then inside of my curly braces there,

let's go ahead and print out, quote unquote, a single question mark, but no

line.

Let me now go ahead and make Mario.

And can you anticipate a arguably aesthetic bug when I hit Enter?

It's not going to move the cursor to the next line.

But the solution here is a little non -obvious. I don't think this helps me.

I put the backslash n there and I do make Mario again and dot slash Mario,

is this output going to look like instead?

Yeah, like a vertical column of question marks, which, while nice enough, is not

the goal at hand. The goal is these horizontal ones.

So someone else, what's the fix here? It's clearly putting the backslash in

inside of line 7 is wrong.

Yeah, so put it after the loop, and not after the printf line specifically.

after and thus outside of the loop so that after that loop is finished

three total times, it's totally fine to just print nothing other than a

backslash n so long as we now recompile the code, make Mario, dot slash Mario,

and voila.

Now we have four in a row. It's a little generalized.

OK, so we've sort of plucked off a fairly easy problem.

Well, let's go back to the world of Mario and try something that is, in

vertical like this. So this is another scene with three bricks here. Instead of

using question marks, we'll use hash symbols to represent bricks. This

is the incarnation of my mistake a moment ago.

So let me undo this by getting rid of that printf.

Let me change the inside one from a question mark to a hash symbol, which

most similar in ASCII to a brick.

And let's go ahead and put in backslash n after that.

If I do go ahead and do make Mario, dot slash Mario, it's not that interesting.

But, and it's actually not that correct, because I wanted three.

So no big deal.

I can, of course, go back to my code and change the four to a three. Or better

yet, I could use get int or my new get positive int function and just

this further so that I can print out any number of them. But for now, dot slash

Mario gives me three.

All right, so we've plucked off the second of two problems.

Let's now let things escalate a bit. So it turns out once you get to like world

two and beyond, there's some underground parts of Mario where you actually have

bigger, more solid bricks like these here.

And just by eyeballing it, this is like a three by three grid of bricks. Like

nine of them total will conjecture. So how can I go about implementing this?

Well, now is where the program gets a little more interesting.

And the poorly designed way to do this would be like,

printf, hash, hash, hash, backslash n, semicolon, and then maybe printf,

printf. That's kind of correct, but not well -designed. So make Mario, dot slash

Mario. It doesn't look like a square, just because these hashes are more

vertical than they are horizontal.

But it is correct, this example. But it's not very generalizable. And this is

literally hard coding. I copy -paste. And I'm just doing a lot of bad

here. So what could I do instead?

Well, it turns out we can combine today's ideas, including loops, to do

again and again.

So what is this grid of bricks?

It's a three by three.

So it's like a row and a row and a row.

And then within each row, there's column, column, column.

So it too is like an old timey typewriter that sort of prints one line,

next line, then the next line, and so forth. So how can we conjure that in

Well, let me go ahead and do this.

I think an approach would work is like this. For int i equals 0, i less than 3,

i plus plus, because I know I want to do something three times.

But what do I want to do three times? This loop kind of represents in my

eye rho, rho, rho.

So in fact, I could be more pedantic. If I want my i to mean something beyond

int, I could say rho equals 0, rho less than 3.

row plus plus, just to help me think about it.

And then what do I want to do on each row?

What do I want to print?

Like column, column, column.

So brick, brick, brick.

So how do I print three bricks or any number of bricks? Well, I could kind of

cheat and just do printf hash, hash, hash, backslash n. But again, I can't

generalize. I can't take an input from the user and print four or five or six

bricks. So that's going to get me into trouble eventually.

So maybe I could use a loop. So I could do like for int i equals 0, i less than

3, i plus plus inside of my loop. And then in here, I could print out one

And that's kind of on the right direction, the right path, because now

using the simple building block or brick.

but reusing it again and again. And it's totally fine to have nested these

columns in this way.

I used i out of habit, but what would a better name be?

Well, maybe column, or maybe just col, call for short, so that my code is sort

of saying what it does for me.

And I don't have to use row or column explicitly. I don't need to print them,

but I am using them as counters, one after the other.

So let me go ahead and run make Mario, dot slash Mario.

And I'm feeling good about this, but .

Damn it. There's nine brick, but they're not really laid out right.

Why? What's the fix? Yeah.

Yeah, I never went to a new line. And let me do what I think you're not going

suggest I do. Let me just go the obvious place. All right, well, let's put one

right after the brick. But of course, if I do make Mario, dot slash Mario, I'm

making the same mistake as before. I'm printing out too many new lines. So in

between, what lines do I actually want to print a new line?

Between, yeah.

Yeah, so 10 and 11. So outside of the inner loop, but inside of the outer

So it happens again and again. So let's just print out as before, single

backslash n, semicolon. Now let's do make Mario, dot slash Mario, enter. Ah,

it's generalized as I see fit. And if I really wanted to dwell on this.

I could go in, and I could prompt the user with get int or with get positive

int, figure out what row and or column should be. We can make any size brick

that we want. But now we have sort of a nice starting point.

But there's another way to think about this. Because I dare say, especially for

your first CS50 problem set, if you're trying to print bricks and the world of

Mario in this way, it's probably not going to be obvious to come up with

like this and just magically get it working after like 45 seconds in total.

It'll be a struggle at first.

there are some patterns to follow. So one, it's pretty conventional.

Nonetheless... to use just i and then j and then k and then l. And if you've got

nested, nested, nested, nested for loops, at some point nesting, you're

writing bad code. It's not well -designed. But one or two or maybe three

nestings could be an OK thing.

But you cannot use and reuse i again and again. Why?

Because if you're counting i here, but then you're changing i here to do your

columns left to right, you're going to get all of your math out of sync. So you

need two separate variables.

i and j are conventional.

row and column would work too.

But if we go back to this idea of rows and columns, well, let me actually

something out here.

And this might help you instead.

Suppose that you set out on this problem.

You know you want to do something like three times, but you don't quite

understand how to print those rows.

Well, take a baby step, a bite out of the problem, and maybe do this.

Create a function with no output.

just a side effect, whose purpose in life is to print a row.

And how many rows?

Well, maybe n for some number of bricks.

How do you print a row of brick?

Well, let me just think about this in isolation.

How do I print a single row of brick? That's easy. For int i equals 0, i is

than n, if I'm generalizing, i plus plus, and then, whoops, i plus plus, and

then. Inside of my curly braces, go ahead and just print out a single hash.

And at the end, as you suggested, print out a single new line. In other words,

abstract away the idea of printing a single row.

And in fact, at this point in the story, especially if you're struggling to get

started, you don't even need to start with main. Take a byte out of the

that makes sense to you that's smaller than the whole problem.

printing a single row.

Because then you can come in and iterate.

Then you can go in and say, OK, now let's write my actual main function.

So int main void, as always.

And now what do I want to do? I want to print out a whole bunch of rows.

How do I print out a whole bunch of rows? Oh my god, it's like the same

int i equals 0. i is less than, let's call it 3 for now, but we can generalize

that. i plus plus.

And what do I want to do on each iteration of this loop?

My gosh, just print row.

with three bricks.

And then we're sort of done.

Again, out of sight, out of mind. This function can go away and never be seen

before, because once print row exists, that's what it, in fact, does for me.

Now, this isn't 100 % correct.

I still need my prototype, because if I've made my own function, I need to

see in advance that it shall exist. So I need to copy and paste that one line of

code. If I were really being pedantic, this is bad design.

In general, when you have the same number in multiple places in a program,

programmer would call this a magic number. How is that working? You're just

honor system that you're using the same number again and again.

So a better solution here, even if you're not going to take user input,

to do this.

int n equals 3.

and then use n here, and then use n here, or you could call it anything you

want, but now you've specified three in one.

and only one place.

And we can go one step further. It turns out in C and in other languages, you

can protect yourself against yourself.

If you know that a variable should never change its value, it should always stay

3 in this case, you can use what's called a constant, where you can

say, I don't want just n to be an int. I want it to be a const int, const for

short for constant. And this means even if I try to change n in my code, the

compiler will not let me. So I can protect myself from myself or in the

world, you can use a variable that none of your colleagues can foolishly change

on you without you realizing that it has happened.

So a lot of programming, honestly, is just not trusting yourself the next

morning when you've forgotten what code you wrote, let alone the next month, the

next year when you're writing code in the real world. So constants just give

a feature to defend against ourselves.

There's another feature that's useful too, especially when you wake up the

day and you're like, oh my god, how does this code work? What does it do?

Well, there's comments in code. And some of you might have used this in Scratch.

You could add little yellow sticky notes in Scratch for comments.

In code, you can do something like this.

You can, if you want to put an English reminder to yourself, or if you speak

some other human language, a comment in Spanish or any other human language, you

can write it with a slash slash at the start of the line. And then you can say

something like print n.

And then this tells you in a comment what those subsequent lines of code are

doing. It's sort of a note to self. It has no functionality. For the computer's

sake, it just is a note to yourself.

Or you can say something like this, like, never change n, because you're

clear that it's indeed constant. But that, too, is a little pedantic, since

const says the same. But comments are notes to self to help you remember what

something is doing or why you did it this way.

Questions now on any of these Mario problems that we have solved?

No?

All right. So one final set of examples that puts the limit of what computers

can actually do. That's why we've solved every problem I proposed.

That's because I've kind of been skirting some of the underlying

So it turns out that we have not only functions that give us side effects,

visually on the screen, we again have functions that have return values. So

let's focus on those and where things can go wrong. And let's use a bunch of

other operators as well.

Suffice it to say, computers got their start by being really good calculators.

So computer support, addition, subtraction, multiplication, division,

operators represented by the percent sign here, which says take the remainder

something over something else. And there's even more operators than this.

let's go ahead and implement our own calculator of sorts that actually has

bugs along the way. Let me go back over to VS Code here. I'll close mario .c,

open my terminal, and code up one final file called calculator .c. And in this

calculator file, let's go ahead and do something super simple initially.

Let's go ahead and include cs50 .h.

Let's include standardio .h.

Let's do int main void, as always, all boilerplate thus far.

And now let's do something more interesting.

int x equals get int.

And we'll prompt the user for an x value.

int y, prompt the user for a y value, as we've done previously for comparing

numbers. And let's just do something super simple. Let's give myself another

variable, int z equals x plus y.

And then let's print out the sum.

So printf, quote unquote, and I don't want %s here. If I want to print out a

number, someone said it earlier, we want %s for string, but %i for integer,

backslash n.

and print out the value of z.

So it's a little silly, this calculator.

It just adds two numbers together, but it's going to demonstrate some points.

make calculator, enter.

So far, so good. Dot slash calculator.

Let's just say x is 1, y is 2, z is going to be 3. This code is correct,

though it is. Is there an opportunity for marginally better design?

Could we tighten this up, make it shorter? Fewer lines means lower

of bugs, probably?

Yeah.

Yeah, we don't really need a separate variable z.

I mean, it's fine if it's clearer to you, if it's clearer to your TF, if it's

clearer to your colleagues. But honestly, this is so relatively simple,

we just get rid of z and just say something like x plus y here, which is

reasonable as well.

But you don't want to take this to an extreme.

Heck, if we don't need z, do we really need x and y?

Well, we could do something like this.

Let me actually delete these lines of code.

And claim, we can do this all in one very pretty one -liner.

We could do, say, get int x plus get int y.

And notice now, kind of like the join example last time, I'm calling get int

twice.

Both of them return a value.

which is going to be 1 and 2, respectively, based on what I typed

Then I'm doing 1 plus 2.

That's going into printf as the second argument. This is actually correct and

will work. It's just stupid.

Don't do this. We've crossed some ill -defined line where this is just harder

now to read.

And so even though the variables aren't strictly necessary,

I would argue, and I think most programmers would argue, This is just

readable. Each line is doing a little bit less work. There's less chance for

error. It just makes a little more sense. But reasonable people will

So therefore, this is to say, over time too, like you and your TF might

disagree. You and your colleagues might disagree.

And at that point is when the sort of religious debates kick in as to which

is the right way.

All right, so that's one calculator.

Let's do something else that maybe just doubles a number here.

So let me change this to just get one integer from the user. Let's just call

x. And let's just double it quite simply. So printf %i backslash n x times

2. We'll quite simply double it. The star operator is indeed multiplication

this case. So that's going to go ahead and double my number. So make calculator

again, dot slash calculator, Enter. And let's go ahead and type in 1.

And I get back 2. Let's run it again. Type in 2.

I get back 4.

Type it again. Let's type in 3.

I get back 6, and so forth. All right, so that's not bad in this case here.

But what if we actually want to write a proper program here?

In fact, yeah, let's see. This is sort of a meme that comes and goes.

Let me see if you recognize this.

I'm going to go ahead and say.

Another variable, not x. Let's be more specific, like int dollars equals 1.

And then let me deliberately induce an infinite loop. Sometimes it is useful to

induce an infinite loop so long as you eventually break out of it somehow if

don't want the program to run forever.

I'm going to ask the user a question, asking them for a char c using get char.

And I'm going to ask them, quote unquote, here's percent i, period.

Double it and give it to the next person, question mark.

This is ringing a bell. And then we can pass in to Getchar the dollars value

there. So actually, this looked a little cryptic already. I'm going to put a

dollar sign in front of it as though we're actually dealing with US currency.

And what do we want to do? How about if the user says Y for yes, double it and

give it to the next person, then let's go ahead and do dollars.

And let's double dollars. So I can do dollars equals dollars times two. Or

recall the trick for plus and minus. I can also do.

times equals 2, which just doubles it in one line as well. Just a little

syntactic sugar, as programmers call it, that just tighten up your code, even

though it's the exact same thing.

But what if the user does not type y and they want to keep the money?

Well, we have an else condition.

At that point, you don't want to keep asking, asking, asking, asking them with

get char.

Let's just break out.

of this loop instead.

So break is another keyword that if you're inside of a for loop, a while

do while loop, you can forcibly break out of the loop early if and when you

to. And so this sort of satisfies the goal of making sure that this doesn't

forever, but it is going to run again and again and again while we keep

prompting the user with this question.

So let's see now what happens.

Except at the end, let's go ahead and make sure the user knows how much money

they're walking away with.

Here's dollar sign, percent i, backslash n, dollar. So we will see at the end of

this whatever dollar amount the person ends up with.

Make calculator, enter, dot slash calculator.

And let me increase my terminal window size.

So here we go. Here's $1. Double it and give it to the next person. Yes.

Here's $2. Double it and give it to the next person.

Yes. Yes.

Yes. Yes.

Yes. So the Instagram reels aren't that long. But if you keep doubling it again

and again, this is called exponentiation, which will make you

quite quickly. Because notice, we're already in the thousands of dollars by

saying yes and yes and yes.

It's an interesting sort of societal question as to what dollar amount you

keep the money and no longer double it and pass it on. But for now, we'll just

keep doubling it, because this is just getting bigger and bigger, seemingly

infinitely large in the C program.

But oh my god, like apparently,

The Instagram reels cut off the meme too short because eventually it goes

negative and then zero.

Like, what's actually going on here?

Like, the code is actually correct, but we're bumping up against a different

kind of problem.

Any instinct for what is actually going wrong here? It's not doubling forever?

Yeah.

Yeah, there's not enough bits to store bigger and bigger numbers. Recall with

bits, which happens to be how big most ints are, you can count as high as 4

billion if you start at 0, or roughly as high as 2 billion if you want to handle

negative numbers as well, negative 2 billion to positive 2 billion. So

eventually, once I get to $1 billion, it goes negative, and then it just goes to

0 altogether.

This is because of something called integer overflow, whereby if you only

finite number of bits, And you keep incrementing them, incrementing them,

incrementing them.

Eventually, you can't just carry the 1, because there's no 33rd bit.

So all of the other bits wrap around from 1s to 0s. And it looks like all 32

your bits are 0.

Because the 33rd bit was supposed to be the one, but it's not there. They don't

have enough memory. So this is a fundamental problem with computers

you count high enough, things will just start to break, at least if you're using

C or C++ or certain other languages that don't anticipate this.

And there's a very real implication of this. So here's a photograph of

we'll look at more in time to come, like of memory inside of your computer or

phone or any electronic device.

Suffice it to say, there's only a finite amount of memory. And if you're only

using 32 bits then, or heck, even three bits, you will eventually overflow.

We used three bits last week. So here's an example. In binary, if you're only

using three bits per the white digits here, I've put in gray the fourth just

show you what carry we might want to have.

Here's 0, 1, 2, 3, 4, 5, 6, 7, just like last week. And

just like last week, someone said, how do we get to 8? We need another bit.

But if that bit is grayed out because it doesn't exist, we've just overflowed

this tiny integer and gotten back to 0, just like my money went to $0 instead.

So how do we actually avoid that?

One way to do this is this. Let me hit Control -C to break out of the program,

or I could just type no. Let me shrink my terminal window.

and clear it here, I could actually do this.

It turns out that ints use 32 bits typically, but there's another data type

was on the slide before called long, which is a longer version of an int,

is 64 bits, which is crazy big.

There's not that many dollars in the world, but it's still finite, even

can't pronounce the number that big. But if we change all of our int to long,

and we change our placeholder from percent i to percent li for long int, I

actually count higher and higher. So case in point, let me actually go back

my terminal, make calculator, Enter.

Make it larger again.

Dot slash calculator.

And I'm just going to keep saying yes, but faster this time. The sequence is

exactly the same. But recall that once we got into the billions, it started to

wrap to negative and then zero.

This is a lot of money now. Like longs are indeed longer. And I could do this

probably all day long.

Oh, interesting. No, I shouldn't have said that.

Can't do this all day long because eventually a long two will overflow. I

didn't think it was going to happen that fast.

So a long 2 will overflow because we'll need a 65th bit, but the computer has

not allocated it. So that 2 becomes an issue of overflow.

To read an excerpt, like these are very real world issues. And in fact, here's a

photograph of a Boeing.

787 years ago that actually had issues beyond the most recent issues with

airplanes, whereby after 248 days, the Boeing 787 years ago can lose all

of its electrical power due to the generator control unit simultaneously

into failsafe mode, whatever that means.

But if you dig into this, it turns out that there was a software counter in

these airplanes years ago that would overflow after 248 days of continuous

power.

248 days, why?

Well, Boeing was using a 32 -bit integer, and they were using it to

tenths of seconds.

And it turns out if you do the math, after 248 days, you have used too many

tenths such that you overflow the size of a 32 -bit integer. The plane would

essentially have this integer, this tiny, stupid little variable overflow.

But generally speaking, when your numbers suddenly go negative or zero,

things happen. The plane could literally lose its power mid -flight or on the

ground. And if you can believe it, anyone want to guess what Boeing's

was till they fixed the actual software?

What's that?

Not even.

Reboot the plane.

Like, they were told every few days, certainly every 248 days, turn the power

off, turn it back on, which stupidly is what all of us have been told for years

with our Macs and PCs and phones. Why?

Because sometimes, because of bugs in software, computers get into funky

which is a colloquial way of saying, like, some programmer made a mistake,

some counter overflowed, or some condition wasn't handled, and just

unexpected things happen.

So rebooting just resets all of your variables back to their original values

sort of gives you more time. more runway, in this case, no pun intended.

There are others. In fact, one of the most famous ones from the 1980s was the

original Pac -Man game. Only had support for 255 levels.

Why? They were using 8 bits.

Recall that 8 bits gives you 256.

But if you start counting at 0, you can only go to 255. So the crazy kids who

were so good at Pac -Man that they got to level 256, the makers of Pac -Man did

not anticipate that anyone was going to win that many levels. And just weird

stuff happened on the screen. All of the fruit sort of started overwriting

everything because they didn't have enough memory allocated to the level.

did they have a condition that says, if level equals equals 255, you win.

Like, there was just nothing handling that corner case, so to speak. So these

things abound even these days.

Thankfully, in some languages, There are better solutions where you can use big

integers. And you'll just use 64, maybe 128, maybe 256 bits. But you need to use

a language or a library that allows you to grow and shrink the amount of memory

being used. And many, if not most, languages do not do that for us.

So there's a few final problems to see that we've been taking for granted thus

far. And they also involve...

numbers, and memory.

So let's go back into our calculator.

Let's throw away all of this meme code here.

And instead, let's go ahead and do something simple again.

int x equals get int and prompt the user for a variable x. int y equals get int,

prompt the user for a variable y.

And this time, instead of addition, instead of doubling, let's do division.

So printf, quote unquote, percent i, backslash n, and then plug in.

x divided by y. So you use a single forward slash for division.

Let me go ahead and make calculator down here, dot slash calculator.

And let's go ahead and do 1 divided by 3, which should in fact be, well, it's

not really 0, right? It's like 0 .333.

Let's try this again. How about dot slash calculator? 3 divided by 2 should

.5. Nope. Computer thinks it's 1.

Well, what's happening here? Well, it turns out when you're using integers in

program, you are vulnerable to what's called truncation.

An integer plus an integer gives you an integer. An integer divided by an

integer, funny enough, gives you an integer.

So even if the answer is supposed to be 0 .333 or 1 .5, everything in the world

of integers throws away the decimal point onward, and you only get the

part of the value. So it's not even rounding.

It's truncating everything after the decimal.

So this program is just not correct. But there are solutions, potentially.

For instance, if I go back into my code here and I use a different format code

we haven't used yet. We had s for string, i for int. There's also f for

And a float was Like a real number, something with a decimal point in it by

definition. We just haven't used it yet. I could tell the computer to print this

as a float. So let me do make calculator again.

And now, hmm, it's specifying type double. There's an error here.

The problem is that I can't just tell the computer to format this number as a

float. I need to convert.

the number x divided by y to a float.

And I can do this in a couple of ways. One, I could literally change all of

to floats and just avoid the problem altogether.

Use float, use get float, use %f, and I'm done.

But if I want to use ints for whatever reason, because I want the user to type

in integers, but I want to show them real numbers with decimal points for

correct math, I can do what's called casting a value.

I can, in parentheses, which is a weird new use of parentheses, I can say, hey,

computer, please treat the following integer as a float instead, thereby

avoiding truncation. Do not truncate for me. So if I now run make calculator

again. dot slash calculator, and type in, for instance, 1 for x, 3 for y, now

get an actual floating point value.

I'm formatting it as such, and I'm telling the computer to actually

arithmetically calculate it as such as well.

But here, too, I'm kind of cheating you of a reality.

It turns out, let me clear this screen here, and it turns out that there are

fancy ways in printf to tell it how many digits to show you, how many

significant digits.

And the syntax is very weird. I have to look it up constantly. But instead of

just saying percent f, you literally put some numbers in between there. And you

say 0 .5.

And that will say, it's weird syntax, hey, printf, format this to five digits

instead. So let me go ahead and do make calculator again, dot slash calculator.

And let's do 1 divided by 3. And indeed, I get 5.

significant digits there. But suppose I get a little crazy and I want 50

significant digits.

Well, according to grade school, I should just see more like threes. But

this. Make calculator dot slash calculator.

And it turns out that whoever taught you grade school math was kind of telling

you some white lies. Because if you really do it with a powerful Mac or PC

phone, one third is actually 0 .33333334326744079.

Who's right?

Mr. and Mrs. So -and -so from grade school or like the internet?

What's going on here?

What explains this? It all comes down somehow to weak zeros, zeros, and ones.

Why is this floating point number imprecise, so to speak?

What's the intuition? Yeah.

Yes, similar in spirit.

Just as ints only use 32 bits, floats also use only 32 bits. If you want more,

just as int has long, floats have something called double. So I could kind

avoid some of the problem by switching to double, but that's still going to be

finite. And if you think about this intuitively, if you're using a finite

of bits, be it 32 or 64, you can only represent literally so many patterns and

thus so many floating point values, so many real numbers. But how many real

numbers are there in the world?

Like literally infinitely many is the challenge of real numbers. You can just

keep adding numbers after the digits. So how could a computer, Mac PC or

otherwise, possibly represent every floating point value super precisely if

there's not enough patterns to represent every number in the world? Moreover,

the way that computers use to represent numbers sometimes do not allow them to

represent numbers so precisely. We can get more significant digits maybe, but

not 100 % perfection or precision.

So floating point precision too. is a fundamental problem with computers

And unless, again, you're using a specialized language or library that

understands for scientific computing the implications of overflow or

imprecision, your code will have mistakes, much like Boeing discovered,

like Pac -Man discovered as well.

And in fact, just to end on a gloom and doom note, it turns out there's another

problem like this on the horizon already.

So back in my day, everyone was really worried about the Y2K problem, the year

2000 problem. Why?

when computers were invented, most systems were using just two digits,

independent of bits, two digits to represent years.

Why? Computers came out a few decades ago.

Who would think that a computer is still going to be running decades later?

Turns out they were, especially in government and corporations and the

if you're only using two digits to represent years, And the millennium

around, and it's 1999, about to roll over, about to roll over. What comes

1999?

Well, if you're only using two digits, ideally 2000.

But if you're only using two digits, the year zero comes after the year 1999.

And the whole world, truly, you can look it up nowadays on Wikipedia, was

freaking out because there was so much old software in the world that could

had this mistake. And who knows? Planes falling out of the sky, computers

rebooting, freezing. No one really knew because this was an unhandled situation

in code.

So thankfully, the world actually got its act together. The world did not end

the year 2000, and most systems were updated in time without crazy horror

stories. But we're going to have this happen again, because it turns out Just

few years from now, at this point, computers for years have been using 32

integers to keep track of time, in the sense of what time of day it is. And the

point in time they decided years ago was, hey, everyone, let's just keep

of how many seconds have passed since January 1, 1970.

And we can relatively compute time any time thereafter.

So that's great. That gives us a lot of decades worth. But 32 bits eventually

maxes out at like 4 billion. and positive, or 2 billion if you want

positive. And it turns out if you count the number of seconds between 1970 on

up, On the day, January 19, 2038, the world might again end because all of

clocks are going to overflow.

And we're going to end up in the year zero or negative something.

Now, what's the solution there?

I mean, my god, it's the exact same thing. Like, stop using so few bits. Use

more bits. But bits and memory and computers used to be expensive.

Nowadays, storage is so much more available.

But among the things we'll discuss then is how you can throw both hardware and

software at this problem. But for now, maybe set a Google Calendar reminder for

January. January 19th, 2038, and hopefully we'll see you next week.

Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.