简体   繁体   English

跟踪递归函数

[英]Tracing Recursive Function

The following program's output looks like this: n = 2 n = 1 n = 0 n = -1 n = 0 n = 1 以下程序的输出如下所示:n = 2 n = 1 n = 0 n = -1 n = 0 n = 1

I can follow through the program to the point where it prints out n = -1, but why does it go back up and prints n = 0 and n = 1 at the end? 我可以按照程序进行操作,直到打印出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;

}

There are two printf s in the function, the last 3 printfs ( n = -1 n = 0 n = 1 ) in your sequence are printed by the second printf call, that's why it goes up again. printf有两个printf ,序列中的最后3个printfsn = -1 n = 0 n = 1 )由第二个printf调用打印,这就是为什么它再次上升的原因。 You are forgetting about that one. 您忘记了那个。 When the recursion ends, the function returns back to the previous level and continues from there. 递归结束后,函数将返回上一级并从该处继续。

Eventually n-- is executed for n==0 , n becomes negative, n >= 0 is evaluates to false and countdown(n) is not executed any more. 最终n--用于执行n==0n变为负, n >= 0是评估为假,并countdown(n) ,不执行任何更多。 That's the terminal case. 那是终端盒。 That means that the function stops calling itself and continues and to the next statement which is the second printf , which will print n = -1 . 这意味着该函数将停止调用自身,并继续执行下一条语句,即第二个printf ,该语句将打印n = -1

Then the function returns and the last and continues, which executes the second printf and you get n = 0 . 然后该函数返回,最后一个函数继续执行,执行第二个printf ,您将得到n = 0 Then the function ends and returns to the first level, where the second printf is executed and you get n = 1 . 然后该函数结束并返回到第一级,在此执行第二个printf ,您将得到n = 1 Then the function returns back to main . 然后函数返回到main

If you change the printf sa little bit in your recursion, you'll see immediately why you get the output. 如果您在递归中稍稍更改了printf ,您将立即看到为什么得到输出。 Try this: 尝试这个:

void countdown (int n)
{

    printf("[1] n = %d\n", n);

    n--;

    if (n >= 0)

    {

            countdown(n);

    }

    printf("[2] n = %d\n", n);

}

Now the output will be 现在的输出将是

[1] n = 2
[1] n = 1
[1] n = 0
[2] n = -1
[2] n = 0
[2] n = 1

You have two printf statements being executed per call of the countdown function (one before and one after the recursive countdown() call). 每次调用countdown函数时,您将执行两个printf语句(递归countdown()调用之前和之后)。

It's a little hard to illustrate here, but let's look at how your countdown() function is being executed, and remember that in this case, the variable n is local to its associated function scope meaning that each occurrence of "n" within each countdown() function call is independent of the other. 这里有点难以说明,但是让我们看一下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

For n = 1 and n = 0 , stack position is saved to go ahead where the function is stopped temporarily. 对于n = 1n = 0 ,将堆栈位置保存到前面以暂时停止该功能。 After n=-1 case, the stack goes back from the saved positon. n=-1情况下,堆栈从保存的位置返回。 That's why you got n = 0 and n = 1 again with reversed-ordered. 这就是为什么您再次得到n = 0n = 1反向顺序。 I recommend you to look at stack structure thereby grasping recursion logic. 我建议您看一下stack结构,从而掌握递归逻辑。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM