理解这个递归函数

understanding this recursive function

本文关键字:递归函数      更新时间:2023-10-16
#include <stdio.h>
void e(int );      
int main( ) 
{   
    int a;    
    a=3;    
    e(a); 
    return 0;
}    
void e(int n)  
{    
    if(n>0)   
    {
        e(n-1); 
        n = n-1;     
        printf("%d" , n);      
        e(n-1);  
        n = n-1; 
    }    
} 

我不明白这如何计算为 0120,因为我认为如果它是 0,if 语句就不会运行......我知道我不擅长编码,但想知道是否有人可以解释它是如何输出 0120 的。

像这样的简单程序可以通过一些打印来"增强"以理解。

您的原件:

// original
void e(int n)
{
   if(n>0)
   {
      e(n-1);
      n = n-1;
      printf("%d" , n);
      e(n-1);
      n = n-1;
   }
}

它的输出是相同的(即使使用 C++ 编译(

// 0120

这是非常相似的递归代码,还有几张打印

// with debug prints
void e2(int n, std::stringstream& ss)
{
   static size_t seq = 0;
   std::cout << "seq=" << ++seq << " e2() " << "  n=" << n << std::endl; // invocation sequence
   if(n>0)
   {
      e2(n-1, ss);
      n = n-1;
      ss << "n= " << n << " " << std::flush;
      e2(n-1, ss);
      n = n-1;
   }
   else
      std::cout << "seq=" << seq << " e2()   else " << n << std::endl;
}

并且使用的调用:

int t267(int argc0)
{
   std::cout << "argc0: " << argc0 << std::endl << std::endl;
   int a = 3;
   std::cout << "ne()----------------------------" << std::endl;
   e(a);
   std::cout << "ne2()----------------------------" << std::endl;
   std::stringstream ss;
   ss << "e2: " << std::endl;
   e2(a, ss);
   std::cout << ss.str() << std::endl;
   std::cout << "n----------------------------" << std::endl;
   return(0);
} // int t267(void)

一些中间输出:

seq=1 e2()   n=3
seq=2 e2()   n=2
seq=3 e2()   n=1
seq=4 e2()   n=0
seq=4 e2()   else 0
seq=5 e2()   n=-1
seq=5 e2()   else -1
seq=6 e2()   n=0
seq=6 e2()   else 0
seq=7 e2()   n=1
seq=8 e2()   n=0
seq=8 e2()   else 0
seq=9 e2()   n=-1
seq=9 e2()   else -1

ss 捕获所有 n= x,以更简单的方式报告它们,而不是在调试 cout 之间交错。 ss的输出:

n= 0 n= 1 n= 2 n= 0   

注意:这显示了与原始数字相同的数字序列

它还显示发生了 9 次递归调用。(顺序=9(
这是你所期望的吗?

。调试打印通常也可以提供足够的信息来观察和修复编码错误。

接下来尝试 a=0,或 1,或 2,或 4,...等。并尝试添加其他打印件。
实践。

并逐步查看中间输出以了解其工作原理。

祝你好运。

要理解递归函数,您必须首先了解递归:)说真的,去阅读维基百科页面和你能找到的任何其他文章。https://en.wikipedia.org/wiki/Recursion

这里要记住的要点是,每次对 e 的递归调用都会增加你的调用堆栈,一旦你返回,你就从调用堆栈中弹出最后一帧并返回到你上次调用 e 的位置

以下是在您的案例中实际发生的情况以及它为什么这样做的步骤。调试器还将允许您执行此演练:)

  1. e 被调用 3
  2. 3> 0 所以我们用 3 - 1 (2( 调用 e
  3. 2> 0,所以我们用 2 - 1 (1( 调用 e
  4. 1> 0 所以我们用 1 - 1 (0( 调用 e
  5. 0 不是> 0,所以我们回到 int n = 1 时
  6. 我们现在设置 n = n
  7. - 1 所以 n = 0
  8. 打印 n (打印 0(
  9. 用 0 - 1 (-1( 调用 E>这只返回
  10. 设置 n = n
  11. - 1 并在 n = 2 时返回
  12. 集合 n = n
  13. - 1 所以 n = 1
  14. 打印
  15. n(打印 1(
  16. 用 n - 1 (0( 调用 e>这只返回
  17. 设置 n = n
  18. - 1 并在 n = 3 时返回
  19. 集合 n = n
  20. - 1 所以 n = 2
  21. 打印
  22. n(打印 2(
  23. 用 n - 1 调用 E (1(
  24. 1> 0 所以用 n - 1 (0( -> 调用 e ,这只返回
  25. 集合 n = n - 1 (0(
  26. 打印 n (打印 0(
  27. 用 n - 1 (-1( 调用 e>这只返回
  28. 设置 n = n
  29. - 1 并再次返回到 n = 3 时(原始函数调用(
  30. 我们的函数调用到此结束,我们现在返回打印 0120