Default parameters
Our next program [DEFAULT.CPP] has an example of the use of
default parameters in C++. This program really looks strange since it
contains default values for some of the parameters in the prototype, but
these default values are very useful as we will see shortly.
#include <iostream.h>
#include <stdio.h>
int get_volume(int length, int width = 2, int height = 3);
void main()
{
int x = 10, y = 12, z = 15;
cout << "Some box data is " << get_volume(x, y, z) << "\n";
cout << "Some box data is " << get_volume(x, y) << "\n";
cout << "Some box data is " << get_volume(x) << "\n";
cout << "Some box data is ";
cout << get_volume(x, 7) << "\n";
cout << "Some box data is ";
cout << get_volume(5, 5, 5) << "\n";
}
int get_volume(int length, int width, int height)
{
printf("%4d %4d %4d ", length, width, height);
return length * width * height;
}
This prototype says that the first parameter named length must be given
for each call of this function because a default value is not supplied. The
second parameter named width, however, is not required to be specified
for each call, and if it is not specified, the value 2 will be used for the
variable width within the function. Likewise, the third parameter is
optional, and if it is not specified, the value of 3 will be used for height
within the function.
In line 7 of this program all three parameters are specified so there is
nothing unusual about this call from any other function call we have
made. Only two values are specified in line 8 however, so we will use
the default value for the third parameter and the system acts as if we
called it with get_value(x, y, 3) since the default value for the third
value is 3. In line 9 we only specified one parameter, which will be used
for the first formal parameter, and the other two will be defaulted. The
system will act as if we had called the function with get_volume(x, 2,
3). Note that the output from these three lines is reversed; this will be
explained shortly.
There are a few rules which should be obvious but will be stated
anyway. Once a parameter is given a default value in the list of formal
parameters, all of the remaining must have default values also. It is not
possible to leave a hole in the middle of the list, only the trailing values
can be defaulted. Of course, the defaulted values must be of the correct
types or a compiler error will be issued. The default values can be given
in either the prototype or the function header, but not in both. If they
are given in both places, the compiler must not only use the default
value, but it must carefully check to see that both values are identical.
This could further complicate an already very complicated problem, that
of writing a C++ compiler.
As a matter of style, it is highly recommended that the default values be
given in the prototype rather than in the function. The reason will be
obvious when we begin studying the object-oriented structures found in
C++.
Scrambled output
When the compiler finds a cout statement, the complete line of code is
initially scanned from right to left to evaluate any functions, then the
data is output field by field from left to right. Thus in line 7
get_volume( ) is evaluated with its internal output displayed first. Then
the fields of the cout are displayed from left to right with "Some box
data is" displayed next. Finally, the result of the return from
get_volume( ) is output in int format, the type of the returned value.
The end result is that the output is not in the expected order when lines
7 to 9 are executed. (The output is not what you would intuitively
expect to happen so appears to be a deficiency in the language. Borland
International verified that this is operating correctly.)
Lines 10 to 13 are similar to any two of the lines of code in lines 7 to 9,
but are each separated into two lines so the output is in the expected
order.
Variable number of arguments
The next program [VARARGS.CPP] shows how to use a variable
number of arguments in a function call.
#include <iostream.h>
#include <stdarg.h>
// Declare a function with one required parameter
void display_var(int number, ...);
void main()
int index = 5;
int one = 1, two = 2;
display_var(one, index);
display_var(3, index, index + two, index + one);
display_var(two, 7, 3);
}
void display_var(int number, ...)
{
va_list param_pt;
va_start(param_pt,number); // Call the setup macro
cout << "The parameters are ";
for (int index = 0 ; index < number ; index++)
cout << va_arg(param_pt,int) << " "; // Extract a parameter
cout << "\n";
va_end(param_pt); // Closing macro
}
We have gone to a lot of trouble to get the compiler to help us by
carefully checking how many parameters we use in the function calls
and checking the types of the parameters. On rare occasion, we may
wish to write a function that uses a variable number of parameters. The
printf( ) function is a good example of this. ANSI-C has a series of
three macros available in the "stdarg.h" header file to allow the use of a
variable number of arguments. These are available for use with C++
also, but we need a way to eliminate the strong type checking that is
done with all C++ functions. The three dots illustrated in line 4 will do
this for us. This prototype says that a single argument of type int is
required as the first parameter, then no further type checking will be
done by the compiler.
You will note that the main program consists of three calls to the
function, each with a different number of parameters, and the system
does not baulk at the differences in the function calls. In fact, you could
put as many different types as you desire in the calls. As long as the first
one is an int type variable, the system will do its best to compile and run
it for you. Of course the compiler is ignoring all type checking beyond
the first parameter, so it is up to you to make sure you use the correct
parameter types in this call.
In this case the first parameter gives the system the number of
additional parameters to look for and handle. In this simple program,
we simply display the numbers on the monitor to illustrate that they
really did get handled properly.
You will realize that using a variable number of arguments in a function
call can lead to very obscure code and should be used very little in a
production program, but the capability exists if you need it.
Links: Home C Programming Guide C++ programming Guide