As we have seen before, C++ allows function calls from within the main or other functions. One additional feature which is often useful is that functions can be called recursively in C++. In other words, a function can call itself.
Some of you may have seen induction in a mathematics class. Recursive functions in C++ act out a very similar process to mathematical induction.
Example: A good example of this is
provided by the factorial function. We've already seen an
implementation of this function using a loop. It can also be done
using a recursive function. Here is a first try at a function
definition for the factorial function: (WARNING: This
function has a subtle bug in it which we discuss below.)
long unsigned int factorial(int n)
{
if (n)
return n * factorial(n-1);
else
return 1;
}
Let's see what happens. If 0 is passed into the variable n of this function, then the expression n is zero (i.e. it's false) and the function returns the value 1. So in other words, factorial(0) is 1.
Now let's see what happens if we call factorial(3). Then n is 3, and the expression n is true. Then the function returns 3 * factorial(2). So the factorial function is called again and we must now compute factorial(2). Then in this function call, n is now 2. Again n is true, and the function returns 2 * factorial(1). Then we compute factorial(1) in the same way to be 1 * factorial(0), which is 1 * 1 = 1. Let's record this in the following table:
| n | factorial(n) = returned value |
| 3 | factorial(3) = 3 * factorial(2) |
| 2 | factorial(2) = 2 * factorial(1) |
| 1 | factorial(1) = 1 * factorial(0) |
| 0 | factorial(0) = 1 |
So now to compute the value of factorial(3), we plug in until we get to the case of factorial(0), which is defined.

There is a problem with this function, however. Remember that with loops, the programmer should be very careful to avoid infinite loops. A similar thing can happen with recursive function calls. Our factorial function provides an example of this. If another function calls factorial(-1), then we compute recursively:
| n | factorial(n) = returned value |
| -1 | factorial(-1) = (-1) * factorial(-2) |
| -2 | factorial(-2) = (-2) * factorial(-3) |
| -3 | factorial(-3) = (-3) * factorial(-4) |
long unsigned int factorial(int n)
{
if (n>=1)
return n * factorial(n-1);
else
return 1;
}
This version ensures that no infinite recursion occurs.
One unfortunate fact is that factorial often computes values that are larger than the largest long unsigned int value, which is around 4 billion. Recall that in this case, the value will wrap around to 0 after it passes the largest allowed value. It turns out that for any n >= 13, the wrong value is returned. One way around this would be to use the double type instead, but we would lose the precision that integer arithmetic affords us.
Example: The following program
prints out an integer by using base 10 digits. (Of course the
cout object already does this automatically; so this program
can be viewed as a possible implementation of it.)
#include<iostream.h>
void printbase(int, int);
void main() {
int base=10;
int num;
cout << "Please enter an integer: ";
cin >> num;
printbase(num, base);
cout << endl;
}
void printbase(int n, int b) {
// cout << "n is " << n << ". b is " << b << ".\n";
if (n<0){
cout << '-';
n=-n;
}
if (n/b)
printbase(n/b, b);
cout << static_cast<char>(n%b + '0');
/* This prints out the character of the digit n%b. */
}
Examine what happens if the user enters in -45 as num. Then printbase is called with n = -45 and b = 10. First of all, the minus sign is handled by the if (n<0) statement. This prints out a minus sign and then make n = 45. Then n/b is 4, so printbase is called recursively. In this call of printbase, n = 4. Now (n/b) = 0 and so printbase is not called again. Then the cout statement at the end of the function takes over, and the character 4 = n%b is printed out. Then printbase returns to the place it was called (which is inside the printbase function), and the character n%b = 5 is printed out. Finally printbase returns to the main function, an endl is printed to the screen and the program terminates.
The following schematic picture may help:
printbase(n = -45, b = 10)
n<0 true
cout '-', n = 45
(n/b = 4) true
printbase(4, 10)
printbase(n = 4, b = 10)
n<0 false
(n/b = 0) false
cout '4'
cout '5'
Notice that part of this function implements a simple way of finding the last digit of any positive integer. So if n is a nonnegative integer, then n%10 gives the last digit of n. So it is easy to find the last digit of an integer. But if we're printing out the digits, we want the last digit to be printed out last, instead of being printed out first. Notice how the recursive function call in printbase, when followed by the command to print the digit n%10, solves this problem.
Exercise: Modify this program to
print the hexadecimal (base 16) digits of an integer the user
inputs. One obvious thing to change is to set base = 16,
but the line to print out the digits should be changed as well (to
ensure that the hexadecimal digits A to F are printed
out for digit values 10 to 15).
Example: The following example
implements an important algorithm called a binary search. The
problem is to find a real root of a cubic polynomial
Now the strategy of the binary search is to divide and conquer. So
for example, if
and
, then we check
. If
, we've found the root. But also, if
, then
we now know that there must be a root between
and
.
(Similarly if
, there must be a root between
and
.) So by checking the sign of
, we either find a
root or we've reduced the problem to a problem on a smaller
interval. Now we can repeat this process by considering the
midpoint of the smaller interval. For example, we may have this
situation, as given by this table and the picture below it:
| so there is a root in the interval | [1,2] | |
| so there is a root in the interval | [1.5,2] | |
| so there is a root in the interval | [1.5,1.75] | |
| so there is a root in the interval | [1.5,1.625] |
So notice that each time we test this, the root is pinned down more and more. In particular, for a given tolerance of say 1e-10, the process will proceed until the interval's length is less than the tolerance, and we will know the root up to a possible error of 1e-10 (so this is about 10 places after the decimal).
Here is a program that implements this plan using recursive function calls.
#include<iostream.h>
double a,b,c, tolerance = 1e-10;
int sign(double); /* returns the sign of a number */
double root(double, double); /* This is the primary function, which
is called recursively. The values
passed to it are the limits of the
interval. */
double cubic(double); /* calculates the polynomial */
bool isroot(double); /* checks if a given value is a
root */
void main() {
double min_range=-10., max_range=10., r;
cout << "Enter the coefficients a, b, c of a cubic polynomial of the form\n"
"x*x*x + a*x*x + b*x + c: ";
cin >> a >> b >> c;
/* The following loop expands the range until the signs of the polynomial
evaluated at max_range and at min_range are different. This is always
possible for a CUBIC polynomial (any polynomial of odd degree works).
*/
while (sign(cubic(max_range)) == sign(cubic(min_range))) {
max_range += 10.;
min_range -= 10.;
}
if (isroot(min_range)) {
/* cout << "min_range\n"; */
r=min_range;
}
else if (isroot(max_range)) {
/* cout << "max_range\n"; */
r=max_range;
}
else
r=root(min_range,max_range);
cout << "x = " << r << " is a root of the polynomial\n"
"x*x*x + " << a << "*x*x + " << b << "*x + " << c << ".\n";
}
int sign(double z) /* returns the sign of z, which is -1 if z is
negative, 0 if z is 0, and 1 if z is positive */
{
if (z<-tolerance) return -1;
if (z<tolerance) return 0;
return 1;
}
double root(double x_min, double x_max) {
double x_mid;
if (x_max - x_min < tolerance) /* Since x_max > x_min, this checks
if they're essentially equal. This
will be true once the function has
been called recursively many times.
*/
return x_min;
x_mid = (x_min + x_max)/2.;
if (isroot(x_mid))
return x_mid;
/* The following gives the recursive call of the function. */
if (sign(cubic(x_mid))!=sign(cubic(x_min)))
return root(x_min,x_mid);
else
/* In this case, sign(cubic(x_mid))!=sign(cubic(x_max)). */
return root(x_mid,x_max);
}
double cubic(double x) {
return x*x*x + a*x*x + b*x + c;
}
bool isroot(double x) {
return (sign(cubic(x))==0);
}