But when you create your own functions, you have to handle all three aspects—defining, prototyping, and calling—yourself. Listing 7.1 shows these steps in a short example.
Listing 7.1. calling.cpp
// calling.cpp -- defining, prototyping, and calling a function
#include
void simple(); // function prototype
int main()
{
using namespace std;
cout << "main() will call the simple() function:\n";
simple(); // function call
cout << "main() is finished with the simple() function.\n";
// cin.get();
return 0;
}
// function definition
void simple()
{
using namespace std;
cout << "I'm but a simple function.\n";
}
Here’s the output of the program in Listing 7.1:
main() will call the simple() function:
I'm but a simple function.
main() is finished with the simple() function.
Program execution in main() halts as control transfers to the simple() function. When simple() finishes, program execution in main() resumes. This example places a using directive inside each function definition because each function uses cout. Alternatively, the program could have a single using directive placed above the function definitions or otherwise use std::cout.
Let’s take a more detailed look at these steps now.
Defining a Function
You can group functions into two categories: those that don’t have return values and those that do. Functions without return values are termed type void functions and have the following general form:
void
{
return; // optional
}
Here
void cheers(int n) // no return value
{
for (int i = 0; i < n; i++)
std::cout << "Cheers! ";
std::cout << std::endl;
}
The int n parameter list means that cheers() expects to have an int value passed to it as an argument when you call this function.
A function with a return value produces a value that it returns to the function that called it. In other words, if the function returns the square root of 9.0 (sqrt(9.0)), the function call has the value 3.0. Such a function is declared as having the same type as the value it returns. Here is the general form:
{
return
}
Functions with return values require that you use a return statement so that the value is returned to the calling function. The value itself can be a constant, a variable, or a more general expression. The only requirement is that the expression reduces to a value that has, or is convertible to, the
As a programmer, you don’t need to know how a function returns a value, but knowing the method might clarify the concept for you. (Also it gives you something to talk about with your friends and family.) Typically, a function returns a value by copying the return value to a specified CPU register or memory location. Then the calling program examines that location. Both the returning function and the calling function have to agree on the type of data at that location. The function prototype tells the calling program what to expect, and the function definition tells the called program what to return (see Figure 7.1). Providing the same information in the prototype as in the definition might seem like extra work, but it makes good sense. Certainly, if you want a courier to pick up something from your desk at the office, you enhance the odds of the task being done right if you provide a description of what you want both to the courier and to someone at the office.
Figure 7.1. A typical return value mechanism.