Week 2: Wednesday - CS50 2011 - Harvard University

CS50 · Intermediate ·⚡ Algorithms & Data Structures ·10y ago

Key Takeaways

Covers functions, global variables, parameters, return values, stack, frames, scope, arrays, strings, command-line arguments, and cryptography in C

Full Transcript

all right welcome back this is uh the end of week two in cs50 and this is an excessive amount of what's called asy Art uh people who have spent way too much of their free time actually sketching out most of the scenes from Star Wars entirely in uh their own asy uh character code so this is a bit of an that's a bit of an internet meme these days and goes around but we've linked to it on the course's website if you'd like to watch the whole film later um we thought we'd begin though not just with aski art but with something a little sexier than that that paints the picture for this week's and next week's problem domain that of cryptography and security more generally some of you might have seen this actual film before one of my favorite excerpts of which is this one is this one H that one too is this one here what's going on what are you doing to my daughter permit me to introduce the brilliant young plastic surgeon Dr Philip schlotkin the greatest nose job man in the entire universe and Beverly Hills your highness nose job I don't understand she's already had a nose job it was a sweet 16 present no it's not what you think it's much much worse if you do not give me the combination to the airshield Dr schlotkin will give your daughter back her old nose no where did you get that all right I'll tell I'll tell no daddy no you mustn't you're right my dear I'll miss your new nose but I will not tell them the combination no matter what very well Dr schlotkin do your worst my pleasure no wait wait wait I'll tell I'll tell I knew it would work all right give it to me the combination is one one one two two two three three three four four four five five five so the combination is 1 2 3 4 five that's the stupidest combination I ever heard in my life that's the kind of thing an idiot would have on his luggage thank you your highness what did you do I turned off the wall no you didn't you turned off the whole movie I must have pressed the wrong button well put it back on put yes sir let's go Arnold come Gretchen of course you know I'll still have to bill you for this well did it work where's the Kake it works sir we have the combination great now we can take every last breath of fresh air from planet druidia what's the combination 1 2 3 4 5 1 2 3 4 5 yes that's amazing I've got the same combination on my luggage prepare space ball one for immediate departure yes sir and change the combination on my luggage ah so if you'd like more of that that is a classic called Space Balls we have another little classic for you in a little bit um so you might laugh but odds are statistically some of you in this room has a password that's not all that dissimilar from 1 two 3 four five and some of you might even have Post-it notes back on your desk um so 1 2 3 4 5 is clearly insecure as a password one because it's just so easy to guess even you if you're trying to break into someone's account you might try simple things like that or the ever popular password password or something similar but in reality what systems typically do even if a password is weak like that they actually store computer systems things like this so if you've ever forgotten a password on a website or one of Harvard's passwords and you're told by some it person that they cannot in fact tell you your password but you can change it that's generally algorithmically correct for security purposes passwords are typically not stored in computers in so-called clear text but rather in Cipher text in some kind of encrypted fashion that looks mostly like random nonsense but the reality is that that is the result of applying some mathematical formulas to the original password 1 2 3 4 5 the output of which is something crazier looking the idea being if you see the crazy looking thing it's not all that easy if at all possible to figure out what the original password actually was so in short when you create an account on some new website Facebook Google any of these sites they're storing in a database your username and that's generally in the clear or your email address but then your password is encrypted but this seems to beg a pro beg a question the next time you log in time number two or three how in the world does Google or Facebook or Harver know that you've typed in the right username and password if they to no longer know what your password is it seems like once you've encrypted the password you're kind of screwed because you no longer remember what the new one is if this is all you're storing so what could you do what are some options okay so you could decrypt it so decrypting is just the opposite of encrypting the problem with decrypting is that if you're going to decrypt something like this on an automated fashion well that means that the web server or Harvard server itself needs to know how to decrypt it and generally encryption works by having some secret some secret password or special key that only the website's owner knows so if you wanted the website like Google or Facebook to automatically decrypt this and then compare your password well the implication is that then the website's password or key with which to do that decryption has to be stored somewhere in the server so this this then implies that if some bad guy breaks into the server not only can he or she steal the crazy looking stuff like this which is mostly useless but if they have access now to the server they can steal also whatever trick you're using to decrypt these things because that's got to be implemented in source code right whether it's C or some other language so it's really not helping you if you've actually encrypted these in that fashion yeah encrypt what you put in and then check it against what it has stored yeah that so that's a nice solution here so if the server is only remembering the cipher text and actually let me cl let me tweak my wording now though it's very similar in spirit to encryption a better word for this would be a hash value h a and a hash value is generally the result of encrypting something and essentially throwing away the key though the mathematics are a little different than that in other words when you take a hash of some input the result is some hash value and statistically it should be impossible to reverse that so it's one-way encryption if you will so that's okay though because if Facebook and Google are storing this as the uh as the um the king's password well that's fine because the next time the king logs into this website he types in his username he types in 1 2 3 4 5 hits enter but then all the website has to do is take another hash of that input that is Run 1 2 3 4 5 through the same algorithm the same mathematical formulas and if the output of that process matches the output of the original process well then you can assume that okay he must have typed in the exact same thing so this is why it people can't tell you your password but you can continue logging in they can't tell you it because this encryption is one way it's taking the so-called hash of the original input and this is for security purposes because again if means if some bad guy steals all of this from your server physically steals your server breaks in over the Internet takes your whole database they might have your usernames and your users's email addresses which is perhaps bad for privacy but at least they don't know your user passwords because those are at least encrypted and these days if you read in the mass media or see on CNN some story about some website being hacked the likes of Sony or the like where their users databases are stolen and you suddenly have to change your password that is often because these companies amazingly aren't even doing something simple like this there are numerous cases of companies actual legit companies storing users passwords in the clear just as 1 2 3 4 5 or whatever it is they typed in and then you're screwed if that database is actually compromised so toward semester's end when we introduce web program in my SQL and databases we'll talk about these kinds of issues because it's actually amazingly relatively easy to protect yourself against this so that's our segue today into security and now back to se so with problem set one if still tackling it know that office hours are broke tonight and if you decide to cash in a late day they'll be tomorrow as well in LOL know that if you've been attending office hours and have had issues with wireless and whatnot know that uh Harvard is actually installing more access points in all of these House dining halls for us over the next week or so so that we'll have more capacity for everyone as well as more cookies and the like also if you have any remaining questions with the appliance um there's definitely been some FAQs about like cursor kind of spinning or Windows not quite working um realize we have solutions to all of these problems so do reach out to us via help. cs50.net catch me right after lecture or email me directly in the worst case um if you're really pushing up against the deadline and then lastly um with the appliance 2 the only real challenging issues with the appliance is if you have a older computer 3 four five 6 years old or a fancy Netbook that's by Design very limited in Ram and CPU Cycles but we have a a new solution for that too for the next problem set and Beyond where you'll be able to connect to our servers using a very minimalist program on your computer not necessarily the appliance so we'll announce that once details are available so we should have solutions for all so here we are this little song last time which is kind of itself a little tedious to both recite and also implement but once you actually have the notion of say a Loop which we did you were able to implement this with as we saw like a four Loop so let me go back into this week's source code this was a file called uh beer one. C so following along at home this is in Source directory for lecture two and if I go into here beer one so what do we now how did we go about implementing this well we have int main void that's old hat at the very top here how many bottles of beer will there be and then get in so that just gets a number from the user then recall we had a bit of error checking just make sure the user's not messing with us and in this case we don't repeatedly re uh reprompt them for a number we just say h let's just yell at them sorry that makes no sense and return one and return one again is the notion like of an error code an exit code and then lastly the actual implementation of this song Simply happened down here sing the annoying song So for in I gets n so for if the user types in 99 start counting at 99 on each iteration subtract one from I and that's what iusus denotes the opposite of I ++ and then do this so long as I is greater than zero and on each iteration of this Loop print this four-line stanza and the only thing that's kind of interesting here is this one we have a placeholder for the integer D and we're plugging in I as you can see over here we have another placeholder that's identical it's just the English words have changed this is completely uninteresting because it's just a uh string constant string that gets spit out every time and the interesting aspect here is just this cuz the song again is 99 bottles of beer on the wall 99 bottles of beer take one down pass it around 98 bottles of beer on the wall so we need to somehow dynamically insert IUS one but we can do that very simply arithmetically here so IUS one so the only worry here you might have or should have is all right what's going to happen on at the corner cases a recurring theme in programming is you can get 98 cases perfectly right with your code but it doesn't really matter at the end of the day if you screww up the first case or the last case and by name those are typically called Corner cases and so as you start writing your own programs and you start testing your programs by typing in values well program like this if you type in five or six or seven or 97 odds are you're going to get the same fundamental Behavior but things get interesting if you choose those Corner cases type in one type in zero type in negative 1 type in 100 type in something distinct conceptually something that's close to any boundaries you've defined to actually see whether or not something breaks so in this version here is there any risk of my printing out negative one bottles of beer on the wall will this ever print out negative one bottles of beer on the wall in that last line of print F okay so no it won't and why what's the simple protection I've put in place yeah so I has to be greater than zero according to this right so as soon as I is not greater than zero it is zero this Loop's going to stop executing which means the value of I itself will never be zero inside of this Loop the very last iteration will have a value of I equals one and so that's safe because we'll say one bottle of beer one bottle of beer dot dot dot zero bottles of beer on the wall and we'll stop but of course if we had done something like this so I'll go ahead and change this to greater than or equals I'll save the file let me go down to my terminal window here into the source directory and I'll type type make beer one and now I'm going to go ahead and run beer 1 with let's say the value 99 enter well dramatic effect if we now scroll up to see what's actually there here we go there's the bug so now we've introduced the bug but we had it right the first time so again recurring theme especially before submitting your pet test these kinds of cases because the TFS are going to be looking for exactly these kinds of things we're not going to test your program with three and four and five and six because most likely those are all functionally equivalent it's the interesting the negative numbers the zero numbers the huge numbers that might ultimately be of particular uh opportunity for your code to break questions of any sorts yeah how exactly do you implement the return one how do you implement the return one and return one uh implement it in what sense like how do you use it to like jump back and get it good question so how do you use return one to get another in from the user in short you don't so this was a deliberate design decision in this program that I'm not going to use a while loop or for Loop or a do while loop to ask the user again and again if they don't give me what I ask for which is a non-zero number of bottles then I'm just going to quit immediately because it's not a fun song to sing but we could have done this with a do while loop like in the pets yeah so how do you use this number return zero uh return one so short answer we're not going to yet but starting next week we're going to introduce something called a debugger which is a separate tool from the compiler that actually lets you figure out what's going on inside of the computer and even lets you step through your code line by line by line and for that tool and others the return code is going to be useful for now it's the sort of thing just take it on faith because it will soon become useful so we now have beer 2 so we want to do something a little better here and introduce kind of a big topic that frankly you might see in a textbook but no one ever really says it in uh in person um which is that of hierarchical decomposition so what does this actually mean and who cares so let me scroll down now to actually let me go with let's go with beer 4. c yeah this is this is the one I want okay so in programming you'll often find yourself doing something a little repeatedly like if you yourself have been writing programs where you're kind of stealing code you wrote a few minutes ago on some other line and pasting it pasting it pasting it that's probably going to be an opportunity for hierarchical decomposition which just means write your own function so thus far we've been using main which we have to to write a program from the GetGo you've been using printf which someone else wrote You've been using get in which someone else wrote so you haven't really most likely written your own functions and yet this is actually relatively easy and it's not even new syntax we just kind of mimic the same syntax we've seen with get int and printf and Main so let's take a look at this version here so if I zoom in here notice at the very top of this file I have again the same code at the top how many bottles of beer will there be I get an INT from the user I quit immediately by returning one if they don't cooperate and then I have this two liner which is kind of interesting for a couple of reasons so one I'm have a while loop now why it's just a little different from a for loop I decided to do this aesthetically but what's interesting is I've got n minus minus we'll come back to that but more interestingly all of a sudden there's a chorus function that why apparently I could have been using all this time to print out the chorus that four-line stanza of this song it's as though I've now outsourced to a little black box called chorus that itself is a function that someone else wrote and that function's purpose in life is to sing this song for me so I don't have to write these lines myself now in reality someone did have to write those lines and in reality it was me and if you scroll down to the bottom of this file now notice the following so this is familiar syntax even though we've not used this too many times thus far the thing with the Stars that's just a comment slash star then some stuff then star slash that's a multi-line comment and that's just my note to myself sings about specified number of bottles then below that I have something that's similar syntactically but still a bit new conceptually I've got void and then the word chorus and then int B and then inside of this I've got a couple of new features I have this new syntax which will'll come to in a moment so let's ignore anything we don't quite understand yet and focus only on this well this is kind of interesting sing verses so what am I doing that's different here so I still have my percent D but what new format what format code is now obviously new so percent s so I'm actually fixing a couple of problems now and refining this code with a more sophisticated implementation percent D is still going to be the value of the number of bottles of beer percent s is going to be which of two words if even if you just take a guess it's going to be bottle or bottles so I'm fixing that grammar problem that I admitted to on Monday so we'll come back to how that's working in just a moment but B what happened to I well this is the fundamentally interesting aspect of actually writing your own functions notice that at the top of this function I've specified what kind of input this function called chorus takes and it's pretty obvious that it takes an INT and just because I'm going to be talking about bottles I decided that b is a reasonable name for the variable to give to the input to this function now notice how I'm using chorus if I go up here and actually let me simplify this just for a moment I'm going to change this code just for the moment to I minus minus and then this Clos brace here so notice on every iteration of this while loop if I start by typing in 99 for n what value apparently gets passed inside of parentheses to this function called chorus this is 99 right whatever values in N is what get handed to chorus as an input all right so now let me scroll down to the bottom here well just because chorus takes an INT doesn't mean it has to take an INT whose name is identical to what the original value was I can name it anything I want and I decided stylistically B makes sense because I'm talking about bottles so what's going to happen then is when I call the chorus function up in main by just writing chorus open parenthesis and closed parenthesis semicolon what's going to happen is that chorus is going to get executed and be handed as input that number 99 and it's going to get its own copy of 99 its own 32 bits its own four bytes somewhere in Ram and they're just going to be called B in the context of this function now what am I doing with B well let's scroll down to the print FS well I'm apparently plugging in for percent D the value B I'm plugging in for the value uh percent D the value B again and then in the very last line I'm plugging in for percent d minus1 so functionally this is equivalent all I've done is kind of outsourced now the singing of this song to someone other than Main and that someone is a new function called chorus so now what about S2 and S1 well let me rewrite something quickly as this if B equals equals 1 then I'm going to do this string one S2 I'm going to say S1 gets bottle else S1 gets bottles and then I'm going to do a quick copy paste here and actually let me clean this up I'll do this on the Fly S2 and I'm going to do S1 up here and I'm going to say if uh bottle equals 2 then I'm going to say S2 gets bottle bottles all right so what is going on here so first Let's ignore the goal and focus only on the syntax well what does it mean if I say string S1 in a program just translate that to English it okay not quite initialize but declare a variable of type string and call it S1 this is identical conceptually to doing something like int n semicolon that means declare an integer call it n and that's it because there's no equal sign don't do anything else with it yet now a string recall is just a word a phrase a sentence a paragraph it's some number characters so string S1 means okay prepare to get me a string and that string is going to be called S1 so what am I doing here well if the number of bottles passed in equals one I want this string to represent bottle in the singular El if B is anything else 2 3 four five whatever then I want it to be bottles so it seems like now I'm using just a branching condition to fix some grammar and then I actually have S2 down here but we'll see why in just a moment so let me scroll down down here and see what I'm doing so print F percent D so if I type in 99 that goes there if I type in 99 what's going to go here for percent s if what I'm putting in there is S1 botles right so again I'm just creating a variable on the Fly here string S1 and if B equals equals 1 make S1 be bottle in the singular El make S1 be bottles in the plural and so that's what gets plugged in there now y S2 I'm going to wave my hand at this detail just for now but it's simply because in the very last line of this song again I might need to change the pluralization right it might go from bottle to bottles because it might be one bottle to zero bottles or it might be two bottles to one b and so you need to have two different words one might be singular one might be plural or vice versa or they might both be plural so that's simply why I have S1 and S2 now in terms of uh conditions like we've done this before right if this else that and just so you've seen new syntax it turns out that syntactically these two lines at the very top are what we would call a very elegant oneline implementation of that same idea by no means strictly required doing it the way I did here with the indentation and whatnot is perfectly fine but let's just see what this is this is the only uh this is the only funky line of code we're going to see for a while that has multiple pieces of punctuation in the middle of it so what's going on here well let's do the first part on the left string S1 means give me a string call it S1 that's it the equal sign means put some value in there so the last question to ask ourselves is what value do you want to put there Well turns out that this expression right here is identical to this it's just a slightly more succinct dare say a prettier way of expressing that same idea what this means is that if B equals equals 1 the word after the question mark is going to get plopped into S1 else so this colon represents else now else bot in the plural is going to get plopped into S1 so in other words it collapses all five of these lines into one line that once you know the syntax it's just a little easier to swallow just a little easier to read but let me point out one thing I intentionally did this string S1 why if you think back to Monday did I not do this it's only if I declare a variable in this case a string inside of a condition that's pretty much equivalent recall to writing this even though the curly braces are not necessary if it's just one line but conceptually it's equivalent to this and what was the rule of thumb we discussed on Monday when it comes to variables scope they're only in scope they only exist inside of the confines of the most recent curly braces even if those curly braces have been omitted just cuz it's one line of code for convenience those variables only exist inside of those curly braces which means I'm kind of out of luck if I want to use S1 down here and so the solution is simply make sure that the strings are declared outside of those conditions so this again is a question of scope so in short we've solved a few problems here all at once so on the one hand with chorus we declared our own function it takes input and now I don't have to clutter up my main function if I have this well-defined task sing the chorus of a song that's a candidate for hierarchical decomposition it just means Factor It Out Create a little black box give it a user-friendly name like chorus Define it as taking some input like an integer call it whatever you want B and then it does something and the only last question to ask about the syntax here is what does it mean if chorus is prefixed with this word void so it yeah so it uh not so it does take input because the input is always defined between the parentheses so what's the opposite of input so output so this means chus does not have any outputs now this feels like a bit of a lie because clearly this song is going to have some kind of output what's it going to do well it's going to print a whole bunch of stuff to the screen based on these print F lines but this is a different type of output recall that you can print something to the screen but you can also hand the user back a value for instance what's a function you've been using for a week or more now now that returns some value so get ins right get int get string get double in those cases the function get int it doesn't just print it out on the screen and leave it for you the human to figure out what it was it returns it so to speak so that you can put it to the right of an equal sign so that you can assign its return value to some variable well same idea here chorus though is only purpose in life is to have these aesthetic side effects of printing something to the screen it doesn't actually hand the user back any value any sentence any string whatsoever it just prints and so its return type is void and we'll see this again and again in more clarity yeah oh so there is we just scrolled Beyond it so if I scroll back up recall that we began the story with main just as usual yeah if you declare a a variable in will it still be declared in another function really good question if you declare a variable in main will it be accessible to another function like chorus what do you think so no and again you can fall back on the same rule of thumb variables only exist when the confines of the curly braces so main has its own curly braces at the very start and the very end so any variables in there are not in fact accessible by a function like chorus and let me point out one other detail here before we can put to rest this uh singing song example there's one piece of new stuff at the top of this file so besides all of the comments up at the top of the file besides my use of include cs50.h and standard i.h there's this thing whose word is going to be called generally a function prototype well what does this mean so C is kind of stupid right it's an older language the compilers for it are fairly even though they've been updated over the years they were very simplistic in terms of their design early on and what is that mean it means that the compiler if you don't tell it it in advance that a function exists like chorus and it encounters that word somewhere in the program before it's actually seen your implementation of that function it's going to yell at you it's going to trigger some kind of error in other words let me do this I'm going to undo all of the changes I've done in this example just so we know I didn't screw it up and it's back in its pristine form and we'll come back another time to the syntax of doing the minus minus inside of the parentheses there I'm going to go up to the top here I'm going to expand my terminal window and I'm going to go ahead and compile this thing which again was Beer 4 so make beer 4 I'm going to go ahead and run Beer 4 and I'll type in oh just two bottles to keep it short and simple that seems to work no weird side effects so now let me break it let me accidentally delete this thing that we're calling a function prototype and just start typing Main and now notice if I scroll down further Main's there and chorus is still there so in theory the I have all the building blocks I need I've dragged all of my puzzle pieces to the stage but again C is not quite as smart as scratch C cares about the order in which you do things so if I now recompile this thing with make beer 4 enter a whole lot of stuff just broke and this is the most telling line and you might have seen this yourself over time implicit declaration a function in this case chorus has anyone seen a similarly sounding message do you remember what the solution was the past week include include include the header file right if you've ever seen this message thus far or you see this message in the future implicit Declaration of function just means you used a function in this case chorus but you didn't tell the compiler what it looks like what's its return value so to speak and what's its input what's its output and what's its input and you kind of did but you told the compiler it too late you put your function all the way at the bottom of the file so as soon as the compiler started reading your program top to bottom left to write it encountered this special new word chorus but you've never told it that there's a chorus function in existence before so it throws this error so just think intuitively what's the quickest fix for this perhaps and the answer is not function prototype yeah that sounds perfectly reasonable right so if the problem is I'm declaring chorus too late I'm teaching the compiler about it too late because I'm using it in Main all right well let's just relocate it to the top of my file so now chorus is at the top main is at the bottom let me go ahead and zoom in now and let's redo this make beer one uh make beer four when that actually did fix it so that is indeed a very reasonable solution but it's probably not the best because you can definitely once your programs get more complex you can definitely come up with scenarios where X has to call Y but y might call X so you might get into these possibly these circular relationships where it's just impossible to put one above the other logically and also it's kind of nice as a matter of good style to just always put main at the very top of your program because if you open a program that you wrote or someone else wrote for the very first time you don't care about a function called chorus or anything else you want to see what does this program do and the answer to that is almost always going to lie in Maine so ideally we want to leave chorus where it was below Maine but it turns out the simple solution then is just to tell the compiler about this function before or you actually implement it and you just can do this with a oneliner you specify what's its output in this case void what's its name chorus what's its input int B so in other words you literally copy and paste the first line or two of your function and just put a semicolon at the end you don't do open curly brace you don't start writing your function you just do this one liner and notice that is now identical to what's down here now why this this is just a matter of convention it is perfectly legitimate to write your functions all on one line like this but if you look back at the cs50 style guide you'll see that we discuss why this is actually useful long story short if you're using a text editor or like some kind of programming tool and you want to search where in your file you've actually implemented a function like chorus there are usually little tricks in the find dialogue to say start searching at the front of a line the start of a line so the fact that if you adopt this convention of putting the function name all the way to the left it just means you can find it more easily when your files get big but it's just a convenience nothing more than that all right so we'll come back to some of these syntactic features but any questions on the concept of writing your own function and this notion of declaring it with this so-called prototype yeah ah good question um why do you have to tell the compiler that it does or doesn't have an output can't you infer that from the code you could infer it some of the time but the problem is that if you just analyze a program a function that you've written you could have an if condition an else if and else if and it could actually return different things maybe not even at all and so the idea of proactively telling the compiler this will no matter what return this data type is a commitment you then make to adhering to certain conventions so in short it it improves the probability of correctness among other things any other questions all right so let's try to generalize this a little bit so we just wrote a function functions have return values return values are just is just the buzzword for output but we can run into problems with this again related to scope let's actually see a more concrete example where scope kind of breaks things for us with regard to these things called local variables so this is a buggy program this is buggy 3 and this is among the source code here uh in lectures two Source if I open up buggy 3 we'll see an attempt to actually swap two variables so let ignore the top of the file let's just look at Main as is generally most useful it looks like main declares an INT called X assigns it one another int called y assigns it to and then it prints out their values it then says printing sorry then says swapping dot dot dot then it calls a function called swap who takes two arguments so it's a little different syntactically but you just separate the arguments with commas then it claims on the screen to say swapped exclamation point and then it reprints X and Y so this program's pretty simple at least in terms of what we've learned thus far the only new thing is this use of apparently a function called swap which is not built in I wrote it elsewhere in the program so let's see if it works it's not going to so let's go into lectures to Source I'm going to go ahead and compile now make buggy 3 enter so compile is okay so that's promising now buggy 3 enter hm X is 1 Y is 2 swapping swapped X is 1 Y is 2 feels like this is definitely broken so let's see maybe I did something stupid like I left out the Prototype well no so that's there I did include the Prototype and I should know that I did this correctly because GCC did not yell at me with implicit Declaration of function so syntactically this program's right apparently swap returns nothing but it takes an INT takes another int and calls them A and B respectively so let's now scroll down and see how I implemented this well it's apparently just three lines of code so swap has no output it takes two inputs A and B each of them is an INT and now conceptually does this sound correct so it actually is so here's one gotcha first if you've got a value let's call it a and another value call it B how do you swap them well if you think about it you sort of visually you do this right but you can't quite do that in a computer because if you say a gets B and then b gets a well what value is in both A and B So it's b right order of operations if on the first line you put the value of b in a and then you put the value of a in B well that means that B's value whatever it is is now in both of those variables so what's the solution well you introduce we'll call a temporary variable now usually TMP would be a silly name for a variable but if it is a temporary variable it's quite reasonable here so the solution is to remember what a is by storing its value in an in then updating the value of a and putting in it the value of B and now at this point in the story what value is in a well the value of B what value is in temp the original value of a and so now we can put inside of B temp which is equivalent to a so we just need a third line of code now as an aside especially for those of you interested in hacker additions there actually is a way in C code to do this where you swap two variables simultaneously without using any temporary storage space it's kind of a nice magicians trick but more on that perhaps next week but for now this code feels correct right I've got a and b i put a in a temporary variable I change B I put b in a and then I put this guy here right so that logically feels correct and in fact at the very last line here where my cursor currently is a and b have yes been swapped but we just saw when I run this program that X and Y are not swapped even though I'm passing X and Y to this function so where do things break some yeah in back oh sure you it's okay so it's not assigning the answers back out of the function somehow okay so that's true and what other point can be made too here yeah values of X and Y that it's taking from the main function get messed up when they're passing on to the swap function okay so maybe the values X and Y are getting messed up in some way when being passed in so messed up isn't quite what I'd say but there is another uh there's a verb here that would apply they're being copied into the swap function so recall earlier and I said it briefly in our previous beer example that when you call a function and you just specify the input with a variable name you get the value but you get a copy of that value so at this moment in time when this program is executing there are now four variables actually five variables in existence in this program right now there's X and Y and those live inside of Maine there's also a and b and also temp TMP so five separate integers that's five separate chunks of 32 bits somewhere in the computer's memory and inside of X is the number one apparently if you think back to the how we started so inside of X is the number one inside of what other variable is also apparently the number one initially before swap executes so also the number one y has the value two as soon as we call swap B has the value to but then when you finish executing swap before it actually finishes is so if we get conceptually right to where my cursor is here before it's all done X is 1 Y is 2 a is two and B is one the problem is that the goal is to swap X and Y and all we've done is swap A and B so it seems to be a fundamental problem that when you pass inputs to a function you're actually passing copies of them in and the buzz word here is you're passing them by value now those of you with prior programming backgrounds know that in Java you actually don't run into this at least if you're using objects and we can fix this in C fast forwarding to a couple weeks from now we'll introduce the notion of pointers and low-level memory addresses but for now let's just assume we've run up against a wall right now when you have what are called local variables which X and Y R anytime you have a variable inside of a function it's called a local variable it's kind of for self-explanatory reasons it's local to that function that function cannot that variable cannot be accessed in some other function because A and B meanwhile we keep calling them arguments or parameters but they're also just local variables they exist only inside of swap so at this point then there's two variables in main there's three in Swap and those guys even though they might share some values they're copies of those values and we can actually see this as follows so this is a little picture that we might paint of a computer's memory so if you think about now your own computer you've got like a gigabyte of ram 2 gigabytes 4 gigabytes something like that let's just assume that your RAM looks like a rectangle and RAM is again 1 GB 2 4 gbes and bytes is the key word there if you have a total number of something you can you can number those things so this thing at the bottom left this might be bite number zero if I move my hand over a little that's bite one bite two bite three bite four then I go up to the next row that's bite five six seven and eight in short we could assign like a billion unique numbers to every little square portion of this picture if this whole rectang angle represents my computer's memory so what happens when you actually run a program well when you run a program what function gets executed by default it's just main right so main gets executed by default main might have some local variables where do they end up they end up at the very beginning of your computer's memory let's say this is a little bit of a simplification but they'll end up at the bottom left hand corner there inside of the uh the rows labeled main now main can take arguments thus far we've been writing in main void so right now there actually are no inputs to main but we'll get there Main's locals means all of Main's local variables might end up there but what if main calls a function like printf or get int or in this case swap where does it end up well where does Swap and all of its local variables end up one layer higher literally in Ram if something starts here the next function ends up here the next function's variables end up here and here and here and here and here so where we say FU and Foo incidentally is like a mathematician might say XYZ computer scientists say Foo bar baz quux and then there's some other crazy words it's just when you need a verbal placeholder foo's local variables end up on top of mains and guess what if Foo calls its own function where does it end up in memory here and here and here so again one of today's and next week's themes are security turns out that this is actually a brilliant way of hacking a computer if you have the ability to call a function that calls a function that calls a function that calls a fun function if you do this enough times you can actually start to change the contents of a computer's memory potentially in dangerous places and so if you've ever heard of a a word like a buffer overflow exploit or more generally a website being hacked to this day it is still incredibly common to hack into computers by passing them bigger strings or bigger numbers than they were expecting and what happens is those strings or numbers start filling up space in your computer's Ram at the bottom left but it gets so big that it overwrites something important and for today's purposes that's bad because if you overwrite something important you can actually trick the computer into executing almost anything you want but it derives from this problem here so just to hammer this home who cares about these rectangles and this depiction of memory pictorially now if you have X and Y and they live inside of Maine just graphically they are not accessible to Foo and vice versa because they're ending up in different locations in memory so let's actually go back here and try fixing this so I could fix this by introducing not a local variable but a global variable so let's scroll down here the only thing different now in this version of swap is that I'm actually going to sorry not of swap in this program I'm going to try to solve this problem in this way so let's scroll down here and let's simplify this rather than involve two variables X and Y and swap let's simplify let's instead change the story to a function called increment and increments purpose in life is just to increment a variable so let's do let me change this real fast let me break this and then we'll fix this so look at Main here I've got an in X gets one I then claim initialized because I've initialized it to One X is now one incrementing dot dot dot I call the increment function not even passing in a value here incremented and then I claim it's some new value so if I look now at increment and I try to do this will this work or not work so no and what's the short answer I'm trying to do x++ inside of increment but so it's a void function which means it has no output it doesn't return anything but more worrisomely what else is also buggy here yeah not the function exactly this x was not declared inside of increment it was declared inside of main which means you don't have the right to actually do Plus+ here and you can't even compile this if we run make on this it will just yell at us that X is not initialized because it's not in scope so how can we fix this well you know what rather than make X local let me try another little trick and scroll up here and let me actually declare my int outside of this whole program and if I declare the int X at the very top here here now there actually aren't curly braces anymore CU I'm outside the huge Mage file but is X do you think in scope or not in scope now with regard to the rest of this file and all of its functions so it actually is in scope so just as before where the Quick Fix was just copy and paste our whole function put it at the very top here too we can kind of fix this by just putting our variables at the very top of our program and now both Main and uh increment and any other function here can execute them all right is this a good thing bad thing in this case it actually solves the problem very reasonably and it gets the job done but what's maybe a downside of these things now called Global variables Global in the sense that they're not inside of functions they're inside of files uh someone how about over here any all right over here here we go so for example if you globalize X over there's function samei good yeah so if you start thinking ahead and granted this is a little hard to do when we're just implementing pennies thus far right now and similarly short programs realize that this is also a solution that doesn't really scale very well one before long we'll be writing more sophisticated programs that have more variables than just one and so again as a matter of good design if you just start plopping all of your variables at the top of your file as globals you totally defeat the purpose of trying to declare your variables as close as possible to where you actually use them which lends themselves to readability and it's just easier to understand what your program is doing if you do everything really only when you want to use something if you're just littering the top of your file with these Global variables long story short this does not scale well and in fact once you start using other people's code libraries or apis like I referred to a week or so ago things like even cs50's data apis for course catalog data and uh shuttle data and uh dining hall data and the like once you start using Code that other people have written my God what if you use a variable called X and that other person uses a variable called X right what if the person who implemented printf in a file called standard i.h and another file standard I.C what if he or she also decided that he or she needed a variable called X so he or she put X at the top of their file now you have collisions and this suggests that now you can't even use the variable X if you want to use print F so again long story short putting stuff at the very top of your file in terms of variables tends not to be the right solution so they exist and we'll see cases where Global variables are compelling but thus far this is not in fact the right solution well let's see if we can't now completely abuse some of these ideas and see what bad things can happen so I'm going to go ahead and save this as let's say bad. C and I'm going to go ahead and zoom in here and I'm going to do something like include let's say standard iio Doh and I'm going to have int main void and then here I'm going to do something I don't know what yet I'm going to then have a function called void um bad can be the same thing as the file um is it going to take any inputs um no not even going to take any inputs I'll say void but I could have a take input um and now here I'm going to say print F oh you know what I will have it take input let's have it take an integer n and what I'm going to have it print out is that value of n followed by a new line character with percent so all this function does and it doesn't seem all that bad thus far all it does is it prints out the value of its arguments so how do I call this well let's do uh int n gets let's say zero let's call bad of N and that's it so what will this program print when I run it so I think it will just print zero right quick super quick sanity check so if I do make bad oh my God so many mistakes all right good so when you see lots of mistakes just listen to everyone yell at yelling at you and fix it this way so with double quotes hopefully that's fixed now let's okay no what' I do wrong still yeah exactly I simply haven't declared bad so fix one could be move it to the top of the file but again better practice is leave main at the top and instead what do I type at the very top of the file void bad in the same thing but semicolon all right so now let's see if I fix this let me go bac

Original Description

Functions, continued. Global variables. Parameters. Return values. Stack. Frames. Scope. Arrays. Strings. Command-line arguments. Cryptography.
Watch on YouTube ↗ (saves to browser)
Sign in to unlock AI tutor explanation · ⚡30

Playlist

Uploads from CS50 · CS50 · 42 of 60

1 Hello, World: Hadi Partovi
Hello, World: Hadi Partovi
CS50
2 Content Distribution and Archival in a Digital Age
Content Distribution and Archival in a Digital Age
CS50
3 CS50 2014 - Week 1
CS50 2014 - Week 1
CS50
4 CS50 2014 - Week 3
CS50 2014 - Week 3
CS50
5 CS50 2014 - Week 0, continued
CS50 2014 - Week 0, continued
CS50
6 CS50 2014 - Week 4
CS50 2014 - Week 4
CS50
7 Week 3, continued
Week 3, continued
CS50
8 Quiz 0 Review
Quiz 0 Review
CS50
9 CS50 2014 - Week 3, continued
CS50 2014 - Week 3, continued
CS50
10 CS50 2014 - Week 7
CS50 2014 - Week 7
CS50
11 CS50 2014 - Week 7, continued
CS50 2014 - Week 7, continued
CS50
12 Breaking Through The (Google) Glass Ceiling by Christopher Bartholomew
Breaking Through The (Google) Glass Ceiling by Christopher Bartholomew
CS50
13 Introduction to Amazon Web Services by Leo Zhadanovsky
Introduction to Amazon Web Services by Leo Zhadanovsky
CS50
14 CS50 2014 - Week 9
CS50 2014 - Week 9
CS50
15 How to Build Innovative Technologies by Abby Fichtner
How to Build Innovative Technologies by Abby Fichtner
CS50
16 Light Your World (with Hue Bulbs) by Dan Bradley
Light Your World (with Hue Bulbs) by Dan Bradley
CS50
17 Building Dynamic Web Apps with Laravel by Eric Ouyang
Building Dynamic Web Apps with Laravel by Eric Ouyang
CS50
18 CS50 2014 - CS50 Lecture by Steve Ballmer
CS50 2014 - CS50 Lecture by Steve Ballmer
CS50
19 CS50 2014 - Week 10
CS50 2014 - Week 10
CS50
20 This is CS50 with Steve Ballmer?
This is CS50 with Steve Ballmer?
CS50
21 Meteor: a better way to build apps by Roger Zurawicki
Meteor: a better way to build apps by Roger Zurawicki
CS50
22 Data Analysis in R by Dustin Tran
Data Analysis in R by Dustin Tran
CS50
23 Data Visualization and D3 by David Chouinard
Data Visualization and D3 by David Chouinard
CS50
24 CS50 2014 - Week 6
CS50 2014 - Week 6
CS50
25 Build Tomorrow's Library by Jeffrey Licht
Build Tomorrow's Library by Jeffrey Licht
CS50
26 CS50 2014 - Week 9, continued
CS50 2014 - Week 9, continued
CS50
27 Essential Scale-Out Computing by James Cuff
Essential Scale-Out Computing by James Cuff
CS50
28 iOS App Development with Swift by Dan Armendariz
iOS App Development with Swift by Dan Armendariz
CS50
29 Sam Clark Leads Yale Students on Tour to CS50 at Harvard
Sam Clark Leads Yale Students on Tour to CS50 at Harvard
CS50
30 3D Modeling and Manufacture by Ansel Duff
3D Modeling and Manufacture by Ansel Duff
CS50
31 CS50 2014 - Week 5, continued
CS50 2014 - Week 5, continued
CS50
32 hello, world
hello, world
CS50
33 CS50 2014 - Deep Thoughts - Hash Table
CS50 2014 - Deep Thoughts - Hash Table
CS50
34 CS50 2014 - Deep Thoughts - Binary Tree
CS50 2014 - Deep Thoughts - Binary Tree
CS50
35 CS50 2014 - Deep Thoughts - Scratch
CS50 2014 - Deep Thoughts - Scratch
CS50
36 CS50 2014 - Deep Thoughts - MySQL
CS50 2014 - Deep Thoughts - MySQL
CS50
37 LaunchCode Visits CS50
LaunchCode Visits CS50
CS50
38 CS50 Live, Episode 100
CS50 Live, Episode 100
CS50
39 CS50 Field Trip to Google
CS50 Field Trip to Google
CS50
40 This is CS50 AP
This is CS50 AP
CS50
41 Week 4: Monday - CS50 2011 - Harvard University
Week 4: Monday - CS50 2011 - Harvard University
CS50
Week 2: Wednesday - CS50 2011 - Harvard University
Week 2: Wednesday - CS50 2011 - Harvard University
CS50
43 Week 1: Wednesday - CS50 2011 - Harvard University
Week 1: Wednesday - CS50 2011 - Harvard University
CS50
44 Week 11: Monday - CS50 2011 - Harvard University
Week 11: Monday - CS50 2011 - Harvard University
CS50
45 Week 3: Wednesday - CS50 2011 - Harvard University
Week 3: Wednesday - CS50 2011 - Harvard University
CS50
46 Week 12: Monday - CS50 2011 - Harvard University
Week 12: Monday - CS50 2011 - Harvard University
CS50
47 Week 1: Friday - CS50 2011 - Harvard University
Week 1: Friday - CS50 2011 - Harvard University
CS50
48 Week 3: Monday - CS50 2011 - Harvard University
Week 3: Monday - CS50 2011 - Harvard University
CS50
49 Week 10: Wednesday - CS50 2011 - Harvard University
Week 10: Wednesday - CS50 2011 - Harvard University
CS50
50 Week 2: Monday - CS50 2011 - Harvard University
Week 2: Monday - CS50 2011 - Harvard University
CS50
51 Week 9: Monday - CS50 2011 - Harvard University
Week 9: Monday - CS50 2011 - Harvard University
CS50
52 Week 7: Monday - CS50 2011 - Harvard University
Week 7: Monday - CS50 2011 - Harvard University
CS50
53 Week 5: Monday - CS50 2011 - Harvard University
Week 5: Monday - CS50 2011 - Harvard University
CS50
54 Week 5: Wednesday - CS50 2011 - Harvard University
Week 5: Wednesday - CS50 2011 - Harvard University
CS50
55 Week 7: Wednesday - CS50 2011 - Harvard University
Week 7: Wednesday - CS50 2011 - Harvard University
CS50
56 Week 8: Monday - CS50 2011 - Harvard University
Week 8: Monday - CS50 2011 - Harvard University
CS50
57 Week 9: Wednesday - CS50 2011 - Harvard University
Week 9: Wednesday - CS50 2011 - Harvard University
CS50
58 Week 8: Wednesday - CS50 2011 - Harvard University
Week 8: Wednesday - CS50 2011 - Harvard University
CS50
59 Week 10: Monday - CS50 2011 - Harvard University
Week 10: Monday - CS50 2011 - Harvard University
CS50
60 Week 2: Wednesday - CS50 2010 - Harvard University
Week 2: Wednesday - CS50 2010 - Harvard University
CS50

Related AI Lessons

Bloom Filters, Explained Properly
Learn how Bloom filters work and their benefits, including tiny memory and blazing speed, in exchange for potential false positives.
Dev.to · Daksh Gargas
Prefix Sums: The Preprocessing Trick That Makes Range Queries Instant
Learn how prefix sums enable instant range queries in arrays, boosting performance in various applications
Medium · Programming
I Thought I Was Ready for the Interview — Then One Simple Math Question Destroyed Me
A simple math question can destroy a developer's interview, highlighting the importance of being prepared for unexpected questions
Medium · Programming
Week 2(Day 10): LeetCode Two Pointers(slow & fast): Remove Duplicates from Sorted Array (Brute…
Learn to remove duplicates from a sorted array using the two pointers technique, improving from brute force to optimized solutions
Medium · Python
Up next
Stump Grinder Carbide Wheel Grinds Hardwood To Chips
Innoforge Studio
Watch →