“The function of leadership is to produce more leaders, not more followers” Ralph Nader
Functions in C++ programming somehow act like different departments in a company.
A program usually has a goal, for example considering a calculator; its main goal is to take numbers as its input and do mathematical operations (adding, subtraction, division, multiplication etc.) on them.
We can consider each of these mathematical operations as a separated task and put it in different function. For example one function contains the instructions about how to multiply input values to each other; the other function contains instructions about how to divide input values; another function is in charge of getting inputs from the user and send those inputs to a function if needed etc.
As you can see, by diving the whole instructions and works of a program into functions (sub-task) and focusing on those functions separately we can increase the speed and quality of developing the application at the end.
In C++ programming, because with functions we can divide the entire task of a program into sub-tasks, it does make sense for functions to be able to call each other. For example one function named sum accepts integer values as its input and returns the sum of those inputs. So if another function needs such functionality, it can simply call this sum function.
There are more into these calling functions which we will learn about them in this section but for now, take two notes:
-
Functions can call, send and receive values from each
other. -
The function that calls another function is named `caller
function`. And the function that is called is named `called or callee
function`. Also a function can be `called/ callee ` and `caller ` at the
same time. For example one function calls another function but the
second function also calls a third party to send or receive a value. So
the second function which is the middle one is `called/ callee` as well
as `caller` function.
Now let’s get into the details of how to create and run a function in C++ language.
There are two steps in order to create a function:
-
Declare the function.
-
Define the function.
-
Declare the function: declaring a function is
about creating the prototype of the function. Which includes:
-
The name of the function.
-
The return type of the function (if any).
-
The parameters of the function (if any).
Notes:
-
At this stage we don’t care about the logic that should be
defined within the body of the function (this is what we do when we
reach the function-definition). -
The prototype of a function is always declared before the
function is defined and of course before it is being called. Also the
usual place of declaring a function is above the `main` function. But
that doesn’t mean we can’t put the prototype inside a function. The
point is that before a function is called, there should be a prototype
already declared somewhere that the compiler knows about. -
Also we can skip declaring a function. In this case the function
should be defined above the `main` function.
There are two ways that we can declare the prototype of a function:
Data_type function_name();
Data_type function_name(data_type parameter_1, double parameter_2, double parameter_N );
If the function that we want to build takes inputs, the second structure is the way to go, but if the function does not take any input, the first structure is the one to build the function’s prototype.
Data_type: compilers are strict; they need to know if a function returns a value, and if yes, what's the type of that retuned value. For example if a function returns a value of type integer, then we replace the `Data-type` with `int`. Or if the function returns a value of type `double` then the `Data_type` should be replaced with `double`. The types can be those that are covered in data-type section as well as compound and custom data-types like structure, string, class-type etc.
Note: if the function does not return any output, we replace the data_type with the keyword void which means empty.
Example:
void sum();
function_name: any function should have a unique name in order to differentiate functions from each other and be able to call them. Rules for creating a name for a function is the same as those rules that apply to variable names.
Open and close parentheses (): using parentheses is a sign that the target declaration is a function and not a variable (so it helps both developers and compilers to differentiate between variables and functions). Also if the target function takes input value as well, within the parentheses we declare the type and number of those inputs (each separated via comma).
Note: we also use parentheses in order to call a function which is covered later in this section.
Function's parameter: as mentioned before, if a function takes input, we need to declare the data-type of those inputs within the parentheses. This is called function's parameter.
Note: these parameters are separated from each other by comma `,`.
Example:
int multiply(int vOne, int vTwo );
In the example above, we’ve declared or prototyped a function that outputs a value of type int, the name of the function is multiply and it takes two inputs of type int.
Each input of the function is called the parameter of that function and we separate them via comma , and each parameter is considered the local variable of that function.
So in the example above, we’ve declared two parameters for the multiply function with the names vOne and vTwo. These two parameters are also the local variables of the multiply function.
Note: only the data-type of the parameters in a function declaration is important. The names are optional. But you should know that when defining the function, the names of the parameters should also be declared.
Example:
double maxNumber(int , double, float, long);
In the example above, the function’s name is maxNumber, the output’s type of this function is double and it has 4 parameters with the types of int, double, float, long respectively.
Again, when defining a function, setting the names for parameters are necessary because these parameters are actually the local variables of the function and any variable should have a name.
Also you should know that when calling a function, the order of inputs (also known as arguments) should match the parameters’ order of that function. And of course we can’t put less or more inputs than the number of parameters of the target function. This will cause the compiler to return error.
For example the prototype mentioned above, needs 4 inputs (also called arguments) and the order is int, double, float, long respectively. So the correct way of calling this function is:
maxNumber(1 , 3.2, 2.4f, 2235);
These are some examples of wrong way calling this function:
maxNumber(1 , 3.2);// less arguments than is expected.
maxNumber(1); // less arguments than is expected.
maxNumber(1 , 3.2, 2.4f, 2235,23,233); // inserting more arguments than what it can take.
All of these function calls will cause the compiler to return error.
Again don’t worry; you’ll learn about how to call a function in this section.
Semicolon `;`: when a function is declared (prototyped), we end that function declaration with semicolon `; `.
-
Define that function:
Defining a function is about creating a body and putting the instructions and source-code in that body.
These are the structures of defining a function:
Data_type function_name(){
// logic of the function goes here between open and close brackets.
return value; // the return keyword is only used when the function expected output.
}
Data_type function_name(data_type parameter_1, double parameter_2, double parameter_N ){
// logic of the function goes here between open and close brackets.
return value; // the return keyword is only used when the function expected output.
}
Data_type: Here we use the same data_type that we set for the prototype of the function. For example if the prototype is `double` then the defined function should also be `double`.
Function_name: The Function_name is the name of the function that we used when declaring the prototype of that function. For example if the name of a prototype is `multiply` then the defined function should also be named `multiply`.
Parameters: when defining a function, the `type`, `number` and `order` of the parameters of a defined function should be the same as its prototype. Also if the function's prototype skipped the name of the parameters, we need to declare the parameter's name in function's definition as well.
Open and close brackets {}: The body of a function starts from open brace `{` and ends at closing brace `}`. This is the place where we can put the instructions and source code of the function.
Note: there’s no need to put ; after the closing bracket.
return: if the target function returns a value, we use the `return` keyword to declare what value should be returned. On the right side of the `return` keyword we put the value and end that with semicolon `;`.
Note: if the defined function does not output any value (the output type was `void`) then there's no need to use the `return` keyword.
Example:
#include <iostream>
using namespace std;
int sum(int v1 , int v2);
int main() {
int result= sum(1,2);
cout<<"result is: "<<result;
return 0;
}
int sum(int valueOne , int valueTwo ){
return valueOne + valueTwo;
}
Output:
result is: 3
In the example above, we first declared a function named sum right above the main function. The type of this function is int, the name as mentioned is sum and it takes two parameter both of type int.
After that, right below the body of the main function, the sum function is defined. As you can see the return type + the name and the number of parameters of this function is exactly the same as its prototype. We also changed the name of the parameter in the defined function just to show that compilers won’t complain about it.
Also this function returns a value of type int and so we used the return keyword within the body of the function in order to return a value (in this case the result of valueOne + valueTwo expression)
Remember: you can't define a function within the body of another function.
Let’s go with another example that returns no value (void type):
#include <iostream>
using namespace std;
void sum(int v1 , int v2);
int main() {
sum(1,2);
return 0;
}
void sum(int valueOne , int valueTwo ){
int result = valueOne + valueTwo;
cout<<"Result is: "<<result;
}
Output:
Result is: 3
In this example, because the sum() function does not return any value, we declared its type as void. And so you can see, there’s no return keyword to return a value from the body of this function (in its definition).
Calling a function:
In order to call a function, simply write its name and put parentheses on the right side of the function’s name. Also in the parentheses we put the arguments (inputs) that the function needs (if any).
Structure:
Function_name();
If the called function takes arguments (inputs) then we need to put the inputs within the parentheses as well.
This means the first argument to the function will be assigned to the first parameter, the second argument will be assigned to the second parameter and so on….
Also parameters as mentioned before are the local variables of that function.
Structure:
Function_name( value1, value2, valueN);
Note: each input is separated via comma , .
You should know that calling a function can only happen within the body of another function or the body of itself which in this case is called recursion and you can learn about it in recursion section.
Note: calling a function outside any function will cause compiler error.
Example:
#include <iostream>
using namespace std;
int main() {
int multiply(int valueOne , int valueTwo);
int result = multiply(300,21);
cout<<"Result is: "<<result;
return 0;
}
int multiply(int valueOne , int valueTwo ){
int result = valueOne * valueTwo;
return result;
}
In this example, we’ve declared a function named multiply in the body of the main function and just before calling it right at the next line.
As mentioned before, there’s no limitation on declaring a function inside or outside of another function. The limit is on the function-definition which is only allowed outside of all functions.
Moving on with the example, in the int result = multiply(300,21); we’ve called the multiply function here with two arguments as expected (because this function has two parameters).
After the call to the multiply() function, its body will run and in that function we basically multiplied the two arguments and returned the result. This result will be assigned to the result variable and then in the next line in the main() function we simply sent this result to the output stream.
When calling a function at runtime (like multiply() in the example above) the computer will stop running the instructions within the current function right where the call to another function happened, and will move to the target function to run its instruction.
After the target function finished its work, the computer will return to the body of the first function right where the call happened and start to execute the rest of instructions in that function. (This is covered in more details in stack& heap section).