 back to 105. Thank you for joining me again today. So today we get to talk about scope. What the hell does that even mean that sounds like? I don't know, I have like a pair of binoculars or a telescope or something like that. Let's see what the hell we're actually talking about today. So some terminology before we start, we were talking about function so if you want to sound like a pro I will tell you all of the terms to use to describe what happens when we use functions. So given what we had before at the end of the last lecture where we've used functions to implement that print triangle example, in our main we had something like we got some input through scanf and then we called this print triangle function that didn't return anything and took an integer argument as input. So if you want to sound like an expert what you would say is the main function calls print triangle. So we call them function calls whenever we kind of jump to it. So see what it's going to do it's going to copy the arguments to that for that function and then execution will suddenly jump there. So it's another way to just kind of jump around in the code and control what statements get executed when. So in this specific case what we would call that is main is the caller and then print triangle is the call e. Terms you won't get tested on but if you want to impress other professors with your programming language knowledge that is the proper terminology for that. So why do I say that? Well so I can hopefully explain things a bit better so explain or that the return statement that will stop the call e from executing and then the caller resumes from wherever it left off and if the function happened to return an int or have some type of output then the caller would get a copy of that return value whenever that function is done. So fun terminology to know. So title of the lecture today scope so scope is the part of the program where you can actually use a variable and it's actually valid to use. So typically while we can always use a variable so the variable declaration within the curly brackets so within the curly brackets that means we can use it from the beginning curly bracket until the matching curly bracket. So if we have multiple levels of them it's whatever one close the one we opened. So C will declare function arguments as part of the next set of curly brackets and also for loops so they will be declared in the next set of curly brackets coming up not the current one we are in. So what does that look like? So variables will always exist within a function so whenever we have something like this so we have main we would start our execution in main if we have a variable declaration int i equals 42 well then it's within a set of curly brackets and after we declare it we can use it until the ending curly bracket here so i would be valid to use on any of the lines I could return i if I wanted to I can use it part of printf I can use i at any point within the main function so at the bottom here I will draw out like all the variables that are currently valid and their value if and their values so to help you out execution would always start at main so I draw a little dotted green line with main titled here and then anything above this line those are variables that exist within main that I am currently allowed to access at this point of the program wherever that yellow arrow is pointing to so at that printf I'm allowed to use I I can go ahead and print it off in this case it'll print off the value of I is 42 and then on the return line I could use I if I chose to right now I didn't I just return zero which means a okay our program is good so questions about that should yeah all right so for loops how they work so if I start my execution at main again started with the same program or start with this start at the first line sorry I've in I equals 42 so right now there are currently no variables active because I haven't finished executing the line that would actually declare it so as soon as I execute this declaration statement then I'm allowed to use I so I can use I at any point in my program here everyone good all right so then I would have a four and then remember the for loop has like three components an initialization statement and then like the conditional expression and then the increment expression so this initialization statement the scope of this variable J J will be valid for within the next set of curly brackets so it will only be valid between this and this so we can only use J here so we have we can do printf J also I is still valid here so if we wanted to print off I and J we could do that if we want and then after we reach the end here so we're at the closing curly bracket for the for loop so if we go to the next statement here at the return well if we look over here J does not exist anymore so to go through that really quick again at the beginning we declared I so we create an I here lives in Maine then we have a for loop it declares J so if we move on to the next line we now have a J equal to zero and we can use it in the printf statement do something here and then on the return line on the next of curly bracket J no longer exists so just to make sure we can see what happens so here same program my for loop while it goes from J equals zero to J less than one so it should only execute once so if I run this I'll see J equals zero and then I equals 42 and I can go ahead and show that hey if I move this print statement out of here so if I tried to use J J is currently out of scope and if I tried to compile that I'll get some error message that the same thing is like if I tried to if I tried to use it before I declare it so C is not that smart but it just tells us a generic error message of this variable does not exist so if you just came across that randomly it might not make any sense so why it doesn't exist is because how we say it is it's not in scope so so we can go ahead delete that but if I wanted to you know I could move I into the loop no problem because I exist for the entire lifetime of Maine so questions about any questions about that yep yeah so the question is can I just create some old random mole curly braces anywhere and the answer to that is yes and it declares a new scope so if I wanted to perfectly valid to just say new set of curly braces and I could have it J again equals to four and I can print off J here if I go ahead and do that then I see J is four so that's this J and then J no longer exists at this point then we have a for loop that declares another J and then that J is valid here and then J no longer exists here so I'm allowed to have the same name and this is actually its own scope so if I tried to do a print F at the end of this curly bracket well I should get the message that undeclared use of identifier J J does not exist because it is not within scope so it disappears as soon as we hit here so if you want to you could it's a bit weird to just write curly brackets kind of willy nearly but if you want to you can it might have some applications depending on some other programs yeah and I have a discord question which I will go over next all right so any other questions for this or shall I answer the discord question so the discord question is essentially what could I do something like this so I'll just rename the variable in the loop I so let's see I can compile that see compiler doesn't doesn't give me any problems what would I expect to happen if I actually run this program any guesses yep yeah two outputs for I and what will the value be for I for both of them first and second 0 and 42 0 and 42 so there's two plausible answers here so it could be at this point it's like what I are you talking about it could be this I which should be 0 or this I would be 42 so it's either going to be I is 42 and then here the loop I doesn't exist so this will always be 42 so I'll either see 42 42 or the or 0 and 42 so spoiler alert I will see 0 and 42 so if I run that 0 and 42 and this illustrates the problem because it might be a bit confusing and also having two variables that are probably doing two different things name the exact same thing probably something you should never do so in this case good thing I prepared for it so what that is called is it has a term and it's very ill-advised that term is called shadowing so you can shadow a variable with the same name so here is that same example on the slide where all I did is change the loop variable from J to I and we'll start off executing at main so if I keeping track of my variables here I declare in I equals 42 and there is that's my variable that currently exists then I'm on this line so my for loop in I equals 0 and that would be my initialization stage so I would check the condition 0 is less than 1 great so it would go into the body of the loop and I would be valid so in this case I is 0 and the inner I is valid here so C will always use the most recent declaration of variables that have the same name so in this case inside the loop the most recent declaration of I is this I here that was declared in the loop so it would print I 0 which is what we saw and then at the end of the loop well this I that loop I no longer exists anymore and then I just have a return here and I could return I I would be 42 questions about that yep yeah question is there a way to access the outer I in there and the answer to that is come up with a different name so no easy way to access it yep yeah so that's why in here it should be a different name than the outer one as long as I want to access it yeah so in general it's just really confusing to have variables that like shadow each other so same name that has different values so hot tip for the day is do not name variables the same name otherwise you might confuse yourself and confuse other people reading your code so think about having to remember that rule and then coming back to a piece of code in like four months time and then you're like wait how the hell does this work crap I have to watch that lecture again that's no good so any other questions okay so and then here's that other example so yeah a set of curly brackets that declares a new inner scope by itself so same thing again start executing at main we have this declaration for I so we'd create a variable I set it to 42 and then we have a set of curly brackets here so I would be valid the entire time now we're within a new set of curly brackets we declare in J so after we execute this declaration we create a variable called J it's equal to zero and we can use it on this line here until the ending curly bracket and then we can't use it after that so after this line J goes away and then at the return statement the only variable we can use is I so any questions about that alright so other rules so the reason why I drew like main and the line is that each function has its own scope so you can't use variables in other functions so how does that look let's have a little program here and see what it does so the purpose of this program is it asks the user to input two characters I'll go into why I have spaces there in a bit so we just get two characters from the user and then the whole purpose of the program is it's gonna spit back out to the user whatever characters are digits if it's not a digit it's not going to show you anything so I wrote this function called is digit that takes a character as input and then returns a Boolean and because I named it correctly it's called is digit so it should return true if the character is a digit and false if the character is not a digit so there's a lot of ways to write this I could just you know generally if I could write it like if this whole thing returned true else return false you could do that but that's a lot of code and generally people or at least experienced programmers will kind of make fun of you if you do that so if you already know the expression and it's a Boolean you can just return it directly and it will return true or false because essentially you'd be writing if true return true if else return false so makes more sense to just return true or false so in this case to check if it's a digit we remember our ASCII so if C is greater equal to the character zero and they'll all be sequential up till nine and the character is less than or equal to the character nine so that's the last digit then it is a digit so here's how so everyone understand the program before I actually fake execute it good so let's fake execute it so I start here at main where I declare characters C1 and C2 my creative juices were flowing so here after that line main now has a variable called C1 and I didn't initialize it to any value so I'll put a question mark there that says I don't know what the hell the value currently is same for C2 then I would execute the line print F input to characters so that would show in my terminal and then here I'm at scan F and ignore that thing at the top I messed up so we would have a scan F and it would wait for us to input to characters after we do it prints digits then here it would do oh if is digit C1 so it would evaluate this so we make a function call to is digit and the argument is C1 so remember last lecture we talked about call or call by value or pass by value so this function will get a copy of C1 and it will be usable in this function as C so what does that look like so here that's why I draw a line here so I have my is digit function and above this green line is our variables we can access in the is digit function so it would this argument would be a copy of in this case C1 so be the value of C1 because it's passed by value so we would initialize its argument C as just the value of C1 in this case so it is equal to the character why I'm assuming I inputted the character why and then to so questions about that okay so in this function now C is equal to why so C is equal to why is this going to be true or false hopefully false right so why is not a digit if you run this and these it says why is a digit you need to rewrite it in this case it will go ahead and while this will be true because if we remember the ASCII ordering the letters are above digits so this will be true but in order for everything to be true both sides need to be true because of the ampersands so why is not less than or equal to a 9 so this would be false which would make the whole thing false so it would return false so this would evaluate to false so if it's if false we just skip to the end so execution would just skip to the end there we wouldn't go inside the if statement we wouldn't execute anything so everyone good and if I didn't indent curly brackets I did not meant mean to all right so now we are reusing the same function again so now we have the next if statement so we have now is digit with C2 so we're doing another function call so this time we're going to call is digit and it's going to get a copy of the value of C2 so for the function call to is digit C will be a copy of the value for C2 so in this case we're going to run the same function again but now with a different input so now the input is the character 2 so is that a digit are we awake all right I see one thumbs up all right hopefully it's a digit we got lots of thumbs up all right good so in this case it's a digit so this will be true so if we have if true then we will execute the next line and when we come back from a function that functions done so all of its variables go away so they all go away and now we have print f so we're in the if statement and we would just print off the character in this case to finish and then print off a new line and then we're done our program so any questions about that program right we're more or less good in that case I am going to show you some warnings of why so here's that program again except I just initialize things so yeah before I start actually breaking things any questions about the program as we've written it minus that line I just commented out so just to see that it does work we got is digit if I input why and then to I see that the digits I entered I just entered it to and yeah I have a question about spaces I'm going to go into spaces so are we all good with the program before we get the scan f weirdness that I have to warn you about because I'm contractually obligated to yeah yeah so that's what I'm gonna get into it's okay besides the space is there any questions because I'm gonna go into the space stuff and it's gonna get real stupid okay so so the program works right I'd print let's say I did to one hey I inputted the digits to one so here I have my print f so you'll notice here in the format specifier I have no space and then a character and then space and then a character so if I run this again and it says input two characters and I type space why space to I would hopefully expect that C1 is still why and C2 is two but if I run it I see C1 looks like nothing but remember all of these characters are asking coded so they just correspond to some magical number that someone came up with so in the brackets I just print off the number as well so it's just C1 both times but I print as a character and then I printed as a digit so it says 32 turns out 32 is a magical number for a space so it actually just captured a space so if you don't have a space before it the rule is that if you actually type a literal space it will match a literal space if you put a space before this capital or the format specifier for C it will ignore any spaces however many spaces you type up until a non-white space character and then it will actually match with that character so in this case here I put a space between both of them and it behaves as I expect so here space space space why space space space space to and oops I didn't recompile it I bet alright space space space space why space space space to and see this time now I get why and to which is what I expected so if I also mistakenly did no spaces between everything for characters oh god so with if you do something like this so there's no spaces between characters and you do is did and you run this program and I do space space space why to it matches two spaces because well it just literally just takes the next character you input whether it's a space or not so this rule is fairly stupid so if you just want to get a character just remember to always put a space before it unless you want to literally have a space as input which you probably don't want so just remember scan f is weird put a space before a percent sign character if you want you can do it before percent sign d it won't really matter but definitely before character otherwise it will match a space and bad things will happen that's my warning to you so questions about that you should have questions because it's stupid all right so just so you have it also on the slides so I even put a slide but where it's strange so here I don't have a space before the first format specifier so if my input was literally space capital A space capital B then C1 is the space character and then it would have ignored anything else if I type more spaces because I had this space and then it would match the A if I write no spaces between them like I just showed you and my input was like two spaces and then a space B then both C1 and C2 are going to be literal space characters so unless you really want to capture space characters I even put in bold for you always put the space before the percent sign C and never put the space after the format specifier because it gets even weirder if you do that so if I put a space after what happens when I compile and run this is let's say I input two digits or two characters why and then two and then hit enter and it will sit here and wait forever what the hell I put in two digits you stupid scan F piece of crap what are you doing so turns out if you put a space at the end for some I'm because this isn't really supposed to be for user input it waits until you type just some gibberish and then press enter and then it'll go so do not put a space at the end bad things will happen so I even put so this is from the real documentation if you look up how to use scan F it literally says it is very difficult to use these functions correctly and because you have to remember weird esoteric rules like that so don't worry whenever you start programming for real you'll probably not use scan F I have never used scan F before yeah so the question is you want to do you want to do space like this is my format specifier okay three characters without a space so I run it and do like ABC so it should it'll just match the first two characters so C1 will be a C2 will be B and then the other one gets ignored and let's see if I'm right yeah so C1 is a C2 is B other one just gets ignored so it will ignore stuff it needs other rules all right so don't be discouraged by scan F being weird it's like some weird thing that I don't know so just remember these rules if you have percent sign C put a space before that never put a space after it otherwise really bad things will happen so and yeah this is just for scan F for print F doesn't have that issues because it's not taking a user input or matching it's just replacing stuff so no problems with print F print F's cool just scan F scan F's bad so just in case so I've seen this come on up on exams and part of it is they don't really use it like this but you should know maybe just in case a comma is actually like if it's in an expression it's technically an operator that evaluates the left hand side so it will execute anything it needs to do to compute the result and then it throws the result away and then it evaluates the right hand side and then the final result of the expression is whatever the final result of the right hand side is generally you never use the result anyway so you don't really have to ever know that rule if someone starts using commas and expressions you should probably shoot them okay maybe a bit too extreme all right but you may see things like this on exam so like a for loop where it declares two variables as part of the initialization so it puts a comma between them and declares an int x equals 0 and a y equals 10 and then my conditional expression is just y is less than or x is less than y and then here for my increment step I'm both incrementing and decrementing two different variables so it decrements x and it increments y and this case this would loop forever it should be the other way around but you can do two things at part of the increment if you have two variables generally it's kind of weird if you do this but I've seen it on exams so just be aware of that all right any questions about that before I pose another one yeah yeah so this is a statement yeah so you like you can write this whole thing as a statement I could move that up and write it as a statement oh so this is a statement so this means like I could so this comma is not part of an expression so it doesn't follow the operator rules technically in compiler it's not an expression it's part yeah because why has to be a name so yeah but that's like compiler rules and stuff so yeah so what do I mean by it throws away the results so in this case in this increment step we we like don't even care about the final result of this because it just executed doesn't check the value or anything but if we really wanted to remember this is the post fix one so let's assume I is equal to zero minus minus or sorry x is equal to zero minus minus x well that will decrease the value of x by one so in this case it would be negative one and then that's the value that's the final result of minus minus x so that gets thrown away and then we do plus plus y so y would go from 10 to 11 and the result of that is an 11 so the result of this expression would be 11 but in a for loop like that it doesn't use the result of the expression anyways yeah yeah x still gets updated yeah yeah so we don't in the for loops and everything this increment thing we don't care about the result we care about whatever however we change the variable right so we're just trying to change x and yeah so these both get initialized so this in for loop remember this is my initialization statement so this will always run so these two variables will exist and then it will check this expression and then do the body of the loop I don't have one here and then at the end of the body it would go ahead do this operation and then go ahead check again go and do loop stuff all right then I have a good question for you so I will give you this program and give you a minute so I'm trying to write a function that swaps two variables so here I will take an input a and b and I'll give no output because I want this function to just swap two values so here I'll create an integer called temp because I want to swap them around if I just did a equals b and b equals a well what that would what that would happen is they would both be the value of whatever b was because I just assign say like a is one and b is two then I would have a equals b so a equals two and then I would have b equals a well I just change a to two so I would have b and a both be equal to two so in order to actually swap them around I need to create a new variable to hold the the old a what while I switch it to a different value so I declare int temp equals a and then I set a equals to b so in this case if a is one and b is two a is equal to two and I set b equals to temp which would be one so I swap the two values around so that is my function and in main I have it a equals one b equals two and then print f I'll just print off the values of a and b then I will do the function call swap and then I will print the values of a and b after the swap so yep yeah so his thought is so this line happens first so I would see main before swap a is one b is two everyone should agree on that right then I call swap so I call swap a is one b is two then I go ahead swap the values around now a is one b is or sorry a is two b is one so I would print off swap a to be one then I come back here and you're saying a is one and then b is two why is that yeah we're calling a different function and it's copied by value remember so if I let's go ahead and run it just to make sure we are not crazy so here is our swap program if I run that here's what I see so I see main before swap a is one b is two swap a is two b is one and then in main after the swap a is one and b is two so why is that well execution would start at main so in main main would have an a main would have a b and then we print off the two values we haven't changed them and then when we do this function call for swap well we copy the value of a and b and then go to the swap function so in the swap function it also has a variable named a it also has a variable named b and their values are copies of mains a and b but aside from that aside from having the same values initially they're completely different so in swap a would be equal to one b would be equal to two and they are now in a new function so it is swaps a and swaps b no relation to mains a and mains b so we declare a new variable temp that only exists in swap set it equal to a which is currently one then set swaps a equal to two then set swaps b equal to one and then we'd print off the swap values and then well in this case we don't return a thing so this function just poofs we're done and we would return back to whoever called it and in this case it was main so it would just print off main after swap and then we have mains a and mains b which remain unaffected because doesn't matter questions about that yep how would I go about actually making this work hmm well this also remember scan f sets values for stuff what do I have to do in scan f so if I want like scan f to set the value of int a what do I have to give as an argument to scan f just a or yeah yeah it's the memory address of a right where I did like the amperset you we always do the ampersand to scan f oh yeah so he said some fancy words that actually aren't in C so C references aren't a thing technically they don't exist but yeah you said the magic word pointer which we don't really know what a pointer is yet so we'll learn how to do that in the next lecture but before we do that I'll show you one way to swap them around without having to use an ampersand and it is wholly unadvised but it's fun oops so one way I can do it is I can create something called a global variable which is like a whole brand new scope so the great thing about global variables is you can access them in every function it's the only thing that kind of breaks those rules so a global variable is always in scope below its declaration so they're created they're actually created before main even runs and your operating system is responsible for that so they're not advised for this course you should avoid using them nothing you write is actually that complicated but if you absolutely have to make a global declare them with a static in front of that and you don't have to know what that means it basically makes it so you can't accidentally use it in another C file so if I'm telling you to do something stupid I should at least tell you the responsible version of it so don't worry about what that actually does but what I have now is I can fix that swap by actually making the variables global so here at the top so global variables are don't live in any function so I put them at the very top and I can use them all the way to the bottom I saw some people grab their laptops like they thought of some assignment solution do not use this so in this case though here I have the same swap so I didn't change swap at all but now this a I change the argument to be void because I don't need any inputs because I can already access a I don't need to access this functions a I'll just access the global variable a so now I can swap them around like this so I cut off some of the program so if I go back and I run it here's the global version so if I run the global version swap global then the values actually get swapped because they exist the entire time so here before main well these variables already exist they would have been set a is equal to one b is equal to two so if I have my print line here it would print off a is one b is two then I call swap and notice it didn't have to declare a and b because they're already global swaps them around so now a is one b is one and now back in main well a and b refer to the same thing there's still the global a and b and I changed the value of them in a different function so that is why it is especially not advised in this course to use them because any old function can just change the values and you may end up really really really really really really confusing yourself so for this course there are times where global variables are necessary and appropriate but you have to be writing more complicated programs than we're doing in this course so use responsibly all right uh so just as let me make sure that I'm good so yeah now we've covered functions so again just to prep you so we've completed chapter five of the online book so you should be able to try all the exercises well their past midterm questions so the course can a coordinator wrote it so try them also you can discuss them in discord or if you have any questions about them we'll be doing midterm review unfortunately sooner rather than later so start asking now and pile up your questions and get them answered or if I need to go more in depth I can take lecture time to answer them uh just so you know there's past midterm exams just listed directly on the corpus just in case you're lazy there's a link for it too and again ask questions in discord and all that stuff so to prepare you for next lecture this is what the swap function actually looks like to actually swap things so just by reading main I see that I use the ampersand a and ampersand b in order just like I did with scan f and let's just go to the code so I'll be spending next lecture explaining this thing so here it is I have a in main and a b in main and then I have main before swap I do swap and then I'll print it off after the swap so if I run that it actually swaps the values around because well remember the ampersand a is like the memory address of a so swap is doing some funky things by accessing the memory address of a it's allowed to change the value at that address and it's doing some funky things with that so the actual implementation of it remember I showed you I said there's a star character don't worry about it while the star and the type is going to start coming up now so this is the actual implementation of swap I will not explain it until the next lecture so just remember pulling for you we're all in this together