 Welcome back to 105. Thank you for joining me here today. So today we get to talk about functions. So when we actually write real programs, we just don't stuff everything in main, because, well, that's all we have taught you so far. So today you get to break out of main. So typically when we write more complicated programs, we break it into pieces that are easier to understand. Hopefully they're reusable. So you can imagine something like, well, printf, that is probably something that's really common to do, like printing some characters to your terminal. So someone decided to just write a function and share it with everyone so everyone can use that function. Instead of starting this course with having to talk about how to actually print characters to your terminal without any help. So also makes your code a lot easier to read if you can break it down into more understandable pieces and you just don't have everything cluttering up main. So how we define a function is we have to use the curly brackets after the prototype. So before we briefly talked about the function prototype and what that tells you. So remember function prototype, that tells you all of the inputs to the function with their types in this course should be there be like int, double, char or bool. So we can have multiple inputs, we can give them a name and they will all be of some type. And then also in that function prototype is the type of the output. Again, int, double, char or bool for the purposes of this course. And if we name an argument before we only saw the prototype well if you name the argument you can actually use it in your function. So for example, this is our prototype. So I would have like a function called add to that takes a single input which is an integer which it names x and then it returns an integer. And before we just had a semi colon at the end of that and that was the end of the function prototype. If we want to define the function so we want to actually tell C what to do when someone actually calls this function we just use curly brackets. And it just kind of looks like if we had like a for loop or while loop or an if statement or something like that. And then within the curly brackets we can put in whatever C statements we want. So the only thing special like main there's a special return statement and return will return a value and then end execution of that function. So for example, I can create a function that takes add to takes an integer x and then it returns that value plus two. So it's important to name these things. So if I use something function called add to I expect it to just add two to the number. If I returned x plus two and I named it add four I would probably question my sanity. So should name them something that is actually appropriate. So there are some rules when actually defining these functions. So the order actually matters. So the compiler reads your program like how you normally read things. So from top to bottom but whenever we run our code well it doesn't start from the top and go to the bottom it starts executing at the main function. So always remember the difference between the two for this course your compiler is going to go top from bottom whenever you run it it's going to always start at main. So because the compiler reads top to bottom your function definition or a function prototype has to come before you use it otherwise C has no idea what you are talking about. So for example, let's say I create that function called add to. So you just put it anywhere you want so it's not within main so it's just a new line by itself so I can call it int add to int x and then return x plus two. So now if I save that and compile it well probably some bad things are going to happen. So I compiled it, oops, let me get rid of that. So I'll show the first error. So let's say in my main function I just did print f and then I called a function called add to that doesn't exist yet so I'm just going to give it four as a value and then hopefully I get six as a result. So if I try to compile this you might have seen this error before in lab one but this is what it means. So you could try and compile it. It says it failed to create it and then it says undefined reference to add to. So that means you have told C you've tried to use a function called add to and C doesn't know where it is. So you might have encountered this if you tried to use like a math function and you didn't actually link the math library you probably got this error. That's because without that like dash LM flag C can't find that math function you were using. So it's just going to refuse to compile cause it doesn't know what the hell you're talking about doesn't know where it is. So I could define it something like this. So let's say for some reason I put it at the end of main. So your compiler should also get confused about this because it will read it from top to bottom as well. So your compiler will, you know read this standard out or IO.h put all of its contents here do whatever it needs to do with that same thing for standard lib then it would go C int main okay this is the main function and then oh you use a function called add to and I don't know what that is yet because I've never seen it before I haven't seen the prototype I don't know what it is. So even though it's kind of frustrating cause it's like it's right there just read a little bit more what the hell is wrong with you? Well, C was developed in the 70s and it having to go through your code twice or like go backwards that was just way too slow so this is why this rule exists. So if I compile it now give me a slightly different warning but essentially means the same thing it says implicit again implicit means I didn't write it myself so it says implicit declaration of add to is invalid that's a very bad error message for you so implicit declaration means C just guessed a declaration for a function called add to so it just made it up because at that point wherever I tried to use it I did not declare or provide a prototype for a function called add to so this just means it has no idea what the hell you are talking about even though that it is right here so one fix to this problem is well I can just move it so if C reads top to bottom I'll just make sure that add to comes before main and now if I compile this hey C doesn't complain at me it actually likes me now that's great so now when I run this so when I run this my result now is going to be six because well the compiler is going to know what add to is it's this function and then whatever it starts running it will run main and then knows okay I need to print F something what do I need to print F so I need to figure out the value of this so to figure out the value of a function call it's whatever that function returns so to figure it out so I'll do add to and then we call it pass it or give it the argument X or no give it the argument four so I'm just giving it a four and then this is just my VS code extension that tells me that it's named X so in this case well add to will run and X is equal to four so if X is equal to four then X plus two is equal to six so that is equal yeah that's equal to six so then we'd return the value six so the result of this function is six so that's why we see result equals six there and then question in the discord chat can we have functions inside main and no you can't C should complain very loudly at you so we can try it so C will even tell you function definition is not allowed here so that means you are not allowed to write functions within functions so functions just have to be by themselves so do do do do all right any other questions about that one all right T so whoops so here's what we did we put it after and we got that warning says C doesn't know what we're talking about because C will read top to bottom so that is what the previous message mean implicit declaration like I said you didn't declare or provide a function prototype and that ugly thing here so this W implicit function declaration that's not part of what C is trying to tell you that's actually just a compiler flag for this warning that if you were using the compiler yourself you could go ahead and ignore it if you really wanted to but that's a bad idea it's just a compiler giving you too much information then we have another question can we put void as a return type and of course we can so for functions we are allowed to in this case if I change attitude of void well I'm going to have a problem how I use it right now because void remember that means the function doesn't output anything so C is going to be very very angry with me for at least two reasons so we can see how bad these compiler warnings are so first one says on line five so this line it says void function so that means if I have a void function the function doesn't return anything it gives no output right so this says the void function return two should not return a value so that's saying here I'm trying to return the value six which is an integer and it's saying well it's a void function it's not supposed to output anything what are you doing so if I wanted to write a void function then I could just have return by itself if I have return by itself that means stop executing the function right now if I wanted to I could get rid of the return and then C will put a return at the very end as the last statement there for you the other complaint it gives is that argument of type void is incomplete wow that's a bad warning so that basically just means that here I'm supposed to get like an int a double, a bool, a char or something that actually exists void represents nothing so it has to be a value of something it can't be nothing and the result of this function is a nothing so it doesn't make any sense and it should tell you that well this void function doesn't return a value so you can't use it as an argument to print f wow these compiler warnings are bad for beginners all right any other questions with that I fixed it again all righty so yeah this was my first option I just moved that function before main and then my compiler will go ahead and read add to before it encounters main the other option I have is to essentially do that thing like just write the prototype ahead of time which is essentially what is in all of those like header files so remember for like math.h if you wanted to you could get rid of it and just do like double square root double if you really want and provide your own prototype so if I wanted to say for whatever reason I really liked I really liked add to coming after main but I want to tell C that hey there's going to be a function called add to I'm going to tell you what it does later trust me about that so I will tell you its inputs and its outputs and then trust me bro I will define it later so for that we can just put a function prototype that matches the function before main so here the function prototype would just be add to int x and then a semi colon so here this remember function prototype so I'm saying the function's called add to it takes an int I called it x didn't need to put that there and then it returns an in and then later I can go on and define it so now when I compile this C also gives me the green light because now when it reads it from top to bottom well it will see okay C will know there's I should know that there is a function called add to takes an int returns an in and then by the time I use it here well it already knows what it should do so it's pleased with me now and it will go ahead and figure out that oh okay that's something I'll figure out how to call that later but I know it's something that actually exists and then here that's where I actually define it nothing really changed with that so if I compile and run that no problems whatsoever so questions about that alright and here didn't really like this is a function prototype if I wanted to I didn't really even have to name it if I want wanted I could just say oops I could just leave it unnamed because at that point it's optional but here if I didn't give it a name well then I actually can't use the argument that's passed into me because I don't know what the hell it's called so here this four that gets passed in I can't access it anymore without a name I need to call the argument something in order to access it so I was called x I could have called it whatever I want and yeah the question is do I need to repeat the types in the prototype and yes it needs to match exactly or else really bad and interesting things may happen so if for example I did something like this where I've messed it up the compiler actually tells me conflicting types for add to so it's saying okay and how that works is it would read okay add to takes a double and then returns an int and that's a function that you tell me is going to exist and then you have a function called add to and then it takes an int and returns an int and sees like not nope that's not that doesn't make any sense that's not going to happen so not allowed to do that and same thing if you just do add to without brackets or well that one works okay great thanks see so that one will work and see we'll just kind of guess so that one will work to see we'll just guess it's type based off what you pass to it turns out it doesn't actually matter for see for input types because there's a defined way the C compiler does it but please do not do that that is very confusing because remember I talked about function declaration verse prototype you have these complicit and genociding okay Palestinian people they are one of the really occupation so if you have any if you have any and you walk out with us in solidarity to King's College Circle and make a statement against you all right okay great all right so that was interesting so here we have to do yes so it has to match to do so here we are that function prototype just should come before all the types should match otherwise see will be unhappy and having it without a input types that's technically a seed declaration and see will kind of figure it out and that's the difference between a prototype in the declaration but you shouldn't need to know that just always type out the full input types and output types and that's a prototype and always do that otherwise people will be very very confused and very very angry with you let's write a new program that is slightly more challenging for some practice we will write a program to print a mirrored triangle of stars which is slightly different than what we had so before we were just printing like one star and then that's it and then next line we bring two stars and three stars and four stars and five now we want to have it kind of right aligned so to do this if I'm having five rows of stars there's four spaces here followed by a star then three spaces here followed by two stars then two spaces followed by three then one followed by four then five stars let us try to do this because this is something that would technically be on an exam our program probably looks something like this to start off so we can think about rows and columns so what I want is essentially the first line should be one two three four and then a star second line should be one two three and then two stars third line should be two spaces and then three stars next line should be a space and then four stars next line should be five stars so if I was to write out so let's think about how we would implement that you can let me know because my bout of amnesia is about to hit alright so I'll give you another minute and then we'll see if anyone has some suggestions to help me alright anyone with ideas? yeah okay so yeah yeah if you didn't hear that his solution was okay where my cursor is right now so within those nested for loops I could have some more for loops so I could have a for loop that prints the number of spaces which is going to be you said equal to the number of row five minus the number of row let's just make another for loop so in count equals one to count is less than five minus the row and then plus plus count and then that's to print off spaces and then I could have another loop that goes up to the row and then print stars okay that's it alright so you can compile and run this and we will see something a little bit odd because it is almost right oops first one is at the after this loop which prints all the columns we should probably have a new line there because that's a new line so let's compile and run it now so now looks a bit weird turns out so this one would actually be right I assume if my problem is that for each row and for each column so that's supposed to be for one single element I'm doing this for each one so I'm getting it repeated five times so if I wanted to do this solution I have to get rid of this for loop shove this all back so there we go so that's one solution so can we do it without two four loops in the inner one yeah this solution is not bad but yeah yeah so here this comment was let's go back to this so now we know that so we're always going to be printing five characters each time so for each row we're printing we're going five characters while we're iterating five columns and here we'll always print five characters and since we're going through it every single time well we can use an if statement instead because each time through it I'm either printing a space or a star I could instead do some if something that I'll leave to later and there's lots of different ways to write it so I'll do this version of it so now we want to figure out whether we should print a star or a space let's see if we can break this down because when start thinking about it sometimes it's easier just to kind of draw an example or try and visualize it somehow so if I go here so say we have row one, two actually I'll leave a bit of space and then we'll have the column up here one, two, three, four, five so if I want to think about the first row it's a space space space space star I try and I want to try and make a relationship between the column and the row so that whenever that relationship is true so something with column is five compared to row is one should be true and then for the rest of the values for column should be false because I want to print a space and then for the second row it would be space, space, space star, star so one way to think about the relationship between them is it's kind of inverted with the row right so thinking about it in terms of row minus five might be useful so I'll just make this a little calm here so for this row sorry five minus row oops so five minus row kind of inverts the number right so for row one five minus row is equal to four for row two it's equal to three then two then one then zero so it kind of inverts the number right so now instead of getting bigger as we go on it's getting smaller as it goes on so if I notice here well if I take this number what's the relationship between this and the column this and the column that I want to print a star in any guesses Bueller that's probably way too old any brave soul yep yeah like yeah so I want to write some like I have right now some if statement I want to know what to write in this if statement such that if it's true I print a star and if it's false I print a space yeah yeah so it seems like the condition for all of the cases where I want to print a star from so let's take this first row as an example so in this first row well if I look at the only true statement it's when column is equal to five so column is equal to five well that seems to only be true or sorry if I do column is greater than five minus row so if I do that as my condition okay well if column is equal to zero or sorry if column is equal to one in the first row well then one is not bigger than five minus row which is just four so it's false so I should print a space same thing here same thing here and then if column is four then well five minus row is still four it's not bigger so four is not greater than four so that's still false and then as soon as column becomes five while five is greater than four so that's true and that's the only case in this column when it's true so now for the second row I can do the same thing but the only difference is that now five minus row is three for this row so let's see if that still holds so in this case okay well column is one so one is not greater than three so that would be a space same thing two is not greater than three three is not greater than three so it should be a space oh four is greater than three so we'd have a star yay and then we could and then seems to hold true for the next one so we can always try it and run it and see if we are correct so I did cull is greater than five minus row so if I go ahead compile and run that hey that works too so more than one way to actually solve this problem having those two for loops might be more straightforward um if you're not used to it but this if statement also works quite well although thinking about this logic statement takes a bit of practice so again especially if you're new do that learning c dot org the online textbook so we're up to chapter four so you should be able to do all the exercises and again they're taken from the exam which we're currently writing so good thing to practice any questions about that because this is not the only way I could write it I could try and figure out the uh... the Boolean expression that's the opposite of that right that's false when I want or that's true when I want to print a space and false when I want to print a star so I could just switch it around if I really wanted to whoops shouldn't do that so if I want to switch it around was it less than oh whoops I inverted it okay nevermind shouldn't do that on the fly yeah and then now we have a question like can we use a function that takes an input and then output and then figures out how many spaces to print well that is kind of where we're going about this thinking so that is a good instinct to have that will serve you well so we can just do the same thing as we did in last lecture like write a program to print the rows of stars using functions instead maybe you think keeping track of two for loops at a time is too much you don't want to bother doing it you want to try and more easily relate things together so we can go ahead and do that so we'll just go back to the regular old triangle just to make it a bit simpler for now that was remember it was just given the number of rows uh... you we want to do something like that so here i can break it off into little sections so i could just think about first let's figure out just based off the row number how to go ahead and just print the number of stars for that row i'll just hat write a function it's argument will be an integer the row number was supposed to print out i'll call it print row and in this case it's void because all it's going to do is print the row i don't actually need its value for anything so i could just create a new for loop so from count equals one the count is less than or equal to row plus plus count then i can just print f a star and then at the end of the row here i know at the end the row is the end of the print row function so it's a little uh... harder to forget actually printing a new line at the end of it this would probably be my print row function i can break it down so now i can think about okay so that's how to print a single row now i don't have to worry about it assuming that i wrote it correctly and i can think about just printing a triangle now i can also just create four in row equals one row is less or equal to max row plus plus row then instead of doing that inner for loop like i had before which was kind of ugly well now i can simplify it a whole heck of a lot i can just use print row and then give it the row number and then that's all i have to do so now it's a bit easier to read and i can say hey if i screwed up printing a row like one my rows is wrong well then probably this functions fault when i have to debug it i know to concentrate my efforts in this function if i screw up the number of rows well then probably my print triangle is wrong i should probably go ahead and fix that then here in my main i can also make my main really small and easy to read so here all it does is take an input and then after i take the input well all my program does is print a triangle so i can just call print triangle and then give it and which is my max rows so now if i compile and i run that let's start trying i can say number of rows i can give it fifteen something like that it works and i broke it into little pieces questions about that more or less okay more or less readable than we just had like the two for loops and the two for loops and just that this one might not be more readable it's kind of up to you but whenever we start using a function more than once then actually writing functions becomes more and more useful um... and then yeah this question how does the output of a void work out like how is there no conflict so in this case since these functions return nothing so their output is nothing well i don't have to do anything with them so in this case see we'll go ahead and put a return right here for us if we don't specify one for a void function so whenever cc's that you're out of statements it would just go ahead and do a return for you from this function so that means whether we call print row let's say rows equal to one we'll just print a star print a new line and then we're done that function so we return and that means this function is done so whoever called it like the print triangle it doesn't need to get the output of that function because well doesn't output anything don't need to capture anything we can just call print row and then just let it do whatever print row is going to do then here again since print triangle is also void it does not output anything it doesn't output an int doesn't output a double doesn't output a char doesn't output a bool so we don't need to try and like get its return value into some variable or something that we just call it in fact if we just did like in x equals print triangle it would probably complain loudly at us alright other questions yep so the print triangle so how it works is whenever we execute this well when we execute this will execute main then it will just do its dumb thing where it will go ahead execute this line so print number of rows create a variable called n initialize it to zero do the scan f so wait for us to type something and then from this print triangle it'll immediately start executing whatever print triangle does so it won't copy and paste it'll just immediately jump there with this as the argument and we'll get into more about the arguments in the next lecture but here it will get a copy of n so in this case what I input fifteen so print triangle would get a fifteen so max row would be equal to fifteen then we would do four row to max row and then first time through this loop row is going to be equal to one so when we call print row with row equal to one we'll start running this function now and this function will run and row will be equal to one so we'll go from count equals one to count is less than in this case one so print a single star then a new line and then it would return so it would return and then we'd start resuming execution from wherever we left off so we'd resume we'd go to the next iteration of the for loop so now rows equal to two so now it will use this function but now rows equal to two so we just do the same thing here rows now equal to two so count from one all the way to two print two stars then print a new line and then do that again and again and again until we're finally done in this case max row was fifteen so as soon as max row is fifteen or row is fifteen then we'll do print row with row equal to fifteen and then we'll go ahead and we'll be done and then we'll be done with this function and then it will eventually be done with main alright so real quick to so here's the start of the solution just so you have in the slides what we get into next lecture in more detail but we should know it now is that those arguments that we're giving to the function C actually makes copies of them so specifically in C we refer to this as pass by value different programming languages may have different rules but in C all arguments are passed by value so for example if that variable is an int C creates a copy of that int value so here we can go back to to show it and to get some questions for the next lecture here I'll move this up here see if it's easier to read so say I create a variable called x in main let's say it was four so I will print the value of four so because our program runs line after line I should immediately see x colon four after this print everyone good with that sorry so I start off x equals four then I have a print f of x colon whatever the value is I want x after I run this x should be equal to four so here I'm going to call the function add two and I will give it x as an argument so in here well it gets an x and say we did int result equals x plus two so I'll just create a new variable to save the result of adding two to x let's say I'll just change x to forty two and then I'll return the result so this should always in this case I should return the result of six I'm also changing x here so I'm changing x to be forty two so if I go ahead and print x again here what will the second x colon print alright let's do a vote of who's awake I guess so this second print here does it say x equals forty two alright we got one two like two out of like three three out of a lot of people alright great so will it say x equals four four ish five ish will it say x equals six no one uh... okay so we have like maybe eleven people awake of this entire class great so if I go ahead and I run this I'll see x four and then the result and I'll see x equals four again we don't know what pointers are yet in this case why we saw even though that it looks like if we follow it what would happen is x equals four then we go ahead and we print off x six four that makes sense and then we run add two and we give it the x and then here well this is the same x isn't it and then we do x okay that's four plus two so result is six and then we change x to be forty two so when we come back it might make sense that x is forty two but because c copies by value and in fact these names being the same just was a coincidence too so I could have remember I could have called this whatever I wanted I could have called this a so it might be less surprising if I do something like that but the reason why I saw x equals four both times is because when I call this function with x because it's copy by value or pass by value this function just gets a copy of whatever the value of x is at the time that I made that function call so at the time I made this function call x was equal to four it gets a new variable so in this function creates a new variable called a and it gets a copy so it just happens that a is equal to four since a is equal to four well four plus two is six I can change this variable which only exists for this function which will get into the next lecture and then we'll return six it is also copied so we print off six and then since x was copied mains x does not change that's to get you ready for the next lecture we'll spend the whole lecture going into details of this but bring questions for tomorrow so just remember full and full yes we're all in this together