Both fill() and show() have drawbacks. For show(), the problem is that expenses holds four double values and it’s inefficient to create a new object of that size and to copy the expenses values into it. The problem gets worse if we modify the program to handle expenses on a monthly basis or daily basis and expand expenses accordingly.
The fill() function avoids this inefficiency problem by using a pointer so that the function acts on the original object. But this comes at the cost of notation that makes the programming look more complicated:
fill(&expenses); // don't forget the &
...
cin >> (*pa)[i];
In the last statement, pa is a pointer to an array
Using references, as discussed in Chapter 8, helps solve both the efficiency and the notational problems.
Recursion
And now for something completely different. A C++ function has the interesting characteristic that it can call itself. (Unlike C, however, C++ does not let main() call itself.) This ability is termed
Recursion with a Single Recursive Call
If a recursive function calls itself, then the newly called function calls itself, and so on, ad infinitum unless the code includes something to terminate the chain of calls. The usual method is to make the recursive call part of an if statement. For example, a type void recursive function called recurs() can have a form like this:
void
{
if (
recurs(
}
With luck or foresight,
Recursive calls produce an intriguing chain of events. As long as the if statement remains true, each call to recurs() executes
Listing 7.16. recur.cpp
// recur.cpp -- using recursion
#include
void countdown(int n);
int main()
{
countdown(4); // call the recursive function
return 0;
}
void countdown(int n)
{
using namespace std;
cout << "Counting down ... " << n << endl;
if (n > 0)
countdown(n-1); // function calls itself
cout << n << ": Kaboom!\n";
}
Here’s the annotated output of the program in Listing 7.16:
Counting down ... 4 ‹level 1; adding levels of recursion
Counting down ... 3 ‹level 2
Counting down ... 2 ‹level 3
Counting down ... 1 ‹level 4
Counting down ... 0 ‹level 5; final recursive call
0: Kaboom! ‹level 5; beginning to back out
1: Kaboom! ‹level 4
2: Kaboom! ‹level 3
3: Kaboom! ‹level 2
4: Kaboom! ‹level 1
Note that each recursive call creates its own set of variables, so by the time the program reaches the fifth call, it has five separate variables called n, each with a different value. You can verify this for yourself by modifying Listing 7.16 so that it displays the address of n as well as its value:
cout << "Counting down ... " << n << " (n at " << &n << ")" << endl;
...
cout << n << ": Kaboom!"; << " (n at " << &n << ")" << endl;
Doing so produces output like the following:
Counting down ... 4 (n at 0012FE0C)
Counting down ... 3 (n at 0012FD34)
Counting down ... 2 (n at 0012FC5C)
Counting down ... 1 (n at 0012FB84)
Counting down ... 0 (n at 0012FAAC)
0: Kaboom! (n at 0012FAAC)
1: Kaboom! (n at 0012FB84)
2: Kaboom! (n at 0012FC5C)
3: Kaboom! (n at 0012FD34)
4: Kaboom! (n at 0012FE0C)