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.

 

 Encapsulation

    

Links:  Home C Programming Guide  C++ programming Guide

Contact Me