So we're going to have one last lecture on functions I was hoping to be able to move into the other
topics by now, but there are a couple sub topics that have to do with functions that I do need to mention.
So this is going to be a short lecture.
Don't worry, I won't be stuffing a ton of information into this.
I just have to cover like two last little things with functions.
So that's why we have this part three.
So let's go over those two things.
So the first thing is something called prototypes.
Well, what are the prototypes?
Well, think about it this way.
The compiler must know about a functions definition before it's called.
So think back to what a function definition is because we just went over that right.
The definition is where you put all of the actual code that's meaningful, that the function runs right.
It has the curly braces and all that.
The function call just has the name with the parentheses and the arguments.
Right definition has the parameters.
Vesta.
So if we're doing things tough down and then we have a function that is defined below main notice that
we've only defined the functions above Maine so far, and this is actually important point.
If we were to instead define it below Maine, when we call that function in Maine, the compiler will
not know about the function definition yet.
So at the time that it sees that call to the function, it's not going to know what it is and it's going
to throw an error.
So the compiler is going to throw an error because what it will be thinking is, Oh, this is not within
the scope, right?
We talked about scope within like, you know, if condition or a loop, you know, stuff inside of those
curly braces.
Also for a function, there's a scope, right?
We talked about in Maine's scope or in another function scope.
It's all the scope is whatever falls between the curly braces, you know, and what that function can
recognize, except Maine doesn't recognize anything is just going to be like there was nothing in my
scope that makes me recognize this.
There is a way to fix that, though, since we haven't hit the definition yet, but we want to call
it in Maine, and let's say we want to leave the definition below Maine.
It is possible we just have to use something called a prototype or a function prototype.
So I will show you that here on this next page.
So this is what the functional prototypes look like.
Syntactically you notice that they're pretty much just the first line of the definition, right?
So we have two right here and there for each one of these functions down here.
So the first one, says Boyd, say hello with some parentheses, which is pretty much just line 12,
right, is the first line of the function definition, the function implementation right here, right?
So what we do is just for the prototype.
We're going to take everything on this first line, but not including the curly brace, of course.
Instead, we'll have a semicolon afterwards since it's the C++ statement, something that we're defining
in C++ here.
Every line, this kind of an actual line of code ends up having a semicolon after it to finish it off.
So we have the one for say hello.
We also have one for Find Some.
If we want to declare these up here as prototypes, then we would run into those issues when we called
say hello here in Maine and call to find some.
What would actually happen is and say hello is the first thing that runs in Maine.
If these didn't exist, then it would have a compiler error.
Once it saw this, it would say, OK, well, this is not in scope.
Say hello is not something recognized in my scope, right?
If you got rid of say hello, but or sorry, if you got rid of find some but left say hello, then it
would actually fail here on the find some.
Another important thing is notice that the Find Some also has the parameters mentioned that is also
necessary for the prototype if you have parameters in the function definition.
You must also put them in the prototype.
Later on, we might see that you don't necessarily have to include the very variable name here.
You can just put the word end to signify that the first parameter is an integer and you could just put
and for the second parameter or two to say, Hey, the second parameter is an integer, but I like to
do it this way because it just makes sense.
Like why not put the variable names here?
Why not just like, line it up so you everything makes sense?
I don't know.
That's just my preference.
But.
Pretty simple, not much more to it, just, you know, everything on this first line is what's going
to be the prototype and when do you do the prototype?
You have to do the prototype if you're going to put these functions below wherever you call it.
So that's the main thing you.
From top to bottom, moving from top to bottom.
You cannot call a function before it is defined unless you have a prototype.
All right.
You may be thinking that this seems like kind of a dumb thing, like why do we even care?
Why can't we just put these above me?
Well, yeah, you can.
It's going to be more interesting, though later on we're going to use prototypes when we have multiple
files from one program in C++.
So you kind of see the purpose of prototypes at that point when we want to use multiple files, we have
these things called header files.
We're going to get into that later on.
All right.
So let's go ahead and move on to the next thing.
So the next thing is simply just me trying to introduce functions, calling other functions.
You notice I have some prototypes up here.
Voight avoid be void.
See?
That's because these three functions are implemented below main and I call a here and main.
So pretty interesting.
We have a gets called right here, so in Maine, when the program runs was going to do is it's going
to see a it's going to jump to the function a the implementation here, the definition.
And there's going to run this line of code.
Then it's going to be so it's going to jump to be around this line of code in a CCS can jump to see
it or in this line of code.
So let's go ahead and step in to the editor and kind of look at some things.
So one thing that I want to point out right off the bat is what I was mentioning when you don't have
a prototype, so I'm going to go ahead and comment this out so we can see what happens.
I'll save this.
I'll go ahead and compile it.
Well, look, it looks like we have an error.
So let's scroll up and see what this area is, looks.
Go ahead and clear and compile again so we can get something cleaner.
OK, so it says that we have an air online eight.
Right here in Line eight.
And it says, and of course, notice this is line eight.
It says Error A was not declared in this scope, but that's what we were talking about since it wasn't
prototyped up here when we get to Maine.
Maine says I don't know what this is.
I've never seen this.
How can I call a function that I've never seen and I don't know where it is or whether it exists?
That's pretty much what this error means.
Right, so you ahead and uncomment this.
Go ahead and save it, compile it.
Right, there we go.
And so it really matters like the fact that you just put it before the call, so let's go ahead and
try this.
So if I go down here, I delete that.
I copied it.
So what I can do is just put it right here.
Let's go ahead and save this and a clear.
You notice that this compiles fine, even though we didn't put the void B prototype up here with the
other ones, we put it below main.
Why is that?
Why is it fine?
Well, it's because we don't call be in Maine.
We only call it a right.
The rule is that you have to make sure to either have the definition before you call it or a prototype
before you call it.
Let's see what happens, though, when I move it below a you notice that Function A. calls Function
B. So what if I don't prototype B until down here and we'll go ahead and save this and compile it?
Look what happened.
It says Line 14, you notice that's this line right here.
It says Air B was not declared in this scope.
So same thing a function a it's like, I don't know what this is.
I've never seen this.
How can I call this function that I don't know what it is?
All right.
So that's why we're going to go ahead.
And I think the cleanest kind of way is to just put them on top here.
So I like to go ahead and just put them in order up top here.
So pretty cool.
You notice I can go ahead and run this now.
I'll compile it and run it, so I actually do this.
So you notice that it says we're in function, a let's call a function B. It jumps to B.
It says hello from function B, where c it jumps.
It calls C and jumps to see it says, Hello, this is C right.
We could, of course, change this around.
You know, it doesn't have to be in this order.
These functions could call each other in different orders like we can have this call Maine calls Function
C, function C calls function a.
Function calls, function B, and then of course, I would want to comment this out, and I'll show
you why in a second.
So I can go ahead and compile this and run it, so now it's in a different order, right?
We start in Maine, we call Function C, so it says Hello, hello, I'm sorry right here, says hello,
this is C.
See, calls function a.
So we jump up to function A and it says wear in function a let's call function B, so it cost function
B.
It goes to be in and says hello from function B where c but CRT got called up here.
We just changed the ordering.
But something interesting is what happens if we did not comment this or did not comment this out.
So.
Before I run this, I want you to take a look at this code here.
We make some room.
Want you to take a look at this code here and think about what is going to happen.
All right.
Trace the code, trace the function calls.
We start out and see, so go ahead and think about starting out from see main cause see, so we get
to see right what happens afterwards, though, you know, there's a call to a here, you know, there's
a call to be here.
You know, there's a call to see here.
I want you to think about what's going to happen, and I will go ahead and show you.
So.
I think I already say this, but I'll just say it again, just just in case.
All right, so let's compile this and let's run it.
Oh, what is going on here?
Oh my gosh.
It's just printing so much stuff.
This looks like an infinite wow loop, doesn't it?
Don't worry, you can exit it out just the same way that you did with the infinite while loop with a
control seal.
So you control C, then it'll stop it.
Well, look what it's doing it just as like, Hello, this is c one functional.
It's called function B.
Hello.
This is function B where c hello.
This is C, you know, and it goes right back to C.
That's because it's just jumping back and forth.
This is an interesting topic that is going to be covered.
Quite a ways ahead in the course, in the data structures and algorithms section.
It's something called recursion.
It's a slightly more advanced topic, but all it really is is when a function either directly or indirectly
calls itself, which is kind of what's happening, it's almost like making a circle and coming right
back to where it started, right?
We main calls C C calls a equals B, so let's just do that again.
I'll try and have a little smoother, so make calls.
See, we're seeing a we go to a.
A Class B, we got to be because C we got a C C calls a we go to a AA Class B, we got a B because see
we got a C C calls a we just keep doing that over and over again, just bouncing around between these.
So that is something called indirect recursion.
Direct recursion would be something like this when C just calls itself and it just keeps going like
this.
It just as like, call myself, go to hear myself, go to here, call myself going to here, and it
would just get stuck printing, hello, this is C for a super long time.
So we can see that.
If I compile this, this looks a little wonky, but you know, this is just doing hello to see over
and over and over again.
And you could just scroll up and it would just be like you could see me scrolling over here.
There's a lot of stuff that printed out.
So of course we don't.
We don't want that.
You know, this is something that.
We're not going to go over at this point.
Just wanted to show you because their chances are that you might have made a mistake and you have an
indirect or direct recursion in here, or you might have just messed around and you saw that happen
and you were like, Well, this is crazy.
It looks like an infinite loop.
So I wanted to mention that just in case.
All right.
So I just wanted to demonstrate that you can, of course, use multiple functions and the functions
can call themselves and not call themselves sorry.
The functions can call each other and stuff like that.
You could actually put multiple calls here if you'd like to.
You don't just have to have it call one each.
You can call function a from Maine and then.
You could actually call function B and C from A if you wanted, and you could do the same with these
other functions to.
Right.
So pretty cool functions are really powerful.
Main thing to take away from this is the prototypes in relation to where you place the definition in
relation to the calls.
All that stuff, right?
However, how they the position of the call in the program in the file compared to the position of the
definition that is really what the prototype is based on, right?
We need to make sure that we have either the definition of the function, which is also the implementation.
You know, this is the implementation of the function when you make sure that we have that before the
function call.
Otherwise, we have to do these prototypes of you.
All right.
So with that, I think we are pretty much done with our introduction to functions now.
Later on, we will be deep diving more into functions, but it's going to be in relation to other topics
that we have not yet covered.
That's why we have to hold off.
So with that, I will see you in the next lectures.