1 00:00:00,000 --> 00:00:00,487 2 00:00:00,487 --> 00:00:11,210 >> [MUSIC PLAYING] 3 00:00:11,210 --> 00:00:12,100 >> ROB BODEN: All right. 4 00:00:12,100 --> 00:00:15,620 So, first thing first, of video from a familiar face. 5 00:00:15,620 --> 00:00:22,080 6 00:00:22,080 --> 00:00:22,560 >> [VIDEO PLAYBACK] 7 00:00:22,560 --> 00:00:23,370 >> -All right. 8 00:00:23,370 --> 00:00:27,150 This is CS50, and this is the start of week three. 9 00:00:27,150 --> 00:00:29,980 I'm sorry I couldn't be there with you today, but allow me to introduce 10 00:00:29,980 --> 00:00:32,880 CS50's own Rob Boden. 11 00:00:32,880 --> 00:00:33,872 >> [END VIDEO PLAYBACK] 12 00:00:33,872 --> 00:00:39,340 >> [APPLAUSE AND CHEERS] 13 00:00:39,340 --> 00:00:41,277 >> ROB BODEN: The filmography in that video is fantastic. 14 00:00:41,277 --> 00:00:47,280 15 00:00:47,280 --> 00:00:47,770 All right. 16 00:00:47,770 --> 00:00:50,960 So first, there's another lunch. 17 00:00:50,960 --> 00:00:52,330 It's tomorrow at 1:15. 18 00:00:52,330 --> 00:00:54,480 There's no lunch this Friday. 19 00:00:54,480 --> 00:00:55,810 It is with Quora. 20 00:00:55,810 --> 00:01:00,190 And Tommy's not here yet, but one of the people there is former head CF, 21 00:01:00,190 --> 00:01:01,530 Tommy McWilliam. 22 00:01:01,530 --> 00:01:02,730 So he's a fun guy. 23 00:01:02,730 --> 00:01:04,819 You should come. 24 00:01:04,819 --> 00:01:05,900 >> All right. 25 00:01:05,900 --> 00:01:11,360 So last week, we started breaking apart about what a string really is. 26 00:01:11,360 --> 00:01:14,830 We've known since the beginning that it's a sequence of characters. 27 00:01:14,830 --> 00:01:18,130 But last week, we delved into the fact that what is really a sequence of 28 00:01:18,130 --> 00:01:22,110 characters, well, we now have arrays of characters. 29 00:01:22,110 --> 00:01:26,450 And we know that a string, it's an array of characters, at the very end, 30 00:01:26,450 --> 00:01:30,920 we have this special null byte, this backslash 0, that indicates the end of 31 00:01:30,920 --> 00:01:32,230 the string. 32 00:01:32,230 --> 00:01:36,970 >> And so a string is an array of characters, but we can have more than 33 00:01:36,970 --> 00:01:39,530 just an array of characters, we can have an array of any 34 00:01:39,530 --> 00:01:40,890 type of thing we want. 35 00:01:40,890 --> 00:01:51,570 So, if you recall from last week, the Ages program that David introduced 36 00:01:51,570 --> 00:01:53,560 really quickly. 37 00:01:53,560 --> 00:01:57,010 So first thing we're going to do is ask the user for an integer, the 38 00:01:57,010 --> 00:01:58,800 number of people in the room. 39 00:01:58,800 --> 00:02:01,260 Once we have that integer, we're declaring an array. 40 00:02:01,260 --> 00:02:02,890 Notice this bracket syntax. 41 00:02:02,890 --> 00:02:04,540 You're going to get used to that. 42 00:02:04,540 --> 00:02:09,430 >> So we're declaring an array of integers called ages, and there are n 43 00:02:09,430 --> 00:02:12,080 integers in this array. 44 00:02:12,080 --> 00:02:16,480 So this pattern right here, this 4 int i equals 0, i is less than n, i plus 45 00:02:16,480 --> 00:02:20,580 plus, that is also going to be a pattern that you get very used to. 46 00:02:20,580 --> 00:02:24,000 Because that's pretty much how you're always going to iterate over arrays. 47 00:02:24,000 --> 00:02:26,330 So remember that n is the length of our array. 48 00:02:26,330 --> 00:02:32,120 And so here, we are repeatedly asking for the age of person i in the room. 49 00:02:32,120 --> 00:02:36,640 >> After this, we go down, and for whatever arbitrary reason, we then 50 00:02:36,640 --> 00:02:40,220 print out how old they're going to be a year from now. 51 00:02:40,220 --> 00:02:49,980 And running that program, let's make ages, dot slash ages. 52 00:02:49,980 --> 00:02:53,010 So number of people in the room, let's say there are three. 53 00:02:53,010 --> 00:02:59,880 And say, the first person is 13, next is 26, and the last is 30. 54 00:02:59,880 --> 00:03:05,080 So then it'll iterate over those three people, print out 14, 27, and 31. 55 00:03:05,080 --> 00:03:16,060 >> So remember that when we declare an array of size n, the indices in that 56 00:03:16,060 --> 00:03:19,950 array, the array has values and indices 0, 1, 2, all the way 57 00:03:19,950 --> 00:03:21,680 up to n minus 1. 58 00:03:21,680 --> 00:03:26,255 So when we said there were three people in the room, and we put in here 59 00:03:26,255 --> 00:03:29,850 the first iteration through this loop, i is going to be 0. 60 00:03:29,850 --> 00:03:31,650 So in index 0. 61 00:03:31,650 --> 00:03:34,540 We are assigning the first age the user enters. 62 00:03:34,540 --> 00:03:38,870 Then in the next one, we're entering the second n the user enters, and in 63 00:03:38,870 --> 00:03:40,580 next to two, the last n. 64 00:03:40,580 --> 00:03:44,200 >> So notice that an array of size three does not have anything 65 00:03:44,200 --> 00:03:46,040 in the index three. 66 00:03:46,040 --> 00:03:49,036 This is not valid. 67 00:03:49,036 --> 00:03:50,250 All right. 68 00:03:50,250 --> 00:03:55,136 So, going back here. 69 00:03:55,136 --> 00:03:57,650 70 00:03:57,650 --> 00:04:01,590 So now that we've dealt with arrays, we have some familiarity. 71 00:04:01,590 --> 00:04:03,780 Now we're going to move on to command line arguments, which are going to be 72 00:04:03,780 --> 00:04:05,890 pretty relevant to this problem set. 73 00:04:05,890 --> 00:04:09,670 >> So up until now, whenever you've declared your main function, we've 74 00:04:09,670 --> 00:04:11,230 said int main void. 75 00:04:11,230 --> 00:04:14,070 So void just means that we aren't passing any 76 00:04:14,070 --> 00:04:16,440 arguments to this function. 77 00:04:16,440 --> 00:04:19,190 Now we're going to see that main can take some arguments. 78 00:04:19,190 --> 00:04:22,470 Here we call them int argc and string argv brackets. 79 00:04:22,470 --> 00:04:26,930 The brackets, once again, indicating that we're dealing with arrays. 80 00:04:26,930 --> 00:04:31,850 So here, string argv brackets, we're dealing with an array of strings. 81 00:04:31,850 --> 00:04:35,360 So argc, that's going to indicate how many arguments we've 82 00:04:35,360 --> 00:04:37,580 passed to this program. 83 00:04:37,580 --> 00:04:46,050 And to see what that means, let's close this. 84 00:04:46,050 --> 00:04:46,490 >> OK. 85 00:04:46,490 --> 00:04:50,790 So up until now, we've run every program like dot slash ages. 86 00:04:50,790 --> 00:04:55,250 We can also, at the command line, past pass arguments, thus the term, command 87 00:04:55,250 --> 00:04:56,550 line arguments. 88 00:04:56,550 --> 00:04:59,760 So the first argument, hello world. 89 00:04:59,760 --> 00:05:03,350 So here, argc would be three. 90 00:05:03,350 --> 00:05:07,720 It's the count of the arguments at the command line. 91 00:05:07,720 --> 00:05:12,840 Argc is always at least 1, since dot slash ages, itself, counts as one of 92 00:05:12,840 --> 00:05:14,490 the command line arguments. 93 00:05:14,490 --> 00:05:17,010 >> Then hello is the first. 94 00:05:17,010 --> 00:05:20,460 If dot slash ages is the zeroth, then hello is the first, and world is the 95 00:05:20,460 --> 00:05:22,830 second command line argument. 96 00:05:22,830 --> 00:05:29,490 So the string argv, we're going to see, contains the strings, dot slash 97 00:05:29,490 --> 00:05:33,830 ages, hello, and world. 98 00:05:33,830 --> 00:05:38,945 And, by David's request, we're going to play a video introducing that. 99 00:05:38,945 --> 00:05:42,486 100 00:05:42,486 --> 00:05:43,890 >> [VIDEO PLAYBACK] 101 00:05:43,890 --> 00:05:46,240 >> -Up until now in programs we've written, we've declare 102 00:05:46,240 --> 00:05:48,500 main as int main void. 103 00:05:48,500 --> 00:05:51,170 And all this time, that void has simply been specifying that the 104 00:05:51,170 --> 00:05:54,430 program does not take any command line arguments. 105 00:05:54,430 --> 00:05:57,750 In other words, when a user runs a program, he or she can provide command 106 00:05:57,750 --> 00:06:01,710 line arguments by writing additional words or phrases after the program's 107 00:06:01,710 --> 00:06:03,000 name at the prompt. 108 00:06:03,000 --> 00:06:06,550 >> Well, if you do you want your program to take command line arguments, one or 109 00:06:06,550 --> 00:06:10,540 more such words, we need to replace void with a couple of arguments. 110 00:06:10,540 --> 00:06:12,200 So let's do that. 111 00:06:12,200 --> 00:06:15,750 Include CS50.h. 112 00:06:15,750 --> 00:06:19,360 Include standard io.h. 113 00:06:19,360 --> 00:06:20,760 Int main. 114 00:06:20,760 --> 00:06:26,330 And now, instead of void, I'm going to specify an int called argc, and an 115 00:06:26,330 --> 00:06:28,780 array of strings called argv. 116 00:06:28,780 --> 00:06:31,820 Now, argc and argv are simply conventions. 117 00:06:31,820 --> 00:06:34,000 >> We could have called these arguments most anything we want. 118 00:06:34,000 --> 00:06:37,630 But what is important is that argc is an int because, by definition, it is 119 00:06:37,630 --> 00:06:41,360 going to contain the argument count, the number of words in total that the 120 00:06:41,360 --> 00:06:43,380 user has typed at his or her prompt. 121 00:06:43,380 --> 00:06:47,910 argv, meanwhile, argument vector, is going to actually be an array storing 122 00:06:47,910 --> 00:06:52,020 all of the words that the user has typed at his or her prompt. 123 00:06:52,020 --> 00:06:54,500 >> Let's proceed to do something now with one or more of these 124 00:06:54,500 --> 00:06:55,660 command line arguments. 125 00:06:55,660 --> 00:07:00,070 In particular, let's go ahead and print whatever word the user types 126 00:07:00,070 --> 00:07:03,960 after the program's name at the prompt. 127 00:07:03,960 --> 00:07:04,730 Open bracket. 128 00:07:04,730 --> 00:07:06,240 Close bracket. 129 00:07:06,240 --> 00:07:10,510 Printf percent s backslash and comma. 130 00:07:10,510 --> 00:07:14,550 And now I need to tell printf what value to plug into that placeholder. 131 00:07:14,550 --> 00:07:18,600 I want the first word that the user has typed after the program's name, 132 00:07:18,600 --> 00:07:23,130 and so I'm going to specify argv bracket 1, close 133 00:07:23,130 --> 00:07:24,830 parenthesis, semicolon. 134 00:07:24,830 --> 00:07:27,290 >> Now, why bracket 1 and not bracket 0? 135 00:07:27,290 --> 00:07:30,990 Well, it turns out, automatically stored in argv 0 is going to be the 136 00:07:30,990 --> 00:07:32,620 program's actual name. 137 00:07:32,620 --> 00:07:36,180 So the first word that the user types after the program's name is, by 138 00:07:36,180 --> 00:07:38,990 convention, going to be stored in argv 1. 139 00:07:38,990 --> 00:07:42,380 Let's now compile and run this program. 140 00:07:42,380 --> 00:07:47,780 >> Make argv 0, dot slash argv 0. 141 00:07:47,780 --> 00:07:50,520 And now a word like hello. 142 00:07:50,520 --> 00:07:51,670 Enter. 143 00:07:51,670 --> 00:07:53,520 And there we have it, hello. 144 00:07:53,520 --> 00:07:55,750 >> [END VIDEO PLAYBACK] 145 00:07:55,750 --> 00:07:57,000 >> ROB BODEN: All right. 146 00:07:57,000 --> 00:07:59,380 147 00:07:59,380 --> 00:08:01,230 Close that. 148 00:08:01,230 --> 00:08:16,730 So taking a look at that program that we just introduced to us, well, just 149 00:08:16,730 --> 00:08:24,710 to show, if we print argv 0, make, now what is it, argv 0, dot slash argv 0. 150 00:08:24,710 --> 00:08:30,440 So, as expected, it's printing out the name of the program, since argv 0 is 151 00:08:30,440 --> 00:08:32,970 always going to be the name of the program. 152 00:08:32,970 --> 00:08:35,640 But let's do something a bit more interesting. 153 00:08:35,640 --> 00:08:42,080 >> So in the problem set, you'll be introduced to this function, atoi. 154 00:08:42,080 --> 00:08:44,440 So what do we use atoi for? 155 00:08:44,440 --> 00:08:48,550 That's going to convert a string to an integer. 156 00:08:48,550 --> 00:08:53,280 So if I pass the string, one two three, to atoi, that'll convert that 157 00:08:53,280 --> 00:08:56,910 to the integer, one two three. 158 00:08:56,910 --> 00:09:01,480 So we're going to convert the first command line argument to an integer, 159 00:09:01,480 --> 00:09:05,690 and then just print that integer. 160 00:09:05,690 --> 00:09:09,680 >> So basically, we're kind of reimplementing getint, just the 161 00:09:09,680 --> 00:09:12,350 integer is entered at the command line instead of in the program 162 00:09:12,350 --> 00:09:14,560 interactively. 163 00:09:14,560 --> 00:09:23,170 So then, making argv 0, let's do it in here, and close that. 164 00:09:23,170 --> 00:09:27,670 So running argv 0, and let's enter the integer, one two three four one two. 165 00:09:27,670 --> 00:09:30,840 So it'll print the integer, one two three four one two. 166 00:09:30,840 --> 00:09:35,500 There are some subtleties to atoi that it'll stop caring about anything 167 00:09:35,500 --> 00:09:39,040 beyond a valid numeric character, but that doesn't matter. 168 00:09:39,040 --> 00:09:42,870 >> So what do you think happens if I do this? 169 00:09:42,870 --> 00:09:45,520 170 00:09:45,520 --> 00:09:47,050 Segmentation fault. 171 00:09:47,050 --> 00:09:50,410 So why is that? 172 00:09:50,410 --> 00:09:56,060 If you look back at our program, we're converting argv 1, the first argument 173 00:09:56,060 --> 00:09:59,610 after the program name, to an integer. 174 00:09:59,610 --> 00:10:03,350 But there is no argument passed after the program name. 175 00:10:03,350 --> 00:10:08,060 So here, we see that this is a buggy program, since, if we try to run it 176 00:10:08,060 --> 00:10:10,530 without any arguments, it will just crash. 177 00:10:10,530 --> 00:10:16,950 >> So another common pattern you'll see is something like, if argc is less 178 00:10:16,950 --> 00:10:21,100 than two, indicating that there was not at least the program name and a 179 00:10:21,100 --> 00:10:29,100 first argument, then we'll do something like printf, not enough 180 00:10:29,100 --> 00:10:31,190 command line arguments. 181 00:10:31,190 --> 00:10:33,170 That's probably not a good one to print, it's probably something, like 182 00:10:33,170 --> 00:10:35,440 you should enter an integer at the command line. 183 00:10:35,440 --> 00:10:37,450 I'll just end it there. 184 00:10:37,450 --> 00:10:39,600 And then return 1. 185 00:10:39,600 --> 00:10:44,740 So remember that at the end of our program, if we return 0, that sort of 186 00:10:44,740 --> 00:10:47,060 indicates success. 187 00:10:47,060 --> 00:10:50,940 And main also automatically returns 0 if you don't. 188 00:10:50,940 --> 00:10:55,800 >> So here, we're retuning 1 to indicate that that's not success. 189 00:10:55,800 --> 00:11:01,000 And you can return whatever you want, just, 0 indicates success, and 190 00:11:01,000 --> 00:11:03,390 anything else indicates failure. 191 00:11:03,390 --> 00:11:04,855 So let's run this version of things. 192 00:11:04,855 --> 00:11:12,880 193 00:11:12,880 --> 00:11:16,600 So now, if we don't enter a command line argument, it'll correctly tell 194 00:11:16,600 --> 00:11:18,290 us, not enough command line. 195 00:11:18,290 --> 00:11:20,610 Didn't finish the sentence. 196 00:11:20,610 --> 00:11:24,950 Else, if we actually pass it one, it can complete the program. 197 00:11:24,950 --> 00:11:27,920 So this is how you would use argc in order to validate the number of 198 00:11:27,920 --> 00:11:30,630 command line arguments that are actually passed. 199 00:11:30,630 --> 00:11:39,360 >> So let's make this program a bit more complicated, and look at the second 200 00:11:39,360 --> 00:11:42,180 iteration of things. 201 00:11:42,180 --> 00:11:46,310 So now, we're not just printing the first command line argument. 202 00:11:46,310 --> 00:11:51,210 Here, we're iterating from int i equals 0, i is less than argc, i plus 203 00:11:51,210 --> 00:11:55,280 plus, and printing argv, index i. 204 00:11:55,280 --> 00:11:59,300 So this pattern, again, this is the same pattern as before, except instead 205 00:11:59,300 --> 00:12:02,600 of calling the variable n, we're using argc. 206 00:12:02,600 --> 00:12:09,520 >> So this is iterating over each index in the array, and printing each 207 00:12:09,520 --> 00:12:11,910 element in that array. 208 00:12:11,910 --> 00:12:20,300 And so, when we run this program, well, I didn't enter any command line 209 00:12:20,300 --> 00:12:22,540 arguments, so it just prints the program name. 210 00:12:22,540 --> 00:12:26,053 If I enter a bunch of things, it'll print one, each on its own line. 211 00:12:26,053 --> 00:12:31,213 212 00:12:31,213 --> 00:12:32,210 >> OK. 213 00:12:32,210 --> 00:12:34,770 So let's take this one step further. 214 00:12:34,770 --> 00:12:38,890 And instead of printing each argument on its own line, let's print each 215 00:12:38,890 --> 00:12:42,590 character of each argument on its own line. 216 00:12:42,590 --> 00:12:46,700 So remember that argv is an array of strings. 217 00:12:46,700 --> 00:12:50,960 So what is a string, but an array of characters? 218 00:12:50,960 --> 00:12:57,140 So that means that argv is really an array of an array of characters. 219 00:12:57,140 --> 00:13:04,920 So taking advantage of that, let's ignore this for now. 220 00:13:04,920 --> 00:13:08,190 Let's just consider the string argv 0. 221 00:13:08,190 --> 00:13:14,170 >> So if we want to bring each character of argv 0 on its own line, then I want 222 00:13:14,170 --> 00:13:19,500 to do the pattern we're used to, i is less than the length of the array, 223 00:13:19,500 --> 00:13:23,990 which here, is strlen of, that's not what I want to do, string 224 00:13:23,990 --> 00:13:26,450 s equals argv 0. 225 00:13:26,450 --> 00:13:30,390 So i is less than the length of our array, which in this case is an array 226 00:13:30,390 --> 00:13:34,410 of characters, i plus plus. 227 00:13:34,410 --> 00:13:41,040 And so, as we saw last week, it's ideal if we move that strlen outside 228 00:13:41,040 --> 00:13:45,210 of the condition, since n will be adding the strlen of s each time we go 229 00:13:45,210 --> 00:13:47,720 through the loop, and it's not going to be changing. 230 00:13:47,720 --> 00:13:50,230 So we'll set it equal to n over here. 231 00:13:50,230 --> 00:13:54,260 232 00:13:54,260 --> 00:13:55,170 >> OK. 233 00:13:55,170 --> 00:14:01,320 So now, we're iterating over each index in the array. 234 00:14:01,320 --> 00:14:05,630 And so, if we want to print each character in that array, percent c is 235 00:14:05,630 --> 00:14:06,880 the flag we want to use for characters. 236 00:14:06,880 --> 00:14:10,750 237 00:14:10,750 --> 00:14:19,770 And now a bracket i is going to be the string, index character i, so if the 238 00:14:19,770 --> 00:14:20,970 string were hello. 239 00:14:20,970 --> 00:14:27,530 then s 0 is going to be h, s bracket 1 will be e, and so on. 240 00:14:27,530 --> 00:14:30,800 >> So now we want to combine these two things. 241 00:14:30,800 --> 00:14:35,440 We want to print each character of each command line argument. 242 00:14:35,440 --> 00:14:38,950 So we're going to have a nested for loop. 243 00:14:38,950 --> 00:14:47,480 And conventionally, the first counter is i, the next is going to be j, n 244 00:14:47,480 --> 00:14:54,450 will be the strlen of argv i, i is less than n, i plus plus. 245 00:14:54,450 --> 00:14:59,150 246 00:14:59,150 --> 00:15:06,870 And now instead of printing argv i, so argv bracket i is going to index-- 247 00:15:06,870 --> 00:15:14,280 that's going to be the i-th command line argument, argv i, j is going to 248 00:15:14,280 --> 00:15:16,925 be the jth character of the i-th argument. 249 00:15:16,925 --> 00:15:20,580 250 00:15:20,580 --> 00:15:24,810 I'll get rid of this up here now since we put it into that loop. 251 00:15:24,810 --> 00:15:33,900 So is equivalent to string s equals argv i, and then s bracket j. 252 00:15:33,900 --> 00:15:36,980 >> Well, we don't need to declare this variable s. 253 00:15:36,980 --> 00:15:44,530 Instead, we'll just combine these two into what we had, argv i, j. 254 00:15:44,530 --> 00:15:45,780 >> SPEAKER 1: [INAUDIBLE]. 255 00:15:45,780 --> 00:15:48,850 256 00:15:48,850 --> 00:15:49,680 >> ROB BODEN: Good call. 257 00:15:49,680 --> 00:15:52,936 So this is broken. 258 00:15:52,936 --> 00:15:55,510 If I actually ran it, we would have realized this. 259 00:15:55,510 --> 00:16:01,210 So the counter I care about in this particular for 260 00:16:01,210 --> 00:16:05,410 loop is j, the iterator. 261 00:16:05,410 --> 00:16:08,560 So you would have run into issues, probably an infinite loop, if we 262 00:16:08,560 --> 00:16:09,540 hadn't fixed that. 263 00:16:09,540 --> 00:16:12,220 That's why we're also talking about debugging today. 264 00:16:12,220 --> 00:16:13,120 >> OK. 265 00:16:13,120 --> 00:16:15,240 So let's run this program. 266 00:16:15,240 --> 00:16:21,200 And let's actually add a separate printf right here that will just print 267 00:16:21,200 --> 00:16:27,480 another line, since this means when we run the program, there'll be a blank 268 00:16:27,480 --> 00:16:31,830 line in between each character of each command line argument. 269 00:16:31,830 --> 00:16:33,448 Well, we'll see what that means. 270 00:16:33,448 --> 00:16:37,310 271 00:16:37,310 --> 00:16:37,790 Oop. 272 00:16:37,790 --> 00:16:39,870 Got some bug. 273 00:16:39,870 --> 00:16:42,860 Error implicitly declaring library function strlen. 274 00:16:42,860 --> 00:16:51,630 >> So going back into our program, I forgot to hash include string.h. 275 00:16:51,630 --> 00:16:54,240 276 00:16:54,240 --> 00:16:57,730 So string.h is going to be the header file that declares 277 00:16:57,730 --> 00:16:58,980 the function strlen. 278 00:16:58,980 --> 00:17:04,650 279 00:17:04,650 --> 00:17:06,060 OK, it compiles. 280 00:17:06,060 --> 00:17:09,109 Now, let's run it. 281 00:17:09,109 --> 00:17:10,930 So just that. 282 00:17:10,930 --> 00:17:17,790 It's going to print out our program name, hello world. 283 00:17:17,790 --> 00:17:23,510 It's going to print each thing, each character, on its own line. 284 00:17:23,510 --> 00:17:24,540 OK. 285 00:17:24,540 --> 00:17:30,625 >> So let's actually take this one step further. 286 00:17:30,625 --> 00:17:34,050 287 00:17:34,050 --> 00:17:39,700 And instead of using string.h, let's think about how we'd implement our own 288 00:17:39,700 --> 00:17:41,420 strlen function. 289 00:17:41,420 --> 00:17:45,600 So I'll immediately give a function signature. 290 00:17:45,600 --> 00:17:52,900 So let's call in my_strlen, and it's going to take a string as an argument, 291 00:17:52,900 --> 00:17:57,220 and we expect to return the length of that string. 292 00:17:57,220 --> 00:18:03,430 So, where's that guy? 293 00:18:03,430 --> 00:18:04,990 Yes. 294 00:18:04,990 --> 00:18:06,740 OK. 295 00:18:06,740 --> 00:18:12,900 So remember from the earlier slide that was also from last week, that an 296 00:18:12,900 --> 00:18:18,890 array of characters, well, a string, so let's say this is our string s. 297 00:18:18,890 --> 00:18:29,870 So if s is the string, hello, then, H-E-L-L-O, in memory, that's going to 298 00:18:29,870 --> 00:18:35,610 be, and then this backslash 0 character. 299 00:18:35,610 --> 00:18:39,170 >> So how do we get the length of s? 300 00:18:39,170 --> 00:18:43,190 Well, the trick is looking for this backlash 0 character, this null 301 00:18:43,190 --> 00:18:44,380 terminator. 302 00:18:44,380 --> 00:18:50,270 So the algorithm Is going to be something like few 303 00:18:50,270 --> 00:18:51,510 enough characters that-- 304 00:18:51,510 --> 00:18:56,180 let's have this hand represent some counter, let's call this int length. 305 00:18:56,180 --> 00:19:00,060 So, starting from over here, we're going to iterate over our string. 306 00:19:00,060 --> 00:19:04,100 >> So the first character, it's H, and it's not back slash 0, so 307 00:19:04,100 --> 00:19:05,170 the length is 1. 308 00:19:05,170 --> 00:19:08,050 Iterate to the next character, E, and it's not backslash 0. 309 00:19:08,050 --> 00:19:09,630 Length is 2. 310 00:19:09,630 --> 00:19:10,960 L, 3. 311 00:19:10,960 --> 00:19:11,850 L, 4. 312 00:19:11,850 --> 00:19:13,050 O, 5. 313 00:19:13,050 --> 00:19:16,690 And finally, we reach backslash 0, and so that means, well, 314 00:19:16,690 --> 00:19:17,780 this string is over. 315 00:19:17,780 --> 00:19:20,130 So let's return 5. 316 00:19:20,130 --> 00:19:33,630 >> So actually implementing that, first, my n length equals 0, my right hand. 317 00:19:33,630 --> 00:19:36,088 And we're going to iterate-- 318 00:19:36,088 --> 00:19:38,000 >> SPEAKER 1: [INAUDIBLE] 319 00:19:38,000 --> 00:19:38,640 >> ROB BODEN: Oh, shoot. 320 00:19:38,640 --> 00:19:39,870 Good call. 321 00:19:39,870 --> 00:19:42,680 Boom. 322 00:19:42,680 --> 00:19:44,140 So n length equals 0. 323 00:19:44,140 --> 00:19:46,910 324 00:19:46,910 --> 00:19:58,310 So now, while s length does not equal and then, backslash 0. 325 00:19:58,310 --> 00:20:04,660 So remember, this backslash 0, it is an actual character, and it indicates 326 00:20:04,660 --> 00:20:05,820 the end of the string. 327 00:20:05,820 --> 00:20:09,850 Just like, also, backslash n is an actual character. 328 00:20:09,850 --> 00:20:14,040 Backslash 0 is going to indicate the end of our string. 329 00:20:14,040 --> 00:20:15,414 I don't want to put that there. 330 00:20:15,414 --> 00:20:19,190 331 00:20:19,190 --> 00:20:25,620 And while s indexed by length is not equal to the null terminator, then 332 00:20:25,620 --> 00:20:27,130 we're just going to increment length. 333 00:20:27,130 --> 00:20:29,860 334 00:20:29,860 --> 00:20:34,880 So then, at the end of our program, length is eventually going to 335 00:20:34,880 --> 00:20:37,610 be 5 in this case. 336 00:20:37,610 --> 00:20:39,210 And we'll just return length. 337 00:20:39,210 --> 00:20:42,570 338 00:20:42,570 --> 00:20:43,530 >> OK. 339 00:20:43,530 --> 00:20:48,290 So now down here, I don't do my_strlen. 340 00:20:48,290 --> 00:20:50,700 Let's compile it to make sure everything runs smoothly. 341 00:20:50,700 --> 00:20:55,820 342 00:20:55,820 --> 00:20:58,210 Was I doing in 2? 343 00:20:58,210 --> 00:21:00,565 Or was that 1? 344 00:21:00,565 --> 00:21:01,940 That should do. 345 00:21:01,940 --> 00:21:02,690 All right. 346 00:21:02,690 --> 00:21:08,490 So this is argv 2. 347 00:21:08,490 --> 00:21:11,585 Works as anticipated, although was that the one I did it in? 348 00:21:11,585 --> 00:21:15,060 349 00:21:15,060 --> 00:21:15,550 Yes. 350 00:21:15,550 --> 00:21:16,760 OK. 351 00:21:16,760 --> 00:21:21,820 This version of things did not have the printf new line after, but it 352 00:21:21,820 --> 00:21:22,910 doesn't make any difference. 353 00:21:22,910 --> 00:21:23,300 OK. 354 00:21:23,300 --> 00:21:25,780 So worked as expected. 355 00:21:25,780 --> 00:21:34,750 >> Now we can even combine this one step further, where notice here, well, 356 00:21:34,750 --> 00:21:38,920 first, we're grabbing the strlen of argv i, and then we're iterating over 357 00:21:38,920 --> 00:21:41,450 each character in that string. 358 00:21:41,450 --> 00:21:47,480 So instead of doing that, what if we just combine this logic of waiting 359 00:21:47,480 --> 00:21:50,740 until we hit backslash 0 right into this for loop? 360 00:21:50,740 --> 00:21:53,740 361 00:21:53,740 --> 00:22:07,490 So iterate while argv i, j does not equal backslash 0. 362 00:22:07,490 --> 00:22:10,680 So let's run it first. 363 00:22:10,680 --> 00:22:19,838 364 00:22:19,838 --> 00:22:21,180 >> All right. 365 00:22:21,180 --> 00:22:27,655 So here, this condition is saying-- 366 00:22:27,655 --> 00:22:38,090 367 00:22:38,090 --> 00:22:40,060 let's clear that. 368 00:22:40,060 --> 00:22:49,140 So now, let this be our argv. 369 00:22:49,140 --> 00:22:55,290 So when I just ran that program before, argv is an array of strings. 370 00:22:55,290 --> 00:23:03,100 And so, if I run it with dot slash argv 2, hello world, then the argv 371 00:23:03,100 --> 00:23:07,650 itself is length 3, for argv zero, hello, and world. 372 00:23:07,650 --> 00:23:11,700 373 00:23:11,700 --> 00:23:19,660 >> And inside of each of these indices is, itself an array, where this'll be 374 00:23:19,660 --> 00:23:23,780 dot, this will be slash, I don't know if that was the right direction, I 375 00:23:23,780 --> 00:23:25,680 don't think it was. 376 00:23:25,680 --> 00:23:30,110 A-R-V dash, need more space. 377 00:23:30,110 --> 00:23:32,570 Let's cut into this array. 378 00:23:32,570 --> 00:23:38,230 A-R-V dash 0, and then backslash 0. 379 00:23:38,230 --> 00:23:43,160 And then in disarray will be hello. 380 00:23:43,160 --> 00:23:45,910 Let's say, H-E backslash 0. 381 00:23:45,910 --> 00:23:51,130 And finally, W-O backslash 0. 382 00:23:51,130 --> 00:23:59,730 >> So the algorithm that we just wrote, the nested for loops, what they're 383 00:23:59,730 --> 00:24:07,321 doing is, we first have the counter i and then j. 384 00:24:07,321 --> 00:24:15,206 This would be easier with code on the screen, Let's go back to this. 385 00:24:15,206 --> 00:24:17,476 OK. 386 00:24:17,476 --> 00:24:24,600 So notice that i is the iterator that's iterating over each command 387 00:24:24,600 --> 00:24:25,610 line argument. 388 00:24:25,610 --> 00:24:28,870 And j is the iterator iterating over each character in that 389 00:24:28,870 --> 00:24:30,410 command line argument. 390 00:24:30,410 --> 00:24:46,755 So what this innermost printf is doing is, we have printf argv 0 0, printf 391 00:24:46,755 --> 00:24:58,680 argv 0 1, printf argv 0 2, 0 3, 0 4, 0 5, 0 6, but now, argv 0 7 is going to 392 00:24:58,680 --> 00:25:00,670 equal backslash 0. 393 00:25:00,670 --> 00:25:05,730 >> So then we exit that for loop, and now i iterates to 1. 394 00:25:05,730 --> 00:25:10,910 And now we're going to print argv 1 0, argv 1 1-- 395 00:25:10,910 --> 00:25:17,040 well, now, since I cut hello short, argv 1 2 is again going to be 396 00:25:17,040 --> 00:25:18,170 backslash 0. 397 00:25:18,170 --> 00:25:25,050 And so, increment i and continue, and so on, until we print out all of 398 00:25:25,050 --> 00:25:28,580 world, and those are three command line arguments, and we'll exit out of 399 00:25:28,580 --> 00:25:31,670 the outermost loop, and finish our program. 400 00:25:31,670 --> 00:25:38,390 401 00:25:38,390 --> 00:25:39,640 OK. 402 00:25:39,640 --> 00:25:43,903 403 00:25:43,903 --> 00:25:46,795 >> So let's come back here. 404 00:25:46,795 --> 00:25:49,670 405 00:25:49,670 --> 00:25:52,370 So you'll gain some familiarity with command line arguments on this 406 00:25:52,370 --> 00:25:54,460 particular problem set. 407 00:25:54,460 --> 00:25:56,630 >> Now, debugging. 408 00:25:56,630 --> 00:26:01,680 So you probably have already had to do some debugging with your previous 409 00:26:01,680 --> 00:26:03,120 problem set. 410 00:26:03,120 --> 00:26:08,420 And one very easy way of debugging, first, let's look at a buggy program. 411 00:26:08,420 --> 00:26:20,710 412 00:26:20,710 --> 00:26:23,830 Well, walking through this program, we're going to ask the user for an 413 00:26:23,830 --> 00:26:29,350 integer, grab that integer, and then, arbitrarily, we have a while loop that 414 00:26:29,350 --> 00:26:32,280 is just going to decrement i until it's equal to 10. 415 00:26:32,280 --> 00:26:35,820 Let's just assume I'm entering an integer greater than 10. 416 00:26:35,820 --> 00:26:38,700 So decrement i until it's equal to 10. 417 00:26:38,700 --> 00:26:42,630 >> And then we have another while loop that, while i does not equal 0, we're 418 00:26:42,630 --> 00:26:44,540 going to decrement i by 3. 419 00:26:44,540 --> 00:26:49,790 So if you see the intent of the bug here, it's that this'll decrement i to 420 00:26:49,790 --> 00:26:57,010 be 10, and then this while loop will decrement i from 10, to 7, to 4, to 1, 421 00:26:57,010 --> 00:27:02,880 to negative 2, to negative 5, and so on, to negative infinity, since i will 422 00:27:02,880 --> 00:27:05,920 never actually equal 0. 423 00:27:05,920 --> 00:27:08,610 And then at the end of this program, we have the foo function which is 424 00:27:08,610 --> 00:27:12,130 going on print out that i. 425 00:27:12,130 --> 00:27:16,520 >> So this is a short and trivial program, and the bug is obvious, 426 00:27:16,520 --> 00:27:18,790 especially after I just said what the bug was. 427 00:27:18,790 --> 00:27:24,840 But the intent here is, well, this might actually look like some of your 428 00:27:24,840 --> 00:27:30,040 solutions from greedy from the last problem set, and maybe you do have 429 00:27:30,040 --> 00:27:32,800 some infinite loop in your program, and you have no idea 430 00:27:32,800 --> 00:27:34,100 what's causing it. 431 00:27:34,100 --> 00:27:38,690 So a very useful debugging technique is to just add printfs 432 00:27:38,690 --> 00:27:40,180 all over your code. 433 00:27:40,180 --> 00:27:49,200 >> So here I want a printf outside first while loop. 434 00:27:49,200 --> 00:27:53,155 And here I want a printf, and I'll just print i. 435 00:27:53,155 --> 00:27:55,670 436 00:27:55,670 --> 00:27:58,330 I'll even do first while loop, i. 437 00:27:58,330 --> 00:28:05,130 438 00:28:05,130 --> 00:28:09,040 Outside, second while loop. 439 00:28:09,040 --> 00:28:12,170 Once again, print inside of here, the value i. 440 00:28:12,170 --> 00:28:16,270 441 00:28:16,270 --> 00:28:17,520 And let's run this. 442 00:28:17,520 --> 00:28:22,620 443 00:28:22,620 --> 00:28:24,800 >> So dot slash debug. 444 00:28:24,800 --> 00:28:25,610 Enter an integer. 445 00:28:25,610 --> 00:28:28,150 Let's do 13. 446 00:28:28,150 --> 00:28:28,760 And boom. 447 00:28:28,760 --> 00:28:33,300 We see that we are infinite looping inside of the second while loop. 448 00:28:33,300 --> 00:28:36,305 So now we know what the bug is. 449 00:28:36,305 --> 00:28:39,610 450 00:28:39,610 --> 00:28:45,610 But printf debugging is perfectly great, but once your programs get 451 00:28:45,610 --> 00:28:50,560 longer and more complicated, there are more sophisticated solutions to 452 00:28:50,560 --> 00:28:51,705 getting things working. 453 00:28:51,705 --> 00:28:52,955 So let's remove all these printfs. 454 00:28:52,955 --> 00:29:06,242 455 00:29:06,242 --> 00:29:08,896 And let's make sure I didn't break anything. 456 00:29:08,896 --> 00:29:09,850 OK. 457 00:29:09,850 --> 00:29:14,180 >> So the program we're going to introduce is called 458 00:29:14,180 --> 00:29:16,715 GDB, for GNU Debugger. 459 00:29:16,715 --> 00:29:21,892 460 00:29:21,892 --> 00:29:27,510 Well, actually, let's remove debug for a second, and make debug again. 461 00:29:27,510 --> 00:29:31,420 462 00:29:31,420 --> 00:29:34,440 Well, actually first, a good lesson in command line arguments. 463 00:29:34,440 --> 00:29:37,780 Notice that this Clang command that is compiling everything is being passed 464 00:29:37,780 --> 00:29:41,300 at the command line, these command line arguments. 465 00:29:41,300 --> 00:29:46,250 So exactly how you are going to be using command line arguments, as we 466 00:29:46,250 --> 00:29:51,500 did before, and as you will in PSET 2, that's how Clang is using them. 467 00:29:51,500 --> 00:30:00,070 >> So notice that this first flag, dash ggdb3, what that's saying is, Clang, 468 00:30:00,070 --> 00:30:03,790 you should compile this file with the intent that we will eventually 469 00:30:03,790 --> 00:30:05,380 need to debug it. 470 00:30:05,380 --> 00:30:13,840 So as long as you have that flag, then we can GDB debug. 471 00:30:13,840 --> 00:30:17,380 And it'll open up the GNU Debugger. 472 00:30:17,380 --> 00:30:22,920 >> So there are a lot of commands that you need to get used to. 473 00:30:22,920 --> 00:30:27,100 First one that you'll probably immediately need is Run. 474 00:30:27,100 --> 00:30:28,200 So what is Run going to do? 475 00:30:28,200 --> 00:30:30,910 It's going to start our program. 476 00:30:30,910 --> 00:30:36,180 So run, starting program, the program asks us for an integer, 13. 477 00:30:36,180 --> 00:30:39,170 And then it's infinite looping as expected, except I removed the 478 00:30:39,170 --> 00:30:40,500 printfs, so we don't even see that. 479 00:30:40,500 --> 00:30:43,320 480 00:30:43,320 --> 00:30:44,600 Exited normally. 481 00:30:44,600 --> 00:30:45,850 Oh. 482 00:30:45,850 --> 00:30:48,570 483 00:30:48,570 --> 00:30:53,640 It's possible that it wrapped all the way around, back to-- ignoring that. 484 00:30:53,640 --> 00:30:55,170 Assume it did not exit normally. 485 00:30:55,170 --> 00:30:59,500 486 00:30:59,500 --> 00:31:03,370 There's a complicated answer to that. 487 00:31:03,370 --> 00:31:07,890 >> So now, that's not very useful. 488 00:31:07,890 --> 00:31:11,480 So just running our program inside of this debugger doesn't help us in any 489 00:31:11,480 --> 00:31:15,610 way, since we could have just done dot slash debug from outside GDB. 490 00:31:15,610 --> 00:31:21,250 So the one command that you'll probably-- 491 00:31:21,250 --> 00:31:22,970 and I'll quit this. 492 00:31:22,970 --> 00:31:25,850 Control-d or quit, both work. 493 00:31:25,850 --> 00:31:29,550 So let's open it up again. 494 00:31:29,550 --> 00:31:31,130 >> Another command that you'll probably immediately want to 495 00:31:31,130 --> 00:31:33,600 get used to is Break. 496 00:31:33,600 --> 00:31:37,120 So we'll break on main for now, and then I'll explain that. 497 00:31:37,120 --> 00:31:41,010 498 00:31:41,010 --> 00:31:46,370 Well, here we see we set a breakpoint at this line in debug.c. 499 00:31:46,370 --> 00:31:50,160 So what break means is that when I type run, the program is going to 500 00:31:50,160 --> 00:31:53,560 continue running until I hit a breakpoint. 501 00:31:53,560 --> 00:31:59,390 So when I hit run, the program starts, and then it breaks as soon as it 502 00:31:59,390 --> 00:32:01,940 enters the main function. 503 00:32:01,940 --> 00:32:06,930 Break main is going to be something you pretty commonly do. 504 00:32:06,930 --> 00:32:11,340 >> And now, to introduce you to some more commands. 505 00:32:11,340 --> 00:32:14,330 Notice here, that it's saying we broke at line 11, which is 506 00:32:14,330 --> 00:32:16,230 printf, enter an integer. 507 00:32:16,230 --> 00:32:21,260 So the command Next is going to be how we go to the next line of code. 508 00:32:21,260 --> 00:32:24,810 This is going to allow us to step through our program line by line. 509 00:32:24,810 --> 00:32:26,260 So next. 510 00:32:26,260 --> 00:32:29,820 >> Now line 12, we're going to get the integer. 511 00:32:29,820 --> 00:32:30,450 Next. 512 00:32:30,450 --> 00:32:34,290 And if you just hit Enter again, it'll redo the last thing you did. 513 00:32:34,290 --> 00:32:36,480 So I don't need to type next each time. 514 00:32:36,480 --> 00:32:40,100 So enter an integer, 13. 515 00:32:40,100 --> 00:32:46,940 So now, line 14, while i is greater than 10, and I'll do next. 516 00:32:46,940 --> 00:32:48,685 And we see we're going to decrement i. 517 00:32:48,685 --> 00:32:50,210 So we're going to decrement i again. 518 00:32:50,210 --> 00:32:53,620 >> So now, another useful command is Print. 519 00:32:53,620 --> 00:32:55,750 So Print is going to print out the value of the variable. 520 00:32:55,750 --> 00:32:57,825 Let's bring out the value of variable i. 521 00:32:57,825 --> 00:32:58,705 Let's print i. 522 00:32:58,705 --> 00:33:00,910 It's going to say i is 11. 523 00:33:00,910 --> 00:33:03,330 Now we Next again while i is greater than 10. 524 00:33:03,330 --> 00:33:05,590 So i's still greater than 10, since it's 11. 525 00:33:05,590 --> 00:33:06,920 i minus minus. 526 00:33:06,920 --> 00:33:08,250 Let's print i again. 527 00:33:08,250 --> 00:33:10,950 As expected, it's 10. 528 00:33:10,950 --> 00:33:12,510 >> So now, next. 529 00:33:12,510 --> 00:33:16,250 It's going back to the condition, i is greater than 10, but i is now 10, so 530 00:33:16,250 --> 00:33:20,040 it's not greater than 10, so we expect it to fall out of the while loop. 531 00:33:20,040 --> 00:33:22,220 And now we're below that line of code. 532 00:33:22,220 --> 00:33:28,750 And another command, List, is just going to display the previous and next 533 00:33:28,750 --> 00:33:31,240 couple of lines of code, in case you lost yourself. 534 00:33:31,240 --> 00:33:35,420 So we just exited this while loop, and now we have entered this 535 00:33:35,420 --> 00:33:37,080 while loop, line 18. 536 00:33:37,080 --> 00:33:39,860 So while i does not equal 0. 537 00:33:39,860 --> 00:33:46,570 And, next, i equals i minus 3, and we'll notice, this'll just keep going. 538 00:33:46,570 --> 00:33:48,270 And we can print i. 539 00:33:48,270 --> 00:33:49,990 >> Each command sort of has shortcuts. 540 00:33:49,990 --> 00:33:51,720 So p is short for Print. 541 00:33:51,720 --> 00:33:53,400 So we can p i. 542 00:33:53,400 --> 00:33:57,550 Just keep holding n, or keep doing Next. 543 00:33:57,550 --> 00:33:58,340 Print i again. 544 00:33:58,340 --> 00:34:00,380 You see now it's negative 167. 545 00:34:00,380 --> 00:34:06,030 So this will go on forever, but not really forever, since you just saw, it 546 00:34:06,030 --> 00:34:09,330 will actually end at some point. 547 00:34:09,330 --> 00:34:15,699 >> So that is Beginning GDB. 548 00:34:15,699 --> 00:34:19,504 But let's do one more thing in GDB. 549 00:34:19,504 --> 00:34:20,754 Uh, debug. 550 00:34:20,754 --> 00:34:23,540 551 00:34:23,540 --> 00:34:28,534 So, in this particular case, the infinite loop happened to be inside of 552 00:34:28,534 --> 00:34:30,050 the main function. 553 00:34:30,050 --> 00:34:35,779 And for now, just accept that that I'm going to move the infinite loop into 554 00:34:35,779 --> 00:34:37,029 the foo function. 555 00:34:37,029 --> 00:34:40,679 556 00:34:40,679 --> 00:34:43,730 Just remember that, at the end of this program, well, this was originally 557 00:34:43,730 --> 00:34:46,210 calling foo, which was just going to print i. 558 00:34:46,210 --> 00:34:51,880 But now we're calling foo, which is going to decrement i until it's 0, and 559 00:34:51,880 --> 00:34:54,548 then print that variable. 560 00:34:54,548 --> 00:34:55,469 OK. 561 00:34:55,469 --> 00:34:57,970 Save that. 562 00:34:57,970 --> 00:35:00,175 Make debug. 563 00:35:00,175 --> 00:35:03,310 And now, gdb debug. 564 00:35:03,310 --> 00:35:04,090 OK. 565 00:35:04,090 --> 00:35:10,580 >> So if I just Run then I'm not going to be able to actually step through my 566 00:35:10,580 --> 00:35:11,730 program line-by-line. 567 00:35:11,730 --> 00:35:19,820 So let's break at main, and then type run. 568 00:35:19,820 --> 00:35:28,160 So go through this, printf, enter an integer, get the integer, 13. 569 00:35:28,160 --> 00:35:34,180 570 00:35:34,180 --> 00:35:37,490 So we're going to keep decrementing until i is greater than 10. 571 00:35:37,490 --> 00:35:42,840 Then we're going to fall through the while loop, and get to the line-- 572 00:35:42,840 --> 00:35:44,364 let's open it up in a separate window. 573 00:35:44,364 --> 00:35:48,720 574 00:35:48,720 --> 00:35:53,300 So we decremented until i was no longer greater than 10, and then we 575 00:35:53,300 --> 00:35:55,700 called the function, foo. 576 00:35:55,700 --> 00:36:01,340 >> So what happened as soon as I hit function foo, well, I called foo, and 577 00:36:01,340 --> 00:36:04,030 then I no longer had control over GDB. 578 00:36:04,030 --> 00:36:10,230 So as soon as I hit Next at this line, things continued until this happened, 579 00:36:10,230 --> 00:36:12,400 where the program exited when-- 580 00:36:12,400 --> 00:36:14,450 assume it didn't exist eventually. 581 00:36:14,450 --> 00:36:16,390 You saw it pause for a bit though. 582 00:36:16,390 --> 00:36:22,040 So why did I lose control over the program at that point? 583 00:36:22,040 --> 00:36:27,540 Well, when I type next, that goes to the literal next line of code that 584 00:36:27,540 --> 00:36:28,850 will execute. 585 00:36:28,850 --> 00:36:35,950 So after line 21, the next line of code that will execute is line 22, 586 00:36:35,950 --> 00:36:38,520 which is, exiting from main. 587 00:36:38,520 --> 00:36:43,810 So I don't want to just go to the next line of code. 588 00:36:43,810 --> 00:36:48,170 I want to go into the function, foo, and then also step through 589 00:36:48,170 --> 00:36:49,830 those lines of code. 590 00:36:49,830 --> 00:36:53,726 >> So for that, we have an alternative. 591 00:36:53,726 --> 00:36:56,770 Let's quit that again. 592 00:36:56,770 --> 00:36:58,020 Break main. 593 00:36:58,020 --> 00:37:00,520 594 00:37:00,520 --> 00:37:06,370 Uh, 1, next, next, 13, next, next, next, carefully, 595 00:37:06,370 --> 00:37:09,820 before we hit line foo. 596 00:37:09,820 --> 00:37:10,520 OK. 597 00:37:10,520 --> 00:37:13,700 >> So now, we're at line 21, where we call foo. 598 00:37:13,700 --> 00:37:17,100 We don't want to type next, since that will just call the function foo, and 599 00:37:17,100 --> 00:37:18,710 go to the next line of code. 600 00:37:18,710 --> 00:37:20,840 What we want to use is Step. 601 00:37:20,840 --> 00:37:25,690 So there's a difference between Step and Next, where Step steps into the 602 00:37:25,690 --> 00:37:28,190 function, and Next goes over the function. 603 00:37:28,190 --> 00:37:32,830 It just executes the entirety of the function and keeps going. 604 00:37:32,830 --> 00:37:37,210 >> So Step is going to bring us into the function, foo. 605 00:37:37,210 --> 00:37:41,160 And we see here, now, we're back at this while loop that's, in theory, 606 00:37:41,160 --> 00:37:44,190 going to continue forever. 607 00:37:44,190 --> 00:37:50,420 And if you hit Step, when it isn't even a function to call, then it's 608 00:37:50,420 --> 00:37:51,720 identical to Next. 609 00:37:51,720 --> 00:37:55,320 So it's only when you're at a line that is calling a function that Step 610 00:37:55,320 --> 00:37:56,970 is going to differ from Next. 611 00:37:56,970 --> 00:37:57,930 So Step will bring us here. 612 00:37:57,930 --> 00:38:02,100 Step, step, step, step, step, step, and we'll just infinite loop forever. 613 00:38:02,100 --> 00:38:06,810 >> So you might get used to that as your way of identifying infinite loops, is 614 00:38:06,810 --> 00:38:08,960 just holding this Enter key to see where you get stuck. 615 00:38:08,960 --> 00:38:11,610 616 00:38:11,610 --> 00:38:14,780 There are better ways to do that, but for now, that is perfectly sufficient. 617 00:38:14,780 --> 00:38:17,967 And stylistically, to conform to Style 50, I should have done this. 618 00:38:17,967 --> 00:38:21,550 619 00:38:21,550 --> 00:38:24,030 OK. 620 00:38:24,030 --> 00:38:28,400 >> So one last command to introduce. 621 00:38:28,400 --> 00:38:30,810 Well, let's gdb debug in. 622 00:38:30,810 --> 00:38:35,580 So instead of breaking at main, if I know the foo function is also the 623 00:38:35,580 --> 00:38:39,230 problem, then I could have just said, break at foo, instead. 624 00:38:39,230 --> 00:38:42,310 Let's say I break at both main and foo. 625 00:38:42,310 --> 00:38:45,390 So you can set as many breakpoints as you want. 626 00:38:45,390 --> 00:38:49,230 When I type run, it's going to stop at the-- 627 00:38:49,230 --> 00:38:52,180 ooh, let's recompile, since I changed things. 628 00:38:52,180 --> 00:38:55,950 You'll see this line, Warning, source file is more recent than executable. 629 00:38:55,950 --> 00:38:59,680 So that means that I just went in here and changed these to conform to Style 630 00:38:59,680 --> 00:39:03,100 50, but I did not recompile the program. 631 00:39:03,100 --> 00:39:04,870 So GDB makes me aware of that. 632 00:39:04,870 --> 00:39:10,130 I'll quit, make debug again, hit gdb debug. 633 00:39:10,130 --> 00:39:10,700 OK. 634 00:39:10,700 --> 00:39:12,800 >> So now, back to what I was doing. 635 00:39:12,800 --> 00:39:15,720 Break main, break foo. 636 00:39:15,720 --> 00:39:20,680 Now if I run the program, so it's going to continue until hits a 637 00:39:20,680 --> 00:39:21,320 breakpoint. 638 00:39:21,320 --> 00:39:24,680 That breakpoint happens to be the first one at main. 639 00:39:24,680 --> 00:39:28,630 Now, instead of doing next, next, next, next, next, until I hit foo, I 640 00:39:28,630 --> 00:39:35,230 can type continue, which will continue until you hit the next breakpoint. 641 00:39:35,230 --> 00:39:37,200 I have to enter the integer first. 642 00:39:37,200 --> 00:39:40,570 Continue will continue until I hit the next breakpoint, which is that 643 00:39:40,570 --> 00:39:43,320 function of foo. 644 00:39:43,320 --> 00:39:50,130 >> So Run will run until you hit a breakpoint, but you only type run when 645 00:39:50,130 --> 00:39:54,060 you're starting the program, and then, from then on, it's continue. 646 00:39:54,060 --> 00:40:01,950 If I just did break main and then ran, it'll break at 647 00:40:01,950 --> 00:40:03,670 main, and then continue. 648 00:40:03,670 --> 00:40:10,050 Since I don't have a break point at foo, enter the integer, then now I'm 649 00:40:10,050 --> 00:40:11,380 not going to break at foo. 650 00:40:11,380 --> 00:40:16,318 It's just going to infinite loop until that. 651 00:40:16,318 --> 00:40:17,568 OK. 652 00:40:17,568 --> 00:40:19,500 653 00:40:19,500 --> 00:40:24,420 >> So that's Intro to GDB. 654 00:40:24,420 --> 00:40:27,790 You should start using it in your problem sets. 655 00:40:27,790 --> 00:40:30,550 It can be very helpful to identify bugs. 656 00:40:30,550 --> 00:40:35,280 If you actually just, line-by-line, go through your code, and compare what is 657 00:40:35,280 --> 00:40:39,740 actually happening with what you expect to happen, then it's pretty 658 00:40:39,740 --> 00:40:41,060 difficult to miss your bugs. 659 00:40:41,060 --> 00:40:45,280 660 00:40:45,280 --> 00:40:46,530 OK. 661 00:40:46,530 --> 00:40:48,310 662 00:40:48,310 --> 00:40:54,040 >> So last week David brought up this secret-key cryptography stuff for the 663 00:40:54,040 --> 00:40:59,350 first time, where we don't want passwords just be stored on our 664 00:40:59,350 --> 00:41:03,210 computer in some plain text file, where someone can come over and just 665 00:41:03,210 --> 00:41:04,660 open it up and read them. 666 00:41:04,660 --> 00:41:07,530 Ideally, they would be encrypted in some way. 667 00:41:07,530 --> 00:41:13,340 And in Problem Set 2, you'll be dealing with one method of encryption, 668 00:41:13,340 --> 00:41:16,520 or, well, two methods, but they aren't so great. 669 00:41:16,520 --> 00:41:20,050 If you do the hacker edition, you're also going to be dealing with 670 00:41:20,050 --> 00:41:22,150 decrypting some things. 671 00:41:22,150 --> 00:41:29,770 >> So the issue now is, well, even if we have the strongest encryption 672 00:41:29,770 --> 00:41:34,830 algorithm in the world, if you choose a particularly poor password, then it 673 00:41:34,830 --> 00:41:37,720 won't help you very much, since people will still be able to figure it out. 674 00:41:37,720 --> 00:41:41,530 Even if seeing the encrypted string and it looks like a mess of garbage 675 00:41:41,530 --> 00:41:44,760 that means nothing to them, if they still just need to try a few passwords 676 00:41:44,760 --> 00:41:50,560 to figure it out, then you aren't very secure. 677 00:41:50,560 --> 00:41:55,890 So watching a video that makes that point. 678 00:41:55,890 --> 00:41:59,587 679 00:41:59,587 --> 00:42:00,970 >> [VIDEO PLAYBACK] 680 00:42:00,970 --> 00:42:02,100 >> -Helmet, you fiend. 681 00:42:02,100 --> 00:42:03,370 What's going on? 682 00:42:03,370 --> 00:42:05,170 What are you doing to my daughter? 683 00:42:05,170 --> 00:42:09,910 >> -Permit me to introduce the brilliant young plastic surgeon, Dr. Phillip 684 00:42:09,910 --> 00:42:13,730 Schlotkin, the greatest nose job man in the entire 685 00:42:13,730 --> 00:42:16,080 universe, and Beverly Hills. 686 00:42:16,080 --> 00:42:17,210 >> -Your Highness. 687 00:42:17,210 --> 00:42:18,070 >> -Nose job? 688 00:42:18,070 --> 00:42:18,670 I don't understand. 689 00:42:18,670 --> 00:42:20,090 She's already had a nose job. 690 00:42:20,090 --> 00:42:21,910 It was a sweet sixteen present. 691 00:42:21,910 --> 00:42:22,140 >> -No. 692 00:42:22,140 --> 00:42:23,690 It's not what you think. 693 00:42:23,690 --> 00:42:25,420 It's much, much worse. 694 00:42:25,420 --> 00:42:30,300 If you do not give me the combination to the air shield, Dr. Schlotkin will 695 00:42:30,300 --> 00:42:34,226 give your daughter back her old nose. 696 00:42:34,226 --> 00:42:35,476 >> -No. 697 00:42:35,476 --> 00:42:38,712 698 00:42:38,712 --> 00:42:40,516 Where did you get that? 699 00:42:40,516 --> 00:42:41,440 >> -All right. 700 00:42:41,440 --> 00:42:42,180 I'll tell. 701 00:42:42,180 --> 00:42:43,381 I'll tell. 702 00:42:43,381 --> 00:42:44,263 No, daddy. 703 00:42:44,263 --> 00:42:45,590 No, you mustn't. 704 00:42:45,590 --> 00:42:46,860 >> -You're right, my dear. 705 00:42:46,860 --> 00:42:48,450 I'll miss your new nose. 706 00:42:48,450 --> 00:42:52,090 But I will not tell him the combination, no matter what. 707 00:42:52,090 --> 00:42:53,680 >> -Very well. 708 00:42:53,680 --> 00:42:55,685 Dr. Schlotkin, do your worst. 709 00:42:55,685 --> 00:42:56,914 >> -My pleasure. 710 00:42:56,914 --> 00:43:00,690 >> [TOOLS BEING SHARPENED] 711 00:43:00,690 --> 00:43:01,910 >> -No. 712 00:43:01,910 --> 00:43:02,520 Wait. 713 00:43:02,520 --> 00:43:03,836 Wait. 714 00:43:03,836 --> 00:43:05,300 I'll tell. 715 00:43:05,300 --> 00:43:06,880 I'll tell. 716 00:43:06,880 --> 00:43:09,130 >> -I knew it would work. 717 00:43:09,130 --> 00:43:09,900 All right. 718 00:43:09,900 --> 00:43:12,850 Give it to me. 719 00:43:12,850 --> 00:43:16,918 >> -The combination is one. 720 00:43:16,918 --> 00:43:17,406 >> -One. 721 00:43:17,406 --> 00:43:18,382 >> -One. 722 00:43:18,382 --> 00:43:19,358 >> -Two. 723 00:43:19,358 --> 00:43:19,846 >> -Two. 724 00:43:19,846 --> 00:43:20,822 >> -Two. 725 00:43:20,822 --> 00:43:21,310 >> -Three. 726 00:43:21,310 --> 00:43:21,798 >> -Three. 727 00:43:21,798 --> 00:43:22,774 >> -Three. 728 00:43:22,774 --> 00:43:23,262 >> -Four. 729 00:43:23,262 --> 00:43:23,750 >> -Four. 730 00:43:23,750 --> 00:43:26,150 >> -Four. 731 00:43:26,150 --> 00:43:27,010 >> -Five. 732 00:43:27,010 --> 00:43:27,670 >> -Five. 733 00:43:27,670 --> 00:43:29,010 >> -Five. 734 00:43:29,010 --> 00:43:34,770 >> -So the combination is one, two, three, four, five. 735 00:43:34,770 --> 00:43:37,460 That's the stupidest combination I ever heard in my life. 736 00:43:37,460 --> 00:43:39,710 That's the kind of thing an idiot would have on his luggage. 737 00:43:39,710 --> 00:43:42,000 >> -Thank you, your Highness. 738 00:43:42,000 --> 00:43:43,530 >> -What did you do? 739 00:43:43,530 --> 00:43:44,490 >> -I turned off the wall. 740 00:43:44,490 --> 00:43:45,420 >> -No you didn't. 741 00:43:45,420 --> 00:43:45,840 You turned off the whole movie. 742 00:43:45,840 --> 00:43:46,930 >> -I must have pressed the wrong button. 743 00:43:46,930 --> 00:43:48,265 >> -Well, put it back on. 744 00:43:48,265 --> 00:43:49,110 Put the movie back on. 745 00:43:49,110 --> 00:43:49,510 >> -Yes, sir. 746 00:43:49,510 --> 00:43:49,917 Yes, sir. 747 00:43:49,917 --> 00:43:50,324 >> -Let's go, Arnold. 748 00:43:50,324 --> 00:43:51,140 Come, Gretchen. 749 00:43:51,140 --> 00:43:53,060 Of course, you know I'll still have to bill you for this. 750 00:43:53,060 --> 00:43:53,440 >> [END VIDEO PLAYBACK] 751 00:43:53,440 --> 00:43:54,690 >> ROB BODEN: All right. 752 00:43:54,690 --> 00:43:59,690 753 00:43:59,690 --> 00:44:08,430 So now that we're already talking about security in some ways, nice 754 00:44:08,430 --> 00:44:16,050 little movie poster, so in recent days, these issues with the NSA 755 00:44:16,050 --> 00:44:17,300 monitoring everything. 756 00:44:17,300 --> 00:44:21,840 757 00:44:21,840 --> 00:44:26,930 It can be difficult to feel like you have some sort of privacy in the 758 00:44:26,930 --> 00:44:34,540 online world, although I couldn't tell you most of the details of PRISM. 759 00:44:34,540 --> 00:44:42,130 So moving beyond PRISM, we're not going to be talking about that, now 760 00:44:42,130 --> 00:44:44,030 think about your laptop. 761 00:44:44,030 --> 00:44:48,360 So up here, I want to switch to my actual account, 762 00:44:48,360 --> 00:44:50,370 with my little penguin. 763 00:44:50,370 --> 00:44:57,310 So I have a password set, and that password is whatever I want it to be. 764 00:44:57,310 --> 00:45:02,430 >> But remember that what I'm logging in with, so this login 765 00:45:02,430 --> 00:45:04,850 prompt, is some program. 766 00:45:04,850 --> 00:45:07,910 It's some program that was written by some person. 767 00:45:07,910 --> 00:45:13,250 And so, that person, if they are particularly malicious, they could 768 00:45:13,250 --> 00:45:17,780 have said, all right, so if the password that I enter is equal to my 769 00:45:17,780 --> 00:45:22,800 actual password, or it's equal to some special password-- 770 00:45:22,800 --> 00:45:25,550 David is awesome or something-- 771 00:45:25,550 --> 00:45:27,190 then let them in. 772 00:45:27,190 --> 00:45:33,760 So a malicious programmer could have access to all of your Macs, or 773 00:45:33,760 --> 00:45:36,150 Windows, or anything. 774 00:45:36,150 --> 00:45:41,980 >> So that isn't much of a concern, since, I mean, this is login program 775 00:45:41,980 --> 00:45:48,720 that's shipped with OS X, hundreds or thousands of people have 776 00:45:48,720 --> 00:45:50,020 reviewed this code. 777 00:45:50,020 --> 00:45:55,330 And so, if, in your code somewhere, you say if this string equals equals 778 00:45:55,330 --> 00:45:58,860 David is awesome, login, then someone's going to be, like, wait. 779 00:45:58,860 --> 00:45:59,800 This is not right. 780 00:45:59,800 --> 00:46:01,790 This shouldn't be here. 781 00:46:01,790 --> 00:46:06,650 So that's one way we get things to be kind of secure. 782 00:46:06,650 --> 00:46:10,300 >> But think about even programs that you write. 783 00:46:10,300 --> 00:46:13,000 Let's say you wrote the login program. 784 00:46:13,000 --> 00:46:20,440 So this login program that you wrote, so obviously, you are a good 785 00:46:20,440 --> 00:46:21,210 programmer. 786 00:46:21,210 --> 00:46:25,610 You're not going to put any malicious if x equals equals David is awesome 787 00:46:25,610 --> 00:46:27,860 into your code. 788 00:46:27,860 --> 00:46:31,930 But this program, what do you use to compile this program? 789 00:46:31,930 --> 00:46:34,180 Something like Clang. 790 00:46:34,180 --> 00:46:38,460 So what if the person who happened to write Clang special cased in Clang 791 00:46:38,460 --> 00:46:44,310 something like, if I am compiling the login program, then enter this code 792 00:46:44,310 --> 00:46:49,720 into the login program that says, if x equals equals David is awesome? 793 00:46:49,720 --> 00:46:59,890 So not quite yet, but we have the same issue here, where Clang, well, 794 00:46:59,890 --> 00:47:03,790 thousands, if not tens of thousands of people, have looked at Clang, have 795 00:47:03,790 --> 00:47:07,160 looked at its lines of code and said, all right, there's nothing bad here. 796 00:47:07,160 --> 00:47:10,680 Obviously, no one is doing anything this malicious. 797 00:47:10,680 --> 00:47:15,780 >> But what is Clang itself, like, what if I compile Clang? 798 00:47:15,780 --> 00:47:20,900 What if I have some compiler that compiles Clang that inserts into Clang 799 00:47:20,900 --> 00:47:25,610 this special hack that says, all right, when I compile Clang, then the 800 00:47:25,610 --> 00:47:31,290 executable I get should specially look inside of the login program and insert 801 00:47:31,290 --> 00:47:34,230 this password, equals equals Dave is awesome? 802 00:47:34,230 --> 00:47:37,990 So remember that your compiler itself needs to be compiled at some point. 803 00:47:37,990 --> 00:47:42,810 So if what you choose to compile Clang with, itself is malicious, then you 804 00:47:42,810 --> 00:47:45,580 could be screwed the whole way down the line. 805 00:47:45,580 --> 00:47:49,630 >> So here, we have Ken Thompson and Dennis Ritchie. 806 00:47:49,630 --> 00:47:53,780 So this is an iconic photo. 807 00:47:53,780 --> 00:47:55,470 Dennis Ritchie is on the right. 808 00:47:55,470 --> 00:47:58,740 He is a major-- 809 00:47:58,740 --> 00:48:03,640 pretty much wrote C. So you can thank him for this class. 810 00:48:03,640 --> 00:48:04,840 Ken Thomson's on the left. 811 00:48:04,840 --> 00:48:07,780 The two of them basically wrote UNIX. 812 00:48:07,780 --> 00:48:10,140 Well, they were major contributors in UNIX. 813 00:48:10,140 --> 00:48:11,310 There were some others. 814 00:48:11,310 --> 00:48:16,240 So Ken Thompson, at some point, he wins the Turing Award. 815 00:48:16,240 --> 00:48:20,860 And the Turing award, I've always heard it referenced this way, it's the 816 00:48:20,860 --> 00:48:23,100 Nobel Prize of computer science. 817 00:48:23,100 --> 00:48:27,500 >> So at the Turing Award, he has to give his acceptance speech. 818 00:48:27,500 --> 00:48:31,790 And he gives this very famous speech now, called Reflections on Trusting 819 00:48:31,790 --> 00:48:35,620 Trust, which we have linked to on the course website. 820 00:48:35,620 --> 00:48:41,670 And in this speech, he says, all right, so I wrote UNIX, and now all of 821 00:48:41,670 --> 00:48:43,320 you people are using UNIX. 822 00:48:43,320 --> 00:48:46,960 Now, remember today that Linux is a direct descendant of UNIX. 823 00:48:46,960 --> 00:48:50,140 OS X directly uses UNIX. 824 00:48:50,140 --> 00:48:53,810 Windows doesn't so much, but a lot of ideas were taken from UNIX. 825 00:48:53,810 --> 00:48:59,220 >> So he goes up to the stage and says, all right, I wrote UNIX. 826 00:48:59,220 --> 00:49:03,940 And just so you guys know, I'm able to log into every 827 00:49:03,940 --> 00:49:05,590 single one of your computers. 828 00:49:05,590 --> 00:49:14,280 Since I put one of these special if x equals equals Ken Thomson is awesome, 829 00:49:14,280 --> 00:49:16,350 then I'm allowed to login. 830 00:49:16,350 --> 00:49:18,370 So people are like, well, how'd you do that? 831 00:49:18,370 --> 00:49:21,090 We looked at the login program and nothing's there. 832 00:49:21,090 --> 00:49:24,700 He's like, well, I modified the compiler to log in the login program 833 00:49:24,700 --> 00:49:30,490 so that the login program now will have that x equals equals Ken Thompson 834 00:49:30,490 --> 00:49:31,700 is awesome. 835 00:49:31,700 --> 00:49:33,120 >> And they say, well, that's not true. 836 00:49:33,120 --> 00:49:35,740 We're looking at the compiler, and the compiler doesn't have any lines of 837 00:49:35,740 --> 00:49:36,400 code like that. 838 00:49:36,400 --> 00:49:40,540 He's like, OK, but what are you compiling the compiler with? 839 00:49:40,540 --> 00:49:44,810 And they think, and he's, like, well, I'm the one who gave you the compiler 840 00:49:44,810 --> 00:49:50,580 you're using to compile the compiler, so you are compiling a compiler, that 841 00:49:50,580 --> 00:49:56,390 itself is malicious, and will break the login program. 842 00:49:56,390 --> 00:49:59,360 So basically, at that point, there's no way you could look at the source 843 00:49:59,360 --> 00:50:02,450 code of the login program to see what is wrong. 844 00:50:02,450 --> 00:50:04,220 You couldn't even look in the source code of the compiler 845 00:50:04,220 --> 00:50:06,790 to see what is wrong. 846 00:50:06,790 --> 00:50:11,940 >> You would need to look at the machine code, the actual binary of the 847 00:50:11,940 --> 00:50:16,760 compiled compiler to see, wait, these lines of code should not be here. 848 00:50:16,760 --> 00:50:22,130 But Ken Thompson took it one step further and said, well, there are 849 00:50:22,130 --> 00:50:25,980 these special programs that actually help you read the binary of programs, 850 00:50:25,980 --> 00:50:29,340 and so if someone used that program to read the binary, they would see these 851 00:50:29,340 --> 00:50:30,490 lines of code. 852 00:50:30,490 --> 00:50:34,020 He modified those programs to say, all right, if you're looking at the 853 00:50:34,020 --> 00:50:38,460 compiler, don't show this particular set of binary. 854 00:50:38,460 --> 00:50:42,830 >> So then you need to take that a step further and basically, that could have 855 00:50:42,830 --> 00:50:46,210 taken multiple levels of indirection, and at some point, no one's actually 856 00:50:46,210 --> 00:50:47,990 going to be checking. 857 00:50:47,990 --> 00:50:52,590 So the moral of the story is, you're not going to be writing 858 00:50:52,590 --> 00:50:54,340 Clang in this class. 859 00:50:54,340 --> 00:50:57,020 You're going to be using climbing Clang a lot in this class. 860 00:50:57,020 --> 00:51:00,490 For all you know, Clang is a malicious program that is sabotaging every 861 00:51:00,490 --> 00:51:03,520 single program you've ever compiled. 862 00:51:03,520 --> 00:51:08,206 And to leave you on that very ominous note, see you on Wednesday. 863 00:51:08,206 --> 00:51:10,030 >> [APPLAUSE] 864 00:51:10,030 --> 00:51:12,935 >> SPEAKER 2: At the next CS50. 865 00:51:12,935 --> 00:51:14,580 >> SPEAKER 3: Don't you dare say that. 866 00:51:14,580 --> 00:51:15,930 You can do this. 867 00:51:15,930 --> 00:51:19,440 You've done this before, you can do this today, you can do this tomorrow. 868 00:51:19,440 --> 00:51:20,930 You've been doing this for years. 869 00:51:20,930 --> 00:51:22,790 Just go up there and do this. 870 00:51:22,790 --> 00:51:24,310 You can do this. 871 00:51:24,310 --> 00:51:26,102 >> [MUSIC PLAYING]