Prototypes

Our first look at a prototype is in the next program [PROTYPE1.CPP].

The prototyping used in C++ is no different to that used in ANSI-C.

Actually, many C programmers take a rather dim view of prototyping

and seem reluctant to use it, but with C++ it is considerably more

important and is in much heavier use. In fact, prototyping is required to

be used in most modern C++ compilers.

#include <iostream.h>

void do_stuff(int wings, float feet, char eyes);

void main()

{

int arm = 2;

float foot = 1000.0;

char lookers = 2;

do_stuff(3, 12.0, 4);

do_stuff(arm, foot, lookers);

}

void do_stuff(int wings, float feet, char eyes)

{

cout << "There are " << wings << " wings." << "\n";

cout << "There are " << feet << " feet." << "\n";

cout << "There are " << (int)eyes << " eyes." << "\n\n";

}

A prototype is a limited model of a more complete entity to come later.

In this case, the full function is the complete entity to come later and the

prototype is illustrated in line 2. The prototype gives a model of the

interface to the function that can be used to check the calls to the

function for the proper number of parameters and the correct types of

parameters. Each call to the function named do_stuff() must have

exactly three parameters or the compiler will give an error message. In

addition to the correct number of parameters, the types must be

compatible or the compiler will issue an error message. Notice that

when the compiler is working on lines 8 and 9, the type checking can be

done based on the prototype in line 2 even though the function itself is

not yet defined. If the prototype is not given, the number of parameters

will not be checked, nor will the types of the parameters be checked.

Even if you have the wrong number of parameters, you will get an

apparently good compile and link, but the program may do some very

strange things when it is executed.

To write the prototype, simply copy the header from the function to the

beginning of the program and append a semicolon to the end as a signal

to the compiler that this is not a function but a prototype. The variable

names given in the prototype are optional and act merely as comments

to the program reader since they are completely ignored by the

compiler. You could replace the variable name wings in line 2 with your

first name and there would be no difference in compilation. Of course,

the next person that had to read your program would be somewhat

baffled with your choice of variable names. In this case, the two

function calls to this function, given in lines 8 and 9, are correct so no

error will be listed during compilation.

Even though we wish to use the char type for eyes in the function, we

wish to use it as a number rather than as a character. The cast to int in

line 15 is required to force the printout of the numerical value rather

than an ASCII character. The next example program is similar but

without the cast to int.

 

Compatible types

Compatible types complete our discussion of prototyping. Compatible

types are any simple types that can be converted from one to another in

a meaningful way. For example, if you used an integer as the actual

parameter and the function was expecting a float type as the formal

parameter, the system would do the conversion automatically, without

mentioning it to you. This is also true of a float changing to a char, or a

char changing to an int. There are definite conversion rules which

would be followed. These rules are given in great detail in the ANSI-C

standard and are also given in the second edition of the Kernighan and

Ritchie.

If we supplied a pointer to an integer as the actual parameter and

expected an integer as the formal parameter in the function, the

conversion would not be made because they are two entirely different

kinds of values. Likewise, a structure would not be converted

automatically to a long float, an array, or even to a different kind of

structure, they are all incompatible and cannot be converted in any

meaningful manner. The entire issue of type compatibility as discussed

earlier in the tutorial applies equally well to the compatibility of types

when calling a function. Likewise, the type specified as the return type,

in this case void, must be compatible with the expected return type in

the calling statement, or the compiler will issue a warning.

This is your chance to try prototyping for yourself and see how well it

works and what kinds of error messages you get when you do certain

wrong things. Change the actual parameters in line 8 of the program

above to read (12.2, 13, 12345) and see what the compiler says about

that change. It will probably say nothing because they are all type

compatible. If you change it to read (12.0, 13), it will issue a warning or

error because there are not enough arguments given.

Likewise you should receive an error message if you change one of the

parameters in line 9 to an address by putting an ampersand in front of

one of the variable names. Finally, change the first word in line 3 from

void to int and see what kind of error message is given. You will first be

required to make the function header in line 9 agree with the prototype,

then you will find that there is no variable returned from the function.

You should the (correct) impression that prototyping is doing

something useful after making these changes.

 

More prototyping

The next example program [PROTYPE2.CPP] includes a little more

information on prototyping.

#include <iostream.h>

void do_stuff(int, float, char);

void main()

{

int arm = 2;

float foot = 1000.0;

char lookers = 65;

do_stuff(3, 12.0, 67);

do_stuff(arm, foot, lookers);

}

void do_stuff(int wings, // Number of wings

float feet, // Number of feet

char eyes) // Number of eyes

{

cout << "There are " << wings << " wings." << "\n";

cout << "There are " << feet << " feet." << "\n";

cout << "There are " << eyes << " eyes." << "\n\n";

}

This program is identical to the last one except for a few small changes.

The variable names have been omitted from the prototype in line 2

merely as an illustration that they are interpreted as comments by the

C++ compiler. The function header is formatted differently to allow for

a comment alongside each of the actual parameters. This should make

the function header a little more self explanatory. However, you should

remember that comments should not be used to replace careful selection

of variable names. In this particular case, the comments add essentially

nothing to the clarity of the program.

 

 Default Parameters.

 

Links:  Home C Programming Guide  C++ programming Guide

Contact Me