Chapter-5 Function (C++)
Chapter-5 Function (C++)
Function
A function is a group of statements that together perform a task and often returns a value. A
program written with numerous functions is easier to maintain, update and debug than one very
long program. Functions allow to structure programs in segments of code to perform individual
tasks. Each function has its own name. When that name is encountered in a program, the
execution of the program branches to the body of that function. When the function is finished,
execution returns to the area of the program code from which it was called, and the program
continues on to the next line of code. Every C++ program has at least one function, which is
main(), and all the most trivial programs can define additional functions. Functions are often
called modules.
Advantages of Functions
In C++, a function is a group of statements that is given a name, and which can be called from
some point of the program.
User-defined functions in C++ are classified into two categories:
Value-returning functions—functions that have a return type. These functions return a
value of a specific data type using the return statement, which we will explain shortly.
Void functions—functions that do not have a return type. These functions do not use a
return statement to return a value.
5.2.1 Value-returning functions
Predefined C++ functions such as pow, abs, islower, and toupper. These are examples of value-
returning functions. To use these functions in your programs, you must know the name of the
header file that contains the functions’ specification. Value-returning functions includes
1. The name of the function
2. The number of parameters, if any
3. The data type of each parameter
4. The data type of the value computed (that is, the value returned) by the function, called the type of the
function
5. The code required to accomplish the task
6. body
The first fifth properties form what is called the heading of the function (also called the function
header); the sixth property is called the body of the function. Together, these five properties
form what is called the definition of the function. For example, for the function abs, the heading
might look like:
int abs(int number)
{
if (number < 0)
number = -number;
return number;
}
The variable declared in the heading of the function abs is called the formal parameter of the
function abs. Thus, the formal parameter of abs is number.
double pow(double base, double exponent) // heading of the function pow and formal parameters
double m = 2.5; // of pow is base and exponent
double n = 3.0;
double x, y;
x = pow(m, n); //Line 1
y = pow(2.0, 3.2) + 5.1; //Line 2
cout << m << " to the power of 7 = " << pow(m, 7) << endl; //Line 3
The values of m and n are passed to the function pow. In fact, the value of u is copied into base,
and the value of v is copied into exponent. The variables m and n that appear in the call to the
function pow in Line 1 are called the actual parameters of that call. In Line 2, the function pow is
called with the parameters 2.0 and 3.2. In this call, the value 2.0 is copied into base, and 3.2 is
copied into exponent. Moreover, in this call of the function pow, the actual parameters are 2.0
and 3.2, respectively. Similarly, in Line 3, the actual parameters of the function pow are m and 7;
the value of m is copied into base, and 7.0 is copied into exponent.
Formal Parameter: A variable declared in the function heading.
Actual Parameter: A variable or expression listed in a call to a function.
Syntax: Value-Returning function
Function Name: T his is the actual name of the function. The function name and the
parameter list together constitute the function signature.
FunctionType is the type of the value that the function returns. The functionType is also
called the data type or the return type of the value-returning function.
Statements enclosed between curly braces form the body of the function that specify what
the function actually does. In which statements are usually declaration statements and/or
executable statements.
Function Body: The function body contains a collection of statements that define what the
function does.
Syntax: Formal Parameter List
The syntax of the formal parameter list is:
Parameters List (as many as needed): Each parameter consists of a type followed by an
identifier, with each parameter being separated from the next by a comma. Each parameter
looks very much like a regular variable declaration (for example: int x), and in fact acts
within the function as a regular variable which is local to the function.
The purpose of parameters is to allow passing arguments to the function from the location
where it is called from.
Function Call
The syntax to call a value-returning function is:
Expression can be a single constant value. To call a value returning function, you use its
name, with the actual parameters (if any) in parentheses.
A function’s formal parameter list can be empty. However, if the formal parameter list is
empty, the parentheses are still needed.
If the formal parameter list is empty, the following form:
If the formal parameter list of a value-returning function is empty, the actual parameter is
also empty in a function call. In this case (that is, an empty formal parameter list), in a
function call, the empty parentheses are still needed.
Thus, a call to a value-returning function with an empty formal parameter list is:
In a function call, the number of actual parameters, together with their data types, must match
with the formal parameters in the order given.
Actual and formal parameters have a one-to-one correspondence.
A value-returning function is called is an expression. The expression can be part of either an
assignment statement or an output statement, or a parameter in a function call.
A function call in a program causes the body of the called function to execute.
return Statement
Once a value-returning function computes the value, the function returns this value via the return
statement. In other words, it passes this value outside the function via the return statement.
Syntax: return Statement
The return statement has the following syntax:
In which expr is a variable, constant value, or expression. The expr is evaluated, and its value
is returned.
The data type of the value that expr computes must match the function type.
In C++, return is a reserved word. When a return statement executes in a function, the function
immediately terminates and the control goes back to the caller. Moreover, the function call
statement is replaced by the value returned by the return statement. When a return statement
executes in the function main, the program terminates.
Look at the following examples. Let us write a function that determines the larger of two
numbers. Because the function compares two numbers, it follows that this function has two
parameters and that both parameters are numbers.
This program is divided in two functions: addition and main. Remember that no matter the order
in which they are defined, a C++ program always starts by calling main. In fact, main is the only
function called automatically, and the code in any other function is only executed if its function
is called from main (directly or indirectly).In the example above, main begins by declaring the
variable z of type int, and right after that, it performs the first function call: it calls addition. The
call to a function follows a structure very
similar to its declaration. In the example above, the call to addition can be compared to its
definition just a few lines earlier:
The parameters in the function declaration have a clear correspondence to the arguments passed
in the function call. The call passes two values, 5 and 3, to the function; these correspond to the
parameters a and b, declared for function addition.
At the point at which the function is called from within main, the control is passed to function
addition: here, execution of main is stopped, and will only resume once the addition function
ends. At the moment of the function call, the value of both arguments (5 and 3) are copied to the
local variables int a and int b within the function.
Then, inside addition, another local variable is declared (int r), and by means of the expression
r=a + b, the result of a plus b is assigned to r; which, for this case, where a is 5 and b is 3, means
that 8 is assigned to r.
The final statement within the function: return r;
Ends function addition, and returns the control back to the point where the function was called;
in this case: to function main. At this precise moment, the program resumes its course on main
returning exactly at the same point at which it was interrupted by the call to addition. But
additionally, because addition has a return type, the call is evaluated as having a value, and this
value is the value specified in the return statement that ended addition: in this particular case, the
value of the local variable r, which at the moment of the return statement had a value of 8.
Therefore, the call to addition is an expression with the value returned by the function, and in
this case, that value, 8, is assigned to z. It is as if the entire function call (addition(5,3)) was
replaced by the value it returns (i.e., 8).
Then main simply prints this value by calling:
cout << "The result is " << z;
A function can actually be called multiple times within a program, and its argument is naturally
not limited just to literals:
// function example
#include <iostream>
using namespace std;
int subtraction (int a, int b)
{
int r;
r=a-b;
return r; The first result is 5
}
The second result is 5
int main ()
{ The third result is 2
int x=5, y=3, z; The fourth result is 6
z = subtraction (7,2);
cout << "The first result is " << z << '\n';
cout << "The second result is " << subtraction (7,2) << '\n';
cout << "The third result is " << subtraction (x,y) << '\n';
z= 4 + subtraction (x,y);
cout << "The fourth result is " << z << '\n';
}
Similar to the addition function in the previous example, this example defines a subtract
function, that simply returns the difference between its two parameters. This time, main calls this
function several times, demonstrating more possible ways in which a function can be called.
Let's examine each of these calls, bearing in mind that each function call is itself an expression
that is evaluated as the value it returns. Again, you can think of it as if the function call was itself
replaced by the returned value:
z = subtraction (7,2);
cout << "The first result is " << z;
If we replace the function call by the value it returns (i.e., 5), we would have:
z = 5;
cout << "The first result is " << z;
as:
cout << "The second result is " << 5;
The parentheses are what differentiate functions from other kinds of declarations or statements.
The following would not call the function:
printmessage;
Because the implicit return 0; statement for main is a tricky exception, some authors consider it
good practice to explicitly write the statement.
Arguments passed by value and by reference
In the functions seen earlier, arguments have always been passed by value. This means that,
when calling a function, what is passed to the function are the values of these arguments on the
moment of the call, which are copied into the variables represented by the function parameters.
For example, take:
int x=5, y=3, z;
z = addition ( x, y );
In this case, function addition is passed 5 and 3, which are copies of the values of x and y,
respectively. These values (5 and 3) are used to initialize the variables set as parameters in the
function's definition, but any modification of these variables within the function has no effect on
the values of the variables x and y outside it, because x and y were themselves not passed to the
function on the call, but only copies of their values at that moment.
In certain cases, though, it may be useful to access an external variable from within a function.
To do that, arguments can be passed by reference, instead of by value. For example, the function
duplicate in this code duplicates the value of its three arguments, causing the variables used as
arguments to actually be modified by the call:
// Example 20: passing parameters by reference
#include <iostream>
using namespace std;
void duplicate (int& a, int& b, int& c)
{
a*=2;
b*=2;
c*=2;
x=2, y=6, z=14
}
int main ()
{
int x=1, y=3, z=7;
duplicate (x, y, z);
cout << "x=" << x << ", y=" << y << ", z=" << z;
return 0;
}
To gain access to its arguments, the function declares its parameters as references. In C++,
references are indicated with an ampersand (&) following the parameter type, as in the
parameters taken by duplicate in the example above.
When a variable is passed by reference, what is passed is no longer a copy, but the variable itself,
the variable identified by the function parameter, becomes somehow associated with the
argument passed to the function, and any modification on their corresponding local variables
within the function are reflected in the variables passed as arguments in the call.
In fact, a, b, and c become aliases of the arguments passed on the function call (x, y, and z) and
any change on a within the function is actually modifying variable x outside the function. Any
change on b modifies y, and any change on c modifies z. That is why when, in the example,
function duplicate modifies the values of variables a, b, and c, the values of x, y, and z are
affected.
In this example, there are two calls to function divide. In the first one:
divide (12)
The call only passes one argument to the function, even though the function has two parameters.
In this case, the function assumes the second parameter to be 2 (notice the function definition,
which declares its second parameter as int b=2). Therefore, the result is 6.
In the second call:
divide (20,4)
The call passes two arguments to the function. Therefore, the default value for b (int b=2) is
ignored, and b takes the value passed as argument, that is 4, yielding a result of 5.
2. Declaring functions
In C++, identifiers can only be used in expressions once they have been declared. For example,
some variable x cannot be used before being declared with a statement, such as:
int x;
The same applies to functions. Functions cannot be called before they are declared. That is why,
in all the previous examples of functions, the functions were always defined before the main
function, which is the function from where the other functions were called. If main were defined
before the other functions, this would break the rule that functions shall be declared before being
used, and thus would not compile.
The prototype of a function can be declared without actually defining the function completely,
giving just enough details to allow the types involved in a function call to be known. Naturally,
the function shall be defined somewhere else, like later in the code. But at least, once declared
like this, it can already be called.
The declaration shall include all types involved (the return type and the type of its arguments),
using the same syntax as used in the definition of the function, but replacing the body of the
function (the block of statements) with an ending semicolon.
The parameter list does not need to include the parameter names, but only their types. Parameter
names can nevertheless be specified, but they are optional, and do not need to necessarily match
those in the function definition. For example, a function called protofunction with two int
parameters can be declared with either of these statements:
int protofunction (int first, int second);
int protofunction (int, int);
Anyway, including a name for each parameter always improves legibility of the declaration.
This example is indeed not an example of efficiency. You can probably write yourself a version
of this program with half the lines of code. Anyway, this example illustrates how functions can
be declared before its definition:
The following lines:
void odd (int a);
void even (int a);
Declare the prototype of the functions. They already contain all what is necessary to call them,
their name, the types of their argument, and their return type (void in this case). With these
prototype declarations in place, they can be called before they are entirely defined, allowing for
example, to place the function from where they are called (main) before the actual definition of
these functions.
But declaring functions before being defined is not only useful to reorganize the order of
functions within the code. In some cases, such as in this particular case, at least one of the
declarations is required, because odd and even are mutually called; there is a call to even in odd
and a call to odd in even. And, therefore, there is no way to structure the code so that odd is
defined before even, and even before odd.
3. Recursivity
Recursivity is the property that functions have to be called by themselves. It is useful for some
tasks, such as sorting elements, or calculating the factorial of numbers. For example, in order to
obtain the factorial of a number (n!) the mathematical formula would be:
n! = n * (n-1) * (n-2) * (n-3) ... * 1
More concretely, 5! (factorial of 5) would be:
5! = 5 * 4 * 3 * 2 * 1 = 120
And a recursive function to calculate this in C++ could be:
// Example 23: factorial calculator
#include <iostream.h>
long factorial (long a)
{
if (a > 1)
return (a * factorial (a-1));
else
return 1; 9! = 362880
}
int main ()
{
long number = 9;
cout << number << "! = " << factorial (number);
return 0;
}
Notice how in function factorial we included a call to itself, but only if the argument passed was
greater than 1, since, otherwise, the function would perform an infinite recursive loop, in which
once it arrived to 0, it would continue multiplying by all the negative numbers (probably
provoking a stack overflow at some point during runtime).