我正在学习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;
}
所以在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..."
现在它已经达到0,我认为它应该循环说... “根本就没有瓶子......” 或者,至少,当它在堆叠中添加另一个瓶子时,为什么不说“哦,我又喝了一瓶。拿下一瓶?”
是什么原因导致代码转到另一个已建立的堆栈并从1-4跳过“放一个瓶子......”而不再遍历整个if/else
?
答案 0 :(得分:5)
这是一个recursive function,这意味着它“循环”,因为它自称。当函数以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
}
答案 1 :(得分:1)
在进行回收中的Put瓶印刷之前,你一直打电话给singSongFor。它最终将击中瓶子== 0然后它将不再递归循环,因为它无法达到singSongFor呼叫并完全结束。作为一个c#人我建议将其写为for循环,以便能够更好地可视化它,你可能会在递归中看到错误。快乐的编码。