Skip to main content

Section 21.4 Value-Returning functions

Now let’s consider a more complicated situationβ€”a recursive function that returns a value.
Many mathematical functions are defined recursively, because that is often the simplest way. For example, the factorial of an integer \(n\text{,}\) which is written \(n!\text{,}\) is defined like this:
\begin{align*} 0! = \amp 1\\ n! = \amp n \cdot(n-1)! \end{align*}
Don’t confuse the mathematical symbol \(!\text{,}\) which means factorial, with the C++ operator !, which means not. This definition says that factorial(0) is 1, and factorial(n) is n * factorial(n - 1).
It is trivial to turn that into a recursive function. The two parts of the definition are the base case and the recursive case:
Listing 21.4.1.
Why is the answer 120? Well...
If we use those rules to keep expanding `factorial(5) it looks like:
Once we there are no more factorial calls, we can evaluate the expression and get 120.
To actually see this play out in the code, it can help to break up the steps of the recursive case. This version of factorial does the same math, but prints more information along the way.
Listing 21.4.2.
Notice that as you run the code, you get a chance to see the values being returned at each step of the recursion.

Insight 21.4.1.

It is easier to debug recursion if we store the value that is returned from the recursive call, calculate and store the answer for the current call, and then return the result. That way we can use a debugger or print statements to view how the result is being built up level by level.
The original version of factorial, which did return n * factorial(n - 1);, gave us no chance to see what came back from the call factorial(n - 1) or what value would be returned.
Below is a stack diagram that shows how the value is built up over the recursive calls. This stack diagram cheats a little. Instead of showing the stack at a particular point in time, it shows the final state of each stack frame all at the same time. It also shows what is being returned from one level to the next.
There are 4 stack frame boxes for the countdown function. They have different values of n, from 3 to 0.
Figure 21.4.3. Stack diagram for the factorial program.

Checkpoint 21.4.1.

Construct the function sumFrom(int start, int end). It should return the sum of all integers from start to end (inclusive). If start is greater than end, it should return 0.
Each call will be responsible for the current start value. Recursion will change the start.

Checkpoint 21.4.2.

Build another version of the function sumFrom(int start, int end). It should return the sum of all integers from start to end (inclusive). If start is greater than end, it should return 0.
This version will have two base cases. One for when start is equal to end, and another for when start is greater than end.
Each call should be responsible for the current end value. Recursion will change the end.
You have attempted of activities on this page.