Why does the for loop repeat in this recursion?

milon@lemm.ee to Programming@programming.dev – 32 points –

I used the debugger to examine this code but not understanding a couple areas.

  1. Why does the for loop repeat after it exits to print a new line? If it exits the loop, shouldn't it be done with it?
  2. Why is n incremented and not i as stated with i++?

int main(void)
{
    int height = get_int("Height: ");

    draw(height);
}

void draw(int n)
{
    if (n <= 0)
    {
        return;
    }

    draw(n - 1);

    for (int i = 0; i < n; i++)
    {
        printf("#");
    }
    printf("\n");
}
30

You are viewing a single comment

Why does the for loop return when it hits the end of the function? Isn't the recursive portion already completed in draw(n - 1)? The rest of it is just normal non-recursive code if I understand it correctly.

No, the moment that draw(9) is called, draw(10) goes on pause while draw(9) runs, which pauses when it calls draw(8) … which repeats (or recurses) until draw(0) gets called. Then it returns which returns to draw(1). The draw(1) un-pauses and does the #\n bit and returns to draw(2), which un-pauses and does ##\n and so forth until draw(10) does ##########\n

Gotcha. Thanks for the explanation.

When the draw function calls itself it yields control to that new function its calling. When that function ends it takes back control and continues doing what it was doing.

This means all of the for loops in all of the functions will execute. Draw(1) will do the for loop and then return as it hits the end of the function (standard behaviour when you reach the end of a function even if theres no return statement). Then draw(2) will do the for loop as it gets back control now that draw(1) is done and then return, etc. all the way up

All parts of a function are recursive, theres no such thing as a non recursive part

The for loop doesn't return, it's just that when control flows to the end of the function, returning is the standard behaviour. It has nothing left to do, so control is returned to the calling code.

The recursive portion is begun with draw(n - 1), but then you have a new for loop, because the same function has been called again. That's what recursion is. Nothing in this function is non-recursive. It calls itself, so all of the code it contains could be happening from the initial call, or within a recursive call. When draw(3) is called, you will get 3 for loops. You will actually get 4 draw calls, but the last one will be draw(0) which returns immediately.

It's confusing slightly because it works in reverse to what you'd expect. The operational part of the code - the part that does the drawing - only completes after the recursion is finished. That's why it does draw(1) first, to make the pyramid right way up.

I don't know that I've ever done recursion like this. It seems deliberately fancy and somewhat confusing for a new learner.

Imagine if you put the for loop before the recursive call. What would happen? You would draw three first, then decrease, so you would have an inverted pyramid. That would be easier to understand, but it would also not make a pyramid.

This is all a really great example of how The Stack works. As the loop recurses it continually adds to the program stack in memory and then plays the next “item” in the stack. There is a specific limit to recursion as well based on this principle.