1 00:00:00,000 --> 00:00:11,280 2 00:00:11,280 --> 00:00:13,650 >> SPEAKER 1: All right. 3 00:00:13,650 --> 00:00:14,390 Welcome back. 4 00:00:14,390 --> 00:00:19,260 This is Week Two of CS50, and we have thus far been using functions but 5 00:00:19,260 --> 00:00:20,830 largely taken them for granted. 6 00:00:20,830 --> 00:00:23,430 We've used printf which has the side effect of printing 7 00:00:23,430 --> 00:00:24,110 things on the screen. 8 00:00:24,110 --> 00:00:25,790 We've used get-int, get float. 9 00:00:25,790 --> 00:00:29,230 >> But what if you actually want to create your own functions, as some of 10 00:00:29,230 --> 00:00:31,740 you might have already begun to do for Problem Set One, though 11 00:00:31,740 --> 00:00:33,140 not strictly required? 12 00:00:33,140 --> 00:00:37,150 Well, let's go ahead and revisit that problem of just asking the user for 13 00:00:37,150 --> 00:00:40,660 their name and printing something on the screen, but try to factor out some 14 00:00:40,660 --> 00:00:44,000 of the commonality that we've seen in our code thus far. 15 00:00:44,000 --> 00:00:45,120 So by that I mean the following. 16 00:00:45,120 --> 00:00:47,315 >> I'm going to go ahead and create a new program, just call 17 00:00:47,315 --> 00:00:49,320 it hello.c as usual. 18 00:00:49,320 --> 00:00:53,730 I'm going to go ahead and give myself include standard io.h at the top. 19 00:00:53,730 --> 00:00:57,040 I'm going to also give myself preemptively the CS50 library so that 20 00:00:57,040 --> 00:00:59,080 I don't get yelled at by the compiler. 21 00:00:59,080 --> 00:01:02,400 And now I'm going to go ahead and declare int, main, void. 22 00:01:02,400 --> 00:01:09,020 >> And then in here, this is where I want to begin to outsource functionality to 23 00:01:09,020 --> 00:01:12,090 some other function that I myself am going to write but that doesn't 24 00:01:12,090 --> 00:01:13,820 currently exist. 25 00:01:13,820 --> 00:01:19,210 For instance, suppose that I wanted to write a function that allows me to 26 00:01:19,210 --> 00:01:23,830 print out hello, comma, and then some user's name. 27 00:01:23,830 --> 00:01:29,010 Rather than continuing to do printf hello, %s, wouldn't it be nice if 28 00:01:29,010 --> 00:01:33,380 there were just a function called not printf but print name? 29 00:01:33,380 --> 00:01:36,600 >> So in other words, I want to be able to write a program that does a little 30 00:01:36,600 --> 00:01:37,710 something like this. 31 00:01:37,710 --> 00:01:42,070 First, I'm going to say printf your name, thereby prompting the user to 32 00:01:42,070 --> 00:01:46,150 give me his or her name, and then I'm going to use the familiar string s to 33 00:01:46,150 --> 00:01:47,290 declare a string. 34 00:01:47,290 --> 00:01:50,420 Give me a variable of type string, call it s, and store in that the 35 00:01:50,420 --> 00:01:52,120 result of calling get string. 36 00:01:52,120 --> 00:01:56,060 But now in weeks past, I would have somewhat tediously done hello, %s/n. 37 00:01:56,060 --> 00:01:58,630 38 00:01:58,630 --> 00:02:02,570 >> And in other words, we've seen this example a bunch of times, and it's a 39 00:02:02,570 --> 00:02:05,280 trivial example because there's just one line of code so it's really not a 40 00:02:05,280 --> 00:02:06,860 big deal to keep typing in again. 41 00:02:06,860 --> 00:02:09,990 But suppose that this line of code actually were becoming a burden, and 42 00:02:09,990 --> 00:02:12,900 it's not one line of code but it's 10 lines of code a couple weeks from now, 43 00:02:12,900 --> 00:02:15,190 and you're just getting tired of copying and pasting or 44 00:02:15,190 --> 00:02:17,180 retyping that same code. 45 00:02:17,180 --> 00:02:22,100 Wouldn't it be nice instead of doing printf hello, %s and so forth, 46 00:02:22,100 --> 00:02:26,500 wouldn't it be nice if there were just a function called print name that 47 00:02:26,500 --> 00:02:27,560 takes an argument-- 48 00:02:27,560 --> 00:02:29,120 in other words, it takes input-- 49 00:02:29,120 --> 00:02:30,620 and then semicolon. 50 00:02:30,620 --> 00:02:33,240 So that function, wouldn't it be nice if that existed? 51 00:02:33,240 --> 00:02:36,690 Then I wouldn't have to worry about what printf is, what %s and all of 52 00:02:36,690 --> 00:02:39,400 these complexities that are not all that interesting. 53 00:02:39,400 --> 00:02:40,570 They are useful. 54 00:02:40,570 --> 00:02:44,700 >> So print name, unfortunately, was not invented some 40 plus years ago. 55 00:02:44,700 --> 00:02:45,980 No one thought to write it. 56 00:02:45,980 --> 00:02:48,300 But that's the beauty of having a programming language, just like in 57 00:02:48,300 --> 00:02:52,930 Scratch you can define custom blocks, so in C and most any language, can you 58 00:02:52,930 --> 00:02:57,260 define your own functionality, can you define your own functions. 59 00:02:57,260 --> 00:03:01,710 So even though we get main by automatically for free, we can declare 60 00:03:01,710 --> 00:03:02,730 our own functions. 61 00:03:02,730 --> 00:03:05,670 >> So I'm going to make some room up here up top, and I'm going to declare my 62 00:03:05,670 --> 00:03:08,210 own function that's going to look a little strange at first but we'll come 63 00:03:08,210 --> 00:03:09,400 back to this before long. 64 00:03:09,400 --> 00:03:12,310 I'm going to say void, thereby indicating this function does 65 00:03:12,310 --> 00:03:16,040 something, has a side effect, but it doesn't return something to me in the 66 00:03:16,040 --> 00:03:18,810 same way that get int or get string itself does. 67 00:03:18,810 --> 00:03:22,450 And I'm going to give this function a name of print name, and I'm going to 68 00:03:22,450 --> 00:03:26,470 specify that this guy is going to take a string, and I'm going to call that 69 00:03:26,470 --> 00:03:27,600 string name. 70 00:03:27,600 --> 00:03:32,100 I could call it anything I want, but I want my code to be self-documenting. 71 00:03:32,100 --> 00:03:34,770 In other words, if one of you were to open this file and read it, you could 72 00:03:34,770 --> 00:03:39,020 sort of infer from the name of that input what role it's supposed to play. 73 00:03:39,020 --> 00:03:42,270 >> And now below that, I'm going to open curly brace and closed curly brace, 74 00:03:42,270 --> 00:03:47,140 and so notice I've followed the same pattern on lines four through seven as 75 00:03:47,140 --> 00:03:51,622 I've been following for a good week plus now between, say, lines nine and 76 00:03:51,622 --> 00:03:53,400 14 which compose main. 77 00:03:53,400 --> 00:03:56,160 In other words, print name is another function. 78 00:03:56,160 --> 00:03:58,990 Now, the compiler is not going to know to call this thing automatically 79 00:03:58,990 --> 00:04:02,670 because I literally just invented it, but it will know still to call main 80 00:04:02,670 --> 00:04:08,710 automatically, and then of course in line 13, I am calling my own function. 81 00:04:08,710 --> 00:04:12,805 And because I've declared that function up on line four before main, 82 00:04:12,805 --> 00:04:16,579 this is going to teach the compiler what quote, unquote, "print name" 83 00:04:16,579 --> 00:04:18,140 means and what it should do. 84 00:04:18,140 --> 00:04:22,700 So I'm sort of giving it a new custom block in the context of, say, Scratch. 85 00:04:22,700 --> 00:04:27,240 >> So in here, I can put that very common or recurring pattern of code I keep 86 00:04:27,240 --> 00:04:32,300 writing in class, printf %s hello, %s/n",-- 87 00:04:32,300 --> 00:04:36,720 88 00:04:36,720 --> 00:04:37,590 what do I want to put here? 89 00:04:37,590 --> 00:04:39,200 S? 90 00:04:39,200 --> 00:04:41,420 So I want to put name in this context. 91 00:04:41,420 --> 00:04:43,440 So notice a bit of a dichotomy here. 92 00:04:43,440 --> 00:04:47,680 Because I am declaring my own function and I have somewhat arbitrarily called 93 00:04:47,680 --> 00:04:50,880 it print name, and because I've specified in parentheses that this 94 00:04:50,880 --> 00:04:55,035 function takes one argument, the type of which is a string-- so it's a word 95 00:04:55,035 --> 00:05:00,010 or phrase or something like that-- and I'm calling that argument name, that 96 00:05:00,010 --> 00:05:04,770 means the only variable that's in scope, so to speak, is name. 97 00:05:04,770 --> 00:05:07,780 >> S only exists between what two curly braces, of course? 98 00:05:07,780 --> 00:05:12,990 Well really, just like line 10 through 14, so just like on Monday cannot use 99 00:05:12,990 --> 00:05:17,650 S, but what I can do is pass S into print name. 100 00:05:17,650 --> 00:05:21,030 Print name just so happens to give it an alias, a synonym, a nickname, 101 00:05:21,030 --> 00:05:24,400 calling it name, and now using it in this line. 102 00:05:24,400 --> 00:05:26,840 So now let me save this, zoom out. 103 00:05:26,840 --> 00:05:31,250 >> Let me go ahead and make hello. 104 00:05:31,250 --> 00:05:32,400 Looks good. 105 00:05:32,400 --> 00:05:36,110 Didn't spit out any errors. ./hello Enter. 106 00:05:36,110 --> 00:05:37,020 What's my name? 107 00:05:37,020 --> 00:05:38,060 David. 108 00:05:38,060 --> 00:05:39,270 And hello David. 109 00:05:39,270 --> 00:05:41,820 So not all that exciting, but just think now. 110 00:05:41,820 --> 00:05:44,310 You now have that same ingredient as we did in Scratch to 111 00:05:44,310 --> 00:05:45,420 make our own functions. 112 00:05:45,420 --> 00:05:46,770 >> But there is a bit of a gotcha. 113 00:05:46,770 --> 00:05:50,620 Suppose that I hadn't really thought this through and I actually without 114 00:05:50,620 --> 00:05:54,250 really thinking about it wrote that function down here. 115 00:05:54,250 --> 00:05:55,420 Feels perfectly reasonable. 116 00:05:55,420 --> 00:05:58,440 In Scratch there is no notion of location in your scripts. 117 00:05:58,440 --> 00:06:00,670 You could put one up here, one up here, one up here, and it might start 118 00:06:00,670 --> 00:06:03,310 to look a little messy if you don't lay it out neatly, but it doesn't 119 00:06:03,310 --> 00:06:05,910 matter where physically the scripts were on the screen. 120 00:06:05,910 --> 00:06:09,660 Unfortunately in C-- and this is unlike languages like Java and Python 121 00:06:09,660 --> 00:06:13,600 and others that you might be familiar with-- unfortunately in C, order does 122 00:06:13,600 --> 00:06:15,830 matter because watch what's going to happen now. 123 00:06:15,830 --> 00:06:19,010 >> The default function that's going to execute is, of course, main. 124 00:06:19,010 --> 00:06:22,290 Main is going to call print name on line eight, but unfortunately, the 125 00:06:22,290 --> 00:06:26,660 compiler won't even know that print name exists until it gets to line 11, 126 00:06:26,660 --> 00:06:28,520 which unfortunately is going to be too late. 127 00:06:28,520 --> 00:06:30,660 So let's do make hello. 128 00:06:30,660 --> 00:06:32,950 And now damn, two errors generated. 129 00:06:32,950 --> 00:06:36,050 So now let me scroll up to the very first, as we should always do, and 130 00:06:36,050 --> 00:06:39,560 notice that it's yelling at me, "implicit declaration of function 131 00:06:39,560 --> 00:06:40,540 print name." 132 00:06:40,540 --> 00:06:43,860 >> So we've seen this message before, implicit declaration of function. 133 00:06:43,860 --> 00:06:48,080 When have we seen that kind of error? 134 00:06:48,080 --> 00:06:49,180 When I didn't include a library. 135 00:06:49,180 --> 00:06:53,470 If I forgot cs50.h and I would get yelled at for get string or get int. 136 00:06:53,470 --> 00:06:56,880 But in this case, this function print name isn't in a library, right? 137 00:06:56,880 --> 00:07:00,230 It's literally in this file, so what's really the problem? 138 00:07:00,230 --> 00:07:04,660 >> Well unfortunately in C, it takes you so incredibly literally that if you 139 00:07:04,660 --> 00:07:08,640 want a function called print name to exist, you either have to implement 140 00:07:08,640 --> 00:07:11,940 that function at the very top of your code so that it's accessible to lower 141 00:07:11,940 --> 00:07:15,070 functions, but frankly, that becomes sloppy very quickly. 142 00:07:15,070 --> 00:07:18,160 Personally, I like putting main first because then it's very clear what this 143 00:07:18,160 --> 00:07:19,890 program does at first glance. 144 00:07:19,890 --> 00:07:23,290 And plus, you can get into weird corner cases where if x wants to call 145 00:07:23,290 --> 00:07:27,530 y but y might call x, you just physically can't actually put one 146 00:07:27,530 --> 00:07:28,540 above the other. 147 00:07:28,540 --> 00:07:31,230 >> But it turns out in C, we can solve this very simply. 148 00:07:31,230 --> 00:07:34,010 I'm going to put a little bit of space up here, and I'm just going to 149 00:07:34,010 --> 00:07:38,170 preemptively, albeit somewhat redundantly, going to teach the 150 00:07:38,170 --> 00:07:42,320 compiler that there exists a function called print name, it takes a string, 151 00:07:42,320 --> 00:07:46,330 and I'm going to call it name semicolon. 152 00:07:46,330 --> 00:07:50,220 >> So this now in line four, which we haven't seen before, is a declaration 153 00:07:50,220 --> 00:07:53,940 of a function print name, but it's only a promise that this function will 154 00:07:53,940 --> 00:07:56,620 eventually be defined, eventually be implemented. 155 00:07:56,620 --> 00:08:00,180 This now I can leave alone because now this is the definition, the 156 00:08:00,180 --> 00:08:04,090 implementation, sort of the last mile of the implementation of this 157 00:08:04,090 --> 00:08:05,130 particular function. 158 00:08:05,130 --> 00:08:08,450 So frankly it's stupid, it's annoying, but this is the way C is, and it's 159 00:08:08,450 --> 00:08:12,050 because it takes you very literally and, as a computer frankly should, 160 00:08:12,050 --> 00:08:16,020 only does exactly what you tell it to do, and so that ordering is important. 161 00:08:16,020 --> 00:08:18,940 >> So keep that in mind and again, start to notice the recurrence of patterns. 162 00:08:18,940 --> 00:08:21,850 Odds are you will, if you haven't already, start to encounter messages 163 00:08:21,850 --> 00:08:24,700 like this that at first glance seem completely cryptic, but if you start 164 00:08:24,700 --> 00:08:29,000 to look for these key words like "implicit declaration," mention of a 165 00:08:29,000 --> 00:08:32,380 function in this case-- and frankly, you sometimes even get a little green 166 00:08:32,380 --> 00:08:35,010 carrot symbol that tells you where the issue probably is-- 167 00:08:35,010 --> 00:08:40,980 you can begin to work your way through yet unseen error messages. 168 00:08:40,980 --> 00:08:45,860 Any questions on writing your own function in this way? 169 00:08:45,860 --> 00:08:47,540 >> Let's do something that's a little more compelling. 170 00:08:47,540 --> 00:08:51,760 Rather than just do something that has a side effect of printing, let me go 171 00:08:51,760 --> 00:08:55,340 ahead and save a new file, and we'll call this positive.c, even though it's 172 00:08:55,340 --> 00:08:57,600 going to be a little different versus last time. 173 00:08:57,600 --> 00:09:01,910 And this time, I want to re-implement last time's positive.C example, which 174 00:09:01,910 --> 00:09:04,430 is force the user to give me a positive integer. 175 00:09:04,430 --> 00:09:07,280 But I had to use get int last time. 176 00:09:07,280 --> 00:09:10,780 Wouldn't it have been nice if there was a function called get positive int 177 00:09:10,780 --> 00:09:13,610 that I could just outsource this piece of functionality to? 178 00:09:13,610 --> 00:09:16,480 So the difference here is we'll implement get positive int, but unlike 179 00:09:16,480 --> 00:09:20,330 print name which had a side effect-- it didn't return something to me like 180 00:09:20,330 --> 00:09:21,710 a number or a string-- 181 00:09:21,710 --> 00:09:25,510 get positive int is, of course, going to return, hopefully, a positive int. 182 00:09:25,510 --> 00:09:26,170 >> So let's do this. 183 00:09:26,170 --> 00:09:30,840 Include cs50.h, Include standard io.h. 184 00:09:30,840 --> 00:09:33,520 Int main void. 185 00:09:33,520 --> 00:09:42,160 And now in here, I'm going to go ahead and let's say int, call it n, equals 186 00:09:42,160 --> 00:09:44,270 get positive int. 187 00:09:44,270 --> 00:09:49,080 And just like get int already exists because the staff wrote it, I'm going 188 00:09:49,080 --> 00:09:53,950 to assume for the moment that get positive int exists, and now I'm going 189 00:09:53,950 --> 00:09:57,730 to go ahead and say printf, thanks for the %i/n",n. 190 00:09:57,730 --> 00:10:02,940 191 00:10:02,940 --> 00:10:07,770 >> So now if I compile this program, what is going to happen in my terminal 192 00:10:07,770 --> 00:10:09,075 window at the bottom of the screen? 193 00:10:09,075 --> 00:10:11,580 194 00:10:11,580 --> 00:10:13,900 I'm going to probably get that same error as before. 195 00:10:13,900 --> 00:10:14,570 So let's try this. 196 00:10:14,570 --> 00:10:16,450 Make positive. 197 00:10:16,450 --> 00:10:19,900 And again, implicit declaration of function, get positive int. 198 00:10:19,900 --> 00:10:21,970 So we can solve this in a couple of ways. 199 00:10:21,970 --> 00:10:27,310 I'm going to keep it simple and just put my declaration up here and get 200 00:10:27,310 --> 00:10:28,120 positive int. 201 00:10:28,120 --> 00:10:29,720 I need the so-called signature. 202 00:10:29,720 --> 00:10:32,410 The signature just refers to the aesthetics of the 203 00:10:32,410 --> 00:10:34,090 first line of the program. 204 00:10:34,090 --> 00:10:37,420 So what should get positive int return? 205 00:10:37,420 --> 00:10:37,970 >> So an int. 206 00:10:37,970 --> 00:10:41,540 I mean ideally, it would return something like positive int, but that 207 00:10:41,540 --> 00:10:42,160 doesn't exist. 208 00:10:42,160 --> 00:10:45,280 We've not seen that among our data types, so we have to deal with the 209 00:10:45,280 --> 00:10:47,170 fact that we have very few data types to work with. 210 00:10:47,170 --> 00:10:50,360 But we can return an int and just trust that it will be positive. 211 00:10:50,360 --> 00:10:52,690 It's going to be called get positive int. 212 00:10:52,690 --> 00:10:55,122 >> And now how about its arguments? 213 00:10:55,122 --> 00:10:56,440 Does it take any input? 214 00:10:56,440 --> 00:10:58,280 Does it need any input? 215 00:10:58,280 --> 00:11:00,900 So it doesn't need to know in advance anything. 216 00:11:00,900 --> 00:11:03,220 Get string doesn't, get int doesn't. 217 00:11:03,220 --> 00:11:06,430 Printf does-- it needs to have some input passed into it-- and print name 218 00:11:06,430 --> 00:11:09,020 needed some input, but get positive int does not. 219 00:11:09,020 --> 00:11:11,530 So I'm going to explicitly tell the compiler void. 220 00:11:11,530 --> 00:11:13,470 Void is the absence of anything else. 221 00:11:13,470 --> 00:11:17,990 So void means nothing is going inside of those parentheses, semicolon. 222 00:11:17,990 --> 00:11:20,840 >> And now at the bottom of my file-- and again, I'm just being kind of anal 223 00:11:20,840 --> 00:11:23,640 here putting main at the top, which is good practice because this way, 224 00:11:23,640 --> 00:11:26,220 anytime you or someone else opens your file, the 225 00:11:26,220 --> 00:11:27,400 functionality is right there. 226 00:11:27,400 --> 00:11:29,660 You can dive in from square one. 227 00:11:29,660 --> 00:11:34,190 So now I'm going to duplicate this, get positive int void, but I'm not 228 00:11:34,190 --> 00:11:35,430 going to hit a semicolon now. 229 00:11:35,430 --> 00:11:38,280 I'm going to open curly braces, and now I need to borrow 230 00:11:38,280 --> 00:11:39,700 some ideas from Monday. 231 00:11:39,700 --> 00:11:44,450 >> So as you recall, we did something like do the following while 232 00:11:44,450 --> 00:11:45,830 something was true. 233 00:11:45,830 --> 00:11:46,630 And what did I do? 234 00:11:46,630 --> 00:11:51,540 I did something like give me a positive integer, 235 00:11:51,540 --> 00:11:52,430 little bit of a prompt. 236 00:11:52,430 --> 00:11:53,540 I could use any words I want. 237 00:11:53,540 --> 00:11:54,960 And then I used what? 238 00:11:54,960 --> 00:11:59,530 Int n equals get int, no arguments to it. 239 00:11:59,530 --> 00:12:00,550 >> And notice the difference. 240 00:12:00,550 --> 00:12:04,680 When you call a function, when you use a function, you don't put in void. 241 00:12:04,680 --> 00:12:08,570 You only do that when declaring a function, teaching the compiler what 242 00:12:08,570 --> 00:12:09,780 it should expect. 243 00:12:09,780 --> 00:12:11,650 So you don't need to put void there yourself. 244 00:12:11,650 --> 00:12:12,940 >> And now what was my condition? 245 00:12:12,940 --> 00:12:19,670 Well, n is not equal to positive, but that's just pseudo-code. 246 00:12:19,670 --> 00:12:22,530 So how do I express this more cleanly? 247 00:12:22,530 --> 00:12:24,090 So less than or equal to zero. 248 00:12:24,090 --> 00:12:26,250 So again, notice you can do less than or equal to. 249 00:12:26,250 --> 00:12:28,100 Even though it's two separate symbols, you can do it on 250 00:12:28,100 --> 00:12:29,350 your keyboard as such. 251 00:12:29,350 --> 00:12:33,950 >> But there's still a bug that I screwed up last time too. 252 00:12:33,950 --> 00:12:36,950 I have to declare-- 253 00:12:36,950 --> 00:12:37,460 exactly. 254 00:12:37,460 --> 00:12:39,640 I have to declare n outside of the loop. 255 00:12:39,640 --> 00:12:44,180 So I need to put n up here, and I don't want to re-declare it in here 256 00:12:44,180 --> 00:12:46,480 lest I get a new variable. 257 00:12:46,480 --> 00:12:48,860 I just want to assign a value in here. 258 00:12:48,860 --> 00:12:54,320 >> And now I'm not quite done here. 259 00:12:54,320 --> 00:12:57,290 Let me get ahead of myself and pretend I'm done. 260 00:12:57,290 --> 00:13:01,220 Make positive, and now there's a new error. 261 00:13:01,220 --> 00:13:04,550 Control reaches end of non-void function. 262 00:13:04,550 --> 00:13:07,760 So new error message, but if you kind of tease apart each of the words, it 263 00:13:07,760 --> 00:13:09,620 probably hints at what's wrong. 264 00:13:09,620 --> 00:13:11,240 >> Control. 265 00:13:11,240 --> 00:13:14,250 Control just means to the order of operations in a program. 266 00:13:14,250 --> 00:13:16,510 The computer's in control and something went wrong. 267 00:13:16,510 --> 00:13:18,510 So it reaches the end of a non-void function. 268 00:13:18,510 --> 00:13:21,760 What function is it apparently referring to? 269 00:13:21,760 --> 00:13:24,790 What function is non-void? 270 00:13:24,790 --> 00:13:27,400 So get positive int, and a little confusing in that well, 271 00:13:27,400 --> 00:13:29,010 it's kind of void. 272 00:13:29,010 --> 00:13:33,070 It has a specification of void for its arguments, but its output is going to 273 00:13:33,070 --> 00:13:34,540 be of type n. 274 00:13:34,540 --> 00:13:37,260 So the word on the left is the so-called return type. 275 00:13:37,260 --> 00:13:40,320 The word on the inside here is the zero or more arguments 276 00:13:40,320 --> 00:13:41,970 that a function takes. 277 00:13:41,970 --> 00:13:44,060 >> So what do I need to do? 278 00:13:44,060 --> 00:13:47,650 At this point in my code, line 21 where the blinking prompt now is, I 279 00:13:47,650 --> 00:13:51,430 have a positive int inside of the variable called n. 280 00:13:51,430 --> 00:13:55,200 How do I give it back to main? 281 00:13:55,200 --> 00:13:55,960 Literally. 282 00:13:55,960 --> 00:13:59,320 Return n semicolon. 283 00:13:59,320 --> 00:14:04,090 >> So just as Colton returned a piece of paper with an answer to me by dropping 284 00:14:04,090 --> 00:14:07,020 that piece of paper in the little black box on the table, to do that in 285 00:14:07,020 --> 00:14:10,100 code, you literally just write, return n, and it's as though Colton were 286 00:14:10,100 --> 00:14:12,140 handing me something physical back. 287 00:14:12,140 --> 00:14:15,870 In this case, what's happening is get positive int is going to hand back 288 00:14:15,870 --> 00:14:19,220 what's presumably a positive integer to whom? 289 00:14:19,220 --> 00:14:21,380 Where does that value end up? 290 00:14:21,380 --> 00:14:29,080 That ends up in this variable, n, and then we proceed with line nine. 291 00:14:29,080 --> 00:14:31,920 >> So in other words, in order of operations, this program starts 292 00:14:31,920 --> 00:14:34,430 executing, and the compiler realizes, oh, you want the library? 293 00:14:34,430 --> 00:14:36,310 Let me go grab whatever's inside that. 294 00:14:36,310 --> 00:14:37,750 Oh, you want the standard IO library? 295 00:14:37,750 --> 00:14:39,660 Let me go grab whatever's inside that. 296 00:14:39,660 --> 00:14:44,510 What does the compiler say to itself when it hits line four? 297 00:14:44,510 --> 00:14:47,980 Oh, you promised to implement the function called get positive, but 298 00:14:47,980 --> 00:14:50,820 we'll get back to that later, something along those lines. 299 00:14:50,820 --> 00:14:53,450 >> Int main void just means here's the guts of my program. 300 00:14:53,450 --> 00:14:54,990 Line seven is just a curly brace. 301 00:14:54,990 --> 00:14:59,540 Line eight is saying on the left, give me 32 bits for an integer, call it n. 302 00:14:59,540 --> 00:15:02,160 On the right hand side, it's saying get positive int. 303 00:15:02,160 --> 00:15:07,120 Now let's pause that story because now I don't keep moving my cursor down. 304 00:15:07,120 --> 00:15:11,720 My cursor now goes down here because now get positive int executes. 305 00:15:11,720 --> 00:15:13,100 Int n is declared. 306 00:15:13,100 --> 00:15:14,040 Do the following. 307 00:15:14,040 --> 00:15:16,090 Printf gives me a positive integer. 308 00:15:16,090 --> 00:15:19,740 >> Get an int from the user, store it in n, and maybe do this again and again. 309 00:15:19,740 --> 00:15:23,010 This loop means that this code might execute up and down like this again 310 00:15:23,010 --> 00:15:25,810 and again, but when the user finally cooperates and gives me a positive 311 00:15:25,810 --> 00:15:31,750 int, I hit line 21, at which point the number is handed back, and which one 312 00:15:31,750 --> 00:15:34,280 should I highlight now? 313 00:15:34,280 --> 00:15:35,070 Nine. 314 00:15:35,070 --> 00:15:39,010 Control, so to speak, returns to line nine. 315 00:15:39,010 --> 00:15:40,650 That's the line that's now in charge. 316 00:15:40,650 --> 00:15:43,250 >> So that's what's been happening all this time underneath the hood, but 317 00:15:43,250 --> 00:15:46,480 when we've used functions like printf or even get string that someone else 318 00:15:46,480 --> 00:15:50,600 wrote for you, control was being handed off to someone else's code line 319 00:15:50,600 --> 00:15:51,290 by line by line. 320 00:15:51,290 --> 00:15:53,770 It's just we couldn't see it and we couldn't really depict it in this 321 00:15:53,770 --> 00:15:57,620 program because it's in some other file on the hard drive 322 00:15:57,620 --> 00:16:00,000 unbeknownst to us. 323 00:16:00,000 --> 00:16:02,100 So let's actually compile and run this now. 324 00:16:02,100 --> 00:16:03,890 >> Make positive. 325 00:16:03,890 --> 00:16:05,260 Compile, that's progress. 326 00:16:05,260 --> 00:16:06,650 ./positive. 327 00:16:06,650 --> 00:16:08,020 Give me a positive integer. 328 00:16:08,020 --> 00:16:08,800 Let's be difficult. 329 00:16:08,800 --> 00:16:10,430 Negative 1. 330 00:16:10,430 --> 00:16:11,360 Zero. 331 00:16:11,360 --> 00:16:13,370 Let's give it 50. 332 00:16:13,370 --> 00:16:18,100 Thanks for the 50, and so control has now returned. 333 00:16:18,100 --> 00:16:21,750 Any questions, then, on that? 334 00:16:21,750 --> 00:16:23,180 Yeah? 335 00:16:23,180 --> 00:16:25,630 >> [INAUDIBLE]. 336 00:16:25,630 --> 00:16:26,130 >> Say again. 337 00:16:26,130 --> 00:16:27,860 Oh, good question. 338 00:16:27,860 --> 00:16:31,100 So you might notice a parallel here that I'm kind of cutting a corner on. 339 00:16:31,100 --> 00:16:35,420 In line 12, I'm saying, get positive int returns an int, but by that same 340 00:16:35,420 --> 00:16:39,660 logic, it now stands to reason that in line six, I'm saying that main returns 341 00:16:39,660 --> 00:16:44,040 an int, but what have we never had in any of our programs? 342 00:16:44,040 --> 00:16:46,470 We've never had mention of this key word return. 343 00:16:46,470 --> 00:16:49,970 >> So it turns out that in C, at least the version of it that we're using 344 00:16:49,970 --> 00:16:55,750 made in 1999, technically, this is happening for you automatically. 345 00:16:55,750 --> 00:16:59,300 Anytime you implement a program and you implement a function called main, 346 00:16:59,300 --> 00:17:04,230 that function will return zero by default if you don't say otherwise, 347 00:17:04,230 --> 00:17:05,849 and zero is just a convention. 348 00:17:05,849 --> 00:17:09,430 The world returns zero thereby indicating that all is well, 349 00:17:09,430 --> 00:17:13,040 effectively leaving us with four billion possible things that could go 350 00:17:13,040 --> 00:17:17,530 wrong so that if we return one, that might signify a code that means this 351 00:17:17,530 --> 00:17:18,310 thing went wrong. 352 00:17:18,310 --> 00:17:20,589 We could return two, which means this other thing went wrong. 353 00:17:20,589 --> 00:17:23,440 We could return four billion, which means this other thing went wrong. 354 00:17:23,440 --> 00:17:27,170 >> And if you now think about your own PC or Mac, you might recall that 355 00:17:27,170 --> 00:17:29,610 sometimes you get cryptic error messages from software that you're 356 00:17:29,610 --> 00:17:32,650 using, and sometimes it has a human friendly description, but there's 357 00:17:32,650 --> 00:17:35,265 often a code or a number on the screen? 358 00:17:35,265 --> 00:17:37,800 If this doesn't come to mind, just keep an eye out for it. 359 00:17:37,800 --> 00:17:40,790 That's typically what these codes are referring to. 360 00:17:40,790 --> 00:17:44,200 They're included in Microsoft Word and other programs so that if you file a 361 00:17:44,200 --> 00:17:48,850 bug report with the company, you can tell them, oh, I got error number 45. 362 00:17:48,850 --> 00:17:51,750 And some programmer back at the company can look that up in his or her 363 00:17:51,750 --> 00:17:54,940 code and say, oh, that's because I made this bug and that's why the user 364 00:17:54,940 --> 00:17:56,240 got this message. 365 00:17:56,240 --> 00:17:59,490 >> But frankly, it's just a little distracting and a little tedious to 366 00:17:59,490 --> 00:18:02,130 conclude that, at least on our first few programs, so we've 367 00:18:02,130 --> 00:18:02,970 been omitting it. 368 00:18:02,970 --> 00:18:07,450 But all this time every one of your functions main has secretly had this 369 00:18:07,450 --> 00:18:11,600 line automatically added for you by the compiler, just by convention to 370 00:18:11,600 --> 00:18:13,172 save you some time. 371 00:18:13,172 --> 00:18:14,620 >> [INAUDIBLE]. 372 00:18:14,620 --> 00:18:16,250 >> You do not need to include it in main. 373 00:18:16,250 --> 00:18:16,700 That's fine. 374 00:18:16,700 --> 00:18:20,260 You do need to include it if you were implementing a function like this. 375 00:18:20,260 --> 00:18:22,850 Otherwise the function flat out would not work. 376 00:18:22,850 --> 00:18:24,480 But in main, it's not necessary. 377 00:18:24,480 --> 00:18:28,450 In a week or two, we'll start getting into that habit once we want to start 378 00:18:28,450 --> 00:18:29,690 signifying errors. 379 00:18:29,690 --> 00:18:32,550 Really good question. 380 00:18:32,550 --> 00:18:36,880 >> So quick verbal break to mention that this Friday, we won't be having lunch 381 00:18:36,880 --> 00:18:39,980 per se, but we'll be having dinner with some of the students and staff. 382 00:18:39,980 --> 00:18:42,940 If you'd like to join us, feel free to go to cs50.net/rsvp. 383 00:18:42,940 --> 00:18:45,030 6:00 PM this Friday. 384 00:18:45,030 --> 00:18:47,990 Space is, as always, limited, but we'll continue doing these on a nearly 385 00:18:47,990 --> 00:18:51,420 weekly basis if space runs out this week. 386 00:18:51,420 --> 00:18:56,160 >> So the cliffhanger that we left off on Monday was that strings can actually 387 00:18:56,160 --> 00:19:00,520 be indexed into, which just means you can get at the first character, the 388 00:19:00,520 --> 00:19:03,770 second character, the third character and so forth, because you can 389 00:19:03,770 --> 00:19:07,860 effectively think of a string, like hello, as being in this case five 390 00:19:07,860 --> 00:19:09,670 letters inside of boxes. 391 00:19:09,670 --> 00:19:13,370 And you can get at each of those boxes with what syntax did we 392 00:19:13,370 --> 00:19:15,230 introduce on Monday? 393 00:19:15,230 --> 00:19:16,760 Those square brackets on your keyboard. 394 00:19:16,760 --> 00:19:18,980 That just meant go to location zero. 395 00:19:18,980 --> 00:19:22,840 >> We start counting at zero, so bracket zero signifies h, bracket one 396 00:19:22,840 --> 00:19:25,170 signifies e, and so forth. 397 00:19:25,170 --> 00:19:28,490 And so all the time when we've been using strings and typing in "hello" 398 00:19:28,490 --> 00:19:31,250 and "world" and other things on the screen, it's been stored 399 00:19:31,250 --> 00:19:32,820 in boxes like this. 400 00:19:32,820 --> 00:19:33,370 And take a guess. 401 00:19:33,370 --> 00:19:37,470 What does each box represent physically inside of your computer? 402 00:19:37,470 --> 00:19:38,250 >> [INAUDIBLE]. 403 00:19:38,250 --> 00:19:39,150 >> Sorry? 404 00:19:39,150 --> 00:19:39,580 >> Characters. 405 00:19:39,580 --> 00:19:44,760 >> So a character, certainly in the case of strings, and a character is just 406 00:19:44,760 --> 00:19:46,800 eight bits or one byte. 407 00:19:46,800 --> 00:19:49,550 So you probably are at least vaguely familiar with the fact that your 408 00:19:49,550 --> 00:19:50,500 computer has memory. 409 00:19:50,500 --> 00:19:52,110 It has two types of memory at least. 410 00:19:52,110 --> 00:19:54,810 One is the hard disk where you save stuff permanently, and that's 411 00:19:54,810 --> 00:19:57,400 typically big so you can have movies and music and so forth. 412 00:19:57,400 --> 00:20:04,010 >> Then you have another type of memory called RAM, R-A-M, Random Access 413 00:20:04,010 --> 00:20:07,510 Memory, and this is the type of memory that is used when your computer is 414 00:20:07,510 --> 00:20:11,520 running but if you lose power or your battery dies, anything that's stored 415 00:20:11,520 --> 00:20:15,300 in RAM disappears if you lose power altogether because it's not 416 00:20:15,300 --> 00:20:16,060 persistent. 417 00:20:16,060 --> 00:20:19,120 You typically have, these days, a gig of it, two gigs, maybe more. 418 00:20:19,120 --> 00:20:23,490 And the upside of RAM is that it's much much, much faster than hard disks 419 00:20:23,490 --> 00:20:27,390 or even solid state drives these days, but it's typically more expensive so 420 00:20:27,390 --> 00:20:28,480 you have less of it. 421 00:20:28,480 --> 00:20:32,400 >> So today's conversation really refers to RAM, that type of memory that 422 00:20:32,400 --> 00:20:35,270 exists only while there's power being fed into your computer. 423 00:20:35,270 --> 00:20:40,530 So when you type in H-E-L-L-O, Enter on the keyboard, the H is going in one 424 00:20:40,530 --> 00:20:44,550 byte of RAM, the E is going in another byte of RAM, as is 425 00:20:44,550 --> 00:20:45,800 the rest of the word. 426 00:20:45,800 --> 00:20:49,010 So recall what we were able to do last time was this. 427 00:20:49,010 --> 00:20:53,940 Let me go ahead and open up the file that we called string.c, and recall 428 00:20:53,940 --> 00:20:56,860 that it looked a little something like this. 429 00:20:56,860 --> 00:20:59,860 Let me actually roll back and change it to exactly what it looked like, 430 00:20:59,860 --> 00:21:02,654 string length of s. 431 00:21:02,654 --> 00:21:04,560 >> So look at the program here. 432 00:21:04,560 --> 00:21:08,530 We include the CS50 library so that we can use get string. 433 00:21:08,530 --> 00:21:11,400 We include standard io.h so we can use printf. 434 00:21:11,400 --> 00:21:13,580 Why did we include string.h? 435 00:21:13,580 --> 00:21:16,980 This was new on Monday. 436 00:21:16,980 --> 00:21:18,230 So we wanted string length. 437 00:21:18,230 --> 00:21:19,090 Str leng. 438 00:21:19,090 --> 00:21:21,470 People decided years ago, let's just be succinct. 439 00:21:21,470 --> 00:21:24,290 Instead of calling it "string length," let's call it "str leng" and let the 440 00:21:24,290 --> 00:21:28,540 world figure that out, and so that's what we get access to with string.h. 441 00:21:28,540 --> 00:21:29,390 >> This is familiar. 442 00:21:29,390 --> 00:21:30,320 This is familiar. 443 00:21:30,320 --> 00:21:31,450 This is familiar. 444 00:21:31,450 --> 00:21:32,370 This is a little new. 445 00:21:32,370 --> 00:21:35,420 In line 22-- and we'll come back to this, but for now know-- 446 00:21:35,420 --> 00:21:37,880 and you would only know this from having read the documentation or if 447 00:21:37,880 --> 00:21:39,010 you knew C already-- 448 00:21:39,010 --> 00:21:41,510 get string sometimes can screw up. 449 00:21:41,510 --> 00:21:45,130 If the user is really adversarial or uncooperative and he or she just 450 00:21:45,130 --> 00:21:49,450 doesn't type anything at the keyboard or types so much at the keyboard that 451 00:21:49,450 --> 00:21:53,760 it overwhelms the computer's memory, in theory, get string could return 452 00:21:53,760 --> 00:21:56,270 something other than a string of characters. 453 00:21:56,270 --> 00:22:01,930 It could return a special value called NULL in all caps, N-U-L-L, and this is 454 00:22:01,930 --> 00:22:03,390 just a so-called sentinel value. 455 00:22:03,390 --> 00:22:08,010 It's a special value that signifies something bad happened in this case. 456 00:22:08,010 --> 00:22:10,520 It is the absence of a string. 457 00:22:10,520 --> 00:22:16,190 >> So null I'm checking for simply so that, long story short, str leng and 458 00:22:16,190 --> 00:22:20,230 other functions that come with C, if they expect a string but you pass them 459 00:22:20,230 --> 00:22:23,630 the absence of a string, if you pass them NULL, the computer or the program 460 00:22:23,630 --> 00:22:25,000 will just crash outright. 461 00:22:25,000 --> 00:22:25,610 It will hang. 462 00:22:25,610 --> 00:22:27,250 It will throw up some error message. 463 00:22:27,250 --> 00:22:28,690 Bad things will happen. 464 00:22:28,690 --> 00:22:31,130 So even though this is still not well-defined-- 465 00:22:31,130 --> 00:22:33,730 this will make more sense in a week or two-- in line 22, this is just an 466 00:22:33,730 --> 00:22:38,790 example of self defensive error checking just in case one time out of 467 00:22:38,790 --> 00:22:42,040 a million something goes wrong, at least my program won't crash. 468 00:22:42,040 --> 00:22:45,960 >> So if s does not equals something bad, I have this for loop, and this was 469 00:22:45,960 --> 00:22:47,710 where we had that other new piece of syntax. 470 00:22:47,710 --> 00:22:51,580 I have a for loop iterating from zero on up to the length of s. 471 00:22:51,580 --> 00:22:56,140 And then here, I was a printing out s bracket i, but why did I use %c all of 472 00:22:56,140 --> 00:23:00,770 a sudden instead of %s even though s is a string? 473 00:23:00,770 --> 00:23:02,110 It's a character, right? 474 00:23:02,110 --> 00:23:06,560 S is a string, but s bracket something, s bracket i where i is zero 475 00:23:06,560 --> 00:23:10,380 or one or two, that's an individual character in the string, and so for 476 00:23:10,380 --> 00:23:14,970 that, printf needs to be informed that it's indeed a character to expect. 477 00:23:14,970 --> 00:23:18,096 >> And then recall, what did this program actually do? 478 00:23:18,096 --> 00:23:19,848 >> Printed it out in columns. 479 00:23:19,848 --> 00:23:21,120 >> Yeah, exactly. 480 00:23:21,120 --> 00:23:24,990 It just printed the word that I type in a column, one character per line. 481 00:23:24,990 --> 00:23:26,190 So let's see this again. 482 00:23:26,190 --> 00:23:27,810 So make string. 483 00:23:27,810 --> 00:23:30,200 Compiled OK. ./string. 484 00:23:30,200 --> 00:23:35,560 Let me type in H-E-L-L-O, Enter, and indeed I get it, one per line. 485 00:23:35,560 --> 00:23:37,280 >> So let me do one optimization here. 486 00:23:37,280 --> 00:23:40,240 If you think about it, especially if you've programmed before, there's 487 00:23:40,240 --> 00:23:43,340 arguably an inefficiency in line 24. 488 00:23:43,340 --> 00:23:46,160 In other words, it's not necessarily the best design. 489 00:23:46,160 --> 00:23:50,200 Straightforward, at least once you remember what str leng is, but it's 490 00:23:50,200 --> 00:23:52,640 doing something dumb potentially. 491 00:23:52,640 --> 00:23:54,863 What might that be? 492 00:23:54,863 --> 00:23:56,280 >> [INAUDIBLE]. 493 00:23:56,280 --> 00:23:56,800 >> Exactly. 494 00:23:56,800 --> 00:24:00,340 It's checking for the length of s every single time even though 495 00:24:00,340 --> 00:24:02,980 H-E-L-L-O is always going to be five characters. 496 00:24:02,980 --> 00:24:05,490 Every time through this loop, the five is not changing. 497 00:24:05,490 --> 00:24:08,750 I might be incrementing i, but what is the length of s on every 498 00:24:08,750 --> 00:24:09,690 iteration of this loop? 499 00:24:09,690 --> 00:24:15,810 It's five, it's five, it's five, and yet I am nonetheless asking this 500 00:24:15,810 --> 00:24:18,320 question again and again and again. 501 00:24:18,320 --> 00:24:20,750 Now frankly, the computer is so damn fast, no one's going to notice a 502 00:24:20,750 --> 00:24:23,780 difference in this case, but these kinds of poor design decisions can 503 00:24:23,780 --> 00:24:28,330 start to add up if the compiler itself doesn't try to fix this for you which 504 00:24:28,330 --> 00:24:30,630 it typically wouldn't, at least in the appliance. 505 00:24:30,630 --> 00:24:31,540 >> So I'm going to do this. 506 00:24:31,540 --> 00:24:34,580 I'm going to add a comma after my first variable, i. 507 00:24:34,580 --> 00:24:37,310 I'm going to give myself another variable, calling it n, just by 508 00:24:37,310 --> 00:24:41,330 convention for numbers, and then I'm going to assign n the value of string 509 00:24:41,330 --> 00:24:42,530 length of s. 510 00:24:42,530 --> 00:24:46,060 And then I'm going to change my condition to be what? 511 00:24:46,060 --> 00:24:51,960 I'm going to change my condition to while i is less than n. 512 00:24:51,960 --> 00:24:55,700 >> So now, how many times am I checking the length of s? 513 00:24:55,700 --> 00:25:00,110 Once, but it's OK to check i against n again and again because now those 514 00:25:00,110 --> 00:25:03,170 values are not actually changing. 515 00:25:03,170 --> 00:25:06,020 Now for now, just know that anytime you call a function, there's a bit of 516 00:25:06,020 --> 00:25:09,930 overhead, not enough to discourage you really from ever using functions, but 517 00:25:09,930 --> 00:25:12,750 certainly when there's a line of code like that-- and the lines will get 518 00:25:12,750 --> 00:25:15,490 more interesting before long-- where there's an opportunity to think, if I 519 00:25:15,490 --> 00:25:18,320 type this code, how many times will it execute? 520 00:25:18,320 --> 00:25:20,950 You'll start to see over time the performance of your programs can 521 00:25:20,950 --> 00:25:21,660 indeed change. 522 00:25:21,660 --> 00:25:24,110 >> In fact, one of the problem sets we've done in years past involves 523 00:25:24,110 --> 00:25:27,600 implementing, as you may recall from week zero, a spell checker, but a 524 00:25:27,600 --> 00:25:31,380 spell checker that's designed to support a dictionary of 150,000 plus 525 00:25:31,380 --> 00:25:32,860 words that we give you guys. 526 00:25:32,860 --> 00:25:37,100 You would have to write code that loads those words into RAM, so into 527 00:25:37,100 --> 00:25:40,700 boxes like we saw on the screen a moment ago, and then as fast as you 528 00:25:40,700 --> 00:25:43,740 can, you need to be able to answer a question of the form, is this word 529 00:25:43,740 --> 00:25:44,280 misspelled? 530 00:25:44,280 --> 00:25:45,420 Is this word misspelled? 531 00:25:45,420 --> 00:25:46,770 Is this word misspelled? 532 00:25:46,770 --> 00:25:49,525 >> And in something like that what we've done in years past is turned it into, 533 00:25:49,525 --> 00:25:53,500 albeit on an opt-in optional basis, a competition of sorts, whereby the 534 00:25:53,500 --> 00:25:59,470 students who use the less RAM and less time, fewer CPU cycles, end up 535 00:25:59,470 --> 00:26:02,640 bubbling up to the top of a little leader board or ranking that we put on 536 00:26:02,640 --> 00:26:04,770 the course's homepage as we've done in years past. 537 00:26:04,770 --> 00:26:08,100 So again, totally optional, but this speaks to the design opportunities 538 00:26:08,100 --> 00:26:11,250 that are ahead once we start building atop some of these 539 00:26:11,250 --> 00:26:14,010 basic building blocks. 540 00:26:14,010 --> 00:26:16,780 >> So let me go back to this diagram for just a moment and reveal a little 541 00:26:16,780 --> 00:26:17,610 something more. 542 00:26:17,610 --> 00:26:21,400 This indeed is a string, and we've taken advantage of a few libraries, 543 00:26:21,400 --> 00:26:25,150 standard io.h which has-- 544 00:26:25,150 --> 00:26:26,110 >> Printf. 545 00:26:26,110 --> 00:26:27,860 >> Printf, among other things. 546 00:26:27,860 --> 00:26:31,540 cs50.h, which has get int and get string and so forth, string.h, which 547 00:26:31,540 --> 00:26:32,570 had str leng. 548 00:26:32,570 --> 00:26:34,800 But it turns out there's yet another. 549 00:26:34,800 --> 00:26:38,540 Frankly, there's lots and lots of header files that declare functions 550 00:26:38,540 --> 00:26:43,320 for libraries, but this ctype.h is actually going to be somewhat 551 00:26:43,320 --> 00:26:46,900 advantageous because I'm going to go ahead and implement one 552 00:26:46,900 --> 00:26:48,120 other program here. 553 00:26:48,120 --> 00:26:52,420 >> Let me go ahead and open up something I wrote in advance called 554 00:26:52,420 --> 00:26:55,750 capitalize.c, and let's take a look at how this works. 555 00:26:55,750 --> 00:27:00,340 Notice that I'm using, in this version of it, three familiar files. 556 00:27:00,340 --> 00:27:04,110 Notice that in line 18, I'm getting a line of text. 557 00:27:04,110 --> 00:27:07,660 Notice in line 21, I'm claiming that the following code is going to 558 00:27:07,660 --> 00:27:12,170 capitalize s, whatever the user typed in, and how am I doing that? 559 00:27:12,170 --> 00:27:13,300 Well, I'm taking-- 560 00:27:13,300 --> 00:27:14,750 lesson learned from last time-- 561 00:27:14,750 --> 00:27:18,370 I'm declaring i and n and iterating over the characters in the string. 562 00:27:18,370 --> 00:27:22,720 And then what is this block of code in line 24 through 27 563 00:27:22,720 --> 00:27:24,550 doing in layman's terms? 564 00:27:24,550 --> 00:27:27,766 565 00:27:27,766 --> 00:27:29,730 >> Lowercase letter back. 566 00:27:29,730 --> 00:27:30,430 >> Exactly. 567 00:27:30,430 --> 00:27:35,920 If s bracket i-- so if the i-th character of s, which is a specific 568 00:27:35,920 --> 00:27:40,220 char in the string, is greater than or equal to lowercase a and-- 569 00:27:40,220 --> 00:27:42,670 recall that double ampersand signify and-- 570 00:27:42,670 --> 00:27:46,810 and the same character, s bracket i, is less than or equal to lowercase z, 571 00:27:46,810 --> 00:27:50,600 that means it's an a or a b or a c or dot, dot, dot, or a z, which means 572 00:27:50,600 --> 00:27:51,340 it's lowercase. 573 00:27:51,340 --> 00:27:52,900 What do I want to do in that case? 574 00:27:52,900 --> 00:27:55,010 Well, I can do this somewhat cryptically, but 575 00:27:55,010 --> 00:27:56,160 let's tease this apart. 576 00:27:56,160 --> 00:28:00,210 >> I'm going to call printf, prints %c because I want to reprint this 577 00:28:00,210 --> 00:28:01,580 character on the screen. 578 00:28:01,580 --> 00:28:06,650 I'm then going to take s bracket i, the i-th character in s, and then why 579 00:28:06,650 --> 00:28:12,330 am I doing this little trick here, lowercase a minus capital A? 580 00:28:12,330 --> 00:28:16,352 What is that going to give me, generally speaking? 581 00:28:16,352 --> 00:28:18,600 >> [INAUDIBLE]. 582 00:28:18,600 --> 00:28:19,390 >> Exactly. 583 00:28:19,390 --> 00:28:20,860 I don't really remember-- 584 00:28:20,860 --> 00:28:24,390 it was 65 for capital A. I don't really remember what lowercase a is, 585 00:28:24,390 --> 00:28:25,540 but no matter. 586 00:28:25,540 --> 00:28:26,580 The computer knows. 587 00:28:26,580 --> 00:28:30,380 So by saying, lowercase a minus capital A, it's weird to be 588 00:28:30,380 --> 00:28:33,530 subtracting one char from another, but what are chars underneath the hood? 589 00:28:33,530 --> 00:28:34,520 They're just numbers. 590 00:28:34,520 --> 00:28:36,980 So whatever those numbers are, let the computer remember it 591 00:28:36,980 --> 00:28:38,240 rather than me the human. 592 00:28:38,240 --> 00:28:41,710 >> So lowercase a minus capital A is going to give me a difference. 593 00:28:41,710 --> 00:28:45,370 It happens to be 32, and that would be the case for lowercase b and capital B 594 00:28:45,370 --> 00:28:45,930 and so forth. 595 00:28:45,930 --> 00:28:47,710 It stays consistent, thankfully. 596 00:28:47,710 --> 00:28:51,930 So I'm essentially saying, take the lowercase letter, subtract off that 597 00:28:51,930 --> 00:28:55,340 standard difference, and that effectively changes s bracket i from 598 00:28:55,340 --> 00:28:59,400 lowercase to, of course, uppercase, without my really having to think 599 00:28:59,400 --> 00:29:03,040 about or remember, what were those numbers we talked about when the eight 600 00:29:03,040 --> 00:29:04,800 volunteers came up on stage? 601 00:29:04,800 --> 00:29:08,800 Now meanwhile, in the else, if it's not a lowercase letter as determined 602 00:29:08,800 --> 00:29:10,400 by line 24, just print it out. 603 00:29:10,400 --> 00:29:12,590 I only want to touch the characters that were 604 00:29:12,590 --> 00:29:14,410 actually originally lowercase. 605 00:29:14,410 --> 00:29:15,150 >> So let's see this. 606 00:29:15,150 --> 00:29:17,400 Make capitalize. 607 00:29:17,400 --> 00:29:18,470 Compiled, OK. 608 00:29:18,470 --> 00:29:19,730 ./capitalize. 609 00:29:19,730 --> 00:29:23,530 And let me type in H-E-L-L-O in lowercase, Enter. 610 00:29:23,530 --> 00:29:26,370 And notice that it is converted into uppercase. 611 00:29:26,370 --> 00:29:27,940 Let me do this again with a different word. 612 00:29:27,940 --> 00:29:32,720 How about D-A-V-I-D with the first D capitalized as a name typically is? 613 00:29:32,720 --> 00:29:33,560 Enter. 614 00:29:33,560 --> 00:29:34,870 Notice it's still correct. 615 00:29:34,870 --> 00:29:40,250 It just outputted that first D unchanged via that else construct. 616 00:29:40,250 --> 00:29:42,170 >> So keep in mind, then, a couple of things here. 617 00:29:42,170 --> 00:29:45,060 One, if you ever want to check two conditions at once, you can and them 618 00:29:45,060 --> 00:29:46,500 together as we predicted. 619 00:29:46,500 --> 00:29:49,900 You can compare characters in this way and effectively treat characters as 620 00:29:49,900 --> 00:29:53,050 numbers, but frankly, this is so damn cryptic I'm never going to remember 621 00:29:53,050 --> 00:29:56,510 how to come up with this from scratch without reasoning through it for quite 622 00:29:56,510 --> 00:29:57,140 a bit of time. 623 00:29:57,140 --> 00:30:00,590 >> Wouldn't it have been nice if someone out there wrote a function called is 624 00:30:00,590 --> 00:30:05,390 lower that could answer for me true or false, this character is lowercase? 625 00:30:05,390 --> 00:30:09,350 Well thankfully, whoever wrote ctype.h did exactly that. 626 00:30:09,350 --> 00:30:15,540 Let me go up here and add ctype for c types, and now let me go down here and 627 00:30:15,540 --> 00:30:18,820 rewrite this line as follows. 628 00:30:18,820 --> 00:30:27,510 >> So if it's called is lower, I claim, s bracket i, then I'm going to delete 629 00:30:27,510 --> 00:30:29,400 these two lines altogether. 630 00:30:29,400 --> 00:30:32,570 So now someone else, I'm hoping, wrote a function called is lower, and it 631 00:30:32,570 --> 00:30:36,250 turns out they did and they declared it inside of ctype.h. 632 00:30:36,250 --> 00:30:39,480 And now I'm going to leave line 27 alone, I'm going to leave line 31 633 00:30:39,480 --> 00:30:41,890 alone, but notice how much I've tightened up my code. 634 00:30:41,890 --> 00:30:42,690 It's now cleaner. 635 00:30:42,690 --> 00:30:47,250 It's less difficult to look through because now the function, moreover, is 636 00:30:47,250 --> 00:30:50,080 so wonderfully named it just does what it says. 637 00:30:50,080 --> 00:30:51,520 >> So now I'm going to save this. 638 00:30:51,520 --> 00:30:52,930 I'm going to zoom out. 639 00:30:52,930 --> 00:30:56,650 And just as in Scratch you could have Booleans, Boolean values true or 640 00:30:56,650 --> 00:31:01,530 false, that's exactly what is lower effectively returns. 641 00:31:01,530 --> 00:31:02,960 Let me recompile. 642 00:31:02,960 --> 00:31:04,500 Let me re-run. 643 00:31:04,500 --> 00:31:07,350 And now let's try it again, H-E-L-L-O, Enter. 644 00:31:07,350 --> 00:31:07,970 That's pretty good. 645 00:31:07,970 --> 00:31:10,150 And try it again, make sure I didn't screw something up. 646 00:31:10,150 --> 00:31:11,670 That is capitalized as well. 647 00:31:11,670 --> 00:31:14,190 >> But this isn't good enough because the other thing that I'm never going to 648 00:31:14,190 --> 00:31:19,090 remember unless I work through it really carefully on, say, paper is 649 00:31:19,090 --> 00:31:19,920 this damn line. 650 00:31:19,920 --> 00:31:23,450 Wouldn't it be nice if there were a function called to upper? 651 00:31:23,450 --> 00:31:26,930 Well it turns out there is in ctype.h as well. 652 00:31:26,930 --> 00:31:30,150 I'm going to go ahead and type-- 653 00:31:30,150 --> 00:31:31,340 let me bring that line back. 654 00:31:31,340 --> 00:31:36,430 Instead of this here, let me go ahead and say, substitute for the %c the 655 00:31:36,430 --> 00:31:42,110 result of calling this function to upper on the i-th character of s. 656 00:31:42,110 --> 00:31:45,430 And now notice it's getting a little balanced. 657 00:31:45,430 --> 00:31:48,870 I have to keep track of how many parentheses I've opened and closed. 658 00:31:48,870 --> 00:31:50,050 >> So now it's even cleaner. 659 00:31:50,050 --> 00:31:53,460 Now this program is getting better and better designed arguably because it's 660 00:31:53,460 --> 00:31:56,450 much, much more readable but it's no let's correct. 661 00:31:56,450 --> 00:31:57,600 Make capitalize. 662 00:31:57,600 --> 00:31:58,930 ./capitalize. 663 00:31:58,930 --> 00:32:03,220 H-E-L-L-O. Let's run it again, D-A-V-I-D. OK, so we're still in 664 00:32:03,220 --> 00:32:04,250 pretty good shape. 665 00:32:04,250 --> 00:32:06,030 >> But now to upper. 666 00:32:06,030 --> 00:32:09,720 I propose that there's one more refinement we could make that would be 667 00:32:09,720 --> 00:32:12,820 really nice, that could really tighten up this code and really give us five 668 00:32:12,820 --> 00:32:15,150 out of five for design, for instance. 669 00:32:15,150 --> 00:32:16,510 What would be nice to get rid of? 670 00:32:16,510 --> 00:32:20,770 Well, look how damn long this block of code is just to do something simple. 671 00:32:20,770 --> 00:32:23,850 >> Now as an aside, as you might have seen in super section this past 672 00:32:23,850 --> 00:32:27,570 weekend, you don't strictly need the curly braces when you just have one 673 00:32:27,570 --> 00:32:32,180 line of code, even though we proposed keeping them so that it makes much 674 00:32:32,180 --> 00:32:36,190 more clear, like in Scratch's U-shaped blocks, what's inside of the branch. 675 00:32:36,190 --> 00:32:40,170 But wouldn't it be nice if to upper, when given its input, turned it into 676 00:32:40,170 --> 00:32:44,730 uppercase if it's not, and what would be wonderful in the opposite case if 677 00:32:44,730 --> 00:32:47,210 it's already uppercase? 678 00:32:47,210 --> 00:32:49,620 Just pass it through and leave it alone. 679 00:32:49,620 --> 00:32:50,660 >> So maybe it does that. 680 00:32:50,660 --> 00:32:52,990 I could try and just hope that it does, but let me 681 00:32:52,990 --> 00:32:54,450 introduce one other thing. 682 00:32:54,450 --> 00:32:57,440 Instead of using this built-in terminal window down here, recall that 683 00:32:57,440 --> 00:33:01,130 this square black icon gives you a bigger terminal window that I can full 684 00:33:01,130 --> 00:33:02,260 screen if I want? 685 00:33:02,260 --> 00:33:05,820 So it turns out they're sort of oddly named, but there's these things called 686 00:33:05,820 --> 00:33:10,970 man pages, manual pages, man for short, and I can access these by 687 00:33:10,970 --> 00:33:14,515 typing man-- 688 00:33:14,515 --> 00:33:15,570 what do I want to type? 689 00:33:15,570 --> 00:33:17,830 Man to upper. 690 00:33:17,830 --> 00:33:21,090 >> And now notice if there exists a function inside of the computer, in 691 00:33:21,090 --> 00:33:23,970 this case the appliance, which is just the operating system Linux, it's going 692 00:33:23,970 --> 00:33:27,920 to give me a somewhat cryptic set of output, but you'll find over time that 693 00:33:27,920 --> 00:33:31,720 it always is formatted pretty much the same so you start to get used to it. 694 00:33:31,720 --> 00:33:35,130 Notice at the top to upper, and apparently is the same documentation 695 00:33:35,130 --> 00:33:35,680 for to lower. 696 00:33:35,680 --> 00:33:38,740 Whoever wrote it was cutting some corners and put it all on one page. 697 00:33:38,740 --> 00:33:40,720 These things' purpose in life is to convert a 698 00:33:40,720 --> 00:33:42,780 letter to upper or lowercase. 699 00:33:42,780 --> 00:33:46,290 >> Notice that under Synopsis, the man page is teaching me what file I have 700 00:33:46,290 --> 00:33:48,130 to include to use this thing. 701 00:33:48,130 --> 00:33:51,320 It's giving me the signatures for these functions, both of them, even 702 00:33:51,320 --> 00:33:53,510 though we right now only care about one. 703 00:33:53,510 --> 00:33:54,730 Here is now a description. 704 00:33:54,730 --> 00:33:58,800 To upper converts the letter c to uppercase if possible. 705 00:33:58,800 --> 00:34:02,280 >> Still not that instructive, but let me now look under return value, the thing 706 00:34:02,280 --> 00:34:03,520 that's handed back. 707 00:34:03,520 --> 00:34:08,600 So the value returned is that of the converted letter or c if the 708 00:34:08,600 --> 00:34:09,870 conversion was not possible. 709 00:34:09,870 --> 00:34:11,202 What is c? 710 00:34:11,202 --> 00:34:12,560 >> The original character. 711 00:34:12,560 --> 00:34:15,370 >> The original character and we know that by, again, going up to the 712 00:34:15,370 --> 00:34:19,179 synopsis, and whoever wrote this function just decided that the input 713 00:34:19,179 --> 00:34:22,909 to to upper and to lower is just arbitrarily going to be called c. 714 00:34:22,909 --> 00:34:24,909 They could have called it most anything they want, but they kept it 715 00:34:24,909 --> 00:34:26,270 simple as c. 716 00:34:26,270 --> 00:34:27,880 So I've consulted the man page. 717 00:34:27,880 --> 00:34:31,870 This sentence reassures me that if it's not a lowercase letter, it's 718 00:34:31,870 --> 00:34:34,969 going to just give me back c, which is perfect, which means I can get rid of 719 00:34:34,969 --> 00:34:36,199 my else condition. 720 00:34:36,199 --> 00:34:39,679 >> So let me go back to GEdit, and now let me just do this. 721 00:34:39,679 --> 00:34:41,960 I'm going to copy my printf statement. 722 00:34:41,960 --> 00:34:45,969 I'm going to go ahead and right inside the for loop print that out, and get 723 00:34:45,969 --> 00:34:48,760 rid of now this whole if construct. 724 00:34:48,760 --> 00:34:51,860 Wasn't a bad idea, and it was very much correct and consistent with 725 00:34:51,860 --> 00:34:54,100 everything we've preached, but just not necessary. 726 00:34:54,100 --> 00:34:57,070 As soon as you realize some library function exists that someone else 727 00:34:57,070 --> 00:35:01,340 wrote, or maybe you wrote elsewhere in the file, you can use it and really 728 00:35:01,340 --> 00:35:02,690 start to tighten up the code. 729 00:35:02,690 --> 00:35:06,080 >> And when I say things like good style, the fact that this person called the 730 00:35:06,080 --> 00:35:11,490 function to upper, or previously is lower is wonderfully useful because 731 00:35:11,490 --> 00:35:12,900 they're very descriptive. 732 00:35:12,900 --> 00:35:16,120 You wouldn't want to call your functions x and y and z, which have 733 00:35:16,120 --> 00:35:19,620 much, much less meaning. 734 00:35:19,620 --> 00:35:25,160 Any questions on that series of improvements? 735 00:35:25,160 --> 00:35:28,010 >> So suffice it to say one of the takeaways is even as your own problem 736 00:35:28,010 --> 00:35:30,960 set-- maybe problem set one, but certainly P set two and onward, even 737 00:35:30,960 --> 00:35:34,380 when they're correct doesn't necessarily mean they are perfect just 738 00:35:34,380 --> 00:35:36,155 yet or particularly well-designed. 739 00:35:36,155 --> 00:35:38,420 That's the other axis to start thinking about. 740 00:35:38,420 --> 00:35:41,730 So this was a string inside of your computer's memory, but if you have a 741 00:35:41,730 --> 00:35:46,180 whole bunch of characters like H-E-L-L-O inside of RAM, and suppose 742 00:35:46,180 --> 00:35:51,330 that you in your program call get string multiple times such that you 743 00:35:51,330 --> 00:35:54,200 call get string once, then you call get string again. 744 00:35:54,200 --> 00:35:55,880 Well, what's going to happen over time? 745 00:35:55,880 --> 00:35:59,170 >> In other words, if you have a line of code, albeit out of context, like 746 00:35:59,170 --> 00:36:02,120 string s gets-- 747 00:36:02,120 --> 00:36:02,960 let's do this. 748 00:36:02,960 --> 00:36:05,270 String name equals get string. 749 00:36:05,270 --> 00:36:08,590 So suppose that line of code is meant to ask the user for his or her name. 750 00:36:08,590 --> 00:36:14,580 This next line of code is meant to ask the user for his or her school, and 751 00:36:14,580 --> 00:36:15,920 this next line, and so forth. 752 00:36:15,920 --> 00:36:18,150 Suppose that we keep asking the user for another and 753 00:36:18,150 --> 00:36:19,750 another and another string. 754 00:36:19,750 --> 00:36:22,390 They're going to stay in memory at the same time. 755 00:36:22,390 --> 00:36:24,280 One is not going to clobber the other. 756 00:36:24,280 --> 00:36:26,420 School is not overwrite the other. 757 00:36:26,420 --> 00:36:28,520 But where do they all end up in memory? 758 00:36:28,520 --> 00:36:32,030 >> Well, if we start to draw on the screen, which we can use this thing 759 00:36:32,030 --> 00:36:35,800 here like a chalkboard, if this black rectangle represents my computer's 760 00:36:35,800 --> 00:36:39,800 memory, I'm going to arbitrarily start dividing it up into little squares, 761 00:36:39,800 --> 00:36:42,120 each of which represents one byte of memory. 762 00:36:42,120 --> 00:36:46,560 Frankly, if you have a gigabyte of RAM these days, you have a billion bytes 763 00:36:46,560 --> 00:36:49,540 of memory in your computer, so a billion of these squares. 764 00:36:49,540 --> 00:36:52,110 So suffice it to say, this isn't really to scale. 765 00:36:52,110 --> 00:36:58,250 >> But we could keep drawing all of these clearly not to scale squares, and this 766 00:36:58,250 --> 00:37:01,260 collectively represents my computer's memory. 767 00:37:01,260 --> 00:37:03,136 Now we'll just do dot, dot, dot. 768 00:37:03,136 --> 00:37:06,260 So in other words, when I now prompt the user with get string to give me a 769 00:37:06,260 --> 00:37:07,350 string, what happens? 770 00:37:07,350 --> 00:37:14,270 If the user types in "hello," that ends up in H-E-L-L-O. But suppose the 771 00:37:14,270 --> 00:37:15,720 user then types in-- 772 00:37:15,720 --> 00:37:17,250 actually, I shouldn't have done hello because we're asking 773 00:37:17,250 --> 00:37:18,330 them for their names. 774 00:37:18,330 --> 00:37:20,580 So let's go back if I can do this. 775 00:37:20,580 --> 00:37:26,130 >> So if I type in D-A-V-I-D for my name, but recall that the second line of 776 00:37:26,130 --> 00:37:29,220 code was get string again to get their school. 777 00:37:29,220 --> 00:37:32,090 Where is that word that the user types in going to go next? 778 00:37:32,090 --> 00:37:38,290 Well, maybe it's going to go into H-A-R-V-A-R-D. So even though I've 779 00:37:38,290 --> 00:37:41,560 drawn it as two rows, this is just a whole bunch of bytes in your 780 00:37:41,560 --> 00:37:42,710 computer's RAM. 781 00:37:42,710 --> 00:37:46,560 There's a problem now because now if I'm using RAM in this very reasonable 782 00:37:46,560 --> 00:37:49,910 but sort of naive way, what can you not apparently distinguish? 783 00:37:49,910 --> 00:37:52,640 784 00:37:52,640 --> 00:37:54,680 Where one begins and where one ends, right? 785 00:37:54,680 --> 00:37:55,860 They're kind of blurring together. 786 00:37:55,860 --> 00:37:57,920 >> So it turns out the computer doesn't do this. 787 00:37:57,920 --> 00:38:04,720 Let me actually scroll back in time a few characters, and instead of Harvard 788 00:38:04,720 --> 00:38:09,570 going immediately after the user's name, the user actually gets, behind 789 00:38:09,570 --> 00:38:12,000 the scenes, a special character inserted by the 790 00:38:12,000 --> 00:38:13,885 computer for him or her. 791 00:38:13,885 --> 00:38:19,470 /0, otherwise known as the nul character annoyingly called N-U-L, not 792 00:38:19,470 --> 00:38:22,190 N-U-L-L, but you write it as /0. 793 00:38:22,190 --> 00:38:27,130 It's just all zero bits is a marker in between the first word that the user's 794 00:38:27,130 --> 00:38:28,290 typed and the second. 795 00:38:28,290 --> 00:38:33,020 >> So Harvard actually now ends up as this sequence of characters 796 00:38:33,020 --> 00:38:36,110 and one more /0. 797 00:38:36,110 --> 00:38:41,690 So in other words, by having these sentinel values, eight contiguous zero 798 00:38:41,690 --> 00:38:45,220 bits, you can now begin to distinguish one character from another. 799 00:38:45,220 --> 00:38:49,720 So all this time what was "hello" is actually "hello" with a /0, and 800 00:38:49,720 --> 00:38:53,580 meanwhile, there might very well be quite a bit more RAM 801 00:38:53,580 --> 00:38:56,400 inside of the computer. 802 00:38:56,400 --> 00:38:57,810 >> Let me do one other thing now. 803 00:38:57,810 --> 00:39:01,800 It turns out that all of these squares we've been drawing, they are, yes, 804 00:39:01,800 --> 00:39:06,140 strings, but more generally, these things are arrays. 805 00:39:06,140 --> 00:39:10,590 An array is just a chunk of memory that's back to back to back to back, 806 00:39:10,590 --> 00:39:15,130 and you typically use an array by way of this square bracket notation. 807 00:39:15,130 --> 00:39:18,210 So we're going to see these quite a bit over time, but let me go ahead and 808 00:39:18,210 --> 00:39:21,160 open up, let's call it ages. 809 00:39:21,160 --> 00:39:23,920 And notice what we can do with these same tricks, a little 810 00:39:23,920 --> 00:39:25,750 bit more syntax here. 811 00:39:25,750 --> 00:39:29,270 >> So in line 17 of this program-- actually, let me run the program first 812 00:39:29,270 --> 00:39:30,770 so we can see what this thing does. 813 00:39:30,770 --> 00:39:33,530 Let me call make ages to compile this program. 814 00:39:33,530 --> 00:39:34,950 ./ages. 815 00:39:34,950 --> 00:39:36,480 How many people are in the room? 816 00:39:36,480 --> 00:39:38,020 Call it three. 817 00:39:38,020 --> 00:39:39,575 Age of the first person? 818 00:39:39,575 --> 00:39:42,710 18, 19, and 20. 819 00:39:42,710 --> 00:39:46,770 And now somewhat ridiculously, I just have made a program that ages those 820 00:39:46,770 --> 00:39:47,740 three people. 821 00:39:47,740 --> 00:39:50,390 >> So there's clearly an opportunity for some fun arithmetic here. 822 00:39:50,390 --> 00:39:51,560 Thankfully, the math is correct. 823 00:39:51,560 --> 00:39:54,720 18 went to 19, 19 went to 20 and so forth. 824 00:39:54,720 --> 00:39:58,510 But what's really meant to be illustrative here is how we're storing 825 00:39:58,510 --> 00:40:00,190 those three people's ages. 826 00:40:00,190 --> 00:40:02,370 Let me zoom in at what's going on here. 827 00:40:02,370 --> 00:40:06,240 >> So first, these first few lines should be getting pretty familiar. 828 00:40:06,240 --> 00:40:08,770 I'm just prompting the user for the number of people in the room. 829 00:40:08,770 --> 00:40:11,490 Then I'm using get int and do while to do this again and again and again. 830 00:40:11,490 --> 00:40:15,780 We've seen that pattern before, but line 27 is new and actually quite 831 00:40:15,780 --> 00:40:18,160 useful, and will become increasingly useful. 832 00:40:18,160 --> 00:40:21,620 Notice that what's different in line 27 is that I appear to be declaring an 833 00:40:21,620 --> 00:40:23,960 int called ages, but wait. 834 00:40:23,960 --> 00:40:27,140 It's not just int ages. 835 00:40:27,140 --> 00:40:30,130 There's these square brackets, inside of which is n. 836 00:40:30,130 --> 00:40:35,150 >> So the bracket n in this context, not inside of a printf statement here but 837 00:40:35,150 --> 00:40:44,370 in this sole line 27, this line is saying, give me n ints, each of which 838 00:40:44,370 --> 00:40:46,080 is of type int. 839 00:40:46,080 --> 00:40:49,870 So this is a bucket, so to speak, of, in this case, three integers back to 840 00:40:49,870 --> 00:40:52,770 back to back so that I effectively have three variables. 841 00:40:52,770 --> 00:40:54,890 The alternative, to be clear, would be this. 842 00:40:54,890 --> 00:40:57,400 >> If I wanted the first student's age, I might do this. 843 00:40:57,400 --> 00:40:59,520 If I wanted the second student's age I might do this. 844 00:40:59,520 --> 00:41:01,860 If I wanted the third student's age, I might do this. 845 00:41:01,860 --> 00:41:04,320 And god forbid we need everyone's age in this room-- 846 00:41:04,320 --> 00:41:07,670 I mean, this is a heck of a lot of copy, paste again and again and again. 847 00:41:07,670 --> 00:41:10,870 And plus once I compile this program, if another student walks in over out 848 00:41:10,870 --> 00:41:14,200 of that door, now my number of variables is incorrect. 849 00:41:14,200 --> 00:41:17,450 >> So what's nice about an array is as soon as you start feeling yourself 850 00:41:17,450 --> 00:41:20,190 copying and pasting, odds are that's not the best approach. 851 00:41:20,190 --> 00:41:22,240 An array is dynamic potentially. 852 00:41:22,240 --> 00:41:24,610 I don't know in advance how many people are going to be in the room, 853 00:41:24,610 --> 00:41:28,670 but I do know I need n of them, and I'll figure out n when the time comes. 854 00:41:28,670 --> 00:41:35,500 This line of code now means, give me a chunk of memory that looks like this 855 00:41:35,500 --> 00:41:40,380 where the number of boxes on the screen is entirely dependent on n that 856 00:41:40,380 --> 00:41:42,010 the user typed in. 857 00:41:42,010 --> 00:41:44,850 >> So now the rest of this program is actually pretty similar to what we 858 00:41:44,850 --> 00:41:46,860 just did with characters. 859 00:41:46,860 --> 00:41:49,970 Notice I have a for loop starting in line 30. 860 00:41:49,970 --> 00:41:54,920 So right after I get the array, I iterate from y equals zero on up to n. 861 00:41:54,920 --> 00:41:58,890 I just have this instructive printf message just saying, give me the age 862 00:41:58,890 --> 00:42:03,690 of person #%i, so number one, number two, number three. 863 00:42:03,690 --> 00:42:04,730 And why did I do this? 864 00:42:04,730 --> 00:42:08,870 Frankly, humans prefer to count from one on up whereas computer scientists, 865 00:42:08,870 --> 00:42:09,620 zero on up. 866 00:42:09,620 --> 00:42:11,700 computer scientists are not going to use this kind of program, so we're 867 00:42:11,700 --> 00:42:13,990 going to just start counting at one like normal people. 868 00:42:13,990 --> 00:42:17,630 >> And now in line 33, notice the slightly different piece of syntax. 869 00:42:17,630 --> 00:42:23,710 The i-th age in that variable of type array is going to get an int. 870 00:42:23,710 --> 00:42:25,770 And now lastly, this is just arithmetic down here. 871 00:42:25,770 --> 00:42:29,200 I decided in a separate loop to claim some time passes, and now in this 872 00:42:29,200 --> 00:42:31,400 separate loop, these lines execute. 873 00:42:31,400 --> 00:42:35,810 >> A year from now, person i will be i years old, but notice this isn't the 874 00:42:35,810 --> 00:42:36,500 variable i. 875 00:42:36,500 --> 00:42:38,390 This is now %i for int. 876 00:42:38,390 --> 00:42:43,210 And notice as the first placeholder, I plug in i plus 1, so we count like a 877 00:42:43,210 --> 00:42:44,250 normal person. 878 00:42:44,250 --> 00:42:49,190 And then for the value of their age, for i years old, I take ages bracket 879 00:42:49,190 --> 00:42:52,980 i-- and why am I doing plus one here? 880 00:42:52,980 --> 00:42:53,760 They just aged. 881 00:42:53,760 --> 00:42:55,030 It's my stupid choice of programs. 882 00:42:55,030 --> 00:42:56,810 They just aged one year. 883 00:42:56,810 --> 00:42:59,770 I could type in any number that I actually want there. 884 00:42:59,770 --> 00:43:02,430 >> So what's actually all of the relevance here? 885 00:43:02,430 --> 00:43:07,610 Well, let me actually scroll back over here and paint a picture 886 00:43:07,610 --> 00:43:10,830 of what lies ahead. 887 00:43:10,830 --> 00:43:15,720 What we'll be doing with our next Problem Set Two is dabbling in the 888 00:43:15,720 --> 00:43:17,070 world of cryptography. 889 00:43:17,070 --> 00:43:22,500 So this is a string of characters, so a sequence of multiple chars, and what 890 00:43:22,500 --> 00:43:23,750 does this say? 891 00:43:23,750 --> 00:43:28,530 892 00:43:28,530 --> 00:43:30,600 It's not in the online version of the slides. 893 00:43:30,600 --> 00:43:35,880 >> So I claim that this equals this, a stupid advertisement from many years 894 00:43:35,880 --> 00:43:39,950 ago that might actually recall one of its origins. 895 00:43:39,950 --> 00:43:42,740 So this is an example of encryption or cryptography. 896 00:43:42,740 --> 00:43:46,150 It turns out that if you want to actually send information or share 897 00:43:46,150 --> 00:43:49,310 information with someone securely, like a message like this, you can 898 00:43:49,310 --> 00:43:50,500 scramble the letters. 899 00:43:50,500 --> 00:43:53,170 But typically, the words are not scrambled randomly. 900 00:43:53,170 --> 00:43:56,365 They're permuted in some way or changed in some way so that-- oops. 901 00:43:56,365 --> 00:43:59,040 That's a fun spoiler for next time. 902 00:43:59,040 --> 00:44:04,390 >> So you can map what is apparently O to B. Notice that lines up 903 00:44:04,390 --> 00:44:05,420 capitalization-wise. 904 00:44:05,420 --> 00:44:07,960 Apparently r becomes e. 905 00:44:07,960 --> 00:44:14,000 Apparently F-H-E-R becomes S-U-R-E. So it turns out there's a mapping, and in 906 00:44:14,000 --> 00:44:18,720 this case there's a pretty stupid mapping if anyone has figured it out? 907 00:44:18,720 --> 00:44:21,440 This is something called Rot 13, Rotate 13. 908 00:44:21,440 --> 00:44:24,760 It is the stupidest of encryption mechanisms because it literally just 909 00:44:24,760 --> 00:44:29,160 adds 13 to every one of the letters, stupid in the sense that if you just 910 00:44:29,160 --> 00:44:31,890 have a bit of free time on your hands and a pencil, or you just think it 911 00:44:31,890 --> 00:44:35,260 through in your head, you could try all possible additions-- one, two, 912 00:44:35,260 --> 00:44:38,470 three, dot, dot, dot, 25 to just rotate the whole alphabet, and 913 00:44:38,470 --> 00:44:40,860 eventually, you'll figure out what this message is. 914 00:44:40,860 --> 00:44:43,700 So if you did something like this in grade school passing messages to your 915 00:44:43,700 --> 00:44:46,830 best friend, if your grade school teacher simply read through the 916 00:44:46,830 --> 00:44:50,320 message and brute forced the solution, you might have gotten 917 00:44:50,320 --> 00:44:52,550 an answer by that. 918 00:44:52,550 --> 00:44:54,970 >> Now of course, in the real world, cryptography is more sophisticated. 919 00:44:54,970 --> 00:45:00,120 This is a snippet of text from a computer system that has usernames and 920 00:45:00,120 --> 00:45:03,630 passwords, as almost all of ours do, and this is what your password might 921 00:45:03,630 --> 00:45:07,260 look like if stored on your hard drive but in encrypted form. 922 00:45:07,260 --> 00:45:11,050 This is not just a rotation of letters, A is B and B is C. This is 923 00:45:11,050 --> 00:45:15,620 much more sophisticated, but it uses what's generally known as secret key 924 00:45:15,620 --> 00:45:16,690 cryptography. 925 00:45:16,690 --> 00:45:20,210 This picture tells the following story with a few icons. 926 00:45:20,210 --> 00:45:22,250 >> On the left, we have what we'll call plain text. 927 00:45:22,250 --> 00:45:25,420 In the world of cryptography, plain text is just the original message 928 00:45:25,420 --> 00:45:29,050 written in English or French or any language whatsoever. 929 00:45:29,050 --> 00:45:32,405 If you want to encrypt it, we'll pass it pictorially through a padlock, so 930 00:45:32,405 --> 00:45:35,580 some of kind of algorithm, some function or program that someone wrote 931 00:45:35,580 --> 00:45:39,880 that scrambles the letters hopefully more complicatedly than just adding 13 932 00:45:39,880 --> 00:45:40,980 to each of them. 933 00:45:40,980 --> 00:45:43,780 >> What you get out of that process in the middle there is called cyphertext. 934 00:45:43,780 --> 00:45:44,850 So kind of a sexy word. 935 00:45:44,850 --> 00:45:47,630 It just means it's the encrypted version of the plain text. 936 00:45:47,630 --> 00:45:52,570 And only if you have that same secret, 13 or minus 13, are you able to 937 00:45:52,570 --> 00:45:54,970 decrypt a message like that. 938 00:45:54,970 --> 00:45:57,770 >> So in Problem Set Two, among the things you'll do if in the Hacker 939 00:45:57,770 --> 00:46:01,860 Edition, you will have to write code to crack these passwords, figuring out 940 00:46:01,860 --> 00:46:05,170 what they were and how they were encrypted, though we do give you a bit 941 00:46:05,170 --> 00:46:06,460 of guidance along the way. 942 00:46:06,460 --> 00:46:09,320 In the Standard Edition, we introduce a couple of ciphers, encryption 943 00:46:09,320 --> 00:46:12,400 mechanisms, one called Caesar, one called Vigenere, that are still 944 00:46:12,400 --> 00:46:16,100 rotational ciphers where A becomes something, B becomes something, but 945 00:46:16,100 --> 00:46:18,820 you have to do it programmatically because there will indeed be a secret 946 00:46:18,820 --> 00:46:22,840 key involved which is typically a number or a keyword that only the 947 00:46:22,840 --> 00:46:26,420 sender and the recipient of these messages should understand. 948 00:46:26,420 --> 00:46:28,660 >> Now, this actually has incarnations in the real world. 949 00:46:28,660 --> 00:46:32,910 This, for instance, is little orphan Annie's secret decoder ring, and you 950 00:46:32,910 --> 00:46:35,180 can actually implement these rotational ciphers-- 951 00:46:35,180 --> 00:46:37,930 A becomes something, B becomes something-- with a couple of wheels, 952 00:46:37,930 --> 00:46:40,840 one on the outside, one on the inside such that if you rotate the wheel or 953 00:46:40,840 --> 00:46:44,170 the ring, you can actually line up the letters with different letters, 954 00:46:44,170 --> 00:46:45,430 getting a secret code. 955 00:46:45,430 --> 00:46:48,110 And so as the cliffhanger for today, what I thought I'd do is a bit of 956 00:46:48,110 --> 00:46:52,170 throwback that if you turn on the TV on December 24, you can watch the 957 00:46:52,170 --> 00:46:55,390 movie ad nauseum for 24 hours in a row. 958 00:46:55,390 --> 00:47:06,030 But for today, I'll open it up here and give us just two minutes of a 959 00:47:06,030 --> 00:47:13,493 pedagogically relevant Christmas Story with a little fellow named Ralphie. 960 00:47:13,493 --> 00:47:14,400 >> [VIDEO PLAYBACK] 961 00:47:14,400 --> 00:47:17,420 >> -Be it known to all and sundry that Ralph Parker is hereby appointed a 962 00:47:17,420 --> 00:47:20,650 member of the Little Orphan Annie secret circle and is entitled to all 963 00:47:20,650 --> 00:47:23,460 the honors and benefits occurring thereto. 964 00:47:23,460 --> 00:47:25,990 >> -Signed, Little Orphan Annie. 965 00:47:25,990 --> 00:47:30,100 Countersigned, Pierre Andre in ink. 966 00:47:30,100 --> 00:47:34,270 Honors and benefits already at the age of nine. 967 00:47:34,270 --> 00:47:39,440 >> [SHOUTING ON RADIO] 968 00:47:39,440 --> 00:47:40,770 >> Come on, let's get on with it. 969 00:47:40,770 --> 00:47:44,965 I don't need all that jazz about smugglers and pirates. 970 00:47:44,965 --> 00:47:48,270 >> -Listen tomorrow night for the concluding adventure of the black 971 00:47:48,270 --> 00:47:49,650 pirate ship. 972 00:47:49,650 --> 00:47:53,320 Now, it's time for Annie's Secret Message for you members 973 00:47:53,320 --> 00:47:55,720 of the secret circle. 974 00:47:55,720 --> 00:47:56,580 Remember, kids. 975 00:47:56,580 --> 00:48:01,720 Only members of Annie's Secret Circle can decode Annie's secret message. 976 00:48:01,720 --> 00:48:05,872 Remember, Annie is depending on you. 977 00:48:05,872 --> 00:48:08,670 Set your pins to B2. 978 00:48:08,670 --> 00:48:11,000 Here is the message. 979 00:48:11,000 --> 00:48:12,335 12, 11, 2-- 980 00:48:12,335 --> 00:48:14,670 >> -I am in my first secret meeting. 981 00:48:14,670 --> 00:48:19,720 >> -25, 14, 11, 18, 16-- 982 00:48:19,720 --> 00:48:21,650 >> -Pierre was in great voice tonight. 983 00:48:21,650 --> 00:48:24,830 I could tell that tonight's message was really important. 984 00:48:24,830 --> 00:48:26,400 >> -3, 25. 985 00:48:26,400 --> 00:48:28,540 That's a message from Annie herself. 986 00:48:28,540 --> 00:48:30,086 Remember, don't tell anyone. 987 00:48:30,086 --> 00:48:34,370 988 00:48:34,370 --> 00:48:38,710 >> -90 seconds later, I'm in the only room in the house where a boy of nine 989 00:48:38,710 --> 00:48:42,668 could sit in privacy and decode. 990 00:48:42,668 --> 00:48:47,628 Aha, B. I went to the next. 991 00:48:47,628 --> 00:48:53,060 E. The first word is "be." S. It was coming easier now. 992 00:48:53,060 --> 00:48:54,980 U. 25. 993 00:48:54,980 --> 00:48:55,940 That's R. 994 00:48:55,940 --> 00:48:56,900 >> -Come on, Ralphie. 995 00:48:56,900 --> 00:48:57,860 I gotta go. 996 00:48:57,860 --> 00:48:59,780 >> -I'll be right down, Ma. 997 00:48:59,780 --> 00:49:01,030 Gee whiz. 998 00:49:01,030 --> 00:49:04,300 999 00:49:04,300 --> 00:49:08,220 >> -T. O. Be sure to. 1000 00:49:08,220 --> 00:49:09,500 Be sure to what? 1001 00:49:09,500 --> 00:49:11,660 What was Little Orphan Annie trying to say? 1002 00:49:11,660 --> 00:49:12,844 Be sure to what? 1003 00:49:12,844 --> 00:49:14,732 >> -Ralphie, Randy has got to go. 1004 00:49:14,732 --> 00:49:16,148 Will you please come out? 1005 00:49:16,148 --> 00:49:17,092 >> -All right, Ma. 1006 00:49:17,092 --> 00:49:18,510 I'll be right out. 1007 00:49:18,510 --> 00:49:20,270 >> -I was getting closer to now. 1008 00:49:20,270 --> 00:49:21,823 The tension was terrible. 1009 00:49:21,823 --> 00:49:23,045 What was it? 1010 00:49:23,045 --> 00:49:26,510 The fate of the planet may hang in the balance. 1011 00:49:26,510 --> 00:49:28,985 >> -Ralphie, Randy's gotta go. 1012 00:49:28,985 --> 00:49:32,680 >> -I'll be right out for crying out loud. 1013 00:49:32,680 --> 00:49:33,956 >> -Almost there. 1014 00:49:33,956 --> 00:49:35,140 My fingers flew. 1015 00:49:35,140 --> 00:49:36,880 My mind was a steel trap. 1016 00:49:36,880 --> 00:49:38,010 Every pore vibrated. 1017 00:49:38,010 --> 00:49:39,878 It was almost clear. 1018 00:49:39,878 --> 00:49:43,210 Yes, yes, yes, yes, yes. 1019 00:49:43,210 --> 00:49:49,030 >> -Be sure to drink your Ovaltine. 1020 00:49:49,030 --> 00:49:50,280 Ovaltine? 1021 00:49:50,280 --> 00:49:53,980 1022 00:49:53,980 --> 00:49:55,230 A crummy commercial? 1023 00:49:55,230 --> 00:49:58,572 1024 00:49:58,572 --> 00:50:00,694 Son of a bitch. 1025 00:50:00,694 --> 00:50:01,900 >> [END VIDEO PLAYBACK] 1026 00:50:01,900 --> 00:50:04,260 >> SPEAKER 1: This is CS50, and that will be Problem Set Two. 1027 00:50:04,260 --> 00:50:06,305 See you next week. 1028 00:50:06,305 --> 00:50:08,800 >> SPEAKER 2: At the next CS50, this happens. 1029 00:50:08,800 --> 00:50:11,060 >> SPEAKER 1: So one topic we haven't looked at thus far is 1030 00:50:11,060 --> 00:50:12,220 that of function pointers. 1031 00:50:12,220 --> 00:50:14,540 Now, a function pointer is just the address of a public 1032 00:50:14,540 --> 00:50:17,000 function, but much like-- 1033 00:50:17,000 --> 00:50:18,250 son of a-- 1034 00:50:18,250 --> 00:50:19,670