这段代码如何跳转到最后一个字符串并反转堆栈?

ElR*_*ito 0 c stack

我正在学习C,这是一个自学成才的事情.这很好,但是当我有问题时会变得毛茸茸,所以我希望得到一些帮助!

我有一些代码,我被指示写,我理解代码,我理解堆栈如何工作(取一个,进入另一堆等),main()并将始终先运行.

但我不明白为什么,在numberOfBottles达到0之后,它不会继续循环.为什么它首先反转堆栈,它是如何跳转到最后一个字符串的呢?

#include <stdio.h>

void singSongFor(int numberOfBottles)
{
    if (numberOfBottles == 0)
    {
      printf("there are simply no more 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, pass it around %d bottles of beer on the wall. \n\n", oneFewer);

        singSongFor(oneFewer);
        printf("Put a bottle in the recycling, %d empty bottles in the bin. \n", numberOfBottles);
    }
}
int main(int argc, const char * argv[])
{
    singSongFor(4);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

所以在最底层if/else我们"在回收中放了一个瓶子",但我读它的方式是这样的:

4 take one down
3 take one down 
2 take one down 
1 take one down
0 "there are simply no more bottles..."
Run Code Online (Sandbox Code Playgroud)

现在它已达到0,我认为它应该只是循环说......"根本就没有更多的瓶......"或者,至少,当它在堆栈中添加另一个瓶子时,为什么不说"哦,我又喝了一瓶.拿下一瓶?"

是什么导致代码转到已建立的另一个堆栈并从1-4跳过"放一个瓶子......"并且不再通过整个if/else

Typ*_*eIA 5

这是一个递归函数,这意味着它"循环",因为它调用自身.当函数以4的参数运行时,它再次使用参数3调用自身.当它变为零时,由于该if语句,它不再调用自身,因此"循环"终止,并且控制开始返回备份函数调用链.

是什么导致代码转到已经建立的另一个堆栈并从1-4跳过"放一个瓶子......"并且不再通过整个if/else?

没有"其他堆栈".我认为通过这种方式思考堆栈会让你感到困惑.只需将其视为一个不断调用自身直到其参数为零的函数.如果你要绘制这个程序的嵌套函数调用序列,它看起来像这样(注意这是一个调用堆栈图,而不是C代码):

main()
{
    singSongFor(4)
    {
        // prints "4 take one down"
        singSongFor(3)
        {
            // prints "3 take one down"
            singSongFor(2)
            {
                // prints "2 take one down"
                singSongFor(1)
                {
                    // prints "1 take one down"
                    singSongFor(0)
                    {
                        // prints "0 there are simply..."
                    }
                    // prints "recycling 1"
                }
                // prints "recycling 2"
            }
            // prints "recycling 3"
        }
        // prints "recycling 4"
    }
    // end
}
Run Code Online (Sandbox Code Playgroud)