有人能解释一下为什么printf会执行吗?还是那个人错了?
因为
main
返回。
这个答案写出了逻辑,但我看到你仍然在评论中提出这个问题。所以我会用另一种方式说同样的话,希望对你更清楚。
因为该变量是
static
,在第一次调用之前,变量被声明并设置为4.由于它是
static
,每次都会使用相同的变量。如果再次调用它(或者很可能在第一次调用时),它只是跳过了声明和初始化。
在第一次调用中,变量减少到3。3是真值,所以我们执行
if
块。这将递归调用
main
。
在第二次调用中,变量减少到2。2在C语言中仍然是真值。我们再次递归调用
main
。
在第三次调用中,变量减少到1。1仍然是真值。我们再次递归到
main
。
在第四次调用中,变量减少到0。0在C语言中是假值。我们不进入
if
块。我们不递归。我们不打印。在这次调用
main
中没有剩余的任务可做。它在结尾处返回。
现在我们回到了第三次调用。 我们刚从对main
的调用返回。 我们仍然在if
块内部。 下一条语句是一个printf
。 变量的值现在为0。 因此,我们打印出0。 没有其他事情可做,我们在结尾处返回。
现在我们回到了第二次调用。 仍然是0,所以我们再次打印0并返回。
现在我们回到了第一次调用。 仍然是0,所以我们再次打印0并返回。
我们打印了3次0,所以是000。
正如您所注意到的,在下降的过程中,我们不会打印。 我们在回程时打印。 那时,变量为0。 然后我们进入if
的then块3次。 因此,我们递归,然后打印3次。
当您递归调用函数时,不会消除先前的调用。 它被放在堆栈上。 完成后,您回到离开的地方,并继续执行下一条语句。
您可能想考虑以下三个代码片段将如何产生不同的反应:
void recurse() {
static int i = 4;
if (--i) {
recurse();
printf("%d", i);
}
}
第一次调用时打印000。第二次调用可能不会打印任何内容并崩溃。如果您的堆栈比int
大小大(这在理论上似乎不太可能,但并非不可能),则会打印许多0。例如,对于8位int
,它将打印255个0(每个可能的非零值都有一个)。
void recurse(int i) {
if (--i) {
recurse(i);
printf("%d", i);
}
}
如果以recurse(4)
的形式调用,将会打印出123。作为参数,每次函数调用时我们都在处理不同的i
。
void recurse(int i) {
if (--i) {
printf("%d", i);
recurse(i);
}
}
如果以recurse(4)
调用,则打印321。在下降时打印而不是在返回时打印。
void recurse(int i) {
printf("%d", i);
if (--i) {
recurse(i);
}
}
如果以recurse(4)
的形式调用,将打印4321。 它在向下的过程中打印,而不是在向上的过程中。
void recurse() {
static int i = 4;
printf("%d", i);
if (--i) {
recurse();
}
}
将会打印4321。我们是在向下执行时进行打印,而不是向上执行。请注意,参数和static
变量以这种方式给出相同的结果。但是,如果再次调用此函数,它将不会有任何作用。参数将再次打印相同的内容。
void recurse() {
int i = 4;
if (--i) {
recurse();
printf("%d", i);
}
}
循环永远执行。没有使用"static",每次都会创建一个新的"i"。这将一直运行,直到超载堆栈并崩溃。没有输出,因为它从未达到"printf"。
最简单的方法是去ideone.com之类的地方运行代码来检查。询问为什么会打印某些内容是合理的,但询问它打印了什么则应该自己回答。
main
会导致未定义的行为。如果想要的话,这段代码可能会让你的机器着火。 - cHaoprintf
,并且你说它是C,所以C++标签是错误的。 - Marcus Müllermain()
函数的意外输出”非常相似。打印结果不同,并且还有一个额外的本地变量也被打印出来,但是…… - Jonathan Leffler