[ fromfile: cppintro.xml id: intro-functions ]
Functions enable you to divide a program into manageable components, instead of presenting it as a large, complex monolith.
This enables you to develop and test small components individually, or in small groups, and makes it easier to build and maintain software.
Functions also provide a way to write reusable code for specific tasks.
For example, Example 1.1 computes the factorial of a given number inside the main()
function.
Example 1.3 shows how to extract the code for computing factorials and transform it into a reusable function.
Example 1.3. src/early-examples/fac2.cpp
#include <iostream> long factorial(long n) { long ans = 1; for (long i = 2; i <= n; ++i) { ans = ans * i; if (ans < 0) { return -1; } } return ans; } int main() { using namespace std; cout << "Please enter n: " << flush; long n; cin >> n; if (n >= 0) { long nfact = factorial(n); if (nfact < 0) { cerr << "overflow error: " << n << " is too big." << endl; } else { cout << "factorial(" << n << ") = " << nfact << endl; } } else { cerr << "Undefined: " << "factorial of a negative number: " << n << endl; } return 0; }
With the exception of constructors and destructors, [4] discussed in Chapter 2, and conversion operators, discussed in Section 19.9.1, every function must have
A return type (which may be void
)
A name
An ordered, comma-separated list (which may be empty) of the types of the function's parameters
A body (a block of zero or more statements enclosed in {braces})
The first three are the function's interface, and the last is its implementation.
A function prototype includes the following information:
Function's return type
Function's name
Function's parameter list
In other words, everything except the function's body.
Here are a few prototypes.
int toCelsius(int fahrenheitValue);
QString toString();
double grossPay(double hourlyWage, double hoursWorked);
It is an error to omit the return type (even if it is void
) except for the main()
function, in which case the return type implicitly defaults to int
.
C++ permits overloading of function names.
The signature of a function consists of its name and its parameter list.
In C++, the return type is not part of the signature.
A function name is overloaded if two or more functions within a given scope have the same name but different signatures.
It is an error to have two functions in the same scope with the same signature but different return types.
Example 1.4. src/functions/overload-not.cpp
#include <iostream> using namespace std; void foo(int n) { cout << n << " is a nice number." << endl; } int main() { cout << "before call: " << 5 << endl; foo(5); cout << "before call: " << 6.7 << endl; foo(6.7); cout << "before call: " << true << endl; foo(true); }
src/functions> g++ overload-not.cpp src/functions> ./a.out before call: 5 5 is a nice number. before call: 6.7 6 is a nice number. before call: 1 1 is a nice number. src/functions>
First, when a floating point number gets converted to an int
, its fractional part (the decimal point and all digits to the right of it) is discarded.
Second, the bool value true
is displayed as 1
(and false
is displayed as 0
).
Example 1.5. src/functions/overload.cpp
#include <iostream> using namespace std; void foo(int n) { cout << n << " is a nice int." << endl; } void foo(double x) { cout << x << " is a nice double." << endl; } void foo(bool b) { cout << "Always be " << (b?"true":"false") << " to your bool." << endl; } int main() { foo(5); foo(6.7); foo(true); }
Notice the use of the conditional operator in the third version of foo().[5]
src/functions> g++ overload.cpp src/functions> ./a.out 5 is a nice int. 6.7 is a nice double. Always be true to your bool. src/functions>
Chapter 5 discusses in more detail the many interesting and useful features of C++ functions.
[4] A constructor must not have a return type and may have an empty body. A destructor must not have a return type, must have an empty parameter list, and may have an empty body.
[5] The ternary conditional operator, testExpr ? valueIfTrue : valueIfFalse
provides a terse way to insert a simple choice into an expression. If testExpr
has a nonzero value (e.g., true
) the value immediately to the right of the question mark (?
) is returned. If testExpr
has value 0 (e.g., false
) the value to the right of the colon (:
) is returned.
Generated: 2012-03-02 | © 2012 Alan Ezust and Paul Ezust. |