Don't understand recursion

I tried to debug and understand the following code. The program is correct but I don't understand how the last four lines of outputs prints and how the value of numberOfBottles increased from 0 to 4 during recursion. Does someone has an easier way to explain me this. Thanks in advance.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
  #include <stdio.h>

void singSongFor(int numberOfBottles)
{
    if (numberOfBottles == 0)
    {
        printf("There are simply no bottles of beer on the wall.\n\n");
    }
    else
    {
        printf("%d bottles of beer on the wall. %d bottles of beer.\n", numberOfBottles, numberOfBottles);
        int oneFewer = numberOfBottles - 1;
        printf("Take one down and pass it around. %d bottles of beer on the wall.\n", oneFewer);
    
        singSongFor(oneFewer);  // The function calls itself. This process is called recursion.
    
        // Print message just before the function ends
        printf("Put a bottle in the recycling, %d empty bottles in the bin.\n", numberOfBottles);
    }
}

int main(int argc, const char * argv[])
{
    // We could sing 99 verses, but 4 is easier to think about
    
    singSongFor(4);
    
    return 0;
}
Last edited on
Maybe this will help
Call singSongFor with numberOfBottles = 4
Output starting lines for numberOfBottles (4)
|   Call singSongFor with numberOfBottles = 3
s   Output starting lines for numberOfBottles (3)
a   |   Call singSongFor with numberOfBottles = 2
m   |   Output starting lines for numberOfBottles (2)
e   |   |   Call singSongFor with numberOfBottles = 1
|   |   |   Output starting lines for numberOfBottles(1)
v   |   |   |   Call singSongFor with numberOfBottles = 0
a   |   |   ↓   Output special message
r   |   ↓   Output end line with numberOfBottles(1)
s   ↓   Output end line with numberOfBottles(2)
↓   Output end line with numberOfBottles (3)
Output end line with numberOfBottles (4)
How the value of numberOfBottles keep on increasing is what I don't understand.
It is not increasing. When calling funtion, current function execution is paused and will resume after function finishes.

So, for example:

call singSongFor with numberOfBottles = 1. We will call it function1. It executes lines 11-13 outputting
1 bottles of beer on the wall. 1 bottles of beer.
Take one down and pass it around. 0 bottles of beer on the wall.
Then on line 15 it calls singSongFor with numberOfBottles = oneFewer(0). We will call it function2. function1 execution is paused at line 16.
function2 executes and outputs
There are simply no bottles of beer on the wall.
function2 finishes and function1 resumes from line 16. In function1 numberOfBottles = 1, so line 18 will output
Put a bottle in the recycling, %d empty bottles in the bin.
It doesn't.

MiiNiPaa's example explains it pretty well. But maybe this will help visualize it more:

singSongFor(0) outputs this:

There are simply no bottles of beer on the wall.


singSongFor(1) outputs this:

1 bottles of beer on the wall. 1 bottles of beer.
Take one down and pass it around. 0 bottles of beer on the wall.
   <<< Whatever singSongFor(0) outputs >>>                       <- this is the recursive call
Put a bottle in the recycling, 1 empty bottles in the bin.


Since we already know what singSongFor(0) outputs, this means the full output for singSongFor(1) is this:

1 bottles of beer on the wall. 1 bottles of beer.
Take one down and pass it around. 0 bottles of beer on the wall.
There are simply no bottles of beer on the wall.
Put a bottle in the recycling, 1 empty bottles in the bin.





So now... singSongFor(2) outputs this:

2 bottles of beer on the wall. 2 bottles of beer.
Take one down and pass it around. 1 bottles of beer on the wall.
   <<< Whatever singSongFor(1) outputs >>>                       <- this is the recursive call
Put a bottle in the recycling, 2 empty bottles in the bin.


Again... since we know what singSongFor(1) outputs, just substitute that in... making the full output this:


2 bottles of beer on the wall. 2 bottles of beer.
Take one down and pass it around. 1 bottles of beer on the wall.
1 bottles of beer on the wall. 1 bottles of beer.
Take one down and pass it around. 0 bottles of beer on the wall.
There are simply no bottles of beer on the wall.
Put a bottle in the recycling, 1 empty bottles in the bin.
Put a bottle in the recycling, 2 empty bottles in the bin.



And so on... and so on.... and so on...
Great. I think now I am getting it. Actually where I was getting confused was the function resuming part. So I guess what I understand is that every singSongFor function call the numberOfBottles variable value is just dedicated to that call. It's the same variable used but it's value is different for every singSongFor call. Is that correct?
Yes. Every function call has its own local variables. If it would be otherwise, mutithreading would be impossible in C++.
Topic archived. No new replies allowed.