1 00:00:00,506 --> 00:00:09,086 [ Silence ] 2 00:00:09,586 --> 00:00:10,456 >> Alright, welcome back! 3 00:00:10,636 --> 00:00:14,206 This is the end of week 2 in CS50 4 00:00:14,246 --> 00:00:17,846 and this is an excessive amount of what's called ASCII art, 5 00:00:18,116 --> 00:00:19,886 people who have spent way too much 6 00:00:19,886 --> 00:00:22,646 of their free time actually sketching out most of the scenes 7 00:00:22,646 --> 00:00:29,046 from Star Wars entirely in their own ASCII character code. 8 00:00:29,046 --> 00:00:30,806 So this is a bit of animation that's a bit 9 00:00:30,806 --> 00:00:33,446 of an internet mean these days and goes around but we've linked 10 00:00:33,446 --> 00:00:34,616 to on the course's website if you'd 11 00:00:34,616 --> 00:00:36,476 like to watch the whole film later. 12 00:00:36,746 --> 00:00:39,516 We thought we'd begin though not just with ASCII art 13 00:00:39,516 --> 00:00:41,416 but with something a little sexier than that 14 00:00:41,876 --> 00:00:43,656 that paints the picture for this week's 15 00:00:43,656 --> 00:00:46,396 and next week's problem domain that of cryptography 16 00:00:46,396 --> 00:00:47,626 and security more generally. 17 00:00:47,626 --> 00:00:50,526 Some of you might have seen this actual film before, 18 00:00:50,686 --> 00:00:54,026 one of my favorite excerpts of which is this one-- 19 00:00:54,896 --> 00:00:58,296 is this one-- that one too, is this one here. 20 00:00:58,506 --> 00:01:00,166 >> Helmet, you fiend! 21 00:01:00,166 --> 00:01:01,066 What's going on? 22 00:01:01,066 --> 00:01:02,416 What are you doing to my daughter? 23 00:01:02,416 --> 00:01:05,136 >> Permit me to introduce the brilliant, 24 00:01:05,136 --> 00:01:07,966 young plastic surgeon, Dr. Phillip Schlotkin, 25 00:01:08,776 --> 00:01:10,496 the greatest nose job man 26 00:01:10,496 --> 00:01:13,136 in the entire universe and Beverly Hills. 27 00:01:13,746 --> 00:01:14,176 >> Your highness? 28 00:01:14,906 --> 00:01:15,566 >> Nose job? 29 00:01:15,566 --> 00:01:17,786 I don't understand, she's already had a nose job. 30 00:01:17,786 --> 00:01:19,546 It was a sweet 16 present. 31 00:01:19,546 --> 00:01:21,686 >> No, it's not what you think. 32 00:01:21,686 --> 00:01:22,776 It's much, much worse. 33 00:01:23,276 --> 00:01:26,536 If you do not give me the combination to the air shield, 34 00:01:26,926 --> 00:01:36,766 Dr. Schlotkin will give your daughter back her old nose. 35 00:01:36,766 --> 00:01:37,416 >> No! Where did you get that? 36 00:01:38,626 --> 00:01:40,166 >> Alright, I'll tell, I'll tell. 37 00:01:40,226 --> 00:01:42,466 >> No, Daddy, no, you mustn't. 38 00:01:43,256 --> 00:01:44,076 >> You're right, my dear. 39 00:01:44,836 --> 00:01:46,066 I'll miss your new nose, 40 00:01:46,526 --> 00:01:51,276 but I will not tell 'em the combination no matter what. 41 00:01:52,426 --> 00:02:00,376 >> Very well, Dr. Schlotkin, do your worst. 42 00:02:00,596 --> 00:02:02,436 >> My pleasure. 43 00:02:02,676 --> 00:02:03,086 >> No! Wait! 44 00:02:03,086 --> 00:02:03,366 Wait! I'll tell. 45 00:02:03,366 --> 00:02:03,746 I'll tell. 46 00:02:03,746 --> 00:02:05,726 >> I knew it would work. 47 00:02:06,156 --> 00:02:08,546 Alright, give it to me. 48 00:02:10,116 --> 00:02:13,876 >> The combination is one-- 49 00:02:14,096 --> 00:02:15,096 >> One. 50 00:02:15,096 --> 00:02:15,616 >> One. 51 00:02:16,306 --> 00:02:16,556 >> Two. 52 00:02:17,076 --> 00:02:17,536 >> Two. 53 00:02:17,536 --> 00:02:18,196 >> Two. 54 00:02:18,476 --> 00:02:19,096 >> Three. 55 00:02:19,096 --> 00:02:19,486 >> Three. 56 00:02:19,606 --> 00:02:20,026 >> Three. 57 00:02:20,516 --> 00:02:20,946 >> Four. 58 00:02:21,316 --> 00:02:21,936 >> Four. 59 00:02:22,336 --> 00:02:22,726 >> Four. 60 00:02:24,106 --> 00:02:24,506 >> Five. 61 00:02:24,686 --> 00:02:24,986 >> Five. 62 00:02:25,326 --> 00:02:26,716 >> Five. 63 00:02:26,716 --> 00:02:31,206 >> So the combination is 1, 2, 3, 4, 5? 64 00:02:31,816 --> 00:02:34,116 It's the stupidest combination I've ever heard in my life. 65 00:02:34,116 --> 00:02:37,046 That's the kind of thing an idiot would have on his luggage! 66 00:02:37,136 --> 00:02:38,636 >> Thank you, your highness. 67 00:02:40,126 --> 00:02:40,536 >> What did you do? 68 00:02:41,216 --> 00:02:42,246 >> I turned off the wall. 69 00:02:42,436 --> 00:02:43,646 >> Clayton, you turned off the whole movie. 70 00:02:43,696 --> 00:02:45,866 >> I must have pressed the wrong button. 71 00:02:45,866 --> 00:02:47,856 >> Well, put it back on. 72 00:02:48,146 --> 00:02:48,366 >> Yes, sir! 73 00:02:48,366 --> 00:02:49,736 >> Put the movie back on. 74 00:02:49,976 --> 00:02:50,126 >> Yes, sir! 75 00:02:50,126 --> 00:02:51,596 >> Let's go, Arnold. 76 00:02:51,726 --> 00:02:52,236 Come on, Gretchen. 77 00:02:52,326 --> 00:02:56,006 Of course, you know, I'll still have to bill you for this. 78 00:02:56,006 --> 00:02:56,073 [ Noise ] 79 00:02:56,073 --> 00:02:57,086 >> Well, it worked, where's the key? 80 00:02:57,176 --> 00:02:58,516 >> It works where we have the combination. 81 00:02:58,846 --> 00:03:01,206 >> Great! Now, we can take every last breath 82 00:03:01,206 --> 00:03:03,056 of fresh air from planet Druidia. 83 00:03:03,716 --> 00:03:04,476 What's the combination? 84 00:03:04,656 --> 00:03:06,596 >> 1, 2, 3, 4, 5. 85 00:03:07,036 --> 00:03:08,596 >> 1, 2, 3, 4, 5? 86 00:03:08,716 --> 00:03:09,156 >> Yes. 87 00:03:09,156 --> 00:03:09,846 >> That's amazing! 88 00:03:09,846 --> 00:03:13,256 I've got the same combination on my luggage. 89 00:03:13,256 --> 00:03:13,323 [ Laughter ] 90 00:03:13,323 --> 00:03:15,856 >> Prepare Spaceball 1 for immediate departure. 91 00:03:15,926 --> 00:03:16,926 >> Yes, sir! 92 00:03:16,926 --> 00:03:19,806 >> And change the combination on my luggage. 93 00:03:19,806 --> 00:03:20,106 [ Music ] 94 00:03:20,106 --> 00:03:20,406 [ Laughter ] 95 00:03:20,406 --> 00:03:24,336 >> So if you like more of that, 96 00:03:24,336 --> 00:03:26,776 that is a classic called Spaceballs. 97 00:03:26,776 --> 00:03:29,506 We have another little classic for you in a little bit. 98 00:03:29,896 --> 00:03:33,016 So you might laugh but odds are statistically, 99 00:03:33,016 --> 00:03:35,316 some of you in this room has a password that's not all 100 00:03:35,316 --> 00:03:37,566 that dissimilar from 1, 2, 3, 4, 101 00:03:37,566 --> 00:03:39,846 5 and some of you might even have post-it notes back 102 00:03:39,846 --> 00:03:40,256 on your desk. 103 00:03:40,796 --> 00:03:45,396 So 1, 2, 3, 4, 5 is clearly insecure as a password. 104 00:03:45,396 --> 00:03:47,976 One, 'cause its just so easy to guess even you if you're trying 105 00:03:47,976 --> 00:03:50,656 to break into someone's account, you might try simple things 106 00:03:50,656 --> 00:03:52,986 like that or the ever popular password 107 00:03:53,066 --> 00:03:55,006 "Password" or something similar. 108 00:03:55,276 --> 00:03:57,536 But in reality, what systems typically do even 109 00:03:57,536 --> 00:03:59,656 if a password is weak like that, 110 00:03:59,896 --> 00:04:03,176 they're actually store computer systems, things like this. 111 00:04:03,496 --> 00:04:06,416 So if you've ever forgotten a password on a website or one 112 00:04:06,416 --> 00:04:09,316 of Harvard's passwords, and you're told by some IT person 113 00:04:09,316 --> 00:04:11,556 that they cannot in fact tell you your password 114 00:04:11,786 --> 00:04:12,816 but you can change it, 115 00:04:13,016 --> 00:04:15,096 that's generally algorithmically correct. 116 00:04:15,096 --> 00:04:18,246 For security purposes, passwords are typically not stored 117 00:04:18,246 --> 00:04:21,856 on computers in so-called Cleartext but rather 118 00:04:21,856 --> 00:04:25,016 in ciphertext in some kind of encrypted fashion 119 00:04:25,246 --> 00:04:27,316 that looks mostly like random nonsense. 120 00:04:27,436 --> 00:04:29,926 But the reality is that that is the result 121 00:04:29,926 --> 00:04:31,766 of applying some mathematical formulas 122 00:04:31,966 --> 00:04:35,306 to the original password 1, 2, 3, 4, 5, their output 123 00:04:35,306 --> 00:04:37,076 of which is something crazier-looking. 124 00:04:37,076 --> 00:04:39,826 The idea being, if you see the crazy-looking thing, 125 00:04:40,036 --> 00:04:44,006 it's not all that easy if it all possible to figure 126 00:04:44,006 --> 00:04:46,426 out what the original password actually was. 127 00:04:46,846 --> 00:04:49,766 So ensure when you create an account on some new websites, 128 00:04:49,766 --> 00:04:52,656 Facebook, Google, any of these sites, they're storing 129 00:04:52,656 --> 00:04:55,896 in a database your username and that's generally in the clear 130 00:04:55,896 --> 00:04:58,906 or your email address but then your password is encrypted 131 00:04:59,326 --> 00:05:00,606 but this seems to beg a-- 132 00:05:00,606 --> 00:05:05,206 beg a question the next time you log in, time number 2 or 3, 133 00:05:05,476 --> 00:05:08,806 how in the world does Google or Facebook or Harvard know 134 00:05:08,806 --> 00:05:11,506 that you've typed in the right username and password 135 00:05:11,806 --> 00:05:14,106 if they too no longer know what your password is. 136 00:05:15,556 --> 00:05:17,676 It seems like once you've encrypted the password, 137 00:05:17,676 --> 00:05:20,086 you're kind of screwed 'cause you no longer remember what the 138 00:05:20,086 --> 00:05:22,726 new one is if this is all you're storing, so what could you do? 139 00:05:22,726 --> 00:05:23,486 What are some options? 140 00:05:25,026 --> 00:05:26,336 Okay, so you could decrypt it, 141 00:05:26,396 --> 00:05:28,376 so decrypting is just the opposite of encrypting. 142 00:05:28,376 --> 00:05:30,096 The problem with decrypting it is 143 00:05:30,096 --> 00:05:31,786 that if you're gonna decrypt something like this 144 00:05:31,876 --> 00:05:35,216 on an automated fashion, well that means that the web server 145 00:05:35,216 --> 00:05:38,456 or Harvard server itself needs to know how to decrypt it. 146 00:05:38,456 --> 00:05:41,086 And generally encryption works by having some secret, 147 00:05:41,126 --> 00:05:43,086 some secret password or special key 148 00:05:43,336 --> 00:05:45,306 that only the website's owner knows. 149 00:05:45,526 --> 00:05:47,956 So if you wanted the website like Google or Facebook 150 00:05:47,956 --> 00:05:51,266 to automatically decrypt this and then compare your password. 151 00:05:51,446 --> 00:05:54,596 Well, the implication is that-- then the website's password 152 00:05:54,596 --> 00:05:57,156 or key with which to do that decryption has 153 00:05:57,156 --> 00:05:58,876 to be stored somewhere in the server. 154 00:05:59,276 --> 00:06:02,056 So this then implies that if some bad guy breaks 155 00:06:02,056 --> 00:06:03,986 into the server, not only can he 156 00:06:03,986 --> 00:06:06,206 or she steal the crazy-looking stuff like this, 157 00:06:06,206 --> 00:06:07,366 which is mostly useless. 158 00:06:07,646 --> 00:06:09,666 But if they have access now to the server, 159 00:06:09,836 --> 00:06:12,696 they can steal also whatever trick you're using 160 00:06:12,696 --> 00:06:14,946 to decrypt these things 'cause that's gotta be implemented 161 00:06:14,946 --> 00:06:16,166 in Source Code, right? 162 00:06:16,166 --> 00:06:17,626 Whether it's C or some other language, 163 00:06:17,896 --> 00:06:19,416 so it's really not helping you 164 00:06:19,416 --> 00:06:26,806 if you've actually encrypted this in that fashion. 165 00:06:26,806 --> 00:06:26,906 Yeah? 166 00:06:26,906 --> 00:06:26,973 [ Inaudible Question ] 167 00:06:26,973 --> 00:06:29,386 >> Yeah, that's-- so that's a nice solution here. 168 00:06:29,386 --> 00:06:32,556 So if the server is only remembering the ciphertext 169 00:06:32,886 --> 00:06:35,366 and actually let me-- let me tweak my wording now, 170 00:06:35,616 --> 00:06:37,376 though its very similar [inaudible] to encryption, 171 00:06:37,376 --> 00:06:41,036 a better word for this would be a Hash Value, H-A-S-H, 172 00:06:41,246 --> 00:06:43,616 and a hash value is generally the result 173 00:06:43,616 --> 00:06:44,776 of encrypting something 174 00:06:45,056 --> 00:06:47,936 and essentially throwing away the key though the mathematics 175 00:06:47,936 --> 00:06:49,096 are a little different than that. 176 00:06:49,096 --> 00:06:51,496 In other words, when you take a hash of some input, 177 00:06:51,726 --> 00:06:54,636 the result is some hash value and statistically, 178 00:06:54,636 --> 00:06:56,676 it should be impossible to reverse that, 179 00:06:56,676 --> 00:06:58,816 so its one way encryption if you will. 180 00:06:59,116 --> 00:07:02,206 So that's okay though because the Facebook 181 00:07:02,206 --> 00:07:05,616 and Google are storing this as the-- the king's password, 182 00:07:05,756 --> 00:07:07,906 well that's fine because the next time the king logs 183 00:07:07,906 --> 00:07:10,956 in to this website, he types in his username, he types in 1, 2, 184 00:07:10,956 --> 00:07:13,836 3, 4, 5, hits Enter, but then all the website has 185 00:07:13,836 --> 00:07:17,996 to do is take another hash of that input that is run 1, 2, 3, 186 00:07:17,996 --> 00:07:20,876 4, 5 to the same algorithm, the same mathematical formulas 187 00:07:21,026 --> 00:07:24,406 and if the output of that process matches the output 188 00:07:24,406 --> 00:07:27,666 of the original process, well, then you can assume that okay, 189 00:07:27,666 --> 00:07:29,876 he must have typed in the exact same thing. 190 00:07:30,146 --> 00:07:32,886 So this is why IT people can't tell you your password 191 00:07:33,086 --> 00:07:35,516 but you can't continue logging in, they can't tell you what 192 00:07:35,516 --> 00:07:37,446 because this encryption is one way, 193 00:07:37,446 --> 00:07:40,286 it's taking the so-called hash of the original input. 194 00:07:40,516 --> 00:07:42,466 And this is for security purposes because again 195 00:07:42,466 --> 00:07:44,756 if it means that some bad guy steals all of this 196 00:07:44,756 --> 00:07:46,786 from your server, physically steals your server, 197 00:07:46,786 --> 00:07:49,416 breaks in over the internet, takes your whole database, 198 00:07:49,546 --> 00:07:52,356 they might have your usernames and user's email addresses 199 00:07:52,356 --> 00:07:53,806 which is perhaps bad for privacy 200 00:07:54,096 --> 00:07:57,046 but at least they don't know your user's passwords 201 00:07:57,316 --> 00:07:59,386 because those are at least encrypted. 202 00:07:59,386 --> 00:08:02,076 And these days if you read in the mass media or see 203 00:08:02,076 --> 00:08:04,706 on CNN some story about some website being hacked, 204 00:08:04,956 --> 00:08:06,206 the likes of Sony or the 205 00:08:06,206 --> 00:08:08,236 like where their user's databases are stolen 206 00:08:08,236 --> 00:08:11,236 and you suddenly have to change your password, that is often-- 207 00:08:11,676 --> 00:08:14,356 because these companies amazingly aren't even doing 208 00:08:14,356 --> 00:08:15,496 something simple like this. 209 00:08:15,496 --> 00:08:17,516 There are numerous cases of companies, 210 00:08:17,516 --> 00:08:21,006 actual legit companies storing user's passwords in the clear, 211 00:08:21,336 --> 00:08:23,906 just as 1, 2, 3, 4, 5 or whatever it is that they typed 212 00:08:23,906 --> 00:08:25,216 in and then you're screwed 213 00:08:25,216 --> 00:08:27,076 if that database is actually compromised. 214 00:08:27,076 --> 00:08:29,526 So towards semester's end when we introduce web programming 215 00:08:29,526 --> 00:08:31,916 and my sequel in databases, we'll talk about these kinds 216 00:08:31,916 --> 00:08:34,936 of issues because it's actually, amazingly, relatively easy 217 00:08:34,936 --> 00:08:36,666 to protect yourself against this. 218 00:08:37,056 --> 00:08:41,236 So that's our segway today and to security and now back to C. 219 00:08:41,236 --> 00:08:43,866 So with problem set 1, if still tackling it, 220 00:08:43,866 --> 00:08:45,276 know that office hours are brought tonight 221 00:08:45,276 --> 00:08:46,916 and if you decide to cash in a late day, 222 00:08:46,916 --> 00:08:48,586 that'll be tomorrow as well enroll. 223 00:08:48,766 --> 00:08:50,656 Know that if you've been attending office hours and if 224 00:08:50,656 --> 00:08:52,116 that issue is with wireless and whatnot, 225 00:08:52,336 --> 00:08:55,066 know that Harvard is actually installing more access points 226 00:08:55,066 --> 00:08:57,416 in all of these house dining halls for us over the next week 227 00:08:57,416 --> 00:09:00,006 or so, so we'll have more capacity for everyone as well 228 00:09:00,006 --> 00:09:01,976 as more cookies and the like. 229 00:09:02,186 --> 00:09:05,416 Also, if you have any remaining questions with the Appliance, 230 00:09:05,416 --> 00:09:08,086 there's definitely been some FAQ's about like cursors kind 231 00:09:08,086 --> 00:09:10,376 of spinning, or windows not quite working, 232 00:09:10,586 --> 00:09:13,556 realize we have solutions to all of these problems so do reach 233 00:09:13,556 --> 00:09:16,566 out to us via help.cs50.net, catch me right after lecture 234 00:09:16,826 --> 00:09:18,986 or email me directly in the worst case 235 00:09:19,246 --> 00:09:21,086 if you're really pushing up against the deadline. 236 00:09:21,086 --> 00:09:23,926 And then lastly, with the Appliance too, 237 00:09:23,926 --> 00:09:26,666 the only real challenging issues with the Appliance is 238 00:09:26,666 --> 00:09:28,086 if you have an older computer-- 239 00:09:28,166 --> 00:09:32,026 3, 4, 5, 6 years old or a fancy netbook that's 240 00:09:32,176 --> 00:09:35,506 by design very limited in RAM in CPU cycles but we have a-- 241 00:09:35,716 --> 00:09:38,826 a new solution for that too for the next problem set and beyond 242 00:09:38,826 --> 00:09:39,676 where you'll be able to connect 243 00:09:39,676 --> 00:09:42,326 to our servers using a very minimalist program 244 00:09:42,326 --> 00:09:44,216 on your computer, not necessarily the Appliance. 245 00:09:44,296 --> 00:09:46,706 So we'll announce that once details are available, 246 00:09:46,706 --> 00:09:48,396 so we should have solutions for all. 247 00:09:49,366 --> 00:09:50,026 So here we are. 248 00:09:50,116 --> 00:09:52,316 This little song last time which is kind 249 00:09:52,316 --> 00:09:55,096 of itself a little tedious to both to recite 250 00:09:55,096 --> 00:09:59,166 and also implement but once you actually have the notion of say, 251 00:09:59,166 --> 00:10:02,036 a loop, which we did, you were able to implement this 252 00:10:02,036 --> 00:10:02,976 with as we saw like a for loop. 253 00:10:03,126 --> 00:10:06,386 >> So let me go back into this week's source code, 254 00:10:06,386 --> 00:10:11,846 this was a file called beer1.c, so following along at home, 255 00:10:11,846 --> 00:10:14,846 this is in source directory for lecture 2 256 00:10:15,186 --> 00:10:17,116 and if I go into here, beer1. 257 00:10:17,696 --> 00:10:21,486 So what do we now-- how did we go about implementing this? 258 00:10:21,486 --> 00:10:23,626 Well, we have-- into main board, that's all it has, 259 00:10:23,786 --> 00:10:26,196 at the very top here, how many bottles of beer will there be? 260 00:10:26,196 --> 00:10:28,806 And then getint so that just gets a number from the user, 261 00:10:29,026 --> 00:10:30,866 then recall we had a bit of error checking, 262 00:10:30,866 --> 00:10:32,426 just make sure the user is not messing with us 263 00:10:32,426 --> 00:10:34,576 and in this case, we don't repeatedly-- 264 00:10:35,126 --> 00:10:37,416 reprompt them for a number, we just say, "Ugh, 265 00:10:37,416 --> 00:10:39,466 lets yell at them, sorry that makes no sense." 266 00:10:39,466 --> 00:10:40,256 and return one. 267 00:10:40,576 --> 00:10:41,916 And return one again as the notion 268 00:10:41,916 --> 00:10:43,736 like of an error code, and exit code. 269 00:10:43,736 --> 00:10:46,616 And then lastly, the actual implementation 270 00:10:46,616 --> 00:10:49,456 of this song simply happened down here, 271 00:10:49,456 --> 00:10:50,736 sing the annoying song. 272 00:10:50,986 --> 00:10:54,896 So for int, I gets N, so-- if the user types in 99, 273 00:10:54,896 --> 00:10:59,506 start counting at 99 on each iteration, subtract one from I 274 00:10:59,506 --> 00:11:02,216 and that's what I minus minus denotes the opposite 275 00:11:02,216 --> 00:11:05,416 of I plus plus, and then do this so long as I is greater 276 00:11:05,416 --> 00:11:08,056 than zero, and on each iteration of this loop, 277 00:11:08,056 --> 00:11:10,076 print this four-line stanza. 278 00:11:10,536 --> 00:11:12,866 And the only thing that's kind of interesting here is this. 279 00:11:13,056 --> 00:11:16,876 One, we have a placeholder for the integer D and we're plugging 280 00:11:16,876 --> 00:11:18,706 in I as you can see over here, 281 00:11:19,016 --> 00:11:20,776 we have another placeholder that's identical, 282 00:11:20,776 --> 00:11:22,386 its just the English words have changed. 283 00:11:22,556 --> 00:11:26,556 This is completely uninteresting 'cause it's just a string, 284 00:11:26,696 --> 00:11:28,916 constant string that gets spit out every time. 285 00:11:29,246 --> 00:11:31,106 And the interesting aspect here is just this, 286 00:11:31,306 --> 00:11:33,616 'cause the song again is "99 bottles of beer on the wall, 287 00:11:33,616 --> 00:11:35,236 99 bottles of beer, take one down, pass it around, 288 00:11:35,556 --> 00:11:37,736 98 bottles of beer on the wall," so we need 289 00:11:37,736 --> 00:11:41,116 to somehow dynamically insert I minus one but we can do 290 00:11:41,116 --> 00:11:44,266 that very simply, arithmetically here so I minus one. 291 00:11:44,676 --> 00:11:47,596 So the only worry here you might have or should have is-- 292 00:11:47,596 --> 00:11:50,146 alright, what's gonna happen on-- at the corner cases? 293 00:11:50,236 --> 00:11:50,986 The recurring theme 294 00:11:50,986 --> 00:11:54,706 in programming is you can get 98 cases perfectly right 295 00:11:54,706 --> 00:11:56,726 with your code, but it doesn't really matter at the end 296 00:11:56,726 --> 00:11:59,546 of the day if you screw up the first case or the last case. 297 00:11:59,776 --> 00:12:02,486 And by name, those are typically called Corner Cases and so 298 00:12:02,486 --> 00:12:03,896 as you start writing your own programs 299 00:12:03,896 --> 00:12:06,346 and you start testing your programs by typing in values, 300 00:12:06,666 --> 00:12:11,596 we'll program like this, if you type in 5 or 6 or 7 or 97, 301 00:12:11,886 --> 00:12:14,526 odds are you're gonna get the same fundamental behavior. 302 00:12:14,746 --> 00:12:18,446 But things get interesting if you choose those corner cases. 303 00:12:18,446 --> 00:12:22,536 Type in one, type in zero, type in negative one, type in 100, 304 00:12:22,756 --> 00:12:25,116 type in something distinct conceptually, 305 00:12:25,306 --> 00:12:27,806 something that's closed to any boundaries you define 306 00:12:28,066 --> 00:12:30,756 to actually see whether or not something breaks. 307 00:12:30,976 --> 00:12:34,196 So in this version here, is there any risk of my printing 308 00:12:34,196 --> 00:12:40,846 out "negative one bottles of beer on the wall"? 309 00:12:41,026 --> 00:12:43,836 Will this ever print out "negative one bottles of beer 310 00:12:43,836 --> 00:12:45,806 on the wall" in that last line of printf? 311 00:12:46,616 --> 00:12:46,683 >> No. 312 00:12:47,556 --> 00:12:48,766 >> Okay, so no, it won't, and why? 313 00:12:48,766 --> 00:12:50,686 What's the simple protection I've put in place? 314 00:12:50,686 --> 00:12:51,666 [ Inaudible Answers ] 315 00:12:51,666 --> 00:12:54,686 >> Yeah, so I has to be greater 316 00:12:54,686 --> 00:12:56,826 than zero according to this, right? 317 00:12:56,826 --> 00:13:00,676 So as soon as I is not greater than zero, it is zero, 318 00:13:00,826 --> 00:13:03,786 this loop is gonna stop executing which means the value 319 00:13:03,786 --> 00:13:07,666 of I itself will never be zero inside of this loop. 320 00:13:07,666 --> 00:13:11,076 The very last iteration will have a value of I equals one 321 00:13:11,286 --> 00:13:13,936 and so that's safe 'cause we'll save one bottle of beer, 322 00:13:13,936 --> 00:13:16,716 one bottle of beer, dot, dot, dot, zero bottles of beer 323 00:13:16,716 --> 00:13:17,806 on the wall and we'll stop. 324 00:13:17,916 --> 00:13:20,456 But of course, if we had done something like this, 325 00:13:21,016 --> 00:13:23,126 so I'll go ahead and change this to greater than or equals, 326 00:13:23,126 --> 00:13:26,976 I'll save the file, let me go down to my terminal window here 327 00:13:26,976 --> 00:13:30,226 into the source directory, and I'll type "make beer1" 328 00:13:30,226 --> 00:13:34,086 and now I'm gonna go ahead and run beer1 with-- 329 00:13:34,086 --> 00:13:36,876 lets say, the value 99, Enter. 330 00:13:37,356 --> 00:13:39,916 Well, dramatic effect, if we now scroll 331 00:13:39,916 --> 00:13:41,996 up to see what's actually there. 332 00:13:42,426 --> 00:13:43,496 There we go. 333 00:13:44,216 --> 00:13:44,896 There's the bug. 334 00:13:44,896 --> 00:13:46,186 So now, we've introduced the bug 335 00:13:46,186 --> 00:13:47,646 but we had it right the first time. 336 00:13:47,646 --> 00:13:48,846 So again, recurring theme, 337 00:13:48,846 --> 00:13:51,526 especially before submitting your PSet, test these kinds 338 00:13:51,526 --> 00:13:54,046 of cases because the TF's are gonna be looking 339 00:13:54,046 --> 00:13:55,446 for exactly these kinds of things. 340 00:13:55,446 --> 00:13:58,266 We're not gonna test your program with 3 and 4 and 5 and 6 341 00:13:58,306 --> 00:14:00,836 because most likely, those are all functionally equivalent. 342 00:14:01,016 --> 00:14:02,726 It's the interesting, the negative numbers, 343 00:14:02,726 --> 00:14:05,566 the zero numbers, the huge numbers that might ultimately be 344 00:14:05,566 --> 00:14:08,566 of particular opportunity for your code to break. 345 00:14:09,846 --> 00:14:11,626 Questions of any sorts? 346 00:14:13,066 --> 00:14:13,216 Yeah. 347 00:14:13,556 --> 00:14:16,386 >> How exactly do you implement the "return 1"? 348 00:14:17,336 --> 00:14:20,826 >> How do you implement the "return 1"-- in "return 1" in-- 349 00:14:20,966 --> 00:14:21,846 implement it in what sense? 350 00:14:22,696 --> 00:14:27,336 >> Like how do you use it to like jump back [inaudible]? 351 00:14:28,526 --> 00:14:31,626 >> Good question, so how do you use "return 1" 352 00:14:31,626 --> 00:14:33,126 to get another int from the user? 353 00:14:33,126 --> 00:14:33,876 In short, you don't. 354 00:14:33,936 --> 00:14:36,286 So this was a deliberate design decision in this program 355 00:14:36,546 --> 00:14:39,296 that I'm not gonna use a while loop, or for loop, 356 00:14:39,296 --> 00:14:41,746 or do-while loop to ask the user again and again. 357 00:14:41,906 --> 00:14:44,766 If they don't give me what I ask for, which is a non-zero number 358 00:14:44,766 --> 00:14:47,046 of bottles, then I'm just gonna quit immediately 359 00:14:47,126 --> 00:14:50,056 because it's not a fun song to sing, but we could've done this 360 00:14:50,056 --> 00:14:52,476 with a do-while loop like in the PSets. 361 00:14:52,476 --> 00:14:52,896 Yeah. 362 00:14:53,516 --> 00:15:00,566 [ Inaudible Question ] 363 00:15:01,066 --> 00:15:04,366 >> So how do you use this number "return zero"-- "return 1"? 364 00:15:04,686 --> 00:15:07,136 So short answer, we're not going to yet, but starting next week, 365 00:15:07,136 --> 00:15:08,926 we're gonna introduce something called a Debugger 366 00:15:08,956 --> 00:15:10,816 which is a separate tool from the compiler 367 00:15:11,046 --> 00:15:13,376 that actually lets you figure out what's going on inside 368 00:15:13,376 --> 00:15:15,076 of the computer and even lets you step you 369 00:15:15,076 --> 00:15:17,606 through your code line by line by line, 370 00:15:17,856 --> 00:15:20,726 and for that to another's the return code is gonna be useful. 371 00:15:20,726 --> 00:15:23,376 For now, since sort of thing just take it on faith 372 00:15:23,376 --> 00:15:24,636 because it will soon become useful. 373 00:15:25,516 --> 00:15:26,926 So we now have beer2, 374 00:15:27,006 --> 00:15:29,566 so we wanna do something a little better here 375 00:15:29,566 --> 00:15:31,676 and introduce kind of a big topic that frankly you might see 376 00:15:31,676 --> 00:15:34,146 in a textbook but no one ever really says it in-- 377 00:15:34,396 --> 00:15:38,516 in person which is that of hierarchical decomposition. 378 00:15:38,676 --> 00:15:40,696 So what is this actually mean and who cares? 379 00:15:41,136 --> 00:15:45,376 So let me scroll down now to actually let me go with-- 380 00:15:46,006 --> 00:15:49,346 let's go with beer4.c. Yeah, this is-- 381 00:15:49,526 --> 00:15:50,446 this is the one I want. 382 00:15:50,916 --> 00:15:52,926 Okay, so in programming, 383 00:15:53,106 --> 00:15:55,096 you will often find yourself doing something a little 384 00:15:55,096 --> 00:15:57,886 repeatedly like if you yourself have been writing programs 385 00:15:57,886 --> 00:16:00,186 where you're kind of stealing code you wrote a few minutes ago 386 00:16:00,186 --> 00:16:02,456 on some other line and pasting it, pasting it, and pasting it, 387 00:16:02,826 --> 00:16:04,506 that's probably gonna be an opportunity 388 00:16:04,506 --> 00:16:06,246 for hierarchical decomposition 389 00:16:06,336 --> 00:16:08,236 which just means write your own function. 390 00:16:08,556 --> 00:16:11,186 So thus far, we've been using main, which we have to, 391 00:16:11,186 --> 00:16:14,086 to write a program from the get go, you've been using printf 392 00:16:14,416 --> 00:16:15,416 which someone else wrote. 393 00:16:15,416 --> 00:16:17,626 You've been using getint which someone else wrote, 394 00:16:17,916 --> 00:16:20,356 so you haven't really most likely written your own 395 00:16:20,416 --> 00:16:23,046 functions and yet this is actually relatively easy 396 00:16:23,046 --> 00:16:24,806 and its not even new syntax, we just kind 397 00:16:24,806 --> 00:16:26,786 of mimic the same syntax we've seen 398 00:16:26,946 --> 00:16:29,096 with getint and printf, and main. 399 00:16:29,356 --> 00:16:31,006 So let's take a look at this version here. 400 00:16:31,006 --> 00:16:34,866 So if I zoom in here, notice at the very top of this file, 401 00:16:34,926 --> 00:16:37,656 I have again the same code at the top, 402 00:16:37,796 --> 00:16:39,256 how many bottles of beer will it be? 403 00:16:39,456 --> 00:16:41,856 I get an int from the user, I quit immediately 404 00:16:41,856 --> 00:16:43,896 by returning one if they don't cooperate, 405 00:16:44,156 --> 00:16:49,536 and then I have this two-liner which is kind of interesting 406 00:16:49,536 --> 00:16:50,676 for a couple of reasons. 407 00:16:50,676 --> 00:16:53,536 So one, I'm-- have a while loop now, why? 408 00:16:53,916 --> 00:16:55,556 It's just a little different from a for loop, 409 00:16:55,556 --> 00:16:57,176 I decided to do this aesthetically. 410 00:16:57,556 --> 00:17:00,466 But what's interesting too is I've got N minus minus, 411 00:17:00,826 --> 00:17:03,346 we'll come back to that, but more interestingly all 412 00:17:03,346 --> 00:17:06,016 of a sudden there's a chorus function that why-- 413 00:17:06,016 --> 00:17:08,946 apparently, I could've been using all this time to print 414 00:17:08,946 --> 00:17:12,456 out the chorus, that four-line stanza of this song. 415 00:17:12,646 --> 00:17:14,126 It's as though I've now outsourced 416 00:17:14,126 --> 00:17:17,546 to a little black box called Chorus that itself is a function 417 00:17:17,546 --> 00:17:20,676 that someone else wrote and that function's purpose in life is 418 00:17:20,676 --> 00:17:22,696 to sing the song for me so I don't have 419 00:17:22,696 --> 00:17:24,026 to write these lines myself. 420 00:17:24,386 --> 00:17:27,586 Now, in reality, someone did have to write those lines 421 00:17:27,586 --> 00:17:28,956 and in reality it was me. 422 00:17:29,096 --> 00:17:31,706 And if you scroll down to the bottom of this file now, 423 00:17:31,706 --> 00:17:34,666 notice the following, so this is familiar syntax even though 424 00:17:34,666 --> 00:17:37,026 we've not used this too many times this far, 425 00:17:37,276 --> 00:17:39,056 the things with the stars, that's just a comment. 426 00:17:39,326 --> 00:17:42,276 Slash star, then some stuff, then star slash, 427 00:17:42,456 --> 00:17:44,716 that's a multiline comment and then that's just my note 428 00:17:44,716 --> 00:17:47,426 to myself, sings about specified number of bottles. 429 00:17:47,856 --> 00:17:48,776 Then below that, 430 00:17:48,886 --> 00:17:50,856 I have something that's similar syntactically 431 00:17:50,856 --> 00:17:53,366 but still a bit new conceptually, I've got void 432 00:17:53,366 --> 00:17:58,136 and then the word Chorus and then int B. And then inside 433 00:17:58,136 --> 00:18:00,606 of this, I've got a couple of new features. 434 00:18:00,606 --> 00:18:03,766 I have this new syntax which we'll come to in a moment, 435 00:18:03,766 --> 00:18:05,706 so let's ignore anything we don't quite understand yet, 436 00:18:05,706 --> 00:18:06,876 and focus only on this. 437 00:18:07,486 --> 00:18:09,706 Well, this is kind of interesting, sing verses. 438 00:18:10,276 --> 00:18:13,626 So what am I doing that's different here? 439 00:18:13,906 --> 00:18:16,526 So I still have my percent D but what new format-- 440 00:18:16,526 --> 00:18:18,326 what format code is now obviously new? 441 00:18:18,986 --> 00:18:23,526 So percent S, so I'm actually fixing a couple of problems now 442 00:18:23,526 --> 00:18:24,586 and are finding this code 443 00:18:24,586 --> 00:18:26,486 with a more sophisticated implementation. 444 00:18:26,716 --> 00:18:28,636 Percent D is still gonna be the value 445 00:18:28,636 --> 00:18:30,096 of the number of bottles of beer. 446 00:18:30,376 --> 00:18:32,726 Percent S is gonna be which of two words? 447 00:18:33,186 --> 00:18:34,186 If any of you just take a guess. 448 00:18:34,186 --> 00:18:34,506 [ Inaudible Answer ] 449 00:18:34,506 --> 00:18:37,786 >> It's gonna be bottle or bottles so I'm fixing 450 00:18:37,786 --> 00:18:40,276 that grammar problem that I admitted to on Monday, 451 00:18:40,486 --> 00:18:43,026 so we'll come back to how that's working in just a moment. 452 00:18:43,316 --> 00:18:44,836 But B, what happened to I? 453 00:18:45,096 --> 00:18:47,426 Well, this is the fundamentally interesting aspect 454 00:18:47,426 --> 00:18:49,556 of actually writing your own functions. 455 00:18:49,776 --> 00:18:51,536 Notice that at the top of this function, 456 00:18:51,536 --> 00:18:53,116 I've specified what kind 457 00:18:53,116 --> 00:18:55,536 of input this function called Chorus takes 458 00:18:55,636 --> 00:18:57,366 and it's pretty obvious that it takes an int. 459 00:18:57,736 --> 00:19:00,406 And just because I'm gonna be talking about bottles, 460 00:19:00,406 --> 00:19:04,686 I decided that B is a reasonable name for the variable to give 461 00:19:04,686 --> 00:19:06,146 to the input to this function. 462 00:19:06,606 --> 00:19:10,626 Now, notice how I'm using chorus, if I go up here 463 00:19:10,626 --> 00:19:12,956 and actually let me simplify this just for a moment. 464 00:19:12,996 --> 00:19:17,266 I'm gonna change this code just for the moment to I minus minus 465 00:19:17,806 --> 00:19:19,516 and then this closed brace here. 466 00:19:19,886 --> 00:19:22,816 So notice on every iteration of this while loop, 467 00:19:22,816 --> 00:19:24,956 if I start by typing in 99 for N, 468 00:19:25,296 --> 00:19:27,876 what value apparently gets passed inside the parenthesis 469 00:19:27,876 --> 00:19:29,046 to this function called chorus? 470 00:19:30,396 --> 00:19:31,306 This is 99, right? 471 00:19:31,306 --> 00:19:33,076 Whatever values in N is what-- 472 00:19:33,076 --> 00:19:35,556 gets handed to Chorus as an input. 473 00:19:35,716 --> 00:19:38,116 Alright, so now let me scroll down to the bottom here. 474 00:19:38,306 --> 00:19:42,916 Well, just because chorus takes an int, doesn't mean it has 475 00:19:42,956 --> 00:19:45,416 to take an int whose name is identical 476 00:19:45,466 --> 00:19:47,026 to what the original value was. 477 00:19:47,256 --> 00:19:48,536 I can name it anything I want 478 00:19:48,536 --> 00:19:51,126 and I decided stylistically B makes sense 'cause I'm talking 479 00:19:51,126 --> 00:19:51,826 about bottles. 480 00:19:52,166 --> 00:19:55,926 So what's gonna happen then is when I call the chorus function 481 00:19:55,926 --> 00:19:58,836 up in main by just writing chorus, open parenthesis, N, 482 00:19:58,956 --> 00:19:59,976 close parenthesis, semicolon. 483 00:20:00,166 --> 00:20:03,576 >> What's gonna happen is that chorus is gonna be executed 484 00:20:03,716 --> 00:20:06,876 and be handed as input that number, 99, and it's getting-- 485 00:20:06,876 --> 00:20:09,836 get its own copy of 99, its own 32 bits, 486 00:20:09,836 --> 00:20:11,466 its own 4 bytes somewhere in RAM 487 00:20:11,696 --> 00:20:13,906 and they're just gonna be called B 488 00:20:13,906 --> 00:20:15,316 in the context of this function. 489 00:20:15,556 --> 00:20:16,906 Now, what am I doing with B? 490 00:20:16,906 --> 00:20:19,336 Well, lets scroll down to the printfs while I'm apparently 491 00:20:19,456 --> 00:20:22,746 plugging in for percent D, the value B, I'm plugging 492 00:20:22,746 --> 00:20:25,276 in for the value-- percent D, the value B again. 493 00:20:25,276 --> 00:20:27,406 And then in the very last line, I'm plugging 494 00:20:27,406 --> 00:20:29,626 in for percent D, B minus one. 495 00:20:29,866 --> 00:20:32,016 So functionally, this is equivalent. 496 00:20:32,206 --> 00:20:34,816 All I've done is kind of outsourced now the singing 497 00:20:34,816 --> 00:20:37,036 of the song to someone other than main 498 00:20:37,036 --> 00:20:40,226 and that someone is a new function called Chorus. 499 00:20:41,186 --> 00:20:43,116 So now what about S2 and S1? 500 00:20:43,316 --> 00:20:46,876 Well, let me rewrite something quickly as this, 501 00:20:46,876 --> 00:20:52,496 if B equals equals one, then I'm gonna do this, string 1 S2. 502 00:20:52,666 --> 00:21:01,586 I'm gonna say, "S1 gets bottle else S1 gets bottles," 503 00:21:01,586 --> 00:21:05,256 and then I'm gonna do a little quick copy paste here, 504 00:21:05,256 --> 00:21:07,296 and actually let me clean this up. 505 00:21:07,296 --> 00:21:11,176 I did this on the fly S2, and I'm gonna do S1 up here, 506 00:21:11,176 --> 00:21:20,396 and I'm gonna say, "If a bottle equals 2, then I'm going to say, 507 00:21:20,746 --> 00:21:22,766 S2 gets bottle bottles." 508 00:21:23,426 --> 00:21:25,566 Alright, so what is going on here? 509 00:21:25,736 --> 00:21:28,766 So first, let's ignore the goal and focus only on the syntax. 510 00:21:28,956 --> 00:21:32,496 Well, what does it mean if I say string S1 in a program? 511 00:21:33,066 --> 00:21:37,506 Just translate that to English. 512 00:21:37,506 --> 00:21:37,573 [ Inaudible Answer ] 513 00:21:37,573 --> 00:21:40,606 >> Okay, not quite initialized but declare a variable 514 00:21:40,606 --> 00:21:43,286 of type string and call it S1. 515 00:21:43,286 --> 00:21:44,896 This is identical conceptually 516 00:21:44,896 --> 00:21:47,606 to doing something like int N semicolon. 517 00:21:47,766 --> 00:21:51,426 That means declare an integer, call it N and that's it 518 00:21:51,596 --> 00:21:52,686 because there's no equal sign. 519 00:21:52,686 --> 00:21:53,826 Don't do anything else with it yet. 520 00:21:54,156 --> 00:21:57,236 Now, a string recall is just a word, a phrase, a sentence, 521 00:21:57,236 --> 00:22:00,746 a paragraph at some number of characters, so string S1 means, 522 00:22:00,746 --> 00:22:03,746 okay, prepare to get me a string 523 00:22:04,046 --> 00:22:05,906 and that string is gonna be called S1. 524 00:22:05,966 --> 00:22:07,166 So what am I doing here? 525 00:22:07,356 --> 00:22:10,786 Well, if the number of bottles past N equals one, 526 00:22:10,946 --> 00:22:14,126 I want this string to represent bottle in the singular, 527 00:22:14,366 --> 00:22:18,866 else if B is anything else, 2, 3, 4, 5, whatever, 528 00:22:19,176 --> 00:22:20,526 then I want it to be bottles. 529 00:22:20,696 --> 00:22:22,966 So it seems like now I'm using just a branching condition 530 00:22:22,966 --> 00:22:25,836 to fix some grammar and then I actually have S2 down here 531 00:22:25,836 --> 00:22:27,676 but we'll see why in just a moment. 532 00:22:27,816 --> 00:22:30,246 So let me scroll down here and see what I'm doing. 533 00:22:30,526 --> 00:22:35,286 So printf, percent D, so if I type in 99, that goes there. 534 00:22:35,536 --> 00:22:39,026 If I type in 99, what's gonna go here for percent S 535 00:22:39,416 --> 00:22:41,846 if what I'm putting in there is S1. 536 00:22:43,166 --> 00:22:44,376 Bottles, right? 537 00:22:44,376 --> 00:22:46,836 So again, I'm just creating a variable on the fly here, 538 00:22:46,836 --> 00:22:51,716 string S1, and if B equals equals one, make S1 be bottle 539 00:22:51,716 --> 00:22:54,716 in the singular, else make S1 bottles in the plural 540 00:22:54,716 --> 00:22:56,886 and so that's what gets plugged in there. 541 00:22:57,146 --> 00:22:57,976 Now, why S2? 542 00:22:57,976 --> 00:23:00,326 I'm gonna wave my hand at this detail just for now 543 00:23:00,536 --> 00:23:03,306 but it's simply because in the very last line 544 00:23:03,306 --> 00:23:04,866 of the song again, I might need 545 00:23:04,866 --> 00:23:07,026 to change the pluralization, right? 546 00:23:07,026 --> 00:23:08,886 It might go from bottle to bottles 547 00:23:08,886 --> 00:23:11,746 because it might be one bottle to zero bottles, 548 00:23:12,046 --> 00:23:15,106 or it might be two bottles to one bottle. 549 00:23:15,346 --> 00:23:17,506 And so you need to have two different words. 550 00:23:17,506 --> 00:23:20,226 One might be singular, one might plural, or vice versa. 551 00:23:20,226 --> 00:23:21,446 Or they might both be plural 552 00:23:21,676 --> 00:23:24,126 so that's simply why I have S1 and S2. 553 00:23:24,666 --> 00:23:27,196 Now, in terms of conditions-- 554 00:23:27,386 --> 00:23:28,596 like we've done this before, right? 555 00:23:28,596 --> 00:23:32,216 If this else that, and just so you've seen new syntax, 556 00:23:32,326 --> 00:23:35,956 it turns out that syntactically, these two lines 557 00:23:35,956 --> 00:23:39,546 at the very top are what we would call a very elegant one 558 00:23:39,546 --> 00:23:41,606 line implementation of that same idea. 559 00:23:41,606 --> 00:23:44,826 By no means strictly required doing it the way I did here 560 00:23:44,826 --> 00:23:47,146 with the indentation and whatnot is perfectly fine 561 00:23:47,346 --> 00:23:48,696 but let's just see what this is. 562 00:23:48,696 --> 00:23:53,286 This is the only-- this is the only funky line 563 00:23:53,286 --> 00:23:56,926 of code we're gonna see for awhile that has multiple pieces 564 00:23:56,926 --> 00:23:59,586 of punctuation in the middle of it, so what's going on here? 565 00:23:59,586 --> 00:24:01,046 Well, let's do the first part on the left. 566 00:24:01,576 --> 00:24:05,526 String S1 means give me a string, call it S1, that's it. 567 00:24:06,046 --> 00:24:08,326 The equal sign means put some value in there, 568 00:24:08,576 --> 00:24:10,206 so the last question to ask ourselves is, 569 00:24:10,326 --> 00:24:11,756 what value do you wanna put there? 570 00:24:12,086 --> 00:24:15,346 Well, it turns out that this expression right here is 571 00:24:15,346 --> 00:24:19,756 identical to this, it's just a slightly more succinct, 572 00:24:19,756 --> 00:24:23,086 there's a-- a prettier way of expressing that same idea. 573 00:24:23,436 --> 00:24:25,986 What this means is that if B equals equals one, 574 00:24:26,386 --> 00:24:30,486 the word after the question mark is gonna plopped into S1. 575 00:24:30,616 --> 00:24:35,246 Else, so this colon represent else now, else bottles 576 00:24:35,246 --> 00:24:37,786 in the plural is gonna get plopped into S1. 577 00:24:37,786 --> 00:24:40,946 So in other words, it collapses all five of these lines 578 00:24:41,196 --> 00:24:43,576 into one line that once you know the syntax, 579 00:24:43,636 --> 00:24:45,616 its just a little easier to swallow, 580 00:24:45,616 --> 00:24:46,986 just a little easier to read. 581 00:24:47,616 --> 00:24:49,066 But let me point out one thing. 582 00:24:50,106 --> 00:24:54,576 I intentionally did this, string S1, why? 583 00:24:55,026 --> 00:25:01,596 If you think back to Monday did I not do this? 584 00:25:01,596 --> 00:25:05,576 Its-- if I declare as variable, in this case a string inside 585 00:25:05,576 --> 00:25:08,696 of a condition that's pretty much equivalent recall 586 00:25:08,866 --> 00:25:12,156 to writing this even though the curly braces are not necessary 587 00:25:12,156 --> 00:25:13,106 if its just one line. 588 00:25:13,106 --> 00:25:16,066 But conceptually, its equivalent to this, and what was the rule 589 00:25:16,096 --> 00:25:18,426 of thumb we discussed on Monday when it comes to variables? 590 00:25:19,486 --> 00:25:21,566 Scope. They're only in scope. 591 00:25:21,566 --> 00:25:23,606 They only exist inside of the confines 592 00:25:23,606 --> 00:25:25,606 of the most recent curly braces even 593 00:25:25,796 --> 00:25:28,366 if those curly braces have been omitted just 'cause its one line 594 00:25:28,366 --> 00:25:29,426 of code for convenience. 595 00:25:29,716 --> 00:25:32,896 Those variables only exist inside of those curly braces 596 00:25:33,106 --> 00:25:34,846 which means I'm kind of out of luck 597 00:25:34,846 --> 00:25:37,206 if I wanna use S1 down here. 598 00:25:37,616 --> 00:25:39,816 And so the solution is simply make sure 599 00:25:39,816 --> 00:25:43,166 that the strings are declared outside of those conditions. 600 00:25:43,166 --> 00:25:45,616 So this again is a question of scope. 601 00:25:46,426 --> 00:25:49,646 So in short, we've solved a few problems here all at once. 602 00:25:49,746 --> 00:25:53,356 So on the one hand with chorus, we declared our own function, 603 00:25:53,546 --> 00:25:55,296 it takes input and now I don't have 604 00:25:55,296 --> 00:25:56,646 to clutter up my main function. 605 00:25:56,646 --> 00:25:59,686 If I have this well-defined task, sing the chorus of a song, 606 00:25:59,906 --> 00:26:02,436 that's a candidate for hierarchical decomposition, 607 00:26:02,436 --> 00:26:03,766 it just means factor it out. 608 00:26:03,956 --> 00:26:06,256 Create a little black box, give it a user-friendly name 609 00:26:06,256 --> 00:26:08,666 like chorus, define it as taking some input 610 00:26:08,666 --> 00:26:10,686 like an integer call it whatever you want, 611 00:26:10,686 --> 00:26:12,616 B and then it does something. 612 00:26:12,646 --> 00:26:16,466 And the only last question to-- ask about the syntax here is, 613 00:26:16,666 --> 00:26:20,726 what does it mean if Chorus is prefixed with this word Void? 614 00:26:24,136 --> 00:26:25,896 So it-- yeah? 615 00:26:25,896 --> 00:26:26,796 [ Inaudible Answer ] 616 00:26:26,796 --> 00:26:29,856 >> So it-- not input, so it does take input 617 00:26:30,056 --> 00:26:32,386 because the input is always defined between the parenthesis, 618 00:26:33,146 --> 00:26:34,226 so what's the opposite of input? 619 00:26:34,226 --> 00:26:34,526 [ Inaudible Answer ] 620 00:26:34,526 --> 00:26:37,276 >> So output, so this means chorus does not have 621 00:26:37,276 --> 00:26:38,176 any outputs. 622 00:26:38,436 --> 00:26:39,916 Now, this feels like a bit of a lie 623 00:26:39,916 --> 00:26:42,246 because clearly the song is gonna have some kind 624 00:26:42,246 --> 00:26:43,476 of output, what's it gonna do? 625 00:26:43,696 --> 00:26:45,616 Well, it's gonna print the whole bunch of stuff 626 00:26:45,616 --> 00:26:47,956 to the screen based on this printf lines, 627 00:26:48,166 --> 00:26:49,616 but this is a different type of output. 628 00:26:50,026 --> 00:26:52,706 Recall that you can print something to the screen 629 00:26:52,936 --> 00:26:55,366 but you can also hand the user back a value. 630 00:26:55,456 --> 00:26:57,246 For instance, what's the function you've been using 631 00:26:57,246 --> 00:27:01,866 for a week or more now that return some value? 632 00:27:01,866 --> 00:27:01,933 [ Inaudible Answer ] 633 00:27:01,933 --> 00:27:02,676 >> So getints, right? 634 00:27:02,676 --> 00:27:06,226 Getints, get string, get double, in those cases, 635 00:27:06,326 --> 00:27:09,166 the function getint, it doesn't just print it out on the screen 636 00:27:09,166 --> 00:27:11,266 and leave it for you, the human, to figure out what it was, 637 00:27:11,486 --> 00:27:14,996 it returns it so to speak so that you can put it to the right 638 00:27:14,996 --> 00:27:17,916 of an equal sign so that you can assign its return value 639 00:27:17,916 --> 00:27:18,846 to some variable. 640 00:27:18,846 --> 00:27:22,636 Well, same idea here, chorus though, is only purpose 641 00:27:22,636 --> 00:27:25,126 in life is to have these aesthetic side effects 642 00:27:25,176 --> 00:27:27,026 of printing something to the screen, 643 00:27:27,236 --> 00:27:29,956 it doesn't actually hand the user back any value, 644 00:27:29,956 --> 00:27:32,776 any sentence, any string, whatsoever, it just prints 645 00:27:33,056 --> 00:27:35,636 and so its return type is void. 646 00:27:35,636 --> 00:27:38,556 And we'll see this again and again in more clarity, yeah. 647 00:27:39,516 --> 00:27:46,676 [ Inaudible Question ] 648 00:27:47,176 --> 00:27:49,006 >> Oh, so there is, we just scrolled beyond it. 649 00:27:49,086 --> 00:27:51,876 So if I scroll back up, recall that we begin the story 650 00:27:51,876 --> 00:27:53,456 with main just as usual. 651 00:27:54,386 --> 00:27:54,516 Yeah. 652 00:27:54,726 --> 00:27:58,176 >> If you declare a-- a variable in main, 653 00:27:58,696 --> 00:28:01,706 will it still be declared in another function of the main? 654 00:28:01,706 --> 00:28:04,406 >> Really good question, if you declare a variable in main, 655 00:28:04,406 --> 00:28:06,946 will it be accessible to another function like chorus? 656 00:28:06,946 --> 00:28:08,186 What do you think? 657 00:28:09,136 --> 00:28:09,326 >> No. 658 00:28:09,716 --> 00:28:12,076 >> So no, and again, you can fall back on the same rule 659 00:28:12,146 --> 00:28:13,936 of thumb, variables only exist 660 00:28:13,936 --> 00:28:15,646 within the confines of the curly braces. 661 00:28:15,646 --> 00:28:17,276 So main has its own curly braces 662 00:28:17,276 --> 00:28:18,866 at the very start and the very end. 663 00:28:19,116 --> 00:28:21,806 So any variables in there are not in fact accessible 664 00:28:22,056 --> 00:28:23,316 by a function like chorus. 665 00:28:23,316 --> 00:28:27,316 And let me point out one other detail here before we can put 666 00:28:27,316 --> 00:28:29,716 to rest this singing song example. 667 00:28:29,956 --> 00:28:33,336 There's one piece of new stuff at the top of this file, 668 00:28:33,336 --> 00:28:36,086 so besides all of the comments up at the top of the file, 669 00:28:36,386 --> 00:28:40,106 besides my use of include CS50.h and standard IO.h, 670 00:28:40,446 --> 00:28:43,196 there's this thing whose word is gonna be called generally a 671 00:28:43,296 --> 00:28:44,366 function prototype. 672 00:28:44,876 --> 00:28:45,756 Well, what does this mean? 673 00:28:46,076 --> 00:28:47,916 So C is kind of stupid, right? 674 00:28:47,916 --> 00:28:51,366 It's an older language, the compilers for it are fairly-- 675 00:28:51,366 --> 00:28:53,106 even though they've been updated over the years, 676 00:28:53,436 --> 00:28:57,006 they were very simplistic in terms of their design early on 677 00:28:57,356 --> 00:28:58,516 and what does that mean? 678 00:28:58,516 --> 00:29:02,026 It means that the compiler, if you don't tell it in advance 679 00:29:02,396 --> 00:29:06,356 that a function exists like chorus, and it encounters 680 00:29:06,356 --> 00:29:07,516 that word somewhere 681 00:29:07,516 --> 00:29:09,556 in the program before its actually seeing your 682 00:29:09,556 --> 00:29:12,356 implementation of that function, its going to yell at you. 683 00:29:12,606 --> 00:29:14,566 It's gonna trigger some kind of error. 684 00:29:14,886 --> 00:29:17,516 In other words, let me do this, I'm gonna undo all 685 00:29:17,516 --> 00:29:19,446 of the changes I've done in this example just 686 00:29:19,446 --> 00:29:20,756 so we know I didn't screw it up 687 00:29:20,756 --> 00:29:22,566 and its back in its pristine form. 688 00:29:23,036 --> 00:29:25,176 And we'll come back another time to this syntax 689 00:29:25,176 --> 00:29:27,676 of doing the minus minus inside of the parenthesis there. 690 00:29:28,086 --> 00:29:29,476 I'm gonna go up to the top here, 691 00:29:29,476 --> 00:29:33,226 I'm gonna expand my terminal window and I'm gonna go ahead 692 00:29:33,226 --> 00:29:35,726 and compile this thing which again was beer4. 693 00:29:35,726 --> 00:29:39,546 So make beer4, I'm gonna go ahead and run beer4 694 00:29:39,546 --> 00:29:42,156 and I'll type in just two bottles to keep it short 695 00:29:42,156 --> 00:29:43,846 and simple, that seems to work. 696 00:29:44,086 --> 00:29:45,566 No weird side effects. 697 00:29:45,926 --> 00:29:47,126 So now, let me break it. 698 00:29:47,486 --> 00:29:49,896 Let me accidentally delete this thing 699 00:29:49,896 --> 00:29:51,366 that we're calling a function prototype 700 00:29:51,366 --> 00:29:52,636 and just start typing main. 701 00:29:52,796 --> 00:29:55,106 And now, notice if I scroll down further, main's there 702 00:29:55,106 --> 00:29:57,176 and chorus is still there. 703 00:29:57,396 --> 00:30:00,436 So in theory, I have all the building blocks I need, 704 00:30:00,436 --> 00:30:02,786 I've dragged all of my puzzle pieces to the stage. 705 00:30:03,096 --> 00:30:05,226 >> But again, C is not quite as smart as scratch. 706 00:30:05,226 --> 00:30:07,816 C cares about the order in which you do things. 707 00:30:08,156 --> 00:30:12,426 So if I now recompile this thing with make beer4, Enter, 708 00:30:12,426 --> 00:30:14,886 a whole lot of stuff just broke 709 00:30:15,036 --> 00:30:16,696 and this is the most telling line 710 00:30:16,696 --> 00:30:19,076 and you might have seen this yourself over time, 711 00:30:19,366 --> 00:30:22,506 implicit declaration of function, in this case chorus. 712 00:30:22,506 --> 00:30:24,606 Has anyone seen a similarly sounding message, 713 00:30:24,606 --> 00:30:29,786 do you remember what the solution was the past week? 714 00:30:29,786 --> 00:30:29,986 [ Inaudible Answer ] 715 00:30:29,986 --> 00:30:31,016 >> Include? 716 00:30:31,376 --> 00:30:32,566 Include the header file, right? 717 00:30:32,566 --> 00:30:34,516 If you've ever seen this message thus far, 718 00:30:34,516 --> 00:30:37,486 or you see this message in the future, implicit declaration 719 00:30:37,486 --> 00:30:39,536 of function just means you use the function, 720 00:30:39,536 --> 00:30:42,516 in this case chorus but you didn't tell the compiler what it 721 00:30:42,516 --> 00:30:44,916 looks like, what its return value so to speak? 722 00:30:45,116 --> 00:30:46,036 And what's its input? 723 00:30:46,036 --> 00:30:47,566 What's its output and what's its input? 724 00:30:47,856 --> 00:30:51,646 And you kinda did but you told the compiler too late. 725 00:30:51,646 --> 00:30:53,796 You put your function all the way at the bottom of the file 726 00:30:54,006 --> 00:30:57,286 so as soon as the compiler started reading your program top 727 00:30:57,326 --> 00:30:58,416 to bottom, left to right, 728 00:30:58,596 --> 00:31:00,666 it encountered this special new word, Chorus, 729 00:31:00,826 --> 00:31:03,156 but you've never told it that there's a chorus function 730 00:31:03,156 --> 00:31:05,746 in existence before so it throws this error. 731 00:31:06,146 --> 00:31:07,736 So just think intuitively, 732 00:31:07,976 --> 00:31:10,526 what's the quickest fix for this perhaps? 733 00:31:11,726 --> 00:31:13,006 And the answer is not function prototype. 734 00:31:13,006 --> 00:31:13,086 Yeah. 735 00:31:13,086 --> 00:31:15,316 >> Move the [inaudible] when you make the function 736 00:31:16,236 --> 00:31:18,516 up above the main. 737 00:31:18,726 --> 00:31:20,526 >> That sounds perfectly reasonable, right? 738 00:31:20,696 --> 00:31:24,286 So if the problem is, I'm declaring chorus too late, 739 00:31:24,496 --> 00:31:27,376 I'm teaching the compiler about it too late 'cause I'm using it 740 00:31:27,376 --> 00:31:29,496 in main, alright, well let's just relocate it 741 00:31:29,496 --> 00:31:30,666 to the top of my file. 742 00:31:30,876 --> 00:31:33,706 So now, chorus is at the top, main is at the bottom, 743 00:31:33,706 --> 00:31:37,806 let me go ahead and zoom in now and lets redo this, make beer1-- 744 00:31:37,806 --> 00:31:41,296 make beer4 when that actually did fix it. 745 00:31:41,546 --> 00:31:44,176 So that is indeed a very reasonable solution, 746 00:31:44,296 --> 00:31:46,806 but its probably not the best because you can definitely-- 747 00:31:46,806 --> 00:31:49,096 once your programs gets more complex, you can definitely come 748 00:31:49,096 --> 00:31:53,206 up with scenarios where X has to call Y but Y might call X 749 00:31:53,206 --> 00:31:54,426 so you might get into this-- 750 00:31:54,426 --> 00:31:56,156 possibly this circular relationships 751 00:31:56,286 --> 00:31:59,246 where its just impossible to put one above the other logically. 752 00:31:59,556 --> 00:32:03,086 And also it's kind of nice as a matter of good style 753 00:32:03,286 --> 00:32:06,126 to just always put main at the very top of your program. 754 00:32:06,306 --> 00:32:08,146 Because if you open a program that you wrote 755 00:32:08,146 --> 00:32:10,486 or someone else wrote for the very first time, you don't care 756 00:32:10,486 --> 00:32:12,506 about a function called Chorus or anything else, 757 00:32:12,696 --> 00:32:15,146 you wanna see what does this program do, and the answer 758 00:32:15,146 --> 00:32:17,406 to that is almost always gonna lie in main. 759 00:32:17,686 --> 00:32:21,656 So ideally, we wanna leave chorus where it was, below main, 760 00:32:21,876 --> 00:32:24,806 but it turns out the simple solution then is just 761 00:32:24,806 --> 00:32:28,426 to tell the compiler about this function before you actually 762 00:32:28,426 --> 00:32:30,946 implement it an you just can do this with a one-liner. 763 00:32:31,166 --> 00:32:32,666 You specify what its output. 764 00:32:32,666 --> 00:32:34,756 In this case void, what's its name? 765 00:32:34,856 --> 00:32:36,736 Chorus. What's its input? 766 00:32:36,736 --> 00:32:39,246 Int B. So in other words, you literally copy 767 00:32:39,246 --> 00:32:41,956 and paste the first line or two of your function 768 00:32:42,146 --> 00:32:43,686 and just put a semicolon at the end. 769 00:32:43,686 --> 00:32:44,926 You don't do open curly brace. 770 00:32:44,926 --> 00:32:46,116 You don't start writing your function. 771 00:32:46,336 --> 00:32:48,456 You just do this one-liner and notice 772 00:32:48,456 --> 00:32:51,956 that is now identical to what's down here. 773 00:32:52,696 --> 00:32:53,466 Now, why this? 774 00:32:53,796 --> 00:32:55,056 This is just a matter of convention. 775 00:32:55,056 --> 00:32:58,096 It is perfectly legitimate to write your functions all 776 00:32:58,096 --> 00:32:59,776 on one line like this but if you look back 777 00:32:59,776 --> 00:33:00,936 at the CS50 style guide, 778 00:33:01,176 --> 00:33:03,706 you'll see that we discussed why this is actually useful. 779 00:33:03,956 --> 00:33:06,226 Long story short, if you're using a text editor 780 00:33:06,226 --> 00:33:08,876 or like some kind of programming tool and you wanna search 781 00:33:08,946 --> 00:33:11,426 where in your file you've actually implemented a function 782 00:33:11,426 --> 00:33:13,716 like chorus, there are usually little tricks 783 00:33:13,716 --> 00:33:16,526 in the find dialogue to say start searching at the front 784 00:33:16,526 --> 00:33:17,926 of a line, the start of a line. 785 00:33:18,306 --> 00:33:20,506 So the fact that if you adopt this convention 786 00:33:20,506 --> 00:33:22,626 of putting the function name all the way to the left, 787 00:33:22,966 --> 00:33:24,526 it just means you can find it more easily 788 00:33:24,526 --> 00:33:27,156 when your files get big but it's just a convenience, 789 00:33:27,596 --> 00:33:28,626 nothing more than that. 790 00:33:29,456 --> 00:33:30,676 Alright, so we'll come back to some 791 00:33:30,676 --> 00:33:33,936 of these syntactic features, but any questions on the concept 792 00:33:34,026 --> 00:33:37,336 of writing your own function and this notion of declaring it 793 00:33:37,556 --> 00:33:38,806 with the so-called prototype? 794 00:33:38,866 --> 00:33:38,996 Yeah. 795 00:33:39,196 --> 00:33:41,196 [ Inaudible Question ] 796 00:33:41,396 --> 00:33:45,536 >> Good question. 797 00:33:45,756 --> 00:33:48,596 Why do you have to tell the compiler that it does 798 00:33:48,596 --> 00:33:49,926 or doesn't have an output? 799 00:33:49,926 --> 00:33:51,616 Can't you infer that from the code? 800 00:33:52,066 --> 00:33:55,096 You could infer it some of the time but the problem is 801 00:33:55,096 --> 00:33:56,796 that if you just analyze a prog-- 802 00:33:56,796 --> 00:33:59,266 a function that you were in, you could have an if condition, 803 00:33:59,266 --> 00:34:00,526 and else if, and else if, 804 00:34:00,526 --> 00:34:02,406 and it could actually return different things, 805 00:34:02,406 --> 00:34:03,946 maybe not even at all. 806 00:34:04,186 --> 00:34:06,946 And so the idea of proactively telling the compiler, 807 00:34:07,166 --> 00:34:09,876 this will-- no matter what return this data type is a 808 00:34:09,876 --> 00:34:12,876 commitment to then make to adhering to certain conventions. 809 00:34:13,266 --> 00:34:15,506 So in short it-- it improves the probability 810 00:34:15,506 --> 00:34:17,486 of correctness, among other things. 811 00:34:18,636 --> 00:34:19,366 Any other questions? 812 00:34:20,646 --> 00:34:23,826 Alright, so let's try to generalize this a little bit. 813 00:34:23,956 --> 00:34:25,426 So we just wrote a function, 814 00:34:25,426 --> 00:34:27,256 were taught functions have return values. 815 00:34:27,256 --> 00:34:30,786 Return values are just-- it's just the buzz word for output, 816 00:34:31,006 --> 00:34:32,696 but we can run into problems with this. 817 00:34:33,016 --> 00:34:34,396 Again, related to scope. 818 00:34:34,396 --> 00:34:36,216 Let's actually see a more concrete example 819 00:34:36,216 --> 00:34:40,006 where scope kind of breaks things for us with regard 820 00:34:40,006 --> 00:34:42,066 to these things called Local Variables. 821 00:34:42,066 --> 00:34:45,126 So this is a buggy program, this is buggy3 822 00:34:45,466 --> 00:34:47,626 and this is among the source code here, 823 00:34:48,506 --> 00:34:51,046 in lectures two source. 824 00:34:51,536 --> 00:34:54,626 If i open up buggy3, we'll see an attempt 825 00:34:54,786 --> 00:34:57,346 to actually swap two variables. 826 00:34:57,346 --> 00:34:58,646 So let's ignore the top of the file. 827 00:34:58,646 --> 00:35:00,896 Let's just look at main as is generally most useful. 828 00:35:01,146 --> 00:35:04,196 It looks like main declares an int called X assigns it one, 829 00:35:04,306 --> 00:35:06,256 another int called Y assigns it two, 830 00:35:06,566 --> 00:35:08,266 and then it prints out their values. 831 00:35:08,646 --> 00:35:12,076 It then says printing-- sorry, then says swapping dot, dot, 832 00:35:12,076 --> 00:35:15,356 dot, then it calls a function called Swap 833 00:35:15,546 --> 00:35:16,896 who takes two arguments. 834 00:35:17,116 --> 00:35:18,476 So it's a little different syntactically 835 00:35:18,476 --> 00:35:20,216 but you just separate the arguments with commas. 836 00:35:20,506 --> 00:35:22,986 Then it claims on the screen to say, "Swapped, 837 00:35:22,986 --> 00:35:25,646 exclamation point" and then it reprints X and Y. 838 00:35:26,166 --> 00:35:29,196 So this program's pretty simple, at least in terms 839 00:35:29,196 --> 00:35:30,226 of what we've learned thus far. 840 00:35:30,226 --> 00:35:31,626 The only new thing is this use 841 00:35:31,626 --> 00:35:34,116 of apparently a function called Swap which is not built in. 842 00:35:34,316 --> 00:35:35,796 I wrote it elsewhere in the program 843 00:35:36,316 --> 00:35:37,456 so let's see if it works. 844 00:35:38,266 --> 00:35:39,186 It's not going to. 845 00:35:39,496 --> 00:35:41,606 So let's go into lectures to source. 846 00:35:41,606 --> 00:35:46,756 I'm gonna go ahead and compile now, make buggy3, Enter, 847 00:35:47,136 --> 00:35:49,066 so compiles okay, so that's promising. 848 00:35:49,066 --> 00:35:56,006 Now, buggy3, Enter-- X is one, Y is two, swapping, swaps X is 1, 849 00:35:56,006 --> 00:35:58,046 Y is 2, feels like this is definitely broken. 850 00:35:58,486 --> 00:35:59,976 So lets see, maybe I did something stupid 851 00:35:59,976 --> 00:36:01,156 like I left out the prototype. 852 00:36:01,156 --> 00:36:04,486 Well, no, so that's there, I did include the prototype 853 00:36:04,486 --> 00:36:07,396 and I should know that I did this correctly 'cause GCC did 854 00:36:07,396 --> 00:36:09,946 not yell at me with implicit declaration of functions, 855 00:36:09,946 --> 00:36:11,756 so syntactically, this program is right. 856 00:36:12,066 --> 00:36:14,816 Apparently, Swap returns nothing, but it takes an int, 857 00:36:15,066 --> 00:36:17,486 takes another int, and calls them A and B respectively. 858 00:36:17,756 --> 00:36:20,806 So let's now scroll down and see how I implemented this. 859 00:36:21,706 --> 00:36:23,726 Well, it's apparently just three lines of codes, 860 00:36:23,726 --> 00:36:25,356 so swap has no output. 861 00:36:25,816 --> 00:36:28,676 It takes two inputs, A and B, each of them is an int, 862 00:36:29,206 --> 00:36:31,916 and now conceptually, does this sound correct? 863 00:36:32,706 --> 00:36:37,306 So it actually is, so here's one gotcha first, 864 00:36:37,306 --> 00:36:39,106 if you've got a value-- let's call it A, 865 00:36:39,106 --> 00:36:42,236 and another value call it B, how do you swap them? 866 00:36:42,566 --> 00:36:44,376 Well, if you think about it, you-- 867 00:36:44,466 --> 00:36:46,796 you sort of visually, you do this, right? 868 00:36:46,796 --> 00:36:48,456 But you can't quite do that in a computer 869 00:36:48,456 --> 00:36:51,696 because if you say A gets B, and then B gets A, 870 00:36:51,696 --> 00:36:54,626 well what value is in both A and B? 871 00:36:54,626 --> 00:36:55,276 [ Inaudible Answer ] 872 00:36:55,276 --> 00:36:57,306 >> So, it's B, right? 873 00:36:57,306 --> 00:37:00,156 Order of operations if on the first line you put the value 874 00:37:00,156 --> 00:37:04,856 of B in A, and then you put the value of A in B, well that means 875 00:37:04,856 --> 00:37:06,356 that B's value whatever it is, 876 00:37:06,356 --> 00:37:07,786 is now in both of those variables. 877 00:37:08,096 --> 00:37:09,586 So what's the solution? 878 00:37:09,756 --> 00:37:11,866 Well, you introduce, we'll call it Temporary Variable. 879 00:37:11,866 --> 00:37:14,586 Now, usually TMP would be a silly name for a variable 880 00:37:14,586 --> 00:37:16,116 but if it is a temporary variable, 881 00:37:16,116 --> 00:37:17,136 it's quite reasonable here. 882 00:37:17,406 --> 00:37:20,966 So the solution is to remember what A is by storing its value 883 00:37:20,966 --> 00:37:24,566 in an int, then updating the value of A and putting 884 00:37:24,566 --> 00:37:27,306 in it the value of B. And now at this point 885 00:37:27,306 --> 00:37:28,806 in the story, what value is in A? 886 00:37:28,806 --> 00:37:32,906 Well, the value of B. What value's in tmp? 887 00:37:33,456 --> 00:37:39,216 The original value of A and so now we can put inside of B, tmp, 888 00:37:39,656 --> 00:37:42,106 which is equivalent to A. So we just need a third line of code. 889 00:37:42,106 --> 00:37:44,156 Now, as an aside, especially for those of you interested 890 00:37:44,156 --> 00:37:46,696 in Hacker Editions, there actually is a way in C code 891 00:37:46,696 --> 00:37:49,746 to do this where you swap two variables simultaneously 892 00:37:49,746 --> 00:37:51,766 without using any temporary storage phase, 893 00:37:51,766 --> 00:37:53,566 its kind of nice magician's trick but more 894 00:37:53,566 --> 00:37:54,586 on that perhaps next week. 895 00:37:54,666 --> 00:37:57,896 But for now, this code feels correct, right? 896 00:37:57,896 --> 00:38:00,756 I've got A and B. I put A in a temporary variable. 897 00:38:00,756 --> 00:38:05,186 I changed B-- I put B in A, and then I put this guy here, right? 898 00:38:05,186 --> 00:38:07,306 So that logically feels correct and in fact 899 00:38:07,746 --> 00:38:10,746 at the very last line here where my cursor currently is, 900 00:38:10,746 --> 00:38:13,786 A and B have, yes, been swapped. 901 00:38:14,146 --> 00:38:17,336 But we just saw, when I run this program that X 902 00:38:17,336 --> 00:38:19,946 and Y are not swapped even though I'm passing X 903 00:38:19,946 --> 00:38:21,106 and Y to this function. 904 00:38:21,586 --> 00:38:22,996 So where do things break? 905 00:38:23,106 --> 00:38:26,076 >> Yeah, in back. 906 00:38:27,596 --> 00:38:28,206 Oh, sure, you. 907 00:38:28,206 --> 00:38:29,176 [ Inaudible Answer ] 908 00:38:29,176 --> 00:38:36,296 >> Okay, so it's not assigning the answers back 909 00:38:36,296 --> 00:38:38,946 out of the function somehow, okay, and so that's true, 910 00:38:38,946 --> 00:38:41,076 and what other point can be made too here? 911 00:38:41,076 --> 00:38:41,686 Yeah. 912 00:38:42,516 --> 00:38:47,766 [ Inaudible Answer ] 913 00:38:48,266 --> 00:38:50,706 >> Okay, so maybe the values X and Y are getting messed 914 00:38:50,706 --> 00:38:52,256 up in some way when being passed in. 915 00:38:52,256 --> 00:38:54,796 So messed up isn't quite what I'd say but there is another-- 916 00:38:55,116 --> 00:38:57,586 there's a verb here that would apply, they're being copied 917 00:38:57,946 --> 00:38:59,756 into the swap function. 918 00:38:59,756 --> 00:39:01,436 So recall earlier and I said it briefly 919 00:39:01,436 --> 00:39:04,566 in our previous beer example that when you call a function, 920 00:39:04,566 --> 00:39:07,426 and you just specify the input with a variable name, 921 00:39:07,736 --> 00:39:10,326 you get the value but you get a copy of that value. 922 00:39:10,556 --> 00:39:13,636 So at this moment in time when this program is executing, 923 00:39:13,786 --> 00:39:15,816 there are now four variables-- 924 00:39:15,856 --> 00:39:18,186 actually five variables in existence 925 00:39:18,186 --> 00:39:19,306 in this program right now. 926 00:39:19,506 --> 00:39:22,986 There's X and Y, and those live inside of main, there's also A 927 00:39:22,986 --> 00:39:26,986 and B, and also tmp, T-M-P. 928 00:39:26,986 --> 00:39:30,286 So five separate integers, that's five separate chunks 929 00:39:30,286 --> 00:39:32,446 of 32 bits somewhere in the computer's memory, 930 00:39:32,736 --> 00:39:35,836 and inside of X is the number one apparently if you think back 931 00:39:35,836 --> 00:39:37,066 to the-- how we started. 932 00:39:37,066 --> 00:39:38,876 So inside of X is the number one. 933 00:39:39,206 --> 00:39:41,896 Inside of-- what other variable is also apparently the number 934 00:39:41,896 --> 00:39:45,576 one-- initially-- before swap executes. 935 00:39:46,556 --> 00:39:49,516 So also, the number one, Y has the value two, 936 00:39:49,516 --> 00:39:52,306 as soon as we call Swap, B has the value 2, 937 00:39:52,596 --> 00:39:56,126 but then when you finish executing swap before it 938 00:39:56,126 --> 00:39:59,076 actually finishes, so if we get conceptually right 939 00:39:59,076 --> 00:40:02,316 to where my cursor is here before its all done, X is one, 940 00:40:02,436 --> 00:40:08,596 Y is two, A is two and B is one. 941 00:40:09,296 --> 00:40:11,996 >> The problem is that the-- your goal is to swap X and Y, 942 00:40:12,036 --> 00:40:14,886 and all we've done is swap A and B. So it seems 943 00:40:14,886 --> 00:40:18,436 to be a fundamental problem that when you pass inputs 944 00:40:18,436 --> 00:40:21,626 to a function, you're actually passing copies of them in. 945 00:40:21,626 --> 00:40:24,306 Ad the buzz word here is you're passing them by value. 946 00:40:24,606 --> 00:40:26,626 Now, those of you with prior programming backgrounds know 947 00:40:26,626 --> 00:40:28,676 that in Java, you actually don't run into this at least 948 00:40:28,676 --> 00:40:30,756 if you're using objects and we can fix this 949 00:40:30,756 --> 00:40:33,586 in C. Fast forwarding to a couple weeks from now, 950 00:40:33,586 --> 00:40:35,616 we'll introduce the notion of pointers 951 00:40:35,616 --> 00:40:36,866 and low level memory addresses. 952 00:40:36,896 --> 00:40:39,476 But for now, let's just assume we've run up against the wall. 953 00:40:39,696 --> 00:40:42,446 Right now, when you have what are called Local Variables, 954 00:40:42,696 --> 00:40:45,766 which X and Y are, anytime you have a variable inside 955 00:40:45,766 --> 00:40:47,856 of a function, its called a Local Variable, 956 00:40:47,856 --> 00:40:49,656 its kind of for self-explanatory reasons, 957 00:40:49,656 --> 00:40:51,246 its local to that function. 958 00:40:51,846 --> 00:40:55,936 That function cannot-- that variable cannot be accessed 959 00:40:55,936 --> 00:40:58,586 in some other function because A and B, meanwhile, 960 00:40:58,786 --> 00:41:00,836 we keep calling them arguments or parameters, 961 00:41:01,016 --> 00:41:02,926 but they're also just local variables. 962 00:41:03,176 --> 00:41:05,136 They exist only inside of swap. 963 00:41:05,376 --> 00:41:07,996 So at this point then, there's two variables in main, 964 00:41:07,996 --> 00:41:10,256 there's three in swap, and those guys, 965 00:41:10,256 --> 00:41:12,016 even though they might share some values, 966 00:41:12,206 --> 00:41:14,086 they're copies of those values. 967 00:41:14,306 --> 00:41:16,536 And we can actually see this as follows. 968 00:41:16,536 --> 00:41:20,566 So this is a little picture that we might paint 969 00:41:20,676 --> 00:41:21,696 of a computer's memory. 970 00:41:21,696 --> 00:41:23,316 So if you think about now your own computer, 971 00:41:23,316 --> 00:41:26,046 you've got like a gigabyte of RAM, 2 gigabytes, 4 gigabytes, 972 00:41:26,046 --> 00:41:29,066 something like that, let's just assume that your RAM looks 973 00:41:29,066 --> 00:41:32,366 like a rectangle and RAM is, again, 1 gigabyte, 2, 974 00:41:32,426 --> 00:41:34,816 4 gigabytes, and bytes is the keyword there. 975 00:41:34,976 --> 00:41:37,956 If you have a total number of something, you can now-- 976 00:41:37,956 --> 00:41:40,966 you can number those things, so this thing at the bottom left, 977 00:41:41,226 --> 00:41:44,096 this might be byte number zero, if I move my hand over a little, 978 00:41:44,096 --> 00:41:46,846 that's byte1, byte 2, byte 3, byte 4, 979 00:41:47,016 --> 00:41:49,776 then I go up to the next road, that's byte 5, 6, 7, and 8. 980 00:41:49,776 --> 00:41:53,166 In short, we could assign like a billion unique numbers 981 00:41:53,166 --> 00:41:56,346 to every little square portion of this picture 982 00:41:56,346 --> 00:41:58,886 if this whole rectangle represents my computer's memory. 983 00:41:59,276 --> 00:42:01,896 So what happens when you actually run a program? 984 00:42:02,116 --> 00:42:03,446 Well, when you run a program, 985 00:42:03,766 --> 00:42:05,206 what function gets executed by default? 986 00:42:06,446 --> 00:42:07,506 Just main, right? 987 00:42:07,506 --> 00:42:09,086 So main gets executed by default, 988 00:42:09,356 --> 00:42:12,386 main might have some local variables, where do they end up? 989 00:42:12,696 --> 00:42:14,646 They end up at the very beginning 990 00:42:14,646 --> 00:42:16,266 of your computer's memory, lets say. 991 00:42:16,586 --> 00:42:18,556 There's a little bit of a simplification, but they'll end 992 00:42:18,556 --> 00:42:22,576 up at the bottom left hand corner there, inside of the-- 993 00:42:22,576 --> 00:42:23,906 the rows labeled main. 994 00:42:24,356 --> 00:42:26,926 Now, main can take arguments. 995 00:42:27,346 --> 00:42:29,576 Thus far, we've been writing int main void. 996 00:42:29,576 --> 00:42:31,936 So right now, there actually are no inputs to main 997 00:42:31,936 --> 00:42:34,986 but we'll get there, main's locals means all 998 00:42:34,986 --> 00:42:36,996 of main's local variables might end up there. 999 00:42:36,996 --> 00:42:40,376 But what if main calls a function like printf, or getint, 1000 00:42:40,376 --> 00:42:43,636 or in this case swap, where does it end up? 1001 00:42:44,006 --> 00:42:47,806 Well, where to swap and all of its local variables end up? 1002 00:42:47,806 --> 00:42:50,866 One layer higher, literally, in RAM, if something starts here, 1003 00:42:50,866 --> 00:42:52,286 the next function ends up here, 1004 00:42:52,366 --> 00:42:54,586 the next function's variables end up here, and here, 1005 00:42:54,586 --> 00:42:55,896 and here, and here, and here. 1006 00:42:56,076 --> 00:42:58,596 So where we say Foo, and foo incidentally is like, 1007 00:42:58,926 --> 00:43:01,666 a mathematician might say XYZ, computer scientist say, "foo, 1008 00:43:01,666 --> 00:43:04,106 bar, baz, quux" and then there's some other crazy words, 1009 00:43:04,336 --> 00:43:05,896 just when you need a verbal placeholder, 1010 00:43:06,116 --> 00:43:08,596 foo is local variables end up on top of mains. 1011 00:43:08,596 --> 00:43:09,076 And guess what? 1012 00:43:09,076 --> 00:43:11,866 If foo calls its own function, where does it end up? 1013 00:43:12,556 --> 00:43:14,986 In memory here, and here, and here. 1014 00:43:15,396 --> 00:43:16,606 So again, if one of today's 1015 00:43:16,606 --> 00:43:18,796 and next week's themes are security turns 1016 00:43:18,796 --> 00:43:20,506 out that this is actually a brilliant way 1017 00:43:20,506 --> 00:43:21,626 of hacking a computer. 1018 00:43:21,836 --> 00:43:24,646 If you have the ability to call a function 1019 00:43:24,926 --> 00:43:26,566 that calls a function, that calls a function, 1020 00:43:26,566 --> 00:43:28,836 that calls a function, if you do this enough times, 1021 00:43:28,836 --> 00:43:31,786 you can actually start to change the contents 1022 00:43:31,786 --> 00:43:34,816 of a computer's memory potentially in dangerous places. 1023 00:43:34,816 --> 00:43:36,526 And so if you ever heard of a-- 1024 00:43:36,526 --> 00:43:40,456 a word like a buffer overflow exploits or more generally, 1025 00:43:40,456 --> 00:43:42,656 a website being hacked, to this day, 1026 00:43:42,656 --> 00:43:46,126 it is still incredibly common to hack into computers 1027 00:43:46,376 --> 00:43:49,406 by passing them bigger strings or bigger numbers 1028 00:43:49,626 --> 00:43:50,776 than they were expecting. 1029 00:43:50,816 --> 00:43:54,476 And what happens is those strings or numbers start filling 1030 00:43:54,476 --> 00:43:56,756 up space in your computer's RAM at the bottom left. 1031 00:43:57,086 --> 00:44:00,186 But it gets so big that it overwrites something important. 1032 00:44:00,186 --> 00:44:01,406 And for today's purposes, 1033 00:44:01,406 --> 00:44:03,906 that's bad because if you overwrite something important, 1034 00:44:04,116 --> 00:44:05,486 you can actually trick the computer 1035 00:44:05,486 --> 00:44:09,056 into executing almost anything you want, but it derives 1036 00:44:09,056 --> 00:44:10,106 from this problem here. 1037 00:44:10,406 --> 00:44:13,596 So just to hammer this home, who cares about these rectangles 1038 00:44:13,596 --> 00:44:14,636 and this depiction of memory? 1039 00:44:15,226 --> 00:44:18,866 Pictorially now, if you have X and Y, and they live inside 1040 00:44:18,866 --> 00:44:22,726 of main, just graphically, they are not accessible to foo 1041 00:44:22,726 --> 00:44:24,376 and vice versa because they're ending 1042 00:44:24,376 --> 00:44:26,816 up in different locations in memory. 1043 00:44:27,456 --> 00:44:31,696 So let's actually go back here and try fixing this. 1044 00:44:32,216 --> 00:44:33,816 So I could fix this 1045 00:44:34,236 --> 00:44:37,776 by introducing not a local variable, but a global variable, 1046 00:44:38,126 --> 00:44:39,766 so let's scroll down here. 1047 00:44:40,126 --> 00:44:43,346 The only thing different now in this version of swap is 1048 00:44:43,346 --> 00:44:47,206 that I'm actually going to-- sorry, not of swap, 1049 00:44:47,206 --> 00:44:48,636 in this program, I'm gonna try 1050 00:44:48,636 --> 00:44:50,076 to solve this problem in this way. 1051 00:44:50,646 --> 00:44:54,416 So lets scroll down here and lets simplify this rather 1052 00:44:54,416 --> 00:44:57,856 than involve 2 variables, X and Y and swap, lets simplify. 1053 00:44:58,116 --> 00:45:00,856 Let's instead change the story to a function called Increment, 1054 00:45:01,156 --> 00:45:05,196 and increment's purpose in life is just to increment a variable. 1055 00:45:06,106 --> 00:45:10,376 So let's do-- let me change this real fast. 1056 00:45:10,656 --> 00:45:12,206 Let me break this and then we'll fix this. 1057 00:45:13,996 --> 00:45:18,006 So look at main here, I've got an int X gets 1, 1058 00:45:18,296 --> 00:45:21,016 I then claim initialize, 'cause I've initialized it to one. 1059 00:45:21,296 --> 00:45:24,436 X is now one incrementing dot, dot, dot, 1060 00:45:24,436 --> 00:45:27,566 I call the increment function not even passing 1061 00:45:27,566 --> 00:45:32,096 in a value here, incremented and then I claim at some new value. 1062 00:45:32,386 --> 00:45:34,966 So if I look now at increment and I try to do this, 1063 00:45:36,156 --> 00:45:38,636 will this work or not work? 1064 00:45:40,256 --> 00:45:41,766 So no, and what's the short answer? 1065 00:45:41,766 --> 00:45:44,826 I'm trying to do X plus plus inside of increment, but-- 1066 00:45:44,826 --> 00:45:46,726 [ Inaudible Remark ] 1067 00:45:46,726 --> 00:45:49,026 >> So it's a void function which means it has no output, 1068 00:45:49,026 --> 00:45:51,536 it doesn't return anything but more were recently, 1069 00:45:51,946 --> 00:45:53,196 what else is also buggy here? 1070 00:45:53,196 --> 00:45:53,336 Yeah. 1071 00:45:53,336 --> 00:45:53,403 [ Inaudible Remark ] 1072 00:45:53,403 --> 00:45:53,956 >> Exactly. 1073 00:45:54,486 --> 00:46:00,516 X-- this X was not declared inside of increment, 1074 00:46:00,516 --> 00:46:03,146 it was declared inside of main 1075 00:46:03,366 --> 00:46:04,886 which means you don't have the right 1076 00:46:04,886 --> 00:46:07,476 to actually do plus plus here and you can't even compile this. 1077 00:46:07,476 --> 00:46:09,756 If we were on make on this, it will just yell at us 1078 00:46:09,756 --> 00:46:12,536 that X is not initialized because it's not in scope. 1079 00:46:13,176 --> 00:46:14,436 So how can we fix this? 1080 00:46:14,856 --> 00:46:15,586 Well, you know what? 1081 00:46:15,706 --> 00:46:18,846 Rather than make X local, let me try another little trick 1082 00:46:19,046 --> 00:46:22,986 and scroll up here and let me actually declare my int outside 1083 00:46:22,986 --> 00:46:23,926 of this whole program. 1084 00:46:23,926 --> 00:46:27,046 And if I declare the int X at the very top here, 1085 00:46:27,356 --> 00:46:30,056 now there are actually aren't curly braces anymore 'cause I'm 1086 00:46:30,266 --> 00:46:33,046 outside the huge made file, but is X-- 1087 00:46:33,126 --> 00:46:35,876 do you think in scope or not in scope now with regard 1088 00:46:35,876 --> 00:46:38,896 to the rest of this file and all of its functions? 1089 00:46:40,156 --> 00:46:41,476 So it actually is in scope. 1090 00:46:41,476 --> 00:46:44,086 So just as before where the quick fix was just copy 1091 00:46:44,086 --> 00:46:46,576 and paste or who you-- whole function put it at the very top, 1092 00:46:46,996 --> 00:46:48,786 here too, we can kind of fix this 1093 00:46:49,006 --> 00:46:52,126 by just putting our variables at the very top of our program 1094 00:46:52,126 --> 00:46:55,476 and now both main and increment 1095 00:46:55,476 --> 00:46:58,166 and any other function here can execute them. 1096 00:46:59,056 --> 00:47:00,746 Alright, is this a good thing, bad thing? 1097 00:47:00,886 --> 00:47:03,336 In this case, it actually solves the problem very reasonably 1098 00:47:03,336 --> 00:47:04,436 and it gets the job done. 1099 00:47:04,856 --> 00:47:06,796 But what's maybe a downside 1100 00:47:06,796 --> 00:47:08,776 of these things now called Global Variables. 1101 00:47:08,776 --> 00:47:10,746 Global in the sense that they're not inside of functions, 1102 00:47:10,816 --> 00:47:11,866 they're inside of files. 1103 00:47:12,856 --> 00:47:17,926 Someone about over here, any-- alright, over here, there we go. 1104 00:47:18,516 --> 00:47:25,586 [ Inaudible Question ] 1105 00:47:26,086 --> 00:47:29,496 >> Good. Yeah, so if you start thinking ahead 1106 00:47:29,496 --> 00:47:30,916 and granted this is a little hard to do 1107 00:47:30,916 --> 00:47:33,206 when we're just implementing pennies this far right now 1108 00:47:33,206 --> 00:47:35,646 and similarly short programs realize 1109 00:47:35,646 --> 00:47:36,776 that this is also a solution 1110 00:47:36,776 --> 00:47:38,646 that really doesn't scale very well. 1111 00:47:38,646 --> 00:47:41,246 One, before long, we'll be writing more sophisticated 1112 00:47:41,246 --> 00:47:43,676 programs that have more variables than just one. 1113 00:47:43,946 --> 00:47:45,736 and so again, as a matter of good design, 1114 00:47:45,736 --> 00:47:48,476 if you just start plopping all of your variables at the top 1115 00:47:48,476 --> 00:47:51,856 of your file as globals, you totally defeat the purpose 1116 00:47:52,006 --> 00:47:54,736 of trying to declare your variables as close as possible 1117 00:47:54,736 --> 00:47:57,356 to where you actually use them which lends themselves 1118 00:47:57,356 --> 00:47:59,066 to readability and its just easier 1119 00:47:59,066 --> 00:48:00,566 to understand what your program is doing 1120 00:48:00,716 --> 00:48:04,316 if you do everything really only when you want to use something. 1121 00:48:04,546 --> 00:48:06,316 If you're just littering the top of your file 1122 00:48:06,316 --> 00:48:07,326 with these global variables, 1123 00:48:07,616 --> 00:48:09,516 long story short this does not scale well. 1124 00:48:09,516 --> 00:48:12,046 And in fact, once you start using other people's code, 1125 00:48:12,046 --> 00:48:15,386 libraries or API's like I referred to a week or so ago, 1126 00:48:15,596 --> 00:48:18,926 things like even CS50s data APIs for course catalog data 1127 00:48:18,986 --> 00:48:22,256 and shuttle data and dining hall data and the like. 1128 00:48:22,496 --> 00:48:24,926 Once you start using code that other people have written, 1129 00:48:25,196 --> 00:48:27,296 my god, what if you use a variable called X 1130 00:48:27,296 --> 00:48:30,746 and that other person uses a variable called X, right? 1131 00:48:30,746 --> 00:48:32,496 What if the person who implemented printf 1132 00:48:33,036 --> 00:48:37,116 in a file called standard IO.h, and another file standard IO.C, 1133 00:48:37,276 --> 00:48:39,856 what if he or she also decided that he 1134 00:48:39,856 --> 00:48:41,666 or she needed a variable called X? 1135 00:48:41,906 --> 00:48:44,076 So he or she put X at the top of their file, 1136 00:48:44,346 --> 00:48:46,356 now you have collisions and this suggest 1137 00:48:46,486 --> 00:48:48,856 that now you can't even use the variable X 1138 00:48:49,126 --> 00:48:50,156 if you wanna use printf. 1139 00:48:50,556 --> 00:48:54,066 So again, long story short, putting stuff at the very top 1140 00:48:54,066 --> 00:48:56,856 of your file in terms of variables tends not 1141 00:48:56,936 --> 00:49:00,236 to be the right solution, so they exist and we'll see cases 1142 00:49:00,236 --> 00:49:01,746 where global variables are compelling 1143 00:49:02,056 --> 00:49:05,686 but thus far this is not, in fact, the right solution. 1144 00:49:06,196 --> 00:49:08,316 Well, lets see if we can now completely abuse some 1145 00:49:08,316 --> 00:49:10,736 of these ideas and see what bad things can happen. 1146 00:49:11,086 --> 00:49:13,496 So I'm gonna go ahead and save this as-- 1147 00:49:13,556 --> 00:49:18,426 lets say, "bad.c" and I'm gonna go ahead and zoom in here. 1148 00:49:18,686 --> 00:49:22,516 I'm gonna do something like include, lets say, standard IO.h 1149 00:49:22,516 --> 00:49:25,256 and I'm gonna have int main void. 1150 00:49:25,476 --> 00:49:27,306 And then here I'm gonna do something, 1151 00:49:27,306 --> 00:49:28,076 I don't know what yet. 1152 00:49:28,476 --> 00:49:34,106 I'm gonna then have a function called void bad can be the same 1153 00:49:34,106 --> 00:49:34,846 thing as the file. 1154 00:49:34,946 --> 00:49:38,566 Is it gonna take any input? 1155 00:49:38,566 --> 00:49:41,866 No, not even gonna take any input, so I'll say void 1156 00:49:41,866 --> 00:49:43,176 but I could have a take input. 1157 00:49:43,606 --> 00:49:47,526 And now here, I'm gonna say, "printf-- " oh, you know what? 1158 00:49:47,526 --> 00:49:48,586 I will have a take input. 1159 00:49:48,866 --> 00:49:51,796 Lets have a take an integer N and what I'm gonna have it print 1160 00:49:51,796 --> 00:49:55,456 out is that value of N followed by a new line character 1161 00:49:56,086 --> 00:49:58,746 with percent D. So all this function does 1162 00:49:58,746 --> 00:50:01,326 and doesn't seem all that bad thus far, all it does it prints 1163 00:50:01,326 --> 00:50:03,976 out the value of its argument. 1164 00:50:04,566 --> 00:50:05,476 >> So how do I call this? 1165 00:50:05,476 --> 00:50:10,166 Well, let's do int N gets-- let's say, zero, 1166 00:50:10,556 --> 00:50:14,456 lets call bad of N and that's it. 1167 00:50:14,986 --> 00:50:17,446 So what will this program print when I run it? 1168 00:50:17,446 --> 00:50:18,896 [ Inaudible Answers ] 1169 00:50:18,896 --> 00:50:20,726 >> So I think it will just print zero, right? 1170 00:50:20,726 --> 00:50:22,546 Quick-- super quick sanity check, 1171 00:50:23,086 --> 00:50:25,726 so if I do make bad-- oh my god! 1172 00:50:25,776 --> 00:50:26,406 So many mistakes. 1173 00:50:26,406 --> 00:50:26,756 [ Inaudible Remarks ] 1174 00:50:26,756 --> 00:50:28,406 >> Alright, good. 1175 00:50:29,546 --> 00:50:31,386 So when you see lots of mistakes, 1176 00:50:31,386 --> 00:50:33,476 just listen to everyone-- they'll be yelling at you 1177 00:50:33,476 --> 00:50:35,456 and fix it this way, so it double quotes, 1178 00:50:35,596 --> 00:50:36,936 hopefully that's fixed now-- 1179 00:50:36,936 --> 00:50:39,836 okay, no, what did I do wrong still? 1180 00:50:39,846 --> 00:50:41,846 [ Inaudible Answer ] 1181 00:50:41,856 --> 00:50:43,136 >> Yeah, exactly. 1182 00:50:43,136 --> 00:50:46,806 I simply haven't declared bad, so fix one could be move it 1183 00:50:46,806 --> 00:50:49,606 to the top of the file but again better practice is leave main 1184 00:50:49,606 --> 00:50:51,386 at the top, and instead, what do I type 1185 00:50:51,386 --> 00:50:52,516 at the very top of the file? 1186 00:50:52,516 --> 00:50:54,096 [ Inaudible Answers ] 1187 00:50:54,096 --> 00:50:57,956 >> Void bad int and the same thing but semicolon, alright? 1188 00:50:57,956 --> 00:50:59,186 So now let's see if I fixed this. 1189 00:50:59,186 --> 00:51:01,316 Let me go back to the bottom, I'll zoom in at the bottom. 1190 00:51:01,656 --> 00:51:06,376 Let me rerun make bad, okay, that's good-- bad, okay. 1191 00:51:06,376 --> 00:51:07,006 So we're on our way. 1192 00:51:07,236 --> 00:51:10,626 Not an interesting program, but now suppose you do this, 1193 00:51:10,946 --> 00:51:12,626 interesting thing here is 1194 00:51:12,626 --> 00:51:14,886 that main is calling bad but that's it. 1195 00:51:15,276 --> 00:51:18,296 I could really create an interesting quandary here 1196 00:51:18,296 --> 00:51:19,636 and perhaps send a message of-- 1197 00:51:19,636 --> 00:51:20,996 along the lines of, "don't do this". 1198 00:51:21,476 --> 00:51:28,166 If I did something like this, what if I did bad in here 1199 00:51:28,646 --> 00:51:35,896 and I'd passed in first N gets N plus 1, or keep it simple, 1200 00:51:35,936 --> 00:51:38,736 N plus plus and passing bad here. 1201 00:51:39,326 --> 00:51:40,296 So, what's gonna happen? 1202 00:51:40,296 --> 00:51:42,116 This should hopefully start messing with your minds, 1203 00:51:42,116 --> 00:51:45,606 so main gets called, we initialize N to zero, 1204 00:51:46,306 --> 00:51:48,296 we then pass that into Bad. 1205 00:51:48,416 --> 00:51:51,396 Now, quick sanity check, is this a coincidence or necessary 1206 00:51:51,396 --> 00:51:55,376 that I also call the input to bad N? 1207 00:51:55,376 --> 00:51:56,626 [ Inaudible Answers ] 1208 00:51:56,626 --> 00:51:57,566 >> So it's not necessary, 1209 00:51:57,566 --> 00:51:59,146 this is actually just a coincidence, why? 1210 00:51:59,406 --> 00:52:01,376 This is actually maybe confusing so I'll change it, 1211 00:52:01,376 --> 00:52:03,926 let me change it to I, then I'll change this to I, 1212 00:52:04,056 --> 00:52:06,786 and I'll change this to I because again I 1213 00:52:06,876 --> 00:52:09,996 or whatever I call it is gonna be a copy of N. 1214 00:52:10,506 --> 00:52:12,736 But it doesn't matter if their named the same 'cause they're 1215 00:52:12,736 --> 00:52:15,316 in different scope so you can reuse names of variables 1216 00:52:15,376 --> 00:52:16,496 if you want in this way. 1217 00:52:16,876 --> 00:52:20,826 So okay, so main initializes N to zero, passes in zero to bad, 1218 00:52:21,136 --> 00:52:24,866 bad takes as input that value zero, and it prints out zero, 1219 00:52:25,136 --> 00:52:28,196 then I gets incremented from zero to one 1220 00:52:28,276 --> 00:52:31,686 and then bad gets called with what input? 1221 00:52:31,686 --> 00:52:31,753 [ Inaudible Answer ] 1222 00:52:31,753 --> 00:52:33,396 >> One. So what happens next? 1223 00:52:33,396 --> 00:52:36,406 We don't go back to main yet, instead bad gets called again. 1224 00:52:36,586 --> 00:52:38,356 So if you're kind of thinking through this linearly, 1225 00:52:38,506 --> 00:52:40,846 we're chugging along here, here, here, here, 1226 00:52:41,006 --> 00:52:44,076 then we do this again, and call bad again. 1227 00:52:44,336 --> 00:52:47,536 So at this point, bad takes as input one, prints out one 1228 00:52:47,786 --> 00:52:48,866 and then does what to I? 1229 00:52:49,756 --> 00:52:54,036 Plus plus, so it becomes two, then bad prints out two, 1230 00:52:54,036 --> 00:52:55,756 and then three, and then four 1231 00:52:55,756 --> 00:52:58,266 and why is this kind of a problem? 1232 00:52:58,266 --> 00:52:59,476 [ Inaudible Answers ] 1233 00:52:59,476 --> 00:53:00,816 >> Right, so it never stops, right? 1234 00:53:00,816 --> 00:53:02,096 And you might have done this accidentally 1235 00:53:02,096 --> 00:53:04,866 with infinite loops already and that's kind of bad 1236 00:53:04,866 --> 00:53:05,836 if you have an infinite loop 1237 00:53:05,836 --> 00:53:07,846 that never stops 'cause you messed up your condition. 1238 00:53:08,136 --> 00:53:10,106 But now if you think about what's going on inside 1239 00:53:10,106 --> 00:53:12,556 of the computer's memory, its kind of worse 1240 00:53:12,756 --> 00:53:14,406 when every time you call a function, 1241 00:53:14,446 --> 00:53:16,946 it turns out its using some amount of memory. 1242 00:53:17,176 --> 00:53:18,686 In fact, its using, lets say a-- 1243 00:53:18,686 --> 00:53:21,256 a slivers worth of RAM in your computer, 1244 00:53:21,436 --> 00:53:23,916 but every time you call a function, it goes on top 1245 00:53:23,916 --> 00:53:25,396 of the previous function that was called, 1246 00:53:25,396 --> 00:53:26,796 on top, on top, on top. 1247 00:53:27,026 --> 00:53:30,776 So even though bad is the same thing, every time you call it, 1248 00:53:30,776 --> 00:53:32,296 you get a distinct sliver 1249 00:53:32,296 --> 00:53:34,276 of memory again and again and again. 1250 00:53:34,276 --> 00:53:35,726 And so if you kind of think through this, 1251 00:53:35,726 --> 00:53:38,086 if you do this infinitely long, what's gonna happen? 1252 00:53:38,856 --> 00:53:41,566 Well, you're gonna overflow your computer's RAM 1253 00:53:41,566 --> 00:53:43,146 and this is just the bottom of your RAM. 1254 00:53:43,146 --> 00:53:45,686 If we actually redraw this and actually acknowledge 1255 00:53:45,686 --> 00:53:47,486 that you only have a finite amount of memory, 1256 00:53:47,486 --> 00:53:49,046 you've got a gigabyte or 2 gigabytes, 1257 00:53:49,046 --> 00:53:50,796 you do not have an infinite amount of RAM. 1258 00:53:51,156 --> 00:53:54,086 Well, there's gotta be something, probably the very top 1259 00:53:54,086 --> 00:53:55,786 of that and indeed there is. 1260 00:53:55,836 --> 00:53:58,556 If you think again about your computer's memory 1261 00:53:58,556 --> 00:54:00,866 as this big rectangle, the thing 1262 00:54:00,866 --> 00:54:02,356 at the bottom now were called the Stack. 1263 00:54:02,606 --> 00:54:05,136 Every time you call a function, you just keep stacking more 1264 00:54:05,136 --> 00:54:08,556 and more memory on top of the stack but it turns 1265 00:54:08,556 --> 00:54:10,676 out at the very top of your computer's memory, 1266 00:54:11,046 --> 00:54:12,686 there's what's called the Text Segment. 1267 00:54:12,686 --> 00:54:15,506 And text is just a fancy way of saying, that's the zeroes 1268 00:54:15,506 --> 00:54:18,616 and ones that represent your actual compiled program. 1269 00:54:18,816 --> 00:54:20,686 In order for them to run when you double click them 1270 00:54:20,686 --> 00:54:23,436 or type their command at the prompt, they get loaded 1271 00:54:23,436 --> 00:54:27,186 into memory, so if nothing else your own program is somewhere 1272 00:54:27,186 --> 00:54:29,996 there in RAM and if you keep calling bad, bad, bad, bad, bad, 1273 00:54:29,996 --> 00:54:31,166 bad, what's gonna happen? 1274 00:54:32,336 --> 00:54:36,066 You're gonna literally overwrite other stuff with the zeroes 1275 00:54:36,066 --> 00:54:39,606 and ones that represents bad's stack frame, 1276 00:54:39,676 --> 00:54:40,706 its local variables. 1277 00:54:40,706 --> 00:54:43,706 He only has one local variable, I, and that's 32 bits. 1278 00:54:43,706 --> 00:54:46,456 So frankly, this is gonna take awhile to get all the way 1279 00:54:46,456 --> 00:54:49,316 up to the very top if we're only doing it 32 bits at a time, 1280 00:54:49,576 --> 00:54:50,656 but if we're doing it infinitely, 1281 00:54:50,656 --> 00:54:52,266 we'll get there eventually 1282 00:54:52,506 --> 00:54:54,516 and you're gonna start overwriting potentially 1283 00:54:54,516 --> 00:54:58,176 important stuff and this isn't quite how a bad guy would do it 1284 00:54:58,176 --> 00:55:02,576 but its the same idea whereby you can then change what code is 1285 00:55:02,576 --> 00:55:04,876 inside your own program and trick the program 1286 00:55:05,116 --> 00:55:06,606 into actually chugging something bad 1287 00:55:06,606 --> 00:55:08,726 like disable the serial number of prompt, 1288 00:55:08,726 --> 00:55:12,186 or disable the password prompt, or give me administrator access. 1289 00:55:12,516 --> 00:55:13,346 So I've compiled-- 1290 00:55:13,346 --> 00:55:14,536 let's recompile this now 1291 00:55:14,536 --> 00:55:17,956 that I've introduced this infinite loop by of calling bad, 1292 00:55:18,006 --> 00:55:21,066 bad, bad, bad, bad, and run this. 1293 00:55:21,706 --> 00:55:24,186 And lets go ahead, went a little long, 1294 00:55:24,186 --> 00:55:26,276 but lets take our two-minute break now, leave this up 1295 00:55:26,276 --> 00:55:27,926 and running and we'll come back and see 1296 00:55:27,986 --> 00:55:30,526 if this is actually broken, no, okay, breaks over. 1297 00:55:30,906 --> 00:55:32,526 No, lets still take our two-minute break then we'll 1298 00:55:32,526 --> 00:55:36,426 come back. 1299 00:55:36,426 --> 00:55:36,493 [ Pause ] 1300 00:55:36,493 --> 00:55:38,806 >> So in short, a couple take aways thus far, 1301 00:55:38,906 --> 00:55:41,046 so we implemented the capability 1302 00:55:41,286 --> 00:55:44,226 of implementing our own functions and syntactically, 1303 00:55:44,226 --> 00:55:46,686 it's really no different from using main, using getint 1304 00:55:46,686 --> 00:55:48,666 and the like, but we did see one, gotcha, 1305 00:55:49,286 --> 00:55:51,446 whereby if you use a function you wrote 1306 00:55:51,446 --> 00:55:54,256 and that function's written at the bottom or just elsewhere 1307 00:55:54,256 --> 00:55:56,816 in your file, you do have to declare it so to speak 1308 00:55:56,816 --> 00:56:00,086 at the very top and the jargon there is you give it a function 1309 00:56:00,086 --> 00:56:02,706 prototype, you declare it at the very top 1310 00:56:02,706 --> 00:56:04,776 of your file ending it with a semicolon. 1311 00:56:05,056 --> 00:56:07,476 So then we looked at again this issue of scope. 1312 00:56:07,476 --> 00:56:11,186 An issue of scope refers to where variables can be used 1313 00:56:11,186 --> 00:56:14,006 and cannot be used, and if you declare a variable inside 1314 00:56:14,006 --> 00:56:16,486 of a function, pass it to another function, 1315 00:56:16,486 --> 00:56:17,786 that function gets a copy of it. 1316 00:56:18,016 --> 00:56:20,726 And you can't access the other guy's copy back and forth 1317 00:56:20,956 --> 00:56:24,716 and that is because of this little picture that we started 1318 00:56:24,716 --> 00:56:27,036 to draw here where your memory is given-- 1319 00:56:27,076 --> 00:56:29,326 your program is given different slivers 1320 00:56:29,566 --> 00:56:30,956 for every individual function. 1321 00:56:31,336 --> 00:56:32,996 Now, if you take this to the extreme 1322 00:56:32,996 --> 00:56:35,386 and call some function an infinite number of times, 1323 00:56:35,616 --> 00:56:38,426 eventually you're gonna hit some kind of ceiling. 1324 00:56:38,686 --> 00:56:42,556 And that ceiling among other things has your own program 1325 00:56:42,626 --> 00:56:45,776 in it, your own program zeroes and ones that were the result 1326 00:56:46,016 --> 00:56:47,466 of GCC compiling them. 1327 00:56:47,696 --> 00:56:50,966 And what eventually happens is usually something like this, 1328 00:56:51,306 --> 00:56:52,856 odds are this won't really happen 1329 00:56:52,856 --> 00:56:54,926 to you this week unless you're doing the Hacker Edition 1330 00:56:54,926 --> 00:56:58,106 of P set 1, but this will happen to everyone in this room 1331 00:56:58,106 --> 00:56:59,206 over the next couple of weeks. 1332 00:56:59,606 --> 00:57:03,546 Segmentation fault simply refers to the fact that you started 1333 00:57:03,546 --> 00:57:05,686 in some segment at the bottom of your memory 1334 00:57:05,846 --> 00:57:09,936 and you overstepped the bounds of someone else's segments, 1335 00:57:10,466 --> 00:57:12,406 some other important chunk of memory. 1336 00:57:12,676 --> 00:57:15,236 So this is actually a good thing and that the computer is trying 1337 00:57:15,236 --> 00:57:16,916 to prevent bad things from happening. 1338 00:57:17,226 --> 00:57:19,136 But as we'll see we can actually, 1339 00:57:19,136 --> 00:57:21,746 with finer grain control, take advantage 1340 00:57:21,746 --> 00:57:22,856 of a computer's memory. 1341 00:57:22,856 --> 00:57:23,966 And again to be clear, 1342 00:57:24,206 --> 00:57:26,496 the context here might be malicious behavior, 1343 00:57:26,496 --> 00:57:29,746 not just compromising a server but frankly a common pastime 1344 00:57:29,746 --> 00:57:32,446 on the internet is to create cracks for programs whereby 1345 00:57:32,616 --> 00:57:35,216 when you wanna install Microsoft Word or Photoshop or something 1346 00:57:35,216 --> 00:57:36,446 like that, you're usually prompted 1347 00:57:36,446 --> 00:57:39,056 for your registration code or product code, 1348 00:57:39,056 --> 00:57:41,156 something like that, that in theory only you have. 1349 00:57:41,546 --> 00:57:43,996 Well, how are those things implemented if you double click 1350 00:57:43,996 --> 00:57:46,416 on Photoshop for the first time, there's probably just an 1351 00:57:46,416 --> 00:57:49,556 If condition in there that says, "If not yet registered, 1352 00:57:49,746 --> 00:57:52,226 show prompt, else show program." 1353 00:57:52,686 --> 00:57:54,766 right? So conceptually, it's probably as simple as that, 1354 00:57:55,096 --> 00:57:56,256 so what do bad guys do? 1355 00:57:56,256 --> 00:57:58,516 Well, they try to figure out where in the program, 1356 00:57:58,516 --> 00:58:02,366 where among those zeroes and ones there is that condition 1357 00:58:02,656 --> 00:58:05,036 to try to circumvent it or try to overwrite it 1358 00:58:05,166 --> 00:58:06,306 with code of their own. 1359 00:58:06,616 --> 00:58:10,166 So again this all relates to the capability in most programs 1360 00:58:10,466 --> 00:58:14,716 to take advantage of or even break their use of memory 1361 00:58:14,716 --> 00:58:16,736 or even their use of disk space, 1362 00:58:17,066 --> 00:58:20,346 and its all because you can address every single byte by way 1363 00:58:20,346 --> 00:58:23,446 of its number byte zero, byte one, byte four billion, 1364 00:58:23,546 --> 00:58:25,086 if you have four gigabytes of RAM 1365 00:58:25,086 --> 00:58:27,076 or four gigabytes of disk space. 1366 00:58:27,726 --> 00:58:31,116 So let's now explode something we've been simplifying 1367 00:58:31,116 --> 00:58:34,726 in the CS50 Library, a string again is what-- in English? 1368 00:58:34,726 --> 00:58:35,326 [ Inaudible Answers ] 1369 00:58:35,326 --> 00:58:38,976 >> So its text, it's a word, it's a sentence, 1370 00:58:38,976 --> 00:58:41,386 maybe it's a single character, it's zero 1371 00:58:41,386 --> 00:58:43,216 or more characters in a row. 1372 00:58:43,436 --> 00:58:45,846 And this is actually the case in memory too. 1373 00:58:46,026 --> 00:58:48,816 If I wrote that program a week ago called Hello World, 1374 00:58:49,036 --> 00:58:52,006 and I typed in H-E-L-L-O and hit Enter 1375 00:58:52,196 --> 00:58:55,346 and that H-E-L-L-O were stored inside of RAM, 1376 00:58:55,656 --> 00:58:58,636 those characters would be stored back to back to back to back, 1377 00:58:59,176 --> 00:59:02,816 one ASCII character, one byte after the other. 1378 00:59:03,076 --> 00:59:09,176 And in fact what really happens inside of a computer program is, 1379 00:59:10,096 --> 00:59:14,816 if I type in H-E-L-L-O, H-- here's a free-- 1380 00:59:14,856 --> 00:59:16,556 formerly blank chunk of memory, 1381 00:59:17,236 --> 00:59:19,376 so this is the first few bytes of, say, 1382 00:59:19,376 --> 00:59:20,816 four gigabytes worth of memory. 1383 00:59:20,996 --> 00:59:23,696 When I type in H-E-L-L-O, when store in a string, 1384 00:59:23,936 --> 00:59:29,536 what really happens is this H-E-L-L-O, 1385 00:59:29,536 --> 00:59:32,806 and then the next word I type in if its Hello World, 1386 00:59:32,996 --> 00:59:40,006 might be W-O-R-L-D, but this is a bit broken and it's a bit 1387 00:59:40,006 --> 00:59:42,636 of a-- a lie because you need some way 1388 00:59:42,636 --> 00:59:44,526 of distinguishing boundaries between words. 1389 00:59:44,706 --> 00:59:47,346 So what C actually does is even though when you type words 1390 00:59:47,346 --> 00:59:48,796 at your keyboard and they're stored in these-- 1391 00:59:48,876 --> 00:59:50,196 the variables called Strings, 1392 00:59:50,456 --> 00:59:53,636 even though it does store the word, one character 1393 00:59:53,826 --> 00:59:56,106 after the other, it also puts a special-- 1394 00:59:56,106 --> 00:59:58,406 let's call it Sentinel Value at the very end. 1395 00:59:58,406 --> 01:00:00,716 And I'm gonna denote this with backslash zero. 1396 01:00:01,226 --> 01:00:02,706 >> So we've seen backslash N 1397 01:00:02,706 --> 01:00:05,166 and the backlash almost always denotes something special. 1398 01:00:05,166 --> 01:00:06,226 It's an escape character. 1399 01:00:06,556 --> 01:00:08,386 Backslash zero is the way 1400 01:00:08,386 --> 01:00:12,546 of representing a byte whose 8 bits are all zeros. 1401 01:00:12,736 --> 01:00:13,956 This is a special character. 1402 01:00:14,306 --> 01:00:15,766 This is in contrast just to be clear. 1403 01:00:15,766 --> 01:00:19,006 If I wrote just zero, that's actually the ASCII character. 1404 01:00:19,006 --> 01:00:21,996 The text that looks like the number we know is zero 1405 01:00:22,166 --> 01:00:26,376 but the letter zero, the ASCII character zero is not zero, 1406 01:00:26,376 --> 01:00:28,286 zero, zero, zero, zero, in terms of bits, 1407 01:00:28,826 --> 01:00:31,976 so backslash zero means a byte worth of all bits-- 1408 01:00:32,226 --> 01:00:34,226 a byte worth of all zeros. 1409 01:00:34,426 --> 01:00:37,566 And I need this one other place backslash zero so that now 1410 01:00:37,566 --> 01:00:39,636 if I have an exclamation point at the end of my sentence, 1411 01:00:39,636 --> 01:00:43,146 I might have another exclamation point there. 1412 01:00:43,626 --> 01:00:46,976 So I typed in "Hello" and hit Enter, 1413 01:00:47,316 --> 01:00:50,806 this ends up in memory followed by this backslash zero. 1414 01:00:50,976 --> 01:00:54,596 If I then on another line typed in "Hello World" it ends 1415 01:00:54,596 --> 01:00:56,076 up in memory in the same way. 1416 01:00:56,296 --> 01:00:59,766 If I typed them both together with just a space bar character, 1417 01:00:59,986 --> 01:01:02,736 you do not get a backslash zero after every word. 1418 01:01:02,946 --> 01:01:05,606 You only get a backslash zero after every string. 1419 01:01:05,716 --> 01:01:08,056 So the moment you-- when you use the CS50 Library 1420 01:01:08,246 --> 01:01:11,346 and use get string and hit Enter, the backslash zero ends 1421 01:01:11,346 --> 01:01:13,256 up at the very end of the string. 1422 01:01:13,546 --> 01:01:16,516 You might still have space bar characters in the middle there. 1423 01:01:16,876 --> 01:01:20,106 So what's the application here? 1424 01:01:20,166 --> 01:01:22,096 So it turns out that a string 1425 01:01:22,126 --> 01:01:25,106 in C is just a new data structure called an array. 1426 01:01:25,106 --> 01:01:27,546 And you might recall from the tail end of scratch 1427 01:01:27,546 --> 01:01:30,016 or specifically the fruit craft RPG game, 1428 01:01:30,316 --> 01:01:32,066 where the little guy walked around stage 1429 01:01:32,066 --> 01:01:33,856 and he actually picked up like oranges and apples 1430 01:01:33,856 --> 01:01:36,446 and pears those kinds of things, he was putting them into a list 1431 01:01:36,696 --> 01:01:38,706 so to speak and to use scratches terminology, 1432 01:01:38,906 --> 01:01:40,056 well that's really just an array. 1433 01:01:40,056 --> 01:01:43,606 An array is a data structure, it's like a special variable 1434 01:01:43,706 --> 01:01:46,386 that doesn't just store one thing it can store two things 1435 01:01:46,386 --> 01:01:48,686 or three things or four things altogether. 1436 01:01:48,956 --> 01:01:51,096 This is great for strings because of what's a string, 1437 01:01:51,386 --> 01:01:54,556 its zero or one or two characters altogether. 1438 01:01:54,916 --> 01:01:57,806 So the way in which C implements strings is it takes a chunk 1439 01:01:57,806 --> 01:02:00,206 of memory, puts the first character here then here then 1440 01:02:00,206 --> 01:02:01,506 here then here and at the very end 1441 01:02:01,506 --> 01:02:04,316 of the string it puts backslash zero. 1442 01:02:04,896 --> 01:02:07,266 And so, what the implication here is that even 1443 01:02:07,266 --> 01:02:09,916 if you have a string that's been past in by the user 1444 01:02:09,916 --> 01:02:11,756 of the keyboard, you can actually get 1445 01:02:11,756 --> 01:02:15,596 at individual characters in it because they are all back 1446 01:02:15,816 --> 01:02:17,436 to back to back in this way. 1447 01:02:18,246 --> 01:02:21,536 So let me go ahead and open this program called argv1 1448 01:02:21,536 --> 01:02:24,626 and we can finally reveal what 1449 01:02:24,626 --> 01:02:26,806 that special thing called argv has been 1450 01:02:26,806 --> 01:02:29,496 that you might have seen in textbooks 1451 01:02:30,126 --> 01:02:31,656 or in the online references. 1452 01:02:31,726 --> 01:02:35,386 So thus far, all of our programs have been declared 1453 01:02:35,386 --> 01:02:37,386 with the very simple void. 1454 01:02:37,686 --> 01:02:40,396 But the question was asked, I think on Monday, what is it mean 1455 01:02:40,396 --> 01:02:43,026 if you actually have something other 1456 01:02:43,026 --> 01:02:44,436 than void inside a parenthesis? 1457 01:02:44,436 --> 01:02:47,726 What if you want a program to take command-line arguments? 1458 01:02:47,906 --> 01:02:49,356 Well, what's a command-line argument? 1459 01:02:49,356 --> 01:02:51,246 Well, most of the programs we've been using down here 1460 01:02:51,246 --> 01:02:53,796 on the terminal window, take command-line arguments. 1461 01:02:53,796 --> 01:02:56,646 There is a program called Make, but anytime you type something 1462 01:02:56,646 --> 01:02:59,516 like beer4 at the prompt, you're passing 1463 01:02:59,676 --> 01:03:04,176 to make a command-line argument which is similar in spirit 1464 01:03:04,176 --> 01:03:06,846 to calling get string and asking the user for a string, 1465 01:03:07,046 --> 01:03:09,316 but notice the one key conceptual difference. 1466 01:03:09,346 --> 01:03:11,536 A command line argument is input, 1467 01:03:11,686 --> 01:03:14,106 is a word that the user types before he 1468 01:03:14,106 --> 01:03:16,056 or she actually runs the program. 1469 01:03:16,346 --> 01:03:19,806 So it's passed to the program as at the so-called command line. 1470 01:03:20,056 --> 01:03:21,976 So how does Make-- how does GCC, 1471 01:03:22,036 --> 01:03:24,806 how do any other programs we've been taking for granted 1472 01:03:24,806 --> 01:03:26,616 in the Appliance actually access those? 1473 01:03:27,036 --> 01:03:30,066 Well, now we can change what main looks like. 1474 01:03:30,566 --> 01:03:34,246 This is the other correct declaration of main 1475 01:03:34,246 --> 01:03:35,616 and it's a little a scarier looking 1476 01:03:35,616 --> 01:03:37,566 but we'll tease this apart in just a second. 1477 01:03:37,916 --> 01:03:42,766 Int is the same, main is the same, what do you think argc 1478 01:03:42,766 --> 01:03:46,386 and argv might represent? 1479 01:03:46,386 --> 01:03:50,676 So arg denotes argument, so just as another function like swap 1480 01:03:50,676 --> 01:03:53,036 or increment or any of these functions we've been playing 1481 01:03:53,036 --> 01:03:55,926 with today or chorus just as they can take arguments, 1482 01:03:56,096 --> 01:03:57,776 it turns out main can as well. 1483 01:03:57,996 --> 01:03:59,626 Thus far, none of the programs we've had 1484 01:03:59,626 --> 01:04:01,896 to write take arguments at the command line. 1485 01:04:01,896 --> 01:04:03,906 We've hit Enter then we're prompted 1486 01:04:03,906 --> 01:04:05,636 for a string via the use of-- 1487 01:04:05,636 --> 01:04:08,596 we then prompt to use the first string, but if you actually want 1488 01:04:08,596 --> 01:04:09,896 to take the arguments 1489 01:04:10,106 --> 01:04:13,226 at the very command line you can declare main as this, 1490 01:04:13,226 --> 01:04:15,666 int argc which stands for argument count. 1491 01:04:16,226 --> 01:04:17,896 And then you can declare this, 1492 01:04:18,146 --> 01:04:21,806 char star argv open bracket, close bracket. 1493 01:04:22,216 --> 01:04:23,676 So this will make sense in just a moment. 1494 01:04:23,676 --> 01:04:26,586 Let me actually simplify this for a moment and rewrite this 1495 01:04:26,586 --> 01:04:30,126 as this, which is again sort of CS50 style, not quite correct 1496 01:04:30,126 --> 01:04:31,246 so we'll fix it in a moment. 1497 01:04:31,796 --> 01:04:34,986 This means that argc is a number and its argument count. 1498 01:04:34,986 --> 01:04:37,186 How many words that the user type at the prompt? 1499 01:04:37,606 --> 01:04:39,646 Argv is what's called argument vector 1500 01:04:39,746 --> 01:04:41,406 which is usually synonymous with array. 1501 01:04:41,586 --> 01:04:42,196 So it's a list. 1502 01:04:42,196 --> 01:04:44,706 It's a collection of words that the user typed. 1503 01:04:45,086 --> 01:04:48,066 So when you type in multiple words at the prompt, 1504 01:04:48,266 --> 01:04:49,216 where did they end up? 1505 01:04:49,306 --> 01:04:52,236 They end up in a variable called argv 1506 01:04:52,236 --> 01:04:55,346 and the square brackets is just C's way 1507 01:04:55,346 --> 01:04:58,346 of saying this is an array of arguments, that is, 1508 01:04:58,346 --> 01:05:01,926 this is multiple words, multiple inputs all inside 1509 01:05:01,926 --> 01:05:03,626 of one variable like a scratch list. 1510 01:05:03,696 --> 01:05:05,946 I'm gonna leave this string for just a moment 1511 01:05:06,176 --> 01:05:08,126 and let's actually see what this program does. 1512 01:05:08,276 --> 01:05:11,636 I'm gonna go ahead and go down here and I'm gonna compile 1513 01:05:11,696 --> 01:05:16,496 in the lectures to source, I'm gonna compile argv1, Enter, 1514 01:05:17,116 --> 01:05:19,706 and now notice unknown typed string. 1515 01:05:20,086 --> 01:05:20,716 How do I fix this? 1516 01:05:21,916 --> 01:05:25,196 Yup, includes CS50.h. So now let me go back 1517 01:05:25,196 --> 01:05:27,166 to my prompt and rerun arg. 1518 01:05:27,246 --> 01:05:28,166 Okay, that's good. 1519 01:05:28,246 --> 01:05:32,626 Now I'm gonna run it, argv1, foo, bar, Enter. 1520 01:05:33,276 --> 01:05:37,226 Interesting, it looks like this program simply does what? 1521 01:05:38,406 --> 01:05:40,876 Print out what you typed but one word per line 1522 01:05:40,876 --> 01:05:42,766 and then its got some-- just for aesthetics, 1523 01:05:42,766 --> 01:05:45,136 just some blank space at the top and blank space on the bottom. 1524 01:05:45,386 --> 01:05:48,336 But it looks like it literally regurgitated what I wrote best 1525 01:05:48,886 --> 01:05:52,036 or just like this, right? 1526 01:05:52,036 --> 01:05:54,206 So it's just spitting out of those words at the prompt. 1527 01:05:54,206 --> 01:05:55,506 How did we get access to them? 1528 01:05:55,666 --> 01:05:57,026 Well, it's actually pretty easy. 1529 01:05:57,186 --> 01:06:00,516 So notice again that main is now being passed a special number, 1530 01:06:00,516 --> 01:06:04,746 the number of words that were typed at the line then a string 1531 01:06:04,746 --> 01:06:08,046 but not a string in array of strings as represented here 1532 01:06:08,386 --> 01:06:10,756 so this represents the number of-- 1533 01:06:10,756 --> 01:06:14,076 the words that were typed at this command line. 1534 01:06:14,556 --> 01:06:15,496 So let's see what happens, 1535 01:06:15,496 --> 01:06:18,286 I print backslash N. Why am I iterating 1536 01:06:18,286 --> 01:06:19,866 from I equals zero to argc? 1537 01:06:19,976 --> 01:06:21,466 Conceptually what is that mean? 1538 01:06:23,086 --> 01:06:24,536 Just iterate over all the arguments. 1539 01:06:24,646 --> 01:06:26,806 Iterate from zero to whatever the number 1540 01:06:26,806 --> 01:06:28,546 of total words there were that were typed. 1541 01:06:28,956 --> 01:06:30,266 And now this is familiar, 1542 01:06:30,336 --> 01:06:32,176 present as means put a string here, 1543 01:06:32,446 --> 01:06:33,926 what string do you wanna put here? 1544 01:06:34,196 --> 01:06:40,556 Well, if argv is said to be an array or a vector of words 1545 01:06:40,676 --> 01:06:44,486 that were typed turns out that syntactically you can get 1546 01:06:44,486 --> 01:06:47,686 at the first word by typing on our keyboard argv of zero. 1547 01:06:47,686 --> 01:06:49,436 That's the very first word that was typed. 1548 01:06:50,046 --> 01:06:54,776 Argv1 is the second, argv2 is the third, argv3, four, five, 1549 01:06:54,846 --> 01:06:57,986 six and so forth, those are each of the individual words numbered 1550 01:06:57,986 --> 01:07:00,056 from zero on up that you typed at the prompt. 1551 01:07:00,056 --> 01:07:02,286 So if I wanna generalize this, I just say I 1552 01:07:02,426 --> 01:07:04,706 and this means get me the I word that was typed 1553 01:07:04,706 --> 01:07:06,146 at the prompt and printed out. 1554 01:07:06,916 --> 01:07:09,736 So now I can go ahead and print this as follows. 1555 01:07:09,736 --> 01:07:15,396 If I go back again and I go ahead and run this and I say, 1556 01:07:15,426 --> 01:07:18,866 "Yes indeed" Enter, it does exactly that. 1557 01:07:19,136 --> 01:07:21,606 But notice too, it's also including not just the words I 1558 01:07:21,606 --> 01:07:23,006 typed after the program's name 1559 01:07:23,006 --> 01:07:25,846 but also the program's name itself. 1560 01:07:26,066 --> 01:07:27,846 So this actually means you have the ability 1561 01:07:27,846 --> 01:07:31,076 to see what your own name is which is sometimes useful. 1562 01:07:31,076 --> 01:07:33,686 Well, let's take this one step further, 1563 01:07:33,776 --> 01:07:35,416 not to make this too complex, 1564 01:07:35,546 --> 01:07:37,166 but let's take this one step further. 1565 01:07:37,166 --> 01:07:39,486 Let me go ahead and open up version 2 of this file. 1566 01:07:40,206 --> 01:07:41,256 It looks a little scarier. 1567 01:07:41,256 --> 01:07:45,866 Let me go down to my prompt and run argv of argv2, argv2, 1568 01:07:46,046 --> 01:07:53,766 we'll zoom in, enter, compiles okay, argv2, Enter. 1569 01:07:54,376 --> 01:07:55,666 Hmm, interesting. 1570 01:07:55,936 --> 01:07:59,446 Hi. So what's this one doing differently obviously? 1571 01:07:59,776 --> 01:08:01,346 So now it's doing not one word per line 1572 01:08:01,346 --> 01:08:02,996 but one character per line. 1573 01:08:03,206 --> 01:08:03,946 So this suggest 1574 01:08:03,946 --> 01:08:07,066 that programmatically I must have the way not only to iterate 1575 01:08:07,066 --> 01:08:09,616 over each of the words that the user types but also over each 1576 01:08:09,616 --> 01:08:13,176 of the-- just the characters that they typed and that's 1577 01:08:13,226 --> 01:08:18,246 because 2 just as argv itself is an array of strings. 1578 01:08:18,246 --> 01:08:19,366 Well, guess what a string is? 1579 01:08:19,946 --> 01:08:21,876 It is an array of characters, 1580 01:08:22,046 --> 01:08:24,146 so we can apply this exact same logic. 1581 01:08:24,556 --> 01:08:26,626 Let me zoom in now on this version 2, 1582 01:08:26,856 --> 01:08:28,766 and again I at the top here I have this 1583 01:08:28,766 --> 01:08:30,446 and I simplified this a moment ago. 1584 01:08:30,446 --> 01:08:33,576 This is the first training wheel that we'll eventually take off 1585 01:08:33,786 --> 01:08:37,166 when we keep saying string in C programs. 1586 01:08:37,596 --> 01:08:41,026 Technically, it's really something called char star 1587 01:08:41,026 --> 01:08:43,346 and the star is just a little confusing for now so we hide it 1588 01:08:43,556 --> 01:08:45,306 under the guides of something called string. 1589 01:08:45,526 --> 01:08:47,386 But note for now that these are synonymous, 1590 01:08:47,426 --> 01:08:48,796 it's just we're currently in the habit 1591 01:08:48,796 --> 01:08:51,046 of calling those things strings, but we will go-- 1592 01:08:51,046 --> 01:08:53,076 get rid of that convention in a week or two. 1593 01:08:53,476 --> 01:08:55,536 So now let's look at what this program is doing. 1594 01:08:55,566 --> 01:09:00,566 It's iterating from zero to argc again, okay, it's now iterating 1595 01:09:00,926 --> 01:09:03,326 from another variable, J equals zero. 1596 01:09:03,326 --> 01:09:07,546 What do you think string length of argvi means? 1597 01:09:09,246 --> 01:09:11,576 String length, strlen is just another function. 1598 01:09:11,576 --> 01:09:12,886 It's in a special library 1599 01:09:13,096 --> 01:09:14,946 and it just gets you the length of a string. 1600 01:09:15,256 --> 01:09:18,606 So, what the string length of argvi generally mean? 1601 01:09:18,606 --> 01:09:20,276 [ Inaudible Answer ] 1602 01:09:20,276 --> 01:09:21,816 >> Given the length of the I word 1603 01:09:21,816 --> 01:09:23,246 that the user typed at the prompt? 1604 01:09:23,246 --> 01:09:25,356 That's it, give me the zeroth word, the first word, 1605 01:09:25,356 --> 01:09:27,246 the second word, the third word and get its length. 1606 01:09:27,646 --> 01:09:28,996 Now as in the aside, had do you figure 1607 01:09:28,996 --> 01:09:30,056 out the length of a string? 1608 01:09:31,426 --> 01:09:33,776 What-- how would-- whoever implemented string length forty 1609 01:09:33,776 --> 01:09:35,106 years ago, how did they do it? 1610 01:09:36,146 --> 01:09:37,506 You just start at the first start 1611 01:09:37,506 --> 01:09:39,276 of the string and look for what? 1612 01:09:39,926 --> 01:09:42,446 Backslash zero, and you return the total number 1613 01:09:42,446 --> 01:09:44,556 of characters you saw before the backslash zero, 1614 01:09:44,556 --> 01:09:46,376 so that's actually a pretty simple program-- 1615 01:09:46,376 --> 01:09:48,086 a function, but let's see what we're doing. 1616 01:09:48,086 --> 01:09:49,836 There's one piece of aesthetic difference here. 1617 01:09:50,076 --> 01:09:52,666 Notice that you can actually declare multiple variables 1618 01:09:52,666 --> 01:09:55,146 at once inside of a for loop, you just put a comma there. 1619 01:09:55,406 --> 01:09:58,826 So I'm declaring not only an int called J and setting it equal 1620 01:09:58,826 --> 01:10:01,526 to zero, I'm also declaring another int called N 1621 01:10:01,526 --> 01:10:04,846 and setting it equal to the length of the string 1622 01:10:05,046 --> 01:10:05,956 and then I'm iterating J up to N. 1623 01:10:06,916 --> 01:10:10,046 >> So from zero up to the length because I'm doing J plus plus, 1624 01:10:10,336 --> 01:10:12,286 so now notice, we can apply the same logic. 1625 01:10:12,466 --> 01:10:14,926 So again the syntax is new but the idea, we're just mimicking. 1626 01:10:15,276 --> 01:10:18,026 If you can index into an array of words called argv 1627 01:10:18,026 --> 01:10:19,816 with the square bracket notation, 1628 01:10:20,216 --> 01:10:23,526 but the thing that's there is a string and what's a string? 1629 01:10:23,676 --> 01:10:25,846 It's just an array of characters. 1630 01:10:26,156 --> 01:10:30,316 You can then use double bracket notations to say give the I word 1631 01:10:30,676 --> 01:10:33,106 and give me its J character. 1632 01:10:33,656 --> 01:10:37,516 And if you do that, this seems to empower us now to iterate 1633 01:10:37,516 --> 01:10:40,766 over all of the lines and all of the-- 1634 01:10:40,766 --> 01:10:43,776 all of the words and all of the characters in a string one 1635 01:10:43,776 --> 01:10:47,386 at a time printing them out by way of the familiar printf. 1636 01:10:48,086 --> 01:10:51,096 But this time present C 'cause it's a character followed 1637 01:10:51,096 --> 01:10:54,356 by backslash N. So in short, what is an array? 1638 01:10:54,356 --> 01:10:58,186 It's just a contiguous block of memory inside 1639 01:10:58,186 --> 01:11:00,466 of which are the same types of thing again and again 1640 01:11:00,466 --> 01:11:02,376 and again either a word, a word, a word, 1641 01:11:02,376 --> 01:11:04,916 a word or in this case a character, a character, 1642 01:11:04,916 --> 01:11:06,016 a character, a character. 1643 01:11:06,466 --> 01:11:08,156 So, who cares? 1644 01:11:08,236 --> 01:11:12,956 Well, it turns out that back in the day, they're actually back 1645 01:11:12,956 --> 01:11:15,206 in Caesar's day, literally, there was something known 1646 01:11:15,206 --> 01:11:19,056 as the Caesar cipher, and the Caesar cipher is not unlike the 1647 01:11:19,056 --> 01:11:22,706 grade school flashback I had the other day whereby you might pass 1648 01:11:22,706 --> 01:11:25,116 a note handwritten to a significant other 1649 01:11:25,116 --> 01:11:27,496 in your third grade class, but you want to encrypt it 1650 01:11:27,776 --> 01:11:29,896 by actually rotating the characters 1651 01:11:29,896 --> 01:11:31,076 in the message by one place. 1652 01:11:31,136 --> 01:11:34,666 A becomes B, B becomes C and so forth and we teased earlier 1653 01:11:34,666 --> 01:11:37,106 on Monday that you could do this now programmatically 'cause a 1654 01:11:37,106 --> 01:11:41,876 letter is just a number like 65 is A and 97 is lower case A. 1655 01:11:41,876 --> 01:11:45,266 So you could actually convert letters to numbers, do some math 1656 01:11:45,266 --> 01:11:47,116 and then convert numbers back to letters 1657 01:11:47,116 --> 01:11:49,076 and you could do this now with the computer program. 1658 01:11:49,076 --> 01:11:50,426 And indeed, according to legend, 1659 01:11:50,626 --> 01:11:53,566 this is exactly how Caesar himself encrypted messages 1660 01:11:53,566 --> 01:11:56,966 to his generals in the field taking hopefully a secret number 1661 01:11:56,966 --> 01:11:57,746 bigger than one. 1662 01:11:57,746 --> 01:12:00,186 He didn't just rotate letters and their alphabet by one 1663 01:12:00,426 --> 01:12:03,126 but rather some bigger number or something similar 1664 01:12:03,406 --> 01:12:05,746 and so thus was born what's called the Caesar cipher, 1665 01:12:05,746 --> 01:12:09,506 a rotational cipher whereby you rotate the letters in the-- 1666 01:12:09,506 --> 01:12:11,486 some word by some number of places. 1667 01:12:12,006 --> 01:12:14,656 So in problem set 2 next week, 1668 01:12:14,726 --> 01:12:17,276 you will see the same idea applied where you'll have 1669 01:12:17,276 --> 01:12:19,316 to implement your own forms of encryption, 1670 01:12:19,556 --> 01:12:22,926 your own Caesar ciphers and some other ciphers whereby you'll 1671 01:12:22,926 --> 01:12:24,876 take input and have to produce output 1672 01:12:24,876 --> 01:12:26,636 that whose input might be 1, 2, 3, 4, 1673 01:12:26,636 --> 01:12:29,516 5 but the output should be something much harder 1674 01:12:29,516 --> 01:12:31,996 to actually decode or decrypt. 1675 01:12:32,466 --> 01:12:35,146 And the little teaser here, I have about one minute left 1676 01:12:35,146 --> 01:12:37,896 on the clock, is that all of these actually relates 1677 01:12:38,016 --> 01:12:40,776 to a little thing you see on the screen here, little orphan Annie 1678 01:12:40,996 --> 01:12:44,016 which is stolen from a movie called-- anyone know? 1679 01:12:44,716 --> 01:12:49,266 A Christmas story where little Ralphie has been listening 1680 01:12:49,266 --> 01:12:52,276 to the radio for ages hearing secret messages from them 1681 01:12:52,496 --> 01:12:53,626 and he tries to decrypt them 1682 01:12:53,626 --> 01:12:56,266 and they finally send them little orphan Annie's secret 1683 01:12:56,266 --> 01:12:59,606 decoder ring which just allows you to rotate the ring and map A 1684 01:12:59,606 --> 01:13:02,996 to B and B to C and so forth but in some general way, 1685 01:13:02,996 --> 01:13:06,096 and so this was Ralphie's and soon your discovery. 1686 01:13:06,096 --> 01:13:07,786 >> "A member of the Little Orphan Annie secret circle 1687 01:13:07,786 --> 01:13:09,056 and is entitled to all the honors 1688 01:13:09,056 --> 01:13:10,616 and benefits occurring thereto." 1689 01:13:11,406 --> 01:13:13,476 >> Signed, Little Orphan Annie. 1690 01:13:13,476 --> 01:13:16,176 Countersigned, Pierre Andre! 1691 01:13:16,576 --> 01:13:19,246 In ink! Honors and benefits. 1692 01:13:19,396 --> 01:13:20,656 Already at the age of nine. 1693 01:13:21,516 --> 01:13:26,626 [ Inaudible Remarks ] 1694 01:13:27,126 --> 01:13:27,956 >> Come on. 1695 01:13:27,956 --> 01:13:28,736 Let's get on with it. 1696 01:13:28,936 --> 01:13:31,186 I don't need all that jazz about smugglers and pirates. 1697 01:13:33,056 --> 01:13:35,346 >> Listen tomorrow night for the concluding adventure 1698 01:13:35,346 --> 01:13:37,046 of the Black Pirate Ship. 1699 01:13:37,566 --> 01:13:40,176 Now it's time for Annie's secret message 1700 01:13:40,416 --> 01:13:42,396 for you members of the secret circle. 1701 01:13:43,566 --> 01:13:45,456 Remember, kids, only members 1702 01:13:45,456 --> 01:13:49,836 of Annie's secret circle can decode Annie's secret message. 1703 01:13:49,836 --> 01:13:49,903 [ Background Music ] 1704 01:13:49,903 --> 01:13:53,126 >> Remember, Annie is depending on you. 1705 01:13:54,066 --> 01:13:55,496 Set your pins to B-2. 1706 01:13:55,546 --> 01:13:56,666 Here is the message. 1707 01:13:56,666 --> 01:13:57,726 12, 11, 2-- 1708 01:13:57,726 --> 01:14:02,846 >> I am in my first secret meeting. 1709 01:14:03,956 --> 01:14:07,726 >> -- 25, 14, 11, 18, 16, 23-- 1710 01:14:07,726 --> 01:14:09,166 >> Pierre was in great voice tonight. 1711 01:14:09,346 --> 01:14:12,296 I could tell that tonight's message was really important. 1712 01:14:12,296 --> 01:14:16,476 >> -- 3, 25, that's a message from Annie herself. 1713 01:14:16,476 --> 01:14:17,956 Remember, don't tell anyone. 1714 01:14:17,956 --> 01:14:18,066 [ Background Noise ] 1715 01:14:18,066 --> 01:14:25,496 >> Ninety seconds later I'm in the only room in the house 1716 01:14:25,496 --> 01:14:30,996 where a boy of nine can sit in privacy and decode. 1717 01:14:30,996 --> 01:14:35,736 Ah! "B." I went to the next. 1718 01:14:35,926 --> 01:14:37,626 "E." The first word is "be"! 1719 01:14:38,226 --> 01:14:40,806 "S." It was coming easier now. 1720 01:14:40,866 --> 01:14:41,086 "U." 1721 01:14:41,506 --> 01:14:42,726 >> Come on, Ralphie! 1722 01:14:43,036 --> 01:14:45,526 I gotta go. 1723 01:14:45,526 --> 01:14:50,136 >> I'll be right down, Ma. 1724 01:14:52,236 --> 01:14:54,546 >> Gee whiz. 1725 01:14:54,546 --> 01:14:54,646 >> "T, O." 1726 01:14:55,266 --> 01:14:56,056 "Be sure to." 1727 01:14:56,276 --> 01:14:57,206 Be sure to what? 1728 01:14:57,776 --> 01:14:59,756 What was Little Orphan Annie trying to say? 1729 01:15:01,446 --> 01:15:07,586 Be sure to what? 1730 01:15:08,356 --> 01:15:08,546 >> Ralphie! 1731 01:15:08,686 --> 01:15:10,526 Randy has got to go! 1732 01:15:11,386 --> 01:15:13,626 Will you please come out? 1733 01:15:14,286 --> 01:15:15,286 >> Alright, Ma! 1734 01:15:15,806 --> 01:15:18,656 I'll be right out! 1735 01:15:19,906 --> 01:15:21,616 >> I was getting closer now. 1736 01:15:21,886 --> 01:15:24,486 The tension was terrible. 1737 01:15:24,906 --> 01:15:25,936 What was it? 1738 01:15:25,936 --> 01:15:35,046 The fate of the planet may hang in the balance. 1739 01:15:35,046 --> 01:15:35,546 >> Ralphie! 1740 01:15:35,546 --> 01:15:37,046 Randy's gotta go! 1741 01:15:37,086 --> 01:15:42,156 >> I'll be right out, for crying out loud! 1742 01:15:42,156 --> 01:15:42,516 >> Almost there! 1743 01:15:42,516 --> 01:15:47,056 My fingers flew. 1744 01:15:47,506 --> 01:15:50,386 My mind was a steel trap. 1745 01:15:50,386 --> 01:15:50,956 Every pore vibrated. 1746 01:15:50,956 --> 01:15:51,846 It was almost clear. 1747 01:15:51,846 --> 01:15:53,386 Yes! Yes! Yes! 1748 01:15:53,386 --> 01:15:56,226 >> Be sure to drink your Ovaltine. 1749 01:15:56,256 --> 01:15:56,946 Ovaltine? A crummy commercial? 1750 01:15:56,946 --> 01:15:57,013 [ Background Music ] 1751 01:15:57,013 --> 01:15:57,336 >> Son of a bitch! 1752 01:15:57,336 --> 01:15:57,403 [ Laughter ] 1753 01:15:57,403 --> 01:15:58,116 >> And that's you have encryption. 1754 01:15:58,146 --> 01:15:58,716 We'll see you next week.