Section 7.4. Function Declarations


7.4. Function Declarations

Just as variables must be declared before they are used, a function must be declared before it is called. As with a variable definition (Section 2.3.5, p. 52), we can declare a function separately from its definition; a function may be defined only once but may be declared multiple times.

A function declaration consists of a return type, the function name, and parameter list. The parameter list must contain the types of the parameters but need not name them. These three elements are referred to as the function prototype. A function prototype describes the interface of the function.

Function prototypes provide the interface between the programmer who defines the function and programmers who use it. When we use a function, we program to the function's prototype.



Parameter names in a function declaration are ignored. If a name is given in a declaration, it should serve as a documentation aid:

      void print(int *array, int size); 

Function Declarations Go in Header Files

Recall that variables are declared in header files (Section 2.9, p. 67) and defined in source files. For the same reasons, functions should be declared in header files and defined in source files.

It may be temptingand would be legalto put a function declaration directly in each source file that uses the function. The problem with this approach is that it is tedious and error-prone. By putting function declarations into header files, we can ensure that all the declarations for a given function agree. If the interface to the function changes, only one declaration must be changed.

The source file that defines the function should include the header that declares the function.



Including the header that contains a function's declaration in the same file that defines the function lets the compiler check that the definition and declaration are the same. In particular, if the definition and declaration agree as to parameter list but differ as to return type, the compiler will issue a warning or error message indicating the discrepancy.

Exercises Section 7.4

Exercise 7.22:

Write the prototypes for each of the following functions:

  1. A function named compare with two parameters that are references to a class named matrix and with a return value of type bool.

  2. A function named change_val that returns a vector<int> iterator and takes two parameters: one is an int and the other is an iterator for a vector<int>.

Hint: When you write these prototypes, use the name of the function as an indicator as to what the function does. How does this hint affect the types you use?

Exercise 7.23:

Given the following declarations, determine which calls are legal and which are illegal. For those that are illegal, explain why.

      double calc(double);      int count(const string &, char);      int sum(vector<int>::iterator, vector<int>::iterator, int);      vector<int> vec(10);      (a) calc(23.4, 55.1);      (b) count("abcda", 'a');      (c) calc(66);      (d) sum(vec.begin(), vec.end(), 3.8); 


7.4.1. Default Arguments

A default argument is a value that, although not universally applicable, is the argument value that is expected to be used most of the time. When we call the function, we may omit any argument that has a default. The compiler will supply the default value for any argument we omit.

A default argument is specified by providing an explicit initializer for the parameter in the parameter list. We may define defaults for one or more parameters. However, if a parameter has a default argument, all the parameters that follow it must also have default arguments.

For example, a function to create and initialize a string intended to simulate a window can provide default arguments for the height, width, and background character of the screen:

      string screenInit(string::size_type height = 24,                        string::size_type width = 80,                        char background = ' ' ); 

A function that provides a default argument for a parameter can be invoked with or without an argument for this parameter. If an argument is provided, it overrides the default argument value; otherwise, the default argument is used. Each of the following calls of screenInit is correct:

      string screen;      screen = screenInit();       // equivalent to screenInit (24,80,' ')      screen = screenInit(66);     // equivalent to screenInit (66,80,' ')      screen = screenInit(66, 256);       // screenInit(66,256,' ')      screen = screenInit(66, 256, '#'); 

Arguments to the call are resolved by position, and default arguments are used to substitute for the trailing arguments of a call. If we want to specify an argument for background, we must also supply arguments for height and width:

      screen = screenInit(, , '?'); // error, can omit only trailing arguments      screen = screenInit( '?');    // calls screenInit('?',80,' ') 

Note that the second call, which passes a single character value, is legal. Although legal, it is unlikely to be what the programmer intended. The call is legal because '?' is a char, and a char can be promoted to the type of the leftmost parameter. That parameter is string::size_type, which is an unsigned integral type. In this call, the char argument is implicitly promoted to string::size_type, and passed as the argument to height.

Because char is an integral type (Section 2.1.1, p. 34), it is legal to pass a char to an int parameter and vice versa. This fact can lead to various kinds of confusion, one of which arises in functions that take both char and int parametersit can be easy for callers to pass the arguments in the wrong order. Using default arguments can compound this problem.



Part of the work of designing a function with default arguments is ordering the parameters so that those least likely to use a default value appear first and those most likely to use a default appear last.

Default Argument Initializers

A default argument can be any expression of an appropriate type:

      string::size_type screenHeight();      string::size_type screenWidth(string::size_type);      char screenDefault(char = ' ');      string screenInit(          string::size_type height = screenHeight(),          string::size_type width = screenWidth(screenHeight()),          char background = screenDefault()); 

When the default argument is an expression, and the default is used as the argument, then the expression is evaluated at the time the function is called. For example, screenDefault is called to obtain a value for background every time screenInit is called without a third argument.

Constraints on Specifying Default Arguments

We can specify default argument(s) in either the function definition or declaration. However, a parameter can have its default argument specified only once in a file. The following is an error:

      // ff.h      int ff(int = 0);      // ff.cc      #include "ff.h"      int ff(int i = 0) { /* ... */ } // error 

Default arguments ordinarily should be specified with the declaration for the function and placed in an appropriate header.



If a default argument is provided in the parameter list of a function definition, the default argument is available only for function calls in the source file that contains the function definition.



C++ Primer
C Primer Plus (5th Edition)
ISBN: 0672326965
EAN: 2147483647
Year: 2006
Pages: 223
Authors: Stephen Prata

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net