理解这个递归函数

时间:2015-12-07 21:41:25

标签: c++ c recursion

#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。

2 个答案:

答案 0 :(得分:1)

像这样的简单程序可以增加&#39;用一些印刷品来理解。

你原来的:

// 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次递归调用。 (SEQ = 9)
这是你所期望的吗?

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

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

逐步检查中间输出,看看它是如何工作的。

祝你好运。

答案 1 :(得分:0)

要理解递归函数,首先必须了解递归:) 尽管如此,请阅读维基百科页面以及您可以找到的任何其他文章。 https://en.wikipedia.org/wiki/Recursion

这里要记住的重要事项是,每次递归调用e都会增加你的调用堆栈,一旦你返回,你就会从你的调用堆栈弹出最后一帧,然后返回你上次调用e的地方

以下是您案例中实际发生的事情的步骤以及它为什么会这样做。调试器还允许您执行此操作:)

  1. e以3
  2. 进行调用
  3. 3&gt; 0所以我们用3 - 1(2)
  4. 来称呼e
  5. 2&gt; 0所以我们用2 - 1(1)
  6. 称呼e
  7. 1&gt; 0所以我们称e为1 - 1(0)
  8. 0不是&gt; 0所以当int n = 1
  9. 时我们返回
  10. 我们现在设置n = n - 1所以n = 0
  11. print n(打印0)
  12. 用0 - 1(-1)调用e - &gt;这只是返回
  13. 设置n = n - 1并返回n = 2
  14. 设置n = n - 1,因此n = 1
  15. print n(打印1)
  16. 用n - 1(0)调用e - &gt;这只是返回
  17. 设置n = n - 1并返回n = 3
  18. 设置n = n - 1,因此n = 2
  19. print n(打印2)
  20. 用n - 1(1)
  21. 打电话给e
  22. 1&gt; 0所以用n - 1(0)调用e - &gt;这只是返回
  23. 设置n = n - 1(0)
  24. print n(打印0)
  25. 用n - 1(-1)调用e - &gt;这只是返回
  26. 设置n = n - 1并在n = 3(原始函数调用)
  27. 时再次返回
  28. 这是我们函数调用的结束,我们现在返回打印0120