Creating and Calling Functions
An introduction to functions - reusable blocks of code that we can use to break our application into smaller pieces.
In our previous discussions, we've seen how objects in programming can be thought of as having two main aspects: properties and behaviors.
Properties are like the characteristics or states of an object. We've already learned how to define and use these through variables. For instance, in a game, a character's health or level can be represented as properties using variables like int Health
or int Level
.
But what about the actions or behaviors these objects can perform? This is where functions come into the picture. Functions are the building blocks that enable our objects to act and interact. They define behaviors by grouping sequences of code to perform specific tasks or actions.
Take the example of a game character again. What kinds of actions might this character need to perform? Perhaps they need to move around, attack enemies, or respond to taking damage. Each of these actions can be encapsulated within a function.
By using functions, we not only organize our code into meaningful blocks but also make it reusable and easier to manage. A well-defined function can be used multiple times, in different contexts, without having to rewrite the same code. This makes our programming more efficient and our code more readable.
In the upcoming sections, we'll learn how to create these functions, how to define their behaviors, and how to invoke them to bring our objects to life.
The main
Function
You may have realized we're already working with a function in our code - the main
function:
int main() {
// ... code here
}
The uniquely named main
function is the "entry point" to our code. When we convert our project from code to a runnable application, the compiler looks for a function called main
. This is the function that is called when our executable is run. When the main function ends, our program ends.
However, in our code, we have the freedom to create as many functions as we want. We're not just limited to the main
function.
Creating Functions
Let's start by creating a simple function that modifies some variables.
To create a function, we first need to decide on a name for it. The rules for naming functions are the same as naming variables. Aside from rules like not having any spaces, we can call our functions almost anything.
Just like with variables, we should aim to be descriptive with our function names.
Let's assume we wanted a function to have our monsters take damage. A good name might simply be TakeDamage
. We can define a new function above our main
function like this:
#include <iostream>
using namespace std;
void TakeDamage() {
}
int main() {
}
Aside from TakeDamage()
having a different name to our main
function, we can also see that we have used the void
prefix rather than int
.
void
and int
refer to the data type that will be returned from the function. We will discuss return types in more detail a little later in this chapter.
For now, let's just ensure we always have the int
keyword in our main
function heading, and void
in every other function heading we create.
Let's add some variables to our code, and also fill in the body of the TakeDamage
function. The body is the area between the {
and }
. This is where we make our function perform actions, just like we have with the main
function in the past.
#include <iostream>
using namespace std;
int Health { 150 };
bool isDead { false };
void TakeDamage() {
cout << "Taking Damage";
Health -= 150;
isDead = true;
}
int main() {
}
Test your Knowledge
Defining Functions
How might we define a function called LevelUp
?
Calling Functions
Just because we have created a function, it doesn't mean the code in that function will ever run. If we run the previous code (or debug it) we'd see the code in our TakeDamage
function is never executed.
The only function that we can consider to run automatically is the main
function.
To execute the code within any other function, we need to call that function. This is sometimes also referred to as invoking the function.
To call a function, we use the function-call operator, which is a set of opening and closing parentheses. It looks like this:
TakeDamage();
Given that we know the main
function is going to be run automatically, we can put the code to call our TakeDamage()
function within the body of the main
function. This ensures it is called:
#include <iostream>
using namespace std;
int Health { 150 };
bool isDead { false };
void TakeDamage() {
cout << "Taking Damage";
Health -= 150;
isDead = true;
}
int main() {
TakeDamage();
}
Taking Damage
Note, that the TakeDamage()
function definition must come before the main
function in our code. Were we to switch the order of these functions, putting main
above TakeDamage()
, our code would not compile.
The compiler reads our code from top to bottom so, when it sees us trying to call a function that we haven't defined yet, it will fail with an error.
We will soon see techniques that make the order in which we define our functions less important, but for now, let's just order our file such that we're always defining functions before calling them.
Test your Knowledge
Calling Functions
How might we call a function called LevelUp
?
Summary
In this lesson, we've explored the fundamentals of creating and calling functions in C++. Here's a quick recap of what you've learned:
- Functions are blocks of code that perform specific tasks.
- The
main
function serves as the entry point of a C++ program. - Functions are defined with a return type (for example,
int
orvoid
), a name, and a body enclosed in curly braces{}
. - We should give our functions descriptive names, and indent their body to keep our code easy to read.
- Functions are invoked using their name followed by parentheses
()
. TheTakeDamage()
example demonstrated how to call a function withinmain
.
The Call Stack and Debugging Functions
An introduction to how our function calls create a call stack, and how we can navigate it in a debugger.