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 dive deeper into how to create these functions, how to define their behaviors, and how to invoke them to bring our objects to life.
main
FunctionYou 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.
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() {
}
Remember, the spacing of our code is not important to the compiler. When it comes to functions, many people prefer to put the opening {
on the line after the function name. That is also valid:
void TakeDamage()
{
Health -= 150;
isDead = true;
}
A common pattern that’s almost always adopted is indenting the code within the body of the function, so it is offset from the left edge. This has been shown in all our code samples so far.
Like with all white space, this is not important to the compiler, but it makes things easier to read for humans. Almost all editors will do this indenting for you automatically, as you may have noticed.
This indenting is either done with the spacebar or the tab key - typical choices for indenting are 2 or 4 spaces or 1 or 2 tabs.
// Indenting by two spaces
void FunctionA(){
cout << "Taking Damage";
Health -= 150;
isDead = true;
}
// Indenting by four spaces
void FunctionB(){
cout << "Taking Damage";
Health -= 150;
isDead = true;
}
You can modify the settings of your editor to specify how big the automated indents should be, and whether they should be done with tabs or spaces.
How might we define a function called LevelUp
?
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.
How might we call a function called LevelUp
?
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:
main
function serves as the entry point of a C++ program.int
or void
), a name, and a body enclosed in curly braces {}
.()
. The TakeDamage()
example demonstrated how to call a function within main
.In the next lesson, we’ll introduce the call stack, and how it affects our use of the debugger. The next lesson will:
An introduction to functions - reusable blocks of code that we can use to break our application into smaller pieces.
Become a software engineer with C++. Starting from the basics, we guide you step by step along the way