Functions are a really vital part of C++. They serve a number of, well, functions. They allow us to make our code more readable and manageable by splitting it up into parts, called functions. They also allow us to avoid duplicating our code. For example, if there is something we need to do more than once, in different places, we can write a function and then call (use/run) that same function from multiple different parts of the code.
[widgets_on_pages id=”udemy_advert_cpp_1″][widgets_on_pages id=”udemy_code_details”]

C++ Function syntax

So what exactly are C++ functions? A function is a collection of variables, expressions and control flow statements (loops and branches). In fact any of the code we have learnt about in the tutorials up until now can be used in a function. The first part of a function that we write is called the signature. Here is an example function signature.

public void bombPlayer(int power, int direction)

Add an opening and closing pair of curly braces {...} with some code that the function actually performs and we have a complete function, a definition.

void shootLazers(int power, int direction)
{
	// ZAPP!
}

We could then use our new function from another part of our code, perhaps like this:

// Attack the player
bombPlayer(50, 180) // Run the code in the function
// I'm back again - code continues here after the function ends

[widgets_on_pages id=”bcgp_cfgp_gpp”]

When we use a function we say that we call it. At the point where we call bombPlayer, our program’s execution branches to the code contained within that function. The function would run until it reaches the end or is told to return. Then the code would continue running from the first line after the function call. If you have completed any of the SFML game projects you will probably recognize that we have been calling functions ever since we got started. We have been using the functions that SFML provides. What is different here is we will learn to write and call our own functions.

Here is another example of a function, complete with the code to make the function  return to the code that called it.

int addAToB(int a, int b)
{

	int answer = a + b;
	return answer;

}

The call to use the above function could look like this:

int myAnswer = addAToB(2, 4);

Obviously, we don’t need to write functions to add two variables together but the example helps us see a little more into the workings of functions. First, we pass in the values 2 and 4. In the function signature, the value 2 is assigned to int a and the value 4 is assigned to int b.

Within the function body, the variables a and b are added together and used to initialize the new variable int answer. The line return answer; does just that. It returns the value stored in answer back to the calling code causing myAnswer to be initialized with the value 6.

Notice that each of the function signatures in the examples above varies a little. The reason for this is the C++ function signature is quite flexible allowing us to build exactly the functions we require.

Exactly how the function signature defines how the function must be called and if/how the function must return a value deserves further discussion. Let’s give each part of that signature a name so we can break it into parts and learn about them.

Here is a function signature with its parts described by their formal technical term.

return type | name of the function (parameters)

And here are a few examples we can use for each of those parts.

Part of the function signature Examples

Return-type: int, also use ( bool, float, int etc. Any C++ type or expression)
Name of function: bombPlayershootLazers, setCoordinates, addAToB etc.
The Parameters: (int number, bool hitDetected), (int x, int y), (float a, float b)

Now let’s look at each part in turn.

 Function return types

The return type, as the name suggests is the type of the value that will be returned from the function to the calling code.

int addAToB(int a, int b){

	int answer = a + b;
	return answer;

}

In our slightly dull but useful addAtoB example above, the return type in the signature is int. The function  addAToB sends back, returns, to the code that called it, a value that will fit in a  int variable. The return type can be any C++ type we have seen so far or one of the ones we haven’t seen yet 😉 . The function does not have to return a value at all, however. In this case, the signature must use the void keyword as the return type. When the void keyword is used the function body must not attempt to return a value as this will cause an error. It can, however, use the return keyword without a value. Here are some combinations of return type and use of the return keyword that are valid.

void doWhatever(){

	// our code
	// I'm done going back to calling code here
	// no return is necessary

}

Another possibility is as follows:

void doSomethigCool(){

	// our code

	// I can do this as long as I don't try and add a value
	return;
}

The following code is yet another couple of possible functions:

void doYetAnotherThing(){
	// some code

	if(someCondition){

		// if someCondition is true returning to calling code
		// before the end of the function body
		return;
	}

	// More code that might or might not get executed

 return;

 // As I'm at the bottom of the function body
 // and the return type is void, I'm
 // really not necessary but I suppose I make it
 // clear that the function is over.
}

bool detectCollision(Ship a, Ship b){

        // Detect if collision has occurred
	if(collision)
        {
           // Bam!!!
           return true;
        } else
        {
           // Missed
           return false;
        }

}

The last function example above  detectCollision is a glimpse into the near future of our C++ code and demonstrates that we can also pass in user defined variables called objects into functions to perform calculations on them.

We could call each of the functions above, in turn, like this:

//OK time to call some functions
doWhatever();
doSomethingCool();
doYetAnotherThing();

if (detectCollision(milleniumFalcon, lukesXWing))
{
      // The jedi are doomed!
      // But there is always Leia.
      // Unless she was on the Falcon?
} else
{
      // Live to fight another day
}

//continue with code from here

Don’t worry about the odd looking syntax regarding the detectCollision function we will see real code like this quite soon. Simply, we are using the return value (true or false) as the condition, directly in a  if statement.

Function names

[widgets_on_pages id=”udemy_advert_cpp_2″][widgets_on_pages id=”udemy_code_details”]
The function name when we design our own function can be almost anything at all. But it is best to use words that clearly explain what the function will do. For example:

void Xvdfgdfgdfgdfse2(int dsads, float dfsdfs)
{

	//code here

}

The above is perfectly legal and will work but these are much clearer:

void doSomeVerySpecificTask()
{

	//code here

}

void getMySpaceShipHealth(){

	//code here

}

void startNewGame()
{

	//code here

}

Function parameters

We know that a function can return a result to the calling code. What if we need to share some data values from the calling code with the function? Parameters allow us to share values with the function. We have actually already seen examples of parameters while looking at return types. We will look at the same example but a little more closely.

int addAToB(int a, int b){

	int answer = a + b;
	return answer;

}

Above, the parameters are int a and int b. Notice that in the first line of the function body we use a + b as if they are already declared and initialized variables? Well, that’s because they are. The parameters in the function signature is their declaration and the code that calls the function initializes them.

Important jargon note

Notice that we are referring to the variables in the function signatures brackets (int a, int b) as parameters. When we pass values into the function from the calling code, these values are called arguments. When the arguments arrive they are used by the parameters to initialize real, usable variables.
int returnedAnswer = addAToB(10,5);

Also, as we have partly seen in previous examples, we don’t have to just use int in our parameters. We can use any C++ type. We can also use as many parameters as is necessary to solve our problem.

As we will see in future tutorials we have left a few of the cooler uses of functions out of this introductory tutorial so we can learn about related C++ concepts before we take the topic of functions further.

Time to get serious about our body.

The function body

The body is the part we have been kind of avoiding with comments like:

// code here
// some code

But actually, we know exactly what to do here already. Any C++ code we have learned already will work in the body of a function.

Function prototypes

We have seen how to code a function and we have seen how to call a function too. There is one more thing we need to do however to make them work. All functions must have a prototype. A prototype is what makes the compiler aware of our function and without a prototype the entire game will fail to compile. Fortunately, prototypes are straightforward. We can simply repeat the function’s signature followed by a semicolon. The caveat is that the prototype must appear before any attempt to call or define the function. So the absolute most simple example of a fully usable function in action is as follows.

// The prototype
// Notice the semicolon
int addAToB(int a, int b);

int main()
{

	// Call the function
	// Store the result in answer
	int answer = addAToB(2,2);

	// Called before the definition
	// but that's OK because of the prototype

        // Exit main
        return 0;

}// End of main

// The definition
int addAToB(int a, int b)
{
	return a + b;
}

What this code demonstrates is the following:

  1. The prototype comes above(before) the main function
  2. The call to use the function is as we might expect, inside the main function
  3. The definition is below(after) the main function

One more thing about functions.

Organizing our functions

Well worth pointing out if we have multiple functions, especially if they are fairly long, is that our .cpp file will quickly become unwieldy. This defeats part of the objective that functions were intended for. The solution that we will see in a working project soon, is that we can add all our function prototypes to our very own header file (.hpp). Then, code all our functions in another .cpp file and then simply add another #include... directive in our Main.cpp file. This way we can use any number of functions without adding any of their code (prototype or definition) to our main code file.

Function conclusion

There is allot more we could learn about functions but we know enough about them already to make some games. And don’t worry if all the technical terms like parameters and signatures etc. have not completely sunk in. The concepts will become clearer when we start to use them. Let’s learn about C++ references.