Chapter Five
Chapter Five
2011
Chapter Five
Functions
5. INTRODUCTION
Using functions in your program requires that you first declare the function and that you then
define the function. The declaration tells the compiler the name, return type, and parameters of
the function. The definition tells the compiler how the function works. No function can be called
from any other function that hasn't first been declared. The declaration of a function is called its
prototype.
The definition of a function consists of the function header and its body. The header is exactly
like the function prototype, except that the parameters must be named, and there is no
terminating semicolon. The body of the function is a set of statements enclosed in braces.
Function Definition Syntax
statements;
A function prototype tells the compiler the return type, name, and parameter list. Func-tions are
not required to have parameters, and if they do, the prototype is not required to list their names,
only their types. A prototype always ends with a semicolon (;). A function definition must agree
in return type and parameter list with its prototype. It must provide names for all the parameters,
and the body of the function definition must be surrounded by braces. All statements within the
body of the function must be terminated with semicolons, but the function itself is not ended
with a semicolon; it ends with a closing brace. If the function returns a value, it should end with
a return statement, although return statements can legally appear anywhere in the body of the
function. Every function has a return type. If one is not explicitly designated, the return type will
be int. Be sure to give every function an explicit return type. If a function does not return a
value, its return type will be void.
There is virtually no limit to the number or types of statements that can be in a function body.
Although you can't define another function from within a function, you can call a function, and
of course main() does just that in nearly every C++ program. Functions can even call
themselves, which is discussed soon, in the section on recursion. Although there is no limit to the
size of a function in C++, well-designed functions tend to be small. Many programmers advise
keeping your functions short enough to fit on a single screen so that you can see the entire
function at one time. This is a rule of thumb, often broken by very good programmers, but a
smaller function is easier to understand and maintain. Each function should carry out a single,
easily understood task. If your functions start getting large, look for places where you can divide
them into component tasks.
Write your prototype into a file, and then use the #include directive to include it in your
program.
Write the prototype into the file in which your function is used.
Define the function before it is called by any other function. When you do this, the definition
acts as its own declaration.
Although you can define the function before using it, and thus avoid the necessity of creating a
function prototype, this is not good programming practice for three reasons. First, it is a bad idea
to require that functions appear in a file in a particular order. Doing so makes it hard to maintain
the program as requirements change. Second, it is possible that function A() needs to be able to
call function B(), but function B() also needs to be able to call function A() under some
circumstances. It is not possible to define function A() before you define function B() and also
to define function B() before you define function A(), so at least one of them must be declared
in any case. Third, function prototypes are a good and powerful debugging technique. If your
prototype declares that your function takes a particular set of parameters, or that it returns a
particular type of value, and then your function does not match the prototype, the compiler can
flag your error instead of waiting for it to show itself when you run the program.
Function Prototypes
Many of the built-in functions you use have their function prototypes already written in the files
you include in your program by using #include. For functions you write yourself, you must
include the prototype. The function prototype is a statement, which means it ends with a
semicolon. It consists of the function's return type, name, and parameter list. The parameter list is
a list of all the parameters and their types, separated by commas. Function Prototype Syntax:
The function prototype and the function definition must agree exactly about the return type, the
name, and the parameter list. If they do not agree, you will get a compile-time error. Note,
however, that the function prototype does not need to contain the names of the parameters, just
their types. A prototype that looks like this is perfectly legal:
This prototype declares a function named Area() that returns a long and that has two
parameters, both integers. Although this is legal, it is not a good idea. Adding parameter names
makes your prototype clearer. The same function with named parameters might be
It is now obvious what this function does and what the parameters are. Note that all functions
have a return type. If none is explicitly stated, the return type defaults to int. Your programs will
be easier to understand, however, if you explicitly declare the return type of every function,
including main().
long FindArea(long length, long width); // returns long, has two parameters
Execution of Functions
When you call a function, execution begins with the first statement after the opening brace ( {).
Branching can be accomplished by using the if statement. Functions can also call other
functions and can even call themselves (see the section "Recursion," later in this chapter). Each
function has its own name, and when that name is encountered, the execution of the program
branches to the body of that function. When the function returns, execution resumes on the next
line of the calling function. This flow is illustrated in the following figure.
Not only can you pass in variables to the function, but you also can declare variables within the
body of the function. This is done using local variables, so named because they exist only locally
within the function itself. When the function returns, the local variables are no longer available.
Local variables are defined like any other variables. The parameters passed in to the function are
also considered local variables and can be used exactly as if they had been defined within the
body of the function. Variables declared within the function are said to have "local scope." That
means that they are visible and usable only within the function in which they are defined. In fact,
in C++ you can define variables anywhere within the function, not just at its top. The scope of
the variable is the block in which it is defined. Thus, if you define a variable inside a set of
braces within the function, that variable is available only within that block.
#include <iostream.h>
float Convert(float);
int main()
{
float TempFer;
float TempCel;
Analysis: On lines 6 and 7, two float variables are declared, one to hold the temperature in
Fahrenheit and one to hold the temperature in degrees Celsius. The user is prompted to enter a
Fahrenheit temperature on line 9, and that value is passed to the function Convert().
Execution jumps to the first line of the function Convert() on line 19, where a local variable,
named TCel, is declared. Note that this is local variable that exists only within the function
Convert(). The value passed as a parameter, TFer, is also just a local copy of the variable
passed in by main().The local function variable TCel is assigned the value that results from
subtracting 32 from the parameter TFer, multiplying by 5, and then dividing by 9. This value is
then returned as the return value of the function, and on line 11 it is assigned to the variable
TempCel in the main() function. The value is printed on line 13. The program is run three times.
The first time, the value 212 is passed in to ensure that the boiling point of water in degrees
Fahrenheit (212) generates the correct answer in degrees Celsius (100). The second test is the
freezing point of water. The third test is a random number chosen to generate a fractional result.
Variables declared within a block are scoped to that block; they can be accessed only within that block
and "go out of existence" when that block ends. Global variables have global scope and are available
anywhere within your program. Normally scope is obvious, but there are some tricky exceptions.
Currently, variables declared within the header of a for loop (for int i = 0; i<SomeValue; i+
+) are scoped to the block in which the for loop is created.
Variables defined outside of any function have global scope and thus are available from any
function in the program, including main(). Local variables with the same name as global
variables do not change the global variables. A local variable with the same name as a global
variable hides the global variable, however. If a function has a variable with the same name as a
global variable, the name refers to the local variable--not the global--when used within the
function. Example illustrates these points.
#include <iostream.h>
void myFunction(); // prototype
int x = 5, y = 7; // global variables
int main()
{
void myFunction()
{
int y = 10;
x from myFunction: 5
y from myFunction: 10
x from main: 5
y from main: 7
Analysis: This simple program illustrates a few key, and potentially confusing, points about
local and global variables. On line 1, two global variables, x and y, are declared. The global
variable x is initialized with the value 5, and the global variable y is initialized with the value 7.
On lines 8 and 9 in the function main(), these values are printed to the screen. Note that the
function main() defines neither variable; because they are global, they are already available to
main().
When myFunction() is called on line 10, program execution passes to line 18, and a local
variable, y, is defined and initialized with the value 10. On line 21, myFunction() prints the
value of the variable x, and the global variable x is used, just as it was in main(). On line 22,
however, when the variable name y is used, the local variable y is used, hiding the global
variable with the same name.The function call ends, and control returns to main(), which again
prints the values in the global variables. Note that the global variable y was totally unaffected by
the value assigned to myFunction()'s local y variable.
#include <iostream.h>
void myFunc();
int main()
{
int x = 5;
cout << "\nIn main x is: " << x;
myFunc();
void myFunc()
{
int x = 8;
cout << "\nIn myFunc, local x: " << x << endl;
{
cout << "\nIn block in myFunc, x is: " << x;
int x = 9;
Analysis: This program begins with the initialization of a local variable, x, on line 10, in main().
The printout on line 11 verifies that x was initialized with the value 5. MyFunc() is called, and a
local variable, also named x, is initialized with the value 8 on line 22. Its value is printed on line
23. A block is started on line 25, and the variable x from the function is printed again on line 26.
A new variable also named x, but local to the block, is created on line 28 and initialized with the
value 9. The value of the newest variable x is printed on line 30. The local block ends on line 31,
and the variable created on line 28 goes "out of scope" and is no longer visible.
When x is printed on line 33, it is the x that was declared on line 22. This x was unaffected by
the x that was defined on line 28; its value is still 8. On line 34, MyFunc() goes out of scope, and
its local variable x becomes unavailable. Execution returns to line 15, and the value of the local
variable x, which was created on line 10, is printed. It was unaffected by either of the variables
defined in MyFunc(). Needless to say, this program would be far less confusing if these three
variables were given unique names!
In C++, global variables are legal, but they are almost never used. Globals are dangerous because
they are shared data, and one function can change a global variable in a way that is invisible to
another function. This can and does create bugs that are very difficult to find.
When a local variable has the same name as a global variable, all references to the variable name
made with in the scope of the local variable. This situation is illustrated in the following
program.
# include<iostream.h>
float num = 42.8; //global variable
int main()
{
float num = 26.4; //local variable
cout<<”the value of num is:”<<num<<endl;
return 0;
}
The output of the above program is:
the value of num is: 26.4
As shown by the above output, the local variable name takes precedence ovger the global
variable. In such cases, we can still access the global variable by using C++’s scope resolution
operator (::). This operator must be placed immediately before the variable name, as in ::num.
When used in this manner, the :: tells the compiler to use global variable.E.g
As indicated the above output, the scope resolution operator causes the global, rather the local
variable to be accessed.
The arguments passed in to the function are local to the function. Changes made to the
arguments do not affect the values in the calling function. This is known as passing by value,
which means a local copy of each argument is made in the function. These local copies are
treated just like any other local variables. An example illustrates this point.
#include <iostream.h>
int main()
{
int x = 5, y = 10;
cout << "Main. Before swap, x: " << x << " y: " <<y<< "\n";
swap(x,y);
cout << "Main. After swap, x: " << x << " y: " <<y << "\n";
return 0;
}
cout << "Swap. Before swap, x: " << x << " y: " <<y<< "\n";
temp = x;
x = y;
y = temp;
cout << "Swap. After swap, x: " << x << " y: " << y << "\n";
Analysis: This program initializes two variables in main() and then passes them to the swap()
function, which appears to swap them. When they are examined again in main(), however, they
are unchanged! The variables are initialized on line 9, and their values are displayed on line 11.
swap() is called, and the variables are passed in. Execution of the program switches to the
swap() function, where on line 21 the values are printed again. They are in the same order as
they were in main(), as expected. On lines 23 to 25 the values are swapped, and this action is
confirmed by the printout on line 27. Indeed, while in the swap() function, the values are
swapped. Execution then returns to line 13, back in main(), where the values are no longer
swapped.
As you've figured out, the values passed in to the swap() function are passed by value, meaning
that copies of the values are made that are local to swap(). These local variables are swapped in
lines 23 to 25, but the variables back in main() are unaffected.
In C++, passing by reference is accomplished in two ways: using pointers and using references.
The syntax is different, but the net effect is the same. Rather than a copy being created within the
scope of the function, the actual original object is passed into the function. Passing an object by
reference allows the function to change the object being referred to. In previous section showed
that a call to the swap() function did not affect the values in the calling function.
#include <iostream.h>
int main()
{
int x = 5, y = 10;
cout << "Main. Before swap, x: " << x << " y: " <<y<< "\n";
swap(x,y);
cout << "Main. After swap, x: " << x << " y: " <<y << "\n";
return 0;
}
cout << "Swap. Before swap, rx: " <<rx<< " ry: " <<ry<<"\n";
temp = rx;
rx = ry;
ry = temp;
cout << "Swap. After swap, rx: " <<rx<< " ry: " <<ry<< "\n";
}
Output: Main. Before swap, x:5 y: 10
Swap. Before swap, rx:5 ry:10
Swap. After swap, rx:10 ry:5
Main. After swap, x:10, y:5
Anaylsis: Two variables are declared on line 10 and their values are printed on line 12. On line
13, the function swap() is called, but note that x and y, not their addresses, are passed. The
calling function simply passes the variables.
When swap() is called, program execution jumps to line 18, where the variables are identified as
references. Their values are printed on line 22, but note that no special operators are required.
These are aliases for the original values, and can be used as such. On lines 24-26, the values are
swapped, and then they're printed on line 28. Program execution jumps back to the calling
function, and on line 14, the values are printed in main(). Because the parameters to swap() are
declared to be references, the values from main() are passed by reference, and thus are changed
in main() as well. References provide the convenience and ease of use of normal variables.