C 跟踪递归函数
以下程序的输出如下所示: n=2 n=1 n=0 n=-1 n=0 n=1 我可以继续执行程序,直到它打印出n=-1,但是为什么它会返回并在最后打印n=0和n=1呢C 跟踪递归函数,c,recursion,C,Recursion,以下程序的输出如下所示: n=2 n=1 n=0 n=-1 n=0 n=1 我可以继续执行程序,直到它打印出n=-1,但是为什么它会返回并在最后打印n=0和n=1呢 #include <stdio.h> void countdown (int n) { printf("n = %d\t", n); n--; if (n >= 0) { countdown(n); } printf("n = %
#include <stdio.h>
void countdown (int n)
{
printf("n = %d\t", n);
n--;
if (n >= 0)
{
countdown(n);
}
printf("n = %d\t", n);
}
int main()
{
countdown(2);
return 0;
}
#包括
无效倒计时(整数n)
{
printf(“n=%d\t”,n);
n--;
如果(n>=0)
{
倒计时(n);
}
printf(“n=%d\t”,n);
}
int main()
{
倒计时(2);
返回0;
}
函数中有两个printf
s,最后3个printfs
(n=-1n=0n=1
)
由第二次printf
调用打印,这就是它再次上升的原因。你忘了那件事了。什么时候
递归结束后,函数返回上一级并继续
从那里开始
最后,对n==0
执行n--
,n
变为负值,n>=0
设置为false,并且不再执行倒计时(n)。那是终端机。
这意味着函数停止调用自己,并继续调用下一个语句,即第二个语句
printf
,它将打印n=-1
然后函数返回最后一个并继续,执行第二个
printf
得到n=0
。然后函数结束并返回到第一个
级别,其中执行第二个printf
,得到n=1
。然后
函数返回到main
如果在递归中稍微更改printf
s,您将看到
你为什么马上得到输出。试试这个:
void countdown (int n)
{
printf("[1] n = %d\n", n);
n--;
if (n >= 0)
{
countdown(n);
}
printf("[2] n = %d\n", n);
}
现在输出将是
[1] n = 2
[1] n = 1
[1] n = 0
[2] n = -1
[2] n = 0
[2] n = 1
对于
n=1
和n=0
,将保存堆栈位置,以便在函数暂时停止时继续执行。在n=-1
case之后,堆栈从保存的位置返回。这就是为什么你得到了反向排列的n=0
和n=1
。我建议您查看堆栈结构,从而掌握递归逻辑。每次调用倒计时函数都会执行两条printf语句(一条在recursive countdown()调用之前,一条在recursive countdown()调用之后)
这里有点难解释,但让我们看看倒计时()函数是如何执行的,请记住,在本例中,变量n是其关联函数作用域的局部变量,这意味着每个倒计时()函数调用中出现的每个“n”都是相互独立的
countdown(2) <- spawns a new execution scope; let's call it S0
=> prints "n=2"
=> sets n=1 in scope S0
=> calls countdown(1) <- spawns a new execution scope; let's call it S1
----Inside S1----
=> prints "n=1"
=> sets n=0 in scope S1
=> calls countdown(0) <- spawns a new execution scope; let's call it S2
----Inside S2----
=> prints "n=0"
=> sets n=-1 in scope S2
=> if condition fails
=> prints "n=-1"
=> returns execution to scope S1
=> prints "n=0" (which is the value "n" has in scope S1)
=> returns execution to scope S0
=> prints "n=1" (which is the value "n" has in scope S0)
=> execution returns to main() function and program terminates
倒计时(2)打印“n=1”
=>在范围S1中设置n=0
=>调用倒计时(0)首先回答这个问题:它为什么打印n=-1?