17A. Ensuring that a Recursive Function Stops

A danger with recursion is that your function might not ever produce an answer. As an extreme example, suppose that you want to define a function f(n). Since you imagine that f is available to you and that it works, you write the definition as follows.

  int f(int n)
  {
    return f(n);
  }
But f(2) calls f(2). That call does another call to f(2). Each call involves creating a frame in the run-time stack. The frames will just pile up until you run out of memory, leading to an infinite recursion.

To avoid infinite recursion, do the following.

  1. Make sure that, if f(n) calls f(x), then x is smaller than n. For example, there is no trouble if f(2) calls f(1).

  2. Make sure that the parameter cannot keep getting smaller forever. For example, if the parameter must be a positive integer, then you know that it cannot keep getting smaller and smaller without end. You will need to ensure that you have a base case to make this work.

  3. Be sure that your recursive calls respect the requirements of your function. For example, if the function requires its parameter to be a positive integer, be sure that every call to the function, including recursive calls, passes it a positive integer.

If a function has more than one parameter, you typically concentrate on one of the parameters, and make sure that it is smaller at the recursive calls, and cannot keep getting smaller forever.

Exercises

  1. Suppose the power function is written as follows. Does it work?

      // power(x,k) returns x to the k-th power.
      //
      // Requirement: k > 0.
    
      double power(double x, int k)
      {
        if(k == 1)
        {
          return x;
        }
        else if(k % 2 == 0)
        {
          return power(power(x,k/2), 2);
        }
        else 
        {
          return x * power(x, k-1);
        }
      }
    
    Answer