[英]Tracing Recursive Function
以下程序的输出如下所示: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 = %d\t", n);
}
int main()
{
countdown(2);
return 0;
}
printf
有两个printf
,序列中的最后3个printfs
( n = -1 n = 0 n = 1
)由第二个printf
调用打印,这就是为什么它再次上升的原因。 您忘记了那个。 递归结束后,函数将返回上一级并从该处继续。
最终n--
用于执行n==0
, n
变为负, n >= 0
是评估为假,并countdown(n)
,不执行任何更多。 那是终端盒。 这意味着该函数将停止调用自身,并继续执行下一条语句,即第二个printf
,该语句将打印n = -1
。
然后该函数返回,最后一个函数继续执行,执行第二个printf
,您将得到n = 0
。 然后该函数结束并返回到第一级,在此执行第二个printf
,您将得到n = 1
。 然后函数返回到main
。
如果您在递归中稍稍更改了printf
,您将立即看到为什么得到输出。 尝试这个:
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
每次调用countdown函数时,您将执行两个printf语句(递归countdown()调用之前和之后)。
这里有点难以说明,但是让我们看一下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
对于n = 1
和n = 0
,将堆栈位置保存到前面以暂时停止该功能。 在n=-1
情况下,堆栈从保存的位置返回。 这就是为什么您再次得到n = 0
和n = 1
反向顺序。 我建议您看一下stack
结构,从而掌握递归逻辑。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.