控制如何通过这些多次调用递归到递归函数?

时间:2017-10-17 08:11:09

标签: c recursion

 #include<stdio.h>
 void display(int n)
 {
     if(n)
     {
        display(n-1);               
        printf("display 1\n"); 
        display(n-1);
        printf("display 2 ");
     }
 }

 int main()
 {
     display(5);
     return 0;
 }

控制如何在display_1display_2之间切换?

这两个电话之间的关系是什么?它们是如何在这里工作的?

我非常熟悉使用递归的 factorial 程序。但我在这里感到困惑,以判断display_1是否会调用display_2,反之亦然。

代码的输出:

screen capture

1 个答案:

答案 0 :(得分:3)

探索控制流有多种可能性(只要没有多线程或多处理,在这种情况下不是这样)。

一种选择是在调试器中逐步执行示例代码。另一种选择可能是“printf”调试。为此,我在您的原始代码中添加了一些printf()

#include <stdio.h>

void display(int n, int depth)
{
  printf("%*sdisplay(%d) entered\n", depth * 4, "", n);
  if (n) {
    printf("%*s1st call display(%d)\n", depth * 4, "", n - 1);
    display(n - 1, depth + 1);               
    printf("display 1\n");
    printf("%*s2nd call display(%d)\n", depth * 4, "", n - 1);
    display(n - 1, depth + 1);
    printf("display 2\n");
  }
  printf("%*sleaving display(%d)\n", depth * 4, "", n);
}

int main(void)
{
  /*
  printf("call display(5)\n");
  display(5, 0);
  */
  printf("call display(2)\n");
  display(2, 1);
  return 0;
}

ideone上编译并执行:

call display(2)
    display(2) entered
    1st call display(1)
        display(1) entered
        1st call display(0)
            display(0) entered
            leaving display(0)
display 1
        2nd call display(0)
            display(0) entered
            leaving display(0)
display 2
        leaving display(1)
display 1
    2nd call display(1)
        display(1) entered
        1st call display(0)
            display(0) entered
            leaving display(0)
display 1
        2nd call display(0)
            display(0) entered
            leaving display(0)
display 2
        leaving display(1)
display 2
    leaving display(2)

此外,我使用缩进来可视化递归深度。 那么,目前还不清楚吗?

因此,display()的每次调用都会产生两个递归下降(如果n尚未0),其中被调用的display()再次进行两次递归下降(如果{{1}还没有n)等等(直到递归终止)。

此模式的一个非常相似的常见应用是Fibonacci number的计算。

遍历树结构是此模式的另一个类似应用(在Tree traversal中提到)。在binary tree的情况下,每步有两个可能的递归调用。 (在一般树中,有与节点有子节点一样多的递归调用。)