1 00:00:00,000 --> 00:00:02,270 [Week 2, Continued] 2 00:00:02,270 --> 00:00:04,220 [David J. Malan, Harvard University] 3 00:00:04,220 --> 00:00:06,880 [This is CS50. - CS50.TV] 4 00:00:06,880 --> 00:00:10,990 All right. This is CS50, and this is the end of week 2. 5 00:00:10,990 --> 00:00:14,410 If you expect to be hungry around this time tomorrow, 6 00:00:14,410 --> 00:00:18,620 know that we're going to convene as a small group tomorrow, Thursday, 1:15 pm. 7 00:00:18,620 --> 00:00:21,360 There's this URL here if you'd like to RSVP. 8 00:00:21,360 --> 00:00:26,740 Space is limited, so please forgive if the form has filled up by the time you fill this out. 9 00:00:26,740 --> 00:00:29,300 Another URL, though, that might be of interest is this. 10 00:00:29,300 --> 00:00:32,369 In just about a month's time, the course is going to be made available 11 00:00:32,369 --> 00:00:36,890 all the more broadly via edX, via which folks on the Internet will be able to follow along, 12 00:00:36,890 --> 00:00:39,380 engage in the course quite actively, in fact. 13 00:00:39,380 --> 00:00:42,270 They'll be using the CS50 Appliance and CS50 Discuss 14 00:00:42,270 --> 00:00:45,490 and most of the various software tools that we already have been using this semester. 15 00:00:45,490 --> 00:00:48,710 And one of the initiatives we'd like to take on as an experiment this year 16 00:00:48,710 --> 00:00:51,930 is to see just how much content we can translate 17 00:00:51,930 --> 00:00:53,960 into other spoken and written languages. 18 00:00:53,960 --> 00:00:57,500 So if you might have an interest in participating in this project 19 00:00:57,500 --> 00:01:02,270 whereby we will provide English transcripts and subtitles for the course's lectures 20 00:01:02,270 --> 00:01:05,450 and shorts and seminars and sections and the like, 21 00:01:05,450 --> 00:01:08,200 if you speak fluently or write fluently some other language, 22 00:01:08,200 --> 00:01:12,290 we would love to engage you in this project whereby you take on one or more of the videos, 23 00:01:12,290 --> 00:01:15,200 translating them into a language you know quite well. 24 00:01:15,200 --> 00:01:18,700 >> To give you a sense of the interface, there's this web-based user interface 25 00:01:18,700 --> 00:01:22,090 that we'll be using that will create essentially a UI like this. 26 00:01:22,090 --> 00:01:24,290 This was me teaching some Halloween ago, 27 00:01:24,290 --> 00:01:27,390 and on the right-hand side there in black next to these time stamps, 28 00:01:27,390 --> 00:01:31,210 you'll see the various things that came out of my mouth that day, 29 00:01:31,210 --> 00:01:34,850 and then below it you'll be able to translate into some other language 30 00:01:34,850 --> 00:01:38,690 exactly what the mapping is between, in this case, English and, say, Spanish. 31 00:01:38,690 --> 00:01:40,440 So it's actually a very user-friendly tool. 32 00:01:40,440 --> 00:01:43,370 You can rewind and fast-forward very readily with keyboard shortcuts. 33 00:01:43,370 --> 00:01:47,490 So if you would like to take part in this experiment and have your words seen and read 34 00:01:47,490 --> 00:01:51,850 by potentially thousands of folks out there, please do feel free to participate. 35 00:01:51,850 --> 00:01:54,350 One word about the kitten from Monday. 36 00:01:54,350 --> 00:02:00,350 Lest we have sent an overly scary message, do realize that, as office hours suggest 37 00:02:00,350 --> 00:02:03,300 and as sections suggest, the design of the course is very much 38 00:02:03,300 --> 00:02:07,360 to have students collaborating and talking to work through problem sets 39 00:02:07,360 --> 00:02:11,260 and problems together, and really the line just comes down to, 40 00:02:11,260 --> 00:02:16,010 again, the work you ultimately submit should be your own. 41 00:02:16,010 --> 00:02:18,860 And so quite honestly, in office hours it's totally normal, 42 00:02:18,860 --> 00:02:22,240 it's totally to be expected even, to be chatting with some friend next to you. 43 00:02:22,240 --> 00:02:24,370 >> If he or she is struggling with some topic and you're like, 44 00:02:24,370 --> 00:02:27,940 "Oh, well, let me give you a glimpse of some line of code that I wrote," that's fine, 45 00:02:27,940 --> 00:02:31,250 that happens, and that's very much conducive, I think, with the process of learning. 46 00:02:31,250 --> 00:02:36,750 Where the line gets crossed is when the head is sort of tilted over here for far too many seconds 47 00:02:36,750 --> 00:02:41,160 or minutes for that really to have just been an unblocking opportunity for your friend, 48 00:02:41,160 --> 00:02:44,160 and certainly when things get exchanged via email and Dropbox and the like, 49 00:02:44,160 --> 00:02:45,640 there too is the line. 50 00:02:45,640 --> 00:02:48,620 So by all means feel comfortable and feel encouraged to chat with friends 51 00:02:48,620 --> 00:02:52,810 and classmates about psets and more and just realize that what you ultimately submit 52 00:02:52,810 --> 00:02:57,340 should really be the product of your creation and not someone else. 53 00:02:57,340 --> 00:03:00,490 And so one of the domain-specific problems for pset2, 54 00:03:00,490 --> 00:03:04,740 which will come out late tomorrow night, is to dive into the world of cryptography, 55 00:03:04,740 --> 00:03:08,970 which is the art of encrypting or scrambling information, 56 00:03:08,970 --> 00:03:12,600 and this ultimately relates to the world of security. 57 00:03:12,600 --> 00:03:16,560 Now, security for most of us comes in the form of fairly mundane mechanisms. 58 00:03:16,560 --> 00:03:19,050 All of us have usernames and passwords, 59 00:03:19,050 --> 00:03:23,450 and all of us have very bad usernames and passwords, most likely. 60 00:03:23,450 --> 00:03:28,240 >> If your password is the same on multiple websites, that's probably not the best idea, 61 00:03:28,240 --> 00:03:30,070 as we'll discuss toward semester's end. 62 00:03:30,070 --> 00:03:34,720 If your password is written on a sticky note--no joke--on your monitor, 63 00:03:34,720 --> 00:03:38,350 that too is not necessarily the best design but quite a common phenomenon. 64 00:03:38,350 --> 00:03:42,470 And if you're not using cryptography to encrypt your passwords, 65 00:03:42,470 --> 00:03:44,210 they are particularly vulnerable. 66 00:03:44,210 --> 00:03:47,270 So if you think you're being super clever by having a hidden Word document 67 00:03:47,270 --> 00:03:49,910 somewhere on your hard drive that has all of your passwords 68 00:03:49,910 --> 00:03:53,670 but it's in a folder that no one's going to look in, that too is not a very secure mechanism. 69 00:03:53,670 --> 00:03:56,990 And so what pset2 will introduce is this art of cryptography 70 00:03:56,990 --> 00:04:02,010 and scrambling information so that things like passwords are all the more secure. 71 00:04:02,010 --> 00:04:05,790 The context here is that with insecure data 72 00:04:05,790 --> 00:04:07,930 comes an opportunity to encrypt it and to scramble it. 73 00:04:07,930 --> 00:04:11,470 And so this, for instance, is an example of an encrypted message. 74 00:04:11,470 --> 00:04:14,700 This actually says something in English, but it's clearly not wholly obvious. 75 00:04:14,700 --> 00:04:18,279 And we'll come full circle today to tease apart what this secret message here is. 76 00:04:18,279 --> 00:04:23,490 But in the real world of computers, things don't even look like they might be English phrases. 77 00:04:23,490 --> 00:04:28,430 For instance, this is what you might find on a standard Linux or Mac or UNIX computer 78 00:04:28,430 --> 00:04:32,070 in a file that was once upon a time called the password file. 79 00:04:32,070 --> 00:04:34,200 >> Nowadays it's been moved to other places. 80 00:04:34,200 --> 00:04:39,210 But if you look in the right place on a system, you'll see not only your username 81 00:04:39,210 --> 00:04:43,400 or that of other people on the system, but you'll see an encrypted version of their password. 82 00:04:43,400 --> 00:04:47,980 Indeed, the word crypt there suggests that the following stuff is encrypted, 83 00:04:47,980 --> 00:04:52,680 and this series of seemingly random letters and characters and numbers and so forth 84 00:04:52,680 --> 00:04:56,480 can be decrypted only by generally knowing some secret-- 85 00:04:56,480 --> 00:04:58,840 a secret word, a secret number-- 86 00:04:58,840 --> 00:05:03,160 and so indeed, the art of cryptography ultimately boils down to trust of some sort 87 00:05:03,160 --> 00:05:05,650 and knowing something that someone else does not. 88 00:05:05,650 --> 00:05:10,090 So we'll explore this in a bit more detail today and in the pset to come. 89 00:05:10,090 --> 00:05:12,200 And now a word on pass/fail. 90 00:05:12,200 --> 00:05:15,360 Especially as some of you have dived into pset1, the Appliance, 91 00:05:15,360 --> 00:05:19,080 and a very new world for yourself, realize that frustrations and confusion 92 00:05:19,080 --> 00:05:21,700 and just technical difficulties are quite to be expected, 93 00:05:21,700 --> 00:05:24,180 especially with the first pset, where there's just so much new, 94 00:05:24,180 --> 00:05:27,730 just getting familiar with ls and cd and all these arcane commands 95 00:05:27,730 --> 00:05:33,050 and a new environment, and that's separate from the actual material and programming itself. 96 00:05:33,050 --> 00:05:36,940 So realize too that there are certainly office hours that exist as a support structure. 97 00:05:36,940 --> 00:05:38,880 >> Sections begin this coming Sunday. 98 00:05:38,880 --> 00:05:42,960 But most importantly, if you're feeling just that this is not the world for you, 99 00:05:42,960 --> 00:05:44,710 realize that it really does just take time. 100 00:05:44,710 --> 00:05:48,600 And were it not for this opportunity years ago for me of taking a class pass/fail, 101 00:05:48,600 --> 00:05:50,990 honestly, I never would have even set foot in the classroom. 102 00:05:50,990 --> 00:05:53,690 And you can change this up until, say, the fifth Monday of the course, 103 00:05:53,690 --> 00:05:58,280 so if you're on the edge now, realize that rather than head into some other waters altogether, 104 00:05:58,280 --> 00:06:01,260 do certainly consider just changing to pass/fail. 105 00:06:01,260 --> 00:06:04,570 Again, there's not really this culture here at Harvard of taking things pass/fail 106 00:06:04,570 --> 00:06:08,670 since everyone really wants to achieve or overachieve, 107 00:06:08,670 --> 00:06:11,130 but frankly, this is a wonderful way of trying something out 108 00:06:11,130 --> 00:06:16,720 that might not be familiar to you, and you'll end up doing, in most cases, quite fine, 109 00:06:16,720 --> 00:06:18,210 perhaps much to your surprise. 110 00:06:18,210 --> 00:06:20,980 And in more concrete terms, what I think pass/fail generally does, 111 00:06:20,980 --> 00:06:22,940 especially as you might have experienced with pset0, 112 00:06:22,940 --> 00:06:26,560 if you put in 10 hours, 15 hours, 25 hours into some pset 113 00:06:26,560 --> 00:06:29,920 and you're just banging your head against the wall and it's getting super late at night 114 00:06:29,920 --> 00:06:33,950 but you've taken the pset 90% of the way and you just can't figure out one thing, 115 00:06:33,950 --> 00:06:36,520 pass/fail really takes the edge off of a class like this, 116 00:06:36,520 --> 00:06:39,100 where you can sort of happily say, "Okay, I know it's not perfect, 117 00:06:39,100 --> 00:06:42,350 but I worked my ass off on this, I'm pretty happy with where it ended up," 118 00:06:42,350 --> 00:06:44,850 and that will meet the expectations for pass/fail. 119 00:06:44,850 --> 00:06:47,540 So do keep that in mind. All right. 120 00:06:47,540 --> 00:06:50,520 >> So those of you who have struggled to use the Harvard University Wi-Fi, 121 00:06:50,520 --> 00:06:54,780 know that there's a CS50 SSID, a Wi-Fi connection, floating around 122 00:06:54,780 --> 00:06:56,490 that you might have better luck for. 123 00:06:56,490 --> 00:07:00,130 It's a little ironic that the password for this, if you would like to try connecting to this 124 00:07:00,130 --> 00:07:08,350 for better speeds--and let us know if it's no better--is 12345, all the way up to 8 125 00:07:08,350 --> 00:07:10,910 because 8 is more secure than 5. 126 00:07:10,910 --> 00:07:16,910 So if you need the Wi-Fi password, connect to CS50 wirelessly here, 12345678, 127 00:07:16,910 --> 00:07:20,380 and post on CS50 Discuss if you still have intermittent connectivity issues, 128 00:07:20,380 --> 00:07:25,420 and we'll let the powers that be know for this space. All right. 129 00:07:25,420 --> 00:07:32,230 So a quick teaser, especially for those of you who are fan boys or girls of all things Apple. 130 00:07:32,230 --> 00:07:37,460 What I dug up from a few years back was this file here, iUnlock.c, 131 00:07:37,460 --> 00:07:39,930 just to kind of make more concrete and more complex 132 00:07:39,930 --> 00:07:42,560 some of the more basic C programs we've been writing. 133 00:07:42,560 --> 00:07:46,910 So I opened up this file, iUnlock.c. It's available on the Lectures page for today. 134 00:07:46,910 --> 00:07:49,810 On the left-hand side you see a long list of functions. 135 00:07:49,810 --> 00:07:53,230 So the fellow who wrote this wrote up a lot of functions, more than just main. 136 00:07:53,230 --> 00:07:57,340 He used a whole bunch of libraries here, and if we start scrolling through, 137 00:07:57,340 --> 00:08:04,890 what this actually is is the very first, I believe, crack for the original iPhone. 138 00:08:04,890 --> 00:08:09,830 >> When you wanted to jailbreak the original iPhone, which means untether it from AT&T 139 00:08:09,830 --> 00:08:13,710 and actually install special software on it and do things that Apple didn't want people to do, 140 00:08:13,710 --> 00:08:18,480 someone took the time to figure out exactly how they could exploit software flaws, 141 00:08:18,480 --> 00:08:22,690 mistakes, bugs, in Apple software, and thus was born iUnlock.c-- 142 00:08:22,690 --> 00:08:26,760 that if you compiled it on your computer and installed it onto an iPhone 143 00:08:26,760 --> 00:08:29,430 that was connected to your computer via, say, a USB cable, 144 00:08:29,430 --> 00:08:32,450 this would give you administrative or root privileges on your iPhone 145 00:08:32,450 --> 00:08:34,620 and let you do pretty much whatever you want. 146 00:08:34,620 --> 00:08:36,400 And so there's been this fascinating cat and mouse game 147 00:08:36,400 --> 00:08:39,340 between Apple and the rest of the world in particular as they, like many companies, 148 00:08:39,340 --> 00:08:43,350 try to lock their stuff down so that you can only do with it what they intend. 149 00:08:43,350 --> 00:08:47,360 But thanks to people like this and the understanding of low-level details-- 150 00:08:47,360 --> 00:08:50,830 and in this case C programming--and a lot of the familiar constructs 151 00:08:50,830 --> 00:08:55,280 that we've started playing with, you are able to really leverage the hardware 152 00:08:55,280 --> 00:08:59,250 in a manner you see fit and not necessarily some corporate entity. 153 00:08:59,250 --> 00:09:01,600 So for instance, I have no idea what all this is doing, 154 00:09:01,600 --> 00:09:03,580 but GetVersion sounds pretty straightforward, 155 00:09:03,580 --> 00:09:05,710 and it looks like this is a function that this person wrote. 156 00:09:05,710 --> 00:09:09,250 It takes some kind of integer as an argument, doesn't return anything, 157 00:09:09,250 --> 00:09:13,710 but appears to loop with a for loop here and an if condition, if condition break, 158 00:09:13,710 --> 00:09:16,770 and somehow relates to version numbers if we scroll down, 159 00:09:16,770 --> 00:09:19,650 even though a lot of these keywords are going to be new. 160 00:09:19,650 --> 00:09:22,590 And there's a whole lot of functions in here we've never seen and might not ever see 161 00:09:22,590 --> 00:09:24,350 over the course of the semester. 162 00:09:24,350 --> 00:09:29,160 >> At the end of the day, it follows the same rules and logic that we've been playing with thus far. 163 00:09:29,160 --> 00:09:34,340 So this is far too old to crack your iPhone 3s or 4s or soon 5s these days, 164 00:09:34,340 --> 00:09:38,830 but know that it's all very much derived from this world that we've dived into. 165 00:09:38,830 --> 00:09:42,280 Let's take a look at a little more simple example: 166 00:09:42,280 --> 00:09:46,260 this one, just to get warmed up with some syntax and also some other data type 167 00:09:46,260 --> 00:09:48,910 that we've talked about but haven't really seen in C. 168 00:09:48,910 --> 00:09:53,670 This is a file called positive1.c, and per the comments at the top, 169 00:09:53,670 --> 00:09:56,070 this just demands that a user provide a positive number. 170 00:09:56,070 --> 00:09:59,910 So it's an example of a do-while loop, which is nice for user interactive programs 171 00:09:59,910 --> 00:10:02,070 where you need to tell the user to do something, 172 00:10:02,070 --> 00:10:05,530 and if they don't cooperate you yell at them or reject their input. 173 00:10:05,530 --> 00:10:10,480 Case in point: I am going to do lines 19 through 24 174 00:10:10,480 --> 00:10:14,620 so long as the user has not given me a positive number. 175 00:10:14,620 --> 00:10:21,340 This detail here on line 18, why did I declare n above this whole looping construct 176 00:10:21,340 --> 00:10:26,870 as opposed to right next to line 22 where I actually care to get n? Yeah. 177 00:10:26,870 --> 00:10:29,330 [student] Scope. >>Yeah, so this issue of scope. 178 00:10:29,330 --> 00:10:31,770 And in layman's terms, what does scope refer to? 179 00:10:34,880 --> 00:10:41,560 Yeah. >>[inaudible student response] >>Can you speak a little louder? 180 00:10:41,560 --> 00:10:45,440 [student] Where you can access that variable. >>Perfect. 181 00:10:45,440 --> 00:10:47,610 Where you can access a particular variable. 182 00:10:47,610 --> 00:10:50,990 And generally, the rule of thumb thus far has been that the scope of some variable 183 00:10:50,990 --> 00:10:56,140 is defined by the most recent curly braces that you've seen. 184 00:10:56,140 --> 00:11:03,070 >> And so in this case, if I made the mistake of declaring n on line 22, that line would work. 185 00:11:03,070 --> 00:11:10,840 I would get an int, and I would put it into that variable n in line 22, 186 00:11:10,840 --> 00:11:17,060 but which line of code would now have no idea what I'm talking about? >>[student] 25. 187 00:11:17,060 --> 00:11:23,840 [Malan] 25, and it turns out 24 as well because in this case it falls outside of the curly braces. 188 00:11:23,840 --> 00:11:28,550 So just a little bit of a nuisance but very easily solved by simply declaring the variable 189 00:11:28,550 --> 00:11:30,700 outside of the function itself. 190 00:11:30,700 --> 00:11:32,760 We'll see later today you can go one step further 191 00:11:32,760 --> 00:11:34,940 and you could even get a little lazy. 192 00:11:34,940 --> 00:11:39,660 And this is not to be recommended in general, but you could even get lazy 193 00:11:39,660 --> 00:11:44,150 and put a variable globally, so to speak, not inside of a function, not inside of a loop, 194 00:11:44,150 --> 00:11:49,800 but in the file itself, outside of all of the functions you've written, as I did here on line 15. 195 00:11:49,800 --> 00:11:55,220 This is generally frowned upon, but realize this is a solution sometimes to other problems, 196 00:11:55,220 --> 00:11:56,910 as we'll eventually see. 197 00:11:56,910 --> 00:11:59,500 So for now we'll leave it like this, but let's see if we can rewrite this 198 00:11:59,500 --> 00:12:02,360 just to start expressing ourselves a little differently. 199 00:12:02,360 --> 00:12:05,550 This program, just to be clear, is positive1. 200 00:12:05,550 --> 00:12:11,980 Let me go ahead here and in my terminal window make positive1, Enter. 201 00:12:11,980 --> 00:12:15,080 Compiles okay. I'm going to run positive1, hit Enter. 202 00:12:15,080 --> 00:12:19,250 I demand that you give me a positive integer. I'll say -1. That didn't work. 203 00:12:19,250 --> 00:12:22,340 0, 99. That seems to work. 204 00:12:22,340 --> 00:12:25,310 Maybe not the most rigorous test, but at least it's a nice sanity check 205 00:12:25,310 --> 00:12:27,100 that we're on the right track. 206 00:12:27,100 --> 00:12:29,570 >> So now let me go ahead and open version 2 of this, 207 00:12:29,570 --> 00:12:32,800 and what is different already? 208 00:12:32,800 --> 00:12:39,030 It implements the same thing, but what's jumping out as clearly different this time? 209 00:12:40,790 --> 00:12:47,090 This bool in green. It is highlighted in green, this keyword known as bool, which is a data type. 210 00:12:47,090 --> 00:12:50,510 It doesn't come built in to all versions of C. 211 00:12:50,510 --> 00:12:52,650 You need to include a specific library. 212 00:12:52,650 --> 00:12:56,460 In our case, I included the CS50 library so that we have access to bool. 213 00:12:56,460 --> 00:12:59,860 But in line 18, we seem to have a Boolean value here called thankful. 214 00:12:59,860 --> 00:13:02,190 I could have called this anything, but I called it thankful 215 00:13:02,190 --> 00:13:04,750 just to kind of convey some semantic meaning. 216 00:13:04,750 --> 00:13:07,700 So initially on line 18, I'm apparently not thankful 217 00:13:07,700 --> 00:13:12,230 because the Boolean value thankful is initialized to false in line 18. 218 00:13:12,230 --> 00:13:16,500 And then it seems what I've done here in lines 21 through 23 219 00:13:16,500 --> 00:13:19,200 is I've just kind of rewritten my logic. 220 00:13:19,200 --> 00:13:26,100 So no functionally different, but in line 22 now I check if the int the user has provided 221 00:13:26,100 --> 00:13:31,360 is greater than 0, then I simply change the value of thankful to true. 222 00:13:31,360 --> 00:13:35,590 And why do I do that? Because in line 25, apparently I'm going to check a condition. 223 00:13:35,590 --> 00:13:39,760 Do this loop while thankful is false. 224 00:13:39,760 --> 00:13:42,960 So I proposed this as an alternative to version 1 225 00:13:42,960 --> 00:13:47,050 because it's at least a little more intuitive perhaps, it's a little more grounded in English. 226 00:13:47,050 --> 00:13:51,980 So do the following while you're not thankful or while thankful is false. 227 00:13:51,980 --> 00:13:56,220 And this time too I apparently don't care to remember what the user typed in 228 00:13:56,220 --> 00:14:00,050 because notice there's no variable n, so actually, a little white lie there. 229 00:14:00,050 --> 00:14:03,290 >> Functionally, the program is a bit different once we get to the bottom of it 230 00:14:03,290 --> 00:14:04,960 because I'm not remembering what n is. 231 00:14:04,960 --> 00:14:09,120 But I wanted to demonstrate here too that even though we've seen GetInt 232 00:14:09,120 --> 00:14:13,780 and GetString being used on the right-hand side of an equals sign thus far 233 00:14:13,780 --> 00:14:17,310 so that we remember the value, technically, that's not strictly necessary. 234 00:14:17,310 --> 00:14:20,290 If for whatever reason you just don't care to save the value, 235 00:14:20,290 --> 00:14:25,540 you just want to check the value, notice that we can simply write this as GetInt, 236 00:14:25,540 --> 00:14:27,320 open paren, close paren. 237 00:14:27,320 --> 00:14:30,570 That function is going to return a value, as we've been saying. 238 00:14:30,570 --> 00:14:32,220 It's going to give you back an int. 239 00:14:32,220 --> 00:14:34,460 And so if you mentally think of this happening, 240 00:14:34,460 --> 00:14:38,190 when I type in 99, GetInt returns the number 99, 241 00:14:38,190 --> 00:14:41,840 and so conceptually, it's as though my code were actually this. 242 00:14:41,840 --> 00:14:45,950 So if 99 is indeed greater than 0, then thankful becomes true, 243 00:14:45,950 --> 00:14:50,810 then line 25 realizes ooh, we're done because I'm now thankful, 244 00:14:50,810 --> 00:14:53,970 and in line 26, we simply say, "Thanks for the positive integer!" 245 00:14:53,970 --> 00:14:55,960 whatever it happened to be. 246 00:14:55,960 --> 00:14:59,140 Now let's do slight syntactic sugar here, so to speak. 247 00:14:59,140 --> 00:15:04,670 Let's see if we can clean up this line 25 with this third and final variant in positive3. 248 00:15:04,670 --> 00:15:13,600 >> Notice the only difference now is what line of code? >>[student] 25. >>[Malan] Yeah, 25. 249 00:15:13,600 --> 00:15:17,680 And we've not really seen this trick just yet, but we did see the exclamation point on Monday, 250 00:15:17,680 --> 00:15:21,070 which denotes what? >>[student] Not. >>Not or negation. 251 00:15:21,070 --> 00:15:23,510 So take a Boolean value and flip its value. 252 00:15:23,510 --> 00:15:25,810 True becomes false, false becomes true. 253 00:15:25,810 --> 00:15:30,420 So this, I would propose, is even a little more intuitive a way of writing the code 254 00:15:30,420 --> 00:15:33,430 because I still initialize thankful to false, I still do the following, 255 00:15:33,430 --> 00:15:36,010 I set thankful to true when the time comes, 256 00:15:36,010 --> 00:15:40,880 but now you can really just translate this code verbally left to right, 257 00:15:40,880 --> 00:15:45,630 while (!thankful); because bang or exclamation point denotes the notion of not, 258 00:15:45,630 --> 00:15:47,580 so while not thankful. 259 00:15:47,580 --> 00:15:49,900 So again, we haven't introduced any new concepts per se. 260 00:15:49,900 --> 00:15:53,730 We talked about Booleans back when we played with Scratch, 261 00:15:53,730 --> 00:15:56,720 but realize now we can just start writing our code in many different ways. 262 00:15:56,720 --> 00:16:01,060 So especially in pset1 if you're sort of struggling to figure out the way to write some program, 263 00:16:01,060 --> 00:16:04,340 odds are you're in luck because there can be any number of solutions 264 00:16:04,340 --> 00:16:06,110 that you can happen upon. 265 00:16:06,110 --> 00:16:10,500 For instance, this is just 3 for even the simplest of programs. All right. 266 00:16:10,500 --> 00:16:14,200 And now recall on Monday we left on this note with return values. 267 00:16:14,200 --> 00:16:18,450 So for the very first time we wrote a program that doesn't just have main; 268 00:16:18,450 --> 00:16:22,550 it also has its own custom function that I wrote here. 269 00:16:22,550 --> 00:16:26,810 So in line 31 through 34 I've implemented a cube function. 270 00:16:26,810 --> 00:16:30,240 It's not complex. It's just a * a * a in this case. 271 00:16:30,240 --> 00:16:34,750 But what's important about it is that I'm taking input in the form of a 272 00:16:34,750 --> 00:16:39,180 and I'm returning output in the form of a * a * a. 273 00:16:39,180 --> 00:16:43,560 So now I have the ability, much like I used to with prinf alone, 274 00:16:43,560 --> 00:16:47,240 to call this function by calling the cube function. 275 00:16:47,240 --> 00:16:51,970 >> And the cube function takes some input, and the cube function returns some output. 276 00:16:51,970 --> 00:16:56,960 By contrast, printf just did something. 277 00:16:56,960 --> 00:17:00,840 It didn't return anything that we cared about, even though as an aside it does return a value; 278 00:17:00,840 --> 00:17:03,110 you just generally ignore it. 279 00:17:03,110 --> 00:17:06,510 Printf just did something. It had a side effect of printing to the screen. 280 00:17:06,510 --> 00:17:11,770 By contrast here, we have the cube function, which actually returns something. 281 00:17:11,770 --> 00:17:15,520 So for those familiar with this, it's a fairly straightforward idea. 282 00:17:15,520 --> 00:17:19,640 But for those less familiar with this idea of passing in inputs and getting back outputs, 283 00:17:19,640 --> 00:17:21,950 let's try just something super simple. 284 00:17:21,950 --> 00:17:25,490 Is anyone comfortable coming up on stage briefly? 285 00:17:25,490 --> 00:17:28,040 You have to be comfortable with a camera on you as well. Yeah? Okay. 286 00:17:28,040 --> 00:17:31,240 What's your name? >>[student] Ken. >>Ken. All right. Ken, come on up. 287 00:17:31,240 --> 00:17:35,050 Ken is going to be a function of sorts here. 288 00:17:35,050 --> 00:17:38,720 Let's go ahead and do this. Let's get a little fancy. 289 00:17:38,720 --> 00:17:42,260 Nice to meet you. Welcome to center stage. All right. 290 00:17:42,260 --> 00:17:46,640 Let's hit this button here. All right. 291 00:17:46,640 --> 00:17:49,820 So here you have a modern chalkboard, 292 00:17:49,820 --> 00:17:53,470 and what I am is the main function, for instance, 293 00:17:53,470 --> 00:17:56,460 and I don't have an iPad in my hand. 294 00:17:56,460 --> 00:17:59,710 >> I don't really remember how to-- Well, I can't say that. 295 00:17:59,710 --> 00:18:02,480 I don't really have good handwriting, 296 00:18:02,480 --> 00:18:05,520 and so therefore I want you to print something on the screen for me. 297 00:18:05,520 --> 00:18:12,040 I am being the main program, and I'm going to have you say this 298 00:18:12,040 --> 00:18:16,720 by writing it in my chicken scratch and then passing you an input. 299 00:18:16,720 --> 00:18:20,400 So silly though this exercise is, the notion of functions and calling a function 300 00:18:20,400 --> 00:18:22,400 and returning a function really boils down to this. 301 00:18:22,400 --> 00:18:26,260 I am main, I have just written printf, quote-unquote something on the screen, 302 00:18:26,260 --> 00:18:29,110 I am running this program, and as soon as printf gets called, 303 00:18:29,110 --> 00:18:32,880 it takes one argument or one parameter sometimes between double quotes. 304 00:18:32,880 --> 00:18:35,880 Here is that argument. I'm passing it to Ken. 305 00:18:35,880 --> 00:18:39,020 He is a black box written some number of years ago 306 00:18:39,020 --> 00:18:41,510 that apparently only knows how to print things on the screen. 307 00:18:41,510 --> 00:18:43,150 So execute. 308 00:18:49,280 --> 00:18:51,280 That's not bad. Very good. 309 00:18:51,280 --> 00:18:55,510 So now Ken is done executing. Does he need to hand me anything back? 310 00:18:55,510 --> 00:18:57,470 Not that we've seen thus far. 311 00:18:57,470 --> 00:19:00,460 Again, printf does actually return a number, but we're going to ignore that for now 312 00:19:00,460 --> 00:19:03,470 because we've never used it. So that's it for Ken. 313 00:19:03,470 --> 00:19:08,580 And so now main takes over control of the program again 314 00:19:08,580 --> 00:19:11,060 because that line of code, printf, is done executing. 315 00:19:11,060 --> 00:19:14,050 And we go about our way, executing whatever other lines are there. 316 00:19:14,050 --> 00:19:17,320 So now let's try a slightly different example. 317 00:19:17,320 --> 00:19:24,940 This time here let's first clear the screen, and this time we'll do the cubing function, 318 00:19:24,940 --> 00:19:27,080 but this time, I expect an output value. 319 00:19:27,080 --> 00:19:29,180 >> So let's go ahead and do this. 320 00:19:29,180 --> 00:19:35,790 Now I have a line of code that says x gets cube of x. 321 00:19:41,370 --> 00:19:46,370 The line of code, recall, looks like this: x = cube(x); 322 00:19:46,370 --> 00:19:50,930 So how is this going to work? Let's go ahead and give you a white screen again. 323 00:19:50,930 --> 00:19:54,070 I am going to write down now the value of x, 324 00:19:54,070 --> 00:20:01,400 which at this moment in time happens to be, let's say, 2 to keep it simple. 325 00:20:01,400 --> 00:20:06,150 I have written down on a piece of paper the value of 2, which is my value x. 326 00:20:06,150 --> 00:20:10,920 I hand it to Ken. >>And I just write the answer? >>Yeah, let's just write the answer. 327 00:20:12,760 --> 00:20:18,940 Okay. And now he has to return me something. Perfect. Nice segue. 328 00:20:18,940 --> 00:20:23,120 So now he hands me back the value of 8 in this case, and what do I do with it? 329 00:20:23,120 --> 00:20:28,250 Actually--let's see, get this right. What am I going to do with it? 330 00:20:28,250 --> 00:20:33,440 Now I'm going to take this value and actually store it in those same bits in memory. 331 00:20:33,440 --> 00:20:35,170 But notice I'm kind of struggling here. 332 00:20:35,170 --> 00:20:38,210 I'm a little confused because where do I actually write the value of x, 333 00:20:38,210 --> 00:20:43,150 because what I've just done is physically hand Ken a piece of paper that had the value 2, 334 00:20:43,150 --> 00:20:46,590 which was x, and indeed, that's precisely what happened. 335 00:20:46,590 --> 00:20:50,210 So it turns out that when you call the function and you pass in an argument 336 00:20:50,210 --> 00:20:53,290 like hello, world or you pass in an argument like 2, 337 00:20:53,290 --> 00:20:57,110 generally, you're passing in a copy of that argument. 338 00:20:57,110 --> 00:21:00,730 And so just as I wrote down the number 2 here and handed it to Ken, 339 00:21:00,730 --> 00:21:04,720 that must mean that I still have a copy of the value 2 somewhere 340 00:21:04,720 --> 00:21:08,890 because indeed, now that I've gotten back the value 8, I need to go back in RAM 341 00:21:08,890 --> 00:21:12,130 and actually write down 8 where I once had the number 2. 342 00:21:12,130 --> 00:21:16,950 So visually, remember this notion of passing in, literally, a copy of the value. 343 00:21:16,950 --> 00:21:20,780 >> Ken does his thing, hands me back something--in this case a value like 8-- 344 00:21:20,780 --> 00:21:24,980 and then I have to do something with that value if I want to keep it around. 345 00:21:24,980 --> 00:21:29,650 So all of this will come back to be all too familiar before long. 346 00:21:29,650 --> 00:21:34,920 Thank you so much for this demo here, Ken. [applause] 347 00:21:34,920 --> 00:21:36,920 Very well done. 348 00:21:36,920 --> 00:21:42,690 Let's see how that ultimately relates to some of the function calling that we've been doing here. 349 00:21:42,690 --> 00:21:47,910 Let me go ahead and bring us back to the cubing example here. 350 00:21:47,910 --> 00:21:53,300 Notice that if we want to actually start taking this further, 351 00:21:53,300 --> 00:21:57,570 we're going to have to be mindful of the fact that the number x that's being passed in here 352 00:21:57,570 --> 00:22:01,530 is different from what's actually being passed in to the function. 353 00:22:01,530 --> 00:22:05,880 So again, this pass by copy is going to become quite germane in just a moment. 354 00:22:05,880 --> 00:22:09,580 Let's take a look at something that doesn't quite work right yet. 355 00:22:09,580 --> 00:22:13,250 I'm going to go ahead and open a third buggy example, which is flawed by nature, 356 00:22:13,250 --> 00:22:18,550 and it's called buggy3 and it implements a swapping function. 357 00:22:18,550 --> 00:22:25,110 Here we have a main function that has x and y arbitrarily initialized to 1 and 2, respectively. 358 00:22:25,110 --> 00:22:27,700 We could use GetInt, but we just need a simple exercise, 359 00:22:27,700 --> 00:22:30,170 so it's hard-coded as 1 and 2. 360 00:22:30,170 --> 00:22:35,340 In lines 21 and 22, we apparently print out x and y, 1 per line. 361 00:22:35,340 --> 00:22:39,720 Then on line 23, I claim I am swapping these values, dot, dot, dot. 362 00:22:39,720 --> 00:22:44,170 I apparently call a function in line 24 called swap that takes 2 arguments. 363 00:22:44,170 --> 00:22:48,300 It's totally legit for functions to take 2 arguments. We've seen printf do it already. 364 00:22:48,300 --> 00:22:51,830 >> So swap apparently takes x and y, and as its name suggests, 365 00:22:51,830 --> 00:22:54,670 I would hope that it's going to swap these 2 values. 366 00:22:54,670 --> 00:23:00,090 So then I claim on line 25 "Swapped!" and I reprint x and y 367 00:23:00,090 --> 00:23:03,070 under the assumption that they've indeed been swapped. 368 00:23:03,070 --> 00:23:06,080 But if I actually run this program--let me open up a terminal window, 369 00:23:06,080 --> 00:23:09,860 let me make buggy3--as the name suggests, this is not going to end well 370 00:23:09,860 --> 00:23:15,770 because when I hit Enter, notice that x is 1, y is 2, 371 00:23:15,770 --> 00:23:19,420 and yet at the end of the program, they are still, in fact, the same. 372 00:23:19,420 --> 00:23:22,960 So based on the demonstration just now with Ken, what's actually going on? 373 00:23:22,960 --> 00:23:28,710 Let's dive into this swap function. It's super short. It's only a few lines of code long. 374 00:23:28,710 --> 00:23:34,520 But what's the fundamental problem based on the simple story told up here with Ken? 375 00:23:34,520 --> 00:23:36,670 Why is swap broken? 376 00:23:36,670 --> 00:23:39,660 [student] You're storing to a copy, not the variable. 377 00:23:39,660 --> 00:23:43,980 Exactly. We're storing to a copy, not the variable itself. 378 00:23:43,980 --> 00:23:47,170 In other words, swap apparently takes 2 arguments, an int, 379 00:23:47,170 --> 00:23:49,370 and it's arbitrarily called a and b, 380 00:23:49,370 --> 00:23:54,420 and up here I've passed in x and y, which are respectively 1 and 2, 381 00:23:54,420 --> 00:23:58,770 but I'm not literally passing in x, I'm not literally passing in y, 382 00:23:58,770 --> 00:24:01,450 I'm passing a copy of x and a copy of y. 383 00:24:01,450 --> 00:24:04,510 It's almost as though you copied and pasted into swap 384 00:24:04,510 --> 00:24:07,810 the values that you want it to actually manipulate. 385 00:24:07,810 --> 00:24:14,480 So if that's the case, when I the program start executing line 35 then 36, 386 00:24:14,480 --> 00:24:18,650 when I get to line 37, at this point in the story, what is the value of a? 387 00:24:21,040 --> 00:24:25,050 At this point in the story, line 37, what is the value of a at this point? >>[student] 1. 388 00:24:25,050 --> 00:24:29,280 [Malan] It should just be 1, right, because x was passed in as the first argument, 389 00:24:29,280 --> 00:24:33,080 and this function just arbitrarily is calling its first argument a. 390 00:24:33,080 --> 00:24:38,200 Similarly is y the second argument, and it's just arbitrarily calling the second argument b. 391 00:24:38,200 --> 00:24:40,990 >> This dichotomy is actually fairly simply explained. Think about it. 392 00:24:40,990 --> 00:24:43,320 None of us have met the person who wrote printf, 393 00:24:43,320 --> 00:24:50,770 so surely, he or she has no idea what our variables 30 years later are going to be called. 394 00:24:50,770 --> 00:24:56,650 So there has to be a distinction between what you call variables in functions you're writing 395 00:24:56,650 --> 00:25:02,080 and what you call variables in functions you're calling or using. 396 00:25:02,080 --> 00:25:05,340 So in other words, I have written my variables as x and y, 397 00:25:05,340 --> 00:25:08,890 but if someone else had written the swap function, he or she certainly wouldn't know 398 00:25:08,890 --> 00:25:10,690 what my variables are going to be called, 399 00:25:10,690 --> 00:25:13,830 so realize that this is why you have this duality of names. 400 00:25:13,830 --> 00:25:16,750 Technically, I could do this by coincidence, 401 00:25:16,750 --> 00:25:20,080 but they would still be passed in as copies. 402 00:25:20,080 --> 00:25:23,650 It would just be a pure coincidence aesthetically if that person who wrote swap 403 00:25:23,650 --> 00:25:26,150 had used the same names. 404 00:25:26,150 --> 00:25:32,370 So at this point in the story, line 37, a is 1, b is 2, and now I proceed to swap them. 405 00:25:32,370 --> 00:25:34,900 First of all, let me actually do this much more simply. 406 00:25:34,900 --> 00:25:36,690 I don't know what those 3 lines of code were doing. 407 00:25:36,690 --> 00:25:41,210 Let me just do this: b = a; a = b; done. 408 00:25:41,210 --> 00:25:44,690 Why is this broken, logically? 409 00:25:46,490 --> 00:25:48,900 It's kind of the intuitive thing, right? 410 00:25:48,900 --> 00:25:52,560 So a becomes b and b becomes a, 411 00:25:52,560 --> 00:25:57,730 but the problem is that as soon as line 37 executes, what's the value of a and b? 412 00:25:57,730 --> 00:26:03,410 The same, 1, because you have clobbered, so to speak, you've changed b to equal a. 413 00:26:03,410 --> 00:26:08,890 So once line 37 has executed, that's great, you now have 2 copies of the number 1 414 00:26:08,890 --> 00:26:13,350 inside of this function, so then when you say in line 38 a = b, 415 00:26:13,350 --> 00:26:17,640 you're kind of screwed because you're just assigning 1 to 1. 416 00:26:17,640 --> 00:26:20,580 You've kind of lost the value you cared about. 417 00:26:20,580 --> 00:26:23,220 So in the original version of this, notice what I did. 418 00:26:23,220 --> 00:26:26,850 I instead had a third line of code that looked like this. 419 00:26:26,850 --> 00:26:28,580 I declare a temporary variable. 420 00:26:28,580 --> 00:26:32,170 >> Tmp is a very common name for a temporary variable, and it's an int 421 00:26:32,170 --> 00:26:34,580 because it has to match what I want to make a copy of. 422 00:26:34,580 --> 00:26:39,770 I store copy of a inside of tmp, so once line 37 has executed, 423 00:26:39,770 --> 00:26:45,860 the value of a is--quick sanity check--1, the value of b is 2, 424 00:26:45,860 --> 00:26:48,970 and the value of tmp is also 1. 425 00:26:48,970 --> 00:26:52,060 So now I execute line 38. 426 00:26:52,060 --> 00:27:00,540 Once line 38 executes, a takes on the value of b. And b was 2, so a is now 2. 427 00:27:00,540 --> 00:27:05,210 So at this point in the story, a is 2, b is 2, and tmp is 1, 428 00:27:05,210 --> 00:27:11,060 so now logically, we can just plop tmp's value into b and we're done. 429 00:27:11,060 --> 00:27:12,800 So we've solved that problem. 430 00:27:12,800 --> 00:27:17,720 Unfortunately, when I run this program in this form, it doesn't actually swap any values. 431 00:27:17,720 --> 00:27:20,100 But to be clear, why? 432 00:27:23,660 --> 00:27:26,450 I fixed the logical problem from just a moment ago, 433 00:27:26,450 --> 00:27:31,020 but again, if I run this program, x and y remain unchanged 434 00:27:31,020 --> 00:27:33,310 by the end of the program's execution. 435 00:27:33,310 --> 00:27:37,220 [inaudible student comment] >>We haven't returned anything, so that's true. 436 00:27:37,220 --> 00:27:39,670 But it turns out there's a bit of a problem here because thus far, 437 00:27:39,670 --> 00:27:44,170 the only thing we've been able to return is one thing, and this is a restriction of C. 438 00:27:44,170 --> 00:27:49,070 You can only return really one value, in which case I'm kind of stuck here 439 00:27:49,070 --> 00:27:53,310 because I could return the new value of x or I could return the new value of y, 440 00:27:53,310 --> 00:27:55,190 but I want both back. 441 00:27:55,190 --> 00:27:58,650 So returning is not the simple solution here. 442 00:27:58,650 --> 00:28:01,710 But the problem fundamentally is why? What have we actually swapped? 443 00:28:01,710 --> 00:28:04,190 [student] a and b. >>a and b. 444 00:28:04,190 --> 00:28:08,230 But a and b are copies of x and y, which means we just did all of this work, 445 00:28:08,230 --> 00:28:11,650 we just spent 3 minutes talking about the swap function and all 3 of these variables, 446 00:28:11,650 --> 00:28:15,420 and that's great, perfectly correct in isolation, 447 00:28:15,420 --> 00:28:20,740 but a and b's scope only is in these lines here. 448 00:28:20,740 --> 00:28:24,790 >> So just like a for loop, if you declare an integer i inside the for loop, 449 00:28:24,790 --> 00:28:28,760 similarly, if you're declaring a and b inside of a function that you've written, 450 00:28:28,760 --> 00:28:33,320 they're only valid inside of that function, which means as soon as swap is done executing 451 00:28:33,320 --> 00:28:38,470 and we go from line 24 to line 25, x and y haven't been changed at all. 452 00:28:38,470 --> 00:28:42,790 You just wasted a whole lot of time swapping copies of variables. 453 00:28:42,790 --> 00:28:47,010 So it turns out that the solution to this is actually non-obvious. 454 00:28:47,010 --> 00:28:50,670 It's not quite sufficient to return values because we can only return 1 value, 455 00:28:50,670 --> 00:28:53,470 and I really do want to swap both x and y at the same time, 456 00:28:53,470 --> 00:28:55,210 so we're going to have to come back to this. 457 00:28:55,210 --> 00:29:01,020 But for now, realize that the issue fundamentally derived from the fact that a and b are copies 458 00:29:01,020 --> 00:29:03,630 and they are in their own scope. 459 00:29:03,630 --> 00:29:05,050 Let's try to solve this in some way. 460 00:29:05,050 --> 00:29:11,250 Let me actually scroll back here and open up, let's say, a fourth variant of this, buggy4. 461 00:29:11,250 --> 00:29:13,370 What about this? 462 00:29:13,370 --> 00:29:17,810 This is a similar but simpler problem to look at before we take a stab at solving it. 463 00:29:17,810 --> 00:29:24,190 This program is called increment, and it apparently initializes an x integer to 1 in line 18. 464 00:29:24,190 --> 00:29:28,150 I then claim x is 1, I then claim "Incrementing..." 465 00:29:28,150 --> 00:29:33,730 I then call increment, but then in lines 22 and 23, I claim it's been incremented, 466 00:29:33,730 --> 00:29:40,220 I claim x is now whatever it is--2, presumably--but this program is buggy. 467 00:29:40,220 --> 00:29:42,610 What's the problem? 468 00:29:43,440 --> 00:29:50,160 Yeah. >>[inaudible student response] >>Exactly. 469 00:29:50,160 --> 00:29:52,490 So x has been declared, obviously, on line 18. 470 00:29:52,490 --> 00:29:54,700 That is inside main's curly braces. 471 00:29:54,700 --> 00:29:58,440 So the simple answer here is that while x exists here, 472 00:29:58,440 --> 00:30:03,930 it does not exist in line 32, so this program actually won't even compile. 473 00:30:03,930 --> 00:30:07,940 The compiler when I try compiling this code is going to yell at me 474 00:30:07,940 --> 00:30:14,100 about some undeclared identifier or something to that effect. In fact, let's try. 475 00:30:14,100 --> 00:30:18,470 This is make buggy4. There it is. 476 00:30:18,470 --> 00:30:22,110 Use of undeclared identifier 'x' in line 32. 477 00:30:22,110 --> 00:30:25,580 And actually, let's be more explicit here today so that this is useful 478 00:30:25,580 --> 00:30:27,580 in office hours and at home. 479 00:30:27,580 --> 00:30:29,300 >> Notice that it's a little cryptically written. 480 00:30:29,300 --> 00:30:37,270 But the fact that Clang has yelled at us, saying buggy4.c:32:5, is actually useful. 481 00:30:37,270 --> 00:30:42,050 It means that the error is on line 32 at character position 5. 482 00:30:42,050 --> 00:30:46,700 So 1, 2, 3, 4, 5. That's, in fact, where the problem is. 483 00:30:46,700 --> 00:30:49,790 And also, too, keep in mind at office hours and at home, I'm lucky here. 484 00:30:49,790 --> 00:30:52,990 I have one mistake. It's going to be relatively easy to fix. 485 00:30:52,990 --> 00:30:55,990 But if you get a whole screen full of overwhelming error messages, 486 00:30:55,990 --> 00:31:00,330 again realize that the bottommost one might just be symptomatic of the topmost one. 487 00:31:00,330 --> 00:31:03,450 So always chase down your bugs from top down 488 00:31:03,450 --> 00:31:05,820 because there might just be a daisy chain effect 489 00:31:05,820 --> 00:31:09,240 that is suggesting you have way more problems than you actually do. 490 00:31:09,240 --> 00:31:15,150 So how could we fix this if my goal is to increment x? >>[student] Make x global. 491 00:31:15,150 --> 00:31:17,060 Okay, so we can make x global. 492 00:31:17,060 --> 00:31:20,480 Let's take the shortcut that I warned about earlier, but heck, we just need a quick fix, 493 00:31:20,480 --> 00:31:25,730 so let's just say int x up here. That makes x global. 494 00:31:25,730 --> 00:31:31,800 So now main has access to it and increment has access to it, 495 00:31:31,800 --> 00:31:34,110 and so let me go ahead and compile this now. 496 00:31:34,110 --> 00:31:37,630 Make buggy4, Enter. Seems to compile now. 497 00:31:37,630 --> 00:31:41,230 Let's run buggy4. And it seems to actually work. 498 00:31:41,230 --> 00:31:45,150 This is one of these things that's do as I say, not as I do, 499 00:31:45,150 --> 00:31:47,010 as I've just done here, because in general, 500 00:31:47,010 --> 00:31:50,440 our programs are going to get much more interesting and much longer than this, 501 00:31:50,440 --> 00:31:56,390 and if your solution to life's problems is just put all the variables at the top of your file, 502 00:31:56,390 --> 00:31:59,690 very quickly do programs get horrifically difficult to manage. 503 00:31:59,690 --> 00:32:02,190 It gets harder to think up new variable names, 504 00:32:02,190 --> 00:32:05,240 it gets harder to understand what variable is doing what, 505 00:32:05,240 --> 00:32:08,460 and so in general, this is not a good solution. 506 00:32:08,460 --> 00:32:10,030 So let's do this better. 507 00:32:10,030 --> 00:32:12,160 We don't want to use a global variable here. 508 00:32:12,160 --> 00:32:16,240 >> I do want to increment x, so I could obviously-- 509 00:32:16,240 --> 00:32:18,670 at the end of the day, this is kind of a silly story because we just do this-- 510 00:32:18,670 --> 00:32:24,450 but if I didn't know about that operator or I wasn't allowed to change it in main itself, 511 00:32:24,450 --> 00:32:30,730 how else could I implement Ken over here this time not to cube but to increment? 512 00:32:31,380 --> 00:32:33,190 How do I change this thing here? Yeah. 513 00:32:33,190 --> 00:32:38,480 [student] Pass in x and then return [inaudible] >>Okay, good. 514 00:32:38,480 --> 00:32:41,900 So why don't I pass in x and then rather than return it, 515 00:32:41,900 --> 00:32:44,870 why don't I just do return x + 1. 516 00:32:44,870 --> 00:32:47,710 A couple more things have to change here. I'm on the right track. 517 00:32:47,710 --> 00:32:49,770 What else do I need to tweak? Someone else. Yeah. 518 00:32:49,770 --> 00:32:51,740 [inaudible student response] 519 00:32:51,740 --> 00:32:54,730 I need to change the return type of increment because it's not void. 520 00:32:54,730 --> 00:32:57,780 Void means nothing is being returned, but clearly now it is, 521 00:32:57,780 --> 00:32:59,830 so this needs to change to-- >>[student] int. 522 00:32:59,830 --> 00:33:02,740 int to be consistent with whatever I'm actually returning. 523 00:33:02,740 --> 00:33:05,180 Now something else is still buggy here. Yeah. 524 00:33:05,180 --> 00:33:08,400 [inaudible student response] >>[Malan] So I need to increment x? 525 00:33:08,400 --> 00:33:12,080 [inaudible student response] >>[Malan] Ah, so I need to pass x. 526 00:33:12,080 --> 00:33:16,660 So I need to do this here. >>[inaudible student comment] 527 00:33:16,660 --> 00:33:20,050 [Malan] So the prototype, I have to change this up here. 528 00:33:20,050 --> 00:33:22,930 So this has to become an int, this has to become-- 529 00:33:22,930 --> 00:33:25,620 hmm, I actually have a bug down here. Let's fix this one first. 530 00:33:25,620 --> 00:33:29,590 What should this actually be? It's got to be an int something. 531 00:33:29,590 --> 00:33:32,700 It could be x, but frankly, if you start calling all of your variables x, 532 00:33:32,700 --> 00:33:35,390 it's going to get less and less clear which is which. 533 00:33:35,390 --> 00:33:39,560 >> So let's just arbitrarily choose a different naming convention for my helper functions, 534 00:33:39,560 --> 00:33:41,940 the functions I'm writing. We'll call it a, or we could call it-- 535 00:33:41,940 --> 00:33:45,010 Let's call it number to be even more explicit. 536 00:33:45,010 --> 00:33:47,560 So then I have to return whatever the number is plus 1, 537 00:33:47,560 --> 00:33:50,740 and now I have to change 1 other thing up here and one other thing up here. 538 00:33:50,740 --> 00:33:54,350 What do I have to change on line 21 first? >>[inaudible student response] 539 00:33:54,350 --> 00:33:57,610 [Malan] I have to assign it to x. I can't just call increment(x). 540 00:33:57,610 --> 00:34:01,960 I need to remember the answer by changing the value of x on the left-hand side. 541 00:34:01,960 --> 00:34:04,680 And even though x is now on the left and right, that's totally fine 542 00:34:04,680 --> 00:34:08,860 because the right-hand side gets executed first then gets plopped into the left-hand thing-- 543 00:34:08,860 --> 00:34:10,600 x in this case. 544 00:34:10,600 --> 00:34:12,159 And then lastly, this is an easy fix now. 545 00:34:12,159 --> 00:34:17,230 This should just match what's down below, int number. 546 00:34:17,230 --> 00:34:20,570 So a whole bunch of changes for a really stupid function 547 00:34:20,570 --> 00:34:24,420 but representative of things that we'll increasingly want to do. 548 00:34:24,420 --> 00:34:27,090 So make buggy4. I've screwed up somewhere. 549 00:34:27,090 --> 00:34:30,139 Oh, my God. Five mistakes in a 6-line program. 550 00:34:30,139 --> 00:34:35,690 So what's wrong on line 18, character 5? 551 00:34:35,690 --> 00:34:39,610 So I have to declare this, int. 552 00:34:39,610 --> 00:34:41,920 Let's see. There are a whole bunch of other errors. 553 00:34:41,920 --> 00:34:47,010 Oh, my God--19, 18, 21--but again, let's just clear the screen, Control L here, 554 00:34:47,010 --> 00:34:49,380 and rerun Clang. 555 00:34:49,380 --> 00:34:51,340 So 5 problems is actually just that 1. 556 00:34:51,340 --> 00:34:57,520 So now let's run buggy4, Enter. Whew, x has been incremented correctly. 557 00:34:57,520 --> 00:35:02,720 All right. Any questions on how to increment numbers? Yeah. 558 00:35:02,720 --> 00:35:09,870 [inaudible student question] >>Good question. 559 00:35:09,870 --> 00:35:14,220 How is it that I can just change x to number and the program will know immediately? 560 00:35:14,220 --> 00:35:16,200 >> Again, think of it as this abstraction. 561 00:35:16,200 --> 00:35:21,600 So if I am main and Ken is increment, frankly, I don't care what Ken calls his iPad. 562 00:35:21,600 --> 00:35:26,570 I don't care what he calls anything that has to do with his implementation of this functionality. 563 00:35:26,570 --> 00:35:33,340 This is an implementation detail that I, main, don't have to care about. 564 00:35:33,340 --> 00:35:38,250 And so simply changing it consistently inside of the function--number here and number here-- 565 00:35:38,250 --> 00:35:40,960 is all it takes so long as I recompile. 566 00:35:40,960 --> 00:35:44,180 It's sort of like if you think about many of us, those of you with driver's licenses 567 00:35:44,180 --> 00:35:46,770 who have driven or if you've even driven in a car, 568 00:35:46,770 --> 00:35:50,950 most of us have no idea how a car works underneath the hood. 569 00:35:50,950 --> 00:35:54,970 And literally, if you open up the hood, most of us--myself included-- 570 00:35:54,970 --> 00:35:56,940 aren't going to really know what we're looking at, 571 00:35:56,940 --> 00:35:59,220 kind of like you might feel with stuff like this right now. 572 00:35:59,220 --> 00:36:01,480 But we don't really have to care how the car works, 573 00:36:01,480 --> 00:36:05,970 we don't have to care what all of the rods and pistons and cables inside of the car 574 00:36:05,970 --> 00:36:08,160 are actually doing. 575 00:36:08,160 --> 00:36:12,770 So something like what you call the piston doesn't matter here in this case. Same idea. 576 00:36:12,770 --> 00:36:25,300 Yeah. >>[inaudible student question] 577 00:36:25,300 --> 00:36:29,180 If there are more uses of the variable x a moment ago, 578 00:36:29,180 --> 00:36:32,150 you, the programmer, would have to change them everywhere. 579 00:36:32,150 --> 00:36:36,600 Or you could literally do File, Menu, and then Find, Replace--something like that-- 580 00:36:36,600 --> 00:36:39,170 but you are going to have to make those changes yourself. 581 00:36:39,170 --> 00:36:47,450 You have to be consistent. >>[student] If there are multiple variables [inaudible] 582 00:36:47,450 --> 00:36:53,100 A particular order like here, if this was int another number? >>[student] Correct. 583 00:36:53,100 --> 00:36:56,590 [Malan] Yeah. Order matters when you are calling the function. 584 00:36:56,590 --> 00:37:00,050 >> So if I were calling increment here with something comma something, 585 00:37:00,050 --> 00:37:01,680 there's a direct mapping. 586 00:37:01,680 --> 00:37:05,690 The first variable, whatever it's called, is made a copy of the first argument over here. 587 00:37:05,690 --> 00:37:07,760 Sorry. This should not be a parenthesis. 588 00:37:07,760 --> 00:37:11,490 The second argument lines up with the second one. So order, yes, matters. All right. 589 00:37:11,490 --> 00:37:17,020 Sorry. I took the long way to get there. Other questions? All right. 590 00:37:17,020 --> 00:37:20,610 So let's see if we can't paint a picture of what's actually going on here 591 00:37:20,610 --> 00:37:23,090 underneath the hood, so to speak. 592 00:37:23,090 --> 00:37:26,640 This is a rectangle that might represent your computer's memory. 593 00:37:26,640 --> 00:37:30,970 Even if you have no idea how memory works or how RAM works, 594 00:37:30,970 --> 00:37:33,940 at least assume that you have bunches of it these days. 595 00:37:33,940 --> 00:37:36,280 You've got megabytes of it, you've got gigabytes of it, 596 00:37:36,280 --> 00:37:40,870 and we know from week 0 that a byte is just what? >>[student] 8 bits. 597 00:37:40,870 --> 00:37:42,950 8 bits, right? So 8 zeroes and 1. 598 00:37:42,950 --> 00:37:45,880 So if your computer has a gig of RAM, 2 gigs of RAM these days, 599 00:37:45,880 --> 00:37:55,030 you have a billion or 2 billion bytes of memory or roughly 8 billion or 16 billion bits 600 00:37:55,030 --> 00:37:56,890 inside of your computer. 601 00:37:56,890 --> 00:38:00,590 Unlike the little Wooly Willy example, it's not magnetic particles typically anymore. 602 00:38:00,590 --> 00:38:04,450 Increasingly--in laptops at least--it's solid state drives, SSDs, 603 00:38:04,450 --> 00:38:08,580 that just have no moving parts. It's all electronic. It's all electricity-based. 604 00:38:08,580 --> 00:38:14,060 So think of this rectangle as just representing the 1 or 2 gigabytes of memory that you have. 605 00:38:14,060 --> 00:38:16,020 >> So it's a chunk of memory. 606 00:38:16,020 --> 00:38:19,830 The world of computer science has sort of partitioned off 607 00:38:19,830 --> 00:38:22,950 chunks of memory to do different things. 608 00:38:22,950 --> 00:38:27,190 For instance, if this is your computer's RAM, as suggested by the rectangle there, 609 00:38:27,190 --> 00:38:31,130 it turns out that by convention, at the top of your RAM, so to speak, 610 00:38:31,130 --> 00:38:33,660 is generally what's called a text segment. 611 00:38:33,660 --> 00:38:36,740 Those are the 0s and 1s that you have compiled. 612 00:38:36,740 --> 00:38:39,020 So when we've looked underneath the hood at what a.out is, 613 00:38:39,020 --> 00:38:41,980 all these 0s and 1s, when you run a program, 614 00:38:41,980 --> 00:38:46,290 those 0s and 1s are loaded from your hard drive into something called RAM, 615 00:38:46,290 --> 00:38:49,320 and in the RAM they're put at the top. 616 00:38:49,320 --> 00:38:52,770 Meanwhile, you have other things: initialize data, uninitialize data. 617 00:38:52,770 --> 00:38:57,510 Those 2 swaths of memory refer to global variables, which you don't often use 618 00:38:57,510 --> 00:39:00,760 but sometimes if you do, they end up up there as well. 619 00:39:00,760 --> 00:39:04,260 Then there's some other stuff: environment variables, which we won't spend much time on, 620 00:39:04,260 --> 00:39:06,860 but then 2 important things that will come back throughout the semester, 621 00:39:06,860 --> 00:39:08,550 stack and heap. 622 00:39:08,550 --> 00:39:12,210 So most of your computer's memory is reserved when running a program 623 00:39:12,210 --> 00:39:15,370 for something called the stack and something called the heap. 624 00:39:15,370 --> 00:39:18,840 We're not going to talk about the heap today, but we will talk about the stack. 625 00:39:18,840 --> 00:39:24,600 The stack is meant to conjure up the visual of the dining hall meal trays in Mather House 626 00:39:24,600 --> 00:39:28,110 or wherever you happen to be where the dining hall staff clean them every day, 627 00:39:28,110 --> 00:39:30,180 they stack them up from floor on up, 628 00:39:30,180 --> 00:39:34,550 and similarly, in memory, there is this idea of putting something on a stack, 629 00:39:34,550 --> 00:39:36,860 putting something on a stack, putting something on a stack. 630 00:39:36,860 --> 00:39:38,240 And what do we mean by this? 631 00:39:38,240 --> 00:39:41,860 >> Let's zoom in on just the lower half of this picture, your computer's RAM, 632 00:39:41,860 --> 00:39:44,330 to propose the following. 633 00:39:44,330 --> 00:39:48,170 It turns out that when you run a program like a.out or hello-- 634 00:39:48,170 --> 00:39:50,100 whatever the program is that you've written-- 635 00:39:50,100 --> 00:39:54,020 again, those 0s and 1s are loaded from your hard drive, which is long-term storage, 636 00:39:54,020 --> 00:39:57,230 stays there even when you pull the plug, loaded into RAM. 637 00:39:57,230 --> 00:40:00,610 RAM is faster than hard drives--it's smaller than hard drives-- 638 00:40:00,610 --> 00:40:03,300 but it's where programs live while you're running them. 639 00:40:03,300 --> 00:40:08,230 So you double click a program on a Mac or PC, it's loaded from hard drive into RAM. 640 00:40:08,230 --> 00:40:11,520 As soon as it's loaded into RAM, the 0s and 1s go at the way top, 641 00:40:11,520 --> 00:40:16,610 the so-called text segment, but then as soon as your program actually starts running, 642 00:40:16,610 --> 00:40:21,360 the main function is called, and main, as we've seen, often has local variables, 643 00:40:21,360 --> 00:40:24,870 and it has ints and strings and chars and the like. 644 00:40:24,870 --> 00:40:29,180 So if your program that you have written or the program that you have double clicked 645 00:40:29,180 --> 00:40:32,970 used some variables inside of main, 646 00:40:32,970 --> 00:40:37,240 they end up at the bottom of your stack of memory, so to speak. 647 00:40:37,240 --> 00:40:39,410 More concretely, what does this actually mean? 648 00:40:39,410 --> 00:40:48,450 This just means that if we were going to number the bytes of RAM in your computer, 649 00:40:48,450 --> 00:40:55,750 notice that this might be byte number 0, this might be byte number 1, 2, 3, 4, 5, 6, 650 00:40:55,750 --> 00:41:01,480 all the way up to 2 billion would be all the way up there at the top. 651 00:41:01,480 --> 00:41:05,880 So in other words, when we talk about RAM or memory in terms of bytes, 652 00:41:05,880 --> 00:41:11,500 it just means that someone has decided what to number each of those chunks of memory. 653 00:41:11,500 --> 00:41:16,650 So when you need 32 bits for an int or you need 8 bits for a char, 654 00:41:16,650 --> 00:41:18,840 where do they end up in memory? 655 00:41:18,840 --> 00:41:22,350 >> Conceptually, they just end up at the bottom of this thing called the stack. 656 00:41:22,350 --> 00:41:25,870 But what's interesting now is when main calls a function-- 657 00:41:25,870 --> 00:41:28,750 suppose a function called foo, just an arbitrary name-- 658 00:41:28,750 --> 00:41:32,330 what happens is main is at the bottom of this stack of memory; 659 00:41:32,330 --> 00:41:35,680 foo now is put on top of main in memory. 660 00:41:35,680 --> 00:41:40,990 So any local variables that foo has end up sort of conceptually above those in main. 661 00:41:40,990 --> 00:41:47,070 If foo calls another function called bar, those variables end up here. 662 00:41:47,070 --> 00:41:50,120 If bar calls something else, here, here, here. 663 00:41:50,120 --> 00:41:53,830 So what's interesting about running a program is that as you call functions 664 00:41:53,830 --> 00:41:57,750 and as those functions call functions and as those functions call functions, 665 00:41:57,750 --> 00:42:01,470 you build up this stack of functions in memory. 666 00:42:01,470 --> 00:42:06,890 And only once a function returns do you start getting that memory back. 667 00:42:06,890 --> 00:42:10,860 So one of the easiest ways to run out of memory in a computer program 668 00:42:10,860 --> 00:42:14,360 is to write functions that never return. 669 00:42:14,360 --> 00:42:18,900 So for instance, let's demonstrate as much with an intentionally buggy program. 670 00:42:18,900 --> 00:42:22,230 Let me go ahead and do #include , 671 00:42:22,230 --> 00:42:25,000 int main(void), 672 00:42:25,000 --> 00:42:32,940 and I'm going to do while (2 > 1), which probably won't ever change on us, 673 00:42:32,940 --> 00:42:37,560 and let me go ahead now and do printf. 674 00:42:37,560 --> 00:42:40,700 Actually, that's going to be less visually interesting. Let's do this. 675 00:42:40,700 --> 00:42:50,240 For int i = 0; i > 0--let's make this mistake--i++. 676 00:42:50,240 --> 00:42:52,720 And let's not printf here. Let's practice what I was preaching. 677 00:42:52,720 --> 00:43:00,190 Let's have a method here, void chorus, and we'll say int i, 678 00:43:00,190 --> 00:43:06,830 and then I'm going to say printf--no, let's make this more interesting. 679 00:43:06,830 --> 00:43:15,790 Let's actually not print anything at all. Let's just do this: chorus(i). 680 00:43:15,790 --> 00:43:20,390 All right. So this is buggy because why? 681 00:43:20,390 --> 00:43:23,380 I'm making this up as I go because the program doesn't actually do anything of interest. 682 00:43:23,380 --> 00:43:25,320 >> But that's not the goal. 683 00:43:25,320 --> 00:43:29,630 The goal is to write a program whose main function does what, apparently? 684 00:43:30,720 --> 00:43:32,860 Call itself. And actually, we don't need the loop. 685 00:43:32,860 --> 00:43:37,200 Let's even simplify this just so as not to lose sight of really the fundamental bug. 686 00:43:37,200 --> 00:43:39,640 Main calls chorus to sing some chorus, 687 00:43:39,640 --> 00:43:41,440 then I did something stupid and I had chorus call chorus 688 00:43:41,440 --> 00:43:43,760 because I assumed someone else was going to implement it maybe, 689 00:43:43,760 --> 00:43:47,210 and now this isn't going to compile yet. I need to do what? 690 00:43:47,210 --> 00:43:49,970 I need the prototype, remember. 691 00:43:49,970 --> 00:43:56,110 So I need to have up here void chorus(int i); 692 00:43:56,110 --> 00:43:59,210 So now if I go down here--actually, let's use the bigger window. 693 00:43:59,210 --> 00:44:01,980 Let's go ahead and make chorus. 694 00:44:01,980 --> 00:44:06,490 Let's go ahead and make chorus. 695 00:44:06,490 --> 00:44:08,370 Use of undeclared identifier i. 696 00:44:08,370 --> 00:44:12,500 Oh, that was stupid. We don't need the argument. Let's just do this. 697 00:44:12,500 --> 00:44:16,370 I wish we had started this way. It would have been a much easier program to write. 698 00:44:16,370 --> 00:44:25,590 There. Now let's go over to my terminal window, rerun Clang, and here we go. 699 00:44:25,590 --> 00:44:28,460 That was really fast. 700 00:44:28,460 --> 00:44:31,150 What actually just happened, though? 701 00:44:31,150 --> 00:44:33,730 Well, now I'll add the print line so we can see. 702 00:44:33,730 --> 00:44:43,490 Let me say printf("I'm in here")--no variables. We'll leave it like that. 703 00:44:43,490 --> 00:44:47,480 Let me rerun make. Let me rerun chorus. 704 00:44:47,480 --> 00:44:57,380 And...come on. Keep going. 705 00:44:57,380 --> 00:44:59,930 As an aside, why has it not crashed yet? 706 00:44:59,930 --> 00:45:02,080 The segmentation fault happened super fast before. 707 00:45:02,080 --> 00:45:06,570 [inaudible student response] >>Exactly. So it takes time to print, right? 708 00:45:06,570 --> 00:45:08,610 It just takes more work on the computer's part. 709 00:45:08,610 --> 00:45:10,620 And there it is: Segmentation fault. 710 00:45:10,620 --> 00:45:12,340 >> So notice just how fast programs run. 711 00:45:12,340 --> 00:45:14,130 If you're not printing anything, super fast. 712 00:45:14,130 --> 00:45:18,770 But we still got this segmentation fault because what was happening? 713 00:45:18,770 --> 00:45:21,210 If you think about how your computer's memory is laid out, 714 00:45:21,210 --> 00:45:28,740 this happens to be main, but here let's just call this chorus, and let's call this chorus. 715 00:45:28,740 --> 00:45:34,550 And now if I do my aesthetics right, this is just going to say chorus, chorus, chorus, 716 00:45:34,550 --> 00:45:40,550 chorus, chorus, chorus, chorus, ad nauseum, and eventually, what's going to happen? 717 00:45:40,550 --> 00:45:45,630 If the big picture, literally, is this, what just happens conceptually? 718 00:45:46,520 --> 00:45:48,630 The stack overruns the heap. 719 00:45:48,630 --> 00:45:51,940 Or, worse, you just overrun everything, including the text segment, 720 00:45:51,940 --> 00:45:54,590 which is the 0s and 1s that represent your program. 721 00:45:54,590 --> 00:45:57,080 In short, this is just super, super bad. 722 00:45:57,080 --> 00:45:58,830 Your program has spiraled out of control. 723 00:45:58,830 --> 00:46:01,220 You're using way more memory than you intended 724 00:46:01,220 --> 00:46:03,960 all because of a stupid mistake in this case, 725 00:46:03,960 --> 00:46:08,040 or in this case a very deliberately done function calling itself. 726 00:46:08,040 --> 00:46:09,500 Now, this is not all bad. 727 00:46:09,500 --> 00:46:13,800 Functions calling themselves actually has great power when you use it correctly. 728 00:46:13,800 --> 00:46:15,800 I have not used it correctly here. 729 00:46:15,800 --> 00:46:19,780 So this is not all bad, but the fact that I never actually stop calling myself 730 00:46:19,780 --> 00:46:23,520 is a fundamental weakness here of this program. 731 00:46:23,520 --> 00:46:26,400 So where are we going with all of this? What's really happening? 732 00:46:26,400 --> 00:46:30,340 When I call the increment function like we were doing in those examples, 733 00:46:30,340 --> 00:46:33,420 I have a value like 1 that I pass in. 734 00:46:33,420 --> 00:46:37,570 I pass in a copy of the number 1, so the following happens. 735 00:46:37,570 --> 00:46:44,240 Let's go into the increment example, this guy right over here. 736 00:46:44,240 --> 00:46:46,870 Here's what's actually happening. 737 00:46:46,870 --> 00:46:53,400 When I call increment and I pass in x, pictorially, what's going on here is this. 738 00:46:53,400 --> 00:46:59,520 >> If I have the value of 1 stored here and I actually call increment, 739 00:46:59,520 --> 00:47:04,330 which is now called chorus--the iPad is throwing me off here. 740 00:47:04,330 --> 00:47:09,760 Let's call this increment, and we don't know what this next function is going to be. 741 00:47:09,760 --> 00:47:14,840 So what's actually happening is here somewhere in main I have a chunk of memory 742 00:47:14,840 --> 00:47:17,000 that is storing the number 1. 743 00:47:17,000 --> 00:47:19,380 When I call increment, I'm using another chunk of memory, 744 00:47:19,380 --> 00:47:21,230 but now I have the copy of 1. 745 00:47:21,230 --> 00:47:26,660 When I increment that value, this becomes 2, 746 00:47:26,660 --> 00:47:30,560 but then what happens as soon as increment returns? 747 00:47:30,560 --> 00:47:33,630 This memory just gets handed back to the operating system, 748 00:47:33,630 --> 00:47:37,450 which means all you've done is nothing useful. 749 00:47:37,450 --> 00:47:43,120 The 1 that was originally contained in main is still actually there. 750 00:47:43,120 --> 00:47:44,890 So where are we going with this? 751 00:47:44,890 --> 00:47:49,770 It turns out that in memory you have this back-to-back sequence of bytes 752 00:47:49,770 --> 00:47:53,050 that you can put stuff in, and it turns out that we've already seen something 753 00:47:53,050 --> 00:47:55,390 that involves putting things back to back to back to back. 754 00:47:55,390 --> 00:47:59,860 What is a string based on week 1 and now week 2? 755 00:48:00,020 --> 00:48:01,980 It's just a collection of characters. 756 00:48:01,980 --> 00:48:04,310 So it turns out just as you can put numbers in memory, 757 00:48:04,310 --> 00:48:06,990 similarly can you put characters in memory. 758 00:48:06,990 --> 00:48:10,530 And once we start putting characters in memory back to back to back to back, 759 00:48:10,530 --> 00:48:13,620 it turns out that using the simplest of things like a for loop or a while loop, 760 00:48:13,620 --> 00:48:17,170 we can iterate from left to right over the characters in a string 761 00:48:17,170 --> 00:48:20,600 and start massaging them into different characters altogether-- 762 00:48:20,600 --> 00:48:23,370 a could become b, b could become c-- 763 00:48:23,370 --> 00:48:27,780 so that ultimately, we can take an English sentence that actually makes sense 764 00:48:27,780 --> 00:48:30,310 and convert each of those letters one at a time 765 00:48:30,310 --> 00:48:34,400 by walking through our computer's memory left to right to actually encrypt. 766 00:48:34,400 --> 00:48:35,810 So let's take our five-minute break here, 767 00:48:35,810 --> 00:48:40,730 and when we come back, we'll start this process of scrambling information. 768 00:48:42,020 --> 00:48:43,520 >> All right. 769 00:48:43,520 --> 00:48:48,070 Before we dive into some crypto and these things called arrays, 770 00:48:48,070 --> 00:48:51,470 let me pause for any questions because I feel like I really kind of muddled 771 00:48:51,470 --> 00:48:54,080 some of those topics. So let's fix now if we can. 772 00:48:54,080 --> 00:48:58,700 We just talked about return values, we talked about arguments, 773 00:48:58,700 --> 00:49:03,250 and we talked about this notion, which we'll come back to in the weeks to come, 774 00:49:03,250 --> 00:49:08,720 of viewing memory as a whole bunch of these stacked trays, so to speak, 775 00:49:08,720 --> 00:49:12,660 from bottom on up, such that each tray that gets put on the stack 776 00:49:12,660 --> 00:49:16,530 represents a function that's currently being called. 777 00:49:17,900 --> 00:49:20,260 Any questions? 778 00:49:20,260 --> 00:49:22,640 Let me ask a question here. 779 00:49:22,640 --> 00:49:27,890 Let me simplify this back to what it was before some of our earlier Q&A. 780 00:49:27,890 --> 00:49:35,570 The fact that increment has open parenthesis, int number, closed parenthesis-- 781 00:49:35,570 --> 00:49:39,110 what does int number represent? 782 00:49:39,110 --> 00:49:42,790 [student] An argument. >>An argument. Okay. But what's an argument? 783 00:49:42,790 --> 00:49:46,370 [inaudible student response] >>What's that? >>[student] Something that you pass in. 784 00:49:46,370 --> 00:49:49,940 Okay, so something that you pass in. And more generally, it's just the input. 785 00:49:49,940 --> 00:49:52,450 If you were writing a function and that function's purpose in life 786 00:49:52,450 --> 00:49:55,770 is to do something a little different every time you use it, 787 00:49:55,770 --> 00:50:00,110 then the only way for that to happen really would seem to be to provide it with input 788 00:50:00,110 --> 00:50:03,510 so that it can do something different with that input each time. 789 00:50:03,510 --> 00:50:06,650 >> So you need to specify two things when a function takes input. 790 00:50:06,650 --> 00:50:09,590 You need to specify the name that you want to give to that input 791 00:50:09,590 --> 00:50:12,700 purely for your own convenience so that you can refer to it 792 00:50:12,700 --> 00:50:16,540 in the function that you yourself are writing, as I did here in line 32. 793 00:50:16,540 --> 00:50:20,800 But you also need to specify its type because C is a programming language 794 00:50:20,800 --> 00:50:25,940 that just requires that if you want a variable, you have to tell the computer what data type it is, 795 00:50:25,940 --> 00:50:30,200 in large part so that it knows how many bits to allocate for that variable 796 00:50:30,200 --> 00:50:33,020 because it could be 6--sorry, it won't be 6. 797 00:50:33,020 --> 00:50:37,080 It can be 16, it can be 8, it can be 32, even 64, 798 00:50:37,080 --> 00:50:39,130 but the computer needs to know. 799 00:50:39,130 --> 00:50:43,180 Now, the int on the left-hand side represents what, by contrast? 800 00:50:46,350 --> 00:50:48,850 [inaudible student response] >>What's that? >>[student] Type of function. 801 00:50:48,850 --> 00:50:53,610 The type of a function and, more specifically, the type of its output. Right. 802 00:50:53,610 --> 00:50:57,380 So whereas the thing in parentheses represents its input, if any, 803 00:50:57,380 --> 00:50:59,660 the thing to the left represents its output. 804 00:50:59,660 --> 00:51:03,530 And in this case, increment apparently returns an int, 805 00:51:03,530 --> 00:51:07,690 and so int is the return type of this function. 806 00:51:07,690 --> 00:51:09,340 What does it mean to return? 807 00:51:09,340 --> 00:51:15,090 Literally, you use the keyword return and then if what you are returning 808 00:51:15,090 --> 00:51:18,600 to the right of the keyword is an integer, 809 00:51:18,600 --> 00:51:21,660 then that is indeed consistent with what we have promised. 810 00:51:21,660 --> 00:51:26,410 You could not do something like this--hello, world--because that is a string. 811 00:51:26,410 --> 00:51:28,860 >> Obviously, it is not an integer. 812 00:51:28,860 --> 00:51:33,140 So in short, the burden is really on us, the programmer, to be specific 813 00:51:33,140 --> 00:51:37,770 as to what we're returning and to then actually go about returning it. 814 00:51:37,770 --> 00:51:43,440 The context here now is that your computer's memory is a gigabyte, 2 gigabytes-- 815 00:51:43,440 --> 00:51:45,920 whatever--maybe it's more, maybe it's less, 816 00:51:45,920 --> 00:51:49,050 but the computer views it as having different sections. 817 00:51:49,050 --> 00:51:51,200 Something goes down there, something else goes up there, 818 00:51:51,200 --> 00:51:54,290 different stuff goes in the middle, and today we just begin telling the story, 819 00:51:54,290 --> 00:51:56,340 but we'll come back to this over time. 820 00:51:56,340 --> 00:51:59,980 For now, the only piece of memory we really care about is the text segment 821 00:51:59,980 --> 00:52:03,360 because that just represents the 0s and 1s that Clang has outputted. 822 00:52:03,360 --> 00:52:06,050 So when you run a command at the keyboard like a.out 823 00:52:06,050 --> 00:52:09,110 or you double click an icon on Mac OS or Windows, 824 00:52:09,110 --> 00:52:11,880 your program is loaded from your hard drive into RAM 825 00:52:11,880 --> 00:52:16,330 and it's plopped at the top of your computer's RAM, so to speak. 826 00:52:16,330 --> 00:52:20,450 Meanwhile, as your program starts running and main gets called 827 00:52:20,450 --> 00:52:23,640 in the program you wrote or the program Microsoft or Apple wrote, 828 00:52:23,640 --> 00:52:27,860 any of its local variables end up down there at the bottom of your computer's memory. 829 00:52:27,860 --> 00:52:33,230 But if main calls another function that itself has variables or arguments, they end up above it. 830 00:52:33,230 --> 00:52:36,680 And if that function calls something, they end up above it, above it, above it. 831 00:52:36,680 --> 00:52:41,460 >> And only once a function is done executing does the stack of trays, so to speak, 832 00:52:41,460 --> 00:52:43,240 start to get lower and lower. 833 00:52:43,240 --> 00:52:48,250 And this is what then, in a nutshell, explains why when you call cube 834 00:52:48,250 --> 00:52:51,550 or you call increment, you're passing in a copy of the value. 835 00:52:51,550 --> 00:52:55,520 And what that means pictorially is that you're literally writing the number 1 836 00:52:55,520 --> 00:53:00,460 in another part of memory, changing that 1 to 2 in the case of increment 837 00:53:00,460 --> 00:53:04,820 or to an 8 in the case of cube and then throwing that memory away 838 00:53:04,820 --> 00:53:09,140 as soon as the increment or the cube function returns. Question. 839 00:53:09,140 --> 00:53:12,900 [student] Where are global variables stored? 840 00:53:12,900 --> 00:53:18,100 Global variables are stored in what's currently called the initialized data or uninitialized data, 841 00:53:18,100 --> 00:53:21,920 the difference being if you have a global variable and you assign it immediately a value 842 00:53:21,920 --> 00:53:24,640 with the equals sign, it ends up at the top there, 843 00:53:24,640 --> 00:53:29,200 and if you just say int x; with no value, it ends up slightly lower in RAM 844 00:53:29,200 --> 00:53:31,710 simply by convention. 845 00:53:31,710 --> 00:53:34,940 Other questions? All right. 846 00:53:34,940 --> 00:53:37,340 So this picture will come back as we get more powerful 847 00:53:37,340 --> 00:53:39,170 with what we can do with the computer, 848 00:53:39,170 --> 00:53:42,720 but for now, let's have a brief intro to cryptography, 849 00:53:42,720 --> 00:53:46,080 a specific type of cryptography that doesn't solve all of the world's problems 850 00:53:46,080 --> 00:53:47,720 but does solve some of them. 851 00:53:47,720 --> 00:53:51,700 In this case here, we have something called secret-key cryptography. 852 00:53:51,700 --> 00:53:56,410 Secret-key cryptography, as the name suggests, derives its security from a secret. 853 00:53:56,410 --> 00:54:00,690 >> For instance, if you were back in grade school and you were passing a little secret love letter 854 00:54:00,690 --> 00:54:04,850 to the boy or girl you were crushing on, if you wanted to pass that note through the audience, 855 00:54:04,850 --> 00:54:08,380 you probably wouldn't write such a note in English or whatever your native language is. 856 00:54:08,380 --> 00:54:13,340 Rather, you might encrypt it or you might just send them a text message these days. 857 00:54:13,340 --> 00:54:15,460 But you might actually pass them a note throughout the classroom. 858 00:54:15,460 --> 00:54:18,700 And to do this securely in such a way that your friends and the teacher 859 00:54:18,700 --> 00:54:22,650 don't know what you're writing, you might come up with a fairly simple algorithm, 860 00:54:22,650 --> 00:54:25,920 young though you might be, to just scramble the words. 861 00:54:25,920 --> 00:54:28,130 So instead of writing a you might write b, 862 00:54:28,130 --> 00:54:30,220 instead of b you might write c, 863 00:54:30,220 --> 00:54:32,140 instead of c you might write d, and so forth. 864 00:54:32,140 --> 00:54:34,360 Or you could come up with a more sophisticated translation 865 00:54:34,360 --> 00:54:36,720 of letters to different letters. 866 00:54:36,720 --> 00:54:39,740 But the catch is the boy or girl to whom you're sending this note 867 00:54:39,740 --> 00:54:45,020 needs to know something, which is what, obviously? >>[student] What you're sending. 868 00:54:45,020 --> 00:54:49,720 What your secret is, like what is that mapping between a's and b's and c's and d's. 869 00:54:49,720 --> 00:54:54,650 Is it just adding 1 to each of the letters to go from a to b, b to c? 870 00:54:54,650 --> 00:54:56,670 Is it more complex than that? 871 00:54:56,670 --> 00:55:01,540 >> So you and your crush need to have this secret information, 872 00:55:01,540 --> 00:55:03,190 but there's kind of a catch-22 here. 873 00:55:03,190 --> 00:55:06,830 If this is the very first time you're sending this love letter through the class, 874 00:55:06,830 --> 00:55:10,720 how is that boy or girl going to know what the secret even is? 875 00:55:10,720 --> 00:55:13,930 So secret-key crypto does not solve all of the world's problems, 876 00:55:13,930 --> 00:55:16,320 and there's actually a relationship here that we'll come back to towards semester's end. 877 00:55:16,320 --> 00:55:25,110 Similarly do most of us not know someone that works, for instance, at Amazon.com, 878 00:55:25,110 --> 00:55:28,190 and yet many of us have probably bought stuff at Amazon.com, 879 00:55:28,190 --> 00:55:31,990 and we've been taught to assume that these e-commerce transactions are secure. 880 00:55:31,990 --> 00:55:36,470 The URL probably says https, there's maybe a silly little padlock icon somewhere, 881 00:55:36,470 --> 00:55:39,930 there's some kind of cryptography securing your credit card information 882 00:55:39,930 --> 00:55:42,160 between you and Amazon.com. 883 00:55:42,160 --> 00:55:45,430 And yet if cryptography involves knowing some secret 884 00:55:45,430 --> 00:55:48,620 and yet I don't know anyone at Amazon and I've certainly not arranged any kind of secret 885 00:55:48,620 --> 00:55:52,710 with someone at Amazon, how is my computer or my browser doing this? 886 00:55:52,710 --> 00:55:55,720 It turns out there's other types of cryptography altogether that solve that problem. 887 00:55:55,720 --> 00:55:57,670 But for today, we'll focus on the simple one 888 00:55:57,670 --> 00:56:00,290 where you can arrange in advance to know some secret 889 00:56:00,290 --> 00:56:03,760 like +1 or some mapping between a's and b's. 890 00:56:03,760 --> 00:56:05,840 And the process of cryptography generally involves this. 891 00:56:05,840 --> 00:56:08,620 You have some plain text, depicted here at left, 892 00:56:08,620 --> 00:56:12,930 you run it through some kind of algorithm or procedure for encrypting it-- 893 00:56:12,930 --> 00:56:15,100 maybe that's just a becomes b, b becomes c-- 894 00:56:15,100 --> 00:56:17,490 and then you end up with ciphertext. 895 00:56:17,490 --> 00:56:20,380 Meanwhile, once your crush receives this secret note, 896 00:56:20,380 --> 00:56:24,200 he or she has to then decrypt it by generally reversing that algorithm 897 00:56:24,200 --> 00:56:27,190 so as to get back the plain text. 898 00:56:27,190 --> 00:56:28,960 There are physical incarnations of this. 899 00:56:28,960 --> 00:56:31,680 >> For instance, this is a little secret decoder ring, 900 00:56:31,680 --> 00:56:35,110 and this is a ring in the sense that there's two dials here. 901 00:56:35,110 --> 00:56:38,490 On the outside periphery of this thing, there's letters A through Z, 902 00:56:38,490 --> 00:56:40,340 although they're in random order, 903 00:56:40,340 --> 00:56:42,880 and on the inside, there's actually some numbers 904 00:56:42,880 --> 00:56:46,620 such that with this ring you can kind of turn the outside but not the inside 905 00:56:46,620 --> 00:56:49,140 in order to line up numbers with letters. 906 00:56:49,140 --> 00:56:53,020 From a movie called A Christmas Story, you'll see that little Ralphie 907 00:56:53,020 --> 00:56:58,000 was so eager to figure out what Little Orphan Annie's secret message was to him 908 00:56:58,000 --> 00:57:02,570 that had been communicated, I think, in the form of numeric messages on a cereal box 909 00:57:02,570 --> 00:57:07,220 and you had to accumulate all the little cards that came in the cereal box, 910 00:57:07,220 --> 00:57:09,770 you had to mail them in, you had to get back the secret decoder ring 911 00:57:09,770 --> 00:57:13,910 so that you can finally figure out what the mapping is between letters and numbers 912 00:57:13,910 --> 00:57:15,550 or letters and letters. 913 00:57:15,550 --> 00:57:19,520 How in a computer can we go about implementing or representing things like this? 914 00:57:19,520 --> 00:57:22,560 We need a way of expressing ourselves a little more flexibly 915 00:57:22,560 --> 00:57:25,080 than our variables thus far have allowed. 916 00:57:25,080 --> 00:57:29,000 We've had ints, we've had chars, we've had floats and doubles and a few others, 917 00:57:29,000 --> 00:57:34,200 but those are individual pieces of memory that don't really allow us to express things 918 00:57:34,200 --> 00:57:36,440 like words and sentences and phrases. 919 00:57:36,440 --> 00:57:38,630 Indeed, we've called such things strings, 920 00:57:38,630 --> 00:57:42,660 but we promise that this is really just a simplification in the CS50 library 921 00:57:42,660 --> 00:57:45,540 that we're intending to peel back. 922 00:57:45,540 --> 00:57:47,500 And so let's start to do that here. 923 00:57:47,500 --> 00:57:49,840 Let me go ahead and open up a file-- 924 00:57:49,840 --> 00:57:54,100 all of these files are available, as usual, online--called array.c 925 00:57:54,100 --> 00:57:58,960 to solve a problem unrelated to strings but that paints a picture here 926 00:57:58,960 --> 00:58:01,520 of how we might use something called an array. 927 00:58:01,520 --> 00:58:04,050 >> An array is a data type. 928 00:58:04,050 --> 00:58:10,730 It's a type of variable of sorts that has multiple smaller data types inside of it 929 00:58:10,730 --> 00:58:12,680 back to back to back to back. 930 00:58:12,680 --> 00:58:16,980 So for instance, if we wanted to write a little program that gives you your quiz average 931 00:58:16,980 --> 00:58:19,780 for a course like 50 that has 2 quizzes, 932 00:58:19,780 --> 00:58:23,450 you could very easily write this program based even on some of last week's material 933 00:58:23,450 --> 00:58:28,830 by using GetInt and a couple of variables: int quiz1, int quiz2. 934 00:58:28,830 --> 00:58:30,550 And it's pretty straightforward. 935 00:58:30,550 --> 00:58:33,500 It's maybe 10, 20 lines of code max to implement a program 936 00:58:33,500 --> 00:58:38,940 that asks the user for 2 quiz scores and then computes their average 937 00:58:38,940 --> 00:58:42,020 by adding them together, dividing by 2, and then printing the results. 938 00:58:42,020 --> 00:58:46,400 We could probably do that pretty readily now after some number of minutes. 939 00:58:46,400 --> 00:58:49,450 But the problem is that suppose that 50 had 3 quizzes or 4. 940 00:58:49,450 --> 00:58:52,830 Suppose that you wanted to use the same program for a class that had weekly quizzes. 941 00:58:52,830 --> 00:58:55,100 Think about a class that has weekly quizzes. 942 00:58:55,100 --> 00:58:58,840 If there's 16 or so weeks in a semester, now you have 16 variables: 943 00:58:58,840 --> 00:59:03,030 int quiz1, int quiz2, int quiz3, int quiz4. 944 00:59:03,030 --> 00:59:06,870 As soon as you start seeing this redundancy, this copying and pasting of code, 945 00:59:06,870 --> 00:59:09,810 it should start to make you wish there were a better way. 946 00:59:09,810 --> 00:59:13,610 And thankfully, because of arrays there is. So let's do this. 947 00:59:13,610 --> 00:59:16,700 First, let me introduce a very simple thing that we've not used thus far, 948 00:59:16,700 --> 00:59:18,820 but you'll see it occasionally in code. 949 00:59:18,820 --> 00:59:21,270 >> This is what's generally called a constant. 950 00:59:21,270 --> 00:59:24,410 So it's a constant in the sense that this value never changes. 951 00:59:24,410 --> 00:59:26,450 The human convention when creating a constant 952 00:59:26,450 --> 00:59:30,420 is to use all capital letters just so that it really stands out in your code, 953 00:59:30,420 --> 00:59:34,270 and the special keyword that you use in C is #define. 954 00:59:34,270 --> 00:59:39,970 So we say #define, then a space, then the word that you want to use for the constant's name 955 00:59:39,970 --> 00:59:41,730 and then the value of the constant. 956 00:59:41,730 --> 00:59:44,710 Notice this is different from assigning something to a variable. 957 00:59:44,710 --> 00:59:46,430 There's no equals sign, there's no semicolon. 958 00:59:46,430 --> 00:59:49,140 This is what's generally known as a preprocessor directive, 959 00:59:49,140 --> 00:59:50,840 but more on that another time. 960 00:59:50,840 --> 00:59:56,350 For now, this creates an unchanging value called QUIZZES 961 00:59:56,350 --> 00:59:58,290 whose actual numeric value is 2. 962 00:59:58,290 --> 01:00:02,180 So anywhere you see QUIZZES, QUIZZES, QUIZZES throughout this file, 963 01:00:02,180 --> 01:00:04,230 that's just the number 2. 964 01:00:04,230 --> 01:00:06,550 If I look at main now, let's see how this works. 965 01:00:06,550 --> 01:00:09,770 First it looks a little cryptic, but it's all stuff from week 1. 966 01:00:09,770 --> 01:00:12,210 Ask the user for grades. How do we do this? 967 01:00:12,210 --> 01:00:17,350 In line 22--this is really the juicy part--I declare a float 968 01:00:17,350 --> 01:00:23,240 but not just a single float. I'm declaring, rather, an array of floating-point values. 969 01:00:23,240 --> 01:00:27,700 That variable is going to be called grades, as implied here, 970 01:00:27,700 --> 01:00:31,420 but the only piece of new syntax then are these square brackets. 971 01:00:31,420 --> 01:00:37,280 The fact that I've said float grades and then open bracket and then a number-- 972 01:00:37,280 --> 01:00:40,980 notice if this is a constant this is just like we did this-- 973 01:00:40,980 --> 01:00:46,840 this means, "Hey computer, give me 2 floats and let's collectively call them grades." 974 01:00:46,840 --> 01:00:51,780 >> This is in contrast to a much more tedious process like this: float grade1; 975 01:00:51,780 --> 01:00:54,580 float grade2; and so forth. 976 01:00:54,580 --> 01:00:58,310 So an array allows us to implement this idea but much less messily, 977 01:00:58,310 --> 01:01:04,560 in such a way that we can write 1 line of code instead of, say, 16 for a 16-week semester. 978 01:01:04,560 --> 01:01:09,060 I didn't want to hard-code 2 because if you think about this now logically, 979 01:01:09,060 --> 01:01:12,560 suppose next year CS50 changes to 3 quizzes instead 980 01:01:12,560 --> 01:01:15,010 and I had the number 2 here, I had the number 2 here, 981 01:01:15,010 --> 01:01:17,210 I had the number 2 here, the number 2 here. 982 01:01:17,210 --> 01:01:19,890 It becomes very tedious and very easy to screw up 983 01:01:19,890 --> 01:01:26,550 and to accidentally change 1 value to 3 and miss some other value of 2. 984 01:01:26,550 --> 01:01:30,660 So I'm going to instead abstract this away and use this constant that, 985 01:01:30,660 --> 01:01:32,520 as its name suggests, never changes. 986 01:01:32,520 --> 01:01:35,870 And now no matter whether we have different quizzes this year or next, 987 01:01:35,870 --> 01:01:39,380 I just have to change it in one place up here at top. 988 01:01:39,380 --> 01:01:41,230 So that's all a constant is. 989 01:01:41,230 --> 01:01:47,100 Meanwhile, the new conceptual feature is that of an array. 990 01:01:47,100 --> 01:01:55,030 So the square brackets give me this many floats and lets me collectively call them grades here. 991 01:01:55,030 --> 01:01:56,720 So now let's see what I'm going to do. 992 01:01:56,720 --> 01:01:59,220 Here in line 24 is the beginning of a for loop. 993 01:01:59,220 --> 01:02:03,380 >> This is really nothing fancy. It's just using QUIZZES instead of a hard-coded number. 994 01:02:03,380 --> 01:02:06,740 But there's nothing intellectually different there from last week. 995 01:02:06,740 --> 01:02:11,650 This is just printf, so printf("Quiz # %d of %d:") 996 01:02:11,650 --> 01:02:16,670 because I just want to print out give me quiz number 1 of 2 and then 2 of 2. 997 01:02:16,670 --> 01:02:18,480 So this is a purely aesthetic thing. 998 01:02:18,480 --> 01:02:21,000 But the interesting part now is in line 27. 999 01:02:21,000 --> 01:02:27,840 In order to fill in one of the two placeholders with a floating-point value, 1000 01:02:27,840 --> 01:02:29,640 you again use square brackets. 1001 01:02:29,640 --> 01:02:35,170 In this case, I'm using i because this for loop has started with i equaling what value, apparently? 1002 01:02:35,170 --> 01:02:36,670 [student] 0. >>[Malan] 0. 1003 01:02:36,670 --> 01:02:40,990 So on the first iteration of this loop, it is as though I wrote this in code, 1004 01:02:40,990 --> 01:02:46,310 but on the second iteration of this loop, it is as though I wrote this in my code. 1005 01:02:46,310 --> 01:02:49,970 But the fact that I'm using a variable is perfect because, as the name suggests, 1006 01:02:49,970 --> 01:02:52,600 it's varying its value on every iteration, 1007 01:02:52,600 --> 01:02:55,900 so I'm filling this array one spot at a time. 1008 01:02:55,900 --> 01:02:57,380 What does this array look like? 1009 01:02:57,380 --> 01:03:01,570 The reason I drew the super simple rectangle on the screen here before was for this reason. 1010 01:03:01,570 --> 01:03:05,590 An array is just a chunk of memory followed by another chunk of memory 1011 01:03:05,590 --> 01:03:08,570 followed by another chunk of memory and so forth. 1012 01:03:08,570 --> 01:03:13,120 So if my array is of size 2 in this case here, all I would be doing 1013 01:03:13,120 --> 01:03:20,200 by typing in my quiz scores like here--I got 100 on this one and then I got a 99 on this one-- 1014 01:03:20,200 --> 01:03:24,970 then this memory might not even be used because I've only asked the computer 1015 01:03:24,970 --> 01:03:26,840 for an array of size 2. 1016 01:03:26,840 --> 01:03:28,600 Those squares are still there, right? 1017 01:03:28,600 --> 01:03:32,670 You still have 2 gigabytes of RAM even if you're only asking for 2 floats. 1018 01:03:32,670 --> 01:03:36,840 So the idea behind arrays is that the computer just takes a chunk of memory 1019 01:03:36,840 --> 01:03:41,340 and then apportions smaller pieces back to back to back to back. 1020 01:03:41,340 --> 01:03:43,310 And so that's all an array is. 1021 01:03:43,310 --> 01:03:47,350 >> It's a contiguous chunk of memory inside of which you can put things. 1022 01:03:47,350 --> 01:03:50,700 This happens to then do just some boring arithmetic. 1023 01:03:50,700 --> 01:03:54,640 If I scroll down here, this is where I then iterate over the array. 1024 01:03:54,640 --> 01:03:58,020 I come up with the summation of all of the values in the array, 1025 01:03:58,020 --> 01:04:02,470 and then I use the round function here to actually do the sum divided by QUIZZES. 1026 01:04:02,470 --> 01:04:06,320 But let me wave my hand at that as sort of enough arithmetic for now. 1027 01:04:06,320 --> 01:04:08,370 But all that's doing for me ultimately is computing an average. 1028 01:04:08,370 --> 01:04:13,580 So first quiz plus second quiz divided by 2 and then printing it out as an int. 1029 01:04:13,580 --> 01:04:17,280 But let's now transition to a different example called string1, 1030 01:04:17,280 --> 01:04:20,700 which paints a similar picture but using strings. 1031 01:04:20,700 --> 01:04:23,940 Let me go ahead and simplify this for just a moment. 1032 01:04:23,940 --> 01:04:27,090 Forgive the indentation for now. 1033 01:04:27,090 --> 01:04:30,870 Notice in line 19 of this example, I get a string from the user. 1034 01:04:30,870 --> 01:04:34,640 But notice what I'm next doing in lines 22 onward. 1035 01:04:34,640 --> 01:04:41,250 I'm actually iterating from i up to--and this is a new trick--strlen, string length. 1036 01:04:41,250 --> 01:04:44,880 This is a function that comes with C that if you pass it a string, 1037 01:04:44,880 --> 01:04:47,730 it tells you how many characters are in that string. That's all. 1038 01:04:47,730 --> 01:04:51,550 And the fact that it's strlen instead of string length is just because it's more succinct. 1039 01:04:51,550 --> 01:04:55,100 Thirty years ago, people liked to write things as succinctly as possible, 1040 01:04:55,100 --> 01:04:57,630 so we've kept that convention here. 1041 01:04:57,630 --> 01:05:00,660 i++ just means increment i in each iteration. 1042 01:05:00,660 --> 01:05:02,990 And now notice this, which is really interesting. 1043 01:05:02,990 --> 01:05:09,180 In line 24, I say, "Computer, give me a character, 8 bits, and call it c." 1044 01:05:09,180 --> 01:05:12,630 But what is this on the right-hand side saying? 1045 01:05:13,490 --> 01:05:16,530 In English, what does that represent? 1046 01:05:16,530 --> 01:05:18,730 [student] The first character in the array. 1047 01:05:18,730 --> 01:05:20,790 Exactly. Give me the first character in the array. 1048 01:05:20,790 --> 01:05:24,090 Or, more generally, give me the ith character in the array. 1049 01:05:24,090 --> 01:05:26,100 And realize it's important now that as computer scientists, 1050 01:05:26,100 --> 01:05:27,890 we're actually counting from 0. 1051 01:05:27,890 --> 01:05:29,720 >> You don't have the discretion now to start doing this. 1052 01:05:29,720 --> 01:05:34,160 Now you have to behave in accordance with the computer's expectations and count from 0 1053 01:05:34,160 --> 01:05:38,180 because [0] is going to be the first character in a string, 1054 01:05:38,180 --> 01:05:42,150 [1] is going to be the second, [2] is going to be the third, and so forth. 1055 01:05:42,150 --> 01:05:49,720 So this program, if I compile it, this is again string1, so make string1, 1056 01:05:49,720 --> 01:05:54,670 and now I've run string1 in my terminal window. 1057 01:05:54,670 --> 01:05:58,330 It's waiting for input, so I'm going to type in David, Enter, 1058 01:05:58,330 --> 01:06:02,540 and now it prints D-a-v-i-d all on different lines because notice what I'm doing. 1059 01:06:02,540 --> 01:06:05,820 I'm printing one character at a time. 1060 01:06:05,820 --> 01:06:10,100 We won't go into detail today on this, but I deleted a moment ago this check here. 1061 01:06:10,100 --> 01:06:15,480 It turns out that if the user is misbehaving, adversarial, or just confused, 1062 01:06:15,480 --> 01:06:20,210 you can actually fail to give a string of some length. 1063 01:06:20,210 --> 01:06:22,860 If you hit the wrong key on the keyboard, you might give no string at all, 1064 01:06:22,860 --> 01:06:26,950 or if you're malicious, you might try to paste in a gigabyte's worth of an essay 1065 01:06:26,950 --> 01:06:29,290 to fill this string, and if the computer runs out of memory, 1066 01:06:29,290 --> 01:06:32,710 it turns out that we're going to get back this special value called NULL. 1067 01:06:32,710 --> 01:06:35,580 So for now, just know that there's this special value called NULL 1068 01:06:35,580 --> 01:06:39,580 that will allow us to check when we're out of memory, among other things. 1069 01:06:39,580 --> 01:06:45,630 But if I open up now string2, notice one difference here. 1070 01:06:45,630 --> 01:06:48,210 Notice one difference here with string2. 1071 01:06:48,210 --> 01:06:51,340 With string2, this for loop is a little different. 1072 01:06:51,340 --> 01:06:55,010 >> Let me delete the NULLs so that we can talk about those another time. 1073 01:06:55,010 --> 01:06:57,800 What's different about the for loop this time? 1074 01:06:59,620 --> 01:07:01,670 I can go back to the previous example. 1075 01:07:01,670 --> 01:07:08,580 So that's version 2, this is version 1. 1, 2. 1076 01:07:08,580 --> 01:07:11,980 1, 2. 1077 01:07:13,520 --> 01:07:16,660 The strlen call is where? 1078 01:07:16,660 --> 01:07:18,860 It's in the first part of the for loop. 1079 01:07:18,860 --> 01:07:21,830 Any thoughts as to why I'm doing this? Yeah. 1080 01:07:21,830 --> 01:07:24,560 [student] So you don't call the function every single time. 1081 01:07:24,560 --> 01:07:26,440 [Malan] So we don't call the function every single time. Exactly. 1082 01:07:26,440 --> 01:07:28,300 Recall from for loops that they're super simple 1083 01:07:28,300 --> 01:07:31,770 once you sort of understand that this is the initialization, the condition, and the update. 1084 01:07:31,770 --> 01:07:34,750 The problem is that the condition happens on every iteration of the loop. 1085 01:07:34,750 --> 01:07:40,010 And so in this example here, what is bad about the fact that this is my condition? 1086 01:07:40,010 --> 01:07:41,830 [student] You're calling strlen. 1087 01:07:41,830 --> 01:07:44,340 [Malan] You're calling strlen again and again and again. 1088 01:07:44,340 --> 01:07:47,410 But once I've typed in D-a-v-i-d, the length of that string is 5, 1089 01:07:47,410 --> 01:07:49,650 and it's not going to change on every iteration of the loop 1090 01:07:49,650 --> 01:07:51,670 because the string is still D-a-v-i-d. 1091 01:07:51,670 --> 01:07:55,320 So this is a hint at what's going to become an increasingly important idea 1092 01:07:55,320 --> 01:08:00,410 known as a design decision where just don't make the computer do unnecessary work. 1093 01:08:00,410 --> 01:08:03,920 >> Just as a sneak preview of pset2, pset2 in the standard edition 1094 01:08:03,920 --> 01:08:07,030 is going to challenge you to actually implement some number of ciphers, 1095 01:08:07,030 --> 01:08:10,410 some number of encryption algorithms, so that you can both encrypt 1096 01:08:10,410 --> 01:08:13,840 and decrypt secret messages much like the one Ralphie there decoded. 1097 01:08:13,840 --> 01:08:16,810 In the hacker edition of pset2, we're going to go a little further. 1098 01:08:16,810 --> 01:08:19,649 We're going to hand you a file from an actual computer system 1099 01:08:19,649 --> 01:08:23,479 that contains a whole bunch of usernames and actual encrypted passwords, 1100 01:08:23,479 --> 01:08:26,939 and the challenge for the hacker edition is going to be to crack those passwords 1101 01:08:26,939 --> 01:08:33,200 and figure out what cryptography or what secret was used to actually generate those passwords. 1102 01:08:33,200 --> 01:08:36,109 And we're going to do this by using a new feature here of C 1103 01:08:36,109 --> 01:08:40,630 that I'll give you just a demo of known as command-line arguments. 1104 01:08:40,630 --> 01:08:44,229 It turns out, as some of you may have seen in section or in textbooks, 1105 01:08:44,229 --> 01:08:48,260 main does not always have to be void in parentheses. 1106 01:08:48,260 --> 01:08:52,430 It turns out that main can also be written like this, with two arguments, 1107 01:08:52,430 --> 01:08:56,870 argc and argv, where argc is the number of words 1108 01:08:56,870 --> 01:09:00,020 that you type after the program's name on your command line 1109 01:09:00,020 --> 01:09:03,420 and argv is the actual words. 1110 01:09:03,420 --> 01:09:07,540 And as the square brackets there suggest, argv is apparently an array. 1111 01:09:07,540 --> 01:09:12,210 It's going to be a string after a string after a string in memory. 1112 01:09:12,210 --> 01:09:16,010 >> So what we're going to be able to do starting with pset 2 is something like this. 1113 01:09:16,010 --> 01:09:21,350 If I make argv1, which is an example we'll come back to on Monday, and run it, 1114 01:09:21,350 --> 01:09:23,370 notice that it doesn't seem to do anything yet. 1115 01:09:23,370 --> 01:09:25,490 It just prints out its own name. 1116 01:09:25,490 --> 01:09:31,479 But if I say goodbye class, notice that this program apparently iterates 1117 01:09:31,479 --> 01:09:35,479 over each of the words that were typed at the prompt. 1118 01:09:35,479 --> 01:09:41,630 And the means by which we will gain access to words that the user has typed at the prompt 1119 01:09:41,630 --> 01:09:49,160 is by changing main starting this weekend from int main(void) to int main(argc, argv) 1120 01:09:49,160 --> 01:09:52,050 and thus will be born command-line arguments. 1121 01:09:52,050 --> 01:09:57,100 And once you get really sophisticated at this, you'll be able to write really trippy programs 1122 01:09:57,100 --> 01:09:59,610 such as this one here, which goes above and beyond 1123 01:09:59,610 --> 01:10:03,940 some of the functionality we've done thus far but all quite powerful. 1124 01:10:03,940 --> 01:10:08,950 >> So we'll leave this with this on the screen, and we will see you on Monday. 1125 01:10:17,570 --> 01:10:20,000 >> [CS50.TV]