[MUSIC PLAYING] DAVID J. MALAN: All right. This is CS50 and this is the start of Week 2. And you'll recall that over the past couple of weeks, we've been introducing computer science and, in turn, programming. And we started the story by way of Scratch, that graphical language from MIT'S Media Lab. And then most recently, last week, did we introduce a higher-- a lower-level language known as C, something that's purely textual. And, indeed, last time we explored within that context a number of concepts. This, recall, was the very first program we looked at. And this program, quite simply, prints out, "hello, world." But there's so much seeming magic going on. There's this #include with these angle brackets. There's int. There's (void). There's parentheses, curly braces, semi-colons, and so much more. And so, recall that we introduced Scratch so that we could, ideally, see past that syntax, the stuff that's really not all that intellectually interesting but early on is, absolutely, a bit tricky to wrap your mind around. And, indeed, one of the most common things early on in a programming class, especially for those less comfortable, is to get frustrated by and tripped up by certain syntactic errors, not to mention logical errors. And so among our goals today, actually, will be to equip you with some problem-solving techniques for how to better solve problems themselves in the form of debugging. And you'll recall, too, that the environment that we introduced last time was called CS50 IDE. This is web-based software that allows you to program in the cloud, so to speak, while keeping all of your files together, as we again will today. And recall that we revisited these topics here, among them functions, and loops, and variables, and Boolean expressions, and conditions. And actually a few more that we translated from the world of Scratch to the world of C. But the fundamental building blocks, so to speak, were really still the same last week. In fact, we really just had a different puzzle piece, if you will. Instead of that purple save block, we instead had printf, which is this function in C that allows you to print something and format it on the screen. We introduced the CS50 Library, where you have now at your disposal get_char, and get_int, and get_string, and a few other functions as well, via which you can get input from the user's own keyboard. And we also took a look at things like these- bool, and char, and double, float, int, long_long string. And there's even other data types in C. In other words, when you declare a variable to store some value, or when you implement a function that returns some value, you can specify what type of value that is. Is it a string, like a sequence of characters? Is it a number, like an integer? Is it a floating point value, or the like? So in C, unlike Scratch, we actually began to specify what kind of data we were returning or using. But, of course, we also ran into some fundamental limits of computing. And in particular, this language C, recall that we took a look at integer overflow, the reality that if you only have a finite amount of memory or, specifically, a finite number of bits, you can only count so high. And so we looked at this example here whereby a counter in an airplane, , actually, if running long enough would overflow and result in a software an actual physical potential error. We also looked at floating point imprecision, the reality that with only a finite number of bits, whether it's 32 or 64, you can only specify so many numbers after a decimal point, after which you begin to get imprecise. So for instance, one-third in the world here, in our human world, we know is just an infinite number of 3s after the decimal point. But a computer can't necessarily represent an infinite number of numbers if you only allow it some finite amount of information. So not only did we equip you with greater power in terms of how you might express yourself at a keyboard in terms of programming, we also limited what you can actually do. And indeed, bugs and mistakes can arise from those kinds of issues. And indeed, among the topics today are going to be topics like debugging and actually looking underneath the hood at how things were introduced last week are actually implemented so that you better understand both the capabilities of and the limitations of a language like C. And in fact, we'll peel back the layers of the simplest of data structure, something called an array, which Scratch happens to call a "list." It's a little bit different in that context. And then we'll also introduce one of the first of our domain-specific problems in CS50, the world of cryptography, the art of scrambling or in ciphering information so that you can send secret messages and decode secret messages between two persons, A and B. So before we transition to that new world, let's try to equip you with some techniques with which you can eliminate or reduce at least some of the frustrations that you have probably encountered over the past week alone. In fact, ahead of you are such-- some of your first problems in C. And odds are, if you're like me, the first time you try to type out a program, even if you think logically the program is pretty simple, you might very well hit a wall, and the compiler is not going to cooperate. Make or Clang is not going to actually do your bidding. And why might that be? Well, let's take a look at, perhaps, a simple program. I'm going to go ahead and save this in a file deliberately called buggy0.c, because I know it to be flawed in advance. But I might not realize that if this is the first or second or third program that I'm actually making myself. So I'm going to go ahead and type out, int main(void). And then inside of my curly braces, a very familiar ("hello, world-- backslash, n")-- and a semi-colon. I've saved the file. Now I'm going to go down to my terminal window and type make buggy0, because, again, the name of the file today is buggy0.c. So I type make buggy0, Enter. And, oh, gosh, recall from last time that no error messages is a good thing. So no output is a good thing. But here I have clearly some number of mistakes. So the first line of output after typing make buggy0, recall, is Clang's fairly verbose output. Underneath the hood, CS50 IDE is configured to use a whole bunch of options with this compiler so that you don't have to think about them. And that's all that first line means that starts with Clang. But after that, the problems begin to make their appearance. Buggy0.c on line 3, character 5, there is a big, red error. What is that? Implicitly declaring library function printf with type int (const char *, ...) [-Werror]. I mean, it very quickly gets very arcane. And certainly, at first glance, we wouldn't expect you to understand the entirety of that message. And so one of the lessons for today is going to be to try to notice patterns, or similar things, to errors you might have encountered in the past. So let's tease apart only those words that look familiar. The big, red error is clearly symbolic of something being wrong. Implicitly declaring library function printf. So even if I don't quite understand what implicitly declaring library function means, the problem surely relates to printf somehow. And the source of that issue has to do with declaring it. Declaring a function is mentioning it for the first time. And we used the terminology last week of declaring a function's prototype, either with one line at the top of your own file or in a so-called header file. And in what file did we say last week that printf is quote, unquote, declared? In what file is its prototype? So if you recall, the very first thing I typed, almost every program last time-- and accidentally a moment ago started typing myself-- was this one here-- hash-- #include