Defining and Calling a Function in C++

1. Introduction

Functions can be used to define reusable code and organize and simplify code.

Suppose that you need to find the sum of integers from 1 to 10, from 20 to 37, and from 35 to 49, respectively. You may write the code as follows:

int sum = 0;

for (int i = 1; i <= 10; i++)

sum += i;

cout << “Sum from 1 to 10 is ” << sum << endl;

sum = 0;

for (int i = 20; i <= 37; i++)

sum += i;

cout << “Sum from 20 to 37 is ” << sum << endl;

sum = 0;

for (int i = 35; i <= 49; i++)

sum += i;

cout << “Sum from 35 to 49 is ” << sum << endl;

You may have observed that computing these sums from 1 to 10, from 20 to 37, and from 35 to 49 are very similar except that the starting and ending integers are different. Wouldn’t it be nice if we could write the common code once and reuse it? We can do so by defining a function and invoking it.

The preceding code can be simplified as follows:

1 int sum(int i1, int i2)
2 {
3   
int sum = 0;
4   
for (int i = i1; i <= i2; i++)
5    sum += i;
6
7   
return sum;
8 }
9
10
int main()
11 {
12    cout <<
“Sum from 1 to 10 is ” << sum(1, 10) << endl;
13    cout <<
“Sum from 20 to 37 is ” << sum(20, 37) << endl;
14    cout <<
“Sum from 35 to 49 is ” << sum(35, 49) << endl;
15
16   
return 0;
17 }

Lines 1-8 defines the function named sum with two parameters i1 and i2. The statements in the main function invokes sum(1, 10) to compute sum from 1 to 10, and sum(20, 37) to compute sum from 20 to 37, and sum(35, 49) to compute sum from 35 to 49.

A function is a collection of statements grouped together to perform an operation. In ear­lier chapters, you learned about such functions as pow(a, b), rand(), srand(seed), time(0), and main(). When you call the pow(a, b) function, for example, the system actually executes the statements in the function and returns the result. In this chapter, you will learn how to define and use functions and apply function abstraction to solve complex problems.

2. Defining a Function

A function definition consists of its function name, parameters, return value type, and body.

The syntax for defining a function is as follows:

returnValueType functionName(1ist of parameters)

{

// Function body;

}

Let’s look at a function created to find which of two integers is bigger. This function, named max, has two int parameters, numl and num2, the larger of which is returned by the function. Figure 6.1 illustrates the components of this function.

The function header specifies the function’s return value type, function name, and parameters.

A function may return a value. The returnValueType is the data type of that value. Some functions perform desired operations without returning a value. In this case, the returnValueType is the keyword void. For example, the returnValueType in the srand function is void. The function that returns a value is called a value-returning function and the function that does not return a value is called a void function.

The variables declared in the function header are known as formal parameters or simply parameters. A parameter is like a placeholder. When a function is invoked, you pass a value to the parameter. This value is referred to as an actual parameter or argument. The parameter list refers to the type, order, and number of the parameters of a function. The function name and the parameter list together constitute the function signature. Parameters are optional; that is, a function may contain no parameters. For example, the rand() function has no parameters.

The function body contains a collection of statements that define what the function does. The function body of the max function uses an if statement to determine which number is larger and returns the value of that number. A return statement using the keyword return is required for a value-returning function to return a result. The function exits when a return statement is executed.

3. Calling a Function

Calling a function executes the code in the function.

In creating a function, you define what it should do. To use a function, you have to call or invoke it. There are two ways to call a function, depending on whether or not it returns a value.

If the function returns a value, a call to that function is usually treated as a value. For example,

int larger = max(3, 4);

calls max(3, 4) and assigns the result of the function to the variable larger. Another example of such a call is

cout << max(3, 4);

which prints the return value of the function call max(3, 4)

When a program calls a function, program control is transferred to the called function. The called function is executed. A called function returns control to the caller when its return statement is executed or when its function-ending closing brace is reached.
Listing 6.1 shows a complete program that is used to test the
max function.

Listing 6.1 TestMax.cpp

1 #include <iostream>
2
using namespace std;
3
4
// Return the max between two numbers
5 int max(int num1, int num2)
6 {
7   
int result;
8
9   
if (num1 > num2)
10     result = num1;
11   
else
12     result = num2;
13
14   
return result;
15 }
16
17
int main()
18 {
19   
int i = 5;
20   
int j = 2;
21   
int k = max(i, j);
22    cout <<
“The maximum between ” << i <<
23       
” and ” << j << ” is ” << k << endl;
24
25   
return 0;
26 }

This program contains the max function and the main function. The main function is just like any other function except that it is invoked by the operating system to execute the pro­gram. All other functions must be executed by function call statements.

A function must be defined before it is invoked. Since the max function is invoked by the main function, it must be defined before the main function.

When the max function is invoked (line 21), variable i’s value 5 is passed to numl, and variable j ’s value 2 is passed to num2 in the max function. The flow of control transfers to the max function. The max function is executed. When the return statement in the max function is executed, the max function returns the control to its caller (in this case the caller is the main function). This process is illustrated in Figure 6.2.

Each time a function is invoked, the system creates an activation record (also called an activation frame) that stores its arguments and variables for the function and places the acti­vation record in an area of memory known as a call stack. A call stack is also known as an execution stack, runtime stack, or machine stack, and is often shortened to just “the stack.” When a function calls another function, the caller’s activation record is kept intact and a new activation record is created for the new function call. When a function finishes its work and returns control to its caller, its activation record is removed from the call stack.

A call stack stores the activation records in a last-in, first-out fashion. The activation record for the function that is invoked last is removed first from the stack. Suppose function ml calls function m2, and then m2 calls m3. The runtime system pushes ml’s activation record into the stack, then m2’s, and then m3’s. After m3 is finished, its activation record is removed from the stack. After m2 is finished, its activation record is removed from the stack. After ml is finished, its activation record is removed from the stack.

Understanding call stacks helps us comprehend how functions are invoked. The variables defined in the main function are i, j, and k. The variables defined in the max function are numl, num2, and resul t. The variables numl and num2 are defined in the function signature and are parameters of the function. Their values are passed through function invocation. Figure 6.3 illustrates the activation records in the stack.

Source: Liang Y. Daniel (2013), Introduction to programming with C++, Pearson; 3rd edition.

Leave a Reply

Your email address will not be published. Required fields are marked *