WEBVTT X-TIMESTAMP-MAP=LOCAL:00:00:00.000,MPEGTS:900000 00:00:00.000 --> 00:00:02.970 [MUSIC PLAYING] 00:00:50.050 --> 00:00:52.480 DAVID MALAN: All right, this is CS50. 00:00:52.480 --> 00:00:55.330 And this is week one, our second week. 00:00:55.330 --> 00:00:59.330 And today, recall that we'll focus on this other programming language called 00:00:59.330 --> 00:00:59.830 C. 00:00:59.830 --> 00:01:02.710 And we gave you a little glimpse of this last time, wherein 00:01:02.710 --> 00:01:05.140 I proposed that this code here on the screen 00:01:05.140 --> 00:01:08.620 is something that you will soon know how to program, if not already. 00:01:08.620 --> 00:01:11.350 But suffice it to say it looks quite a bit dissimilar to what 00:01:11.350 --> 00:01:14.560 we looked at last week which, of course, was Scratch, which was much more 00:01:14.560 --> 00:01:16.120 playful, much more graphical. 00:01:16.120 --> 00:01:20.680 And so allow me to disclaim right from the get go today that for most of us, 00:01:20.680 --> 00:01:22.990 today will feel like a bit of a fire hose. 00:01:22.990 --> 00:01:25.420 In fact, pictured here as an old hack from MIT, 00:01:25.420 --> 00:01:28.750 wherein some industrious seniors hooked up an actual fire hydrant 00:01:28.750 --> 00:01:30.310 to a water fountain. 00:01:30.310 --> 00:01:32.440 The saying being that getting an education from MIT 00:01:32.440 --> 00:01:35.525 is like drinking from a fire hydrant. 00:01:35.525 --> 00:01:37.150 Today will feel a little bit like that. 00:01:37.150 --> 00:01:40.270 Because this is sort of a special occasion that you don't really have 00:01:40.270 --> 00:01:42.250 occasion to describe very often. 00:01:42.250 --> 00:01:44.988 But it's one in which we're all going to learn a new language. 00:01:44.988 --> 00:01:47.030 And indeed, that's not something we do every day. 00:01:47.030 --> 00:01:49.270 And so at the first glance, it's going to look 00:01:49.270 --> 00:01:51.700 like a lot of new syntax, a lot of new ideas. 00:01:51.700 --> 00:01:55.945 And yet, allow me to reassure, that what will soon look like this, 00:01:55.945 --> 00:01:59.500 this C code here, is fundamentally the same thing 00:01:59.500 --> 00:02:03.760 that you've seen and now experimented with last week by way of Scratch. 00:02:03.760 --> 00:02:06.083 That is to say, within this other programming language 00:02:06.083 --> 00:02:09.250 C, which is more traditional, which is more text-based, more keyboard-based, 00:02:09.250 --> 00:02:13.300 we're still going to see functions, conditions, Boolean expressions, loops, 00:02:13.300 --> 00:02:14.065 and so on. 00:02:14.065 --> 00:02:15.940 They're going to all look a little different. 00:02:15.940 --> 00:02:18.130 But the ideas are the same. 00:02:18.130 --> 00:02:22.763 And so much like when walking into someone's home for the very first time 00:02:22.763 --> 00:02:25.180 and getting the lay of the land and seeing a lot of things 00:02:25.180 --> 00:02:28.180 that you haven't seen before, you typically don't care about all 00:02:28.180 --> 00:02:29.200 of those visual details. 00:02:29.200 --> 00:02:31.490 You might just simply walk forward and sit down. 00:02:31.490 --> 00:02:34.600 Similarly today, we're about to see a whole lot of details 00:02:34.600 --> 00:02:36.550 in the world of this programming language. 00:02:36.550 --> 00:02:39.160 But the goal at hand is to ignore things at first glance 00:02:39.160 --> 00:02:43.060 that we don't necessarily understand and latch onto those ideas that 00:02:43.060 --> 00:02:45.440 are familiar from last week. 00:02:45.440 --> 00:02:48.950 So how do we go about actually writing computer programs? 00:02:48.950 --> 00:02:51.290 How do we go about writing them well? 00:02:51.290 --> 00:02:55.750 And so allow me to propose that there's a few guiding lights that 00:02:55.750 --> 00:02:57.428 should guide writing of code. 00:02:57.428 --> 00:02:58.720 One, of course, is correctness. 00:02:58.720 --> 00:03:01.810 And we explored this last week, whereby the correctness of your code 00:03:01.810 --> 00:03:04.540 just speaks to does it work as intended. 00:03:04.540 --> 00:03:07.300 When you double click some icon, when you run some command, 00:03:07.300 --> 00:03:11.020 does the program that you or someone else wrote behave correctly? 00:03:11.020 --> 00:03:12.740 Does it do what it says? 00:03:12.740 --> 00:03:16.330 But there's other aspects to writing good software 00:03:16.330 --> 00:03:18.100 and writing good programs. 00:03:18.100 --> 00:03:19.450 And that has to do with design. 00:03:19.450 --> 00:03:22.070 And we alluded a little bit this last week. 00:03:22.070 --> 00:03:26.050 But with design it's more of a qualitative, a more subjective measure, 00:03:26.050 --> 00:03:28.090 just how well written your code is. 00:03:28.090 --> 00:03:31.750 So imagine, for instance, from taking a class where you have to write essays, 00:03:31.750 --> 00:03:34.720 you could certainly make very correct arguments. 00:03:34.720 --> 00:03:37.810 But you could make very correct arguments by writing very long, 00:03:37.810 --> 00:03:41.800 rambling sentences, repeating yourself, and generally not writing 00:03:41.800 --> 00:03:43.420 a very good essay or paper. 00:03:43.420 --> 00:03:44.590 Now it might be correct. 00:03:44.590 --> 00:03:46.840 There's nothing in that paper for your English class, 00:03:46.840 --> 00:03:50.140 history class, or whatever it may be that you said that was incorrect. 00:03:50.140 --> 00:03:52.000 But you might not get very good marks on it, 00:03:52.000 --> 00:03:54.078 because it's just not very well-designed. 00:03:54.078 --> 00:03:55.870 And so similarly, in the programming world, 00:03:55.870 --> 00:03:59.320 is there this notion of actually writing not only correct code, 00:03:59.320 --> 00:04:00.940 but well-designed code. 00:04:00.940 --> 00:04:02.740 Wherein you don't repeat yourself. 00:04:02.740 --> 00:04:04.600 You write code that's fairly efficient. 00:04:04.600 --> 00:04:08.960 It doesn't do more work than it actually needs to. 00:04:08.960 --> 00:04:12.340 And then lastly, let me propose for today onward in this class, 00:04:12.340 --> 00:04:15.070 that there's a third axis you should keep in mind when 00:04:15.070 --> 00:04:17.019 it comes to writing good code. 00:04:17.019 --> 00:04:18.550 And that has to do with style. 00:04:18.550 --> 00:04:20.380 This is much more of an aesthetic. 00:04:20.380 --> 00:04:23.260 So this, in the analogous world of writing an essay, 00:04:23.260 --> 00:04:26.770 would be are using good punctuation, capitalisation? 00:04:26.770 --> 00:04:28.450 Are you indenting new paragraphs? 00:04:28.450 --> 00:04:30.760 And those kinds of aesthetics that fundamentally 00:04:30.760 --> 00:04:33.430 don't change the correctness of what you're saying, 00:04:33.430 --> 00:04:37.220 don't change necessarily the quality of the arguments that you're making, 00:04:37.220 --> 00:04:41.230 but the style of your essay, much like the style of your code, 00:04:41.230 --> 00:04:44.090 makes your code much, much more readable. 00:04:44.090 --> 00:04:47.140 So when it comes to writing good code, you want it first 00:04:47.140 --> 00:04:49.840 and foremost to be correct, but also well well-designed 00:04:49.840 --> 00:04:51.550 and also well-styled. 00:04:51.550 --> 00:04:54.460 Much like, again, you would when writing an essay that you would hope 00:04:54.460 --> 00:04:59.150 would reflect well on your capabilities as well. 00:04:59.150 --> 00:05:02.603 So when it comes to writing code, like this, for instance, 00:05:02.603 --> 00:05:05.020 this first C program that someone last week proposed quite 00:05:05.020 --> 00:05:07.660 simply prints out on the screen, hello, world. 00:05:07.660 --> 00:05:09.670 Well, how do we go about writing this code? 00:05:09.670 --> 00:05:12.580 Last week we wrote code by going to Scratch.MIT.edu 00:05:12.580 --> 00:05:14.673 and then dragging and dropping puzzle pieces. 00:05:14.673 --> 00:05:16.340 Today is going to be a little different. 00:05:16.340 --> 00:05:18.550 We're going to use a different tool here on out. 00:05:18.550 --> 00:05:20.425 And we're going to use our keyboard much more 00:05:20.425 --> 00:05:22.125 than our mouse to actually program. 00:05:22.125 --> 00:05:24.250 But to do so, we're going to go ahead and introduce 00:05:24.250 --> 00:05:28.640 the first of several tools this semester, this one, known as CS50 IDE. 00:05:28.640 --> 00:05:31.780 IDE is an acronym, a term of art in programming, 00:05:31.780 --> 00:05:34.720 that stands for Integrated Development Environment. 00:05:34.720 --> 00:05:37.150 Which is just a fancy way of saying, in this context, 00:05:37.150 --> 00:05:41.780 that CS50 IDE is CS50's own web-based programming environment. 00:05:41.780 --> 00:05:44.470 And it's not specific to CS50 per se. 00:05:44.470 --> 00:05:47.760 We've simply added a number of educationally useful features 00:05:47.760 --> 00:05:52.860 on top of a third party cloud tool that anyone on the internet can use. 00:05:52.860 --> 00:05:57.233 And our own version thereof lives at this URL, ide.cs50.io. 00:05:57.233 --> 00:05:59.400 So you're welcome to follow along at that URL today. 00:05:59.400 --> 00:06:01.620 But you need not during lecture itself. 00:06:01.620 --> 00:06:04.110 But on this upcoming problem set and beyond, 00:06:04.110 --> 00:06:08.500 will you actually use and get more familiar with this tool hands on. 00:06:08.500 --> 00:06:10.930 So let me go ahead and open up this tool here. 00:06:10.930 --> 00:06:12.600 So I've already logged in in advance. 00:06:12.600 --> 00:06:17.010 And what you see here is the basic user interface that's available to you. 00:06:17.010 --> 00:06:19.650 And fortunately, there's only a couple of salient features 00:06:19.650 --> 00:06:21.270 that we need to point out right now. 00:06:21.270 --> 00:06:23.460 So at the top of the screen here, it's just 00:06:23.460 --> 00:06:27.210 a big black rectangle that in a moment is going to be filled with code. 00:06:27.210 --> 00:06:29.850 Much like using Google documents or something 00:06:29.850 --> 00:06:32.565 like that, where you can create new tabs and create new files, 00:06:32.565 --> 00:06:34.440 this is where I'm going to do my programming, 00:06:34.440 --> 00:06:35.680 along the top of the screen. 00:06:35.680 --> 00:06:37.680 And along the bottom is what we're, in a moment, 00:06:37.680 --> 00:06:39.780 going to start calling our terminal window. 00:06:39.780 --> 00:06:44.400 It's in this terminal window that I can actually run commands and ultimately 00:06:44.400 --> 00:06:46.210 run my actual code. 00:06:46.210 --> 00:06:49.380 But let's go ahead and write our very first program in this environment 00:06:49.380 --> 00:06:52.440 and realize that this tool, indeed, is not very CS50 specific. 00:06:52.440 --> 00:06:56.610 It's meant to be representative of a very common popular programming 00:06:56.610 --> 00:06:58.980 environment, where you have a so-called text editor, 00:06:58.980 --> 00:07:01.170 or tabbed windows where you can write code, 00:07:01.170 --> 00:07:03.900 and a terminal window where you can actually run commands. 00:07:03.900 --> 00:07:05.760 Ours happens to exist in the cloud. 00:07:05.760 --> 00:07:07.950 But you can alternatively program, certainly, 00:07:07.950 --> 00:07:11.040 on your own Mac, or PC, or any other device these days. 00:07:11.040 --> 00:07:13.470 But frankly, it tends to involve just a non-trivial number 00:07:13.470 --> 00:07:16.110 of technical difficulties early on, especially when we all 00:07:16.110 --> 00:07:19.000 have different versions of Mac OS and Windows and the like. 00:07:19.000 --> 00:07:22.440 So this cloud-based environment just ensures that on day zero, 00:07:22.440 --> 00:07:25.918 we can all have the same exact programming experience. 00:07:25.918 --> 00:07:27.460 So I'm going to go ahead and do this. 00:07:27.460 --> 00:07:30.430 I'm going to go ahead and go up to File and New File. 00:07:30.430 --> 00:07:33.690 And this is going to create a new tab, by default called Untitled1, 00:07:33.690 --> 00:07:34.840 not very interesting. 00:07:34.840 --> 00:07:37.200 So I'm going to now go up to File and Save. 00:07:37.200 --> 00:07:40.240 And by default, I'm going to save this file as, for instance, 00:07:40.240 --> 00:07:42.160 the name hello.c. 00:07:42.160 --> 00:07:45.180 So I want to write my very first program in this language called 00:07:45.180 --> 00:07:47.230 C. I'm going to call my file hello. 00:07:47.230 --> 00:07:50.495 But I'm going to end it in a file extension called .c. 00:07:50.495 --> 00:07:51.870 And that's indeed the convention. 00:07:51.870 --> 00:07:55.440 When writing C programs, they should end with .c. 00:07:55.440 --> 00:07:59.685 Just like Scratch programs, as you may recall, end in .sb3. 00:07:59.685 --> 00:08:02.310 So I'm going to go ahead and simply click the green button here 00:08:02.310 --> 00:08:03.360 that's called Save. 00:08:03.360 --> 00:08:06.540 Nothing is really going to change except for the name and the tab there. 00:08:06.540 --> 00:08:10.140 Now I see at top left that this tab is called hello.c. 00:08:10.140 --> 00:08:12.060 And now I can start typing anything I want. 00:08:12.060 --> 00:08:14.130 And frankly, I'm just going to type from memory 00:08:14.130 --> 00:08:17.250 the very first program we saw last week and just a moment ago. 00:08:17.250 --> 00:08:21.570 I'm going to do include stdio.h, whatever that is for now. 00:08:21.570 --> 00:08:25.530 I'm going then going to do int main(void), whatever that is for now. 00:08:25.530 --> 00:08:27.120 I'm going to use the curly brace. 00:08:27.120 --> 00:08:30.480 And then close that curly brace, so to speak, thereafter. 00:08:30.480 --> 00:08:36.659 And in here, I'm going to go ahead and do printf("hello,world") followed 00:08:36.659 --> 00:08:38.230 by a semicolon. 00:08:38.230 --> 00:08:41.027 Now that was a whole lot of text right off the top of my head. 00:08:41.027 --> 00:08:43.110 This is the kind of muscle memory that you'll soon 00:08:43.110 --> 00:08:44.402 develop when writing a program. 00:08:44.402 --> 00:08:46.290 I've, of course, done this many times before. 00:08:46.290 --> 00:08:48.600 So I was able to just do it off the top of my head. 00:08:48.600 --> 00:08:52.500 But in a moment, we'll tease apart what all of the various lines and characters 00:08:52.500 --> 00:08:54.750 that I typed actually do. 00:08:54.750 --> 00:08:57.030 But what I'd now like to do is run this program. 00:08:57.030 --> 00:09:00.990 We conjectured last week that this is just going to print hello, world. 00:09:00.990 --> 00:09:01.800 But how? 00:09:01.800 --> 00:09:04.440 Well, in the world of our Macs and PCs and phones, 00:09:04.440 --> 00:09:08.730 we would all just tap an icon if we want to actually run a program. 00:09:08.730 --> 00:09:12.000 That's not going to be the case today, because now we're 00:09:12.000 --> 00:09:14.650 in more of a traditional programming environment. 00:09:14.650 --> 00:09:17.010 The environment that we're now in requires 00:09:17.010 --> 00:09:19.000 that I use my keyboard a little bit more, 00:09:19.000 --> 00:09:22.830 or what's known as a Command Line Interface, or CLI. 00:09:22.830 --> 00:09:27.780 This is in contrast with a Graphical User Interface, or G-U-I, or GUI, 00:09:27.780 --> 00:09:31.050 which is what describes Mac OS windows, iOS, and Android. 00:09:31.050 --> 00:09:33.540 But in a command line interface, I have to do everything 00:09:33.540 --> 00:09:35.550 at a so-called command line. 00:09:35.550 --> 00:09:38.340 And by that, I'm referring to this blinking 00:09:38.340 --> 00:09:41.080 prompt along the bottom of my screen. 00:09:41.080 --> 00:09:43.080 Along the bottom of my screen here, again, I 00:09:43.080 --> 00:09:46.380 described as the terminal window, where I'm going to type commands, 00:09:46.380 --> 00:09:48.630 and this is my command line interface. 00:09:48.630 --> 00:09:52.000 Anything I type here is going to get sent to this computer 00:09:52.000 --> 00:09:55.510 and hopefully execute on its own hardware. 00:09:55.510 --> 00:09:57.670 So how do I do this? 00:09:57.670 --> 00:09:58.960 And what do I do? 00:09:58.960 --> 00:10:04.140 Well, the catch, of course, is that when writing code in C or Python 00:10:04.140 --> 00:10:07.320 or Java or bunches of other languages that happen to exist, 00:10:07.320 --> 00:10:11.400 that's really meant to be written and understood by me and you, the humans. 00:10:11.400 --> 00:10:14.220 But per last week, what is the only language, 00:10:14.220 --> 00:10:16.140 in a sense, that computers understand? 00:10:16.140 --> 00:10:18.420 Brian, could we call on someone for this? 00:10:18.420 --> 00:10:23.730 What language do computers only speak? 00:10:23.730 --> 00:10:26.790 Because I think there's a disconnect between where we left off last week 00:10:26.790 --> 00:10:31.270 and where we're currently at if I'm writing code that now looks like this. 00:10:31.270 --> 00:10:35.100 Cindy, what language do computers speak, would you say? 00:10:35.100 --> 00:10:36.007 AUDIENCE: Binary. 00:10:36.007 --> 00:10:36.840 DAVID MALAN: Binary. 00:10:36.840 --> 00:10:38.173 And just elaborate a little bit. 00:10:38.173 --> 00:10:39.977 What do you mean by binary, to recap? 00:10:39.977 --> 00:10:40.560 AUDIENCE: Yes. 00:10:40.560 --> 00:10:43.825 So they use 1's and 0's to represent everything. 00:10:43.825 --> 00:10:44.700 DAVID MALAN: Exactly. 00:10:44.700 --> 00:10:46.830 They use 1's and 0's to represent everything. 00:10:46.830 --> 00:10:51.090 And last week we focused on only things like numbers and letters 00:10:51.090 --> 00:10:54.220 and colors and images and videos and sound and so forth. 00:10:54.220 --> 00:10:58.410 But we didn't actually speak to built in functionality, which computers also 00:10:58.410 --> 00:11:00.600 use 0's and 1's to represent. 00:11:00.600 --> 00:11:04.260 That is to say computers, of course, have the ability these days to print 00:11:04.260 --> 00:11:06.120 something on the screen. 00:11:06.120 --> 00:11:10.470 And that notion of printing, that function, that functionality, 00:11:10.470 --> 00:11:13.780 also is represented underneath the hood of a computer, so to speak, 00:11:13.780 --> 00:11:15.720 by some pattern of 0's and 1's. 00:11:15.720 --> 00:11:18.510 Which is to say that everything I just typed, 00:11:18.510 --> 00:11:21.000 even though it kind of sort of looks like English 00:11:21.000 --> 00:11:25.920 and kind of sort of clearly says print hello, world, the computer, ironically, 00:11:25.920 --> 00:11:28.620 does not know what it is I have just typed. 00:11:28.620 --> 00:11:30.750 In order for it to understand what I've just typed, 00:11:30.750 --> 00:11:33.610 I need to actually convert it to 0's and 1's. 00:11:33.610 --> 00:11:35.790 And so, indeed, the next step in this process 00:11:35.790 --> 00:11:39.930 is to take what I'll describe as my source code, written here in C, 00:11:39.930 --> 00:11:42.690 and last week, too, we saw source code, it was just graphical. 00:11:42.690 --> 00:11:44.305 It was those puzzle pieces in Scratch. 00:11:44.305 --> 00:11:47.430 This is my source code that, even though cryptic, is something I, at least, 00:11:47.430 --> 00:11:49.710 the human, eventually can read and write. 00:11:49.710 --> 00:11:53.370 But I need to literally convert it to patterns of 0's and 1's 00:11:53.370 --> 00:11:54.960 that the computer can understand. 00:11:54.960 --> 00:11:56.320 Now how do I get to this point? 00:11:56.320 --> 00:11:58.680 Well, thankfully, we have a mental model from last week 00:11:58.680 --> 00:12:00.330 that involves problem solving. 00:12:00.330 --> 00:12:01.330 And here's a problem. 00:12:01.330 --> 00:12:04.650 How do I take source code, written in this language supposedly called C, 00:12:04.650 --> 00:12:08.010 and convert it to 0's and 1's that the computer understands? 00:12:08.010 --> 00:12:10.980 Well, my input, I daresay, is going to be my source code. 00:12:10.980 --> 00:12:16.440 And my output, ideally, is going to be what we'll call machine code. 00:12:16.440 --> 00:12:19.230 Machine code is just a term of art describing the 0's 00:12:19.230 --> 00:12:21.150 and 1's that computers understand. 00:12:21.150 --> 00:12:23.100 We didn't use that expression last week. 00:12:23.100 --> 00:12:27.480 But this just refers to 0's and 1's on the right and C code on the left. 00:12:27.480 --> 00:12:31.690 So that invites the question, well, what is between my source code and machine 00:12:31.690 --> 00:12:32.190 code? 00:12:32.190 --> 00:12:36.030 If I take my source code and feed it into the proverbial black box, 00:12:36.030 --> 00:12:39.810 how do I get out of this black box the 0's and 1's that the computer 00:12:39.810 --> 00:12:40.470 understands? 00:12:40.470 --> 00:12:42.270 Well, I need a special program that we're 00:12:42.270 --> 00:12:44.220 going to start calling a compiler. 00:12:44.220 --> 00:12:47.460 A compiler is a program that you can download for free, 00:12:47.460 --> 00:12:50.760 or pay for back in the day, that is a program designed 00:12:50.760 --> 00:12:53.410 to convert source code to machine code. 00:12:53.410 --> 00:12:55.860 So all I need do if I want to actually solve 00:12:55.860 --> 00:13:01.140 the problem as stated earlier, whereby I have written this code in C 00:13:01.140 --> 00:13:03.600 and I now need to convert it to 0's and 1's, I just 00:13:03.600 --> 00:13:06.180 need to give myself access to a compiler. 00:13:06.180 --> 00:13:09.570 And it turns out one of those exists within CS50 IDE. 00:13:09.570 --> 00:13:13.230 And this is a tool you could download on your own Mac or PC or the like. 00:13:13.230 --> 00:13:16.680 And for now, we're going to describe that tool as being quite simply called 00:13:16.680 --> 00:13:17.770 "make." 00:13:17.770 --> 00:13:20.250 Literally, if I want to make my program, I'm 00:13:20.250 --> 00:13:22.198 going to go ahead and type make hello. 00:13:22.198 --> 00:13:24.990 And then I'm going to run it with a little bit of a cryptic syntax, 00:13:24.990 --> 00:13:26.820 ./hello. 00:13:26.820 --> 00:13:29.760 But let's see that in action to tie this all together. 00:13:29.760 --> 00:13:32.970 I'm going to move my cursor down into my terminal window, 00:13:32.970 --> 00:13:34.590 or my command line interface. 00:13:34.590 --> 00:13:36.360 And I'm going to literally type hello. 00:13:36.360 --> 00:13:39.450 Notice I am not typing make hello.c. 00:13:39.450 --> 00:13:42.600 I'm typing the name of the program I actually want to make 00:13:42.600 --> 00:13:45.090 and I just want to call this program hello. 00:13:45.090 --> 00:13:48.570 The compiler is going to infer from this command 00:13:48.570 --> 00:13:51.960 that I actually intend to compile a file called hello.c. 00:13:51.960 --> 00:13:53.460 I'm going to go ahead and hit Enter. 00:13:53.460 --> 00:13:55.140 There's some crazy cryptic output. 00:13:55.140 --> 00:13:56.610 More on that another day. 00:13:56.610 --> 00:13:59.790 But the fact that I don't see any big scary red error messages 00:13:59.790 --> 00:14:00.750 is a good thing. 00:14:00.750 --> 00:14:03.570 This means that my program compiled successfully. 00:14:03.570 --> 00:14:04.170 Why? 00:14:04.170 --> 00:14:07.680 There's just no yellow or red messages to say otherwise. 00:14:07.680 --> 00:14:10.410 But now, if I want to actually run this program, 00:14:10.410 --> 00:14:13.170 I need to type a different command that's the analog of double 00:14:13.170 --> 00:14:15.660 clicking an icon on your Mac or PC or phone. 00:14:15.660 --> 00:14:18.990 I'm going to type literally ./hello. 00:14:18.990 --> 00:14:23.550 ./hello essentially is like saying go into the current folder on the computer 00:14:23.550 --> 00:14:26.190 I'm using and look for a program called hello. 00:14:26.190 --> 00:14:30.540 I'm going to go ahead and hit Enter and voila, hello, world. 00:14:30.540 --> 00:14:34.133 Now I see, again, a dollar sign and some other text on the screen. 00:14:34.133 --> 00:14:36.300 And we'll tease apart in just a bit what this means. 00:14:36.300 --> 00:14:39.930 But notice, this dollar sign is just a constant visual reminder 00:14:39.930 --> 00:14:43.888 of where my prompt is, where I can type more commands. 00:14:43.888 --> 00:14:45.930 And the computer has done literally what I asked. 00:14:45.930 --> 00:14:47.340 It printed out hello, world. 00:14:47.340 --> 00:14:49.590 And now it's waiting for my second command. 00:14:49.590 --> 00:14:53.520 So that was the analog of just printing hello, world out of the cat's mouth 00:14:53.520 --> 00:14:54.510 last week. 00:14:54.510 --> 00:14:56.490 But surely we can do more than this. 00:14:56.490 --> 00:14:59.530 But let's tie it back to what we did last week as well. 00:14:59.530 --> 00:15:02.610 So that not everything here is all that dissimilar. 00:15:02.610 --> 00:15:04.758 So recall that last week, we had functions. 00:15:04.758 --> 00:15:07.800 And it turns out we had something called arguments, even though we didn't 00:15:07.800 --> 00:15:09.610 necessarily describe them as such. 00:15:09.610 --> 00:15:12.070 So a function is like a mini-program. 00:15:12.070 --> 00:15:14.580 It's an action or a verb that you can use when writing 00:15:14.580 --> 00:15:16.560 your own program that does something. 00:15:16.560 --> 00:15:18.600 We saw the say block last week. 00:15:18.600 --> 00:15:20.370 We saw the wait block last week. 00:15:20.370 --> 00:15:23.730 Those were verbs, or actions, or more generally noticed functions. 00:15:23.730 --> 00:15:27.390 But functions can also take inputs, recall, and we did see that last week. 00:15:27.390 --> 00:15:31.860 And nowadays, we're going to start calling inputs to functions arguments, 00:15:31.860 --> 00:15:32.680 so to speak. 00:15:32.680 --> 00:15:34.860 Another term for them is parameters. 00:15:34.860 --> 00:15:37.380 But for all intents and purposes, those are synonyms. 00:15:37.380 --> 00:15:39.490 Arguments are the inputs to functions. 00:15:39.490 --> 00:15:41.490 So let's consider then, from last week, the say 00:15:41.490 --> 00:15:45.750 block that we saw last time, which simply is trying to say out 00:15:45.750 --> 00:15:47.430 of the cat's mouth, hello, world. 00:15:47.430 --> 00:15:51.480 Well, let me go ahead and convert this, if you will, to corresponding C code, 00:15:51.480 --> 00:15:55.800 just to emphasize how similar, fundamentally, these two languages 00:15:55.800 --> 00:16:00.120 are, even though syntactically C absolutely looks visually different. 00:16:00.120 --> 00:16:03.540 It turns out that if you want to say something in C, 00:16:03.540 --> 00:16:06.070 using this text-based language like I just did, 00:16:06.070 --> 00:16:07.320 you're not going to write say. 00:16:07.320 --> 00:16:08.940 You're instead going to write print. 00:16:08.940 --> 00:16:10.320 That's actually a bit of a white lie. 00:16:10.320 --> 00:16:11.280 You're not going to say print. 00:16:11.280 --> 00:16:14.197 You're actually going to say printf, for reasons we'll eventually see. 00:16:14.197 --> 00:16:17.050 It means print a formatted something or other. 00:16:17.050 --> 00:16:20.580 So printf is the analog in C of say in Scratch. 00:16:20.580 --> 00:16:23.190 Now notice in C, I've got this open parenthesis 00:16:23.190 --> 00:16:26.500 and closed parenthesis that, nicely enough, are kind of ovular in shape. 00:16:26.500 --> 00:16:28.950 And notice that they kind of mimic the white oval 00:16:28.950 --> 00:16:31.480 into which we provided input last week. 00:16:31.480 --> 00:16:33.690 So in between those parentheses are going 00:16:33.690 --> 00:16:37.932 to be my inputs to this function printf, otherwise known as arguments. 00:16:37.932 --> 00:16:40.140 But they're going to be a little different this week. 00:16:40.140 --> 00:16:43.080 Yes, I'm going to say hello, world, with a comma in between, 00:16:43.080 --> 00:16:44.790 grammatically, just like last week. 00:16:44.790 --> 00:16:47.940 But in the world of C, I have to be a little more particular. 00:16:47.940 --> 00:16:51.450 I also have to add double quotes on the left and the right. 00:16:51.450 --> 00:16:55.440 And, somewhat annoyingly, I also have to add a semicolon 00:16:55.440 --> 00:16:56.773 at the end of this line of code. 00:16:56.773 --> 00:16:59.107 So just like in English, or in a lot of human languages, 00:16:59.107 --> 00:17:01.200 you end a sentence, for instance, with a period, 00:17:01.200 --> 00:17:04.470 in many lines of code you will write in C 00:17:04.470 --> 00:17:08.650 you've also got to finish your thought, in this case, with a semicolon. 00:17:08.650 --> 00:17:11.369 So this, then, on the right, is the closest way 00:17:11.369 --> 00:17:16.557 of translating this thing on the left from Scratch to C respectively. 00:17:16.557 --> 00:17:17.890 So the ideas are still the same. 00:17:17.890 --> 00:17:19.410 But the syntax looks a little different. 00:17:19.410 --> 00:17:21.702 And we've just got to ingrain in ourselves, ultimately, 00:17:21.702 --> 00:17:24.660 what these patterns are and what these human conventions are. 00:17:24.660 --> 00:17:28.990 But notice that what we just did follows the same paradigm as last week. 00:17:28.990 --> 00:17:31.660 But let's add a little more terminology this week. 00:17:31.660 --> 00:17:35.250 Last week, we described the black box as potentially being algorithms, 00:17:35.250 --> 00:17:36.060 initially. 00:17:36.060 --> 00:17:38.050 And then we started calling them functions. 00:17:38.050 --> 00:17:42.780 Functions are just a programmed version of an algorithm, the implementation 00:17:42.780 --> 00:17:45.390 of an algorithm in code, in software. 00:17:45.390 --> 00:17:49.050 So a function might be represented here as taking inputs otherwise known now 00:17:49.050 --> 00:17:50.430 as arguments. 00:17:50.430 --> 00:17:54.540 But it turns out that functions can do at least two different types of things 00:17:54.540 --> 00:17:55.893 in the world of programming. 00:17:55.893 --> 00:17:58.560 And we've seen these things already, but we didn't describe them 00:17:58.560 --> 00:18:00.780 quite as particularly as we will today. 00:18:00.780 --> 00:18:04.290 When a function takes inputs, that is to say arguments, 00:18:04.290 --> 00:18:08.670 just like hello, world is an input to the say block in Scratch 00:18:08.670 --> 00:18:14.070 or the printf function in C, functions can have what are called side effects. 00:18:14.070 --> 00:18:16.110 And recall, we did see this last time. 00:18:16.110 --> 00:18:20.010 When we used the say block, it did output something. 00:18:20.010 --> 00:18:23.640 But more technically, it had a side effect, a visual side effect. 00:18:23.640 --> 00:18:27.450 When I used the say block last week and the printf function this week, 00:18:27.450 --> 00:18:29.160 you see something on the screen. 00:18:29.160 --> 00:18:31.080 And that is, yes, some form of output. 00:18:31.080 --> 00:18:34.140 But it's a little different from a different form of output 00:18:34.140 --> 00:18:35.070 that we saw last time. 00:18:35.070 --> 00:18:38.760 So a side effect of a function is often something visual 00:18:38.760 --> 00:18:43.048 that happens on the screen, like text or audio in that case. 00:18:43.048 --> 00:18:45.840 But there's this other feature of functions that we're going to see 00:18:45.840 --> 00:18:49.620 and leverage today known as return values, where a function can really 00:18:49.620 --> 00:18:51.340 just hand you back a value. 00:18:51.340 --> 00:18:53.100 It's not going to say it on the screen. 00:18:53.100 --> 00:18:55.440 It's not going to vocalize it audibly. 00:18:55.440 --> 00:18:58.680 It's going to just pass it back to you in a way that you, the programmer, 00:18:58.680 --> 00:19:01.530 can reuse whatever the output of that function 00:19:01.530 --> 00:19:03.940 was, ideally storing it even in a variable. 00:19:03.940 --> 00:19:07.110 So for instance, recall last week that we asked the human 00:19:07.110 --> 00:19:09.390 their name by way of this ask block. 00:19:09.390 --> 00:19:13.020 And the input to the ask block in this white oval was, what's your name. 00:19:13.020 --> 00:19:17.130 And then recall that this ask block was a little special last week. 00:19:17.130 --> 00:19:21.900 Because it gave us access to whatever the human ultimately typed in. 00:19:21.900 --> 00:19:27.660 And that is to say that the ask block last week essentially returned a value. 00:19:27.660 --> 00:19:32.790 It didn't just blindly display whatever word the human typed in on the screen. 00:19:32.790 --> 00:19:36.420 No, it instead returned it in some sense metaphorically 00:19:36.420 --> 00:19:39.798 and stored it in a special variable called answer. 00:19:39.798 --> 00:19:41.340 And so, again, that's the difference. 00:19:41.340 --> 00:19:44.040 The say block literally says something on the screen. 00:19:44.040 --> 00:19:46.110 And there's an immediate visual effect. 00:19:46.110 --> 00:19:48.900 With the ask block, after you type in your name, 00:19:48.900 --> 00:19:53.340 you don't see your name printed or displayed again on the screen. 00:19:53.340 --> 00:19:56.010 Instead, your name is sort of tucked away in a variable, 00:19:56.010 --> 00:20:00.240 just like a mathematician would store a number in a variable like x or y or z. 00:20:00.240 --> 00:20:02.610 The onus was then on us, the programmer, last week 00:20:02.610 --> 00:20:07.320 to eventually do something with the value, my name, that 00:20:07.320 --> 00:20:09.610 was in that variable called answer. 00:20:09.610 --> 00:20:13.140 So how are we going to translate last week's ask block to C this week? 00:20:13.140 --> 00:20:16.140 Well, it turns out there's different ways to do this in C, none of which 00:20:16.140 --> 00:20:20.020 are very easy unless you use what's called a library. 00:20:20.020 --> 00:20:22.495 A library is code that someone else has written. 00:20:22.495 --> 00:20:24.370 And indeed, one of the things we'll use today 00:20:24.370 --> 00:20:28.480 is the so-called CS50 library, which is a bunch of code, not terribly much, 00:20:28.480 --> 00:20:32.560 that the staff and I wrote just to make it easier to do simple things. 00:20:32.560 --> 00:20:35.470 These are training wheels of sorts that we'll take off completely 00:20:35.470 --> 00:20:36.702 within a few weeks' time. 00:20:36.702 --> 00:20:38.410 But in order to get started quickly, it's 00:20:38.410 --> 00:20:41.690 going to make it easier to do things like getting text from the user. 00:20:41.690 --> 00:20:44.530 So string is a term of art in the programming world. 00:20:44.530 --> 00:20:46.810 A string is text. 00:20:46.810 --> 00:20:47.710 It's a word. 00:20:47.710 --> 00:20:48.310 It's a letter. 00:20:48.310 --> 00:20:49.400 It's a paragraph. 00:20:49.400 --> 00:20:50.330 It's a page of text. 00:20:50.330 --> 00:20:52.150 It's just text in some form. 00:20:52.150 --> 00:20:55.210 String is what a computer scientist would call text. 00:20:55.210 --> 00:20:58.150 get_string is a function that we wrote that we will 00:20:58.150 --> 00:21:00.340 provide to you that does take inputs. 00:21:00.340 --> 00:21:03.610 Notice, per the parentheses here in C, it can take input. 00:21:03.610 --> 00:21:05.110 What might that input be? 00:21:05.110 --> 00:21:06.910 Well, just like the ask block, it's going 00:21:06.910 --> 00:21:09.910 to be a prompt that the human should ultimately see. 00:21:09.910 --> 00:21:14.200 So there's a bit more involved, though, than just using this function. 00:21:14.200 --> 00:21:18.730 When you use get_string in C, as we will soon see in a live demo, 00:21:18.730 --> 00:21:20.910 you want to do something with the human's name. 00:21:20.910 --> 00:21:22.660 And to do something with the human's name, 00:21:22.660 --> 00:21:25.180 it's not quite sufficient to just trust that Scratch 00:21:25.180 --> 00:21:27.200 will put it in a variable for you. 00:21:27.200 --> 00:21:31.450 In C, as with most programming languages, it's a lot more pedantic. 00:21:31.450 --> 00:21:33.760 Like, if you want something to end up in a variable, 00:21:33.760 --> 00:21:35.100 you've got to do it yourself. 00:21:35.100 --> 00:21:38.650 MIT is not going to magically put it in an answer variable for you. 00:21:38.650 --> 00:21:40.040 You have to do it yourself. 00:21:40.040 --> 00:21:44.290 So to do this, you simply come up with the name of the variable that you want, 00:21:44.290 --> 00:21:48.220 be it x or y or z, or more compellingly, answer, 00:21:48.220 --> 00:21:50.980 and you use an equal sign, a single equal sign. 00:21:50.980 --> 00:21:55.870 And even though in math this generally implies equality, in the context of C, 00:21:55.870 --> 00:21:59.110 and most programming languages, the equal sign actually 00:21:59.110 --> 00:22:01.030 means what we'll call assignment. 00:22:01.030 --> 00:22:04.720 It means, effectively, copy whatever is on the right 00:22:04.720 --> 00:22:07.130 into whatever's on the left. 00:22:07.130 --> 00:22:10.150 So if on the right-hand side there's a function whose purpose in life 00:22:10.150 --> 00:22:13.540 is to ask the human what their name is, that name 00:22:13.540 --> 00:22:16.570 is going to get copied from right to left ultimately 00:22:16.570 --> 00:22:18.790 into this variable called answer. 00:22:18.790 --> 00:22:21.550 MIT did that automatically for us in Scratch. 00:22:21.550 --> 00:22:24.500 In C, you have to do it yourself. 00:22:24.500 --> 00:22:26.650 But you have to be a little more particular, too. 00:22:26.650 --> 00:22:30.280 It turns out that in the world of C, you can't just have variables. 00:22:30.280 --> 00:22:34.090 You have to tell the computer in advance what type of variable you want. 00:22:34.090 --> 00:22:38.050 And specifically, I'm going to tell the computer that the type of variable 00:22:38.050 --> 00:22:39.820 I want is going to be a string. 00:22:39.820 --> 00:22:43.840 And the convention for doing so is you literally write the name of the type 00:22:43.840 --> 00:22:47.170 that you want, string being the only one we've seen thus far. 00:22:47.170 --> 00:22:49.180 Then you write the name of the variable. 00:22:49.180 --> 00:22:53.810 And then, again, to assign a value to that variable from right to left, 00:22:53.810 --> 00:22:56.710 we have to use the single equal sign here. 00:22:56.710 --> 00:22:58.450 And now, just a quick pause. 00:22:58.450 --> 00:23:00.430 Brian, if we could call on someone for this, 00:23:00.430 --> 00:23:03.490 even if you've never programmed before, if you've taken to heart 00:23:03.490 --> 00:23:06.040 one of my pieces of advice earlier. 00:23:06.040 --> 00:23:08.110 I'm still missing something. 00:23:08.110 --> 00:23:11.710 How might I want to finish the translation of this Scratch code 00:23:11.710 --> 00:23:13.370 to C on the right-hand side? 00:23:13.370 --> 00:23:16.368 What is missing from what you can tell? 00:23:16.368 --> 00:23:18.910 If you've programmed before, odds are it will jump right out. 00:23:18.910 --> 00:23:20.500 If you've never programmed before, you'll 00:23:20.500 --> 00:23:22.250 have to think back on what I said earlier. 00:23:22.250 --> 00:23:23.920 Jacob, what do you think? 00:23:23.920 --> 00:23:24.995 AUDIENCE: Semicolon? 00:23:24.995 --> 00:23:25.870 DAVID MALAN: Exactly. 00:23:25.870 --> 00:23:28.960 There's just one single, stupid semicolon 00:23:28.960 --> 00:23:32.980 missing at the end of the line, which is necessary to make clear to the computer 00:23:32.980 --> 00:23:34.810 that this is the end of this thought. 00:23:34.810 --> 00:23:36.533 And I sort of impugn it as stupid. 00:23:36.533 --> 00:23:39.700 Because honestly, one of the biggest frustrations when learning how to code, 00:23:39.700 --> 00:23:42.730 as will now happen today and this week and beyond, 00:23:42.730 --> 00:23:46.510 is initially you're going to forget stupid things like the semicolon, 00:23:46.510 --> 00:23:49.570 or you're going to forget a single quote mark, or a parenthesis, 00:23:49.570 --> 00:23:50.540 or things like this. 00:23:50.540 --> 00:23:52.780 And the most important advice I can give today 00:23:52.780 --> 00:23:57.010 is just try not to get frustrated by those kinds of stupid things. 00:23:57.010 --> 00:23:58.880 It's a lot more interesting. 00:23:58.880 --> 00:24:01.900 It's a lot more useful in life to understand functions and loops 00:24:01.900 --> 00:24:04.600 and conditions and not to let yourself get frustrated 00:24:04.600 --> 00:24:08.870 by the more minor aesthetic things that honestly will just come with practice. 00:24:08.870 --> 00:24:11.890 So if the very first mistake you make is missing a semicolon, 00:24:11.890 --> 00:24:14.650 and it takes you 10 minutes, an hour to figure out what 00:24:14.650 --> 00:24:16.900 is wrong with your code, totally normal. 00:24:16.900 --> 00:24:21.670 And those frustrations go away quite quickly in time. 00:24:21.670 --> 00:24:25.330 So we then have this translation of one function to another. 00:24:25.330 --> 00:24:27.550 Where else can we take it from here? 00:24:27.550 --> 00:24:29.590 Well, let's take a look at one other translation 00:24:29.590 --> 00:24:31.600 that we used after that ask block. 00:24:31.600 --> 00:24:34.120 Last week, after we asked the human their name, 00:24:34.120 --> 00:24:37.630 as by providing an input to the function and getting some output, 00:24:37.630 --> 00:24:44.050 we then proceeded to do something with the return value or output of ask. 00:24:44.050 --> 00:24:46.030 Again, we asked the human their name. 00:24:46.030 --> 00:24:50.810 Scratch magically, last week, put the name into the answer variable. 00:24:50.810 --> 00:24:52.520 But then I did something with it. 00:24:52.520 --> 00:24:56.710 And this is what I mean to distinguish side effects, which just kind of happen 00:24:56.710 --> 00:24:58.900 to you, like something printing on the screen, 00:24:58.900 --> 00:25:04.400 like the cat saying something out of its mouth, versus a return value, 00:25:04.400 --> 00:25:07.780 which is a piece of information, like a name a human has typed 00:25:07.780 --> 00:25:13.310 in being stored somewhere where you, the programmer, can make use of it later. 00:25:13.310 --> 00:25:14.410 It's not happening to you. 00:25:14.410 --> 00:25:16.840 It's being handed to you for subsequent use. 00:25:16.840 --> 00:25:20.650 And last week, in order to say hello comma world all in one breath, 00:25:20.650 --> 00:25:23.560 so to speak, we kind of had to stack these puzzle pieces 00:25:23.560 --> 00:25:27.700 on top of one another, making the output of join the input of say. 00:25:27.700 --> 00:25:31.810 In C, this is actually a little easier even though it's some new syntax. 00:25:31.810 --> 00:25:34.450 Again, printf is going to be the analog for say. 00:25:34.450 --> 00:25:36.660 And we've seen that a moment ago. 00:25:36.660 --> 00:25:38.410 We're still going to have the parentheses. 00:25:38.410 --> 00:25:40.077 We're still going to have the semicolon. 00:25:40.077 --> 00:25:42.040 So what goes inside now the input? 00:25:42.040 --> 00:25:46.120 How do I provide hello, answer to C? 00:25:46.120 --> 00:25:50.500 Well, I'm going to go ahead and do hello, in double quotes, but then, 00:25:50.500 --> 00:25:54.670 this strange new syntax here, %s. 00:25:54.670 --> 00:25:59.170 This is what we're going to call a format code, a format code, and hence 00:25:59.170 --> 00:26:01.125 the f in printf. 00:26:01.125 --> 00:26:02.500 Printf doesn't just print things. 00:26:02.500 --> 00:26:04.880 It can print format codes as well. 00:26:04.880 --> 00:26:09.880 And this is just fancy syntax for saying plug in some actual value here. 00:26:09.880 --> 00:26:12.010 Don't print out s literally. 00:26:12.010 --> 00:26:16.143 This is a placeholder for what will be s, a string. 00:26:16.143 --> 00:26:17.560 Well, what do I want to put there? 00:26:17.560 --> 00:26:18.700 Here's something new, too. 00:26:18.700 --> 00:26:21.250 In Scratch, if you had two inputs to a function, 00:26:21.250 --> 00:26:24.010 you would have two ovals like this and this one 00:26:24.010 --> 00:26:28.060 here that you could either type words or numbers into or drag variables into. 00:26:28.060 --> 00:26:31.660 In C, there's no notion of ovals or graphics at all. 00:26:31.660 --> 00:26:34.900 So instead, we're just going to go old school and just use a comma. 00:26:34.900 --> 00:26:39.580 If you use a comma in between the parentheses as the arguments 00:26:39.580 --> 00:26:43.030 or inputs to a function, that's going to separate the one on the left 00:26:43.030 --> 00:26:45.970 from the one on the right, thereby being analogous to having 00:26:45.970 --> 00:26:48.400 two ovals in the world of Scratch now there's 00:26:48.400 --> 00:26:51.220 something that's potentially a little visually confusing here. 00:26:51.220 --> 00:26:54.980 There's actually two commas here, of course, and here. 00:26:54.980 --> 00:26:56.560 But notice the important detail. 00:26:56.560 --> 00:26:59.710 That first one, that's an English grammatical comma 00:26:59.710 --> 00:27:04.900 that I've put inside of my quoted string, my quoted phrase of text. 00:27:04.900 --> 00:27:06.817 That has nothing to do with programming. 00:27:06.817 --> 00:27:08.650 That just has everything to do with English. 00:27:08.650 --> 00:27:11.440 The fact that this comma is outside of those double quotes, 00:27:11.440 --> 00:27:14.620 though, means it's significant in this language called C. 00:27:14.620 --> 00:27:18.710 And it separates first argument from second argument. 00:27:18.710 --> 00:27:20.770 And so in this way do we have the ability now 00:27:20.770 --> 00:27:28.260 to also say something on the screen using printf in this slightly new way. 00:27:28.260 --> 00:27:31.900 So let me go ahead then and do this for real. 00:27:31.900 --> 00:27:34.930 Let me go back to CS50 IDE. 00:27:34.930 --> 00:27:37.780 And I'm going to go ahead and go back into this program 00:27:37.780 --> 00:27:39.970 here and consider for just a moment how we 00:27:39.970 --> 00:27:43.780 can improve upon this very first program which literally just prints 00:27:43.780 --> 00:27:44.500 hello, world. 00:27:44.500 --> 00:27:45.487 Not that interesting. 00:27:45.487 --> 00:27:46.570 I can run it all day long. 00:27:46.570 --> 00:27:48.170 It's going to say the same thing. 00:27:48.170 --> 00:27:50.710 How do I now get input from the user? 00:27:50.710 --> 00:27:55.040 Well, it turns out that I can simply enhance this code a little bit. 00:27:55.040 --> 00:27:59.290 Let me go ahead and per the translation of Scratch earlier, 00:27:59.290 --> 00:28:05.650 let me do something like string answer equals get_string("What's your name?"). 00:28:08.320 --> 00:28:11.380 So I'm literally typing out what we saw in C a moment ago. 00:28:11.380 --> 00:28:13.940 I'm going to remember my semicolon over here. 00:28:13.940 --> 00:28:17.630 And then I have to change this second line of code now to not say hello, 00:28:17.630 --> 00:28:21.350 world, but instead to say hello, %s. 00:28:21.350 --> 00:28:24.620 And then, outside of the double quotes, I'm going to do a comma 00:28:24.620 --> 00:28:28.070 and then provide literally the word answer, which 00:28:28.070 --> 00:28:29.750 is the name of that variable. 00:28:29.750 --> 00:28:30.953 But I'm not quite done. 00:28:30.953 --> 00:28:32.120 And this is a little subtle. 00:28:32.120 --> 00:28:34.385 And invariably, you'll forget this at some point, too. 00:28:34.385 --> 00:28:37.610 In order to use get_string, I have to use this thing 00:28:37.610 --> 00:28:40.730 called the CS50 library, code that the staff wrote 00:28:40.730 --> 00:28:42.470 that you don't have default access to. 00:28:42.470 --> 00:28:45.230 And in order to do that, I need to add one line of code 00:28:45.230 --> 00:28:47.400 that we'll explain in more detail in a little bit. 00:28:47.400 --> 00:28:51.230 But for now, just take it on faith that by adding this line of code 00:28:51.230 --> 00:28:55.370 at the very top, include CS50.h, that will now 00:28:55.370 --> 00:28:59.360 give me access to the get_string function, which I otherwise 00:28:59.360 --> 00:29:00.412 wouldn't have access to. 00:29:00.412 --> 00:29:02.870 All right, now I'm going to go back to the terminal window. 00:29:02.870 --> 00:29:04.370 And notice the dichotomy here. 00:29:04.370 --> 00:29:07.502 If I just run ./hello, sort of enthusiastically, 00:29:07.502 --> 00:29:08.960 let's see what my new program does. 00:29:08.960 --> 00:29:11.522 I'm about to be, unfortunately, disappointed. 00:29:11.522 --> 00:29:12.980 Because it still says hello, world. 00:29:12.980 --> 00:29:15.770 And you might realize intuitively what the problem, of course, 00:29:15.770 --> 00:29:19.512 here is I haven't actually recompiled to the code. 00:29:19.512 --> 00:29:21.470 And so any time you make a change to your code, 00:29:21.470 --> 00:29:25.370 it does not suffice to just save the file via file save or Control 00:29:25.370 --> 00:29:27.770 or Command-s, I need to recompile it. 00:29:27.770 --> 00:29:30.540 And to recompile my code, that's not such a big deal. 00:29:30.540 --> 00:29:33.170 I just type make hello, enter. 00:29:33.170 --> 00:29:36.050 Cross my fingers that there's no yellow or red scary text. 00:29:36.050 --> 00:29:37.430 This is all good. 00:29:37.430 --> 00:29:40.010 It seems to have compiled into machine code. 00:29:40.010 --> 00:29:42.860 Now I can retype ./hello. 00:29:42.860 --> 00:29:43.790 and enter. 00:29:43.790 --> 00:29:46.400 And you'll see now my program is running and waiting for me. 00:29:46.400 --> 00:29:50.182 Let me go ahead and type my name, David enter hello, David. 00:29:50.182 --> 00:29:52.640 Let me go ahead and run it again after clearing the screen. 00:29:52.640 --> 00:29:53.473 Let me run it again. 00:29:53.473 --> 00:29:55.520 And this time, let's say my name is Brian. 00:29:55.520 --> 00:29:57.508 And I say hello, Brian. 00:29:57.508 --> 00:29:59.300 So quite similar to what we did in Scratch, 00:29:59.300 --> 00:30:05.690 but now we're more powerfully doing this all thus far via my keyboard alone. 00:30:05.690 --> 00:30:07.490 All right, so that was a lot. 00:30:07.490 --> 00:30:10.190 We wrote hello, world super quickly off the top of my memory 00:30:10.190 --> 00:30:12.650 and then enhanced it to now take input from the user. 00:30:12.650 --> 00:30:13.940 Let me pause here. 00:30:13.940 --> 00:30:16.160 If there are any questions, you're welcome to ask 00:30:16.160 --> 00:30:18.950 via chat for either staff or classmates to answer. 00:30:18.950 --> 00:30:22.430 But if you'd like to raise your virtual hand in Zoom, 00:30:22.430 --> 00:30:28.990 please feel free so that I can clarify or expound on anything here. 00:30:28.990 --> 00:30:31.235 Yeah, question from Ryan? 00:30:31.235 --> 00:30:32.860 AUDIENCE: I had asked this in the chat. 00:30:32.860 --> 00:30:37.460 But so the string before the answer, that's not the name of the variable. 00:30:37.460 --> 00:30:44.360 So hypothetically, you could make it, like, string A or string anything else. 00:30:44.360 --> 00:30:47.375 It just matters what comes after string is the name of the variable? 00:30:47.375 --> 00:30:48.250 DAVID MALAN: Exactly. 00:30:48.250 --> 00:30:49.180 Really good question. 00:30:49.180 --> 00:30:52.390 In the world of Scratch, you were required 00:30:52.390 --> 00:30:54.310 to use the variable called "answer." 00:30:54.310 --> 00:30:57.980 In C, we have the complete flexibility over what we want to do. 00:30:57.980 --> 00:31:02.652 So as Ryan proposed, I could change my variable's name to just A for short. 00:31:02.652 --> 00:31:04.360 I would have to change it elsewhere, too, 00:31:04.360 --> 00:31:06.970 to make clear that the variable being used 00:31:06.970 --> 00:31:08.560 is the same one by a different name. 00:31:08.560 --> 00:31:09.760 That's perfectly fine. 00:31:09.760 --> 00:31:15.280 But here's where we now get into a matter of better style. 00:31:15.280 --> 00:31:19.390 Having a variable called just A, it doesn't really lend itself 00:31:19.390 --> 00:31:20.780 to the readability of your code. 00:31:20.780 --> 00:31:22.572 I might now glance at my code and be, like, 00:31:22.572 --> 00:31:24.850 what is the variable A. It's a little better when 00:31:24.850 --> 00:31:27.910 it comes to writing good code to actually be more verbose 00:31:27.910 --> 00:31:31.120 and using an actual word like "answer" in this case. 00:31:31.120 --> 00:31:34.030 Indeed, even though I keep describing x and y and z as the go 00:31:34.030 --> 00:31:36.160 to variables for a mathematician, those really 00:31:36.160 --> 00:31:39.200 say nothing outside the context of a Cartesian plane. 00:31:39.200 --> 00:31:42.880 So in a program that you write in C or Scratch or anything else, 00:31:42.880 --> 00:31:48.280 using descriptive variable names is a matter of good style as well. 00:31:48.280 --> 00:31:49.665 Jonathan, over to you. 00:31:49.665 --> 00:31:50.290 AUDIENCE: Yeah. 00:31:50.290 --> 00:31:51.290 Just a quick question. 00:31:51.290 --> 00:31:54.640 How come we have to compile the code every single time? 00:31:54.640 --> 00:31:57.310 And unlike different IDEs, which if you just run the code, 00:31:57.310 --> 00:31:59.020 it automatically compiles. 00:31:59.020 --> 00:32:00.470 Why do we have to manually do it? 00:32:00.470 --> 00:32:00.950 DAVID MALAN: Yeah. 00:32:00.950 --> 00:32:01.875 Really good question. 00:32:01.875 --> 00:32:03.750 Why do you have to keep recompiling the code? 00:32:03.750 --> 00:32:07.990 The short answer is just because this is the way C is. 00:32:07.990 --> 00:32:10.600 It's an older language, decades now old. 00:32:10.600 --> 00:32:13.300 And so back then, everything was very deliberate. 00:32:13.300 --> 00:32:15.370 User interface was not the top priority. 00:32:15.370 --> 00:32:17.750 Performance instead was, for instance. 00:32:17.750 --> 00:32:21.340 And so nowadays, there are fancier integrated development environments. 00:32:21.340 --> 00:32:25.510 And some of you might have used things like codecademy online, or co.org, 00:32:25.510 --> 00:32:28.450 where there's very often literally a play button that you can just 00:32:28.450 --> 00:32:31.300 click in the user interface, and it just plays your program 00:32:31.300 --> 00:32:32.665 or runs your program. 00:32:32.665 --> 00:32:34.540 What we're doing in this class is showing you 00:32:34.540 --> 00:32:36.320 what those buttons are doing. 00:32:36.320 --> 00:32:39.880 So if you do use in an environment like that that seems to automate this, 00:32:39.880 --> 00:32:40.755 it's still happening. 00:32:40.755 --> 00:32:43.463 But for our purposes, certainly at the beginning of the semester, 00:32:43.463 --> 00:32:45.400 we're going to do it manually ourselves. 00:32:45.400 --> 00:32:48.275 Later in the term, when we introduce a different language altogether, 00:32:48.275 --> 00:32:51.110 for instance, Python, then kind of, sort of you 00:32:51.110 --> 00:32:55.150 don't need to compile anymore, but more on that in a few weeks. 00:32:55.150 --> 00:32:56.050 Good question. 00:32:56.050 --> 00:32:56.920 Sophia? 00:32:56.920 --> 00:32:57.933 Over to you. 00:32:57.933 --> 00:32:59.350 AUDIENCE: I had a question about-- 00:32:59.350 --> 00:33:01.058 I noticed in the source code that there's 00:33:01.058 --> 00:33:04.390 a backslash like n at the end of the string. 00:33:04.390 --> 00:33:07.503 Is that necessary for every time, even if it's just one line? 00:33:07.503 --> 00:33:08.920 DAVID MALAN: Really good question. 00:33:08.920 --> 00:33:12.310 This backslash n that you're seeing elsewhere, a bit of a spoiler. 00:33:12.310 --> 00:33:15.370 But yeah, let's go ahead and fix this problem that we've seen, 00:33:15.370 --> 00:33:16.990 even though I'm kind of ignoring it. 00:33:16.990 --> 00:33:18.893 You know, this now gets a little particular. 00:33:18.893 --> 00:33:20.560 But this looks kind of stupid, honestly. 00:33:20.560 --> 00:33:23.620 It says hello, Brian tilde slash dollar sign. 00:33:23.620 --> 00:33:25.630 Like, that is not my intended output. 00:33:25.630 --> 00:33:28.900 I literally only wanted to say hello, Brian, or hello, David. 00:33:28.900 --> 00:33:32.995 This visual artifact here, the dollar sign and the tilde and the slash 00:33:32.995 --> 00:33:36.015 have to do with my terminal window, this command line environment 00:33:36.015 --> 00:33:36.640 that I'm using. 00:33:36.640 --> 00:33:38.890 And honestly, just to be a little nitpicky, 00:33:38.890 --> 00:33:40.870 frankly, it should probably be on a new line. 00:33:40.870 --> 00:33:45.190 It should just be on its own line so it's not confused with my own output. 00:33:45.190 --> 00:33:48.260 And as Sophie notes, there is a solution to this. 00:33:48.260 --> 00:33:51.910 But, again, per last week, you need to m when writing algorithms 00:33:51.910 --> 00:33:54.610 and in turn, code, you have to be super precise. 00:33:54.610 --> 00:33:57.640 Nowhere in my code have I told the computer 00:33:57.640 --> 00:33:59.950 to move the cursor to the next line. 00:33:59.950 --> 00:34:07.540 So I can do that explicitly by doing backslash n immediately after the %s 00:34:07.540 --> 00:34:09.980 but still inside of the double quotes. 00:34:09.980 --> 00:34:13.900 This is shorthand notation for what would be telling the computer, 00:34:13.900 --> 00:34:15.860 move the cursor to the next line. 00:34:15.860 --> 00:34:19.100 Now you might think that, well, why don't I just hit Enter like this? 00:34:19.100 --> 00:34:23.199 And even though this is all might be new to most of us, suffice it to say 00:34:23.199 --> 00:34:25.510 this just feels like it's going to get messy quickly. 00:34:25.510 --> 00:34:27.909 If you start hitting Enter in the middle of your code, 00:34:27.909 --> 00:34:29.659 that's probably not the right solution. 00:34:29.659 --> 00:34:32.320 So instead, programmers years ago decided 00:34:32.320 --> 00:34:35.590 to come up with shorthand notation like backslash n, otherwise known 00:34:35.590 --> 00:34:41.800 as an escape character that signals to the computer, put a new line here. 00:34:41.800 --> 00:34:43.780 So backslash n is new line. 00:34:43.780 --> 00:34:45.489 And let me go ahead and recompile this. 00:34:45.489 --> 00:34:50.230 After saving my file, let me go ahead and do make hello. 00:34:50.230 --> 00:34:52.210 It seems to compile OK. ./hello. 00:34:52.210 --> 00:34:54.400 And let me go ahead and type in Brian's name again. 00:34:54.400 --> 00:34:58.010 And voila, still the same output, but it's a little cleaner. 00:34:58.010 --> 00:35:00.880 So we're being a little bit better about housekeeping now. 00:35:00.880 --> 00:35:03.580 Really good question. 00:35:03.580 --> 00:35:06.207 BJ is it? 00:35:06.207 --> 00:35:06.790 AUDIENCE: Yes. 00:35:06.790 --> 00:35:09.610 So one question I had is why don't you have 00:35:09.610 --> 00:35:13.930 to call the function get string in order for you for it to ask for input? 00:35:13.930 --> 00:35:17.485 Like, it still asked your input when you assigned it to the variable answer. 00:35:17.485 --> 00:35:19.068 DAVID MALAN: Ah, really good question. 00:35:19.068 --> 00:35:21.310 Why don't I have to call get string, for instance, 00:35:21.310 --> 00:35:23.680 by putting it on a line of its own? 00:35:23.680 --> 00:35:28.150 The way that C and a lot of programming languages work is they 00:35:28.150 --> 00:35:31.150 will evaluate an entire line of code, for instance, 00:35:31.150 --> 00:35:36.370 what I have here on line six from right to left, at least in this context. 00:35:36.370 --> 00:35:39.730 When you have an equal sign in the code like I do here, 00:35:39.730 --> 00:35:43.000 that's telling the computer you first have to execute, 00:35:43.000 --> 00:35:45.640 that is do what is said on the right-hand side. 00:35:45.640 --> 00:35:47.800 And then whatever the output of that thing is, 00:35:47.800 --> 00:35:49.880 store it on the left-hand side. 00:35:49.880 --> 00:35:53.470 So it is indeed getting executed, we're just now spreading things out 00:35:53.470 --> 00:35:57.560 on longer lines of code, if you will, if that makes sense. 00:35:57.560 --> 00:36:02.800 So get string is getting executed because it appears on that line. 00:36:02.800 --> 00:36:03.310 All right. 00:36:03.310 --> 00:36:05.230 So we've been taking for granted, frankly, 00:36:05.230 --> 00:36:08.110 a few details of these programs that it's probably 00:36:08.110 --> 00:36:09.790 only fair to start teasing apart. 00:36:09.790 --> 00:36:11.740 For instance, there was that int, main, void, 00:36:11.740 --> 00:36:13.210 and a whole bunch of other syntax. 00:36:13.210 --> 00:36:15.730 So let's tease apart some of these other lines of code 00:36:15.730 --> 00:36:18.760 that I just typed off the top of my head from memory, but kind of do 00:36:18.760 --> 00:36:21.143 need to be there in every C program you write. 00:36:21.143 --> 00:36:23.560 Let's at least start to make sense of some of that detail. 00:36:23.560 --> 00:36:27.250 Recall that in Scratch, we always started our programs initially 00:36:27.250 --> 00:36:29.320 with when green flag clicked. 00:36:29.320 --> 00:36:34.000 We eventually saw some other puzzle pieces, like when you hear an event, 00:36:34.000 --> 00:36:36.160 or when there's camera motion. 00:36:36.160 --> 00:36:40.330 But this really kick started most of the programs that we wrote in Scratch. 00:36:40.330 --> 00:36:45.340 What is the analog in C of the when green flag clicked puzzle piece? 00:36:45.340 --> 00:36:46.540 It's essentially this. 00:36:46.540 --> 00:36:49.120 We won't spend time in detail today explaining 00:36:49.120 --> 00:36:53.170 why it's int, why it's void, why there's curly braces, why there's parentheses. 00:36:53.170 --> 00:36:55.870 For today's purposes only, let me just stipulate 00:36:55.870 --> 00:37:00.160 that this is the analog for this when green flag clicked puzzle piece. 00:37:00.160 --> 00:37:02.260 You've just got to start your programs initially 00:37:02.260 --> 00:37:04.750 with this kind of boilerplate code, so to speak. 00:37:04.750 --> 00:37:07.092 We will start to explain this in much more detail. 00:37:07.092 --> 00:37:08.800 But for now, just take on faith that this 00:37:08.800 --> 00:37:10.630 is how you start writing a program. 00:37:10.630 --> 00:37:14.260 But there's, of course, a little more to the programs we've written thus far. 00:37:14.260 --> 00:37:17.780 And particularly, we've seen a couple of things called header files. 00:37:17.780 --> 00:37:22.480 This is another term of art that refers to a file written in the language 00:37:22.480 --> 00:37:27.580 called C whose name ends with not .c, but with .h. 00:37:27.580 --> 00:37:30.740 So we've seen these before as follows. 00:37:30.740 --> 00:37:33.910 Here, recall, was the simplest program we wrote last week in Scratch. 00:37:33.910 --> 00:37:37.030 It just says hello, world when you clicked on the green flag. 00:37:37.030 --> 00:37:40.270 This is the analog, the more complete analog on the right, 00:37:40.270 --> 00:37:42.190 of that program today. 00:37:42.190 --> 00:37:43.540 But there's something missing. 00:37:43.540 --> 00:37:45.950 And it's probably jumping out at some of you, 00:37:45.950 --> 00:37:48.850 because the program is a little shorter than it was before. 00:37:48.850 --> 00:37:51.170 Something's missing, which is this line here. 00:37:51.170 --> 00:37:54.490 And I just wrote that from memory earlier, but it's referring to a file 00:37:54.490 --> 00:38:00.760 called stdio.h, which stands for standard input output dot h. 00:38:00.760 --> 00:38:03.190 So io is an acronym in the computer world 00:38:03.190 --> 00:38:05.360 that just generally refers to input and output. 00:38:05.360 --> 00:38:10.150 So standard io.h is just a very popular file 00:38:10.150 --> 00:38:12.910 that is used in C programs that gives you the ability 00:38:12.910 --> 00:38:15.370 to get input and output from the user. 00:38:15.370 --> 00:38:17.502 And it does so by providing you with printf, 00:38:17.502 --> 00:38:19.210 for instance, which of course, allows you 00:38:19.210 --> 00:38:22.270 to generate some form of output via those side effects 00:38:22.270 --> 00:38:23.770 that we described earlier. 00:38:23.770 --> 00:38:25.780 But when I wrote my other program, recall, 00:38:25.780 --> 00:38:28.630 that actually had get string, as BJ noted earlier, 00:38:28.630 --> 00:38:31.270 where I can get a line of text from the user, 00:38:31.270 --> 00:38:33.130 I needed something else altogether. 00:38:33.130 --> 00:38:37.570 And that's when we added, a moment ago, a second header file called CS50.h. 00:38:37.570 --> 00:38:41.770 So these header files just give you access to more functions 00:38:41.770 --> 00:38:45.590 than you might automatically get from the language you're using, 00:38:45.590 --> 00:38:46.840 which here is C. 00:38:46.840 --> 00:38:48.880 It's similar in spirit, recall last week, 00:38:48.880 --> 00:38:51.850 when I started poking around Scratch's extension menu 00:38:51.850 --> 00:38:55.420 and I used the translate block and the voice block, 00:38:55.420 --> 00:38:59.230 the sort of fancier features that were buried under the extensions menu. 00:38:59.230 --> 00:39:04.240 Using an extension in Scratch is similar to using a header file in C. 00:39:04.240 --> 00:39:08.140 It's giving me access to a bit more functionality than you otherwise get 00:39:08.140 --> 00:39:12.320 for free out of the box, so to speak. 00:39:12.320 --> 00:39:14.680 All right, well, let me go ahead and propose 00:39:14.680 --> 00:39:17.740 that there are so many different ways in which I 00:39:17.740 --> 00:39:22.240 could have screwed up over the past few minutes of writing these programs. 00:39:22.240 --> 00:39:24.790 I might have omitted a semicolon, as I implied. 00:39:24.790 --> 00:39:26.650 I might have not closed my quotes. 00:39:26.650 --> 00:39:28.450 I might have gotten my parentheses wrong. 00:39:28.450 --> 00:39:30.430 I might have misspelled words altogether. 00:39:30.430 --> 00:39:33.340 There's many different ways I could have screwed that program up. 00:39:33.340 --> 00:39:36.673 And frankly, off the record, I'm sort of crossing my fingers that I didn't screw 00:39:36.673 --> 00:39:38.230 up our very first program together. 00:39:38.230 --> 00:39:41.950 But invariably, at some point, maybe not your first program, 00:39:41.950 --> 00:39:46.000 but early on in learning how to program or learning how to program in C, 00:39:46.000 --> 00:39:47.050 you will screw up. 00:39:47.050 --> 00:39:48.730 And you're going to make some typo. 00:39:48.730 --> 00:39:51.758 There's going to be some disconnect between what your understanding is 00:39:51.758 --> 00:39:53.800 and what you're trying to get the computer to do. 00:39:53.800 --> 00:39:56.710 And this is to say there are tools, thankfully, 00:39:56.710 --> 00:39:59.260 that can help you solve those problems. 00:39:59.260 --> 00:40:01.060 And the first of which is called help50. 00:40:01.060 --> 00:40:04.150 Any of the tools whose names end with 50 are specifically 00:40:04.150 --> 00:40:07.930 educationally oriented, written by CS50 staff, that are temporary training 00:40:07.930 --> 00:40:10.520 wheels that we'll use for the first several weeks of the class 00:40:10.520 --> 00:40:13.360 but then eventually, optionally, take away in the sense 00:40:13.360 --> 00:40:15.470 that you won't need them anymore. 00:40:15.470 --> 00:40:17.620 And so help50 is one command that's going 00:40:17.620 --> 00:40:20.920 to allow you to troubleshoot problems that you might not otherwise 00:40:20.920 --> 00:40:24.020 see obviously in your own code. 00:40:24.020 --> 00:40:27.440 And let me go and simulate this as follows. 00:40:27.440 --> 00:40:29.980 Let me go back to the very first program that we 00:40:29.980 --> 00:40:34.583 wrote in C, which was quite simply this one whereby it only said hello, world. 00:40:34.583 --> 00:40:37.250 And there's a few different places I could have screwed up here. 00:40:37.250 --> 00:40:39.940 For instance, suppose I was getting a little ahead of myself 00:40:39.940 --> 00:40:45.250 and I admitted the standard io.h file at the top of my program. 00:40:45.250 --> 00:40:48.820 The implication is that now my computer is not 00:40:48.820 --> 00:40:54.370 going to know what printf is, because it hasn't been included via standard io.h. 00:40:54.370 --> 00:40:56.530 So let's see what the error message is. 00:40:56.530 --> 00:40:58.810 Hopefully, it'll be a very self-explanatory message 00:40:58.810 --> 00:41:00.260 that makes perfect sense. 00:41:00.260 --> 00:41:02.260 Let me go ahead and recompile this program, 00:41:02.260 --> 00:41:04.300 knowing it already to be incorrect. 00:41:04.300 --> 00:41:05.320 And oh, my God. 00:41:05.320 --> 00:41:10.310 Like, I have more lines of errors than I actually have lines of code. 00:41:10.310 --> 00:41:15.010 And this is kind of a reality of programming. 00:41:15.010 --> 00:41:17.410 A lot of programming languages, a lot of tools, 00:41:17.410 --> 00:41:20.470 frankly, were not designed with ease of use in mind, 00:41:20.470 --> 00:41:22.120 or user-friendliness in mind. 00:41:22.120 --> 00:41:25.150 They were really designed with succinctness and precision in mind. 00:41:25.150 --> 00:41:28.420 And they tend, unfortunately, to assume that the audience is 00:41:28.420 --> 00:41:30.702 as technical as the person who wrote the program. 00:41:30.702 --> 00:41:33.160 This, of course, can backfire when you're just learning how 00:41:33.160 --> 00:41:34.952 to program in the first place, and you have 00:41:34.952 --> 00:41:37.810 to make sense of crazy cryptic output like this. 00:41:37.810 --> 00:41:40.570 Today we don't have to focus on every single word that's 00:41:40.570 --> 00:41:43.600 been outputted on the screen, but let's start to recognize patterns. 00:41:43.600 --> 00:41:45.670 Walking into a new space and just recognizing 00:41:45.670 --> 00:41:49.120 familiar objects in the physical world, let's now do that with code. 00:41:49.120 --> 00:41:53.740 The most important thing, perhaps, to take notice of is that when you mess up 00:41:53.740 --> 00:41:56.980 and you make some mistake in your code such that your program doesn't even 00:41:56.980 --> 00:41:59.650 compile from source code into machine code, 00:41:59.650 --> 00:42:03.520 odds are you're going to see a clue toward the top of the erroneous output 00:42:03.520 --> 00:42:05.890 that tells you the name of the file where you messed up 00:42:05.890 --> 00:42:07.990 and the line number where you messed up. 00:42:07.990 --> 00:42:11.350 Three implying line three, and then five might 00:42:11.350 --> 00:42:14.530 imply what column or what character in that line, 00:42:14.530 --> 00:42:17.900 but it depends on the particular problem if that's that useful. 00:42:17.900 --> 00:42:22.510 So on line three, I am getting an error, implicitly declaring library function 00:42:22.510 --> 00:42:25.090 printf with type int const char star. 00:42:25.090 --> 00:42:27.550 I mean, like, who knows what that even means? 00:42:27.550 --> 00:42:29.060 You will eventually. 00:42:29.060 --> 00:42:31.780 But for today, it just means something bad went wrong. 00:42:31.780 --> 00:42:32.980 And you might not see it. 00:42:32.980 --> 00:42:35.050 You might not know, if I hadn't told you, 00:42:35.050 --> 00:42:37.135 that I intentionally deleted that line. 00:42:37.135 --> 00:42:39.760 So let's see if we can't make sense of this by using this tool. 00:42:39.760 --> 00:42:42.820 Help50 is a tool written by CS50 staff that 00:42:42.820 --> 00:42:46.570 will help translate arcane cryptic computer 00:42:46.570 --> 00:42:51.010 messages to more human friendly advice and questions 00:42:51.010 --> 00:42:54.070 that you're teaching fellow or teaching assistant might offer you, 00:42:54.070 --> 00:42:56.030 say, in the context of office hours. 00:42:56.030 --> 00:42:59.740 So to use help50, instead of running the same command again and again 00:42:59.740 --> 00:43:03.130 and seeing the same erroneous output, literally just right help50 00:43:03.130 --> 00:43:07.960 first, at your terminal window, then write the same exact command 00:43:07.960 --> 00:43:11.320 that you're struggling with for whatever reason, and hit Enter then. 00:43:11.320 --> 00:43:14.110 And what will happen is the same command will get run. 00:43:14.110 --> 00:43:18.340 We will analyze, using the help50 program, what that output is. 00:43:18.340 --> 00:43:20.950 And we'll try to highlight in yellow the stuff we recognize. 00:43:20.950 --> 00:43:23.290 And then translate it to more human friendly language. 00:43:23.290 --> 00:43:27.460 For instance, after running help50, we're asking for help, dot dot dot. 00:43:27.460 --> 00:43:29.170 In yellow here is the thing we recognize, 00:43:29.170 --> 00:43:31.660 oh, the staff have seen this problem before. 00:43:31.660 --> 00:43:36.700 And then down here, did you forget to include stdio.h, in which printf 00:43:36.700 --> 00:43:38.710 is declared atop of your file? 00:43:38.710 --> 00:43:41.440 So hopefully, if we recognize the problem, 00:43:41.440 --> 00:43:43.690 we can guide you with this sort of rhetorical question 00:43:43.690 --> 00:43:45.250 that makes you realize, oh, yes. 00:43:45.250 --> 00:43:46.640 That's what I did wrong. 00:43:46.640 --> 00:43:50.380 So now I can go back up here, move to the top of my file, 00:43:50.380 --> 00:43:53.980 and add include stdio.h. 00:43:53.980 --> 00:43:59.373 And now notice, if I rerun make hello, voila, the problem is gone altogether. 00:43:59.373 --> 00:44:00.790 And we could do this all day long. 00:44:00.790 --> 00:44:02.207 There's so many places to mess up. 00:44:02.207 --> 00:44:04.120 For instance, I omit the semicolon now. 00:44:04.120 --> 00:44:06.910 Let me go ahead and make hello now without the semicolon. 00:44:06.910 --> 00:44:09.050 Now we're going to get a different error message. 00:44:09.050 --> 00:44:12.610 And you'll see, again, the name of the file where I messed up, hello.c. 00:44:12.610 --> 00:44:14.680 This time it's on line five. 00:44:14.680 --> 00:44:16.990 And that's true because the line numbers moved down 00:44:16.990 --> 00:44:18.640 after I added more stuff up there. 00:44:18.640 --> 00:44:21.637 And you can see expected semicolon after expression. 00:44:21.637 --> 00:44:23.470 So this one's a little more straightforward. 00:44:23.470 --> 00:44:25.210 But you could run help50 on this command, 00:44:25.210 --> 00:44:29.050 too, just to get back a little more explicit advice. 00:44:29.050 --> 00:44:31.960 So help50 will be your friend any time you 00:44:31.960 --> 00:44:36.220 are having trouble getting your code to actually compile. 00:44:36.220 --> 00:44:39.010 Well, let me do something else that's bad now. 00:44:39.010 --> 00:44:43.060 I've very deliberately been writing fairly pretty code. 00:44:43.060 --> 00:44:45.130 I've indented the word printf. 00:44:45.130 --> 00:44:47.320 I included some blank line up here. 00:44:47.320 --> 00:44:49.700 Just to make it clear, I've put these curly braces, 00:44:49.700 --> 00:44:51.520 so to speak, on their own lines. 00:44:51.520 --> 00:44:56.080 But frankly, my computer, or CS50 IDE is not so particular. 00:44:56.080 --> 00:44:58.570 I could technically get rid of this blank line. 00:44:58.570 --> 00:45:00.580 I could move this curly brace way up here. 00:45:00.580 --> 00:45:04.660 I could get rid of this indentation altogether and move it on its own line. 00:45:04.660 --> 00:45:07.000 And then I could just move this curly brace up here. 00:45:07.000 --> 00:45:12.340 Thereby writing a program that's now only two lines long, not six. 00:45:12.340 --> 00:45:15.040 But hopefully already, even if you've never programmed before, 00:45:15.040 --> 00:45:17.620 this should probably rub you the wrong way. 00:45:17.620 --> 00:45:19.510 This is like people in the real world that 00:45:19.510 --> 00:45:21.910 don't use punctuation in their social media posts 00:45:21.910 --> 00:45:23.500 or their emails or the text messages. 00:45:23.500 --> 00:45:25.170 They just kind of go on and on and on. 00:45:25.170 --> 00:45:27.168 And yes, the information is there. 00:45:27.168 --> 00:45:29.460 You can glean what it is they're trying to communicate. 00:45:29.460 --> 00:45:31.200 But my God, is it annoying. 00:45:31.200 --> 00:45:32.630 It's hard to read. 00:45:32.630 --> 00:45:35.130 There's probably a higher probability that there's a mistake 00:45:35.130 --> 00:45:38.560 and it's going to be harder to find it because things aren't nicely balanced 00:45:38.560 --> 00:45:41.200 on the left and on the right and on the top and the bottom. 00:45:41.200 --> 00:45:43.740 So this is what would be described as bad style. 00:45:43.740 --> 00:45:45.270 My program is still correct. 00:45:45.270 --> 00:45:49.030 I've got the stdio.h, I've got the semicolon, and everything else. 00:45:49.030 --> 00:45:50.310 But it's really bad style. 00:45:50.310 --> 00:45:51.720 Because it's just ugly. 00:45:51.720 --> 00:45:53.430 There's not much white space. 00:45:53.430 --> 00:45:55.560 There's not a lot of blank lines or indentation 00:45:55.560 --> 00:46:00.190 that just make it easier for you and I to read this thing from top to bottom. 00:46:00.190 --> 00:46:02.400 So notice, it does compile. 00:46:02.400 --> 00:46:06.840 So help50 is not going to help me fix this problem because it compiles OK. 00:46:06.840 --> 00:46:11.610 But it can run another program that we're going to call style50. 00:46:11.610 --> 00:46:13.470 This is another educationally oriented tool 00:46:13.470 --> 00:46:17.610 that's installed in CS50 IDE that allows you to figure out 00:46:17.610 --> 00:46:19.810 how to improve the style of your code. 00:46:19.810 --> 00:46:24.760 So when I run style50 on this prettier code, it indeed looks good. 00:46:24.760 --> 00:46:26.130 But it's still giving me advice. 00:46:26.130 --> 00:46:28.050 It's telling me to add something called comments. 00:46:28.050 --> 00:46:30.210 And a bunch of you figured this out in the world of Scratch. 00:46:30.210 --> 00:46:32.370 You can add little sticky notes or post-it notes 00:46:32.370 --> 00:46:34.530 to Scratch that are sort of notes to self 00:46:34.530 --> 00:46:38.310 that remind you what something does, or maybe explains to your teaching fellow 00:46:38.310 --> 00:46:40.170 or teaching assistant what something does. 00:46:40.170 --> 00:46:41.890 C supports these as well. 00:46:41.890 --> 00:46:45.270 So for instance, if I just wanted to be really pedantic here and make 00:46:45.270 --> 00:46:49.170 clear to the human reading my code what I'm trying to do, 00:46:49.170 --> 00:46:52.140 I could say something like greet user. 00:46:52.140 --> 00:46:53.790 And notice the syntax here. 00:46:53.790 --> 00:46:57.000 I've put a new line above my existing line of code, 00:46:57.000 --> 00:46:59.610 and I've similarly indented it so everything lines up 00:46:59.610 --> 00:47:01.260 visually beautifully. 00:47:01.260 --> 00:47:05.520 I've done slash slash, which says, hey, compiler, this is a comment. 00:47:05.520 --> 00:47:07.270 This is for human eyes only. 00:47:07.270 --> 00:47:09.690 This is not actual C code, per se. 00:47:09.690 --> 00:47:10.917 Then I hit the spacebar. 00:47:10.917 --> 00:47:12.750 And then I just typed out an English phrase. 00:47:12.750 --> 00:47:14.610 And this could be any spoken language. 00:47:14.610 --> 00:47:16.350 But I went ahead and typed greet user. 00:47:16.350 --> 00:47:16.862 Why? 00:47:16.862 --> 00:47:18.570 Well, it's just a reminder to myself what 00:47:18.570 --> 00:47:22.330 the purpose of the following line of code is, to greet the user. 00:47:22.330 --> 00:47:28.455 This is marginally better, for instance, than saying print hello, world. 00:47:28.455 --> 00:47:30.330 And let me just ask you, even if you've never 00:47:30.330 --> 00:47:34.350 programmed before why is the first comment a better 00:47:34.350 --> 00:47:36.480 comment than the second? 00:47:36.480 --> 00:47:40.650 Like, why should I say, if anything, greet user instead of print 00:47:40.650 --> 00:47:43.800 hello, world in the form of these comments. 00:47:43.800 --> 00:47:46.558 Yeah, Olivia, what do you think? 00:47:46.558 --> 00:47:47.100 AUDIENCE: OK. 00:47:47.100 --> 00:47:48.807 It tells you the purpose of the code. 00:47:48.807 --> 00:47:51.390 DAVID MALAN: Yeah, the purpose of the code as opposed to what? 00:47:51.390 --> 00:47:53.670 What distinction are you making? 00:47:53.670 --> 00:47:56.475 AUDIENCE: Versus telling you exactly what it's doing. 00:47:56.475 --> 00:47:57.600 DAVID MALAN: Yeah, exactly. 00:47:57.600 --> 00:48:00.697 If your comment is almost identical to the actual code, 00:48:00.697 --> 00:48:03.780 you're not really conveying much more information to the reader, let alone 00:48:03.780 --> 00:48:05.460 yourself in the future. 00:48:05.460 --> 00:48:09.120 Explaining it more generally, what the purpose of this line of code is to do, 00:48:09.120 --> 00:48:11.730 is to greet the user, that's a little more descriptive. 00:48:11.730 --> 00:48:14.070 Now to be super fair, honestly, this program 00:48:14.070 --> 00:48:16.650 is so short that even though style50, yes, would 00:48:16.650 --> 00:48:20.250 prefer that you add some comment, if your program really 00:48:20.250 --> 00:48:23.730 reduces to one line of code, you probably don't need a comment here. 00:48:23.730 --> 00:48:26.037 However, pretty much every other program we're 00:48:26.037 --> 00:48:28.620 going to write here on after is going to be more than just one 00:48:28.620 --> 00:48:30.690 main line of code, like this printf. 00:48:30.690 --> 00:48:32.850 So it's going to make much more sense soon 00:48:32.850 --> 00:48:36.000 to come that we're going to want to actually add 00:48:36.000 --> 00:48:38.460 to our code some actual comments. 00:48:38.460 --> 00:48:40.920 Well, let me introduce one final tool here 00:48:40.920 --> 00:48:43.260 that will help us solve problems as we proceed now 00:48:43.260 --> 00:48:45.000 to write more sophisticated programs. 00:48:45.000 --> 00:48:46.080 And this is check50. 00:48:46.080 --> 00:48:50.790 This is a tool specifically that you'll use either in labs or in problem sets, 00:48:50.790 --> 00:48:53.160 the course's programming assignments, to actually check 00:48:53.160 --> 00:48:54.910 the correctness of your code. 00:48:54.910 --> 00:48:58.530 So whereas help50 just helps you compile your code typically, 00:48:58.530 --> 00:49:01.410 when it's not compiling at all, style50 helps 00:49:01.410 --> 00:49:04.560 you improve the style of your code, check50 00:49:04.560 --> 00:49:09.060 will check the correctness of your code against some automated tests 00:49:09.060 --> 00:49:12.690 that we, the staff, have written that are consistent with whatever 00:49:12.690 --> 00:49:14.202 the homework problem actually is. 00:49:14.202 --> 00:49:17.160 So we write some tests to make sure that your code is working correctly 00:49:17.160 --> 00:49:19.200 as per our own specifications. 00:49:19.200 --> 00:49:22.080 So how might I run check50? 00:49:22.080 --> 00:49:25.440 This will totally depend on the problem set or the lab. 00:49:25.440 --> 00:49:28.170 And we will always, in the problem set or lab, 00:49:28.170 --> 00:49:30.543 tell you what command to type for check50. 00:49:30.543 --> 00:49:33.210 It's not something you could necessarily figure out on your own. 00:49:33.210 --> 00:49:35.580 I happen to remember that we have a check, that 00:49:35.580 --> 00:49:40.560 is a test, called CS50/problems/hello. 00:49:40.560 --> 00:49:42.870 Odds are you will never run this identical command. 00:49:42.870 --> 00:49:46.920 Again, in the problem set or lab, we will always tell you what to type. 00:49:46.920 --> 00:49:50.970 You won't know what otherwise to type unless we tell you what test to use. 00:49:50.970 --> 00:49:55.500 This is going to now upload my file hello.c to a service called 00:49:55.500 --> 00:49:58.050 GitHub, which again is a popular tool for sharing code. 00:49:58.050 --> 00:50:00.150 We use it to collect submissions for this. 00:50:00.150 --> 00:50:02.160 I'm going to then type in my password. 00:50:02.160 --> 00:50:02.880 You won't see it. 00:50:02.880 --> 00:50:05.940 You'll instead see asterisks or, like, bullets in a web page. 00:50:05.940 --> 00:50:07.650 I'm going to go ahead and hit Enter then. 00:50:07.650 --> 00:50:09.240 It's going to verify my code. 00:50:09.240 --> 00:50:10.560 It's going to do some thinking. 00:50:10.560 --> 00:50:13.218 It's uploading now, dot dot dot. 00:50:13.218 --> 00:50:15.840 And now we're just waiting for the internet to respond. 00:50:15.840 --> 00:50:18.390 Because somewhere on CS50 servers, we are 00:50:18.390 --> 00:50:22.980 running your code after compiling your code, or in this case mine, 00:50:22.980 --> 00:50:26.830 and making sure, yes, it actually behaved as it should have. 00:50:26.830 --> 00:50:30.060 And what you'll typically see, hopefully, are a bunch of green smiley 00:50:30.060 --> 00:50:33.990 faces saying yes, that your code exists, yes, that your code compiles, 00:50:33.990 --> 00:50:36.450 and yes, for instance, it prints hello, world. 00:50:36.450 --> 00:50:38.610 Sometimes you might see red frowny faces, 00:50:38.610 --> 00:50:42.840 which means no, your code did not work exactly as it should, per the lab, 00:50:42.840 --> 00:50:43.830 or of the problem set. 00:50:43.830 --> 00:50:47.190 At which point, it's back to the drawing board on your part to figure out 00:50:47.190 --> 00:50:49.450 exactly what needs to be fixed up here. 00:50:49.450 --> 00:50:52.830 Sometimes you'll see yellow output with just a straight yellow face, which 00:50:52.830 --> 00:50:55.710 just means we weren't even able to run a certain test 00:50:55.710 --> 00:50:57.620 because some other test already failed. 00:50:57.620 --> 00:51:00.630 So it's meant to be relatively quick feedback 00:51:00.630 --> 00:51:05.440 on the correctness of your code before you even submit it and call it a day. 00:51:05.440 --> 00:51:10.770 And check50 instructions will always be accompanied by the problem itself 00:51:10.770 --> 00:51:13.150 in the lab or problem set. 00:51:13.150 --> 00:51:15.420 So some final commands here now. 00:51:15.420 --> 00:51:21.450 Within this terminal window, I can do more than just run make and ./hello, 00:51:21.450 --> 00:51:23.220 or whatever my program's name is. 00:51:23.220 --> 00:51:26.040 And I can do more than help50 and style50 00:51:26.040 --> 00:51:30.510 and Check50 it turns out that I'm really using, in the form of CS50 IDE, 00:51:30.510 --> 00:51:32.280 my own server in the cloud. 00:51:32.280 --> 00:51:34.150 So yes, I'm using a website. 00:51:34.150 --> 00:51:37.920 But what CS50 IDE really is, it's like your own server 00:51:37.920 --> 00:51:40.080 or your own computer in the cloud. 00:51:40.080 --> 00:51:43.740 Somewhere out there on the internet, you have your own username and password 00:51:43.740 --> 00:51:45.450 in the form of CS50 IDE. 00:51:45.450 --> 00:51:49.830 And only you can access the files that you write, the programs that you 00:51:49.830 --> 00:51:51.900 write that are stored in this IDE. 00:51:51.900 --> 00:51:54.660 And there's a few more features I'll now draw our attention to. 00:51:54.660 --> 00:51:58.350 Perhaps the most friendly one is this little folder icon at top left. 00:51:58.350 --> 00:52:00.570 If I click this little folder icon, you'll 00:52:00.570 --> 00:52:03.120 now see what's generally called a file browser 00:52:03.120 --> 00:52:06.210 or a file tree, which is just a graphical representation 00:52:06.210 --> 00:52:10.680 of the files in my account, or in my IDE, in this case. 00:52:10.680 --> 00:52:12.090 It looks similar to Mac OS. 00:52:12.090 --> 00:52:13.410 It looks similar to Windows. 00:52:13.410 --> 00:52:16.860 And this is just a graphical user interface built into the IDE 00:52:16.860 --> 00:52:20.970 so that, for instance, if I close my tab by clicking this little x button up 00:52:20.970 --> 00:52:23.760 here, and I want to reopen the file, much like you 00:52:23.760 --> 00:52:25.860 would imagine on a Mac or PC, it's as simple 00:52:25.860 --> 00:52:28.710 as double clicking the file on the left-hand side. 00:52:28.710 --> 00:52:31.800 But notice I didn't click on hello. 00:52:31.800 --> 00:52:33.150 Because notice what happens. 00:52:33.150 --> 00:52:38.550 If I open hello, my gosh, like, what is going on here? 00:52:38.550 --> 00:52:39.810 This is kind of a mess. 00:52:39.810 --> 00:52:40.710 There's redness. 00:52:40.710 --> 00:52:41.790 There's dots. 00:52:41.790 --> 00:52:47.865 Any thoughts from someone on why I'm seeing what I'm seeing? 00:52:47.865 --> 00:52:50.250 Because odds are you will, accidentally, at some point, 00:52:50.250 --> 00:52:56.520 click on a file like hello instead of on a file like hello.c. 00:52:56.520 --> 00:52:58.260 Sara, what do you think? 00:52:58.260 --> 00:52:59.850 AUDIENCE: It's a binary code. 00:52:59.850 --> 00:53:01.740 So it's the machine language. 00:53:01.740 --> 00:53:05.385 So it doesn't allow the user to see them, besides the code they write in C. 00:53:05.385 --> 00:53:06.510 DAVID MALAN: Yeah, exactly. 00:53:06.510 --> 00:53:11.410 What you're trying to look at in this tab is binary code, 0's and 1's. 00:53:11.410 --> 00:53:14.220 However, those 0's and 1's are technically 00:53:14.220 --> 00:53:18.060 being misinterpreted at the moment as ASCII characters, 00:53:18.060 --> 00:53:19.260 or Unicode characters. 00:53:19.260 --> 00:53:24.090 So recall from last week, ASCII is this mapping between numbers and letters. 00:53:24.090 --> 00:53:26.850 And numbers, of course, are just patterns of 0's and 1's. 00:53:26.850 --> 00:53:32.100 And this looks super cryptic, because we're trying to misinterpret 0's and 00:53:32.100 --> 00:53:34.230 1's as though they're ASCII characters. 00:53:34.230 --> 00:53:37.830 And recall that there's many more characters in ASCII and Unicode 00:53:37.830 --> 00:53:41.820 than A through Z. And the numbers, there's some unprintable characters. 00:53:41.820 --> 00:53:44.160 And indeed, all the funkiness we're seeing here 00:53:44.160 --> 00:53:47.190 is just a misinterpretation of 0's and 1's that 00:53:47.190 --> 00:53:51.780 are instructions to the computer, machine code for the computer being 00:53:51.780 --> 00:53:53.130 misinterpreted as text. 00:53:53.130 --> 00:53:56.130 So if you can't edit a binary file like this, so to speak, 00:53:56.130 --> 00:53:58.680 you should just close hello when you do something like that 00:53:58.680 --> 00:54:02.190 and make sure you've double clicked on and opened your actual source code 00:54:02.190 --> 00:54:04.420 file as well. 00:54:04.420 --> 00:54:06.450 So we've seen strings. 00:54:06.450 --> 00:54:08.100 And there's other data types. 00:54:08.100 --> 00:54:09.300 And there's other functions. 00:54:09.300 --> 00:54:11.730 And there's loops and conditions and so much more. 00:54:11.730 --> 00:54:15.000 I think we're at a good point now to perhaps take a break, let this sink in. 00:54:15.000 --> 00:54:18.270 Why don't we go ahead and take a seven minute break? 00:54:18.270 --> 00:54:20.910 And when we resume, we'll introduce a few more features of C 00:54:20.910 --> 00:54:23.790 and compare them against what we saw last week in Scratch. 00:54:23.790 --> 00:54:25.500 So we'll see you in seven minutes. 00:54:25.500 --> 00:54:28.260 All right, we are back. 00:54:28.260 --> 00:54:32.190 So recall where we left off was we were looking at this graphical user 00:54:32.190 --> 00:54:33.390 interface at top left. 00:54:33.390 --> 00:54:36.960 The file browser, the file tree, that just gives us more graphical access 00:54:36.960 --> 00:54:38.450 to the files in our account. 00:54:38.450 --> 00:54:44.730 But let's now do this the old school command line way in my terminal window. 00:54:44.730 --> 00:54:47.040 So it turns out that using our terminal window, 00:54:47.040 --> 00:54:51.090 can we not only compile code and run code and run check50 style, help50, 00:54:51.090 --> 00:54:53.850 and the like, we can also manipulate files 00:54:53.850 --> 00:54:57.480 and folders, even, that happen to exist in my IDE. 00:54:57.480 --> 00:55:01.060 That is in the computer I have access to here in the cloud. 00:55:01.060 --> 00:55:04.620 And the first command I've proposed is that we type ls. 00:55:04.620 --> 00:55:07.020 Ls is shorthand notation for list. 00:55:07.020 --> 00:55:12.040 And quite simply, ls lists the files or folders in your current folder. 00:55:12.040 --> 00:55:15.540 So this would be like double clicking on your My Documents folder in Windows, 00:55:15.540 --> 00:55:17.010 or documents in Mac OS. 00:55:17.010 --> 00:55:19.000 Ls just lists the contents. 00:55:19.000 --> 00:55:20.580 Now, notice hello is a little weird. 00:55:20.580 --> 00:55:25.360 It's highlighted in green and there's an asterisk after it. 00:55:25.360 --> 00:55:28.830 And that's just a visual cue that that file is executable. 00:55:28.830 --> 00:55:32.580 That is, that is a program that you can run with ./hello. 00:55:32.580 --> 00:55:34.710 The star is not part of the file name. 00:55:34.710 --> 00:55:36.570 And of course, we see hello.c. 00:55:36.570 --> 00:55:40.620 Now, suppose that I wanted to maybe rename my file. 00:55:40.620 --> 00:55:43.050 Well, I could, much like in Mac OS or Windows, 00:55:43.050 --> 00:55:45.000 I could go up to the file browser up here. 00:55:45.000 --> 00:55:46.830 I could Control click or Right click. 00:55:46.830 --> 00:55:49.110 And notice there's a whole bunch of menu options 00:55:49.110 --> 00:55:51.220 that pop up just like on your own computer. 00:55:51.220 --> 00:55:53.280 And I could rename the file right up here. 00:55:53.280 --> 00:55:56.113 But generally speaking, we're going to do things at the command line 00:55:56.113 --> 00:55:58.710 only because, rudimentary as some of these operations today 00:55:58.710 --> 00:56:02.700 are, it's going to be a much more powerful command line interface for me. 00:56:02.700 --> 00:56:04.920 So suppose I change my mind, and you know what? 00:56:04.920 --> 00:56:06.570 I don't like this version of hello. 00:56:06.570 --> 00:56:08.790 I want to delete that program and start over. 00:56:08.790 --> 00:56:11.070 Strictly speaking, I don't need to delete hello ever. 00:56:11.070 --> 00:56:14.620 I can just recompile it, and it will keep getting changed and changed. 00:56:14.620 --> 00:56:19.050 But if I do want to remove it, I can type rm hello, and then hit Enter. 00:56:19.050 --> 00:56:22.140 And then I'll be asked, remove regular file hello? 00:56:22.140 --> 00:56:25.170 That's just a visual confirmation that I do indeed want to delete. 00:56:25.170 --> 00:56:28.500 And I can type y or yes or some such reply. 00:56:28.500 --> 00:56:31.830 And if I hit y and Enter, nothing seems to happen, 00:56:31.830 --> 00:56:34.990 but notice what happened up here at top left. 00:56:34.990 --> 00:56:38.700 Notice that hello is now gone, leaving only hello.c. 00:56:38.700 --> 00:56:42.623 And if I type ls again, now I see only my code file. 00:56:42.623 --> 00:56:44.790 Maybe now I want to change this program, and I don't 00:56:44.790 --> 00:56:47.760 want to write hello.c, but goodbye.c. 00:56:47.760 --> 00:56:49.860 Well, let me close the tab up there. 00:56:49.860 --> 00:56:52.560 And yes, I could go and Right click or Control click on it, 00:56:52.560 --> 00:56:54.960 but, again, we don't need to use the graphical interface. 00:56:54.960 --> 00:57:00.990 Let me go ahead and instead do mv hello.c goodbye.c. 00:57:00.990 --> 00:57:03.150 Mv is the move command. 00:57:03.150 --> 00:57:06.260 And even though it would be nice if it's called rename instead of move, 00:57:06.260 --> 00:57:10.750 move just moves one file to another location or to another name. 00:57:10.750 --> 00:57:12.840 So if I do mv hello.c goodbye.c. 00:57:12.840 --> 00:57:15.910 Notice what happened at top left. 00:57:15.910 --> 00:57:18.210 Now my same file is called goodbye.c. 00:57:18.210 --> 00:57:23.248 And if, again, I type ls, I can see that it's indeed renamed. 00:57:23.248 --> 00:57:25.290 Now, let me go ahead and move that back because I 00:57:25.290 --> 00:57:27.810 want to stay on my hello.c program. 00:57:27.810 --> 00:57:29.970 But suppose I want to start organizing my files. 00:57:29.970 --> 00:57:32.262 In a moment we're going to start writing more programs, 00:57:32.262 --> 00:57:34.200 and so my account is going to get a little bit 00:57:34.200 --> 00:57:36.900 messy with more and more files over the course of today. 00:57:36.900 --> 00:57:41.050 So suppose you want to create a folder, otherwise known as a directory. 00:57:41.050 --> 00:57:45.598 I'm going to go ahead and type mkdir for make directory. 00:57:45.598 --> 00:57:48.640 And then the name of the directory I want to make, for instance, lecture. 00:57:48.640 --> 00:57:51.765 You can call it anything you want, but if I'm in lecture, I'm writing code, 00:57:51.765 --> 00:57:54.910 maybe I want to store all of today's files in a lecture directory. 00:57:54.910 --> 00:57:58.630 When I hit Enter there, notice what happens in my file tree up here. 00:57:58.630 --> 00:58:00.620 I now see a lecture folder. 00:58:00.620 --> 00:58:04.310 If I click the triangle, it's empty because I haven't put anything in it. 00:58:04.310 --> 00:58:08.170 So let me go ahead and move hello.c into the lecture folder. 00:58:08.170 --> 00:58:13.090 Mv hello.c lecture, and now let me hit Enter. 00:58:13.090 --> 00:58:17.800 And voila, now notice that it's nested inside of this lecture folder. 00:58:17.800 --> 00:58:22.210 And indeed, if I now type ls for list, I only see the lecture folder. 00:58:22.210 --> 00:58:24.730 Unfortunately, I kind of now don't have access 00:58:24.730 --> 00:58:27.730 to hello.c within this command line environment 00:58:27.730 --> 00:58:29.620 unless I change into that directory. 00:58:29.620 --> 00:58:32.020 Now, in the world of Macs and PCs we, obviously, 00:58:32.020 --> 00:58:35.140 would just double click on a folder and voila we're inside of it. 00:58:35.140 --> 00:58:37.810 In a command line interface you need to be more deliberate. 00:58:37.810 --> 00:58:40.960 So I'm going to do cd, for change directory, 00:58:40.960 --> 00:58:43.840 then lecture, and then I'm going to go ahead and hit Enter. 00:58:43.840 --> 00:58:46.180 And now notice, and now it might make more sense 00:58:46.180 --> 00:58:50.815 why this whole time we've been seeing in blue this tilde lecture slash. 00:58:50.815 --> 00:58:53.650 The tilde just means my so-called home directory. 00:58:53.650 --> 00:58:57.970 Like my own account, my own default folder, like my documents and windows, 00:58:57.970 --> 00:58:59.500 or documents on Mac OS. 00:58:59.500 --> 00:59:02.140 That's what tilde represents in shorthand notation. 00:59:02.140 --> 00:59:05.770 Lecture is the name of the folder that I am now inside. 00:59:05.770 --> 00:59:09.850 So it's as though I double clicked on lecture in Mac OS or Windows 00:59:09.850 --> 00:59:11.050 to open a folder. 00:59:11.050 --> 00:59:15.140 Now I'm inside this lecture directory in my terminal window. 00:59:15.140 --> 00:59:18.940 So if I now type ls enter, I should see voila, 00:59:18.940 --> 00:59:23.775 the hello.c file that I moved into it. 00:59:23.775 --> 00:59:25.900 Now, let me undo this because I'm going to go ahead 00:59:25.900 --> 00:59:27.730 and keep things a little simpler for now. 00:59:27.730 --> 00:59:32.650 And suppose that I want to move hello.c into where it previously was. 00:59:32.650 --> 00:59:34.120 Last piece of syntax. 00:59:34.120 --> 00:59:37.670 There's this shorthand notation for what we'll call a parent folder. 00:59:37.670 --> 00:59:40.930 So just like in family trees, there's the notion of parents, and children, 00:59:40.930 --> 00:59:42.490 and grandchildren, and so forth. 00:59:42.490 --> 00:59:45.130 That's also true in computer systems that have folders. 00:59:45.130 --> 00:59:46.840 And folders inside of folders. 00:59:46.840 --> 00:59:49.360 And folders inside of folders inside of folders. 00:59:49.360 --> 00:59:52.220 There's a hierarchy there much like a family tree. 00:59:52.220 --> 00:59:55.960 So if I want to move hello.c one level up, 00:59:55.960 --> 01:00:00.250 I can actually do mv hello.c space dot dot. 01:00:00.250 --> 01:00:04.300 And that's like saying move this file to the folder up above. 01:00:04.300 --> 01:00:07.270 When I do that, notice what happened at top left. 01:00:07.270 --> 01:00:11.920 Now hello.c is not inside of the lecture folder, but below it. 01:00:11.920 --> 01:00:16.090 And indeed, if I type ls now in the lecture folder, there's nothing there. 01:00:16.090 --> 01:00:21.130 How do I move myself up one level in the family tree that are these folders? 01:00:21.130 --> 01:00:24.270 Let me go ahead and type cd space dot dot. 01:00:24.270 --> 01:00:26.650 So change directory to my parent. 01:00:26.650 --> 01:00:28.180 Dot dot just means your parent. 01:00:28.180 --> 01:00:30.160 The folder up above, Enter. 01:00:30.160 --> 01:00:33.250 And now, I'm apparently in just tilde slash, 01:00:33.250 --> 01:00:37.240 which is, again, cryptic shorthand notation for your own home directory-- 01:00:37.240 --> 01:00:40.010 your My Documents or documents folder. 01:00:40.010 --> 01:00:43.647 And if, lastly, I type ls here, I'm done with this lecture folder. 01:00:43.647 --> 01:00:45.730 I don't want to bother storing things in a folder. 01:00:45.730 --> 01:00:50.560 I can do not rm for remove, like I did to get rid of hello, 01:00:50.560 --> 01:00:53.680 but rmdir to remove a directory. 01:00:53.680 --> 01:00:55.300 And voila, it's gone. 01:00:55.300 --> 01:00:59.050 And I've undone all of the various changes that I made earlier. 01:00:59.050 --> 01:01:01.510 But perhaps now it makes a little more sense 01:01:01.510 --> 01:01:03.220 why I was doing something earlier. 01:01:03.220 --> 01:01:05.510 Let me open up my hello.c file. 01:01:05.510 --> 01:01:08.860 Let me make hello again, which is way back where we left off. 01:01:08.860 --> 01:01:13.060 And recall that all this time I've been doing dot slash hello. 01:01:13.060 --> 01:01:14.500 Well, why is that? 01:01:14.500 --> 01:01:18.190 Well, just as dot dot refers to your parent directory, 01:01:18.190 --> 01:01:21.380 a single dot refers to your current directory. 01:01:21.380 --> 01:01:23.350 So even though this looks a little silly, 01:01:23.350 --> 01:01:26.950 dot slash hello is just a very explicit way 01:01:26.950 --> 01:01:30.610 of telling the computer, run the program called hello 01:01:30.610 --> 01:01:33.430 that's right here in my current directory. 01:01:33.430 --> 01:01:35.200 Dot means current directory. 01:01:35.200 --> 01:01:37.180 Dot dot means parent directory. 01:01:37.180 --> 01:01:40.000 And so there we see, finally, why I've been 01:01:40.000 --> 01:01:41.980 typing dot slash hello all this time. 01:01:41.980 --> 01:01:45.310 But again, it's just the textual analog of doing something 01:01:45.310 --> 01:01:50.530 like double clicking on an icon in Mac OS or Windows. 01:01:50.530 --> 01:01:53.740 So there's other commands too, and over time you'll get exposed to these 01:01:53.740 --> 01:01:55.450 and use them for various problems. 01:01:55.450 --> 01:01:58.910 Cp for copy, for instance, is yet another. 01:01:58.910 --> 01:02:01.630 And many others, but these are all just standard commands. 01:02:01.630 --> 01:02:03.610 They are not CS50 specific. 01:02:03.610 --> 01:02:07.900 Standard commands that allow us to manipulate files and folders 01:02:07.900 --> 01:02:10.150 in a computer like this. 01:02:10.150 --> 01:02:12.508 And question from Max. 01:02:12.508 --> 01:02:13.050 AUDIENCE: Hi. 01:02:13.050 --> 01:02:13.660 Yeah, sorry. 01:02:13.660 --> 01:02:14.290 I was just wondering. 01:02:14.290 --> 01:02:16.600 I don't really understand the difference between the hello program 01:02:16.600 --> 01:02:17.800 and the hello.c program. 01:02:17.800 --> 01:02:21.830 It seems like the one that doesn't have dot c on it isn't used for anything. 01:02:21.830 --> 01:02:23.080 DAVID MALAN: Oh, it is though. 01:02:23.080 --> 01:02:25.812 So recall that we have two things in the story. 01:02:25.812 --> 01:02:28.270 We have source code, which is the C code I've been writing. 01:02:28.270 --> 01:02:30.010 And then machine code, which is the zeros 01:02:30.010 --> 01:02:31.790 and ones that the computer understands. 01:02:31.790 --> 01:02:35.860 I have been writing all of my code in the file called hello.c. 01:02:35.860 --> 01:02:39.790 But after I compile it with make, the make program 01:02:39.790 --> 01:02:44.320 creates a new file called hello that technically contains only zeros 01:02:44.320 --> 01:02:45.100 and ones. 01:02:45.100 --> 01:02:47.410 And that is the machine code that I'm actually 01:02:47.410 --> 01:02:50.110 running when I do dot slash hello. 01:02:50.110 --> 01:02:53.710 So again, I can use rm and I can get rid of the hello program 01:02:53.710 --> 01:02:54.820 just like I did before. 01:02:54.820 --> 01:02:57.028 And now we're back at the very beginning of the story 01:02:57.028 --> 01:02:58.750 where we wrote this code from scratch. 01:02:58.750 --> 01:03:01.870 If I now type make, and let me do this now, ls. 01:03:01.870 --> 01:03:03.680 Notice I've only got one file. 01:03:03.680 --> 01:03:05.410 Let me now do make hello. 01:03:05.410 --> 01:03:09.250 I see that cryptic output, but if I type ls again, now I have two files. 01:03:09.250 --> 01:03:14.020 And that's because only the green one with the asterisk is executable. 01:03:14.020 --> 01:03:18.293 That is the machine code that the compiler has created for me. 01:03:18.293 --> 01:03:21.460 And I should say and disclaim, I've been telling a little bit of a white lie 01:03:21.460 --> 01:03:21.960 today. 01:03:21.960 --> 01:03:23.890 Make itself is not actually a compiler. 01:03:23.890 --> 01:03:26.500 We'll see next week exactly what make is doing. 01:03:26.500 --> 01:03:30.460 But it's making it easier for us to actually compile our code, 01:03:30.460 --> 01:03:32.740 but more on that next time. 01:03:32.740 --> 01:03:33.340 All right. 01:03:33.340 --> 01:03:37.600 So we've seen only strings thus far, but it turns out in C, 01:03:37.600 --> 01:03:41.380 and in a lot of languages, there's other things known as types or data types. 01:03:41.380 --> 01:03:43.840 That is to say, you can have variables and values 01:03:43.840 --> 01:03:47.290 that aren't just strings of text, but that are maybe integers, 01:03:47.290 --> 01:03:49.060 like numbers, one, two, three, four. 01:03:49.060 --> 01:03:54.280 Or maybe floating point values, like 3.14159, or other such values. 01:03:54.280 --> 01:03:58.360 You can have Boolean values, which are only true or false. 01:03:58.360 --> 01:04:02.200 You can have characters or chars, which are single characters. 01:04:02.200 --> 01:04:06.010 This is to say, within a language like C there's actually a whole bunch of data 01:04:06.010 --> 01:04:07.660 types that are available to you. 01:04:07.660 --> 01:04:09.740 String is only one of them. 01:04:09.740 --> 01:04:12.070 And there's even more than are on this list here, 01:04:12.070 --> 01:04:16.180 but this is just a list of some of the most common ones that we'll see today 01:04:16.180 --> 01:04:18.820 and we'll use this coming week in the first problem set 01:04:18.820 --> 01:04:22.820 that allow you to tell the computer not only to store a value in a variable, 01:04:22.820 --> 01:04:25.510 but what type of value to store in a variable. 01:04:25.510 --> 01:04:29.740 Moreover, we have in the CS50 library a whole bunch more functions. 01:04:29.740 --> 01:04:31.480 We've seen get_string already. 01:04:31.480 --> 01:04:34.300 But similarly have we created functions that you 01:04:34.300 --> 01:04:36.700 can use for problem sets, labs, and beyond that 01:04:36.700 --> 01:04:40.180 allow you to get a single character via a get_char. 01:04:40.180 --> 01:04:43.120 That can allow you to get an integer via get_int. 01:04:43.120 --> 01:04:45.010 That can allow you to get a floating point 01:04:45.010 --> 01:04:47.650 value, which is a fancy way of describing a real number, 01:04:47.650 --> 01:04:50.440 with a decimal point using get_float. 01:04:50.440 --> 01:04:56.110 But it turns out that each of these data types, like int and float, 01:04:56.110 --> 01:04:58.300 only have a finite number of bits. 01:04:58.300 --> 01:05:01.180 And recall from last week that we played around with light bulbs 01:05:01.180 --> 01:05:03.910 and we played around with bits and zeros and ones more generally. 01:05:03.910 --> 01:05:06.730 It turns out that every one of these data types, 01:05:06.730 --> 01:05:11.500 char, double, floats, int, long, string, and so forth, all 01:05:11.500 --> 01:05:13.930 use a specific number of bits. 01:05:13.930 --> 01:05:20.380 And it turns out that int, for instance, integers in C, only use 32 bits. 01:05:20.380 --> 01:05:24.820 And that's great until such time as you want to count higher than roughly 4 01:05:24.820 --> 01:05:27.220 billion, at which point you can't. 01:05:27.220 --> 01:05:30.610 We'll see later today that if you're only using a specific number of bits 01:05:30.610 --> 01:05:33.550 you can only count so high, and so there exist other data types. 01:05:33.550 --> 01:05:35.230 For instance, a long. 01:05:35.230 --> 01:05:39.520 A long is another type of number in C that just uses 64 bits. 01:05:39.520 --> 01:05:43.300 So it gives you way more expressiveness, way more patterns of zeros and ones 01:05:43.300 --> 01:05:44.320 to count even higher. 01:05:44.320 --> 01:05:47.290 Similarly, a double is like a floating point value. 01:05:47.290 --> 01:05:50.590 A real number with a decimal point and some number of digits after it. 01:05:50.590 --> 01:05:56.050 A double allows you to have even more digits after it than a float would. 01:05:56.050 --> 01:05:59.200 So we'll see and use some of these data types in just a bit. 01:05:59.200 --> 01:06:02.380 Printf, similarly, has the ability to print out not only strings 01:06:02.380 --> 01:06:06.080 as we saw, but also using different format codes other data types as well. 01:06:06.080 --> 01:06:09.413 These are a little more cryptic and it's fine to look these things up as needed, 01:06:09.413 --> 01:06:12.385 but you'll eventually ingrain them for common use cases. 01:06:12.385 --> 01:06:16.015 Percent c is going to be the placeholder for printing a single character. 01:06:16.015 --> 01:06:18.310 Percent c for a char, so to speak. 01:06:18.310 --> 01:06:21.055 Percent f is going to be for a floating point value. 01:06:21.055 --> 01:06:23.680 So if you want to print out a real number with a decimal point, 01:06:23.680 --> 01:06:25.090 you're going to use percent f. 01:06:25.090 --> 01:06:27.370 If you want to print an integer using print f, 01:06:27.370 --> 01:06:29.442 you're going to use percent i for integer. 01:06:29.442 --> 01:06:31.900 If you want to print a string we've already seen percent s. 01:06:31.900 --> 01:06:34.840 And if you want to print a long integer, a.k.a. 01:06:34.840 --> 01:06:36.940 long, you're going to use percent li. 01:06:36.940 --> 01:06:39.910 And there's even others, but these are perhaps some of the most common. 01:06:39.910 --> 01:06:44.050 And it just means that, again, C really needs you, the programmer, 01:06:44.050 --> 01:06:44.858 to be precise. 01:06:44.858 --> 01:06:46.150 You can't just say, print this. 01:06:46.150 --> 01:06:50.830 You have to tell printf how to print the variable or the value 01:06:50.830 --> 01:06:52.310 that you're passing into it. 01:06:52.310 --> 01:06:54.790 And then lastly, it turns out that in C there's 01:06:54.790 --> 01:06:59.480 a whole bunch of operators, certainly mathematical ones and bunches of others 01:06:59.480 --> 01:06:59.980 as well. 01:06:59.980 --> 01:07:02.740 Just like Scratch out a whole toolkit of operators. 01:07:02.740 --> 01:07:06.920 And suffice it to say for now that C also supports addition, subtraction, 01:07:06.920 --> 01:07:09.430 multiplication, division, and even the remainder 01:07:09.430 --> 01:07:13.060 operator, which a little cryptically is represented with a percent sign. 01:07:13.060 --> 01:07:15.497 Not to be confused with printf's format codes, 01:07:15.497 --> 01:07:18.580 but this is to say that some of the earliest uses of computers, of course, 01:07:18.580 --> 01:07:21.220 were all mathematically oriented in spreadsheet programs. 01:07:21.220 --> 01:07:24.880 Programs like VisiCalc and the like back before there was Excel and Google 01:07:24.880 --> 01:07:25.690 spreadsheets. 01:07:25.690 --> 01:07:29.380 And they certainly, computers, are very good at supporting math. 01:07:29.380 --> 01:07:31.990 And so these are just some of the operators that will now see 01:07:31.990 --> 01:07:33.188 are available to us. 01:07:33.188 --> 01:07:34.480 So let me go ahead and do this. 01:07:34.480 --> 01:07:39.250 Let me go back to my IDE after cleaning things 01:07:39.250 --> 01:07:44.110 up, and starting fresh with just nothing in my terminal window and no tabs open. 01:07:44.110 --> 01:07:46.810 And let me go ahead and write my next program this time 01:07:46.810 --> 01:07:48.700 using some more of these functions. 01:07:48.700 --> 01:07:52.630 I'm going to go ahead and create a file up here called addition.c. 01:07:52.630 --> 01:07:55.750 So addition.c, but I could call this anything I want, 01:07:55.750 --> 01:07:58.180 but it's important to add the dot c. 01:07:58.180 --> 01:08:00.970 Otherwise the computer will not know that it's actual source 01:08:00.970 --> 01:08:02.840 code as opposed to machine code. 01:08:02.840 --> 01:08:05.750 And let me go ahead and make use of the CS50 library. 01:08:05.750 --> 01:08:07.780 So let me include cs50.h. 01:08:07.780 --> 01:08:13.330 Let me include stdio.h, so that I can use things like get_int and printf. 01:08:13.330 --> 01:08:15.140 And then, again, for today's purposes, 01:08:15.140 --> 01:08:19.840 I'm just going to do int main void, and then the curly braces. 01:08:19.840 --> 01:08:22.750 And again, for today, just take on faith this is necessary. 01:08:22.750 --> 01:08:25.600 But we'll explain within a week or two exactly why 01:08:25.600 --> 01:08:27.250 we keep writing int main void. 01:08:27.250 --> 01:08:31.420 But for now, it's like the win green flag clicked puzzle piece. 01:08:31.420 --> 01:08:34.227 Let me go ahead now and get an integer from the user. 01:08:34.227 --> 01:08:36.310 Suppose my goal now is not to write a program that 01:08:36.310 --> 01:08:39.850 gets a string of text and prints out hello, Brian, or hello, David. 01:08:39.850 --> 01:08:42.670 Let me go ahead and write a program that maybe asks 01:08:42.670 --> 01:08:46.220 for two integers, two numbers, and then just adds them together. 01:08:46.220 --> 01:08:49.479 So let me make the simplest of calculators using code. 01:08:49.479 --> 01:08:52.990 Well, I'm going to go ahead and declare a variable called 01:08:52.990 --> 01:08:54.910 x, just like a mathematician would. 01:08:54.910 --> 01:08:59.260 And I'm going to assign it the value of calling get_int. 01:08:59.260 --> 01:09:01.630 And I'll just say something like x colon. 01:09:01.630 --> 01:09:04.450 I could say anything I want, what is x? 01:09:04.450 --> 01:09:06.939 But I'm going to keep it simple and just say x colon. 01:09:06.939 --> 01:09:08.740 Semicolon to end my thought. 01:09:08.740 --> 01:09:11.920 So again, similar in spirit to what I did with string before, 01:09:11.920 --> 01:09:16.029 but now I'm using get_int to get a number or an integer from the user. 01:09:16.029 --> 01:09:21.279 The quoted parameter here or argument is the input 01:09:21.279 --> 01:09:24.520 to get_int, which is going to be the prompt that the human sees. 01:09:24.520 --> 01:09:27.560 The equals sign, recall, is the assignment operator, 01:09:27.560 --> 01:09:31.810 which says, copy the return value on the right-- 01:09:31.810 --> 01:09:34.149 the integer that the human hopefully will type in-- 01:09:34.149 --> 01:09:35.800 over to the left. 01:09:35.800 --> 01:09:39.430 And the left says, give me a variable called, x, 01:09:39.430 --> 01:09:42.710 and let me store integers in it. 01:09:42.710 --> 01:09:46.128 So before, we use string on the left and we used get_string the right. 01:09:46.128 --> 01:09:47.920 The only difference now is int on the left, 01:09:47.920 --> 01:09:50.979 because I want a number, and get_int on the right. 01:09:50.979 --> 01:09:54.220 Then let me go ahead and do this again and get another number. 01:09:54.220 --> 01:09:56.320 Get_int, and I'll just say, y colon. 01:09:56.320 --> 01:10:00.052 But again, I could say, what is y question mark, or anything in English. 01:10:00.052 --> 01:10:02.260 But the last line is going to be the interesting one. 01:10:02.260 --> 01:10:05.150 Now, I'm going to go ahead and print out for instance, 01:10:05.150 --> 01:10:07.210 the sum of these two numbers. 01:10:07.210 --> 01:10:12.760 But printf, again, takes an input that tells it what to print out exactly. 01:10:12.760 --> 01:10:15.790 So I can't really type a number here yet because I don't know 01:10:15.790 --> 01:10:17.600 what the human is going to type in. 01:10:17.600 --> 01:10:19.030 So I'm going to put a placeholder. 01:10:19.030 --> 01:10:22.030 I'm going to percent i, which says, put a number here, 01:10:22.030 --> 01:10:23.725 I just don't know yet what it is. 01:10:23.725 --> 01:10:25.600 And then just to keep things clean, I'm going 01:10:25.600 --> 01:10:28.690 to do backslash n, which just says, give me a new line also. 01:10:28.690 --> 01:10:31.690 That's just an aesthetic detail to move the cursor to the next line just 01:10:31.690 --> 01:10:33.280 to keep things clean. 01:10:33.280 --> 01:10:36.475 But now printf is going to take a second argument. 01:10:36.475 --> 01:10:38.350 And whether you've programmed or not before-- 01:10:38.350 --> 01:10:40.870 Brian, let's go to someone in the audience if we could-- 01:10:40.870 --> 01:10:44.440 what should I type after the comma if the purpose of this program 01:10:44.440 --> 01:10:47.560 is quite simply to add two numbers together? 01:10:47.560 --> 01:10:51.310 Even if you've never programmed before, based on the operators that exist 01:10:51.310 --> 01:10:53.200 and some of the syntax we've seen thus far, 01:10:53.200 --> 01:10:55.075 what would your instincts have you type here? 01:10:55.075 --> 01:10:57.220 Even if you've never done this before. 01:10:57.220 --> 01:11:00.160 Santiago, what do you think? 01:11:00.160 --> 01:11:03.460 AUDIENCE: I would say to just write x plus y. 01:11:03.460 --> 01:11:06.400 DAVID MALAN: Yeah, it is simple and as straightforward as that. 01:11:06.400 --> 01:11:08.122 X plus y is the right intuition. 01:11:08.122 --> 01:11:11.080 I'm going to add a semicolon to the very end just to finish my thought. 01:11:11.080 --> 01:11:13.660 But indeed, computers, and C in this case, 01:11:13.660 --> 01:11:17.110 absolutely understand arithmetic and mathematical operations, so just type 01:11:17.110 --> 01:11:17.890 what you mean. 01:11:17.890 --> 01:11:20.800 I'm going to go ahead now and save the file and go down below. 01:11:20.800 --> 01:11:22.690 And I'm not going to type make hello anymore. 01:11:22.690 --> 01:11:26.470 Now I want to type make addition, because that is the name of my file 01:11:26.470 --> 01:11:27.310 implicitly. 01:11:27.310 --> 01:11:28.540 Addition.c. 01:11:28.540 --> 01:11:31.870 I want to compile into a program called addition. 01:11:31.870 --> 01:11:35.170 Hopefully, this is where I cross my fingers, I didn't make any mistakes. 01:11:35.170 --> 01:11:38.350 And I'm going to go ahead and run make addition. 01:11:38.350 --> 01:11:40.305 All this well, no error messages. 01:11:40.305 --> 01:11:42.430 If I had made a mistake and it didn't even compile, 01:11:42.430 --> 01:11:44.920 help50 might have been my next instinct. 01:11:44.920 --> 01:11:47.230 Now I'm going to go ahead and run dot slash addition. 01:11:47.230 --> 01:11:49.510 And notice, I'm first prompted for x. 01:11:49.510 --> 01:11:51.130 I'm going to go ahead and do one. 01:11:51.130 --> 01:11:52.630 I'm next prompted for y. 01:11:52.630 --> 01:11:54.460 I'm going to go ahead and do one again. 01:11:54.460 --> 01:11:59.230 And voila, as Santiago proposed, I indeed see on the screen x plus y, 01:11:59.230 --> 01:12:00.160 or the value two. 01:12:00.160 --> 01:12:01.450 And I didn't hardcode two. 01:12:01.450 --> 01:12:07.600 I substituted in using i whatever the result of x plus y actually is. 01:12:07.600 --> 01:12:11.260 Now notice, some of the features of the get_int function for you. 01:12:11.260 --> 01:12:14.860 Suppose that you're not being very cooperative and you type in cat for x. 01:12:14.860 --> 01:12:18.100 Notice that get_int just ignores you and prompts you again. 01:12:18.100 --> 01:12:21.760 If I type in dog it ignores me and prompts me again. 01:12:21.760 --> 01:12:25.450 If I type in 1.23, it ignores me and prompts me again 01:12:25.450 --> 01:12:27.640 because it wants an integer in this case. 01:12:27.640 --> 01:12:29.140 A number like one, two, three, four. 01:12:29.140 --> 01:12:32.650 Or negative one, two, three, four, or zero, or anything above or below. 01:12:32.650 --> 01:12:35.350 So fine, I'll cooperate now and give it the number one. 01:12:35.350 --> 01:12:36.250 Same for y. 01:12:36.250 --> 01:12:38.437 It's going to ignore any non-integer input. 01:12:38.437 --> 01:12:40.270 So if I give it a number like two this time, 01:12:40.270 --> 01:12:42.720 I'll hopefully get the answer of three. 01:12:42.720 --> 01:12:43.220 All right. 01:12:43.220 --> 01:12:46.930 So we have a basic calculator in C. We're using some basic building 01:12:46.930 --> 01:12:47.800 blocks as before. 01:12:47.800 --> 01:12:52.360 We've got these header files, which just give me access to get_int and printf 01:12:52.360 --> 01:12:53.380 respectively. 01:12:53.380 --> 01:12:55.497 But suppose now I want to count up even higher. 01:12:55.497 --> 01:12:56.080 You know what? 01:12:56.080 --> 01:12:57.372 Let me try something like this. 01:12:57.372 --> 01:12:58.930 Let me run this program once more. 01:12:58.930 --> 01:13:00.640 And let me get a little greedy. 01:13:00.640 --> 01:13:05.540 How about 4,000,000,000. 01:13:05.540 --> 01:13:07.330 So roughly-- well, exactly-- 01:13:07.330 --> 01:13:08.800 4 billion. 01:13:08.800 --> 01:13:10.750 That's the number I want to type in. 01:13:10.750 --> 01:13:13.630 Notice that x does not like that. 01:13:13.630 --> 01:13:16.420 So get_int does not accept 4 billion. 01:13:16.420 --> 01:13:20.500 Well, let me try it maybe 3 billion. 01:13:20.500 --> 01:13:21.062 Uh-huh. 01:13:21.062 --> 01:13:21.770 Didn't like that. 01:13:21.770 --> 01:13:23.960 How about 2 billion? 01:13:23.960 --> 01:13:25.610 OK, that one worked. 01:13:25.610 --> 01:13:27.320 Let me pause here. 01:13:27.320 --> 01:13:29.600 What's going on perhaps? 01:13:29.600 --> 01:13:32.450 Now again, we the staff wrote get_int, so we 01:13:32.450 --> 01:13:36.860 are the ones that are rejecting cats, and rejecting dogs, and rejecting 01:13:36.860 --> 01:13:39.080 4 billion, and even 3 billion. 01:13:39.080 --> 01:13:41.210 But in this case, it's a little less clear. 01:13:41.210 --> 01:13:45.260 Why did we reject 4 billion and 3 billion do you think? 01:13:45.260 --> 01:13:48.780 Based on some of the definitions thus far today. 01:13:48.780 --> 01:13:49.620 Why might this be? 01:13:49.620 --> 01:13:52.260 Nathaniel, what do you think? 01:13:52.260 --> 01:13:54.540 AUDIENCE: There's a cap on the size of the number 01:13:54.540 --> 01:13:59.095 since it would take too many bits and bytes after the size of 2 billion. 01:13:59.095 --> 01:13:59.970 DAVID MALAN: Perfect. 01:13:59.970 --> 01:14:03.900 So integers, again, are implemented in C as these things ints. 01:14:03.900 --> 01:14:06.582 Ints only use, it turns out, 32 bits total. 01:14:06.582 --> 01:14:08.790 And you would only know that by having been taught it 01:14:08.790 --> 01:14:10.960 or looked it up for a particular computer system. 01:14:10.960 --> 01:14:15.842 But they on CS50 IDE, and most modern systems, an integer is only 32 bits. 01:14:15.842 --> 01:14:17.550 And that then invites the question, well, 01:14:17.550 --> 01:14:20.550 if you've got 32 bits or light bulbs, how high can you count? 01:14:20.550 --> 01:14:23.400 Well, it turns out with 32 light bulbs, or bits, 01:14:23.400 --> 01:14:26.040 you can count roughly as high as 4 billion. 01:14:26.040 --> 01:14:28.950 You can absolutely count as high as 3 billion. 01:14:28.950 --> 01:14:31.140 And yet, get_int still rejecting it. 01:14:31.140 --> 01:14:35.640 But that's because the get_int function supports integers broadly 01:14:35.640 --> 01:14:38.340 speaking, which includes not only positive numbers, 01:14:38.340 --> 01:14:41.040 but also negative numbers and zero. 01:14:41.040 --> 01:14:44.190 And the catch is that if you want to support both positive numbers 01:14:44.190 --> 01:14:49.900 and negative numbers, you can represent 4 billion or so total possible values. 01:14:49.900 --> 01:14:53.820 But if you want to go as far to the left and as far to the right on the number 01:14:53.820 --> 01:14:55.200 line that I'm describing. 01:14:55.200 --> 01:14:58.710 You can only really count as high as 2 billion in the positive direction 01:14:58.710 --> 01:15:01.560 and negative 2 billion in the negative direction. 01:15:01.560 --> 01:15:03.900 Because that still gives you a total of 4 billion, 01:15:03.900 --> 01:15:06.840 but not nearly as high as 3 billion or 4 billion. 01:15:06.840 --> 01:15:08.760 So what might the solution here be? 01:15:08.760 --> 01:15:12.040 Well, I recall earlier noting that there's other data types. 01:15:12.040 --> 01:15:14.790 Not just ints and strings, but also longs, which literally 01:15:14.790 --> 01:15:17.730 are longer integers, namely 64 bit. 01:15:17.730 --> 01:15:19.400 So let me go ahead and try this. 01:15:19.400 --> 01:15:21.720 Let me go ahead and change get_int to get_long. 01:15:21.720 --> 01:15:23.740 This get_int to get_long. 01:15:23.740 --> 01:15:26.820 Let me change this int a long, and this int to a long. 01:15:26.820 --> 01:15:29.190 So same program, same calculator, but I'm 01:15:29.190 --> 01:15:31.200 now using a different data type that's just 01:15:31.200 --> 01:15:33.380 going to use more bits to store values. 01:15:33.380 --> 01:15:36.420 Let me run make addition again to recompile my program. 01:15:36.420 --> 01:15:37.590 And, oh, damn it. 01:15:37.590 --> 01:15:39.040 I screwed up. 01:15:39.040 --> 01:15:41.580 So let's see if we can't glean what's wrong here. 01:15:41.580 --> 01:15:42.390 Let me scroll up. 01:15:42.390 --> 01:15:43.920 And I can't emphasize this enough. 01:15:43.920 --> 01:15:47.010 Sometimes-- I got lucky here and I only have one mistake, apparently, 01:15:47.010 --> 01:15:51.150 in the error messages-- it is not going to be uncommon 01:15:51.150 --> 01:15:55.830 for you to have two errors, 10 errors, in like two lines of code. 01:15:55.830 --> 01:15:58.680 This is because sometimes when you have errors in your code, 01:15:58.680 --> 01:16:01.228 the compiler sometimes just gets confused. 01:16:01.228 --> 01:16:04.020 And if it gets sufficiently confused, it starts thinking everything 01:16:04.020 --> 01:16:06.010 is an error in your actual code. 01:16:06.010 --> 01:16:08.520 So the most important takeaway is that no matter 01:16:08.520 --> 01:16:13.230 how many errors you seem to have, always scroll up to the top of the output 01:16:13.230 --> 01:16:15.210 and address the first error first. 01:16:15.210 --> 01:16:18.680 So that's why I scrolled up in my window to look immediately below what I typed, 01:16:18.680 --> 01:16:20.430 make addition, and here's the first error. 01:16:20.430 --> 01:16:21.910 Addition.c on line 10. 01:16:21.910 --> 01:16:22.410 All right. 01:16:22.410 --> 01:16:24.900 I can't see line 10, so let me scroll my code up. 01:16:24.900 --> 01:16:28.200 And it's saying something about format specifies type int, 01:16:28.200 --> 01:16:30.360 but the argument has type long. 01:16:30.360 --> 01:16:33.570 We haven't seen this error before, but I think I can infer from this. 01:16:33.570 --> 01:16:36.900 It's not super cryptic even though it's unfamiliar. 01:16:36.900 --> 01:16:40.650 I think what this means is that percent i recall was for integers. 01:16:40.650 --> 01:16:46.200 I think what I need is a different format code for long integers, which 01:16:46.200 --> 01:16:48.510 is going to be li instead. 01:16:48.510 --> 01:16:50.620 And that was from my little cheat sheet earlier. 01:16:50.620 --> 01:16:52.203 So let me go ahead and try this again. 01:16:52.203 --> 01:16:54.360 Make addition after changing the i to an li. 01:16:54.360 --> 01:16:55.470 That indeed works. 01:16:55.470 --> 01:16:56.850 Now let me do-- 01:16:56.850 --> 01:16:57.720 oops, typo. 01:16:57.720 --> 01:16:59.610 Now let me dot slash addition. 01:16:59.610 --> 01:17:04.108 And now I'll type in 4,000,000,000. 01:17:04.108 --> 01:17:05.340 4 billion. 01:17:05.340 --> 01:17:10.440 Now get_long is happy, and it will accept such a long integer 01:17:10.440 --> 01:17:13.650 because it has enough bits. 01:17:13.650 --> 01:17:19.560 All right, questions on types like ints and longs, 01:17:19.560 --> 01:17:22.080 or functions like get_int or get_long. 01:17:22.080 --> 01:17:23.820 Yeah, Peter. 01:17:23.820 --> 01:17:24.780 AUDIENCE: Yeah. 01:17:24.780 --> 01:17:30.090 When I typed 2 billion and both were integers, well, 01:17:30.090 --> 01:17:32.130 eventually it just gives you the wrong answer. 01:17:32.130 --> 01:17:33.160 Some negative numbers. 01:17:33.160 --> 01:17:34.807 Is that because of the bits and bytes? 01:17:34.807 --> 01:17:35.640 DAVID MALAN: Indeed. 01:17:35.640 --> 01:17:36.640 It's the same answer. 01:17:36.640 --> 01:17:39.330 So I didn't demonstrate that, but if you inputed both 2 billion 01:17:39.330 --> 01:17:45.660 for x and 2 billion for y and then you try to add those together, 01:17:45.660 --> 01:17:48.090 that would give you mathematically 4 billion. 01:17:48.090 --> 01:17:52.170 But again, an int is not big enough to store 4 billion 01:17:52.170 --> 01:17:55.360 if we want to also be able to represent negative numbers. 01:17:55.360 --> 01:17:58.590 So Peter what you're seeing is that you can't fit 01:17:58.590 --> 01:18:01.440 the result in the data type allowed. 01:18:01.440 --> 01:18:02.850 And we'll see in a moment-- 01:18:02.850 --> 01:18:05.657 in a little bit today, actually, what the ramifications of that 01:18:05.657 --> 01:18:07.740 are, but the symptom you're describing is exactly. 01:18:07.740 --> 01:18:13.020 That you tried to cram too big of a number into finitely many bits, 32. 01:18:13.020 --> 01:18:16.990 You can avoid that problem though, of course, by switching over to long. 01:18:16.990 --> 01:18:19.090 Let me try one other thing that's a bit curious. 01:18:19.090 --> 01:18:21.690 Let me go ahead and write a slightly different program now. 01:18:21.690 --> 01:18:25.562 And I'm going to describe this as truncation.c. 01:18:25.562 --> 01:18:28.020 Fancy term, but we'll see what this means in just a moment. 01:18:28.020 --> 01:18:30.450 I'm going to give myself at the top, cs50.h. 01:18:30.450 --> 01:18:32.875 And I'm going to give myself stdio.h. 01:18:32.875 --> 01:18:36.000 And it's certainly fine, once you get started with the first lab or problem 01:18:36.000 --> 01:18:39.270 set, if it takes you much longer to type some of these things out. 01:18:39.270 --> 01:18:41.130 I'm just doing it for muscle memory. 01:18:41.130 --> 01:18:42.450 Int main void. 01:18:42.450 --> 01:18:46.560 And now we're good to go with a new program in a file called truncation.c. 01:18:46.560 --> 01:18:49.690 I'm going to go ahead and prompt a user for an int, again. 01:18:49.690 --> 01:18:51.380 So just like before. 01:18:51.380 --> 01:18:55.760 I'm going to prompt the user for another int, just like before. 01:18:55.760 --> 01:18:57.580 And then I'm going to go ahead and do this. 01:18:57.580 --> 01:18:58.930 I want to do division this time. 01:18:58.930 --> 01:19:00.790 So not just a addition, that was a little too easy. 01:19:00.790 --> 01:19:01.790 Let me do a division. 01:19:01.790 --> 01:19:08.140 So let me give myself another variable, z equals x divided by y. 01:19:08.140 --> 01:19:10.270 And let me pause here for a moment and just ask 01:19:10.270 --> 01:19:14.530 the question, what data type should I perhaps use for z? 01:19:14.530 --> 01:19:17.470 This line of code is not yet correct, because recall that any time you 01:19:17.470 --> 01:19:20.440 create a new variable on the left here, I'm 01:19:20.440 --> 01:19:24.430 going to need to put something to the left of that variable's name 01:19:24.430 --> 01:19:27.370 so that C knows what type of variable I want. 01:19:27.370 --> 01:19:30.380 And thus far we've seen string and int and long. 01:19:30.380 --> 01:19:34.510 So would you propose we use one of those or something else for z? 01:19:34.510 --> 01:19:35.330 How about Jack. 01:19:35.330 --> 01:19:37.360 What do you think? 01:19:37.360 --> 01:19:38.890 AUDIENCE: Would it be a float? 01:19:38.890 --> 01:19:40.090 DAVID MALAN: Yeah, so float. 01:19:40.090 --> 01:19:44.050 So float, which is short for floating point value, which is the programmer's 01:19:44.050 --> 01:19:45.640 way of describing a real number. 01:19:45.640 --> 01:19:46.480 Let me go ahead and do that. 01:19:46.480 --> 01:19:46.990 A float. 01:19:46.990 --> 01:19:51.040 And I'm guessing your instincts for float were that, well, 01:19:51.040 --> 01:19:53.860 if you type in one number for x and another for y 01:19:53.860 --> 01:19:56.285 and the result is a fraction of some sort, so something 01:19:56.285 --> 01:19:57.160 with a decimal point. 01:19:57.160 --> 01:20:01.060 We need to store it in a float so that we can actually 01:20:01.060 --> 01:20:05.030 store whatever the numbers are after the decimal point. 01:20:05.030 --> 01:20:06.280 So let's go ahead and do this. 01:20:06.280 --> 01:20:08.440 Let me now go ahead and print this out. 01:20:08.440 --> 01:20:11.740 Percent f backslash n, because I'm printing a float this time. 01:20:11.740 --> 01:20:14.740 And then let me go ahead and print out the value of z. 01:20:14.740 --> 01:20:15.490 And you know what? 01:20:15.490 --> 01:20:19.050 Just for good measure, let me start practicing good style here too. 01:20:19.050 --> 01:20:21.502 So get a number from user. 01:20:21.502 --> 01:20:22.960 Let me give myself another comment. 01:20:22.960 --> 01:20:24.952 Get another number from user. 01:20:24.952 --> 01:20:25.660 Or you know what? 01:20:25.660 --> 01:20:26.830 This seems a little silly. 01:20:26.830 --> 01:20:28.060 I can combine these lines. 01:20:28.060 --> 01:20:31.420 And why don't I just say, get, for instance, numbers from user. 01:20:31.420 --> 01:20:33.640 That's a reasonable way to comment your code. 01:20:33.640 --> 01:20:37.740 And then let's just go ahead and divide x by y. 01:20:37.740 --> 01:20:39.490 But even this is getting a little pedantic 01:20:39.490 --> 01:20:41.540 because you can kind of read that from the code. 01:20:41.540 --> 01:20:44.900 So at some point we might not even need a comment for that. 01:20:44.900 --> 01:20:47.050 So let's just simplify as such. 01:20:47.050 --> 01:20:49.780 Let's go ahead now and compile this. 01:20:49.780 --> 01:20:51.880 Make-- come on-- 01:20:51.880 --> 01:20:54.520 make truncation. 01:20:54.520 --> 01:20:56.020 All right, it compiles OK. 01:20:56.020 --> 01:20:57.580 And I like how we used a float here. 01:20:57.580 --> 01:20:58.750 That does feel correct. 01:20:58.750 --> 01:21:00.340 So let me run truncation. 01:21:00.340 --> 01:21:04.690 And let me go ahead and type in, for instance, 4 for x and 2 for y. 01:21:04.690 --> 01:21:05.710 OK, I like that. 01:21:05.710 --> 01:21:09.580 It's 2.000, so that's the correct math calculation. 01:21:09.580 --> 01:21:11.290 How about 1 divided by 2. 01:21:11.290 --> 01:21:17.935 So x is 1, y is 2, and it's 0.000000. 01:21:17.935 --> 01:21:19.810 All right, well, maybe that was just a fluke. 01:21:19.810 --> 01:21:22.000 Let me try running it again. 01:21:22.000 --> 01:21:23.230 How about 2/3? 01:21:23.230 --> 01:21:26.560 2 divided by 3. 01:21:26.560 --> 01:21:28.610 That's not right either. 01:21:28.610 --> 01:21:29.110 All right. 01:21:29.110 --> 01:21:30.760 How about 4/3? 01:21:30.760 --> 01:21:35.060 Let's put a bigger number for the x, so 4/3. 01:21:35.060 --> 01:21:37.570 OK, it's closer to right. 01:21:37.570 --> 01:21:41.000 But this is an example, this week, of a bug. 01:21:41.000 --> 01:21:42.980 So my code compile. 01:21:42.980 --> 01:21:46.180 So syntactically it's fine, but this is a logical bug. 01:21:46.180 --> 01:21:49.460 Like I've somehow used C code improperly. 01:21:49.460 --> 01:21:51.860 So what might be going on here? 01:21:51.860 --> 01:21:56.860 Why is 1 divided by 2 and 2 divided by 3 both apparently zero, 01:21:56.860 --> 01:22:00.200 followed by six zeros after the decimal point. 01:22:00.200 --> 01:22:08.290 And even 4/3 gives me 1.000000 instead of 1.33333. 01:22:08.290 --> 01:22:10.300 Nina, what do you think? 01:22:10.300 --> 01:22:15.160 AUDIENCE: Because with int they don't recognize decimals. 01:22:15.160 --> 01:22:20.740 So 4/3 question three only goes into 4 one time, so it returns a 1. 01:22:20.740 --> 01:22:23.470 And you need to use other types of character, 01:22:23.470 --> 01:22:27.145 like a float or a double if you want the actual decimal. 01:22:27.145 --> 01:22:28.270 DAVID MALAN: Yeah, exactly. 01:22:28.270 --> 01:22:30.850 This one's more subtle than the mistakes I've made before. 01:22:30.850 --> 01:22:34.900 But C, like most programming languages, is going to take you literally. 01:22:34.900 --> 01:22:38.500 So if on the right hand side of this expression, on line 11, 01:22:38.500 --> 01:22:41.650 I am literally doing x divided by y. 01:22:41.650 --> 01:22:44.860 You first have to ask yourself, well, what is the type of x? 01:22:44.860 --> 01:22:46.690 What is the type of y? 01:22:46.690 --> 01:22:51.020 If they are both ints, by definition of how C works, 01:22:51.020 --> 01:22:54.260 you are going to get back an integer as your answer. 01:22:54.260 --> 01:22:56.080 So if you do 1 divided by 2. 01:22:56.080 --> 01:23:00.820 Yes, mathematically that's 0.50000. 01:23:00.820 --> 01:23:06.160 However, if you convert that to an int, in so far as x and y are ints, 01:23:06.160 --> 01:23:09.980 the way C works is it truncates everything after the decimal point. 01:23:09.980 --> 01:23:14.140 So it does the math correctly, but because you cannot fit floating point 01:23:14.140 --> 01:23:18.280 values, you cannot fit decimal points and numbers thereafter in an integer, 01:23:18.280 --> 01:23:23.140 you get you lose all of those digits after the decimal point because you can 01:23:23.140 --> 01:23:27.550 only fit the integer part of the answer into an integer. 01:23:27.550 --> 01:23:32.020 It's not relevant that I'm saving the result ultimately in a float 01:23:32.020 --> 01:23:33.160 because that's too late. 01:23:33.160 --> 01:23:36.110 The math has already been done on the right hand side. 01:23:36.110 --> 01:23:40.220 And so yes, I'm storing an integer in a float so I can print it as a float, 01:23:40.220 --> 01:23:40.990 but it's too late. 01:23:40.990 --> 01:23:44.390 Everything after the decimal point has already been thrown away. 01:23:44.390 --> 01:23:46.780 So what are the implications of this, or how could I fix? 01:23:46.780 --> 01:23:49.900 Well, I could go through and just change all of this right. 01:23:49.900 --> 01:23:52.073 Well, if the problem is that x and y are ints, 01:23:52.073 --> 01:23:53.740 well, let me just change them to floats. 01:23:53.740 --> 01:23:57.880 And change this up here, change x to a float, change y to a float, 01:23:57.880 --> 01:23:58.780 and so forth. 01:23:58.780 --> 01:24:00.072 That would fix the problem. 01:24:00.072 --> 01:24:02.530 But that's kind of a heavy handed solution to this problem. 01:24:02.530 --> 01:24:04.300 Go through and change all of your code. 01:24:04.300 --> 01:24:07.210 You can instead be a little more clever, and you 01:24:07.210 --> 01:24:11.590 can convince the computer to convert an integer to a float 01:24:11.590 --> 01:24:13.240 by something known as casting. 01:24:13.240 --> 01:24:17.390 So I can actually go in here, and using a new syntax I can say float y. 01:24:17.390 --> 01:24:20.140 And I can even, for good measure, but it's not strictly necessary, 01:24:20.140 --> 01:24:21.670 also do it to x. 01:24:21.670 --> 01:24:27.190 You can in C, cast or typecast one data type to another 01:24:27.190 --> 01:24:31.070 by literally in parentheses just putting the new data type that you want. 01:24:31.070 --> 01:24:35.590 And if it makes mathematical sense for one to be converted into the other, 01:24:35.590 --> 01:24:37.340 the computer will do it for you. 01:24:37.340 --> 01:24:41.320 So in this way I'm telling the computer, convert x to a float, 01:24:41.320 --> 01:24:43.990 convert y to a float, then do the math. 01:24:43.990 --> 01:24:48.010 And so before when I typed in one and two respectively for x and y, 01:24:48.010 --> 01:24:53.140 now it's like I typed in 1.0 and 2.0. 01:24:53.140 --> 01:24:59.080 And 1.0 divided by 2.0 is going to be mathematically 0.5, 01:24:59.080 --> 01:25:03.160 but because x and y now were converted in advance to floats, 01:25:03.160 --> 01:25:06.520 the answer is going to remain a float, 0.5. 01:25:06.520 --> 01:25:10.400 And that's what's going to get stored in z and ultimately printed. 01:25:10.400 --> 01:25:14.020 So if I rerun truncation having now fixed this problem. 01:25:14.020 --> 01:25:15.760 Let me do dot slash truncation. 01:25:15.760 --> 01:25:17.530 Type in one, type in two. 01:25:17.530 --> 01:25:19.480 I don't have to type the 0.0 myself. 01:25:19.480 --> 01:25:23.560 The computer's doing that for me via these casts in parentheses. 01:25:23.560 --> 01:25:27.910 Now I see that the answer is indeed 0.5. 01:25:27.910 --> 01:25:29.020 All right. 01:25:29.020 --> 01:25:32.410 So we seem to have now some very basic low level control 01:25:32.410 --> 01:25:34.310 over what you can do with the program. 01:25:34.310 --> 01:25:36.247 Let's now add back all of the fancy features 01:25:36.247 --> 01:25:38.080 that we had from Scratch last week so we can 01:25:38.080 --> 01:25:40.330 start making more interesting programs. 01:25:40.330 --> 01:25:44.740 So variables and another term of art called syntactic sugar is also 01:25:44.740 --> 01:25:46.220 among C's features here. 01:25:46.220 --> 01:25:49.150 So recall from last week when we wanted to have a variable called 01:25:49.150 --> 01:25:50.980 counter set equal to zero. 01:25:50.980 --> 01:25:52.960 We can go ahead and define it like this. 01:25:52.960 --> 01:25:56.080 In C, starting today, we're going to instead say something 01:25:56.080 --> 01:25:57.730 like, counter equals zero. 01:25:57.730 --> 01:26:01.420 But we additionally need to specify the data type of that variable, 01:26:01.420 --> 01:26:04.860 and we need to end our thought with a semicolon. 01:26:04.860 --> 01:26:08.020 So whereas we set counter to zero like this last week, now 01:26:08.020 --> 01:26:11.170 it's going to translate quite simply to this on the right hand side. 01:26:11.170 --> 01:26:12.400 Well, what comes after that? 01:26:12.400 --> 01:26:16.120 Well, if we wanted to increment a counter variable last week by one, 01:26:16.120 --> 01:26:18.790 adding one to it, we used quite simply this puzzle piece. 01:26:18.790 --> 01:26:23.200 This week we need to be a little more explicit and say something like this. 01:26:23.200 --> 01:26:27.730 Counter equals counter plus one, and semicolon to finish the thought. 01:26:27.730 --> 01:26:30.670 Now, this might seem very mathematically paradoxical. 01:26:30.670 --> 01:26:34.030 Like, how can counter equal counter plus one? 01:26:34.030 --> 01:26:36.700 Like, that just doesn't work logically. 01:26:36.700 --> 01:26:39.820 But that's not the equal sign in this case. 01:26:39.820 --> 01:26:42.940 In C, as with other languages we'll encounter, 01:26:42.940 --> 01:26:46.880 the equals sign is the assignment operator from right to left. 01:26:46.880 --> 01:26:49.210 So this is saying, take counter plus one, 01:26:49.210 --> 01:26:52.300 and store that mathematical result on the left. 01:26:52.300 --> 01:26:57.550 So whatever counter is, add one, store the result in counter thereafter. 01:26:57.550 --> 01:26:59.950 Effectively, increasing its total by one. 01:26:59.950 --> 01:27:02.170 Now this is a very common operation in programs 01:27:02.170 --> 01:27:04.150 we'll see over the term where you just want to add something up 01:27:04.150 --> 01:27:06.610 because you want to keep track of the count of something. 01:27:06.610 --> 01:27:09.460 So it turns out there's some syntactic sugar, which 01:27:09.460 --> 01:27:12.850 means there's a different way of doing this syntactically that doesn't give 01:27:12.850 --> 01:27:15.010 you any new capabilities that you didn't already 01:27:15.010 --> 01:27:19.510 have in C. It just makes it marginally more pleasant or quicker to type. 01:27:19.510 --> 01:27:24.100 So this line of code in C is identical to saying this line of code 01:27:24.100 --> 01:27:30.130 in C. Counter plus equals one semicolon means take the variable on the left 01:27:30.130 --> 01:27:31.417 and just add one to it. 01:27:31.417 --> 01:27:33.250 And it's slightly more succinct, and it just 01:27:33.250 --> 01:27:36.550 makes your code a little more readable because it's just fewer things for us 01:27:36.550 --> 01:27:38.290 humans to have to read. 01:27:38.290 --> 01:27:40.150 But you can even do one step further. 01:27:40.150 --> 01:27:42.585 Additional syntactic sugar exists, whereby 01:27:42.585 --> 01:27:43.960 you don't even need to type this. 01:27:43.960 --> 01:27:46.990 You can instead just do counter plus plus. 01:27:46.990 --> 01:27:49.520 Counter plus plus is the shortest hand notation 01:27:49.520 --> 01:27:53.320 in C for just adding one to a variable. 01:27:53.320 --> 01:27:54.040 All right. 01:27:54.040 --> 01:27:58.360 Besides variables, what else do we have in our toolkit as of last week? 01:27:58.360 --> 01:28:01.270 Well, we also had in our toolkit last week the notion, of course, 01:28:01.270 --> 01:28:02.230 of conditions. 01:28:02.230 --> 01:28:04.065 A condition was like a fork in the road that 01:28:04.065 --> 01:28:06.940 could allow you to do this thing, this other thing, or something else 01:28:06.940 --> 01:28:07.630 altogether. 01:28:07.630 --> 01:28:11.570 In Scratch for instance, if we wanted last week to compare two variables, 01:28:11.570 --> 01:28:13.780 x and y for inequality. 01:28:13.780 --> 01:28:15.010 Is x less than y? 01:28:15.010 --> 01:28:17.800 And if so, say x is less than y. 01:28:17.800 --> 01:28:19.780 How can we translate this to C? 01:28:19.780 --> 01:28:23.140 Well, the syntax is going to be quite simply this. 01:28:23.140 --> 01:28:24.010 Some new stuff. 01:28:24.010 --> 01:28:26.500 Some more parentheses, some more curly braces. 01:28:26.500 --> 01:28:29.830 But it kind of visually looks the same, albeit in text form. 01:28:29.830 --> 01:28:33.130 I literally say, if a space, then in parentheses I 01:28:33.130 --> 01:28:36.160 include my Boolean expression, recall those from last week. 01:28:36.160 --> 01:28:38.680 X less than y is my Boolean expression. 01:28:38.680 --> 01:28:42.100 Then notice I use an open curly brace and a close curly brace. 01:28:42.100 --> 01:28:45.460 And then I'm just leaving a blank line for one or more lines of code 01:28:45.460 --> 01:28:47.260 just like I might of last week. 01:28:47.260 --> 01:28:49.750 And in fact, let's put the equivalent line of code here. 01:28:49.750 --> 01:28:55.030 Print out using printf, x is less than y, backslash n. 01:28:55.030 --> 01:28:56.950 So we've already done that translation before. 01:28:56.950 --> 01:29:01.390 Say is just like printf, just like if now is like if. 01:29:01.390 --> 01:29:04.090 Strictly speaking, especially if you've programmed before, 01:29:04.090 --> 01:29:07.690 you do not need these two curly braces if you only 01:29:07.690 --> 01:29:10.820 have one line of code inside of the condition. 01:29:10.820 --> 01:29:14.410 However, stylistically for CS50 and for style50's sake, 01:29:14.410 --> 01:29:19.420 always include these curly braces nonetheless, and on their own lines. 01:29:19.420 --> 01:29:21.190 All right, what else can we do in Scratch? 01:29:21.190 --> 01:29:23.140 Recall that we can do if else. 01:29:23.140 --> 01:29:27.130 And we can go either one way in the fork or the other way in the fork. 01:29:27.130 --> 01:29:29.990 In C, the corresponding code is going to look like this. 01:29:29.990 --> 01:29:31.600 So it's almost the same as before. 01:29:31.600 --> 01:29:35.470 I've just added else, and then another curly brace and a close curly brace. 01:29:35.470 --> 01:29:37.240 And let me just add in the printf's. 01:29:37.240 --> 01:29:40.030 And you can see that in C this is really like the black and white, 01:29:40.030 --> 01:29:43.300 the text based version of what was very graphical last week, 01:29:43.300 --> 01:29:44.430 but the idea is the same. 01:29:44.430 --> 01:29:46.930 You just got to start to recognize where the parentheses go, 01:29:46.930 --> 01:29:48.850 where the curly braces go, the semicolons, 01:29:48.850 --> 01:29:51.100 and all that sort of visual stuff. 01:29:51.100 --> 01:29:54.940 All right, let's make one more Scratch comparison. 01:29:54.940 --> 01:29:58.870 Here is one where I said if x is less than y, say x is less than y. 01:29:58.870 --> 01:30:02.470 Else if x is greater than y, say x is greater than y. 01:30:02.470 --> 01:30:06.490 Else if x equals y, then say x equal to y. 01:30:06.490 --> 01:30:08.590 Now, here is where Scratch and C diverge. 01:30:08.590 --> 01:30:10.810 Because Scratch is meant to be very user friendly 01:30:10.810 --> 01:30:15.460 and not require long explanations of assignment operators, MIT for Scratch 01:30:15.460 --> 01:30:18.550 just use the equal sign for equality. 01:30:18.550 --> 01:30:22.120 Whereas C uses the equal sign for assignment from left to right, 01:30:22.120 --> 01:30:24.910 but this means equality as before. 01:30:24.910 --> 01:30:25.630 All right. 01:30:25.630 --> 01:30:27.930 Now, notice the difference here. 01:30:27.930 --> 01:30:30.990 Everything is a line by line translation, 01:30:30.990 --> 01:30:34.140 although we can put else if on the same line and else if on the same line. 01:30:34.140 --> 01:30:36.540 Except here is kind of a stupid workaround, right? 01:30:36.540 --> 01:30:40.200 In some sense humans decades ago realized, oh, shoot, at one point. 01:30:40.200 --> 01:30:42.870 We've already used the equal sign for assignment. 01:30:42.870 --> 01:30:45.180 What do we use now for equality? 01:30:45.180 --> 01:30:49.590 Well, MIT ignored that problem and just used a single equal sign for equality. 01:30:49.590 --> 01:30:53.100 Computer scientists inventing C and subsequent languages 01:30:53.100 --> 01:30:56.460 when comparing two values on the left and right for equality 01:30:56.460 --> 01:30:59.400 used two equal signs just because. 01:30:59.400 --> 01:31:01.950 One equal sign is assignment from right to left. 01:31:01.950 --> 01:31:04.800 Two equal signs is equality comparisons. 01:31:04.800 --> 01:31:06.870 Are these two values equal? 01:31:06.870 --> 01:31:08.220 But you know what? 01:31:08.220 --> 01:31:10.890 This is not necessarily well designed. 01:31:10.890 --> 01:31:11.760 It is correct. 01:31:11.760 --> 01:31:15.360 Logically both my scratch code and my C code is correct, 01:31:15.360 --> 01:31:19.560 but can anyone make an observation as to why the code is not 01:31:19.560 --> 01:31:21.300 necessarily well designed? 01:31:21.300 --> 01:31:24.090 I'm doing a little more work than I need to. 01:31:24.090 --> 01:31:26.730 I could tighten this code up a little bit. 01:31:26.730 --> 01:31:29.790 I could type slightly fewer characters and accomplish 01:31:29.790 --> 01:31:34.120 the same correct decision making. 01:31:34.120 --> 01:31:39.820 Any thoughts on in what sense this code is not perfectly designed? 01:31:39.820 --> 01:31:41.640 [INAUDIBLE], over to you. 01:31:41.640 --> 01:31:45.450 AUDIENCE: Yeah, so you used else if two times. 01:31:45.450 --> 01:31:48.828 You could have used else in the end and without the condition. 01:31:48.828 --> 01:31:50.370 DAVID MALAN: Really good observation. 01:31:50.370 --> 01:31:53.260 I'm using else if twice, which logically is fine. 01:31:53.260 --> 01:31:54.210 This code is correct. 01:31:54.210 --> 01:31:58.050 It's asking and answering the right questions, but consider this. 01:31:58.050 --> 01:32:02.460 If x is less than y, is one possibility, one fork in the road. 01:32:02.460 --> 01:32:05.100 Else if x greater than y is the second. 01:32:05.100 --> 01:32:08.610 What's the only other possibility logically in the world of math? 01:32:08.610 --> 01:32:11.730 Either it's less than or greater than or equal to. 01:32:11.730 --> 01:32:16.380 There's no reason to belabor the point and ask that third question explicitly. 01:32:16.380 --> 01:32:20.820 Let's simplify the code and marginally better design it as this. 01:32:20.820 --> 01:32:23.340 Just get rid of the else if as you proposed. 01:32:23.340 --> 01:32:26.580 Which isn't that much cleaner, isn't that much shorter, 01:32:26.580 --> 01:32:29.170 but it does avoid asking an additional question. 01:32:29.170 --> 01:32:32.497 So instead of maybe three questions being asked, now there's only two. 01:32:32.497 --> 01:32:35.580 And frankly, if you're writing a lot of code or doing this again and again 01:32:35.580 --> 01:32:39.780 and again, that kind of difference might very well add up and indeed 01:32:39.780 --> 01:32:42.130 give us now some better code. 01:32:42.130 --> 01:32:44.910 So now that I have the ability to use these conditions. 01:32:44.910 --> 01:32:47.337 Let's actually try converting this into a program. 01:32:47.337 --> 01:32:49.170 Let me go ahead and open up a program that I 01:32:49.170 --> 01:32:51.590 wrote in advance called conditions.c. 01:32:51.590 --> 01:32:55.170 And I have at the top of the file my two includes as usual. 01:32:55.170 --> 01:32:58.110 And then down here, I have pretty much what we just saw on the slide, 01:32:58.110 --> 01:33:02.220 plus two calls, or uses, of get_int. 01:33:02.220 --> 01:33:05.730 And then I'm just asking this question down here, if x less than y. 01:33:05.730 --> 01:33:07.260 Else if x greater than y. 01:33:07.260 --> 01:33:09.400 Else go ahead and do the following. 01:33:09.400 --> 01:33:13.410 So it's just a copy paste pretty much of the Scratch translation. 01:33:13.410 --> 01:33:16.410 Let me go ahead and make conditions, which again, conditions.c 01:33:16.410 --> 01:33:17.490 is the name of the file. 01:33:17.490 --> 01:33:18.840 No apparent mistakes. 01:33:18.840 --> 01:33:22.200 So let me go ahead and run dot slash conditions, Enter. 01:33:22.200 --> 01:33:24.330 And x will be 1, y is 2. 01:33:24.330 --> 01:33:26.610 And indeed, x is less than y. 01:33:26.610 --> 01:33:31.560 If I go ahead and run this, this time for instance, with how about 10 and 5. 01:33:31.560 --> 01:33:33.060 X is greater than y. 01:33:33.060 --> 01:33:36.170 And then lastly, if I go ahead and run this with 4 and 4. 01:33:36.170 --> 01:33:37.410 X is equal to y. 01:33:37.410 --> 01:33:40.080 So I now have a C program that is adding conditions 01:33:40.080 --> 01:33:43.650 for me, which is actually then allowing me to make decisions and print out 01:33:43.650 --> 01:33:46.410 one thing potentially or the other. 01:33:46.410 --> 01:33:49.050 But let me do something slightly fancier. 01:33:49.050 --> 01:33:51.720 Let me go ahead and open up another-- 01:33:51.720 --> 01:33:53.640 let me write this program from Scratch. 01:33:53.640 --> 01:33:56.820 Suppose I want to write a program called agree.c 01:33:56.820 --> 01:33:59.010 that stimulates the idea of like these stupid forms 01:33:59.010 --> 01:34:02.100 that you have to agree to when using a piece of software 01:34:02.100 --> 01:34:03.480 for the first time or the like. 01:34:03.480 --> 01:34:07.530 Or even when I deleted a file before I had to type in yes or y in order 01:34:07.530 --> 01:34:08.340 to proceed. 01:34:08.340 --> 01:34:12.240 Let me go ahead and include cd50.h at the top. 01:34:12.240 --> 01:34:15.420 Let me go ahead and include stdio.h at the top. 01:34:15.420 --> 01:34:18.480 And then my int main void, which is copy paste from before. 01:34:18.480 --> 01:34:19.500 And now let me do this. 01:34:19.500 --> 01:34:22.542 Let me go ahead and get, not an input from the user, and not even a word. 01:34:22.542 --> 01:34:27.060 Let's keep it simple and just ask the user for y or n, for yes or no. 01:34:27.060 --> 01:34:30.660 Let me go ahead and give myself a char, and I'll call it c. 01:34:30.660 --> 01:34:32.790 But I could call it anything, like answer. 01:34:32.790 --> 01:34:35.580 But c seems reasonable if I only have one char. 01:34:35.580 --> 01:34:38.520 Let me go ahead and call the function, get_char. 01:34:38.520 --> 01:34:42.120 And let me just ask, do you agree, question mark. 01:34:42.120 --> 01:34:43.870 And then let me go ahead and compare this. 01:34:43.870 --> 01:34:52.890 So if c equals y, then let me go ahead and print out agreed backslash n. 01:34:52.890 --> 01:35:01.590 Else if c equals n, let me go ahead and print out for instance, not agreed. 01:35:01.590 --> 01:35:07.108 Now unfortunately, I've made a couple of mistakes here that at least one 01:35:07.108 --> 01:35:09.400 of which might be a little more obvious than the other. 01:35:09.400 --> 01:35:13.950 Any thoughts on what mistakes or bugs I might have introduced already 01:35:13.950 --> 01:35:16.260 into this program? 01:35:16.260 --> 01:35:17.100 Anyone at all? 01:35:17.100 --> 01:35:19.020 Yeah, how about, Olivia. 01:35:19.020 --> 01:35:20.460 What do you think? 01:35:20.460 --> 01:35:23.580 AUDIENCE: For one thing that for the Boolean 01:35:23.580 --> 01:35:27.330 you did use a single equals sign instead of the double. 01:35:27.330 --> 01:35:28.080 DAVID MALAN: Good. 01:35:28.080 --> 01:35:31.650 So I use the single equal sign instead of double, so I need to fix that. 01:35:31.650 --> 01:35:34.070 And there's another even more subtle bug. 01:35:34.070 --> 01:35:38.390 And this is because C is very specific when it comes to its data types. 01:35:38.390 --> 01:35:41.330 All this time I've been using double quotes for strings, 01:35:41.330 --> 01:35:45.230 but it turns out in C you have to use single quotes when 01:35:45.230 --> 01:35:47.030 you're comparing individual characters. 01:35:47.030 --> 01:35:51.440 So I'm going to go in here and change only the quotes around y and n 01:35:51.440 --> 01:35:52.320 to be single quotes. 01:35:52.320 --> 01:35:52.820 Why? 01:35:52.820 --> 01:35:55.100 Because I'm now dealing with the world of chars. 01:35:55.100 --> 01:35:58.400 Chars are individual characters like y or n. 01:35:58.400 --> 01:36:00.560 And when you are talking about characters, 01:36:00.560 --> 01:36:03.060 you need to quote them literally like this. 01:36:03.060 --> 01:36:05.060 The variable name, c, doesn't need to be quoted. 01:36:05.060 --> 01:36:07.100 But y and n do need to be quoted. 01:36:07.100 --> 01:36:09.860 But I don't need to change any of my other quotes in the file 01:36:09.860 --> 01:36:14.810 because those are still strings of text that is actual phrases or sentences. 01:36:14.810 --> 01:36:17.420 So let me go ahead and try running make agree. 01:36:17.420 --> 01:36:18.590 It compiles OK. 01:36:18.590 --> 01:36:20.870 Let me go ahead and run dot slash agree. 01:36:20.870 --> 01:36:21.680 Do I agree? 01:36:21.680 --> 01:36:23.210 Let me go ahead and type in y. 01:36:23.210 --> 01:36:24.540 Agreed, I like that. 01:36:24.540 --> 01:36:26.510 So let me try n, no. 01:36:26.510 --> 01:36:27.620 Not I agreed. 01:36:27.620 --> 01:36:31.550 And I left off a backslash n, so let me fix that real quick just 01:36:31.550 --> 01:36:32.780 for consistency. 01:36:32.780 --> 01:36:35.330 Let me recompile my program and pretend that never happened. 01:36:35.330 --> 01:36:37.020 But let me very reasonably now do this. 01:36:37.020 --> 01:36:38.330 Dot slash agree. 01:36:38.330 --> 01:36:39.170 I want to agree. 01:36:39.170 --> 01:36:41.656 And yes, capital y. 01:36:41.656 --> 01:36:43.020 Huh, nothing happened. 01:36:43.020 --> 01:36:45.480 What about n, capital N? 01:36:45.480 --> 01:36:46.413 Nothing happened. 01:36:46.413 --> 01:36:47.580 But the program still works. 01:36:47.580 --> 01:36:49.560 If I do lower case it works. 01:36:49.560 --> 01:36:51.390 And if I do lower case there it works. 01:36:51.390 --> 01:36:52.388 So what's going on? 01:36:52.388 --> 01:36:54.930 Well, again, the computer's only going to take you literally. 01:36:54.930 --> 01:36:57.013 And even though we humans might be, oh, it's fine. 01:36:57.013 --> 01:36:58.440 It's upper case or a lower case. 01:36:58.440 --> 01:37:00.700 You have to be more explicit. 01:37:00.700 --> 01:37:03.010 So we can ask two questions as follows. 01:37:03.010 --> 01:37:05.400 We could do something like else if c equals 01:37:05.400 --> 01:37:08.460 equals capital Y in single quotes. 01:37:08.460 --> 01:37:11.880 You could imagine, again, saying agreed like this. 01:37:11.880 --> 01:37:15.740 But just like last week when I started copying and pasting Scratch blocks, 01:37:15.740 --> 01:37:17.730 that's probably not very good design. 01:37:17.730 --> 01:37:24.150 Similarly, this block of code, lines 11 through 14, is almost identical to 7 01:37:24.150 --> 01:37:25.020 through 10. 01:37:25.020 --> 01:37:26.590 Let's just get rid of one of them. 01:37:26.590 --> 01:37:28.632 And let's see if we can't combine these thoughts. 01:37:28.632 --> 01:37:34.170 Let me express if c equals equals y, or c equals equals capital Y. 01:37:34.170 --> 01:37:36.480 And indeed, you can use this vertical bar 01:37:36.480 --> 01:37:39.960 operator, which is the logical or operator, 01:37:39.960 --> 01:37:43.290 and actually say two questions at once. 01:37:43.290 --> 01:37:46.320 It turns out you can do this with the notion of and, a logical 01:37:46.320 --> 01:37:48.330 and, by using ampersand ampersand. 01:37:48.330 --> 01:37:49.750 More on those another time. 01:37:49.750 --> 01:37:52.320 But two vertical bars is the equivalent of just saying, 01:37:52.320 --> 01:37:55.650 if this on the left or this on the right. 01:37:55.650 --> 01:37:58.230 And now if I save and recompile the program with make 01:37:58.230 --> 01:38:00.600 agree, and dot slash agree. 01:38:00.600 --> 01:38:05.910 You'll see that I can type in y in lowercase, or Y in uppercase, 01:38:05.910 --> 01:38:07.660 and now it works. 01:38:07.660 --> 01:38:10.500 So again, it would have been correct to just add 01:38:10.500 --> 01:38:12.240 another else if and another else if. 01:38:12.240 --> 01:38:15.810 But again, not necessary because I can combine these thoughts 01:38:15.810 --> 01:38:17.730 and make my program better designed. 01:38:17.730 --> 01:38:21.810 And notice too, all this time I've been very religiously 01:38:21.810 --> 01:38:25.380 indenting every time I'm inside of curly braces. 01:38:25.380 --> 01:38:29.130 Indenting every time I have an if condition or an else if. 01:38:29.130 --> 01:38:34.600 So I'm manifesting, hopefully, good style aesthetics as well. 01:38:34.600 --> 01:38:35.290 All right. 01:38:35.290 --> 01:38:37.980 Well, now let's consider that we have the ability not 01:38:37.980 --> 01:38:41.730 only to express conditions, but how about also these things called loops. 01:38:41.730 --> 01:38:44.340 Well, turns out in Scratch we had very straightforward loops. 01:38:44.340 --> 01:38:45.810 Do the following forever. 01:38:45.810 --> 01:38:47.070 C is a little clunkier. 01:38:47.070 --> 01:38:51.870 There's no forever keyword in C, but we can mimic this idea as follows. 01:38:51.870 --> 01:38:54.960 The closest way to translate forever in C 01:38:54.960 --> 01:38:58.410 is actually to say while, which kind of has the right semantics in English. 01:38:58.410 --> 01:39:01.500 Like, while something is the case, do this, 01:39:01.500 --> 01:39:03.120 but you have to be even more explicit. 01:39:03.120 --> 01:39:06.550 You can't just say while and then say printf hello, world. 01:39:06.550 --> 01:39:10.470 It turns out in C that while, similar to a condition, 01:39:10.470 --> 01:39:15.180 is constantly asking a question to decide whether or not to continue. 01:39:15.180 --> 01:39:18.970 Very similar, again, to a condition with its own Boolean expression. 01:39:18.970 --> 01:39:23.970 So with while in C, you have to have parentheses after the word while, 01:39:23.970 --> 01:39:26.670 and you have to ask a question in those parentheses. 01:39:26.670 --> 01:39:30.240 You have to say something like, x greater than y, x less than y, 01:39:30.240 --> 01:39:31.120 or the like. 01:39:31.120 --> 01:39:33.120 But this is a bit of a corner case in the sense 01:39:33.120 --> 01:39:35.130 that if you want to do something forever, 01:39:35.130 --> 01:39:36.765 who cares what the question is. 01:39:36.765 --> 01:39:39.450 You just want the answer always to be yes. 01:39:39.450 --> 01:39:42.060 Or in computer terms, always to be true. 01:39:42.060 --> 01:39:46.050 And the most blunt way to express true always 01:39:46.050 --> 01:39:48.250 is literally to write the word true. 01:39:48.250 --> 01:39:50.432 So even though this looks a little weird, this in C 01:39:50.432 --> 01:39:52.140 is how you deliberately induce what we'll 01:39:52.140 --> 01:39:57.300 call an infinite loop that never stops because true is always by definition 01:39:57.300 --> 01:39:57.960 true. 01:39:57.960 --> 01:40:00.420 You don't even have to ask a more complicated question. 01:40:00.420 --> 01:40:03.490 You could put a less than sign, a greater than sign, or the like. 01:40:03.490 --> 01:40:05.532 But if you just want something to happen forever, 01:40:05.532 --> 01:40:09.450 this is the most canonical way to express something forever. 01:40:09.450 --> 01:40:12.120 Well, what if you want to do something finitely many times? 01:40:12.120 --> 01:40:14.850 Well, we can do that in C as well using what's 01:40:14.850 --> 01:40:18.120 going to be called a for loop, or a while loop. 01:40:18.120 --> 01:40:21.070 Well, let's consider both of these in turn. 01:40:21.070 --> 01:40:25.920 So if I want to do something 50 times, the most mechanical manual way 01:40:25.920 --> 01:40:28.620 I can think of is like just count on my fingers, right? 01:40:28.620 --> 01:40:31.200 Like, one, two, three, all the way up to 50 somehow. 01:40:31.200 --> 01:40:34.050 Or 10 maximally on my hands. 01:40:34.050 --> 01:40:37.260 So how can I do something finitely many times in C? 01:40:37.260 --> 01:40:39.300 Well, I have at my disposal variables. 01:40:39.300 --> 01:40:41.610 So let me give myself a variable called counter. 01:40:41.610 --> 01:40:44.025 Initialize it to zero semicolon. 01:40:44.025 --> 01:40:45.900 And the data type will be int, because I just 01:40:45.900 --> 01:40:47.640 need to count much like on my fingers. 01:40:47.640 --> 01:40:48.390 But you know what? 01:40:48.390 --> 01:40:50.310 Counter is a little verbose. 01:40:50.310 --> 01:40:54.150 Programmers whenever they're counting frequently, just counting up from zero 01:40:54.150 --> 01:40:58.680 on up, they'll often just use i for integer, or c for character, 01:40:58.680 --> 01:41:00.000 or s for string. 01:41:00.000 --> 01:41:02.110 You don't want to do that always in your code. 01:41:02.110 --> 01:41:05.280 It's sometimes better for your variables to be more descriptively named, 01:41:05.280 --> 01:41:08.230 but for a stupid variable that's just going to count from zero on up, 01:41:08.230 --> 01:41:10.092 let's just keep it simple and call it i. 01:41:10.092 --> 01:41:12.202 I can now do a while loop again, but now I 01:41:12.202 --> 01:41:14.910 have to ask a question because I don't want this running forever. 01:41:14.910 --> 01:41:16.200 I want it running 50 times. 01:41:16.200 --> 01:41:17.542 What question could I ask? 01:41:17.542 --> 01:41:18.750 Well, why don't I just check. 01:41:18.750 --> 01:41:20.970 While i is less than 50. 01:41:20.970 --> 01:41:23.010 So it's like counting up on 50 fingers. 01:41:23.010 --> 01:41:27.300 Let me start at zero and count up to, but not through i equals 50. 01:41:27.300 --> 01:41:30.870 So so long as i is less than 50, do the following. 01:41:30.870 --> 01:41:31.800 What do I want to do? 01:41:31.800 --> 01:41:33.300 I want to keep printing out hello, world. 01:41:33.300 --> 01:41:33.870 Hello, world. 01:41:33.870 --> 01:41:34.980 Hello, world. 01:41:34.980 --> 01:41:36.210 But I'm not done. 01:41:36.210 --> 01:41:40.830 Because on every iteration of this loop, on every cycle of this loop, 01:41:40.830 --> 01:41:42.750 I need to do one more thing mathematically. 01:41:42.750 --> 01:41:45.330 I need to add another finger, add another finger. 01:41:45.330 --> 01:41:48.270 Or in other words, I need to add one to i. 01:41:48.270 --> 01:41:52.410 So let me go ahead and set i equal to whatever it is now, plus one. 01:41:52.410 --> 01:41:54.300 But again, we have some syntactic sugar just 01:41:54.300 --> 01:41:56.680 to make this a little cleaner, a little tighter. 01:41:56.680 --> 01:41:58.140 I could do i plus equals one. 01:41:58.140 --> 01:42:01.410 Or even more succinctly, i plus plus. 01:42:01.410 --> 01:42:05.310 So even though this is way more annoying to implement than in Scratch 01:42:05.310 --> 01:42:09.840 where MIT just gives you what you want, in C we have all of the building blocks 01:42:09.840 --> 01:42:16.920 now with variables and with loops to implement the notion of repeating 01:42:16.920 --> 01:42:18.540 some finite number of times. 01:42:18.540 --> 01:42:20.208 But there's another way to do this. 01:42:20.208 --> 01:42:22.500 And as you might have discovered with problem set zero, 01:42:22.500 --> 01:42:25.440 there's different ways to achieve the same goals in Scratch. 01:42:25.440 --> 01:42:27.600 Similarly in C, I could do this. 01:42:27.600 --> 01:42:31.650 I could just start counting at one and count up through 50. 01:42:31.650 --> 01:42:34.560 So there's no greater than or equal sign key on your keyboard, 01:42:34.560 --> 01:42:36.570 most likely, or less than or equal to. 01:42:36.570 --> 01:42:40.080 So in C, as with other languages, you just use two characters. 01:42:40.080 --> 01:42:43.290 You do less than sign followed by the equals sign. 01:42:43.290 --> 01:42:45.570 And that expresses less than or equal to. 01:42:45.570 --> 01:42:46.800 So this is also correct. 01:42:46.800 --> 01:42:49.870 If I start counting at one I need to count through 50. 01:42:49.870 --> 01:42:51.220 You can do this. 01:42:51.220 --> 01:42:51.885 Don't do this. 01:42:51.885 --> 01:42:53.370 This is unconventional. 01:42:53.370 --> 01:42:55.800 And like programmers will conventionally, 01:42:55.800 --> 01:42:58.590 per last week when we started always counting from zero with all 01:42:58.590 --> 01:43:03.480 the light bulbs off, they'll instead start at zero and count up to 50. 01:43:03.480 --> 01:43:06.760 Which gives you zero through 49 implicitly. 01:43:06.760 --> 01:43:08.350 So do this, not that. 01:43:08.350 --> 01:43:10.440 But this does speak to the fact that you can solve 01:43:10.440 --> 01:43:12.790 problems in so many different ways. 01:43:12.790 --> 01:43:14.490 There's another way, fundamentally, too. 01:43:14.490 --> 01:43:18.090 We could start counting from 50 down to zero. 01:43:18.090 --> 01:43:22.650 The only difference being we have to do i minus minus instead of i plus plus. 01:43:22.650 --> 01:43:25.410 So again, that's three different ways to solve the same problem. 01:43:25.410 --> 01:43:28.327 And again, you'll start to have the right instincts and muscle memory, 01:43:28.327 --> 01:43:31.260 and you'll also start to see common patterns in lecture code, your TF 01:43:31.260 --> 01:43:34.410 or teaching assistants code, books and references online. 01:43:34.410 --> 01:43:38.130 There just tend to be the ways to do things even though all of these 01:43:38.130 --> 01:43:39.520 are still right. 01:43:39.520 --> 01:43:40.050 All right. 01:43:40.050 --> 01:43:42.000 One more approach to loops here. 01:43:42.000 --> 01:43:45.060 It turns out there's another loop construct that's a little more cryptic, 01:43:45.060 --> 01:43:46.500 and it's called a for loop. 01:43:46.500 --> 01:43:48.900 And it allows you to automate-- or rather, 01:43:48.900 --> 01:43:52.560 allows you to express all of those steps a little more concisely. 01:43:52.560 --> 01:43:57.720 So for printf hello, world is going to get us one step closer to printing 01:43:57.720 --> 01:43:59.340 hello, world 50 times. 01:43:59.340 --> 01:44:03.090 But the for statement, just like the while statement, 01:44:03.090 --> 01:44:05.580 comes with necessary parentheses after it, 01:44:05.580 --> 01:44:08.130 but this time you can put more stuff in the parentheses. 01:44:08.130 --> 01:44:10.050 It's not just a Boolean expression. 01:44:10.050 --> 01:44:12.630 First, the first thing in the parentheses 01:44:12.630 --> 01:44:16.110 is you can initialize any variable you want to some value. 01:44:16.110 --> 01:44:18.830 I might say encounter equals zero, or more succinctly, 01:44:18.830 --> 01:44:21.450 int i equals zero semicolon. 01:44:21.450 --> 01:44:23.860 But the way the for loop looks, it's a little funky. 01:44:23.860 --> 01:44:25.990 You can do multiple things on one line. 01:44:25.990 --> 01:44:29.040 The second thing inside of the parentheses to a for loop 01:44:29.040 --> 01:44:32.370 is a condition that you want to check again and again and again. 01:44:32.370 --> 01:44:35.220 And the last thing in the parentheses of a for loop 01:44:35.220 --> 01:44:38.790 is an update, or an incrementation or decrementation 01:44:38.790 --> 01:44:41.490 whereby you can do i equals i plus one. 01:44:41.490 --> 01:44:44.010 Or rather, let's just do i plus equals one. 01:44:44.010 --> 01:44:46.830 Or even more succinctly, i plus plus. 01:44:46.830 --> 01:44:49.710 This is perhaps the most conventional way 01:44:49.710 --> 01:44:54.540 in C and in other programming languages to do something 50 times, 01:44:54.540 --> 01:44:56.042 or a finite number of times. 01:44:56.042 --> 01:44:58.500 It's different looking from the things we've seen thus far. 01:44:58.500 --> 01:45:00.540 There's semicolons in weirder places. 01:45:00.540 --> 01:45:02.020 There's more stuff in parentheses. 01:45:02.020 --> 01:45:04.200 So again, you'll develop the muscle memory overall. 01:45:04.200 --> 01:45:08.430 But for now just realize this says, initialize i to zero. 01:45:08.430 --> 01:45:09.540 Check the condition. 01:45:09.540 --> 01:45:12.420 And if i is less than 50 print hello, world. 01:45:12.420 --> 01:45:14.460 Then update i. 01:45:14.460 --> 01:45:16.060 Then check the condition. 01:45:16.060 --> 01:45:18.420 If it's less than 50, print hello, world. 01:45:18.420 --> 01:45:20.190 Then increment i. 01:45:20.190 --> 01:45:21.690 Then check the condition. 01:45:21.690 --> 01:45:24.340 Then if it's less then, print hello, world. 01:45:24.340 --> 01:45:27.660 So the initialization of the variable happens once. 01:45:27.660 --> 01:45:29.970 Everything else happens again and again and again 01:45:29.970 --> 01:45:33.810 until you've done this some 50 times. 01:45:33.810 --> 01:45:34.530 All right. 01:45:34.530 --> 01:45:36.780 So with those building blocks, that's kind of it 01:45:36.780 --> 01:45:40.110 for our translation of Scratch into C. Let's now start 01:45:40.110 --> 01:45:44.130 to build up some more interesting programs in practice 01:45:44.130 --> 01:45:45.450 for instance, abstraction. 01:45:45.450 --> 01:45:48.570 So abstraction, recall, was this problem solving principle 01:45:48.570 --> 01:45:53.250 whereby you can simplify otherwise more complicated details. 01:45:53.250 --> 01:45:57.570 And abstraction is a simplification on top of more complicated details 01:45:57.570 --> 01:46:00.480 or implementation details as a programmer might say. 01:46:00.480 --> 01:46:02.430 So for instance, let me go ahead and write 01:46:02.430 --> 01:46:06.690 a program here called meow, similar to last week, but this time in C. 01:46:06.690 --> 01:46:09.690 And in order to make a cat meow textually, 01:46:09.690 --> 01:46:12.980 let me give myself stdio.h at the top. 01:46:12.980 --> 01:46:16.140 Int main void down here. 01:46:16.140 --> 01:46:18.105 Again, I'm in a file called meow.c. 01:46:18.105 --> 01:46:21.387 And I've included stdio.h and int main void. 01:46:21.387 --> 01:46:23.970 And now I'm going to go ahead and just do something like this. 01:46:23.970 --> 01:46:27.810 Printf, quote unquote, "meow", backslash n. 01:46:27.810 --> 01:46:31.110 And I want this cat to meow textually three times. 01:46:31.110 --> 01:46:32.700 Let me save that file. 01:46:32.700 --> 01:46:34.150 Make meow. 01:46:34.150 --> 01:46:34.650 All right. 01:46:34.650 --> 01:46:36.090 Now, dot slash meow. 01:46:36.090 --> 01:46:37.660 Meow, meow, meow all in text. 01:46:37.660 --> 01:46:40.740 So not nearly as cute or pretty as the one with the cat last week, 01:46:40.740 --> 01:46:42.630 but it's correct. 01:46:42.630 --> 01:46:45.210 But it's not very well designed, right? 01:46:45.210 --> 01:46:46.740 Because I'm repeating myself. 01:46:46.740 --> 01:46:50.010 I literally copied and pasted, and those are bad instincts. 01:46:50.010 --> 01:46:52.770 But now we have the ability to do things with loops. 01:46:52.770 --> 01:46:55.530 So let me actually delete this part of the function. 01:46:55.530 --> 01:46:58.740 And let me try to remember from the example before. 01:46:58.740 --> 01:47:01.557 If I want to do something three times I could use a while loop, 01:47:01.557 --> 01:47:03.390 but that felt like a bunch of lines of code. 01:47:03.390 --> 01:47:04.050 Let me do this. 01:47:04.050 --> 01:47:06.150 Int i equals zero. 01:47:06.150 --> 01:47:07.950 i less than three. 01:47:07.950 --> 01:47:09.510 i plus plus. 01:47:09.510 --> 01:47:14.850 So cryptic, but this, again, is the de facto way of doing something 01:47:14.850 --> 01:47:16.290 a finite number of times. 01:47:16.290 --> 01:47:20.790 Initialize some variable, like i to zero, check a condition, 01:47:20.790 --> 01:47:23.490 and keep incrementing your variable again and again 01:47:23.490 --> 01:47:26.400 so that it executes a total of that many times. 01:47:26.400 --> 01:47:28.830 Now, let me go ahead and printf meow-- 01:47:28.830 --> 01:47:32.130 mellow-- meow on the inside. 01:47:32.130 --> 01:47:35.280 Let me go ahead and recompile meow by make meow. 01:47:35.280 --> 01:47:37.470 Let me dot slash meow, and voila. 01:47:37.470 --> 01:47:40.297 Now the program is arguably better designed. 01:47:40.297 --> 01:47:41.880 But let me take this one step further. 01:47:41.880 --> 01:47:48.150 Recall that the trajectory last week was to not only implement meow 01:47:48.150 --> 01:47:51.382 with better design, without repeating yourself, thereby using a loop. 01:47:51.382 --> 01:47:53.340 But remember we introduced the abstraction that 01:47:53.340 --> 01:47:55.350 was a custom puzzle piece called meow. 01:47:55.350 --> 01:47:59.462 So in C, turns out we have the ability to make our own functions as well. 01:47:59.462 --> 01:48:02.670 And the syntax is going to take a little getting used to, but let me go ahead 01:48:02.670 --> 01:48:03.330 and do this. 01:48:03.330 --> 01:48:05.250 Let me get rid of my printf here. 01:48:05.250 --> 01:48:08.640 And at the bottom of my file-- actually, at the top of my file 01:48:08.640 --> 01:48:13.890 I'm going to go ahead and type void meow void. 01:48:13.890 --> 01:48:16.140 Which is very cryptic for today, but again, this 01:48:16.140 --> 01:48:19.140 is fine to be boilerplate, copy pasted for now. 01:48:19.140 --> 01:48:21.720 Let me go ahead and just printf meow here. 01:48:21.720 --> 01:48:24.780 Even though we haven't explained and won't explain today 01:48:24.780 --> 01:48:29.010 what this keyword void means, what I've done in lines three through six 01:48:29.010 --> 01:48:31.230 is create my own custom function. 01:48:31.230 --> 01:48:33.990 C does not come with a function called meow. 01:48:33.990 --> 01:48:37.170 CS50's library does not come with a function called meow. 01:48:37.170 --> 01:48:39.510 But now thanks to me, there exists a function 01:48:39.510 --> 01:48:43.440 called meow whose sole purpose in life is just to print out meow. 01:48:43.440 --> 01:48:46.860 But what's cool about this now is that down here, just 01:48:46.860 --> 01:48:51.630 like with Scratch last week, I can now call a function called meow. 01:48:51.630 --> 01:48:53.940 And my code is a little more readable because it rather 01:48:53.940 --> 01:48:58.500 says what it does by just by way of the function's name. 01:48:58.500 --> 01:49:01.020 And let me go ahead now and compile this. 01:49:01.020 --> 01:49:02.760 Make meow. 01:49:02.760 --> 01:49:04.080 So far so good. 01:49:04.080 --> 01:49:08.010 Dot slash meow, and it seems to work OK. 01:49:08.010 --> 01:49:10.950 But I don't love the fact that I've implemented meow 01:49:10.950 --> 01:49:12.120 at the top of the file. 01:49:12.120 --> 01:49:13.290 It's not a big deal. 01:49:13.290 --> 01:49:18.210 By convention we'll typically put custom functions at the bottom of the file. 01:49:18.210 --> 01:49:18.900 Why? 01:49:18.900 --> 01:49:21.570 Only because when a programmer, or in our case, 01:49:21.570 --> 01:49:25.110 a teaching fellow wants to understand your code from top to bottom. 01:49:25.110 --> 01:49:29.100 It's just human convention to put the main program, the main function rather, 01:49:29.100 --> 01:49:31.410 at the top of your file. 01:49:31.410 --> 01:49:36.270 The problem is when I do this, I'm going to have created a problem for myself. 01:49:36.270 --> 01:49:38.670 When I run make meow now, darn it. 01:49:38.670 --> 01:49:42.750 Two errors generated, and so there's a couple of bugs to be solved. 01:49:42.750 --> 01:49:44.583 But first, Brian, a question from the group. 01:49:44.583 --> 01:49:47.375 BRIAN YU: There was a question that came in from the chat about why 01:49:47.375 --> 01:49:49.770 it is that on line five, for example, you don't have 01:49:49.770 --> 01:49:51.480 a semicolon at the end of the for loop. 01:49:51.480 --> 01:49:53.580 And on line 11 you don't have a semicolon 01:49:53.580 --> 01:49:54.940 at the end of the function name. 01:49:54.940 --> 01:49:58.403 So why do some lines need semicolons at the end, but other lines don't? 01:49:58.403 --> 01:49:59.820 DAVID MALAN: Really good question. 01:49:59.820 --> 01:50:03.340 Why do some of these lines not have semicolons, but others do? 01:50:03.340 --> 01:50:06.990 The short answer, not to be glib, is honestly just because. 01:50:06.990 --> 01:50:10.710 The way the language was designed was that you should generally 01:50:10.710 --> 01:50:15.120 finish your thoughts when expressing verbs or actions or functions 01:50:15.120 --> 01:50:16.110 with semicolons. 01:50:16.110 --> 01:50:18.300 And we've seen that after printf for instance. 01:50:18.300 --> 01:50:20.130 We've just seen that after meow. 01:50:20.130 --> 01:50:22.830 However, when you're using other programming constructs, 01:50:22.830 --> 01:50:28.500 like loops or like custom functions, you don't have semicolons there. 01:50:28.500 --> 01:50:29.070 Why? 01:50:29.070 --> 01:50:31.200 Some humans years ago just decided that we 01:50:31.200 --> 01:50:32.783 don't need semicolons in those places. 01:50:32.783 --> 01:50:36.075 And this is one of those things that it will take a while to develop the muscle 01:50:36.075 --> 01:50:39.030 memory and the mental model for recognizing where those things go 01:50:39.030 --> 01:50:39.630 and don't. 01:50:39.630 --> 01:50:42.450 But thus far the only places we've seen semicolons 01:50:42.450 --> 01:50:46.140 are at the ends of functions, like meow and printf here. 01:50:46.140 --> 01:50:51.750 And now, admittedly weirdly, inside of the parentheses for the for loop. 01:50:51.750 --> 01:50:55.740 But again, when tackling problem sets one and the first lab and so forth, 01:50:55.740 --> 01:50:58.920 you'll often want to refer back to examples like these in the slides 01:50:58.920 --> 01:51:01.410 and the references in your section so that you can 01:51:01.410 --> 01:51:03.640 wrap your mind around these patterns. 01:51:03.640 --> 01:51:07.320 So let me go ahead now and solve the two problems I seem to have created here. 01:51:07.320 --> 01:51:10.560 It's a little non obvious, but it's reminiscent of what we've seen before. 01:51:10.560 --> 01:51:14.670 Implicit declaration of function meow is invalid in C99. 01:51:14.670 --> 01:51:19.230 C99 is referring to the 1999 version of C the language we're using, 01:51:19.230 --> 01:51:22.500 but it's just getting confused, C is right now. 01:51:22.500 --> 01:51:23.250 Well, why is that? 01:51:23.250 --> 01:51:27.120 Well, let me scroll up here and let me make the point that frankly C, 01:51:27.120 --> 01:51:29.640 and in turn my compiler, they're not that bright. 01:51:29.640 --> 01:51:32.370 Like, they're only going to do what I tell them to do explicitly. 01:51:32.370 --> 01:51:36.420 And the problem at the moment is that when the compiler reads my code 01:51:36.420 --> 01:51:41.650 from top to bottom, left or right, it is not until line 11 01:51:41.650 --> 01:51:43.960 the meow function even exists. 01:51:43.960 --> 01:51:48.880 However, I am trying on line seven at the moment to use that meow function. 01:51:48.880 --> 01:51:51.250 So my compiler, frankly, just doesn't know 01:51:51.250 --> 01:51:53.830 what meow is because it hasn't gotten to meow later. 01:51:53.830 --> 01:51:56.290 And the compiler is not smart enough, or not 01:51:56.290 --> 01:51:59.765 user friendly enough to read everything first and then decide 01:51:59.765 --> 01:52:00.640 if there's a problem. 01:52:00.640 --> 01:52:03.310 It's only going to read it once through top to bottom, 01:52:03.310 --> 01:52:06.320 and it's going to yell at you the moment it encounters the problem. 01:52:06.320 --> 01:52:09.430 So the solution to this is quite simply, move the function 01:52:09.430 --> 01:52:10.507 to the top of your file. 01:52:10.507 --> 01:52:13.090 But again, that just gets annoying eventually because then you 01:52:13.090 --> 01:52:15.298 have to go fishing for your main function which might 01:52:15.298 --> 01:52:17.320 be dozens of lines down in the file. 01:52:17.320 --> 01:52:20.620 Or there's another way, and we'll explain this in due time too. 01:52:20.620 --> 01:52:26.260 But you can also copy the very first line only of your custom function. 01:52:26.260 --> 01:52:29.890 Put it at the top of your file above main. 01:52:29.890 --> 01:52:33.710 And then, to Brian's question end that with a semicolon. 01:52:33.710 --> 01:52:34.840 So this is weird. 01:52:34.840 --> 01:52:39.490 This is what's generally known as a prototype, which is a hint only. 01:52:39.490 --> 01:52:42.250 It's sort of a clever way of telling the compiler there 01:52:42.250 --> 01:52:45.430 will exist a function called meow, but just not yet. 01:52:45.430 --> 01:52:46.720 But know that it will. 01:52:46.720 --> 01:52:49.480 And it's just kind of a workaround, a common workaround, 01:52:49.480 --> 01:52:52.040 for that particular problem. 01:52:52.040 --> 01:52:52.540 All right. 01:52:52.540 --> 01:52:56.020 So let me go ahead and make one more change, one more change here. 01:52:56.020 --> 01:52:59.440 Suppose that I want to really finish off this meow example 01:52:59.440 --> 01:53:00.610 just like we did in Scratch. 01:53:00.610 --> 01:53:06.110 Whereby we also allow meow to take some number of meows as input. 01:53:06.110 --> 01:53:09.470 So I don't want to have this for loop anymore in my main function. 01:53:09.470 --> 01:53:15.010 Suppose I just want to be able to say, meow three, inside of my main function. 01:53:15.010 --> 01:53:17.560 Three thereby being the input to the meow function. 01:53:17.560 --> 01:53:22.810 I now need to change my custom function, just like I did last week, as follows. 01:53:22.810 --> 01:53:25.390 It turns out-- and more on this in the weeks to come-- 01:53:25.390 --> 01:53:31.150 that this mention a void here on line 11 refers to the return value or output 01:53:31.150 --> 01:53:31.870 of this function. 01:53:31.870 --> 01:53:36.400 Long story short, my custom meow function today has no return value. 01:53:36.400 --> 01:53:39.520 It doesn't output anything per se, it instead only 01:53:39.520 --> 01:53:42.700 has a side effect of printing visually on the screen. 01:53:42.700 --> 01:53:44.140 But it does have an input. 01:53:44.140 --> 01:53:48.850 And if you want to function in C to take input or arguments, 01:53:48.850 --> 01:53:52.128 you can literally do something like, the name of the type you want 01:53:52.128 --> 01:53:53.920 and the name of the variable that you want. 01:53:53.920 --> 01:53:57.640 So suppose I want meow to take as input some number, we'll call it n. 01:53:57.640 --> 01:53:59.560 And I want to use that number in a loop. 01:53:59.560 --> 01:54:01.060 I could then do something like this. 01:54:01.060 --> 01:54:06.940 For int i gets zero, i is less than n, i plus plus. 01:54:06.940 --> 01:54:10.480 I can then surround my printf with curly braces. 01:54:10.480 --> 01:54:15.100 And now notice just like last week with my final implementation of meow, 01:54:15.100 --> 01:54:19.190 my custom function can take input as denoted by the parentheses. i 01:54:19.190 --> 01:54:22.120 doesn't have output per se, that's why I'm leaving void here. 01:54:22.120 --> 01:54:25.390 But again, we'll explain void more in detail down the road. 01:54:25.390 --> 01:54:29.530 But now I'm using that input inside of the for loop. 01:54:29.530 --> 01:54:32.272 So even though this is a new implementation in C, 01:54:32.272 --> 01:54:33.730 I'm using the same building blocks. 01:54:33.730 --> 01:54:37.080 I'm using a for loop like before, but instead of hard coding three, 01:54:37.080 --> 01:54:41.980 or 50 like I did earlier, now I'm actually going to go ahead and just 01:54:41.980 --> 01:54:48.176 plug-in that variable just like Scratch allowed me to do as well. 01:54:48.176 --> 01:54:50.747 Well, what if I want to do something even fancier. 01:54:50.747 --> 01:54:51.330 You know what? 01:54:51.330 --> 01:54:52.497 Let me go ahead and do this. 01:54:52.497 --> 01:54:55.540 Suppose that we want to get input from the user, 01:54:55.540 --> 01:54:58.770 but we really want them to provide a specific type of input. 01:54:58.770 --> 01:55:01.313 Let me go ahead and introduce one other type of loop. 01:55:01.313 --> 01:55:04.230 And this one I'm going to go ahead and grab from my archives, the code 01:55:04.230 --> 01:55:06.240 that I brought with me today. 01:55:06.240 --> 01:55:11.340 And I'm going to go ahead and copy over a file called positive.c, 01:55:11.340 --> 01:55:14.770 which is going to insist that the user give me a positive value. 01:55:14.770 --> 01:55:16.810 So this too is on the course's website. 01:55:16.810 --> 01:55:19.560 And let me just walk us through code that I already wrote. 01:55:19.560 --> 01:55:23.130 Here at the top of my file, I'm including some now familiar header 01:55:23.130 --> 01:55:23.820 files. 01:55:23.820 --> 01:55:26.850 And down here, I'm including a prototype. 01:55:26.850 --> 01:55:29.610 That is a hint for a function that's going to be called, 01:55:29.610 --> 01:55:31.980 quite simply, get_positive_int. 01:55:31.980 --> 01:55:34.870 So this is a function that's only going to get a positive integer. 01:55:34.870 --> 01:55:37.600 Then in my main function, notice I'm going to use this. 01:55:37.600 --> 01:55:40.410 I'm going to get a variable called i on line 10, 01:55:40.410 --> 01:55:43.020 and I'm going to get a positive int from the user. 01:55:43.020 --> 01:55:45.180 And then I'm just going to print it out. 01:55:45.180 --> 01:55:48.720 But what's interesting now is I have this additional abstraction. 01:55:48.720 --> 01:55:52.050 The CS50 library does not come with a function called get_positive_int, 01:55:52.050 --> 01:55:54.660 but it does come with a function called get_int. 01:55:54.660 --> 01:55:58.830 And notice what I've done down here between lines 15 and 24. 01:55:58.830 --> 01:56:03.270 Down here I've declared a function called get_positive_int, 01:56:03.270 --> 01:56:06.060 and notice that's my own custom function name. 01:56:06.060 --> 01:56:09.540 It doesn't take any inputs, it just gets a positive integer from the human. 01:56:09.540 --> 01:56:13.350 But now notice it does have a return value. 01:56:13.350 --> 01:56:16.650 Previously I used the word void to say the absence of input 01:56:16.650 --> 01:56:17.880 or the absence of output. 01:56:17.880 --> 01:56:20.130 Here I'm using it's still to say, no inputs. 01:56:20.130 --> 01:56:22.170 It just always gets a positive int. 01:56:22.170 --> 01:56:25.770 But I'm saying int on the left hand side of this custom function's name 01:56:25.770 --> 01:56:28.420 because this function does have output. 01:56:28.420 --> 01:56:29.910 What is the output going to be? 01:56:29.910 --> 01:56:33.960 We'll, notice here on line 17, I give myself a variable and I call it n. 01:56:33.960 --> 01:56:38.340 Then I have one final new feature of C today, this loop which is called, 01:56:38.340 --> 01:56:41.310 not a while loop, but a do while loop. 01:56:41.310 --> 01:56:44.460 A do while loop is almost the same as a while loop, 01:56:44.460 --> 01:56:49.470 except that it blindly does one thing first before checking a condition. 01:56:49.470 --> 01:56:51.930 So notice here I'm going to do the following. 01:56:51.930 --> 01:56:54.960 Call get_int with this prompt, positive integer, 01:56:54.960 --> 01:56:58.650 and then store the return value into the variable called n. 01:56:58.650 --> 01:57:03.120 Then down here, notice I'm saying while n less than one. 01:57:03.120 --> 01:57:06.000 So this is kind of a weird syntax, but if mathematically I 01:57:06.000 --> 01:57:08.250 want the user to give me a positive integer, 01:57:08.250 --> 01:57:11.850 that's technically the same thing as wanting the user to give me an integer 01:57:11.850 --> 01:57:16.368 and just make sure that it is not less than one. 01:57:16.368 --> 01:57:19.410 Because if it's less than one, it's zero or negative one or negative two, 01:57:19.410 --> 01:57:21.220 that's obviously not a positive integer. 01:57:21.220 --> 01:57:22.890 So how can I express this in code? 01:57:22.890 --> 01:57:24.975 The only new thing at the moment now is the fact 01:57:24.975 --> 01:57:26.850 that there exists this thing called do while. 01:57:26.850 --> 01:57:30.300 And again, the value of do while is that you will do things at least 01:57:30.300 --> 01:57:32.460 once and then check a condition. 01:57:32.460 --> 01:57:36.222 A while loop checks the condition first and then does something instead. 01:57:36.222 --> 01:57:37.930 This is what I want in this case, though. 01:57:37.930 --> 01:57:40.050 I want to do this. 01:57:40.050 --> 01:57:44.080 Get an integer from the user prompting them for a positive integer. 01:57:44.080 --> 01:57:48.090 Then while n is less than one-- so if the human 01:57:48.090 --> 01:57:51.810 typed in zero, or negative one, or negative two, what do I want to do? 01:57:51.810 --> 01:57:54.750 The same thing again and again and again. 01:57:54.750 --> 01:57:56.370 So it reads rather grammatically. 01:57:56.370 --> 01:58:00.590 Do the following while n is less than one. 01:58:00.590 --> 01:58:04.670 And then lastly, and the only other new line here is return n. 01:58:04.670 --> 01:58:08.880 This is the way that a program can actually return some value to you. 01:58:08.880 --> 01:58:11.570 It can hand you back a value, not by printing it on the screen, 01:58:11.570 --> 01:58:14.270 not by saying it audibly or visually from a cat's mouth. 01:58:14.270 --> 01:58:17.300 It returns it in the sense that what's being returned here 01:58:17.300 --> 01:58:21.410 is n, which is an integer that matches the output of this function. 01:58:21.410 --> 01:58:22.830 Why is this useful? 01:58:22.830 --> 01:58:24.200 Well let's scroll back up. 01:58:24.200 --> 01:58:28.320 Let's now take for granted that we get_positive_int function exists. 01:58:28.320 --> 01:58:31.610 And now notice how we can use it in main. 01:58:31.610 --> 01:58:34.070 I call get_positive_int on the right. 01:58:34.070 --> 01:58:37.160 It returns a value I claim that is of type integer. 01:58:37.160 --> 01:58:41.420 I'm storing that return value on the left in this variable called i. 01:58:41.420 --> 01:58:42.830 And then I'm printing out i. 01:58:42.830 --> 01:58:46.010 And just like last week with the meow example in Scratch, 01:58:46.010 --> 01:58:48.590 now that I have implemented get_positive_int, 01:58:48.590 --> 01:58:50.570 it sort of out of sight, out of mind. 01:58:50.570 --> 01:58:53.930 I know that it can be done, and I can abstract away 01:58:53.930 --> 01:58:59.090 the underlying implementation details by just calling it by its name. 01:58:59.090 --> 01:59:01.610 But there's one weird thing that I do want to point out 01:59:01.610 --> 01:59:03.890 about these implementation details. 01:59:03.890 --> 01:59:07.640 Why did I declare n out here? 01:59:07.640 --> 01:59:11.840 Every other time I've created a variable, I've done this. 01:59:11.840 --> 01:59:14.600 It turns out we've been getting lucky this whole time, 01:59:14.600 --> 01:59:17.540 and any time I've declared variables they've technically 01:59:17.540 --> 01:59:19.070 been in between curly braces. 01:59:19.070 --> 01:59:23.120 The curly braces belonging to the main function or my other functions 01:59:23.120 --> 01:59:24.740 that I've written thus far. 01:59:24.740 --> 01:59:26.840 But in this case, the problem is when you 01:59:26.840 --> 01:59:30.050 declare a variable inside of curly braces, 01:59:30.050 --> 01:59:32.390 you run into what we'll call an issue of scope. 01:59:32.390 --> 01:59:36.800 The scope of a variable is the lines of code in which it exists. 01:59:36.800 --> 01:59:41.510 The scope of a variable are the lines of code where you can use that variable. 01:59:41.510 --> 01:59:44.750 And the rule of thumb for today is that if you 01:59:44.750 --> 01:59:47.150 declare a variable inside of curly braces 01:59:47.150 --> 01:59:49.580 like those here on line 26 and 28, which you 01:59:49.580 --> 01:59:53.360 must do for a do while loop, that variable, n, 01:59:53.360 --> 01:59:56.570 only exists inside of those curly braces. 01:59:56.570 --> 02:00:00.530 Which means you cannot compare it against one in line 29. 02:00:00.530 --> 02:00:03.560 Which means you cannot return it in line 30. 02:00:03.560 --> 02:00:05.400 It just no longer exists. 02:00:05.400 --> 02:00:08.840 So you're doing all of this work getting the variable n, and then boom. 02:00:08.840 --> 02:00:13.650 It's gone once you exit top to bottom these curly braces. 02:00:13.650 --> 02:00:16.850 So the workaround for that, stupid though it is frankly, 02:00:16.850 --> 02:00:21.020 is that you can declare n initially on its own line, 25. 02:00:21.020 --> 02:00:23.450 You don't need to assign it a value even, because you're 02:00:23.450 --> 02:00:25.430 going to assign it a value eventually. 02:00:25.430 --> 02:00:29.180 But again, to create a variable, as I keep saying, is to declare a variable. 02:00:29.180 --> 02:00:34.680 You don't need to define it as having a value necessarily right away. 02:00:34.680 --> 02:00:39.980 So this is a way to work around what's otherwise known as an issue of scope. 02:00:39.980 --> 02:00:43.770 All right, with all of these puzzle pieces now in place so to speak, 02:00:43.770 --> 02:00:45.650 let me go ahead and propose that we solve 02:00:45.650 --> 02:00:47.150 something a little more graphical. 02:00:47.150 --> 02:00:51.560 So you'll recall, of course, Super Mario Brothers is one of the first problem 02:00:51.560 --> 02:00:53.130 sets that we alluded to last week. 02:00:53.130 --> 02:00:55.100 And within this game there's a whole bunch of visuals. 02:00:55.100 --> 02:00:57.100 For instance, there's this visual early on where 02:00:57.100 --> 02:00:59.030 there's four question marks in the sky. 02:00:59.030 --> 02:01:02.030 And these question marks, if you jump up and underneath them, 02:01:02.030 --> 02:01:03.232 give you coins for instance. 02:01:03.232 --> 02:01:05.690 So let me draw our attention to that, and let me ask, well, 02:01:05.690 --> 02:01:08.803 how could I write a program in C that just prints out four question marks? 02:01:08.803 --> 02:01:10.220 Well, let me go ahead and do this. 02:01:10.220 --> 02:01:13.040 Let me go ahead and write a program called mario.c. 02:01:13.040 --> 02:01:19.340 Let me go ahead and include stdio.h in a file called mario.c. 02:01:19.340 --> 02:01:21.240 Give myself a main function, int main void. 02:01:21.240 --> 02:01:22.490 I'm going to keep this simple. 02:01:22.490 --> 02:01:26.280 Printf one, two, three, four, backslash n semicolon. 02:01:26.280 --> 02:01:29.840 This is not nearly as cool or pretty as the old school game, 02:01:29.840 --> 02:01:34.280 but if I run make mario and then do dot slash mario, voila. 02:01:34.280 --> 02:01:41.030 I get a very poor approximation of these four blocks in the sky 02:01:41.030 --> 02:01:43.905 using just Ascii, or really called Ascii art. 02:01:43.905 --> 02:01:45.530 But I can do a little better than that. 02:01:45.530 --> 02:01:47.810 Recall that now we have the ability to use loops. 02:01:47.810 --> 02:01:50.180 So I could say for int i gets zero. 02:01:50.180 --> 02:01:53.030 i is less than four, i plus plus. 02:01:53.030 --> 02:01:57.380 And then I could just print out one question mark at a time. 02:01:57.380 --> 02:01:59.470 And then at the very end of my program, I 02:01:59.470 --> 02:02:02.927 could print out a new line just to move the cursor at the very last moment. 02:02:02.927 --> 02:02:04.760 I don't want to do that every question mark, 02:02:04.760 --> 02:02:06.177 because then it would be vertical. 02:02:06.177 --> 02:02:07.680 I want to do it only at the end. 02:02:07.680 --> 02:02:11.000 So now if I make mario, and I run mario now. 02:02:11.000 --> 02:02:13.850 Same exact result, but a little better in the sense 02:02:13.850 --> 02:02:22.550 that now it's using a loop instead of a hard coded value. 02:02:22.550 --> 02:02:26.240 But let me be a little more clever now, and let me do this instead. 02:02:26.240 --> 02:02:29.205 Let me borrow the logic of that positive integer example 02:02:29.205 --> 02:02:30.330 and do something like this. 02:02:30.330 --> 02:02:32.930 Let me give myself a variable called, n, for a number. 02:02:32.930 --> 02:02:35.240 And let me do the following just like before. 02:02:35.240 --> 02:02:37.910 Let me get an integer from the user, and ask the user 02:02:37.910 --> 02:02:41.970 for the width of the bricks that I want to print. 02:02:41.970 --> 02:02:43.250 So it's not always four. 02:02:43.250 --> 02:02:44.780 Maybe it's a variable number. 02:02:44.780 --> 02:02:48.320 And then let me go ahead and do this while n is less than one. 02:02:48.320 --> 02:02:51.330 So identical to my logic before. 02:02:51.330 --> 02:02:52.310 And then you know what? 02:02:52.310 --> 02:02:54.590 Once I have a value of n-- 02:02:54.590 --> 02:02:57.410 so let me go ahead up here and give myself a comment. 02:02:57.410 --> 02:03:00.050 Get positive integer from user. 02:03:00.050 --> 02:03:02.390 That rather says what all of these lines of code do. 02:03:02.390 --> 02:03:04.460 I don't need to comment every single line. 02:03:04.460 --> 02:03:07.700 You can comment every few if it makes logical sense to do so. 02:03:07.700 --> 02:03:12.440 Let me go ahead now and print out that many question marks. 02:03:12.440 --> 02:03:13.520 So I can do a loop. 02:03:13.520 --> 02:03:18.740 For int i gets zero, i is less than n this time, i plus plus. 02:03:18.740 --> 02:03:22.520 And now I can print out a single question mark without a new line. 02:03:22.520 --> 02:03:24.580 And then at the very end of my program, I 02:03:24.580 --> 02:03:28.040 can print out a single new line semicolon. 02:03:28.040 --> 02:03:31.590 Let me go ahead now and increase the size of my terminal window. 02:03:31.590 --> 02:03:33.550 Let me do make mario. 02:03:33.550 --> 02:03:35.470 And now-- oh, darn it. 02:03:35.470 --> 02:03:38.140 Implicit declaration of function get_int. 02:03:38.140 --> 02:03:40.360 Here's where help50 might be my friend. 02:03:40.360 --> 02:03:43.540 So let me go ahead and run help50 make mario. 02:03:43.540 --> 02:03:45.490 It's going to ask for help. 02:03:45.490 --> 02:03:48.190 You seem to have an error in mario.c on line nine. 02:03:48.190 --> 02:03:50.303 By implicit declaration of function get_int, 02:03:50.303 --> 02:03:53.470 clang means-- which is the name of the compiler, which we'll see next week-- 02:03:53.470 --> 02:03:55.390 means that it doesn't recognize get_int. 02:03:55.390 --> 02:03:58.540 Did you forget to include cs50.h in which get_int 02:03:58.540 --> 02:03:59.920 declared at top of your file. 02:03:59.920 --> 02:04:00.890 And indeed, I did. 02:04:00.890 --> 02:04:02.300 So let me fix this. 02:04:02.300 --> 02:04:06.070 So include cs50.h. 02:04:06.070 --> 02:04:07.570 Save the file. 02:04:07.570 --> 02:04:09.730 Recompile with make mario. 02:04:09.730 --> 02:04:13.750 And now let me go ahead and do dot slash mario, 02:04:13.750 --> 02:04:15.370 and I'll give myself a width of four. 02:04:15.370 --> 02:04:16.150 It's the same. 02:04:16.150 --> 02:04:17.920 Let me give myself a width of 40. 02:04:17.920 --> 02:04:19.300 Now I get that dynamism. 02:04:19.300 --> 02:04:22.010 Let me give myself a width of 50, and so forth. 02:04:22.010 --> 02:04:25.360 So now we have a program that's much more dynamic, but you know what? 02:04:25.360 --> 02:04:27.940 Let's go ahead and enhance this a little further. 02:04:27.940 --> 02:04:31.060 Later on in Super Mario Brothers, there's like a lot of this underworld 02:04:31.060 --> 02:04:32.830 here where you see these grids of bricks, 02:04:32.830 --> 02:04:34.413 and let me draw our attention to this. 02:04:34.413 --> 02:04:38.050 This looks like multiple bricks both horizontally and vertically. 02:04:38.050 --> 02:04:40.130 So there's a width and a height. 02:04:40.130 --> 02:04:43.750 So how can I go about printing out, maybe that's three by three. 02:04:43.750 --> 02:04:46.600 Three bricks across by three bricks down. 02:04:46.600 --> 02:04:49.450 Let me actually go into my program here. 02:04:49.450 --> 02:04:52.390 Get rid of all the question mark stuff from before. 02:04:52.390 --> 02:04:56.110 And consider how I could print out a three by three grid. 02:04:56.110 --> 02:05:00.160 Well, the bad approach here, if I go back into my code, 02:05:00.160 --> 02:05:02.620 would be to print out three of these. 02:05:02.620 --> 02:05:04.990 And then maybe three more. 02:05:04.990 --> 02:05:07.720 Maybe three more, and then three more. 02:05:07.720 --> 02:05:10.383 But of course, this copy paste is not going to fly long term, 02:05:10.383 --> 02:05:11.050 but that's fine. 02:05:11.050 --> 02:05:12.730 Let me do make mario. 02:05:12.730 --> 02:05:14.330 Dot slash mario. 02:05:14.330 --> 02:05:14.830 All right. 02:05:14.830 --> 02:05:17.800 I kind of sort of have a grid that looks like this thing here. 02:05:17.800 --> 02:05:20.470 It's not exactly, but at least it's the right idea. 02:05:20.470 --> 02:05:23.170 But this is not necessarily the best way to do this. 02:05:23.170 --> 02:05:26.590 I really want to go three across and three down. 02:05:26.590 --> 02:05:31.850 Well, it turns out using C we can actually express that as well. 02:05:31.850 --> 02:05:33.430 Let me go ahead and do this. 02:05:33.430 --> 02:05:38.050 Let me go ahead and print out for instance, the following. 02:05:38.050 --> 02:05:41.380 Let me go ahead and print out not just hash, hash, hash, again 02:05:41.380 --> 02:05:42.530 and again and again. 02:05:42.530 --> 02:05:43.810 Let me go ahead and do this. 02:05:43.810 --> 02:05:46.160 Let me print out one row at a time. 02:05:46.160 --> 02:05:49.838 So for int i gets zero, i less than three, plus plus. 02:05:49.838 --> 02:05:51.880 I don't know what I'm about to do yet, but I know 02:05:51.880 --> 02:05:53.470 that I'm going to do it three times. 02:05:53.470 --> 02:05:54.845 What do I want to do three times? 02:05:54.845 --> 02:05:58.480 Well, I want three rows, and on every row I want three hashes. 02:05:58.480 --> 02:05:59.830 So you know what you can do? 02:05:59.830 --> 02:06:01.210 You can nest loops. 02:06:01.210 --> 02:06:06.662 Let me do for int j gets zero, j is less than three, and j plus plus. 02:06:06.662 --> 02:06:08.620 I don't know what I'm going to do yet, but I do 02:06:08.620 --> 02:06:10.630 know I'm going to do this three times. 02:06:10.630 --> 02:06:12.490 And you can perhaps see where this is going. 02:06:12.490 --> 02:06:15.850 Three things three times, that's going to give me all nine bricks. 02:06:15.850 --> 02:06:21.040 So long as inside of this inner loop, so to speak, this nested loop, 02:06:21.040 --> 02:06:22.840 I print one of those hashes. 02:06:22.840 --> 02:06:27.770 So long as after that loop, I print out a new line over here. 02:06:27.770 --> 02:06:30.700 So to be clear, even if it's not obvious at first glance what's 02:06:30.700 --> 02:06:35.380 going on, we already know that this is the type of syntax you use for doing 02:06:35.380 --> 02:06:37.750 something finitely many times, three. 02:06:37.750 --> 02:06:40.520 This is the same syntax, but I'm using a different variable name. 02:06:40.520 --> 02:06:42.460 So I can keep track of two different values. 02:06:42.460 --> 02:06:45.543 Essentially, rows and columns. 02:06:45.543 --> 02:06:47.710 And then I'm just printing a single brick each time. 02:06:47.710 --> 02:06:50.080 But after I'm done printing a whole row, I 02:06:50.080 --> 02:06:53.170 do want to move the cursor to a new line. 02:06:53.170 --> 02:06:54.230 So let me try this. 02:06:54.230 --> 02:06:56.950 Let me go ahead and do make mario on my code. 02:06:56.950 --> 02:06:59.680 Dot slash mario, and voila. 02:06:59.680 --> 02:07:02.453 Now I'm using a nested loop to print out bricks like this. 02:07:02.453 --> 02:07:03.370 And I can change this. 02:07:03.370 --> 02:07:06.970 If I want to do a 10 by 10, all I have to do is change that in one place. 02:07:06.970 --> 02:07:10.390 Or if I really wanted to be fancy, I could go use get_int again. 02:07:10.390 --> 02:07:12.550 I could get the width and the height from the user 02:07:12.550 --> 02:07:14.110 and do it completely dynamically. 02:07:14.110 --> 02:07:18.692 But now if I do 10 by 10 for instance, I can at least see an even bigger grid. 02:07:18.692 --> 02:07:21.400 So if you wonder how things like Super Mario Brothers, or frankly 02:07:21.400 --> 02:07:25.450 any game nowadays on a PC or console or phone are made, 02:07:25.450 --> 02:07:27.400 it's with this kind of generation of maps. 02:07:27.400 --> 02:07:30.580 Maybe back in the day they were hard coded, maybe they were generated. 02:07:30.580 --> 02:07:34.690 Using code you can absolutely imagine generating brick after brick 02:07:34.690 --> 02:07:39.070 after brick like that so that, ultimately, your game even, your world, 02:07:39.070 --> 02:07:41.110 is partly dynamically generated. 02:07:41.110 --> 02:07:44.770 And we already have the building blocks via which to do that. 02:07:44.770 --> 02:07:51.340 Unfortunately, we haven't really spoken to the limitations 02:07:51.340 --> 02:07:52.832 of what computers can do. 02:07:52.832 --> 02:07:55.540 And in our final minutes we thought we'd set the stage for things 02:07:55.540 --> 02:07:57.340 that computers aren't very good at. 02:07:57.340 --> 02:08:01.270 And in fact, problems that are latent in pretty much everything 02:08:01.270 --> 02:08:04.630 we've done today, but I've been very carefully avoiding tripping over. 02:08:04.630 --> 02:08:07.930 This picture here is a picture of a typical computer's memory, 02:08:07.930 --> 02:08:09.477 or RAM, random access memory. 02:08:09.477 --> 02:08:11.560 It's just one of the pieces of hardware that you'd 02:08:11.560 --> 02:08:14.410 have in your phone, your desktop, your laptop these days. 02:08:14.410 --> 02:08:17.180 And it's where programs are stored when they're running. 02:08:17.180 --> 02:08:19.630 So in a Mac or PC, if you double click a program 02:08:19.630 --> 02:08:22.570 it's ultimately stored in a piece of hardware that looks like this. 02:08:22.570 --> 02:08:25.930 When you dot slash mario and hit Enter in a program like this, 02:08:25.930 --> 02:08:29.830 you're using CS50 IDE's RAM, but same idea, albeit, 02:08:29.830 --> 02:08:31.750 somewhere else in the cloud. 02:08:31.750 --> 02:08:36.110 So it turns out, though, that if you only have a finite amount of memory, 02:08:36.110 --> 02:08:39.200 like this, you can only do so much with it. 02:08:39.200 --> 02:08:41.590 You can't solve all of the world's problems 02:08:41.590 --> 02:08:43.900 if you only have a finite amount of memory. 02:08:43.900 --> 02:08:45.770 And what do I mean by that? 02:08:45.770 --> 02:08:51.130 Well, let me go ahead and create another program here called imprecision.c, 02:08:51.130 --> 02:08:53.470 and we'll see why I've named it that in just a moment. 02:08:53.470 --> 02:08:57.220 Let me go ahead and include stdio.h, again, and int main void just 02:08:57.220 --> 02:08:58.990 to give myself some set up here. 02:08:58.990 --> 02:09:01.090 And then let me go ahead and very reasonably very 02:09:01.090 --> 02:09:05.290 simply ask the user for a variable called x as a type float. 02:09:05.290 --> 02:09:07.630 Let me ask for the value just like before. 02:09:07.630 --> 02:09:11.557 Let me ask for another one in the form of y, quote unquote "y." 02:09:11.557 --> 02:09:13.390 And then let me go ahead, and you know what? 02:09:13.390 --> 02:09:19.085 Let me go ahead and print out with percent f the value of x divided by y. 02:09:19.085 --> 02:09:20.710 So I'm pretty sure we did this earlier. 02:09:20.710 --> 02:09:22.690 We did division with values. 02:09:22.690 --> 02:09:25.690 This time I'm using floats, but let's go ahead and just run this. 02:09:25.690 --> 02:09:28.960 Make imprecision-- and I goofed here. 02:09:28.960 --> 02:09:32.710 Implicit-- I keep doing it-- implicit declaration of function get_float. 02:09:32.710 --> 02:09:34.750 I didn't practice what I've been preaching. 02:09:34.750 --> 02:09:39.700 I also need to include cs50.h, which is where it get_float is defined. 02:09:39.700 --> 02:09:40.900 Now, let me recompile. 02:09:40.900 --> 02:09:41.890 Now it works. 02:09:41.890 --> 02:09:43.900 Now, let me go ahead and run imprecision. 02:09:43.900 --> 02:09:47.320 And let me go ahead and type in one tenth. 02:09:47.320 --> 02:09:47.980 OK. 02:09:47.980 --> 02:09:51.550 So one tenth it turns out, according to my very simple calculator here, 02:09:51.550 --> 02:09:54.928 is 0.100000. 02:09:54.928 --> 02:09:56.470 But I'm getting a little curious now. 02:09:56.470 --> 02:09:59.920 It turns out that printf is even more powerful than we've seen, 02:09:59.920 --> 02:10:02.650 and you can actually print out more than just single digits. 02:10:02.650 --> 02:10:08.080 Suppose I want to print out not six significant digits, but maybe 10. 02:10:08.080 --> 02:10:11.350 It's a little funky the syntax, but instead of saying percent f, 02:10:11.350 --> 02:10:15.550 you can instead say literally, percent dot the number of digits 02:10:15.550 --> 02:10:17.830 you want to see and then the f. 02:10:17.830 --> 02:10:21.670 So let me go ahead and recompile this, make imprecision. 02:10:21.670 --> 02:10:25.225 Now let me do dot slash imprecision and one tenth-- 02:10:25.225 --> 02:10:26.980 uh-huh. 02:10:26.980 --> 02:10:28.870 Well, that's a little curious. 02:10:28.870 --> 02:10:32.920 I don't recall knowing that there's a 15 at the end of one tenth. 02:10:32.920 --> 02:10:34.630 Well, let's get a little more curious. 02:10:34.630 --> 02:10:38.570 Let's print out 50 decimal points to really dig into what's going on here. 02:10:38.570 --> 02:10:40.310 Let me recompile my code. 02:10:40.310 --> 02:10:44.350 And let me rerun dot slash imprecision and do one divided by ten, 02:10:44.350 --> 02:10:45.610 and oh my God. 02:10:45.610 --> 02:10:49.150 I am quite sure in grade school when we all learned one divided by ten, 02:10:49.150 --> 02:10:52.120 the teacher did tell us one tenth or 0.1. 02:10:52.120 --> 02:11:00.050 And they never mentioned the fact that it's 0.10000000149011, and so forth. 02:11:00.050 --> 02:11:01.300 So what is going on? 02:11:01.300 --> 02:11:03.940 Well, it turns out as powerful as computers 02:11:03.940 --> 02:11:08.320 are and is as sophisticated as all of the syntax we've been looking at today 02:11:08.320 --> 02:11:13.220 is, my God, a computer can't even calculate one tenth correctly. 02:11:13.220 --> 02:11:15.950 And so we're bumping up against a fundamental limitation here, 02:11:15.950 --> 02:11:18.940 which is that if computers are finite in their capacity. 02:11:18.940 --> 02:11:23.320 They only have so much RAM, so much hardware, so many bits. 02:11:23.320 --> 02:11:27.250 Well, it stands to reason that if you only are using a finite number of bits, 02:11:27.250 --> 02:11:29.710 32 for instance, or 64. 02:11:29.710 --> 02:11:33.520 Yes, you can count pretty high or pretty precisely. 02:11:33.520 --> 02:11:37.810 You cannot count infinitely high or infinitely precisely. 02:11:37.810 --> 02:11:40.903 At some point you have to start to approximate values. 02:11:40.903 --> 02:11:42.820 And indeed, that's what the computer is doing. 02:11:42.820 --> 02:11:47.770 If it only has a finite number of bits, 32, via which to represent a float. 02:11:47.770 --> 02:11:52.215 There's an infinite number of floating point real numbers in the world. 02:11:52.215 --> 02:11:54.340 Unfortunately, if you have a finite number of bits, 02:11:54.340 --> 02:11:55.900 you've got to start cutting some corners. 02:11:55.900 --> 02:11:57.483 And that's what the computer is doing. 02:11:57.483 --> 02:12:01.030 It's representing one tenth as closely as it can, 02:12:01.030 --> 02:12:04.210 and this is what you then see when you look enough significant digits out. 02:12:04.210 --> 02:12:07.820 Now, for most problems that's probably not a big deal. 02:12:07.820 --> 02:12:10.450 But it could very well be a big deal if you're doing math, 02:12:10.450 --> 02:12:14.650 you're dealing with finance or monetary values or military operations 02:12:14.650 --> 02:12:18.430 where a lot of small numbers, scientifically, really start to add up. 02:12:18.430 --> 02:12:20.950 And indeed, there have been many examples in the real world 02:12:20.950 --> 02:12:24.970 where bad things happen because of this so-called imprecision. 02:12:24.970 --> 02:12:27.430 And there's another issue that computers run into. 02:12:27.430 --> 02:12:30.940 Not only this floating point imprecision, even integers 02:12:30.940 --> 02:12:32.530 have their limitations. 02:12:32.530 --> 02:12:36.820 Recall that integers, of course, can be represented in decimal or in binary. 02:12:36.820 --> 02:12:38.830 And if we have three light bulbs or three bits, 02:12:38.830 --> 02:12:41.260 let's consider how we might count in binary. 02:12:41.260 --> 02:12:43.630 Zero, zero, zero is where we began last week. 02:12:43.630 --> 02:12:50.060 001, 010, 011, 100, 101, 110, 111. 02:12:50.060 --> 02:12:54.860 And now, this recall from last week is the number we know is seven in decimal. 02:12:54.860 --> 02:12:57.410 How do I count one digit higher? 02:12:57.410 --> 02:12:59.780 Well, I just carry the one, so to speak. 02:12:59.780 --> 02:13:04.430 But if I only have three light bulbs or in turn three bits, or heck, 32 bits. 02:13:04.430 --> 02:13:08.390 That additional bit, the carry, disappears. 02:13:08.390 --> 02:13:10.820 And so there's this problem with integers too. 02:13:10.820 --> 02:13:15.980 And someone noted earlier when you tried to do 2 billion plus 2 billion, 02:13:15.980 --> 02:13:19.040 it couldn't fit in the result. That's because integers 02:13:19.040 --> 02:13:24.410 too if they're only 32 bits or a long in C. If it's only 64 bits, those are big 02:13:24.410 --> 02:13:26.990 numbers, but they're not infinitely large. 02:13:26.990 --> 02:13:29.800 And we humans have tripped over this again and again. 02:13:29.800 --> 02:13:33.890 You might recall hearing about if not living through the Y2K problem. 02:13:33.890 --> 02:13:36.710 Where a lot of stuff in the world broke or was 02:13:36.710 --> 02:13:40.520 worried to be broken on January 1st, 2000, because humans 02:13:40.520 --> 02:13:43.790 had made the reasonable but not very long sighted 02:13:43.790 --> 02:13:46.700 decision to store years using just two digits. 02:13:46.700 --> 02:13:52.460 So 1995 would be represented as 95, 96, 97, 98, 99. 02:13:52.460 --> 02:13:56.310 Then around the change of the year from 1999 to 2000, 02:13:56.310 --> 02:14:00.170 any computer program or system that was still using two digits 02:14:00.170 --> 02:14:02.810 would, of course, add one at the stroke of midnight. 02:14:02.810 --> 02:14:07.370 Unfortunately, if there's no third digit available it disappears. 02:14:07.370 --> 02:14:12.560 And the entire world confuses the year 2000 for the year 1900, 02:14:12.560 --> 02:14:16.820 because 1900 was assumed as being the prefix. 02:14:16.820 --> 02:14:20.900 And if you can believe it, we humans are about to do this again 02:14:20.900 --> 02:14:25.350 in the year 2038, which is not that far off from now. 02:14:25.350 --> 02:14:30.950 We are going to run out of bits via which to keep track of time. 02:14:30.950 --> 02:14:34.220 Because years ago, humans decided reasonably at the time, 02:14:34.220 --> 02:14:37.440 they are going to use 32 bits to represent numbers. 02:14:37.440 --> 02:14:42.110 And we are going to use 32 bits to count up the number of seconds 02:14:42.110 --> 02:14:46.520 from the year a date, January 1st, 1970. 02:14:46.520 --> 02:14:49.500 So that's when time began computing wise, in some sense, 02:14:49.500 --> 02:14:51.530 and we've been counting the seconds ever since. 02:14:51.530 --> 02:14:55.490 Unfortunately, with 32 bits you can only count as high as 4 billion 02:14:55.490 --> 02:14:56.420 give or take. 02:14:56.420 --> 02:15:02.210 And unfortunately, we are going to hit the four billionth second on January 19 02:15:02.210 --> 02:15:03.800 in the year 2038. 02:15:03.800 --> 02:15:07.010 So unless all of us upgrade our Macs and PCS, and worse, 02:15:07.010 --> 02:15:12.320 embedded systems and satellites and any hardware baked into various devices 02:15:12.320 --> 02:15:14.660 that we now use, we're about to run into this problem 02:15:14.660 --> 02:15:19.220 again where all of a sudden and it's going to be like January 1st, 1970 02:15:19.220 --> 02:15:19.910 again. 02:15:19.910 --> 02:15:22.050 Unless we stay ahead of this problem. 02:15:22.050 --> 02:15:25.333 So with all the power we've seen in C and all of the capabilities 02:15:25.333 --> 02:15:27.500 that we've seen in C and in Scratch, there are still 02:15:27.500 --> 02:15:28.800 these fundamental limitations. 02:15:28.800 --> 02:15:32.575 So when it comes to solving your own problems in C and in turn CS50, 02:15:32.575 --> 02:15:35.450 it's going to be ever so important to be mindful of these constraints 02:15:35.450 --> 02:15:38.600 and to, ultimately, find solutions even to these problems. 02:15:38.600 --> 02:15:41.330 But for now, we'll adjourn here, and leave you 02:15:41.330 --> 02:15:44.870 for your first problem set in C on Mario and more. 02:15:44.870 --> 02:15:47.300 We'll see you next time. 02:15:47.300 --> 02:15:50.650 [MUSIC PLAYING]