6.4 Function Prototypes

In this section, we create a user-defined function called maximum that returns the largest of its three int arguments. When the application executes, the main function (lines 9–17 of Fig. 6.3) reads three integers from the user. Then, the output statement (lines 15–16) calls maximum, which in this example is defined after main (lines 20–34)—we’ll discuss the order of this example’s function definitions momentarily. Function maximum returns the largest value to line 16, which displays the result. The sample outputs show that maximum determines the largest value regardless of whether it’s the first, second or third argument.

Fig. 6.3 maximum function with a function prototype.

Alternate View

 1   // Fig. 6.3: fig06_03.cpp
 2   // maximum function with a function prototype.
 3   #include <iostream>
 4   #include <iomanip>
 5   using namespace std;
 6
 7   int maximum(int x, int y, int z); // function prototype
 8
 9   int main() {
10      cout << "Enter three integer values: ";
11      int int1, int2, int3;
12      cin >> int1 >> int2 >> int3;
13
14      // invoke maximum
15      cout << "The maximum integer value is: "
16         << maximum(int1, int2, int3) << endl;
17   }
18
19   // returns the largest of three integers
20   int maximum(int x, int y, int z) {
21      int maximumValue{x}; // assume x is the largest to start
22
23      // determine whether y is greater than maximumValue
24      if (y > maximumValue) {
25         maximumValue = y; // make y the new maximumValue
26      }
27
28      // determine whether z is greater than maximumValue
29      if (z > maximumValue) {
30         maximumValue = z; // make z the new maximumValue
31      }
32
33      return maximumValue;
34   }

Enter three integer grades: 86 67 75
The maximum integer value is: 86

Enter three integer grades: 67 86 75
The maximum integer value is: 86

Enter three integer grades: 67 75 86
The maximum integer value is: 86

Logic of Function maximum

Function maximum first assumes that parameter x has the largest value, so line 21 declares local variable maximumValue and initializes it to parameter x’s value. Of course, it’s possible that parameter y or z contains the actual largest value, so we must compare each of these with maximumValue. The if statement in lines 24–26 determines whether y is greater than maximumValue and, if so, assigns y to maximumValue. The if statement in lines 29–31 determines whether z is greater and, if so, assigns z to maximumValue. At this point the largest value is in maximumValue, so line 33 returns that value to the call in line 16.

Function Prototype for maximum

In preceding chapters, we created classes Account, Student and DollarAmount, each with various member functions. We defined each class in a header (.h) and included it before main in a program’s source-code file. Doing this ensures that the class (and thus its member functions) is defined before main creates and manipulates objects of that class. The compiler then can ensure that we call each class’s constructors and member functions correcly—for example, passing each the correct number and types of arguments.

For a function that’s not defined in a class, you must either define the function before using it or you must declare that the function exists, as we do in line 7 of Fig. 6.3:


int maximum(int x, int y, int z); // function prototype

This is a function prototype, which describes the maximum function without revealing its implementation. A function prototype is a declaration of a function that tells the compiler the function’s name, its return type and the types of its parameters. This function prototype indicates that the function returns an int, has the name maximum and requires three int parameters to perform its task. Notice that the function prototype is the same as the first line of the corresponding function definition (line 20), but ends with a required semicolon.

Good Programming Practice 6.1

Parameter names in function prototypes are optional (they’re ignored by the compiler), but many programmers use these names for documentation purposes. We used parameter names in Fig. 6.3’s function prototype for demonstration purposes, but generally we do not use them in this book’s subsequent examples.

When compiling the program, the compiler uses the prototype to

  • Ensure that maximum’s first line (line 20) matches its prototype (line 7).

  • Check that the call to maximum (line 16) contains the correct number and types of arguments, and that the types of the arguments are in the correct order (in this case, all the arguments are of the same type).

  • Ensure that the value returned by the function can be used correctly in the expression that called the function—for example, for a function that returns void you cannot call the function on right side of an assignment.

  • Ensure that each argument is consistent with the type of the corresponding parameter—for example, a parameter of type double can receive values like 7.35, 22 or –0.03456, but not a string like "hello". If the arguments passed to a function do not match the types specified in the function’s prototype, the compiler attempts to convert the arguments to those types. Section 6.5 discusses this conversion and what happens if the conversion is not allowed.

Common Programming Error 6.1

Declaring function parameters of the same type as int x, y instead of int x, int y is a syntax error—a type is required for each parameter in the parameter list.

 

Common Programming Error 6.2

Compilation errors occur if the function prototype, header and calls do not all agree in the number, type and order of arguments and parameters, and in the return type.

 

Software Engineering Observation 6.2

A function that has many parameters may be performing too many tasks. Consider dividing the function into smaller functions that perform the separate tasks. Limit the function header to one line if possible.

Commas in Function Calls Are Not Comma Operators

Multiple parameters are specified in both the function prototype and the function header as a comma-separated list, as are multiple arguments in a function call.

Portability Tip 6.1

The commas used in line 16 of Fig. 6.3 to separate the arguments to function maximum are not comma operators as discussed in Section 5.5. The comma operator guarantees that its operands are evaluated left to right. The order of evaluation of a function’s arguments, however, is not specified by the C++ standard. Thus, different compilers can evaluate function arguments in different orders.

 

Portability Tip 6.2

Sometimes when a function’s arguments are expressions, such as those with calls to other functions, the order in which the compiler evaluates the arguments could affect the values of one or more of the arguments. If the evaluation order changes between compilers, the argument values passed to the function could vary, causing subtle logic errors.

 

Error-Prevention Tip 6.2

If you have doubts about the order of evaluation of a function’s arguments and whether the order would affect the values passed to the function, evaluate the arguments in separate assignment statements before the function call, assign the result of each expression to a local variable, then pass those variables as arguments to the function.

Returning Control from a Function to Its Caller

Previously, you’ve seen that when a program calls a function, the function performs its task, then returns control (and possibly a value) to the point where the function was called. In a function that does not return a result (i.e., it has a void return type), we showed that control returns when the program reaches the function-ending right brace. You also can explicitly return control to the caller by executing the statement


return;
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset