【问题标题】:How can I analyze a recursive source codes by hand?如何手动分析递归源代码?
【发布时间】:2011-06-21 04:22:17
【问题描述】:

如何手动分析递归源代码?

例如,我设计了一种手动分析迭代源代码的技术,如下所示:

int fact(int n) 
{ 
 int f = 0; 
 int i = 0; 
 if (n<=1)  
 {  
  return 1; 
 } 

 f = 1; 
 i = 2; 
 for (i=2; i<=n ; i++) 
 { 
  f *= i; 
 } 

 return f; 
}

---------------------------
  i         f       new-f
---------------------------
---------------------------
---------------------------

对于每个“i”,我可以手动分析和计算 old-f 和 new-f 的值,并填写表格以查看例程是否正常工作。

但是如何手动分析递归例程?

int fact(int number) {
    int temp;

    if(number <= 1) return 1;

    temp = number * fact(number - 1);
    return temp;
}

【问题讨论】:

    标签: c recursion


    【解决方案1】:

    由于递归将值存储在堆栈中,因此您需要对它进行 2 路分析

    第一遍是:进行递归,直到达到终止条件。

    第二遍:收集值直到堆栈为空。

    1st down  2nd up
    ---------------------------------
    n = 6     tmp = 6 * 120 = 720 <- result
    n = 5     tmp = 5 * 24 = 120
    n = 4     tmp = 4 * 6 = 24
    n = 3     tmp = 3 * 2 = 6
    n = 2     tmp = 2 * 1 = 2
    n = 1     end
    

    【讨论】:

    • @JMSA 不幸的是,这样解释是我自己的想法。我没有更多资源。
    • 你可以用谷歌“递归分析”找到像flylib.com/books/en/2.300.1.85/1这样的页面
    【解决方案2】:

    您可以使用调试器来执行此操作,而无需更改原始代码或编写新代码。 1.在名为fact的函数地址处设置断点 2.运行调试器,每次停在断点处,可以查看参数号的值,以及返回值

    【讨论】:

    • 没关系。但我正在寻找一个可以记录的过程。
    【解决方案3】:

    在处理递归函数时,有效表达函数正在做什么的方法是将其视为数学函数并简化函数的应用。虽然这并不能真正告诉您函数的内部状态(在本例中为 temp 的值),但它为您提供了一种描述函数的非常好的方式。

    对于阶乘示例,我们可以将 fact 定义为:

    fact(x) = 1 when x <= 1
    fact(x) = x * fact(x - 1) otherwise
    

    现在,当你想表达它的工作原理时,你可以选择一个小的起始数字(比如 6)然后...

    fact(6) = 6 * fact(5) = 6 * 5 * fact(4) = 6 * 5 * 4 * fact(3)
    

    等等。

    这样,您所做的是分析函数的结构而不是其实现。现在出于调试目的,这不是太有用(至少不是在非功能语言中)。但它对于 cmets、文档和交流来说非常棒。

    【讨论】:

      猜你喜欢
      • 2023-03-25
      • 1970-01-01
      • 2021-05-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多