1 00:00:09,096 --> 00:00:11,846 >> All right, welcome to CS 50. 2 00:00:11,846 --> 00:00:13,666 This is week 4. 3 00:00:13,666 --> 00:00:15,496 So it's always kind of fun when you pick up the paper 4 00:00:15,496 --> 00:00:17,736 in the morning and there's actually something apropos 5 00:00:17,736 --> 00:00:18,936 to class that day. 6 00:00:19,226 --> 00:00:20,926 And this is an article in the front page 7 00:00:20,926 --> 00:00:22,566 of today's Wall Street Journal. 8 00:00:22,816 --> 00:00:25,286 And those of you who have a computer know 9 00:00:25,286 --> 00:00:27,106 that your computer has a keyboard, 10 00:00:27,106 --> 00:00:29,466 but it's called a QWERTY keyboard for some reason. 11 00:00:30,226 --> 00:00:32,096 Why is it called the QWERTY keyboard? 12 00:00:32,796 --> 00:00:36,436 Okay, can't actually make out any of those comments, 13 00:00:36,436 --> 00:00:40,476 but presumably because it spells QWERTY, Q-W-E-R-T-Y. 14 00:00:40,636 --> 00:00:44,176 Here's a random keyboard from the Internet, Q-W-E-R-T-Y, 15 00:00:44,426 --> 00:00:46,806 never heard this expression you have a QWERTY keyboard just 16 00:00:46,806 --> 00:00:49,086 because that's the most phonetically pronounceable 17 00:00:49,336 --> 00:00:52,006 string of characters someone discovered many years ago. 18 00:00:52,006 --> 00:00:53,766 But there's this alternative called Dvorak, 19 00:00:54,216 --> 00:00:57,896 which some people, perhaps those among those more comfortable, 20 00:00:57,896 --> 00:00:58,796 sometimes use. 21 00:00:59,056 --> 00:01:00,486 Personally, I never got the hang of this. 22 00:01:00,486 --> 00:01:01,226 But this article here 23 00:01:01,226 --> 00:01:02,866 in the Wall Street Journal is about this. 24 00:01:03,276 --> 00:01:05,976 Quick little excerpt which amused me. 25 00:01:05,976 --> 00:01:08,526 The Dvorak keyboard layout, though around for decades, 26 00:01:08,726 --> 00:01:11,256 is as little known among the general typing population 27 00:01:11,256 --> 00:01:14,536 as it is passionately embraced by its devotees. 28 00:01:14,536 --> 00:01:17,166 It is to the keyboard what Esperanto is to language 29 00:01:17,166 --> 00:01:18,966 and what Betamax is to video tape. 30 00:01:18,966 --> 00:01:22,256 Fans say it let's them type at blazing fast speeds, 31 00:01:22,256 --> 00:01:24,706 with less strain on their hands and wrists than typing 32 00:01:24,956 --> 00:01:26,176 on a conventional keyboard. 33 00:01:26,306 --> 00:01:29,256 And this was, I thought, the punch line, nobody else cares. 34 00:01:30,066 --> 00:01:34,796 And if you actually then follow up, let's see, turn to Page A-4, 35 00:01:35,356 --> 00:01:36,726 there's more discussion on this. 36 00:01:36,726 --> 00:01:39,416 And the context was there's a bunch of people sort 37 00:01:39,416 --> 00:01:42,076 of bemoaning the fact that smart phones these days, iPhones 38 00:01:42,076 --> 00:01:44,556 and what not, apparently don't support Dvorak, they've kind 39 00:01:44,556 --> 00:01:46,066 of optimized for the rest of the world. 40 00:01:46,436 --> 00:01:49,096 The Wall Street Journal really went to town on people here. 41 00:01:49,096 --> 00:01:53,326 Smart phones seem dumb to Dvorak fans, but let's see -- 42 00:01:53,326 --> 00:01:55,926 this was kind of cute. 43 00:01:55,926 --> 00:01:58,596 So the final quote in this article is I think it's really 44 00:01:58,596 --> 00:02:01,716 sad, says one Dvorak devotee, that Dvorak isn't 45 00:02:01,716 --> 00:02:04,386 on smart phones, but it's something I'll have 46 00:02:04,386 --> 00:02:04,966 to live with. 47 00:02:04,966 --> 00:02:07,406 I'm a Dvorak typist in a QWERTY world. 48 00:02:07,786 --> 00:02:12,786 So those of you -- some more geek humor, those of you 49 00:02:12,786 --> 00:02:15,026 who have travelled internationally or are 50 00:02:15,026 --> 00:02:17,106 from abroad known that there are certainly differences 51 00:02:17,106 --> 00:02:18,086 in certain countries. 52 00:02:18,376 --> 00:02:20,616 Most recently I was in France and sat 53 00:02:20,616 --> 00:02:23,006 down in the hotel's kiosk and got so frustrated, 54 00:02:23,006 --> 00:02:25,046 because I couldn't find, like, the forward slash symbol, 55 00:02:25,046 --> 00:02:26,426 because it was in just a different place. 56 00:02:26,736 --> 00:02:28,106 But there's yet other keyboards out there. 57 00:02:28,106 --> 00:02:30,526 I just did actually a quick Google image search 58 00:02:30,876 --> 00:02:32,496 and found this one, which actually some 59 00:02:32,496 --> 00:02:34,696 of my more advanced friends have. 60 00:02:35,066 --> 00:02:36,816 It's this crazy looking thing, 61 00:02:36,816 --> 00:02:40,356 which frankly I can not even send an e-mail effectively on. 62 00:02:40,666 --> 00:02:41,836 But it looks a little like this. 63 00:02:41,836 --> 00:02:46,596 And frankly, the motivation -- laughing at me, huh? 64 00:02:46,696 --> 00:02:47,316 There -- oh! 65 00:02:48,576 --> 00:02:55,096 So frankly, I mean, I don't mean to poke fun at these things, 66 00:02:55,136 --> 00:02:56,796 because even I have had issues with RSI, 67 00:02:56,796 --> 00:03:00,926 repetitive strain issues, that actually can be alleviated 68 00:03:00,926 --> 00:03:03,196 to some extent by devices like this. 69 00:03:03,256 --> 00:03:05,876 But again, I just never wrapped my own mind around this. 70 00:03:05,916 --> 00:03:08,956 But the neatest keyboard I think I ever saw was owned 71 00:03:08,956 --> 00:03:11,876 by a really geeky MIT friend of mine in graduate school, 72 00:03:13,076 --> 00:03:15,746 whereby in his lab, I sat down, went to just send an e-mail 73 00:03:15,746 --> 00:03:17,666 or something, looked down at this keyboard, 74 00:03:17,666 --> 00:03:20,016 looked like a very standard, black Dell keyboard, 75 00:03:20,016 --> 00:03:22,136 keys not like this, but a normal keyboard, 76 00:03:22,356 --> 00:03:24,076 but none of them were labelled. 77 00:03:24,456 --> 00:03:27,946 So there was no Q W E R T, no ABC, 78 00:03:27,946 --> 00:03:30,246 there was no labels on this keyboard. 79 00:03:30,516 --> 00:03:33,006 And it was frankly the most effective way I've ever seen 80 00:03:33,006 --> 00:03:34,956 of keeping people off your computer. 81 00:03:35,296 --> 00:03:39,456 Because -- but it was also this really interesting, like, 82 00:03:39,606 --> 00:03:43,226 intellectual challenge, because it reminded me at the end 83 00:03:43,226 --> 00:03:46,086 of Star Wars where Luke kind of has to put away his machine 84 00:03:46,086 --> 00:03:47,286 and just go on faith alone. 85 00:03:47,516 --> 00:03:49,346 I mean, that was the only way I was able to type. 86 00:03:49,346 --> 00:03:51,056 I couldn't look down and type my e-mail. 87 00:03:51,276 --> 00:03:54,196 I had to just literally, like, close my eyes and idea it rote, 88 00:03:54,196 --> 00:03:56,746 from memory, and I actually got through it. 89 00:03:56,746 --> 00:03:59,306 But it was the neatest thing I think I have ever seen. 90 00:03:59,456 --> 00:04:01,016 Better yet, I've also seen on line, 91 00:04:01,296 --> 00:04:03,606 keyboards that are optimized for moving letters 92 00:04:03,606 --> 00:04:05,066 around just to mess with people. 93 00:04:05,126 --> 00:04:07,126 So even though it's actually a normal keyboard, 94 00:04:07,126 --> 00:04:09,966 people don't realize what the labels actually mean. 95 00:04:10,376 --> 00:04:11,866 So enough about that. 96 00:04:11,866 --> 00:04:12,566 In other news. 97 00:04:12,566 --> 00:04:14,356 If you haven't returned your scratch boards yet, 98 00:04:14,356 --> 00:04:15,726 hope you're having a lot of fun with them, 99 00:04:15,966 --> 00:04:18,346 but please do return those to any 100 00:04:18,346 --> 00:04:19,736 of the teaching fellows in the corner here. 101 00:04:19,736 --> 00:04:22,826 We'll pretty much cut off that limit this week on Wednesday. 102 00:04:24,026 --> 00:04:28,046 And let's see -- in other news about grades. 103 00:04:28,046 --> 00:04:30,726 If we can pull up the lights for just a second. 104 00:04:30,786 --> 00:04:32,876 I mentioned briefly at the very start of the term, 105 00:04:33,226 --> 00:04:35,956 but now that you've started getting official feedback 106 00:04:36,006 --> 00:04:39,556 from your TFs, it's perhaps worth a quick recap. 107 00:04:40,906 --> 00:04:42,986 I think two of the wheels are locked today. 108 00:04:43,666 --> 00:04:47,606 So this is essentially a summary, numerically, 109 00:04:47,606 --> 00:04:48,426 of what each Page 2 110 00:04:48,426 --> 00:04:51,866 of the problem sets convey qualitatively. 111 00:04:51,866 --> 00:04:54,516 So the teaching fellows have all been asked very expressly 112 00:04:54,766 --> 00:04:56,786 to focus this term as in past terms 113 00:04:57,106 --> 00:04:59,566 on as much qualitative feedback as possible and less 114 00:04:59,566 --> 00:05:02,186 on the quantitative feed back, for a number of reasons, 115 00:05:02,186 --> 00:05:04,626 the least of which is far more educationally valuable 116 00:05:04,626 --> 00:05:06,016 to get pros comments back 117 00:05:06,016 --> 00:05:08,946 from a teacher pushing you toward how you might write 118 00:05:08,946 --> 00:05:10,886 better code, solve problems more efficiently 119 00:05:11,176 --> 00:05:13,846 than just getting numeric scores in and of themselves, 120 00:05:14,226 --> 00:05:16,036 not pedologically that interesting. 121 00:05:16,036 --> 00:05:18,636 But I know there is a concern, last semester, this semester, 122 00:05:18,876 --> 00:05:22,256 with getting things like threes, because the mathematician 123 00:05:22,256 --> 00:05:24,056 in the room immediately does 3 divided by 5, 124 00:05:24,186 --> 00:05:27,746 60% on my first Problem Set, and you get really frustrated 125 00:05:27,746 --> 00:05:28,736 or angry or disappointed, 126 00:05:28,736 --> 00:05:30,266 or whatever the emotion happens to be. 127 00:05:30,566 --> 00:05:33,496 But realize, as these labels are meant to imply, 128 00:05:33,846 --> 00:05:37,686 the goal of the course in terms of grades at term's start is 129 00:05:37,716 --> 00:05:41,466 to start off as many students as is possible, as is appropriate, 130 00:05:41,666 --> 00:05:43,746 in this middle sweet spot, to be honest. 131 00:05:43,786 --> 00:05:44,416 3 is good. 132 00:05:44,486 --> 00:05:46,636 3 is not a C, 3 is not a 60%. 133 00:05:46,636 --> 00:05:48,176 You can do all the arithmetic you want, 134 00:05:48,446 --> 00:05:50,076 but that's not how we view these numbers. 135 00:05:50,076 --> 00:05:52,566 In fact, the TFs have all been asked very specifically 136 00:05:52,566 --> 00:05:57,906 by me to, you know, keep their students as best as is possible, 137 00:05:58,286 --> 00:05:59,596 you know, in this zone at first, 138 00:05:59,596 --> 00:06:01,176 so there's actually room to grow. 139 00:06:01,176 --> 00:06:03,876 And frankly, even among those more comfortable in this room, 140 00:06:03,876 --> 00:06:06,426 odds are there's still plenty of room for improvements 141 00:06:06,426 --> 00:06:08,146 within your code, even though relative 142 00:06:08,186 --> 00:06:11,316 to say a complete newbs code, it might be better. 143 00:06:11,466 --> 00:06:14,096 But again, we ultimately consider students 144 00:06:14,416 --> 00:06:17,236 on an individual basis at term's semester, then again, 145 00:06:17,236 --> 00:06:19,456 what's most important in this course is not so much 146 00:06:19,456 --> 00:06:22,016 where you end up relative to that person sitting next to you, 147 00:06:22,016 --> 00:06:24,096 but where you are relative to your other self. 148 00:06:24,096 --> 00:06:26,716 So do expect 3s in the beginning of the semester. 149 00:06:26,716 --> 00:06:27,906 If you're getting betters already, 150 00:06:27,906 --> 00:06:30,346 even if you got a couple of bests here, outstanding. 151 00:06:30,346 --> 00:06:32,606 If you're in the 1, 2 range, take advantage 152 00:06:32,606 --> 00:06:35,186 of the innumerable advantages the course offers, office hours 153 00:06:35,186 --> 00:06:38,306 and more, and do realize what these axes mean, if not clear 154 00:06:38,306 --> 00:06:39,636 from the PDFs themselves. 155 00:06:39,906 --> 00:06:41,246 So correctness really boils 156 00:06:41,246 --> 00:06:45,336 down to does your program do what the spec told you it 157 00:06:45,336 --> 00:06:45,876 should do. 158 00:06:45,876 --> 00:06:49,276 Is it buggy, is it bug-free, does it behave as expected. 159 00:06:49,576 --> 00:06:51,706 Design is nor of a subjective matter. 160 00:06:51,706 --> 00:06:53,746 And this is why we have humans grading your work 161 00:06:53,746 --> 00:06:54,846 and not just computers. 162 00:06:54,846 --> 00:06:56,576 We do use automated tools to assess 163 00:06:56,706 --> 00:06:58,126 for the most part correctness, 164 00:06:58,186 --> 00:06:59,676 because we can compare your output 165 00:06:59,676 --> 00:07:00,986 against some conical output, 166 00:07:01,276 --> 00:07:03,886 but computers do not do a very good job at these other details, 167 00:07:03,886 --> 00:07:06,146 and that's why we have a team of some 30 teaching fellows. 168 00:07:06,406 --> 00:07:10,176 So design is about how well did you solve this problem, 169 00:07:10,176 --> 00:07:12,916 how clever was your design or how clean was your design. 170 00:07:13,216 --> 00:07:16,566 If you have a perfectly functional program that's 100% 171 00:07:16,636 --> 00:07:19,366 correct, that doesn't mean it was designed well. 172 00:07:19,406 --> 00:07:23,196 You might have again, loops and if conditions that are nested, 173 00:07:23,246 --> 00:07:24,746 you know, this wide on the screen. 174 00:07:24,746 --> 00:07:26,456 There's probably an opportunity to fix that. 175 00:07:26,456 --> 00:07:27,846 Your program might be this long, 176 00:07:28,126 --> 00:07:29,086 when really it could have been this long, 177 00:07:29,086 --> 00:07:30,986 when really it could have been this long, or your program runs 178 00:07:30,986 --> 00:07:34,516 in quadratic time when really you could have done the problem 179 00:07:34,516 --> 00:07:35,926 -- the same problem linearly. 180 00:07:35,926 --> 00:07:38,646 So that's what design speaks to, and this is where the TFs 181 00:07:38,646 --> 00:07:41,506 on the PDFs and on e-mails are asked to provide 182 00:07:41,506 --> 00:07:43,426 as much qualitative feedback as possible. 183 00:07:43,626 --> 00:07:45,926 And style, frankly, is relatively easy. 184 00:07:45,926 --> 00:07:48,456 If you're losing points on style by semester's end, frankly, 185 00:07:48,456 --> 00:07:49,936 you're just throwing points away. 186 00:07:49,936 --> 00:07:51,526 And this is important. 187 00:07:51,666 --> 00:07:54,186 Naming variables appropriately, commenting your code, 188 00:07:54,186 --> 00:07:57,876 indenting properly, goes a huge way long-term, whether 189 00:07:57,876 --> 00:07:59,866 or not you're still taking courses after 50, 190 00:08:00,126 --> 00:08:03,036 just keeping your code understandable by you, even I. 191 00:08:03,036 --> 00:08:05,646 If I sit down a year hence and look at some of my own code 192 00:08:05,646 --> 00:08:08,136 that I've written, I have no clue what some of it does 193 00:08:08,136 --> 00:08:09,656 if I didn't actually take the time 194 00:08:09,656 --> 00:08:11,606 and priority to design is well. 195 00:08:11,606 --> 00:08:14,196 So think of style as something you should be doing 196 00:08:14,196 --> 00:08:16,386 as you write each and every line of code. 197 00:08:16,386 --> 00:08:18,876 Too often, it seems, do students relegate style 198 00:08:18,876 --> 00:08:21,196 to the very last minute, I'll comment it all later, 199 00:08:21,426 --> 00:08:24,056 I'll fix things later -- that never seems to happen, right? 200 00:08:24,056 --> 00:08:26,186 Because 6:59 p.m. rolls around pretty fast, 201 00:08:26,696 --> 00:08:28,536 and that's the first thing to go. 202 00:08:28,536 --> 00:08:30,536 And it's the easiest thing, frankly, to fix. 203 00:08:30,676 --> 00:08:32,496 So don't do yourself a disservice with that. 204 00:08:32,496 --> 00:08:34,836 And if you have any concerns, by all means reach out to me 205 00:08:35,126 --> 00:08:36,566 or your own teaching fellow or [Inaudible] 206 00:08:37,156 --> 00:08:39,166 or Jan [Inaudible] throughout the semester. 207 00:08:40,176 --> 00:08:42,036 All right, with that said, 208 00:08:42,036 --> 00:08:43,916 today's where I think things begin 209 00:08:43,916 --> 00:08:47,196 to get particularly interesting because we can start 210 00:08:47,306 --> 00:08:50,446 to do more sophisticated things, 211 00:08:50,446 --> 00:08:53,766 both mechanically using various tools and also conceptually, 212 00:08:53,766 --> 00:08:56,926 because now we've gotten underneath our belts a lot 213 00:08:56,926 --> 00:08:58,886 of the basic building blocks, we can now assume 214 00:08:58,956 --> 00:08:59,896 for the rest of the semester. 215 00:08:59,896 --> 00:09:00,926 Now what do I mean by that? 216 00:09:01,136 --> 00:09:02,096 Well, the first thing we're going 217 00:09:02,096 --> 00:09:04,936 to introduce today is called a debugger. 218 00:09:05,226 --> 00:09:07,896 So many of you have suffered bugs in your programs, 219 00:09:07,896 --> 00:09:09,266 and this is certainly to be expected. 220 00:09:09,526 --> 00:09:12,556 This is nothing that you ever move away from entirely, 221 00:09:12,556 --> 00:09:13,946 certainly code I've written, whether it's 222 00:09:13,946 --> 00:09:16,366 for the bulletin board or for certain Problem Sets, 223 00:09:16,666 --> 00:09:18,186 have been erroneous at times. 224 00:09:18,186 --> 00:09:20,456 And you learn to get better at this, but thankfully, 225 00:09:20,456 --> 00:09:23,786 the act of debugging, finding bugs that you've made 226 00:09:23,936 --> 00:09:28,116 and fixing them, does not have to devolve to just thinking 227 00:09:28,116 --> 00:09:30,566 through your code or using print def all over the place. 228 00:09:30,856 --> 00:09:33,956 There are some powerful tools help you help yourself. 229 00:09:34,256 --> 00:09:34,996 And the one we're going 230 00:09:34,996 --> 00:09:38,086 to introduce today is called GDB, the Gnu Debugger. 231 00:09:38,326 --> 00:09:43,436 This is sort of -- sort of the second nice counter part to GCC, 232 00:09:43,606 --> 00:09:44,986 the compiler that you've been using. 233 00:09:44,986 --> 00:09:46,116 And it operates as follows. 234 00:09:46,116 --> 00:09:49,656 I'm going to go ahead and open a program called bar dot, C, 235 00:09:49,656 --> 00:09:52,006 it's in today's print out, so you have a copy of this. 236 00:09:52,296 --> 00:09:54,566 This program really does nothing interesting. 237 00:09:54,566 --> 00:09:56,536 In fact, it does a lot of unnecessary work. 238 00:09:56,876 --> 00:10:01,136 So bar dot C, but I use this as an opportunity to walk 239 00:10:01,246 --> 00:10:03,876 through this program step by step, 240 00:10:04,026 --> 00:10:05,396 which is not something we can do just 241 00:10:05,396 --> 00:10:06,416 by running at the command line. 242 00:10:06,416 --> 00:10:08,456 I'm going to instead compile this program 243 00:10:08,456 --> 00:10:12,526 in a slightly special way, and then run it within the confines 244 00:10:12,526 --> 00:10:14,026 of this thing called a debugger, 245 00:10:14,026 --> 00:10:17,456 a program that let's you pause execution anywhere you want, 246 00:10:17,646 --> 00:10:20,376 a program that let's you look inside of variables, 247 00:10:20,436 --> 00:10:22,446 look inside of arrays, see what's there, 248 00:10:22,446 --> 00:10:24,286 so you can do a little sanity check for yourself, 249 00:10:24,286 --> 00:10:26,366 and they be you can let the program proceed. 250 00:10:26,586 --> 00:10:28,526 In short, with a debugger, you can walk 251 00:10:28,526 --> 00:10:32,166 through your own code step by step, or even jump around, 252 00:10:32,166 --> 00:10:34,826 and this is hugely invaluable, especially now 253 00:10:34,826 --> 00:10:36,836 that your problem sets are getting a little larger, 254 00:10:37,106 --> 00:10:42,026 because you can now diagnosis problems a lot more easily. 255 00:10:42,026 --> 00:10:43,896 So this is again, just a stupid program. 256 00:10:43,896 --> 00:10:44,876 Starts off in main. 257 00:10:45,116 --> 00:10:46,946 Calls a function calls foo, 258 00:10:46,946 --> 00:10:48,426 which calls a function called bar. 259 00:10:48,686 --> 00:10:50,316 Notice at the top here's I've gone ahead 260 00:10:50,316 --> 00:10:53,846 and provided a prototype, as it's called, of each, 261 00:10:53,846 --> 00:10:56,106 so that GCC knows to expect these functions. 262 00:10:56,356 --> 00:10:57,876 But now I'm going to go ahead and compile this 263 00:10:58,606 --> 00:10:59,756 in a slightly different way. 264 00:11:00,036 --> 00:11:03,416 Rather than run GCC of bar dot C, and actually I'm going 265 00:11:03,766 --> 00:11:07,816 to do dash O bar, I'm going to add an additional flag 266 00:11:07,816 --> 00:11:10,076 that you may have seen flash across the seen sometimes, 267 00:11:10,106 --> 00:11:12,826 given how we've automated some tasks on nice.fas. 268 00:11:12,826 --> 00:11:20,406 But I'm going to go ahead and add to this a dash G, G -- GDB. 269 00:11:20,406 --> 00:11:22,696 So it's a little oddly named, but we'll be able 270 00:11:22,696 --> 00:11:24,026 to automate this before long. 271 00:11:24,026 --> 00:11:28,176 And what this tells GCC to do is yes, compile this source code 272 00:11:28,176 --> 00:11:31,556 down to zeros and ones, called object code, but also include 273 00:11:31,556 --> 00:11:35,666 in A dot out or rather in the binary called bar, 274 00:11:35,936 --> 00:11:39,016 include some extra information that a normal human, 275 00:11:39,016 --> 00:11:41,176 normal user, really doesn't care about, 276 00:11:41,176 --> 00:11:42,766 in fact you're just wasting space 277 00:11:42,766 --> 00:11:45,006 by adding the special stuff to the binary. 278 00:11:45,366 --> 00:11:49,036 But include debugging symbols, include some hints 279 00:11:49,036 --> 00:11:51,616 from my own source code so that I, the programmer, 280 00:11:51,846 --> 00:11:54,976 can walk through this code and actually see what's going on. 281 00:11:55,196 --> 00:11:56,086 So what I'm now going to do, 282 00:11:56,086 --> 00:11:58,786 now that I have a program called bar, as usual here, 283 00:11:58,906 --> 00:12:02,446 looks the same, I'm going to run GDB of bar and then hit enter. 284 00:12:02,826 --> 00:12:05,166 So I get a bunch of copyright stuff, not all that interesting, 285 00:12:05,166 --> 00:12:06,646 and then I get a GDB prompt. 286 00:12:07,006 --> 00:12:10,936 Now the simplest thing I can do, and we'll refer you on line 287 00:12:11,526 --> 00:12:14,556 to a really nice cheat sheet for GDB, but there's a couple things 288 00:12:14,556 --> 00:12:16,176 that might be worth jotting down for yourself today, 289 00:12:16,176 --> 00:12:17,376 just so you don't forget, 290 00:12:17,606 --> 00:12:19,806 but run is perhaps the easiest command you can type 291 00:12:19,846 --> 00:12:21,696 at the GDB parenthetical prompt. 292 00:12:22,016 --> 00:12:22,906 Starting program. 293 00:12:23,476 --> 00:12:25,226 Incidentally, this is a longer path 294 00:12:25,556 --> 00:12:27,356 than you might be familiar with, but if you recall 295 00:12:27,356 --> 00:12:28,466 from earlier problem sets, 296 00:12:29,006 --> 00:12:31,966 nice.fas has some big hard drives with lots 297 00:12:31,966 --> 00:12:33,016 of people's data on it. 298 00:12:33,286 --> 00:12:35,926 This is the full path, the number of steps is takes 299 00:12:35,926 --> 00:12:38,206 to find your directory from the root of the hard drive. 300 00:12:38,436 --> 00:12:41,156 And this is just being ever more explicit as to where I am. 301 00:12:41,156 --> 00:12:43,196 So not that interesting, except that I am 302 00:12:43,196 --> 00:12:44,926 in fact running bar at the very end. 303 00:12:45,146 --> 00:12:47,216 And apparently this program just prints out something 304 00:12:47,216 --> 00:12:48,786 like world high on bar. 305 00:12:48,836 --> 00:12:51,666 So again, uninteresting, and it existed normally. 306 00:12:52,126 --> 00:12:54,716 But now let's see if we can step inside this thing. 307 00:12:54,716 --> 00:12:57,506 And incidentally, what do you think it means 308 00:12:57,506 --> 00:12:59,366 for a program to exit normally? 309 00:12:59,366 --> 00:13:01,696 How does GDB exited normally? 310 00:13:02,856 --> 00:13:03,996 Yeah, return zero. 311 00:13:03,996 --> 00:13:07,266 So finally, that detail we've been telling you is a good thing 312 00:13:07,266 --> 00:13:09,946 in many context to do, it's actually becoming useful, 313 00:13:09,946 --> 00:13:12,146 because now when we actually care about the right -- 314 00:13:12,336 --> 00:13:14,746 the correctness or the incorrectness of my code, 315 00:13:15,036 --> 00:13:16,996 getting back exit codes like that is helpful. 316 00:13:16,996 --> 00:13:18,076 So you know what I'm going to do, 317 00:13:18,076 --> 00:13:19,816 that happened way too fast, right? 318 00:13:19,816 --> 00:13:22,346 I'm not yet actually controlling this program. 319 00:13:22,546 --> 00:13:24,216 I'm going go ahead and incidentally , 320 00:13:24,216 --> 00:13:26,706 when I clear my screen it's usually control L, 321 00:13:26,706 --> 00:13:27,736 another little LINUX trick. 322 00:13:28,196 --> 00:13:29,656 So control L cleared my screen. 323 00:13:29,926 --> 00:13:31,046 This time I'm going to say this. 324 00:13:31,046 --> 00:13:33,536 Break in the function called main. 325 00:13:33,856 --> 00:13:34,786 So I'm going to hit enter, 326 00:13:34,786 --> 00:13:36,826 and now I get a slightly esoteric comment back, 327 00:13:36,946 --> 00:13:42,116 break 0.1 at O X, 84, 8505, file bar dot C line 21. 328 00:13:42,116 --> 00:13:43,746 All right, so some of that's confusing. 329 00:13:43,926 --> 00:13:45,056 But this part's pretty clear. 330 00:13:45,106 --> 00:13:46,726 I just said what's called a break point 331 00:13:46,896 --> 00:13:49,456 in the file called bar dot C at line 21. 332 00:13:49,746 --> 00:13:52,156 And as the words, own name implies, 333 00:13:52,386 --> 00:13:56,306 a break point is a moment in time or a line of your code 334 00:13:56,306 --> 00:14:00,506 that the GDB debugger is going to stop executing for a moment 335 00:14:00,776 --> 00:14:02,416 so that you can start to poke around. 336 00:14:02,416 --> 00:14:04,766 And only once you say okay, I'm done poking around, 337 00:14:04,986 --> 00:14:07,186 will GDB continue executing your program. 338 00:14:07,426 --> 00:14:10,826 So now when I type run and hit enter, I get this. 339 00:14:11,086 --> 00:14:14,276 Break point 1 main at bar C colon 21. 340 00:14:14,276 --> 00:14:16,956 So again, a little arcane, but just useful information. 341 00:14:16,956 --> 00:14:19,056 I now know where I am in my program. 342 00:14:19,316 --> 00:14:22,086 So this indicates my line number, this indicates what's 343 00:14:22,186 --> 00:14:25,396 on that line number, and if I do a little sanity check, 344 00:14:25,496 --> 00:14:28,546 you can type list to see the lines of code near 345 00:14:28,546 --> 00:14:29,886 by where you just broke. 346 00:14:30,196 --> 00:14:34,056 Ah, okay, so line 16 was the return value for main, 347 00:14:34,056 --> 00:14:36,236 line 17 is main's prototype here, 348 00:14:36,496 --> 00:14:38,946 line 18 is this curly brace, 349 00:14:38,946 --> 00:14:40,646 I seem to have used tabs accidentally 350 00:14:40,646 --> 00:14:41,566 in my version of this. 351 00:14:41,566 --> 00:14:43,136 Your printed version should be fine. 352 00:14:43,406 --> 00:14:44,576 So ignore this white space -- 353 00:14:44,876 --> 00:14:52,496 actually fix this so there's no unnecessary confusion. 354 00:14:52,496 --> 00:14:52,563 [ Background noise ] 355 00:14:52,563 --> 00:14:57,246 >> Okay, oops, GDB, oops, GCC, GDB, break, main, run. 356 00:14:57,646 --> 00:14:59,846 Okay, back where we are. 357 00:15:00,146 --> 00:15:02,426 can you compile your code that fast? 358 00:15:02,746 --> 00:15:04,076 Okay, so now I type list. 359 00:15:05,146 --> 00:15:06,086 Now my code is prettier. 360 00:15:06,266 --> 00:15:08,206 Okay, so now there's no stupid distractions. 361 00:15:08,446 --> 00:15:12,696 Okay, so we're on line 21, now why did the program break 362 00:15:12,696 --> 00:15:17,566 on apparently line 21 instead of say, 19 or 16, which really seem 363 00:15:17,566 --> 00:15:18,606 to be the first lines. 364 00:15:19,016 --> 00:15:20,386 What is it actually breaking on. 365 00:15:21,436 --> 00:15:24,476 You can think back to some scratch terminology. 366 00:15:24,476 --> 00:15:26,416 What construct is it actually breaking on. 367 00:15:27,256 --> 00:15:28,246 When I say break main. 368 00:15:30,776 --> 00:15:32,126 Well, what's on 21? 369 00:15:32,306 --> 00:15:36,206 So it's like the first statement, right? 370 00:15:36,206 --> 00:15:38,886 It's an assignment statement, I've got a left-hand side thing, 371 00:15:38,886 --> 00:15:42,526 char star S equals hello world, whereas the stuff up top, 372 00:15:42,526 --> 00:15:44,576 these are just variables, declarations, 373 00:15:44,576 --> 00:15:45,946 or arrays declarations. 374 00:15:45,946 --> 00:15:48,386 So you really don't see anything happen 375 00:15:48,386 --> 00:15:49,376 when you declare a variable. 376 00:15:49,376 --> 00:15:52,406 But you certainly will see some stuff happening, 377 00:15:52,406 --> 00:15:54,126 usually when a statement is executed. 378 00:15:54,126 --> 00:15:57,916 So typing break main simply broke execution at line 21. 379 00:15:57,916 --> 00:15:58,746 So what does this mean? 380 00:15:58,996 --> 00:16:01,076 Well, nothing has yet happened in the world. 381 00:16:01,076 --> 00:16:03,516 In fact, what I can now do is type in print, 382 00:16:03,956 --> 00:16:05,836 and as the word implies, it's going to print something. 383 00:16:05,836 --> 00:16:06,576 What do I want to print? 384 00:16:06,806 --> 00:16:09,106 You know what , let me go ahead and print the value 385 00:16:09,136 --> 00:16:12,906 of A. I'm just curious, what is inside of A. Okay, that's weird. 386 00:16:13,786 --> 00:16:18,386 What is with this complete nonsense inside of A. Sorry? 387 00:16:19,031 --> 00:16:21,031 [ Inaudible audience comment ] 388 00:16:21,046 --> 00:16:21,716 >> Louder than murmurs. 389 00:16:21,746 --> 00:16:27,796 What is this weird value, 134514073? 390 00:16:28,516 --> 00:16:32,556 [ Inaudible audience comment ] 391 00:16:33,056 --> 00:16:33,606 >> Exactly. 392 00:16:36,636 --> 00:16:39,316 Good. So we did offer some caution a week or two ago 393 00:16:39,316 --> 00:16:42,246 when we said it's fine to declare variables, 394 00:16:42,416 --> 00:16:44,236 but you should never start using them 395 00:16:44,236 --> 00:16:46,486 until you yourself have assigned them a value. 396 00:16:46,486 --> 00:16:49,496 It might be nice if ideally variables all initialized 397 00:16:49,496 --> 00:16:53,066 to some value, like zero, which actually is the case sometimes, 398 00:16:53,066 --> 00:16:53,996 and in some languages. 399 00:16:54,236 --> 00:16:57,266 But clearly here there's just some garbage value inside the 400 00:16:57,266 --> 00:16:59,526 variable called A. And that's because again, 401 00:16:59,526 --> 00:17:01,716 the program has a whole bunch of RAM allocated to it, 402 00:17:01,956 --> 00:17:04,406 it can do anything it wants with that RAM, or you can, 403 00:17:04,646 --> 00:17:07,026 but it doesn't necessarily clean up that RAM, 404 00:17:07,026 --> 00:17:10,216 it doesn't initialize it all to zeros, and so yes, 405 00:17:10,216 --> 00:17:14,056 I have a 32-bit chunk of memory called A. It's designed 406 00:17:14,056 --> 00:17:17,826 to store an int, but I haven't actually initialized it 407 00:17:17,866 --> 00:17:18,396 to something. 408 00:17:18,396 --> 00:17:21,236 So what's inside of A right now are the bits 409 00:17:21,326 --> 00:17:24,166 that previously belonged to some other variable 410 00:17:24,166 --> 00:17:26,116 or some other entity in this program. 411 00:17:26,386 --> 00:17:27,316 Okay, so that's fine. 412 00:17:27,316 --> 00:17:28,396 That's not such a big deal. 413 00:17:28,686 --> 00:17:30,986 But I don't want to use A for any reason. 414 00:17:30,986 --> 00:17:34,626 And frankly -- just as an aside, the dollar sign 1 here, 415 00:17:34,626 --> 00:17:38,836 this is just a GDB thing so that you can actually reprint values 416 00:17:38,836 --> 00:17:41,236 from earlier, that's sort of like a temporary variable 417 00:17:41,236 --> 00:17:43,096 that for now just turn a blind eye to. 418 00:17:43,096 --> 00:17:44,046 But it can be useful. 419 00:17:44,276 --> 00:17:45,536 All right, what about B? 420 00:17:45,606 --> 00:17:46,636 Let me go ahead and print -- 421 00:17:47,066 --> 00:17:50,706 let me go ahead and print B. Okay, interesting. 422 00:17:50,876 --> 00:17:55,466 So B is an array of type int of size 5, and apparently, 423 00:17:55,466 --> 00:17:57,556 I have five bogus values in there. 424 00:17:57,556 --> 00:17:58,596 What do those numbers mean? 425 00:17:58,716 --> 00:17:59,896 Well, frankly, who knows. 426 00:17:59,936 --> 00:18:01,756 But I haven't initialized that array 427 00:18:01,756 --> 00:18:05,216 to any specific integers yet, so I just have some junk in there. 428 00:18:05,416 --> 00:18:08,416 So what's neat already about GDB is we're literally looking 429 00:18:08,416 --> 00:18:10,006 underneath the hood at what's going 430 00:18:10,006 --> 00:18:11,546 on inside the computer's memory. 431 00:18:11,716 --> 00:18:15,076 Unfortunately, nothing interesting just yet. 432 00:18:15,446 --> 00:18:16,266 What about S? 433 00:18:16,266 --> 00:18:19,606 Let me go ahead and print S. Okay, that's really weird. 434 00:18:20,556 --> 00:18:21,266 So what is that? 435 00:18:21,506 --> 00:18:22,806 So there's some kind of an address. 436 00:18:22,806 --> 00:18:25,546 Any time you see 0 X starting today, that's going to refer 437 00:18:25,546 --> 00:18:28,056 to some memory address, some location RAM. 438 00:18:28,346 --> 00:18:31,646 What all of letters mean we'll determine in a moment. 439 00:18:31,806 --> 00:18:32,946 And then in the quoted string, 440 00:18:32,946 --> 00:18:35,336 that is definitely not hello world, right? 441 00:18:35,336 --> 00:18:37,616 Sort of like the rot 13 hello world, 442 00:18:37,616 --> 00:18:38,996 but even then it's kind of garbage. 443 00:18:39,146 --> 00:18:41,866 But why is that, why is there junk inside of S 444 00:18:41,966 --> 00:18:43,856 at this moment in time at line 21. 445 00:18:45,726 --> 00:18:48,456 All right, so it hasn't actually executed yet. 446 00:18:48,456 --> 00:18:50,186 When I broke in at line 21, 447 00:18:50,246 --> 00:18:53,336 I broke in before line 21 is executed. 448 00:18:53,336 --> 00:18:55,446 So if I actually want to step over it, 449 00:18:55,446 --> 00:18:58,226 step over to the next line, the command in GDB is next. 450 00:18:58,846 --> 00:19:00,936 So now I've advanced to line 22, 451 00:19:01,126 --> 00:19:03,926 this means line 21 has hopefully executed. 452 00:19:04,076 --> 00:19:06,146 So if I type the very same thing again, print S, 453 00:19:07,536 --> 00:19:10,716 there is in fact my hello world string stored inside 454 00:19:10,716 --> 00:19:14,566 of the variable called S. And char star, that's synonymous 455 00:19:14,566 --> 00:19:17,366 with what little shorthand in CSV's library? 456 00:19:17,906 --> 00:19:18,516 Just a string. 457 00:19:18,736 --> 00:19:22,576 Okay, and we'll tease apart what that asterisk is exactly doing 458 00:19:22,576 --> 00:19:24,446 for us later today and Wednesday. 459 00:19:24,446 --> 00:19:25,466 All right, so what comes next. 460 00:19:25,776 --> 00:19:26,546 I do a print def. 461 00:19:26,656 --> 00:19:27,886 Well, what is this all about. 462 00:19:28,066 --> 00:19:30,886 Well print -- let's see, S bracket 7. 463 00:19:30,886 --> 00:19:32,496 This is something we'll spend some time on. 464 00:19:32,656 --> 00:19:33,846 But if I go ahead and hit next, 465 00:19:34,086 --> 00:19:36,276 let's see what gets printed next. 466 00:19:36,496 --> 00:19:37,526 Okay, no pun intended there. 467 00:19:37,576 --> 00:19:40,276 Line 22 is about to get executed when I time next. 468 00:19:40,356 --> 00:19:40,766 Here we go. 469 00:19:41,476 --> 00:19:44,076 Okay, so world printed out. 470 00:19:44,446 --> 00:19:45,346 Now why is that? 471 00:19:45,346 --> 00:19:46,196 Well, let's see. 472 00:19:46,336 --> 00:19:48,866 What I've just done is print, ampersand, S, 473 00:19:49,056 --> 00:19:51,016 bracket, 7, close brackets. 474 00:19:51,016 --> 00:19:52,106 So some new syntax. 475 00:19:52,346 --> 00:19:55,106 But just as a teaser so far, what is 7? 476 00:19:55,106 --> 00:19:55,896 Well, let's see. 477 00:19:55,896 --> 00:19:58,486 Here's S, from here, left to right, 478 00:19:58,826 --> 00:20:03,116 so this is 0, 1, 2, 3, 4, 5, 6, 7. 479 00:20:03,116 --> 00:20:06,696 Is looks like when you start counting from 0, 7 is the index 480 00:20:06,816 --> 00:20:09,036 of the W, and we'll see later today 481 00:20:09,036 --> 00:20:12,146 and Wednesday what its doing for us by adding this ampersand. 482 00:20:12,146 --> 00:20:14,156 Apparently, it's somehow tricking print def 483 00:20:14,336 --> 00:20:18,026 or compelling print def to print what string, exactly? 484 00:20:18,936 --> 00:20:22,016 So world, clearly, because right, even though there's a lot 485 00:20:22,016 --> 00:20:25,356 of int mingling here of GDB commands and output 486 00:20:25,416 --> 00:20:27,246 to the screen, it printed world. 487 00:20:27,246 --> 00:20:29,526 So somehow or other, this little trick 488 00:20:29,526 --> 00:20:33,696 of using ampersand S bracket S is going to the seventh location 489 00:20:33,746 --> 00:20:36,436 and then printing the sub string that starts there. 490 00:20:36,436 --> 00:20:38,346 So we'll see why that actually works. 491 00:20:38,346 --> 00:20:39,816 Okay, I'm getting a little confused where I am, 492 00:20:39,816 --> 00:20:41,036 so I'm going to type list again. 493 00:20:41,246 --> 00:20:42,516 Okay, there I am. 494 00:20:42,576 --> 00:20:44,706 Here's the nearby lines. 495 00:20:44,956 --> 00:20:46,696 I'm on line 23. 496 00:20:46,696 --> 00:20:49,656 So if I type print A, A is still gets valued. 497 00:20:49,656 --> 00:20:50,836 Let's go ahead and type next. 498 00:20:50,836 --> 00:20:55,066 And now print A. Okay, now A is initialized to 5. 499 00:20:55,066 --> 00:20:58,096 Okay, so just baby steps thus far, but you know I'm kind 500 00:20:58,096 --> 00:21:01,436 of curious as to what foo is going to do now. 501 00:21:01,436 --> 00:21:03,916 So line 24 is the next line to be executed. 502 00:21:04,086 --> 00:21:05,486 Here it is in my list of code. 503 00:21:05,736 --> 00:21:07,856 If I just type next, unfortunately, 504 00:21:08,506 --> 00:21:11,706 it steps over foo, it executes it, but then it goes 505 00:21:11,746 --> 00:21:13,116 to the next line after foo. 506 00:21:13,116 --> 00:21:15,416 And the next line after foo, of course, is line 25, 507 00:21:15,666 --> 00:21:16,976 where I'm returning zero. 508 00:21:17,216 --> 00:21:19,836 So if I hit next one more time, next one more time 509 00:21:19,836 --> 00:21:21,656 for the closed brace, viola. 510 00:21:21,816 --> 00:21:24,266 So apparently I'm actually in someone else's code. 511 00:21:24,266 --> 00:21:26,426 Oops. Now in someone else's code. 512 00:21:26,566 --> 00:21:28,986 Typing continue is just going to finish off the program. 513 00:21:28,986 --> 00:21:29,626 Just go to the end. 514 00:21:29,626 --> 00:21:30,976 I've lost interest in this problem. 515 00:21:31,256 --> 00:21:33,996 And it exits normally, because it in fact returns zero. 516 00:21:34,226 --> 00:21:35,686 Let's dive into foo again. 517 00:21:35,686 --> 00:21:37,496 So let me quickly pull up the code, 518 00:21:37,496 --> 00:21:39,616 since I know we're going back and forth a lot here. 519 00:21:39,876 --> 00:21:42,036 So this was main, we stepped all the way through main. 520 00:21:42,036 --> 00:21:45,516 But when I type next at this line here, it went over it, 521 00:21:45,516 --> 00:21:47,606 it did execute it, but I'm really curious 522 00:21:47,606 --> 00:21:50,106 to see what's going on inside of foo. 523 00:21:50,416 --> 00:21:51,176 So let me do this. 524 00:21:51,176 --> 00:21:54,246 I'm going to rerun GDB on the program called bar. 525 00:21:54,246 --> 00:21:55,246 I'm going to hit enter. 526 00:21:55,636 --> 00:21:58,546 And you know what, I'm going to again say break main. 527 00:21:58,656 --> 00:22:01,986 You know what, I'm tired of seeing line 21 execute. 528 00:22:01,986 --> 00:22:02,846 Instead, I'm going to do this. 529 00:22:02,986 --> 00:22:05,736 I'm going to hit delete to delete all my break points, 530 00:22:05,976 --> 00:22:07,376 another little trick, and I'm going 531 00:22:07,376 --> 00:22:10,916 to say break in bar dot C line 22. 532 00:22:10,916 --> 00:22:12,646 I'm really -- don't want to see line 21, 533 00:22:12,646 --> 00:22:13,886 I want to start at line 22. 534 00:22:14,076 --> 00:22:15,656 So you can exercise some precision. 535 00:22:15,656 --> 00:22:19,686 You can specify not a function's name, but a file's name, colon, 536 00:22:19,686 --> 00:22:21,296 line number to start right there. 537 00:22:21,546 --> 00:22:22,796 Okay, so now let me type run. 538 00:22:23,246 --> 00:22:24,776 So I'm breaking at line 22. 539 00:22:24,906 --> 00:22:27,446 Line 21 and prior have all executed. 540 00:22:27,446 --> 00:22:30,136 It's just I have not broken execution until this point. 541 00:22:30,136 --> 00:22:31,476 I'm going to go ahead and click next. 542 00:22:32,406 --> 00:22:34,716 Next, and now I'm going to type step. 543 00:22:35,396 --> 00:22:38,276 So next takes you over a line while still executing it, 544 00:22:38,386 --> 00:22:40,476 step steps you into the line, 545 00:22:40,476 --> 00:22:42,126 which means step into this function. 546 00:22:42,436 --> 00:22:45,026 So now notice I'm inside a function called foo, 547 00:22:45,026 --> 00:22:47,566 N is referring to what exactly? 548 00:22:49,036 --> 00:22:50,126 So that's its parameter. 549 00:22:50,126 --> 00:22:51,996 Let me pull up bar dot C. Ah, here we go. 550 00:22:52,176 --> 00:22:55,656 So here is the prototype or here is the declaration for foo, 551 00:22:55,816 --> 00:22:58,376 returns an int, okay, here it takes a parameter, 552 00:22:58,376 --> 00:23:01,946 N. So what I'm seeing in GDB is the parameterization 553 00:23:01,946 --> 00:23:02,616 of this function. 554 00:23:03,026 --> 00:23:04,176 So again, let me restart this. 555 00:23:04,176 --> 00:23:05,866 I'm going to go ahead and type run again, 556 00:23:05,866 --> 00:23:07,166 which will restart the whole thing. 557 00:23:08,086 --> 00:23:09,956 Enter. I'm at line 22. 558 00:23:10,046 --> 00:23:13,106 Next, next, and step. 559 00:23:13,106 --> 00:23:17,416 And now okay, so the very first line of foo per your print 560 00:23:17,416 --> 00:23:21,396 out says to declare a variable B, and then assign B to N, 561 00:23:21,396 --> 00:23:27,236 and then multiply B by 2 and then call bar and then return B. 562 00:23:27,306 --> 00:23:31,146 So you know what, if I type next that's going to execute line 33. 563 00:23:31,556 --> 00:23:34,206 And then line 34, well, let's do a quick sanity check. 564 00:23:34,206 --> 00:23:37,236 If I type print N what should I see? 565 00:23:38,526 --> 00:23:42,746 What was passed in as the value of N. Okay, it was 5, right? 566 00:23:42,746 --> 00:23:44,076 Because A was 5. 567 00:23:44,076 --> 00:23:45,676 We passed in A to foo. 568 00:23:45,676 --> 00:23:49,436 N takes on the name, is the name we give to the parameter. 569 00:23:49,436 --> 00:23:51,286 So it too says 5. 570 00:23:51,696 --> 00:23:53,276 And now if I print B at this point, 571 00:23:53,276 --> 00:23:56,186 another little sanity check. 572 00:23:56,436 --> 00:24:00,426 So B gets N and then B star equals 2 should give me 573 00:24:00,426 --> 00:24:00,826 what here? 574 00:24:00,826 --> 00:24:02,436 Yeah. So just 10. 575 00:24:02,626 --> 00:24:04,596 You know, I'm getting tired of these long commands. 576 00:24:04,996 --> 00:24:07,136 P, B, will also print. 577 00:24:07,186 --> 00:24:08,496 So there's a lot of little short cuts 578 00:24:08,496 --> 00:24:09,926 where if you just write the first letter, 579 00:24:09,926 --> 00:24:12,656 the first two letters, that's enough to tell GDB what to do. 580 00:24:12,906 --> 00:24:15,696 So finally, if I type step I'm now going to step into bar. 581 00:24:15,936 --> 00:24:18,846 Bar doesn't do all that much, so in fact as soon as I type next 582 00:24:18,846 --> 00:24:20,896 to go to line 42 it prints it. 583 00:24:21,086 --> 00:24:22,006 I'm now done with that. 584 00:24:22,006 --> 00:24:24,486 And now I'm losing interest, I found my problem, I'm just going 585 00:24:24,486 --> 00:24:26,706 to say continue and it finishes along its way. 586 00:24:26,926 --> 00:24:29,096 So this in and of itself was just meant as an exercise 587 00:24:29,096 --> 00:24:30,326 in stepping through code. 588 00:24:30,466 --> 00:24:34,076 We'll soon start using this as a technique to fix problems 589 00:24:34,076 --> 00:24:36,706 in our code or understand what's going on, and you -- 590 00:24:36,706 --> 00:24:38,736 this is going to be one of the hammers we have 591 00:24:38,826 --> 00:24:42,356 to hit all the time -- when you start attending office hours 592 00:24:42,356 --> 00:24:44,146 or tackling bugs in your own code, 593 00:24:44,146 --> 00:24:45,996 do not underestimate the value of GDB. 594 00:24:45,996 --> 00:24:49,456 Eventually, it will be Tuesday, Wednesday, maybe Thursday night, 595 00:24:49,746 --> 00:24:52,596 you just need to get past some bug and you're not going to want 596 00:24:52,816 --> 00:24:54,636 to sort of fuss with a tool like GDB, 597 00:24:54,636 --> 00:24:57,846 because it will cost you initially an extra 15 minutes, 598 00:24:57,846 --> 00:24:58,956 maybe an extra half an hour. 599 00:24:59,246 --> 00:25:02,226 It will save you hours by semester's end, no joke, 600 00:25:02,436 --> 00:25:03,666 leveraging tools like this. 601 00:25:03,666 --> 00:25:06,846 So don't dismiss it as something that was kind 602 00:25:06,916 --> 00:25:09,106 of interesting, but over my head. 603 00:25:09,106 --> 00:25:10,886 It's a quite, quite powerful thing. 604 00:25:11,326 --> 00:25:14,996 All right, so with that said, let's now introduce or talk 605 00:25:14,996 --> 00:25:16,856 about some of the things we've been taking 606 00:25:16,856 --> 00:25:18,166 for value -- for granted. 607 00:25:18,166 --> 00:25:19,926 So this was an example from a while ago, 608 00:25:20,046 --> 00:25:23,276 buggy 3 dot C. We've included it again in today's printouts, 609 00:25:23,476 --> 00:25:24,786 but it was wrong, right? 610 00:25:24,786 --> 00:25:26,226 So a couple weeks ago we tried 611 00:25:26,226 --> 00:25:27,986 to swap two values using a function 612 00:25:28,256 --> 00:25:29,816 and it just didn't work. 613 00:25:30,506 --> 00:25:34,826 So what was the fundamental problem with this code. 614 00:25:35,016 --> 00:25:37,206 Sorry? Scope. 615 00:25:37,206 --> 00:25:38,056 So there was this problem 616 00:25:38,056 --> 00:25:41,446 of scope whereby one main called swap passing 617 00:25:41,446 --> 00:25:44,256 in I think the variables were X and Y. So X 618 00:25:44,356 --> 00:25:48,606 and Y were passed in, but copies of X and Y were passed in. 619 00:25:48,806 --> 00:25:52,376 And so swap has A and B which are identical to X and Y, 620 00:25:52,376 --> 00:25:55,046 but they're copies, they're identical in the sense 621 00:25:55,076 --> 00:25:57,246 that they're copies to those four lines 622 00:25:57,246 --> 00:25:59,556 of code inside the curly braces actually work. 623 00:25:59,556 --> 00:26:03,556 Yeah, so they did work, right? 624 00:26:03,556 --> 00:26:06,776 That is a correct logical way of swapping two values, 625 00:26:06,806 --> 00:26:09,436 but unfortunately the moment we got to the end of this function, 626 00:26:09,596 --> 00:26:12,026 what did we do with the values A and B? 627 00:26:12,876 --> 00:26:14,206 So absolutely nothing. 628 00:26:14,206 --> 00:26:18,156 So this again was buggy 3 dot C. Here again was the code. 629 00:26:18,346 --> 00:26:22,916 And just to be clear if you think back to what memory looks 630 00:26:22,916 --> 00:26:24,356 like inside of a computer -- 631 00:26:24,356 --> 00:26:27,486 oops, what memory looks like inside of a computer, 632 00:26:27,676 --> 00:26:29,826 every time you call function, it gets a frame 633 00:26:29,826 --> 00:26:31,496 on the so-called stack, it gets a chunk 634 00:26:31,496 --> 00:26:33,626 of RAM devoted just to it. 635 00:26:33,936 --> 00:26:37,076 So inside of this chunk here, inside of main, 636 00:26:37,376 --> 00:26:41,566 there apparently are two variables called X and Y, 637 00:26:41,826 --> 00:26:43,666 so what's going on inside of memory here 638 00:26:43,666 --> 00:26:45,216 if I can borrow this board for a moment 639 00:26:45,216 --> 00:26:48,686 and I'll rotate it just a second, 640 00:26:48,776 --> 00:26:56,016 so inside of main are two 32-bit chunks of memory. 641 00:26:57,356 --> 00:26:59,656 All right, so let's see. 642 00:26:59,656 --> 00:27:02,726 If we draw this is our RAM, this sort of big rectangle 643 00:27:03,016 --> 00:27:04,966 down here is main's frame. 644 00:27:05,266 --> 00:27:07,496 So I'll label this as main. 645 00:27:07,886 --> 00:27:11,626 And carved out for main is say 32 bits here, 646 00:27:11,706 --> 00:27:15,986 called X. Another 32 bits here, called Y. And we've put inside 647 00:27:15,986 --> 00:27:17,146 of this RAM two values. 648 00:27:17,526 --> 00:27:19,436 The number 1 and the number 2. 649 00:27:19,816 --> 00:27:20,796 Okay? So this is main. 650 00:27:20,836 --> 00:27:23,616 But then main calls swap in this implementation. 651 00:27:23,906 --> 00:27:28,386 Swap itself takes two arguments, two parameters, called A and B 652 00:27:28,386 --> 00:27:31,286 and per our picture here, what you get first 653 00:27:31,396 --> 00:27:33,766 on the stack is a frame containing a function's 654 00:27:33,766 --> 00:27:35,326 parameters and then on top 655 00:27:35,326 --> 00:27:38,306 of that is another frame containing any local variables 656 00:27:38,366 --> 00:27:39,166 that it might have. 657 00:27:39,236 --> 00:27:41,016 So let's see what this translates to here. 658 00:27:41,436 --> 00:27:44,646 So now I've gone ahead and called foo's parameters, 659 00:27:45,306 --> 00:27:49,736 so we'll call this foos prams, albeit illegibly, 660 00:27:50,136 --> 00:27:56,006 inside of here, well I passed in or rather I defined A and B, 661 00:27:56,006 --> 00:27:57,736 which are another 32-bit values. 662 00:27:57,736 --> 00:27:58,836 And what's going inside of them? 663 00:27:59,096 --> 00:28:00,926 Copies one and two. 664 00:28:01,246 --> 00:28:01,916 Now what is this. 665 00:28:02,256 --> 00:28:03,346 Well, it's just kind of nice to be able 666 00:28:03,346 --> 00:28:04,316 to draw a whole rectangle. 667 00:28:04,316 --> 00:28:06,066 But this is unused space for the moment. 668 00:28:06,126 --> 00:28:08,466 So you can think of this as either being there 669 00:28:08,556 --> 00:28:10,836 or not being there, it's just being unused right now. 670 00:28:10,836 --> 00:28:12,336 All right, so what happens next. 671 00:28:12,336 --> 00:28:15,066 In the swap function per this, int temp -- 672 00:28:15,206 --> 00:28:16,616 where does int temp go. 673 00:28:19,036 --> 00:28:21,246 Yes, so it goes on its own frame, right? 674 00:28:21,246 --> 00:28:24,996 So above a function's parameters goes a memory being used 675 00:28:24,996 --> 00:28:26,296 for the function itself. 676 00:28:26,786 --> 00:28:28,846 So this is foo's own frame, 677 00:28:29,096 --> 00:28:32,216 and so foo now has a 32-bit value called temp, 678 00:28:32,596 --> 00:28:35,226 and initially it's got some garbage value 679 00:28:35,226 --> 00:28:37,356 like 4, 5, 6, 7, right? 680 00:28:37,556 --> 00:28:38,256 Just because. 681 00:28:38,256 --> 00:28:39,686 We saw garbage values with GDB. 682 00:28:39,686 --> 00:28:44,346 Who knows what's in here at the moment in time when this line 683 00:28:44,346 --> 00:28:46,156 of code here is executed. 684 00:28:46,236 --> 00:28:49,406 All that's done is that 32 bits are set aside for temp. 685 00:28:49,796 --> 00:28:53,376 But as soon as I do temp equals A, what happens is 686 00:28:53,376 --> 00:28:56,096 that garbage value gets overwritten 687 00:28:56,096 --> 00:28:59,546 with something useful, so now we have that state of the world, 688 00:28:59,546 --> 00:29:03,216 the next line of code that gets executed here is this one. 689 00:29:03,756 --> 00:29:07,366 So we have A as being assigned the value 690 00:29:07,366 --> 00:29:08,686 of B. So what happens here. 691 00:29:08,736 --> 00:29:10,266 Which of these five boxes changes? 692 00:29:11,726 --> 00:29:14,566 So just A. Right, so this one gets clobbered 693 00:29:14,566 --> 00:29:15,596 and becomes ace 2. 694 00:29:15,596 --> 00:29:17,266 So that is now the state of our world. 695 00:29:17,266 --> 00:29:22,096 And then finally B gets temp, so that means I'm going 696 00:29:22,096 --> 00:29:26,326 to copy temp down to B, so now I have this state of the world. 697 00:29:26,526 --> 00:29:28,956 So in fact, this code is really, really correct. 698 00:29:29,356 --> 00:29:31,406 It has perfectly swapped these two values. 699 00:29:31,626 --> 00:29:34,646 It did cost us something, cost us 32 bits in the form of temp. 700 00:29:35,026 --> 00:29:37,076 But the moment we hit this curly brace 701 00:29:37,356 --> 00:29:42,896 on the overhead, what happens? 702 00:29:42,896 --> 00:29:45,496 Yeah, so this goes away. 703 00:29:45,496 --> 00:29:47,626 And now technically I could erase this. 704 00:29:47,926 --> 00:29:50,376 But we -- we'll discuss this in the context of forensics. 705 00:29:50,376 --> 00:29:52,706 Technically, this 1 does not go away. 706 00:29:52,756 --> 00:29:54,626 We just forget that it's called temp. 707 00:29:55,096 --> 00:29:56,986 So where do these garbage values come from? 708 00:29:57,196 --> 00:29:59,246 Well hence forth, whenever we call a function, 709 00:29:59,496 --> 00:30:01,546 whoever gets allocated this 32 bits is going 710 00:30:01,546 --> 00:30:03,596 to have a garbage value of 1, 711 00:30:03,856 --> 00:30:05,026 because it's just been left there. 712 00:30:05,026 --> 00:30:08,226 But conceptually, this frame is thrown away entirely. 713 00:30:08,476 --> 00:30:10,676 And so now the state of my world is this. 714 00:30:10,816 --> 00:30:12,816 But then oh, the function is now returning, 715 00:30:13,126 --> 00:30:14,486 so this now goes away. 716 00:30:14,756 --> 00:30:17,526 And unfortunately, all of that very correct, quote unquote, 717 00:30:17,526 --> 00:30:19,086 code was completely for naught, 718 00:30:19,356 --> 00:30:21,196 because we did nothing with those values. 719 00:30:21,446 --> 00:30:23,676 And the mode -- the reason for it, ultimately, 720 00:30:23,976 --> 00:30:26,296 was that variables when passed from one function 721 00:30:26,296 --> 00:30:28,766 to another are often, or at least by default, 722 00:30:28,766 --> 00:30:32,156 passed in by value as copies. 723 00:30:32,616 --> 00:30:34,566 So let's do a quick sanity check. 724 00:30:34,566 --> 00:30:38,026 So that was called buggy C. So I'm going to make buggy 3. 725 00:30:38,676 --> 00:30:41,236 And now notice it's an aside, all this time 726 00:30:41,236 --> 00:30:43,806 when you type make, you do get this really long line, 727 00:30:43,806 --> 00:30:45,866 but we sort of anticipated this. 728 00:30:45,866 --> 00:30:47,596 So notice any time you run make, 729 00:30:47,966 --> 00:30:51,376 automatically does dash GDB get inserted for you, 730 00:30:51,726 --> 00:30:56,086 just in case you actually want to poke around your own code. 731 00:30:56,086 --> 00:30:59,886 Now as an aside, it's not a good thing to ship or sell software 732 00:30:59,886 --> 00:31:01,626 that has debugging symbols enabled. 733 00:31:01,936 --> 00:31:05,146 Usually something like this can be used by adversaries, 734 00:31:05,146 --> 00:31:08,036 by hackers, by bad guys who actually, you know, 735 00:31:08,086 --> 00:31:10,726 crack your software, disable serial numbers, 736 00:31:10,726 --> 00:31:13,106 because it's more information than a user needs, 737 00:31:13,326 --> 00:31:15,406 but for you the developer, it's actually very useful. 738 00:31:15,406 --> 00:31:19,326 So let's go ahead and now run GDB on buggy 3. 739 00:31:19,546 --> 00:31:21,316 Okay, a lot of copyright stuff. 740 00:31:21,316 --> 00:31:22,326 Let me go ahead and type run. 741 00:31:23,216 --> 00:31:24,816 Oh, right, doesn't work. 742 00:31:25,046 --> 00:31:25,946 So I want to poke around. 743 00:31:25,946 --> 00:31:30,096 So let's do -- what should I type, how do I poke around? 744 00:31:30,286 --> 00:31:32,906 [Inaudible] sure, short program, won't be hard to go through it. 745 00:31:32,906 --> 00:31:33,926 So now I type run. 746 00:31:34,386 --> 00:31:35,936 All right, so I'm in main, okay. 747 00:31:36,406 --> 00:31:38,826 I'm tired of typing next, I'm just going hit N hence forth. 748 00:31:38,876 --> 00:31:43,246 So N, N, N, N, N, the same program, 749 00:31:43,356 --> 00:31:44,486 here's where it's interesting. 750 00:31:44,726 --> 00:31:45,796 So quick sanity check. 751 00:31:45,976 --> 00:31:49,366 So I'm going to display X, I'm going to display Y. 752 00:31:49,596 --> 00:31:52,196 So whereas print displays value once, 753 00:31:52,276 --> 00:31:54,656 display should keep showing it for us. 754 00:31:54,696 --> 00:31:59,716 So for now if I do step into swap, I'm going to be re -- 755 00:31:59,716 --> 00:32:01,016 oops, not in that case. 756 00:32:01,136 --> 00:32:02,696 Ignore what I said about display for a moment. 757 00:32:02,696 --> 00:32:06,216 Now inside of swap, what was passed in is a copy of X 758 00:32:06,216 --> 00:32:09,476 and a copy of Y, currently called A and B. So if I print A 759 00:32:09,476 --> 00:32:13,646 and I print B, sanity Czechs out, if I print temp 760 00:32:13,646 --> 00:32:17,546 at this point, what should I see? 761 00:32:17,616 --> 00:32:19,276 Zero. Why zero? 762 00:32:19,896 --> 00:32:22,946 Just yeah, just kind of because. 763 00:32:22,946 --> 00:32:26,096 It's a garbage value, there is sometimes some initialization 764 00:32:26,336 --> 00:32:28,556 happens, sometimes you do get zero values, 765 00:32:28,556 --> 00:32:29,696 but you should never assume it. 766 00:32:29,896 --> 00:32:33,776 But if I do type next and now print out temp, ah ha, 767 00:32:33,776 --> 00:32:37,016 there's the value 1, which I explicitly put there inside 768 00:32:37,016 --> 00:32:38,046 of my swap function. 769 00:32:38,256 --> 00:32:40,236 So let me go to the very bottom of this function. 770 00:32:40,296 --> 00:32:43,156 A gets B, B gets temp, there's my curly brace. 771 00:32:43,156 --> 00:32:43,896 So let me check. 772 00:32:43,896 --> 00:32:46,976 Print A should hopefully say 2, yup. 773 00:32:47,256 --> 00:32:49,876 And print B should say 1. 774 00:32:50,236 --> 00:32:54,416 It did in fact work, but then as soon as I continue to the end 775 00:32:54,416 --> 00:32:56,916 of my program, X and Y are obviously unchanged 776 00:32:57,096 --> 00:32:58,886 because of the pictorial that we had there. 777 00:32:59,126 --> 00:33:01,176 All right, so GDB didn't help me solve a problem here, 778 00:33:01,396 --> 00:33:04,526 but it did help me see what's going on underneath the hood. 779 00:33:04,556 --> 00:33:07,546 Now when I ran -- let's tees one thing apart -- 780 00:33:07,546 --> 00:33:11,466 when I ran GDB on bar a moment ago and set a break point 781 00:33:11,466 --> 00:33:13,826 in main I got this cryptic thing. 782 00:33:14,136 --> 00:33:15,136 So I said this was an address. 783 00:33:15,426 --> 00:33:19,866 What does that mean exactly? 784 00:33:20,026 --> 00:33:21,926 Like, what is -- an address of what, where? 785 00:33:23,486 --> 00:33:25,046 What context? 786 00:33:25,776 --> 00:33:28,326 Anyone? So murmuring doesn't seem to help today, 787 00:33:28,326 --> 00:33:29,236 so we'll do this approach. 788 00:33:29,336 --> 00:33:32,946 I'll just stand here awkwardly. 789 00:33:34,626 --> 00:33:35,186 Anyone? Yes? 790 00:33:35,736 --> 00:33:38,926 Yeah, so it's a location in memory. 791 00:33:38,926 --> 00:33:40,096 What kind of memory? 792 00:33:40,096 --> 00:33:41,386 Not hard disc, but RAM. 793 00:33:41,596 --> 00:33:44,826 So again if we model our RAM, model our world of memory 794 00:33:44,826 --> 00:33:46,436 as this rectangle, right, 795 00:33:46,436 --> 00:33:49,386 thus far we've just been drawing nice little boxes that look kind 796 00:33:49,386 --> 00:33:52,176 of like squares and we assume that a square is 33 bits. 797 00:33:52,256 --> 00:33:54,436 But you need to be able to address memory somehow. 798 00:33:54,436 --> 00:33:57,086 So in fact what really a computer does is yes, 799 00:33:57,086 --> 00:33:59,576 it takes your RAM, maybe it thinks of it as kind 800 00:33:59,576 --> 00:34:00,956 of this conceptual rectangle, 801 00:34:00,956 --> 00:34:03,326 but advertisement got a number every location 802 00:34:03,326 --> 00:34:04,366 in this rectangle. 803 00:34:04,626 --> 00:34:07,256 So this chunk of memory here, even though I've labelled it X 804 00:34:07,256 --> 00:34:10,536 and I've labelled it Y, those actually have numeric addresses. 805 00:34:10,736 --> 00:34:17,156 So technically, this box here is numbered 0, X, 1, 2, 3. 806 00:34:17,296 --> 00:34:18,776 And then this box here, 807 00:34:18,816 --> 00:34:20,426 watch and let me pick an easier number. 808 00:34:20,736 --> 00:34:22,656 So let's suppose this is 0 X 1. 809 00:34:22,706 --> 00:34:24,026 That just happens to be the address. 810 00:34:24,186 --> 00:34:27,646 The byte -- so if you've got 2 gigabytes of RAM, 811 00:34:27,866 --> 00:34:29,856 you've got 2 billion bytes of RAM. 812 00:34:30,126 --> 00:34:32,326 This happens to be byte 12. 813 00:34:32,516 --> 00:34:34,186 Albeit something called hex decimal. 814 00:34:34,456 --> 00:34:36,706 So what's the address of Y going to be? 815 00:34:37,926 --> 00:34:41,936 O X 1, just take a guess. 816 00:34:42,136 --> 00:34:45,246 So not 3, because how many bytes away is this guy. 817 00:34:45,886 --> 00:34:48,126 It's an inter. 818 00:34:48,296 --> 00:34:51,576 So an ints 32 bits, 32 bits is 4 bytes. 819 00:34:51,896 --> 00:34:56,836 So that means if this is O X 12 this is going to be O X 16. 820 00:34:56,836 --> 00:34:57,096 All right? 821 00:34:57,096 --> 00:34:59,706 So all that minuta from Week Zero when we talked a little bit 822 00:34:59,706 --> 00:35:01,496 about binary and bit, it's actually useful 823 00:35:01,496 --> 00:35:04,836 because now it applies to the addressing of memory. 824 00:35:05,156 --> 00:35:07,976 Now as an aside, and I think we said this once before, 825 00:35:07,976 --> 00:35:09,196 there are many operating systems, 826 00:35:09,196 --> 00:35:12,206 some of which we're still using, that can only use, 827 00:35:12,346 --> 00:35:14,116 say, 2 gigabytes of RAM. 828 00:35:14,906 --> 00:35:18,546 Why might that be? 829 00:35:18,786 --> 00:35:20,326 Why 2 gigabytes of RAM? 830 00:35:20,416 --> 00:35:23,456 I think XP is limited to this, maybe 3 gigabytes of RAM. 831 00:35:23,596 --> 00:35:23,726 Yeah? 832 00:35:24,421 --> 00:35:26,421 [ Inaudible audience comment ] 833 00:35:26,826 --> 00:35:29,396 >> So there's a limit to how long those statements are. 834 00:35:29,426 --> 00:35:30,976 Yeah, so but put another way, 835 00:35:31,266 --> 00:35:35,466 when we say a computer is a 32-bit computer or a 32-bit CPU, 836 00:35:35,706 --> 00:35:39,186 as we've said, that just means that inside of the CPU are -- 837 00:35:39,186 --> 00:35:40,696 is memory, called registers. 838 00:35:41,076 --> 00:35:43,366 32-bits are used to represent numbers. 839 00:35:43,606 --> 00:35:45,416 Well the biggest number we can represent 840 00:35:45,416 --> 00:35:48,046 with 32 bits is 4 billion. 841 00:35:48,046 --> 00:35:49,096 But if we use positive 842 00:35:49,096 --> 00:35:51,546 and negative values the biggest number we can represent is 843 00:35:51,676 --> 00:35:52,546 2 billion. 844 00:35:52,816 --> 00:35:54,906 And so why can some computers, 845 00:35:54,906 --> 00:35:57,366 some operating systems have a maximum amount 846 00:35:57,366 --> 00:35:59,106 of ram at 2 gigabytes? 847 00:35:59,486 --> 00:36:01,196 Well, that's 2 billion bytes. 848 00:36:01,196 --> 00:36:03,936 Well, if the programmers of that operating system 849 00:36:04,136 --> 00:36:07,496 or the designers of that CPU only use 32-bit values 850 00:36:07,786 --> 00:36:12,956 to implement numbers, how can you address the 2 billion 851 00:36:13,046 --> 00:36:16,516 and 1 bytes up here if you literally cannot count 852 00:36:16,516 --> 00:36:18,686 that high using just 32-bits. 853 00:36:19,206 --> 00:36:22,216 Now thankfully the world has moved to 64-bit computers, 854 00:36:22,216 --> 00:36:25,426 64-bit CPUs, which means you can have a ridiculous amount 855 00:36:25,426 --> 00:36:25,906 of memory. 856 00:36:26,146 --> 00:36:27,056 So this was just kind 857 00:36:27,056 --> 00:36:29,066 of for historical reasons short-sightedness 858 00:36:29,316 --> 00:36:30,866 that we have some of these constraints. 859 00:36:31,266 --> 00:36:32,376 But that's what it boils down to. 860 00:36:32,376 --> 00:36:36,426 You can't use 3 gigabytes or 4 gigabytes or 5 giga bits of RAM 861 00:36:36,426 --> 00:36:38,796 in some computers, even though it's really useful for things 862 00:36:38,796 --> 00:36:39,946 like Photoshop, these days, 863 00:36:40,236 --> 00:36:42,026 because your ints are not big enough. 864 00:36:42,276 --> 00:36:44,046 They once were, but no longer. 865 00:36:44,346 --> 00:36:48,186 All right, so what -- how do we then start counting 866 00:36:48,186 --> 00:36:49,146 in this new scheme? 867 00:36:49,346 --> 00:36:51,386 All right, well we know binary, 868 00:36:51,386 --> 00:36:53,716 zeros and ones, and we know decimal. 869 00:36:54,006 --> 00:36:56,756 Let's see how we can get from zeros and ones and zeros 870 00:36:56,756 --> 00:37:00,016 through nines to O X and these other letters here. 871 00:37:00,016 --> 00:37:03,736 So in binary, what's the number for zero using 4 bits? 872 00:37:04,846 --> 00:37:07,746 Good, all right, how about 1. 873 00:37:08,896 --> 00:37:12,276 Okay, and then oops -- that, an then 1 -- 874 00:37:13,266 --> 00:37:17,096 oops, 1, 1, and this is -- I'll put some little reminders here. 875 00:37:17,096 --> 00:37:18,516 If this has been a while. 876 00:37:18,516 --> 00:37:21,506 Okay, so now 0100 is 4. 877 00:37:21,836 --> 00:37:30,506 0101 is 5, 0110 is 6, 0111 is 7, let's see, 878 00:37:30,726 --> 00:37:34,296 haven't embarrassed myself yet, 1001 is 9, 879 00:37:34,296 --> 00:37:35,346 okay, fun part coming up. 880 00:37:35,616 --> 00:37:42,956 1010 is 10, but if I'm using the decimal system, 881 00:37:42,956 --> 00:37:44,586 the only digits I have 882 00:37:44,666 --> 00:37:48,166 for numbers representations are zero through nine. 883 00:37:48,486 --> 00:37:51,886 So yes, I can compose 10 by using a 1 and a 0, 884 00:37:52,246 --> 00:37:55,006 but if your notion of a digit is a single number, 885 00:37:55,326 --> 00:37:58,326 so zero through nine, we have no way 886 00:37:58,326 --> 00:38:02,586 of expressing the number 10 using individual binary -- 887 00:38:02,586 --> 00:38:03,416 decimal digits. 888 00:38:03,886 --> 00:38:05,756 But fortunately, there are other base systems. 889 00:38:05,756 --> 00:38:07,696 We talked about binary, we talked about decimal, 890 00:38:07,936 --> 00:38:09,726 there's also something called hexadecimal. 891 00:38:09,936 --> 00:38:13,456 Whereas in binary you have two values, 0 and 1, decimal, deck, 892 00:38:13,626 --> 00:38:15,366 you have 10 values, 0 through 9. 893 00:38:15,596 --> 00:38:19,086 Hexadecimal, you have 16, 0 through 9 894 00:38:19,126 --> 00:38:22,246 and then A through F. Right? 895 00:38:22,246 --> 00:38:24,216 So the world needed to count a little higher 896 00:38:24,216 --> 00:38:26,506 than decimal allowed using individual digits. 897 00:38:26,736 --> 00:38:31,356 So now 1011 would normally be 11, but I can't do that, 898 00:38:31,356 --> 00:38:33,066 because again, 11 is not a digit, 899 00:38:33,066 --> 00:38:34,586 it's the composition of two digits. 900 00:38:34,866 --> 00:38:37,996 The single digit I'm looking for in hexadecimal would be B, 901 00:38:38,256 --> 00:38:46,356 and then finally 100 is C, 1101 is D, 1110 is E, 902 00:38:46,356 --> 00:38:49,726 an then thankfully, no mistakes, is F. And the contact frankly 903 00:38:49,726 --> 00:38:51,776 that some you have might have actually seen hexadecimal before 904 00:38:51,776 --> 00:38:53,706 is kind of a silly context, making web pages, 905 00:38:53,896 --> 00:38:55,786 where color codes are often represents 906 00:38:55,786 --> 00:38:57,196 with hexadecimal these days. 907 00:38:57,436 --> 00:38:59,586 So any time we need to count a little higher 908 00:38:59,806 --> 00:39:02,376 than decimal allows, and certainly higher than binary, 909 00:39:02,376 --> 00:39:04,766 I mean, my God, this would be a nightmare if GDB told us 910 00:39:04,766 --> 00:39:06,016 where things were in binary. 911 00:39:06,016 --> 00:39:07,456 It's not very human-friendly. 912 00:39:07,676 --> 00:39:10,126 We can now at least count up, here in Week Four, 913 00:39:10,286 --> 00:39:12,996 to the number 16 using this new base system. 914 00:39:12,996 --> 00:39:15,106 But this is useful, because many, many, 915 00:39:15,106 --> 00:39:18,756 many programs actually use hexadecimal 916 00:39:19,006 --> 00:39:20,376 to remit values here. 917 00:39:20,576 --> 00:39:23,066 Now it's not going to be that useful to you generally to know 918 00:39:23,196 --> 00:39:25,446 where in your computer's RAM, your function, 919 00:39:25,506 --> 00:39:26,836 or your variables ended up. 920 00:39:27,236 --> 00:39:30,506 But sometimes it's useful to care about maybe the last couple 921 00:39:30,506 --> 00:39:33,646 of digits, because then you kind of know where they are relative 922 00:39:33,646 --> 00:39:35,926 to each other in what's otherwise a really big 923 00:39:35,926 --> 00:39:36,676 address space. 924 00:39:36,676 --> 00:39:38,716 And when we get you our forensics problems set 925 00:39:38,766 --> 00:39:41,866 in a couple weeks time and you actually have to recover JPGs 926 00:39:41,866 --> 00:39:44,446 from disc, what you're going to be seeing when you look 927 00:39:44,446 --> 00:39:47,866 at the files on disc are actually not numbers like 0, 928 00:39:47,866 --> 00:39:50,646 1 through 9, but rather you're going to see hex decimal, 929 00:39:50,886 --> 00:39:52,086 partly just by convention. 930 00:39:52,386 --> 00:39:53,636 Because what is one upside 931 00:39:53,636 --> 00:39:57,696 of using hexadecimal instead of let's say decimal? 932 00:39:57,796 --> 00:40:00,576 What's useful about it, even on first glance, like, 933 00:40:00,576 --> 00:40:03,166 what is the value of defining A through F in this way. 934 00:40:04,766 --> 00:40:05,426 It's shorter. 935 00:40:05,426 --> 00:40:05,986 That's it. 936 00:40:05,986 --> 00:40:10,106 Right? You can express more values using just 937 00:40:10,176 --> 00:40:11,186 individual digits. 938 00:40:11,186 --> 00:40:12,616 So there's an efficiency aspect. 939 00:40:12,616 --> 00:40:15,346 And consider, too, the whole reason we use decimals 940 00:40:15,346 --> 00:40:17,636 and as humans instead of binary is my God, 941 00:40:17,636 --> 00:40:21,396 just to represent the number 15, look how many digits -- 942 00:40:21,396 --> 00:40:22,966 well, maybe that's not compelling, 943 00:40:22,966 --> 00:40:25,826 you have to use four digits, we can use two 944 00:40:25,826 --> 00:40:27,366 to represent the number 15. 945 00:40:27,726 --> 00:40:29,366 But if you think a little further out, 946 00:40:29,366 --> 00:40:32,736 this actually does have ripple effects with much larger values, 947 00:40:32,776 --> 00:40:34,036 though that might not have been compelling. 948 00:40:34,036 --> 00:40:36,196 Okay, so that was a lot all at once. 949 00:40:36,196 --> 00:40:38,366 Why don't we go ahead and take our five minute break here. 950 00:40:40,016 --> 00:40:40,936 [ Background noise ] 951 00:40:40,936 --> 00:40:42,266 >> All right, we're back. 952 00:40:42,486 --> 00:40:45,946 So it occurs to me that I might have induced some fear 953 00:40:45,946 --> 00:40:48,496 by saying you shouldn't be getting many ones and twos. 954 00:40:48,496 --> 00:40:53,076 So on the first C Problem Set, you should have gotten some ones 955 00:40:53,076 --> 00:40:55,146 and twos, because design and style 956 00:40:55,146 --> 00:40:56,156 as your TFs may have told you, 957 00:40:56,326 --> 00:40:58,096 were only out of two possible points. 958 00:40:58,166 --> 00:41:00,726 So you probably did get a one or a two. 959 00:41:00,896 --> 00:41:02,206 And the motivation -- normally, 960 00:41:02,206 --> 00:41:03,636 everything will be out of five points. 961 00:41:03,636 --> 00:41:04,986 So that little chart I drew on the back 962 00:41:04,986 --> 00:41:06,336 of the board is applicable. 963 00:41:06,336 --> 00:41:08,296 But in the beginning of the semester with P set 1 964 00:41:08,516 --> 00:41:10,366 when we've barely had time to talk 965 00:41:10,366 --> 00:41:12,256 about what design is, what style is. 966 00:41:12,506 --> 00:41:14,386 We certainly don't want to put you at a disadvantage 967 00:41:14,466 --> 00:41:16,706 by expecting more than we possibly could. 968 00:41:16,766 --> 00:41:18,176 So ones and twos, very good 969 00:41:18,176 --> 00:41:20,526 on Problem Set 1 for those two axes. 970 00:41:21,126 --> 00:41:25,986 So the setup here was that swap has not worked for weeks, 971 00:41:26,146 --> 00:41:28,186 like we've been able to implement functions, 972 00:41:28,386 --> 00:41:30,846 we've been able to take in inputs, produce outputs, 973 00:41:30,896 --> 00:41:34,916 but swap itself cannot swap two values successfully. 974 00:41:35,166 --> 00:41:37,856 So one approach at least instinctively might be well, 975 00:41:37,856 --> 00:41:41,026 maybe the problem this whole time swap has been a void 976 00:41:41,026 --> 00:41:43,796 function, we are not actually returning a value. 977 00:41:44,176 --> 00:41:47,636 So by -- could we in fact maybe start returning a value. 978 00:41:47,636 --> 00:41:50,316 So if I call swap and pass in two values, 979 00:41:50,536 --> 00:41:53,556 maybe I could return the swapped values. 980 00:41:53,796 --> 00:41:54,966 But there's a problem here. 981 00:41:54,966 --> 00:41:57,596 How many values can you return from a function as far 982 00:41:57,596 --> 00:42:00,336 as we've seen in C. So only one. 983 00:42:00,396 --> 00:42:03,296 So we could maybe -- we could pass in -- 984 00:42:03,366 --> 00:42:08,726 we could do something like this, I might be able to do -- 985 00:42:08,836 --> 00:42:14,206 so inter, X, gets 1, int, Y gets 2. 986 00:42:14,436 --> 00:42:18,576 You know, maybe I could do something like X gets swap 987 00:42:18,826 --> 00:42:24,386 and then I can pass in X comma, Y. Okay, so that could 988 00:42:24,386 --> 00:42:29,496 in fact swam X. But now I -- odds are this would not work -- 989 00:42:29,496 --> 00:42:31,576 well, you know, I could kind of pack this, right? 990 00:42:31,576 --> 00:42:35,776 I could do swap Y X. Right, 991 00:42:35,776 --> 00:42:37,816 if you kind of think how I might implement it, you know, 992 00:42:37,816 --> 00:42:39,106 you could kind of hack this together. 993 00:42:39,136 --> 00:42:40,456 This feels kind of stupid, right? 994 00:42:40,456 --> 00:42:42,666 Or if you're still kind of acclimating to what we mean 995 00:42:42,666 --> 00:42:45,066 by good design, probably not good design here. 996 00:42:45,456 --> 00:42:48,696 So it would be ideal if we could just return two new values. 997 00:42:48,746 --> 00:42:54,236 Give me back two values and then I'll assign those to X and Y. 998 00:42:54,236 --> 00:42:58,066 And you can do this in some languages, but not in C. 999 00:42:58,316 --> 00:43:00,606 So the approach that is almost always taken 1000 00:43:00,606 --> 00:43:03,276 that actually opens the doors to some really powerful 1001 00:43:03,276 --> 00:43:05,566 if dangerous code is this one here. 1002 00:43:05,566 --> 00:43:10,186 Thus far we've been passing in arguments by value, by copy. 1003 00:43:10,536 --> 00:43:12,776 By contrast, there's something called passing 1004 00:43:12,776 --> 00:43:14,926 in arguments by pointer. 1005 00:43:15,206 --> 00:43:16,636 Or passing in by reference. 1006 00:43:16,816 --> 00:43:18,806 So pointer, reference, synonymous. 1007 00:43:19,156 --> 00:43:20,836 Value, copy, synonymous. 1008 00:43:21,286 --> 00:43:23,566 So passing in by pointer does something 1009 00:43:23,566 --> 00:43:25,506 fundamentally different. 1010 00:43:25,696 --> 00:43:29,126 Instead of passing to swap the values of X 1011 00:43:29,296 --> 00:43:34,476 and Y you can use this asterisk notation and pass enough values 1012 00:43:34,476 --> 00:43:37,876 of X and Y, but their physical locations in RAM. 1013 00:43:38,716 --> 00:43:43,406 Now as soon as you pass in the locations, AKA, the addresses 1014 00:43:43,696 --> 00:43:48,936 of two variables in RAM, you're essentially handing a function 1015 00:43:48,936 --> 00:43:50,776 like swap the power 1016 00:43:51,046 --> 00:43:53,796 to do anything he wants to those variables. 1017 00:43:53,836 --> 00:43:56,656 Because if you tell swap where X and Y live in memory, 1018 00:43:56,956 --> 00:43:59,376 he can go to town on them and swap them, change them, 1019 00:43:59,376 --> 00:44:02,426 delete theme, overwrite them, anything that function wants. 1020 00:44:02,676 --> 00:44:04,766 Now hopefully you're writing the function and you're not going 1021 00:44:04,766 --> 00:44:05,956 to mess with your own variables. 1022 00:44:06,126 --> 00:44:08,156 But what this is going to do for us is the following. 1023 00:44:08,466 --> 00:44:12,476 If in main I have the following scenarios. 1024 00:44:12,476 --> 00:44:16,466 So here we'll say as my RAM again, and in main, 1025 00:44:16,806 --> 00:44:19,826 we have main's arguments like arg C and arg V, 1026 00:44:19,826 --> 00:44:21,066 which aren't interesting today. 1027 00:44:21,366 --> 00:44:23,406 And then we have main this has this. 1028 00:44:23,676 --> 00:44:27,296 We have a value of X and we have a value for Y, 1029 00:44:27,296 --> 00:44:29,666 and these numbers are 1 and 2. 1030 00:44:30,046 --> 00:44:32,226 Hopefully, you can see this. 1031 00:44:32,816 --> 00:44:35,206 We just have two little boxes, the values 1 and 2, 1032 00:44:35,336 --> 00:44:36,306 and these have addresses. 1033 00:44:36,306 --> 00:44:38,226 So let's just use the same address as before. 1034 00:44:38,226 --> 00:44:41,536 So the address of this thing for reference is 0 X 12, 1035 00:44:41,746 --> 00:44:42,886 it's completely arbitrary. 1036 00:44:42,886 --> 00:44:43,566 I just made that up. 1037 00:44:43,566 --> 00:44:46,786 And the address of this thing completely arbitrary, 1038 00:44:46,786 --> 00:44:51,216 except that it's near by, is O X 16 , which is four bytes away. 1039 00:44:51,466 --> 00:44:53,046 So I'm being consistent relative, 1040 00:44:53,046 --> 00:44:54,166 but the starting point was random. 1041 00:44:54,506 --> 00:44:56,606 Okay, so that's what I've done here. 1042 00:44:56,606 --> 00:45:01,866 If I now calm swap before I allocated 32 bits, 32 bits, 1043 00:45:01,866 --> 00:45:03,596 and passed in the values of 1 and 2. 1044 00:45:03,806 --> 00:45:04,916 But you know what, let me do this. 1045 00:45:05,126 --> 00:45:08,436 Let me call swap this time, I'm just going to label it 1046 00:45:08,436 --> 00:45:12,516 over here, so this is swap's parameters, and I'm still going 1047 00:45:12,516 --> 00:45:17,566 to call these parameters A and B. But you know what? 1048 00:45:17,566 --> 00:45:19,766 What am I going to pass in as A and B? 1049 00:45:19,826 --> 00:45:21,816 Not 1 and 2, but what numbers? 1050 00:45:23,166 --> 00:45:26,496 Yeah, so O X 12, and I apologize for my hand writing, 1051 00:45:26,786 --> 00:45:31,506 we'll clean this up in the scribe notes, and O X 16. 1052 00:45:31,886 --> 00:45:35,296 So now incidentally, O X, this is just human convention 1053 00:45:35,296 --> 00:45:37,476 for the following is a hexadecimal number, that's it. 1054 00:45:37,476 --> 00:45:38,646 It doesn't mean there's a zero there, 1055 00:45:38,646 --> 00:45:39,826 it doesn't mean there's a digit X, 1056 00:45:39,826 --> 00:45:42,096 it just meaning the following digits are hexadecimal. 1057 00:45:42,446 --> 00:45:44,826 All right, so now I'm passing in this address and this address. 1058 00:45:45,096 --> 00:45:48,816 So this means swap can now use that information somehow. 1059 00:45:48,816 --> 00:45:49,726 So how do you do that? 1060 00:45:49,986 --> 00:45:51,706 Well here is the new and improved 1061 00:45:51,706 --> 00:45:53,606 and finally correct version of wrap. 1062 00:45:53,606 --> 00:45:56,646 What we're doing now with swap is the same thing as before, 1063 00:45:56,646 --> 00:45:58,266 we are declaring a temporary variable, 1064 00:45:58,656 --> 00:46:00,166 so that was swap's parameters. 1065 00:46:00,446 --> 00:46:03,716 Here now is swap's other frame, where he -- 1066 00:46:03,716 --> 00:46:05,776 where he can actually put local variables. 1067 00:46:05,776 --> 00:46:08,036 So here's a local variable called temp. 1068 00:46:08,536 --> 00:46:13,106 Now what I don't want to do is do temp equals A semicolon. 1069 00:46:13,396 --> 00:46:16,256 I don't want to just copy the value of A into temp 1070 00:46:16,536 --> 00:46:19,096 because I don't really care fundamentally about the address 1071 00:46:19,096 --> 00:46:22,166 of A, I'm just going to use that as a little short cut 1072 00:46:22,166 --> 00:46:23,766 to actually getting at A itself. 1073 00:46:24,096 --> 00:46:29,986 So the notation for following a pointer, the notation for going 1074 00:46:30,096 --> 00:46:32,106 to an address and getting the value that's 1075 00:46:32,106 --> 00:46:36,256 at that address is this asterisk before the A. 1076 00:46:36,826 --> 00:46:39,366 So this is the so-called dereference operator. 1077 00:46:39,366 --> 00:46:40,996 It's just a star, just an asterisk. 1078 00:46:41,356 --> 00:46:44,736 But what this tells the computer is treat A as a pointer 1079 00:46:45,136 --> 00:46:48,826 in address, so a pointer is an address, a location in memory, 1080 00:46:48,826 --> 00:46:50,206 those two are synonyms, hence force. 1081 00:46:50,516 --> 00:46:53,316 Go to that address, get what's there, 1082 00:46:53,316 --> 00:46:57,356 and what is there, what's that star A? 1083 00:46:57,356 --> 00:47:02,066 1, go to the address A, get what's there, 1084 00:47:02,226 --> 00:47:04,386 this is the address A, O X 12. 1085 00:47:04,546 --> 00:47:06,426 Get what's there, which is 1, and put 1 where? 1086 00:47:06,426 --> 00:47:08,486 Inside of temp. 1087 00:47:09,476 --> 00:47:10,036 So that's it. 1088 00:47:10,036 --> 00:47:13,396 So new syntax, but it's relatively simple. 1089 00:47:13,396 --> 00:47:18,336 We just have now introduced the idea of describing data not just 1090 00:47:18,336 --> 00:47:21,286 by its names, its labels, the variable names like X, Y, 1091 00:47:21,286 --> 00:47:25,176 A and B, but we now have another sort of advanced way of getting 1092 00:47:25,176 --> 00:47:28,716 at data by way of their actual addresses in memory. 1093 00:47:28,716 --> 00:47:31,006 And this is where C is both powerful and dangerous. 1094 00:47:31,006 --> 00:47:34,326 A lot of modern languages do not let you get this close 1095 00:47:34,326 --> 00:47:34,986 to the hardware. 1096 00:47:34,986 --> 00:47:36,326 They don't let you get this close 1097 00:47:36,666 --> 00:47:38,256 to manipulating computer's memory. 1098 00:47:38,426 --> 00:47:40,686 Because you can do a lot of damage relatively easy. 1099 00:47:40,686 --> 00:47:43,216 And we'll do precisely that in a lecture to come. 1100 00:47:43,476 --> 00:47:45,126 But for right now, it's really very powerful, 1101 00:47:45,126 --> 00:47:47,636 because we can really do anything we want underneath 1102 00:47:47,676 --> 00:47:48,136 the hood. 1103 00:47:48,356 --> 00:47:49,946 Which in this case is advantageous. 1104 00:47:49,946 --> 00:47:50,716 So what do I do next? 1105 00:47:51,116 --> 00:47:53,706 I've now copied the value 1 into temp. 1106 00:47:54,066 --> 00:47:55,506 So we're good, we're on our way. 1107 00:47:55,856 --> 00:47:59,986 Now star A gets star B. All right, well let's tease 1108 00:47:59,986 --> 00:48:01,846 that apart, let's start with the right-hand side first. 1109 00:48:01,956 --> 00:48:06,406 Staff B. So that means treat B as a pointer, O X 16. 1110 00:48:06,706 --> 00:48:08,776 Go there. Well, where is O X 16? 1111 00:48:09,106 --> 00:48:10,966 Well, my dotted line says it's right down here. 1112 00:48:11,196 --> 00:48:13,946 So go there and then star B in the end, 1113 00:48:14,376 --> 00:48:17,256 is equivalent to what value? 1114 00:48:17,256 --> 00:48:18,756 2, right? Just get the value 2. 1115 00:48:18,966 --> 00:48:20,326 What do I do with the value 2? 1116 00:48:20,436 --> 00:48:22,186 Well, assign it to the left-hand side. 1117 00:48:22,186 --> 00:48:23,276 What's the left-hand side. 1118 00:48:24,056 --> 00:48:27,836 Okay, same idea, treat A as a pointer, O X 12, 1119 00:48:28,096 --> 00:48:31,416 go to that address, so follow the pointer, 1120 00:48:31,446 --> 00:48:33,106 and then put what there? 1121 00:48:33,966 --> 00:48:34,716 2. That's it. 1122 00:48:35,596 --> 00:48:36,916 All right, so go there. 1123 00:48:36,916 --> 00:48:38,686 So it's kind of like there's this intermediate step. 1124 00:48:38,686 --> 00:48:40,606 We now have to go to an extra location, 1125 00:48:40,606 --> 00:48:42,946 we now have to do a little more work mentally 1126 00:48:42,946 --> 00:48:45,776 and also programatically, but the result is still going 1127 00:48:45,776 --> 00:48:47,336 to be the same, but in a much better way. 1128 00:48:47,336 --> 00:48:48,436 So now what do I do? 1129 00:48:48,696 --> 00:48:49,896 So star B gets temp. 1130 00:48:50,086 --> 00:48:50,896 Well, temp is easy. 1131 00:48:50,896 --> 00:48:53,176 This is the name of a variable, bam, I'm there. 1132 00:48:53,176 --> 00:48:54,386 This is like week one stuff. 1133 00:48:54,526 --> 00:48:55,566 Now what do I do with temp? 1134 00:48:56,086 --> 00:48:59,756 Go to the address pointed at by B. All right, so B is this, 1135 00:48:59,756 --> 00:49:01,346 this is a pointer O X 16. 1136 00:49:01,526 --> 00:49:03,666 Star B says go there, where? 1137 00:49:04,296 --> 00:49:06,146 Here. That is O X 16. 1138 00:49:06,346 --> 00:49:07,106 Do what with it? 1139 00:49:07,186 --> 00:49:08,106 Put there what value? 1140 00:49:09,716 --> 00:49:10,786 1, AKA, temp. 1141 00:49:11,596 --> 00:49:15,436 And so now even though I've used the same amount of memory, 1142 00:49:15,436 --> 00:49:17,206 I've still got two parameters. 1143 00:49:17,446 --> 00:49:18,966 I've still got a local variable. 1144 00:49:19,186 --> 00:49:22,166 Notice what I've done has not changed the local variables, 1145 00:49:22,166 --> 00:49:24,426 which really was a mistake last time, 1146 00:49:24,426 --> 00:49:25,816 really didn't get us anywhere. 1147 00:49:26,146 --> 00:49:28,656 Would have actually used those two parameters, 1148 00:49:28,916 --> 00:49:32,756 is as little shot cuts to go to the location in RAM to go 1149 00:49:32,756 --> 00:49:36,806 into main's own frame and change the original values. 1150 00:49:37,196 --> 00:49:41,916 So when I run this version here, swam dot C, hopefully, finally, 1151 00:49:41,916 --> 00:49:44,666 all these weeks later, will I get a correct answer. 1152 00:49:44,666 --> 00:49:46,146 So it's the same exact function. 1153 00:49:46,486 --> 00:49:49,966 The only thing I've changed is the implementation of swap. 1154 00:49:50,166 --> 00:49:52,426 But I've taken care to do two things here. 1155 00:49:52,516 --> 00:49:54,296 Actually, I did one change in main. 1156 00:49:54,746 --> 00:49:55,596 Notice what I've done. 1157 00:49:55,696 --> 00:49:58,346 I did all the stuff we just described, the star notation. 1158 00:49:58,386 --> 00:50:00,776 And for now this is the dereference operator. 1159 00:50:00,776 --> 00:50:03,546 It means go to this address, okay? 1160 00:50:03,546 --> 00:50:05,306 What did I also change in swap, though? 1161 00:50:05,396 --> 00:50:06,816 Something I didn't yet mention. 1162 00:50:08,126 --> 00:50:12,826 So what did I also do in swap. 1163 00:50:12,826 --> 00:50:13,856 Not ampersand. 1164 00:50:15,366 --> 00:50:17,826 What else has changed, vis-a-vis the buggy version? 1165 00:50:18,346 --> 00:50:22,226 Well, this part, so not ampersand. 1166 00:50:22,226 --> 00:50:23,606 This star is here, right? 1167 00:50:23,606 --> 00:50:26,296 So the declaration of swap has changed ever so slightly. 1168 00:50:26,296 --> 00:50:28,076 Previously, the definition of swap, 1169 00:50:28,376 --> 00:50:32,306 remember in the broken version from just now and also a couple 1170 00:50:32,306 --> 00:50:33,556 of weeks ago was this. 1171 00:50:33,556 --> 00:50:35,696 Int A, int B. And that's great. 1172 00:50:35,696 --> 00:50:36,746 I took in two ints. 1173 00:50:36,806 --> 00:50:37,646 But they were copies. 1174 00:50:37,966 --> 00:50:43,166 So if you instead want to pass by a reference, pass by pointer, 1175 00:50:43,466 --> 00:50:46,226 you instead say you know what, here comes not an int, 1176 00:50:46,566 --> 00:50:48,046 but a pointer to an inter. 1177 00:50:48,446 --> 00:50:49,996 Here comes the address of an inter. 1178 00:50:50,416 --> 00:50:53,626 And the way that you express the address of something is 1179 00:50:53,626 --> 00:50:54,816 to put a star in front of it. 1180 00:50:55,066 --> 00:50:57,666 So slight -- same symbol, which is a little confusing, 1181 00:50:57,756 --> 00:50:59,426 slightly different meaning inside 1182 00:50:59,426 --> 00:51:02,206 of this parenthetical context, versus inside 1183 00:51:02,206 --> 00:51:03,216 of the function itself. 1184 00:51:03,516 --> 00:51:05,956 But this just means that swap takes two arguments, 1185 00:51:06,246 --> 00:51:08,906 one called A, one called B, and both of them happen 1186 00:51:08,906 --> 00:51:11,806 to be the addresses of integers in memory. 1187 00:51:12,186 --> 00:51:14,286 And that's precisely consistent with this picture. 1188 00:51:14,606 --> 00:51:16,076 So I have changed one other thing, 1189 00:51:16,076 --> 00:51:17,226 as a couple of people noticed. 1190 00:51:17,226 --> 00:51:19,456 What has changed in my main function, apparently. 1191 00:51:20,616 --> 00:51:21,746 So there are these ampersands. 1192 00:51:21,746 --> 00:51:24,966 Exactly. So the ampersand operator is kind 1193 00:51:24,966 --> 00:51:27,186 of like the opposite of the dereference operator, 1194 00:51:27,226 --> 00:51:31,776 whereas the star inside of swam says go to this address, 1195 00:51:32,126 --> 00:51:35,226 the ampersand operator says get the address 1196 00:51:35,746 --> 00:51:37,066 of the following variable. 1197 00:51:37,326 --> 00:51:39,226 So previously, in the buggy version 1198 00:51:39,406 --> 00:51:41,446 of my main function, I just did this. 1199 00:51:41,596 --> 00:51:44,856 I passed in X, I passed in Y, but that was problematic, 1200 00:51:44,856 --> 00:51:47,846 because I'm saying here swap, here's two values, 1 and 2. 1201 00:51:48,046 --> 00:51:50,446 Do what you want with them, but do only what you want 1202 00:51:50,446 --> 00:51:52,246 with the copies I am handing you. 1203 00:51:52,566 --> 00:51:56,526 So in this case when I say ampersand X and ampersand Y, 1204 00:51:56,776 --> 00:51:59,966 this is saying hey swap, here comes the address of an int, 1205 00:52:00,396 --> 00:52:02,026 let's call it X -- I'll call it X, 1206 00:52:02,026 --> 00:52:03,146 you can call it anything you want -- 1207 00:52:03,476 --> 00:52:05,486 here comes the address of another inter. 1208 00:52:05,666 --> 00:52:08,826 I'll call it Y, but you can call it anything you want, say B, 1209 00:52:09,136 --> 00:52:10,506 do what you want with these now. 1210 00:52:10,956 --> 00:52:14,886 So you're now handing two swap again the power 1211 00:52:14,886 --> 00:52:17,756 to actually manipulate the data at those locations. 1212 00:52:18,246 --> 00:52:20,716 And this is hugely powerful. 1213 00:52:20,716 --> 00:52:22,046 In fact, we've seen this before. 1214 00:52:22,046 --> 00:52:24,366 Where have we seen the star operator before, 1215 00:52:24,366 --> 00:52:26,036 and not in the context of multiplication. 1216 00:52:26,516 --> 00:52:28,556 What data type? 1217 00:52:28,796 --> 00:52:31,636 Right, we've seen it in R V. So we've had char, star, 1218 00:52:31,636 --> 00:52:34,046 R V brackets, we've seen the asterisk there, 1219 00:52:34,046 --> 00:52:35,616 and it's clearly not multiplication there. 1220 00:52:35,866 --> 00:52:38,196 We've seen char, star, synonymous with string, 1221 00:52:38,196 --> 00:52:40,246 and that too has nothing to do with multiplication. 1222 00:52:40,246 --> 00:52:41,466 So we've seen this before. 1223 00:52:41,656 --> 00:52:43,456 But because now things are getting a little more 1224 00:52:43,456 --> 00:52:45,256 sophisticated, a little more interesting, 1225 00:52:45,536 --> 00:52:48,986 do we final started addressing, pun intended, 1226 00:52:49,256 --> 00:52:52,016 what that symbol actually means. 1227 00:52:52,066 --> 00:52:54,346 So tutorially, we offer this. 1228 00:52:54,456 --> 00:52:57,676 So there's a nice tutorial link on the resources page 1229 00:52:57,676 --> 00:53:00,366 of the courses' web site from how stuff works. 1230 00:53:00,366 --> 00:53:02,016 And it's actually got a nice exposition 1231 00:53:02,016 --> 00:53:03,236 of what's going on inside. 1232 00:53:03,346 --> 00:53:05,306 And their pictures are much cleaner than mine. 1233 00:53:05,666 --> 00:53:10,076 So these two lines of code, inter, I, comma, J, and int, 1234 00:53:10,076 --> 00:53:13,306 star, P, is a clearer picture like the following. 1235 00:53:13,616 --> 00:53:15,156 So what's going on here, and I'm going 1236 00:53:15,156 --> 00:53:17,546 to go ahead and eliminate this. 1237 00:53:17,716 --> 00:53:20,436 It will appear on the scribe notes, if needed. 1238 00:53:20,596 --> 00:53:26,226 And let me go ahead and see if we can't relate this 1239 00:53:26,276 --> 00:53:27,086 to the previous stuff. 1240 00:53:27,086 --> 00:53:29,976 So int I comma J. Well, we've done stuff like this before. 1241 00:53:29,976 --> 00:53:33,796 Int I comma J. And I've even drawn silly little pictures 1242 00:53:33,796 --> 00:53:34,196 like this. 1243 00:53:34,196 --> 00:53:34,836 What does this do? 1244 00:53:34,836 --> 00:53:36,336 Well, this allocates somewhere 1245 00:53:36,336 --> 00:53:38,816 in program RAM 32 bits and it calls it I. 1246 00:53:38,906 --> 00:53:40,896 And then another 32 bits in memory, 1247 00:53:41,136 --> 00:53:43,976 calls it J. They're not necessarily next to each other. 1248 00:53:44,076 --> 00:53:47,706 Odds are they are one after the other, but there's no guarantee 1249 00:53:48,016 --> 00:53:50,276 of contiguousness, unless you've declared an array. 1250 00:53:50,276 --> 00:53:52,436 But I've just declared two ints here, 1251 00:53:52,476 --> 00:53:54,826 I and J. So I get two chunks of RAM. 1252 00:53:55,216 --> 00:54:00,426 Now if I do something like this, I gets -- let's say 3. 1253 00:54:00,936 --> 00:54:02,086 What happens in my picture? 1254 00:54:02,336 --> 00:54:04,026 Well, 3 goes there. 1255 00:54:04,026 --> 00:54:04,686 And what's here? 1256 00:54:04,686 --> 00:54:06,126 Well, this is some garbage value. 1257 00:54:06,126 --> 00:54:06,906 Who knows what's there. 1258 00:54:06,906 --> 00:54:08,526 We better not do anything with it yet. 1259 00:54:08,996 --> 00:54:11,196 All right, let me do something else kind of random. 1260 00:54:11,196 --> 00:54:13,006 So J gets 4. 1261 00:54:13,346 --> 00:54:14,256 All right, what happens? 1262 00:54:14,256 --> 00:54:17,306 Well, this unknown value now becomes a 4. 1263 00:54:17,486 --> 00:54:20,026 Now suppose I want to change the value of I. 1264 00:54:20,296 --> 00:54:23,226 The easiest, most obvious way of changing I from 3 1265 00:54:23,226 --> 00:54:24,906 to say 5 would be this. 1266 00:54:25,836 --> 00:54:28,066 I gets 5. How does the picture change? 1267 00:54:28,496 --> 00:54:30,316 Well the 3 becomes a 5. 1268 00:54:30,376 --> 00:54:32,246 Right? Very much Week One stuff. 1269 00:54:32,576 --> 00:54:34,816 But let's see if we can't now leverage this idea, 1270 00:54:34,816 --> 00:54:38,716 albeit in a little sand box, to use the address of this thing. 1271 00:54:38,716 --> 00:54:42,926 Suppose I want to change I from 3 to 5, but I want to kind 1272 00:54:42,926 --> 00:54:45,386 of impress people and do it in a manner 1273 00:54:45,386 --> 00:54:47,476 that leverages the addresses of this stuff. 1274 00:54:47,806 --> 00:54:49,546 Well, with this slide here, what this picture 1275 00:54:49,546 --> 00:54:52,876 and tutorial are explaining is just as you declare an int 1276 00:54:53,136 --> 00:54:55,256 by saying int, and then the name of the thing, 1277 00:54:55,896 --> 00:55:01,206 you declare a pointer to a data type by saying int star P. 1278 00:55:01,766 --> 00:55:03,586 So this now declares, and for those 1279 00:55:03,586 --> 00:55:04,616 for whom this might be cut off, 1280 00:55:04,616 --> 00:55:07,546 I've just win int star P semicolon. 1281 00:55:07,806 --> 00:55:10,566 All this is doing is saying to GCC, you know what, 1282 00:55:10,666 --> 00:55:13,126 give me 32 bits, but I'm not going to store 1283 00:55:13,126 --> 00:55:17,696 in those 32 bits an inter, but rather an address of an int, 1284 00:55:18,296 --> 00:55:21,196 and it just so happens that with what data type our address is 1285 00:55:21,196 --> 00:55:24,846 actually stored, have we been saying, with ints. 1286 00:55:25,016 --> 00:55:26,936 So in this case, it's actually kind of a coincidence, 1287 00:55:26,986 --> 00:55:28,856 but a pointer, as this thing is called, 1288 00:55:28,856 --> 00:55:32,306 the address in a C program is implemented ultimately 1289 00:55:32,306 --> 00:55:33,036 by way of an inter. 1290 00:55:33,486 --> 00:55:35,576 So this is going to be another 32-bit chunk. 1291 00:55:35,576 --> 00:55:36,536 And that's why I'm drawing them all 1292 00:55:36,536 --> 00:55:38,076 as roughly the same size squares. 1293 00:55:38,376 --> 00:55:45,246 Here is its name P. And if I now say this, let's say P gets I, 1294 00:55:46,976 --> 00:55:49,516 what would that do for me? 1295 00:55:49,646 --> 00:55:53,016 P gets can I. 1296 00:55:53,146 --> 00:55:53,986 So nothing. 1297 00:55:54,516 --> 00:55:55,626 Bad stuff, right? 1298 00:55:55,626 --> 00:55:59,446 Because I'm saying store in this address, 1299 00:55:59,826 --> 00:56:02,466 store in this variable I, well, what does that mean? 1300 00:56:02,466 --> 00:56:06,076 That means put three here, but the compiler is probably going 1301 00:56:06,076 --> 00:56:08,426 to yell at us, because these two things, P and I, 1302 00:56:08,666 --> 00:56:09,946 are different data times. 1303 00:56:10,396 --> 00:56:13,786 Right? This is like trying to cram one data type into another 1304 00:56:13,786 --> 00:56:15,686 that doesn't really belong there. 1305 00:56:15,726 --> 00:56:17,376 P is supposed to be the address of something, 1306 00:56:17,376 --> 00:56:19,826 but I is not the address of something, I is a value. 1307 00:56:20,206 --> 00:56:24,136 So if what my real goal was here is not to store in P the value 1308 00:56:24,136 --> 00:56:25,796 of I, but the address of I, 1309 00:56:26,186 --> 00:56:29,026 what did we just say is the trick syntactically for that? 1310 00:56:29,856 --> 00:56:34,296 Yeah. So P gets ampersand of I, and what that means is 1311 00:56:34,296 --> 00:56:36,556 that what goes here is what, well, gosh, 1312 00:56:36,556 --> 00:56:38,226 now I have to make the picture a little messier. 1313 00:56:38,526 --> 00:56:40,906 All right, I don't know where this stuff is, so let's say it's 1314 00:56:40,906 --> 00:56:44,116 in 0 X 123, somewhere in memory. 1315 00:56:44,396 --> 00:56:47,916 And this one, who knows, this is in 0 X 789. 1316 00:56:47,916 --> 00:56:49,676 Because again, they're not necessarily adjacent 1317 00:56:49,746 --> 00:56:50,206 to each other. 1318 00:56:50,206 --> 00:56:51,176 So who knows where they are. 1319 00:56:51,476 --> 00:56:54,266 But now in this context, P gets ampersand I. 1320 00:56:54,606 --> 00:56:55,296 What am I doing? 1321 00:56:55,296 --> 00:57:00,306 Well, ampersand I is the address of I, which I just said, 1322 00:57:00,306 --> 00:57:02,676 and I'm sort of the omniscient God here who knows 1323 00:57:02,676 --> 00:57:06,996 where stuff is in memory, I'm going to put 0 X 123 here. 1324 00:57:07,366 --> 00:57:10,736 Now what you'll see in most text books, and frankly, even we, 1325 00:57:10,886 --> 00:57:12,926 after this week will start doing, because talking 1326 00:57:12,926 --> 00:57:15,796 about arbitrarily-picked hexadecimal numbers really is 1327 00:57:15,796 --> 00:57:17,146 not intellectually enlightening. 1328 00:57:17,396 --> 00:57:20,336 What we'll typically do is abstract this detail away 1329 00:57:20,336 --> 00:57:21,836 and say you know what, frankly, 1330 00:57:21,836 --> 00:57:23,756 who cares where this thing is in memory. 1331 00:57:23,756 --> 00:57:26,896 It really doesn't benefit us to know the specifics of that. 1332 00:57:27,136 --> 00:57:29,766 We're going to exploit where it is, but we don't have to care 1333 00:57:29,896 --> 00:57:31,056 where it is precisely. 1334 00:57:31,316 --> 00:57:34,076 So what you'll usually see me and most any teacher 1335 00:57:34,076 --> 00:57:37,666 or text do is draw a pointer as a pointer, as an arrow. 1336 00:57:38,096 --> 00:57:41,596 So what's stored inside of P is yes, the address of I, 1337 00:57:41,596 --> 00:57:43,496 but let's depict that, let's convey 1338 00:57:43,496 --> 00:57:46,126 that idea pictorially just by drawing an arrow. 1339 00:57:46,516 --> 00:57:48,526 So what can I now do with this information? 1340 00:57:49,076 --> 00:57:49,856 Well, let's see. 1341 00:57:50,026 --> 00:57:54,266 If I do I gets 5, I immediately change the 3 to a 5. 1342 00:57:54,406 --> 00:57:58,786 But what if I instead do star P gets 5. 1343 00:57:59,136 --> 00:58:00,076 Well, what does that mean? 1344 00:58:00,326 --> 00:58:01,296 Well, P is here. 1345 00:58:01,636 --> 00:58:04,196 Star P means go to that address. 1346 00:58:04,876 --> 00:58:07,126 So this sort of like chutes and ladders style, 1347 00:58:07,126 --> 00:58:10,856 when it says star P, go to that actual address and then do what? 1348 00:58:11,166 --> 00:58:14,636 Then assign it the value of 5. 1349 00:58:15,606 --> 00:58:18,146 So in short, few new syntactic tricks, we've got ampersand 1350 00:58:18,146 --> 00:58:19,506 to say give me the address of something. 1351 00:58:19,726 --> 00:58:22,896 Star means go here, or in the context 1352 00:58:22,896 --> 00:58:27,206 of a function's declaration, star says expect not an int 1353 00:58:27,536 --> 00:58:28,756 but a pointer to an inter. 1354 00:58:28,856 --> 00:58:32,056 So the meaning of the star is somewhat context sensitive. 1355 00:58:32,296 --> 00:58:34,626 But at the end of the day any time you see the star 1356 00:58:34,626 --> 00:58:37,986 or this ampersand operator now, odds are we're actually talking 1357 00:58:37,986 --> 00:58:39,346 about these things called pointers, 1358 00:58:39,396 --> 00:58:40,996 and again a pointer is just a fancy way 1359 00:58:40,996 --> 00:58:43,926 of saying the address of a piece of memory. 1360 00:58:44,596 --> 00:58:48,146 Okay, any questions about pointers? 1361 00:58:49,516 --> 00:58:53,376 No? Okay. So this -- and again, I can't emphasize enough, 1362 00:58:53,626 --> 00:58:55,116 if this feels a little new, 1363 00:58:55,386 --> 00:58:56,756 these pictures are actually pretty good. 1364 00:58:56,756 --> 00:58:59,386 But they just depict what we talked about a moment ago. 1365 00:58:59,746 --> 00:59:02,576 So it turns out there is a relationship with arrays 1366 00:59:02,716 --> 00:59:05,516 that we've kind of been waving our hands at. 1367 00:59:05,626 --> 00:59:08,846 Clearly, R V has something to do with arrays, but also pointers 1368 00:59:08,876 --> 00:59:12,776 because the brackets and the star, and char star is this -- 1369 00:59:12,996 --> 00:59:16,356 is the technical definition for a string, but we already know 1370 00:59:16,356 --> 00:59:18,586 that strings are really just chars, 1371 00:59:18,626 --> 00:59:20,826 but not chars per se, arrays of chars. 1372 00:59:21,146 --> 00:59:25,016 So there's actually been this relationship between pointers 1373 00:59:25,016 --> 00:59:28,066 and array, or at least a similarity between them. 1374 00:59:28,286 --> 00:59:30,046 So just to slap a picture on this too. 1375 00:59:30,046 --> 00:59:31,696 If in code I say inter-I, 1376 00:59:32,006 --> 00:59:35,616 what I get at top right there is a 32-bit chunk of memory. 1377 00:59:35,686 --> 00:59:37,906 The how stuff works tutorial says question mark, 1378 00:59:37,906 --> 00:59:39,946 question mark, because who knows what's there. 1379 00:59:39,946 --> 00:59:40,946 It's some garbage value. 1380 00:59:41,276 --> 00:59:44,446 But that's how we might depict it with a diagram. 1381 00:59:44,916 --> 00:59:49,626 Int A bracket 5 close bracket in layman's terms, or oh, 1382 00:59:49,726 --> 00:59:53,266 slightly more technical layman's terms, that delays an array 1383 00:59:53,266 --> 00:59:54,886 of size of 5 for 5 ints. 1384 00:59:55,396 --> 00:59:56,286 Okay, what does that mean? 1385 00:59:56,566 --> 01:00:00,296 Well, in memory, that means you get five chunks of memory, 1386 01:00:00,356 --> 01:00:02,936 five 32-bit chunks, back to back to back to back, 1387 01:00:02,936 --> 01:00:04,886 as in the middle of this picture, at top right. 1388 01:00:05,176 --> 01:00:07,606 It's called A, that's the name of the variable. 1389 01:00:07,606 --> 01:00:10,106 And A bracket 0 is the first location, 1390 01:00:10,206 --> 01:00:11,956 A bracket 1 is the second location, 1391 01:00:11,956 --> 01:00:13,416 on up to I think bracket 4. 1392 01:00:14,026 --> 01:00:18,326 But turns out you can actually start to treat arrays 1393 01:00:18,326 --> 01:00:21,526 in most context as though they're actually pointers. 1394 01:00:21,946 --> 01:00:25,156 So even though in this context, A is really just the name 1395 01:00:25,156 --> 01:00:28,926 of this array, it turns out you can even in C say something 1396 01:00:28,926 --> 01:00:32,276 like line 3 there, int star P, which says give me a pointer 1397 01:00:32,276 --> 01:00:36,896 to an int and call it P. What am I assigning it? 1398 01:00:37,066 --> 01:00:40,556 A. So what do you think is actually getting stored inside 1399 01:00:40,606 --> 01:00:42,756 of P per this third line of code. 1400 01:00:43,456 --> 01:00:45,686 It's going to be the address. 1401 01:00:45,946 --> 01:00:47,126 What is it the address of? 1402 01:00:47,126 --> 01:00:52,816 Yeah. It's the address of the first element in the array. 1403 01:00:53,146 --> 01:00:56,666 Right? So there's an advantage of arrays being defined 1404 01:00:56,666 --> 01:00:58,866 as contiguous blocks of memory. 1405 01:00:59,166 --> 01:01:00,976 You might think at first glance, wow, if I 1406 01:01:01,046 --> 01:01:03,616 had just been handed five ints, I number know the addresses 1407 01:01:03,616 --> 01:01:05,526 of all five integers, otherwise how am I going 1408 01:01:05,526 --> 01:01:06,196 to hang on to them. 1409 01:01:06,616 --> 01:01:07,696 But really, you don't. 1410 01:01:07,696 --> 01:01:10,356 If you know that the memory is back to back to back to back, 1411 01:01:10,676 --> 01:01:12,916 it's not all that enlightening to know what the address 1412 01:01:12,916 --> 01:01:14,486 of this is, this is, this is. 1413 01:01:14,486 --> 01:01:16,766 All you need to know is where the starting point is, 1414 01:01:16,766 --> 01:01:19,486 and then you, the programmer, hopefully kept around a variable 1415 01:01:19,486 --> 01:01:22,166 like N or just have some recollection of the length. 1416 01:01:22,246 --> 01:01:24,896 Because if you know the starting address in memory and the length 1417 01:01:24,896 --> 01:01:26,336 of the thing and how big each one is, 1418 01:01:26,606 --> 01:01:28,816 you can reverse engineer the actual address 1419 01:01:28,816 --> 01:01:30,156 of anything in between. 1420 01:01:30,436 --> 01:01:33,126 So what's hatching here with int star P gets A, 1421 01:01:33,126 --> 01:01:36,796 this is saying store in P address 1422 01:01:37,196 --> 01:01:39,896 of the first integer in this array. 1423 01:01:40,296 --> 01:01:44,576 Which means if I then proceed to do this, let me write one line 1424 01:01:44,576 --> 01:01:47,866 of code on the fly with respect to this giant bunch of code, 1425 01:01:48,206 --> 01:01:55,316 if I say print F quote unquote percent D, and then bracket A, 1426 01:01:55,316 --> 01:02:02,056 let's say -- would have helped if they gave us values. 1427 01:02:02,056 --> 01:02:03,586 Okay, not the best example. 1428 01:02:03,816 --> 01:02:09,966 What's this going to print? 1429 01:02:10,566 --> 01:02:12,666 Okay, so that's actually a good -- clever answer. 1430 01:02:12,666 --> 01:02:15,246 So the value in the first location of the array. 1431 01:02:15,546 --> 01:02:17,466 Frankly, I realized this was a bag example 1432 01:02:17,466 --> 01:02:19,386 because this is going to print junk, who knows what it's going 1433 01:02:19,386 --> 01:02:20,966 to print, because question marks are there. 1434 01:02:21,136 --> 01:02:22,976 But higher level, this is going 1435 01:02:22,976 --> 01:02:25,446 to print the first int the array. 1436 01:02:25,856 --> 01:02:30,866 But it turns out if I do this too, if I've done star P gets A, 1437 01:02:31,356 --> 01:02:36,376 notice what happens if I just put P, this is going 1438 01:02:36,406 --> 01:02:38,356 to literally print the address, right? 1439 01:02:38,356 --> 01:02:42,566 So int -- rather pointers are in fact numbers, they are integers. 1440 01:02:42,836 --> 01:02:44,666 Percent D means put an integer here. 1441 01:02:45,006 --> 01:02:49,176 So this would actually print the address of the first location 1442 01:02:49,176 --> 01:02:52,726 in A, otherwise known as P. This would print the value inside P. 1443 01:02:52,726 --> 01:02:55,706 But if you actually want to go to P and print that location, 1444 01:02:55,946 --> 01:02:59,676 if I add this it turns out that this is essentially synonymous 1445 01:02:59,676 --> 01:03:03,176 with A bracket 0 at this point in the story. 1446 01:03:03,176 --> 01:03:05,426 So again, I have this ability to figure out the address 1447 01:03:05,426 --> 01:03:06,386 of something in memory. 1448 01:03:06,596 --> 01:03:08,486 But then with a star operator, I have the ability 1449 01:03:08,486 --> 01:03:09,756 to go to that address. 1450 01:03:10,056 --> 01:03:10,906 So I now have a way 1451 01:03:10,906 --> 01:03:14,336 of expressing the same values in different ways. 1452 01:03:14,336 --> 01:03:16,516 And this in and of itself not all that useful, 1453 01:03:16,516 --> 01:03:19,226 because we've not given you a trick that you need 1454 01:03:19,226 --> 01:03:21,706 to solve any new problems in a silly context like this. 1455 01:03:21,906 --> 01:03:24,616 But we'll see that this is actually increasingly powerful. 1456 01:03:24,616 --> 01:03:25,896 So let's take a look, actually. 1457 01:03:26,196 --> 01:03:29,066 In compare 1.C, which you do have a print out of today, 1458 01:03:29,066 --> 01:03:32,686 we have now an explicit use of star. 1459 01:03:33,006 --> 01:03:35,166 So now at least in lectures, we're going to begin 1460 01:03:35,166 --> 01:03:37,586 to take off the training wheels, so to speak, and yes, 1461 01:03:37,586 --> 01:03:38,896 we're going to talk about strings, 1462 01:03:38,896 --> 01:03:41,066 but let's really call them what they are. 1463 01:03:41,066 --> 01:03:42,776 They are char stars. 1464 01:03:43,076 --> 01:03:45,196 Or they are arrays of characters. 1465 01:03:45,486 --> 01:03:46,636 All right, so what does this mean? 1466 01:03:46,716 --> 01:03:50,256 So here's a program called compare 1 dot C per the comments 1467 01:03:50,256 --> 01:03:50,796 up top. 1468 01:03:50,926 --> 01:03:54,676 This is going to try and fail to compare to strings. 1469 01:03:54,676 --> 01:03:56,736 But the interesting question is going to be why. 1470 01:03:57,046 --> 01:03:59,516 Well, it's not a long program, so let's see what's going on. 1471 01:03:59,516 --> 01:04:01,316 So here we have print def. 1472 01:04:01,476 --> 01:04:03,866 So say something this program is going to do. 1473 01:04:03,866 --> 01:04:05,196 Then I'm using get string, 1474 01:04:05,526 --> 01:04:07,206 and I'm storing the string that's returned 1475 01:04:07,206 --> 01:04:08,586 in a variable called S 1. 1476 01:04:08,586 --> 01:04:10,286 But again, training wheels off, 1477 01:04:10,286 --> 01:04:12,186 I'm not calling it a string, it's a char star. 1478 01:04:12,316 --> 01:04:15,186 Same thing, but now we can finally ask the question what 1479 01:04:15,186 --> 01:04:15,896 does that mean. 1480 01:04:16,106 --> 01:04:18,596 All right, then the line 3 here, say something else, 1481 01:04:19,066 --> 01:04:22,236 then I store the second thing the user types in S 2. 1482 01:04:22,526 --> 01:04:24,156 That's where of the string's getting stored. 1483 01:04:24,416 --> 01:04:27,306 But now let's push a little harder on my own language here. 1484 01:04:27,586 --> 01:04:30,026 When I say get string returns a string, 1485 01:04:30,646 --> 01:04:32,426 how do you return a string? 1486 01:04:32,426 --> 01:04:35,016 Like functions can only return one thing. 1487 01:04:35,406 --> 01:04:38,266 Now you can't just hand the user any number of characters 1488 01:04:38,266 --> 01:04:40,896 or whole sentence, what is get string really returning. 1489 01:04:41,016 --> 01:04:44,536 So an array of characters, but what does that mean, 1490 01:04:44,536 --> 01:04:46,116 what literally is being handed back. 1491 01:04:46,116 --> 01:04:48,186 Because an array of characters still sounds plural. 1492 01:04:48,186 --> 01:04:49,566 What's getting handed back? 1493 01:04:50,226 --> 01:04:50,786 A pointer. 1494 01:04:50,786 --> 01:04:54,096 The address of the string in memory. 1495 01:04:54,306 --> 01:04:56,716 So all this time when get string has been getting a string 1496 01:04:56,716 --> 01:04:58,816 from the user, what that means is get string, 1497 01:04:58,816 --> 01:05:00,936 whose implementation we'll look at, 1498 01:05:00,936 --> 01:05:04,126 is actually allocating a bunch of RAM all contiguously, 1499 01:05:04,426 --> 01:05:06,686 any character I type at the keyboard as the human, 1500 01:05:07,226 --> 01:05:08,206 as part of this function, 1501 01:05:08,376 --> 01:05:10,536 gets stored here then here then here then here, 1502 01:05:10,536 --> 01:05:13,906 character by character, and then get string, which again we wrote 1503 01:05:14,046 --> 01:05:17,346 in order to return that string to you, quote unquote, 1504 01:05:17,346 --> 01:05:19,736 to return conceptually that whole string, 1505 01:05:20,036 --> 01:05:22,936 it suffices to return to you what? 1506 01:05:22,936 --> 01:05:25,756 Just the address of the first character in that string. 1507 01:05:25,986 --> 01:05:27,156 And why is that sufficient? 1508 01:05:27,156 --> 01:05:29,966 I don't know in advance how long that string is, 1509 01:05:29,966 --> 01:05:33,486 but what did we say if briefly a few lectures ago, 1510 01:05:33,716 --> 01:05:35,886 demarks the end of a string in memory. 1511 01:05:37,186 --> 01:05:40,596 So special zero character, so if I type in the word foo 1512 01:05:40,596 --> 01:05:43,496 at the keyboard an the get string function 1513 01:05:43,496 --> 01:05:46,976 as we'll see stores a character F, then O, then O, 1514 01:05:47,196 --> 01:05:49,876 it also stores a special terminating character, 1515 01:05:49,876 --> 01:05:51,706 which we represent with back slash zero. 1516 01:05:51,956 --> 01:05:53,706 This is literally all zeros. 1517 01:05:54,006 --> 01:05:57,716 And this demarks the end of the string so I don't have to know 1518 01:05:57,716 --> 01:05:59,546 or guess what the length of the string is. 1519 01:05:59,816 --> 01:06:02,546 If I'm given the address of the beginning of the string, 1520 01:06:02,916 --> 01:06:05,736 I can figure out how long the string is just with a for loop, 1521 01:06:05,736 --> 01:06:07,536 check here, check here, check here, ah ha, 1522 01:06:07,946 --> 01:06:09,186 there's back slash zero. 1523 01:06:09,186 --> 01:06:11,766 So in fact, many of you have probably used the sterling 1524 01:06:11,766 --> 01:06:14,346 function for some piece or another, string length, 1525 01:06:14,476 --> 01:06:15,456 to get the length of a string. 1526 01:06:15,456 --> 01:06:15,966 What is it doing? 1527 01:06:16,196 --> 01:06:19,386 It is literally implemented with a 4 for or a while loop. 1528 01:06:19,606 --> 01:06:21,426 It starts at the beginning of the string and just checks, 1529 01:06:21,536 --> 01:06:23,476 are you back slash zero, are you back slash zero, 1530 01:06:23,476 --> 01:06:24,516 are you back slash zero. 1531 01:06:24,766 --> 01:06:27,286 When the answer is finally yes, it returns the number 1532 01:06:27,286 --> 01:06:28,396 of times it asks that question. 1533 01:06:28,766 --> 01:06:30,406 So that's all Stirling has been doing. 1534 01:06:30,646 --> 01:06:33,456 So what this means is get string is going to return a pointer 1535 01:06:33,766 --> 01:06:38,116 to a character that is a pointer to a -- an array of changes. 1536 01:06:38,466 --> 01:06:40,496 So why does the following fail? 1537 01:06:41,216 --> 01:06:41,976 Notice this. 1538 01:06:42,546 --> 01:06:47,746 If I get one string S 1, and then get string S 2 1539 01:06:47,976 --> 01:06:51,216 and then compare the two, this program's actually broken. 1540 01:06:51,216 --> 01:06:51,776 So let me do this. 1541 01:06:51,776 --> 01:06:54,366 Make compare 1, okay? 1542 01:06:54,366 --> 01:06:59,346 Now I'm going to run compare 1 -- okay, I'm going to say foo 1543 01:06:59,566 --> 01:07:02,156 and bar and obviously, I type different things. 1544 01:07:02,156 --> 01:07:03,476 And the program seems to be correct 1545 01:07:03,476 --> 01:07:04,946 at least 50% of the time. 1546 01:07:05,286 --> 01:07:06,356 Well now let me do this. 1547 01:07:06,786 --> 01:07:09,846 So foo, foo, hmm. 1548 01:07:10,196 --> 01:07:11,766 Maybe it was just buggy that time. 1549 01:07:11,766 --> 01:07:14,646 Bar, bar. All right, so maybe you've even done 1550 01:07:14,646 --> 01:07:15,166 that too, right? 1551 01:07:15,166 --> 01:07:16,496 Maybe I cross my fingers 1552 01:07:16,496 --> 01:07:18,066 and rerun my program the bug will go away. 1553 01:07:18,066 --> 01:07:19,446 But it hasn't in this case. 1554 01:07:20,116 --> 01:07:21,376 So what has happened? 1555 01:07:21,466 --> 01:07:22,566 Well, let's see. 1556 01:07:22,666 --> 01:07:25,656 We don't even know how get string is really implemented, 1557 01:07:25,656 --> 01:07:28,326 well technically you could look at the code you have printed. 1558 01:07:28,326 --> 01:07:29,196 If there's a bunch of it -- 1559 01:07:29,546 --> 01:07:31,996 we can infer what's really going on. 1560 01:07:31,996 --> 01:07:34,406 So get string again is a function we wrote. 1561 01:07:34,626 --> 01:07:37,716 Its purpose in life is to figure out what the user has typed 1562 01:07:37,716 --> 01:07:39,806 at the keyboard and then return it to you 1563 01:07:39,806 --> 01:07:41,016 as an array of characters. 1564 01:07:41,326 --> 01:07:44,356 So what's happening, the first time I call get string, 1565 01:07:44,356 --> 01:07:47,186 and I type in foo, get string is allocating, 1566 01:07:47,246 --> 01:07:48,676 again the thing I just drew. 1567 01:07:48,926 --> 01:07:51,456 Not three but four characters, 1568 01:07:51,846 --> 01:07:55,416 because we need a fourth character, an extra character 1569 01:07:55,416 --> 01:07:57,786 for the back slash zero, what is it returning? 1570 01:07:57,996 --> 01:08:00,666 It's returning to me the address of this thing. 1571 01:08:00,666 --> 01:08:01,896 One, two, three, we'll say. 1572 01:08:01,896 --> 01:08:03,256 I don't know where it is, who cares. 1573 01:08:03,516 --> 01:08:05,506 It's just 0 X 123. 1574 01:08:05,856 --> 01:08:09,736 But then the next time I call get string I'm getting a 1575 01:08:09,736 --> 01:08:10,746 different chunk of memory. 1576 01:08:10,746 --> 01:08:11,846 So up here I did this. 1577 01:08:12,176 --> 01:08:18,056 S 1 gets -- and this is char star S 1 gets get string, 1578 01:08:19,476 --> 01:08:23,586 so what is inside of S 1 at this point? 1579 01:08:23,806 --> 01:08:27,866 Well, S 1 is a local variable, it's a type char star , 1580 01:08:28,106 --> 01:08:30,026 which just means it's a pointer to a char. 1581 01:08:30,026 --> 01:08:30,716 What does that mean? 1582 01:08:30,986 --> 01:08:33,636 After this line of code is executed, what gets put inside 1583 01:08:33,636 --> 01:08:35,306 of this 32-bit chunk of memory. 1584 01:08:35,716 --> 01:08:41,276 O X 123. That's all it takes to store a string, or really, 1585 01:08:41,436 --> 01:08:44,466 that's all it takes to remember where a string is, 1586 01:08:44,466 --> 01:08:47,346 because I can figure out where the string ends just 1587 01:08:47,346 --> 01:08:48,696 by again iterating over it 1588 01:08:48,696 --> 01:08:51,076 or calling the already implemented sterling function. 1589 01:08:51,326 --> 01:08:52,006 But now I do this. 1590 01:08:52,276 --> 01:08:55,846 Now in my own program char star S 2 gets -- 1591 01:08:55,946 --> 01:08:59,586 get string, suppose a do type in the same word again. 1592 01:09:00,216 --> 01:09:01,816 On foo, well what happens? 1593 01:09:01,816 --> 01:09:04,656 Well, get string written by us allocates another chunk 1594 01:09:04,656 --> 01:09:09,086 of 4 bytes, F-O-O gets stored there, back slash zero. 1595 01:09:09,406 --> 01:09:10,566 I don't know where this is. 1596 01:09:10,596 --> 01:09:12,186 Like 0 X 456. 1597 01:09:12,186 --> 01:09:13,076 Who knows where it ends up. 1598 01:09:13,706 --> 01:09:16,506 Now what gets returned and stored in S 2. 1599 01:09:16,506 --> 01:09:20,296 S 2 is another pointer to a char, so this is called S 2. 1600 01:09:20,296 --> 01:09:21,226 And what goes in this box? 1601 01:09:22,686 --> 01:09:25,186 Yeah. So O X, what, 456. 1602 01:09:25,606 --> 01:09:29,676 So now, even if you're a little fuzzy today on what we mean 1603 01:09:29,676 --> 01:09:32,486 by pointers, even this line should make some sense. 1604 01:09:32,906 --> 01:09:34,906 If I then try to compare two strings 1605 01:09:35,226 --> 01:09:39,466 by comparing their variables' names, does X 1 equal equal S 2, 1606 01:09:39,916 --> 01:09:42,326 this is going to be false why? 1607 01:09:42,486 --> 01:09:46,126 Even though foo is clearly equal to foo. 1608 01:09:48,096 --> 01:09:49,056 Yeah, exactly. 1609 01:09:49,056 --> 01:09:52,056 S 1, S 2, I mean, clearly not the same. 1610 01:09:52,056 --> 01:09:54,066 You compare these for equality with equals equals, 1611 01:09:54,346 --> 01:09:55,586 you're going to get back false. 1612 01:09:56,046 --> 01:09:59,176 So that begs the question how do you compare two strings 1613 01:10:00,356 --> 01:10:01,296 for equality. 1614 01:10:01,406 --> 01:10:05,346 Well, right, the Y [Inaudible] would say call stir comp, 1615 01:10:05,346 --> 01:10:06,756 which is a function that's already been implemented 1616 01:10:06,756 --> 01:10:07,346 that does that. 1617 01:10:07,776 --> 01:10:09,176 But how would that be implemented? 1618 01:10:09,816 --> 01:10:13,226 Try to beat you to it that time. 1619 01:10:13,516 --> 01:10:15,216 Yeah, so really what we need to do, 1620 01:10:15,216 --> 01:10:18,456 if we want to compare two strings, is something more 1621 01:10:18,456 --> 01:10:24,406 like a comparison with this function here, stir comp, 1622 01:10:24,406 --> 01:10:25,956 which -- how is it implemented? 1623 01:10:26,716 --> 01:10:27,516 What -- how would you, 1624 01:10:27,516 --> 01:10:29,746 if you had to implement this function called stir comp, 1625 01:10:29,836 --> 01:10:31,846 because it's string comparison, but it's the concise way 1626 01:10:31,846 --> 01:10:34,266 of saying it, how do you compare two strings for equality. 1627 01:10:34,566 --> 01:10:36,576 Given the address of one and the address of another. 1628 01:10:38,396 --> 01:10:40,106 Probably just some kind of for loop. 1629 01:10:40,206 --> 01:10:42,456 Are they equal, are they equal, are they equal. 1630 01:10:42,456 --> 01:10:44,346 If you ever answer no, what do you return? 1631 01:10:45,546 --> 01:10:48,426 False. But if you then hit a null character, what do you do? 1632 01:10:48,456 --> 01:10:50,276 If you hit a null character at the same time, rather? 1633 01:10:51,086 --> 01:10:51,566 Return true. 1634 01:10:51,566 --> 01:10:54,026 All right, you can do this with a for loop, a while loop, 1635 01:10:54,266 --> 01:10:56,236 you can just check for that character within the loop 1636 01:10:56,406 --> 01:10:58,986 so this new and improved version is actually correct, 1637 01:10:58,986 --> 01:11:00,376 and I also did a sanity check. 1638 01:11:00,716 --> 01:11:02,476 So get string as we'll see 1639 01:11:02,476 --> 01:11:06,026 in its documentation can return this special sentinel value 1640 01:11:06,026 --> 01:11:08,016 null, which means something bad happened, 1641 01:11:08,316 --> 01:11:10,016 the user didn't actually type something 1642 01:11:10,226 --> 01:11:12,446 or the user types a special sequence of commands 1643 01:11:12,446 --> 01:11:15,006 that actually in many context could crash your program. 1644 01:11:15,316 --> 01:11:19,096 So get string does return this so-called sentinel value called 1645 01:11:19,096 --> 01:11:19,956 null, and all capped. 1646 01:11:20,456 --> 01:11:23,416 So what I actually need to do here, as we'll see as a matter 1647 01:11:23,416 --> 01:11:26,196 of best practice, is always check the return value 1648 01:11:26,196 --> 01:11:26,986 of a function like this. 1649 01:11:26,986 --> 01:11:29,296 And if it does not equal null, that is, 1650 01:11:29,296 --> 01:11:31,736 if there is actually a string there, okay, go ahead 1651 01:11:31,736 --> 01:11:34,966 and compare the two with -- oops -- go ahead and compare the two 1652 01:11:34,966 --> 01:11:36,556 with this function called stir comp 1653 01:11:37,026 --> 01:11:39,156 which actually returns a negative value, 1654 01:11:39,486 --> 01:11:41,596 a zero value, or a 1 value. 1655 01:11:42,346 --> 01:11:44,486 And you can determine with that if they type the same things. 1656 01:11:44,486 --> 01:11:46,366 What does get returned? 1657 01:11:46,846 --> 01:11:49,026 You can infer this now, using your deductive skills. 1658 01:11:49,306 --> 01:11:51,886 What gets returned by stir comp if two strings are equal? 1659 01:11:52,476 --> 01:11:55,506 Zero. And why might you want to return a negative value 1660 01:11:55,506 --> 01:11:56,646 versus a positive one. 1661 01:11:57,266 --> 01:12:00,606 If it's less than or greater than, i.e., 1662 01:12:00,606 --> 01:12:03,356 if it's alphabetically before it or alphabetically after it, 1663 01:12:03,356 --> 01:12:04,976 so it seems here we have a little building block 1664 01:12:04,976 --> 01:12:06,406 for sorting actual strings. 1665 01:12:06,916 --> 01:12:07,646 More on that Wednesday. 1666 01:12:07,956 --> 01:12:08,346 See you.