objective-c - 关于一个递归代码的问题~
黄舟
黄舟 2017-04-22 09:00:04
0
2
481

最近在学习objective-c,教程中有一段代码没弄清楚,是关于递归的,我用截图的形式发上来,给大家看看

void singTheSong(int numberOfBottles) { if (numberOfBottles == 0) { printf("there are simply no more bottles of beer on the wall.\n"); } else { printf("%d bottles of beer on the wall. %d bottles of beer.\n", numberOfBottles, numberOfBottles); int oneFewer = numberOfBottles - 1; printf("Take one dowm, pass it around, %d bottles of beer on the wall.\n", oneFewer); singTheSong(oneFewer); printf("put a bottle in the recycling, %d empty bottles in the bin.\n", numberOfBottles); } } int main(int argc, const char * argv[]) { singTheSong(99); return 0; }

它的输出结果是这样的:

99 bottles of beer on the wall. 99 bottles of beer.
Take one dowm, pass it around, 98 bottles of beer on the wall.
98 bottles of beer on the wall. 98 bottles of beer.
Take one dowm, pass it around, 97 bottles of beer on the wall.
97 bottles of beer on the wall. 97 bottles of beer.
Take one dowm, pass it around, 96 bottles of beer on the wall.
96 bottles of beer on the wall. 96 bottles of beer.
Take one dowm, pass it around, 95 bottles of beer on the wall.
......(中间重复的省略)
1 bottles of beer on the wall. 1 bottles of beer.
Take one dowm, pass it around, 0 bottles of beer on the wall.
there are simply no more 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.
......(中间重复的省略)
put a bottle in the recycling, 98 empty bottles in the bin.
put a bottle in the recycling, 99 empty bottles in the bin.
Program ended with exit code: 0

这段代码,我看不懂的地方是,它如何从numberOfBottles等于0的时候,又继续运行了

printf("put a bottle in the recyling, %d empty bottles in the bin.\n", numberOfBottles);

这段代码呢?并且numberOfBottles一直在+1

请大家帮我解惑,谢谢了~

黄舟
黄舟

人生最曼妙的风景,竟是内心的淡定与从容!

全部回覆 (2)
迷茫

重點是: 你要理解函數呼叫會有压栈操作, 递归调用返回时会回到递归之前, 并继续執行遞歸呼叫之後的程式碼.

將你的singTheSong(99);替换成singTheSong(3);說下吧.

入参为3, 下面两行打印
3 bottles of beer on the wall. 3 bottles of beer.
Take one dowm, pass it around, 2 bottles of beer on the wall.

第一次遞歸呼叫singTheSong(2), 入參為2.第一次递归调用singTheSong(2), 入参为2.
注意, 此时singTheSong(oneFewer); 之后的printf打印不会出现, 因为递归调用还没有返回;
后面你看到的 numberOfBottles一直在+1 现象的直接原因就在这.注意, 此時singTheSong(oneFewer); 之後的printf列印不會出現, 因為遞歸呼叫還沒有回;

後面你看到的numberOfBottles一直在+1 現象的直接原因就在這.

第二次递归调用singTheSong(1), 入参为1
同样, singTheSong(oneFewer) 之后的printf打印不会出现;2 bottles of beer on the wall. 2 bottles of beer.
Take one dowm, pass it around, 1 bottles of beer on the wall.

第二次遞歸呼叫singTheSong(1), 入參為1

同樣, singTheSong(oneFewer) 之後的printf列印不會出現;第三次递归调用singTheSong(0), 入参为0, 直接打印下面一行, 并退出;
注意, 这里的退出是退回到第二次递归的栈. 并从singTheSong(oneFewer)之后的printf开始执行.1 bottles of beer on the wall. 1 bottles of beer.Take one dowm, pass it around, 0 bottles of beer on the wall.

第三次遞歸調用singTheSong(0), 入參為0, 直接打印下面一行, 並退出;

因为第二次递归入参为1, 所以这里打印下面一行
第二次递归调用退回到 第一次 递归的栈继续执行注意, 這裡的退出是退回到第二次遞歸的棧. 並從singTheSong(oneFewer)之後的printf開始執行.

there are simply no more bottles of beer on the wall.

因为第一次递归入参为2, 所以这里打印下面一行
第一次递归调用退回到最初的singTheSong(3)继续执行因為第二次遞歸入參為1, 所以這裡打印下面一行
第二次遞歸呼叫退回到 第一次 遞歸的棧繼續執行

put a bottle in the recycling, 1 empty bottles in the bin.

最初的singTheSong(3)调用入参为3, 所以打印下面一行.因為第一次遞歸入參為2, 所以這裡印下面一行
第一次遞歸呼叫退回到最初的singTheSong(3)繼續執行

put a bottle in the recycling, 2 empty bottles in the bin. put a bottle in the recycling, 3 empty bottles in the bin.
    Peter_Zhu

    執行順序問題,並沒有出現numberOfBottles一直在+1的情况
    singTheSong(99);执行时需要调用singTheSong(98);但此时singTheSong(99);並沒有執行完

    printf("put a bottle in the recyling, %d empty bottles in the bin.\n", numberOfBottles);

    該段代碼沒有被調用,直到singTheSong(0);运行完成之后,singTheSong(1);方法体中的最下面的printf代碼才被執行,然後依次遞歸,開始執行 2, 3, 4 ... 99

      最新下載
      更多>
      網站特效
      網站源碼
      網站素材
      前端模板
      關於我們 免責聲明 Sitemap
      PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!