了解啤酒瓶示例中的递归

Ral*_*lph 5 c recursion procedural

我自己在C中练习递归,我在网上找到了这个例子.但有一件事我不明白.

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); // This function calls itself!

    // Print a message just before the function ends
    printf("Put a bottle in the recycling, %d empty bottles in the bin.\n",
             numberOfBottles);
   }
}    
Run Code Online (Sandbox Code Playgroud)

然后我使用main方法:

 int main(int argc, const char * argv[])
{
  singSongFor(4);
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出是这样的:

墙上有4瓶啤酒.4瓶啤酒.拿一个,把它传递,墙上有3瓶啤酒.

墙上有3瓶啤酒.3瓶啤酒.拿一个,将它传递到墙上,两瓶啤酒.

墙上有2瓶啤酒.2瓶啤酒.拿一个,将它传递,墙上放一瓶啤酒.

墙上有1瓶啤酒.1瓶啤酒.拿一个,将它传递到墙上,0瓶啤酒.

墙上根本没有更多的啤酒瓶.

将一个瓶子放入回收处,在垃圾箱中放入一个空瓶子.

将一个瓶子放入回收处,在垃圾箱中放入2个空瓶子.

将一个瓶子放入回收箱中,在垃圾箱中放入3个空瓶子.

将一个瓶子放入回收箱中,将4个空瓶放入垃圾箱.

我非常了解第一部分,直到我来到"墙上再也没有啤酒瓶.后来我不明白可变数量的瓶子从1增加到4.

Nat*_*rot 6

较小的啤酒瓶(及其相应的回收)具有内在功能.你的功能树看起来像这样:

4 bottles of beer on the wall. 4 bottles of beer. Take one down, pass it around, 3 bottles of beer on the wall.
|   3 bottles of beer on the wall. 3 bottles of beer. Take one down, pass it around, 2 bottles of beer on the wall.
|   |   2 bottles of beer on the wall. 2 bottles of beer. Take one down, pass it around, 1 bottles of beer on the wall.
|   |   |   1 bottles of beer on the wall. 1 bottles of beer. Take one down, 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, 3 empty bottles in the bin.
Put a bottle in the recycling, 4 empty bottles in the bin.
Run Code Online (Sandbox Code Playgroud)


rod*_*igo 3

请注意,最后一个printf使用numberOfBottles变量,并且永远不会被修改。因此,从打印oneFewer瓶子返回后,它将打印带有 的回收文本numberOfBottles。请记住,每次调用函数时,局部变量都会有一种不同的体现。

如果你缩进对函数的调用,就会更容易看到:

4 bottles of beer on the wall...
  3 bottles of beer on the wall...
    2 bottles of beer on the wall...
      1 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, 3 empty bottles in the bin.
Put a bottle in the recycling, 4 empty bottles in the bin.
Run Code Online (Sandbox Code Playgroud)

现在,从同一列开始的每一行都是通过该函数的同一调用写入的。你看到瓶子的数量和回收的数量是如何吻合的吗?这是因为两者都使用相同的变量:numberOfBottles