【问题标题】:Recursive Function with two calls带有两个调用的递归函数
【发布时间】:2021-11-24 04:01:47
【问题描述】:

这里我有一个来自geeksforgeeks.com的递归代码

#include<stdio.h>
void fun(int x)
{
  if(x > 0)
  {
     fun(--x);
     printf("%d\t", x);
     fun(--x);
  }
}
 
int main()
{
  int a = 4;
  fun(a);
  return 0;
}

我自己真的迷路了,我无法理解这个功能的工作原理。据我所知,首先,函数的递归每次调用都存储在堆栈中,并在达到基本情况后开始弹出。但是,我无法理解在第二次调用 printf 函数之后它是如何工作的。谁能给我解释一下?如果是这样,我很高兴。 提前感谢您的可爱贡献。

【问题讨论】:

  • 只需使用调试器遍历它,或者添加更多打印语句以显示发生了什么。

标签: c recursion


【解决方案1】:

首先,我建议你阅读一本关于递归的书,例如 Rozsa Peter 或 Daniel Friedman(The little schemer)的书,或者最好参加一些第一年的课程/mooc of Introduction .之后你可以学习more advanced stuff

你有这个代码:

void fun(int x)
{
  if(x > 0)
  {
     fun(--x);
     printf("%d\t", x);
     fun(--x);
  }
}

假设你调用 fun(4)。

在这种情况下,您有一个sigma-recursive operator(也称为primitive recursion)。递归需要一些限制情况。在这种情况下,它是一个简单的线性递归,只有“计数器达到空值”的情况(与 Peano 算术的定义相同)。

如果达到 0,则结​​束。否则,它会调用自身,计数向极限情况减 1,然后再堆叠 2 次调用:

 printf("%d\t", x);
 fun(--x);

最后一个调用在尾部位置,所以它什么也不做,它修改了一个不再使用的局部变量。所以你的功能减少到这样:

void fun(int x)
{
  if(x > 0)
  {
     fun(--x);
     printf("%d\t", x);
  }
}

正如其他答案所说,此函数将堆叠一些调用,我不再重现其他答案中存在的堆栈。

实际上,

  • 它为 f(4) 调用自己,
  • 然后是 f(3),
  • 然后是 f(2),
  • 然后是 f(1),
  • 那么 f(0) 是极限情况,
  • 然后它从 f(1) 返回堆叠的 printf,并打印 1,
  • 然后它从 f(2) 和 PRINTS 2 返回到堆叠的 printf,
  • 然后它从 f(3) 和 PRINTS 3 返回到堆叠的 printf,
  • 然后它从 f(4) 返回到堆叠的 printf,并打印 4。

【讨论】:

    【解决方案2】:

    下面的细节说明了使用缩进的调用深度,并显示了对funprintf 的调用,以说明执行顺序和打印输出:

    Line 15: fun(4)                       --> depth 1 
        Line 6: x=3, fun(3)               --> depth 2
            Line 6: x=2, fun(2)           --> depth 3
                Line 6: x=1, fun(1)       --> depth 4
                    Line 6: x=0, fun(0)   --> depth 5, do nothing & return
                    Line 7: printf        --> "0"
                    Line 8: x=-1, fun(-1) --> depth 5, do nothing & return
                    Return                --> depth 3
                Line 7: printf            --> "1"
                Line 8: x=0, fun(0)       --> depth 4, do nothing & return
                Return                    --> depth 2
            Line 7: printf                --> "2"
            Line 8: x=1, fun(1)           --> depth 3
                Line 6: x=0, fun(0)       --> depth 4, do nothing & return
                Line 7: printf            --> "0"
                Line 8: x=-1, fun(-1)     --> depth 4, do nothing & return
                Return                    --> depth 2
        Line 7: printf                    --> "3"
        Line 8: x=2, fun(2)               --> depth 2
            Line 6: x=1, fun(1)           --> depth 3
                Line 6: x=0, fun(0)       --> depth 4, do nothing & return
                Line 7: printf            --> "0"
                Line 8: x=-1, fun(-1)     --> depth 4, do nothing & return
                Return                    --> depth 2
            Line 7: printf                --> "1"
            Line 8: x=0, fun(0)           --> depth 3, do nothing & return
            Return                        --> depth 1
        Return                            --> depth 0
    

    【讨论】:

      【解决方案3】:

      fun(x)中的x变量是本地的,第一次调用是x-1,第二次是x-2

      考虑最简单的情况

      fun(1)
      

      导致 fun(0) 和 fun(-1) 被调用

      fun(2)
      

      导致 fun(1) 和 fun(0) 被调用,因为 1 > 0,所以 fun(1) 也会在 fun(2) 调用 fun(0) 之前调用 fun(0) 和 fun(-1) )

      这是一个部分调用堆栈,根据调用的函数缩进

      fun(4)
        fun(3)
          fun(2)
            fun(1)
              fun(0)
              print
              fun(-1)
            print
            fun(0)
          fun(1)
            fun(0)
            print
            fun(-1)
          print
          fun(0)
        fun(2)
      ...
            
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-04-15
        • 1970-01-01
        • 2019-01-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多