我在递归中遇到了这个问题。我不知道它是如何工作的。我了解递归的基础知识,但这完全让我困惑。请帮助。
main() {
foo(3);
}
void foo(int x) {
if (x >= 1) {
foo(--x);
printf("%d", x);
foo(--x);
}
}
我以为这个程序不会打印任何东西,但它打印的是0120。
对foo(--3)即foo(2)的第一次调用不会跳转到函数的开头并重复到3次递减到0吗?
请解释这是如何工作的。
对foo()
的第一次调用可以使用递归树来解释:
prints (in reverse order)
2 <---------- foo(3)
/ \
1 <----- foo(2) foo(1) -----> 0
/ \ / \
0 <-- foo(1) foo(0) foo(0) foo(-1)
/ \
foo(0) foo(-1)
首先,将评估左侧子树并打印012
,然后评估右侧子树并打印0
。最后你得到输出:
0120
所以foo(3)是:
foo(2)
print 2
foo(1)
foo(2)是:
foo(1)
print 1
foo(0)
foo(1)是:
foo(0)
print 0
foo(-1)
现在foo(0)和foo(-1)是no-ops,所以foo(1)是:
print 0
foo(2)的来源是:
print 0
print 1
foo(3)是:
print 0
print 1
print 2
print 0
这为您提供了观察到的输出。
这是预期的输出。下一个函数调用被推送到堆栈,并且printf语句在前一个函数调用返回之前不会执行。
foo(3) --> foo(2) --> foo(1) --> foo(0)
现在x不是
foo(3) --> foo(2) --> foo(1) --> foo(-1)
// ^^ second foo() call from foo(1)
电流输出:
0
这什么也不做。foo(-1)和foo(1)从堆栈中弹出。
现在从foo(2)调用printf,1转到标准输出。
调用foo(0)。
foo(3) --> foo(2) --> foo(0)
// ^^ second foo() call from foo(2)
电流输出:
01
foo(0)什么都不做,然后弹出堆栈的foo(0)和foo(2)。
现在我们在foo(3)中。打印2并调用foo(1)。
foo(3) --> foo(1)
// ^^ second foo() call from foo(3)
电流输出:
012
foo(1)调用foo(0)然后打印0,然后调用foo(-1)。现在所有剩余的foo都从堆栈中弹出,输出为0120。
@haccks-看这个程序。有对foo(-1)的调用。
#include <stdio.h>
void foo(int);
int main() {
foo(3);
return 0;
}
void foo(int x) {
if (x >= 1) {
printf("executing foo with x = %d\n",x-1);
foo(--x);
printf("original output: %d\n", x);
printf("executing foo with x = %d\n",x-1);
foo(--x);
}
}
输出:
executing foo with x = 2
executing foo with x = 1
executing foo with x = 0
original output: 0
executing foo with x = -1
original output: 1
executing foo with x = 0
original output: 2
executing foo with x = 1
executing foo with x = 0
original output: 0
executing foo with x = -1