GCC编译器在递归函数中的行为

时间:2012-04-21 22:37:55

标签: c gcc recursion

几天前,我的教授说:

  

一个函数在使用相同的值两次调用时重用结果(先前计算的值)。

但是,结果(先前计算的值)在堆内存中分配。

他给出了一些例子,例如:Fibonacci递归函数。

他犯了错误吗?

4 个答案:

答案 0 :(得分:3)

  

当一个函数被调用两次相同的值时,它会重用结果(先前计算的值)。

默认情况下,没有。你可以 memoize 一个函数,这样它就可以重用已经计算过的结果,但这需要程序员(或者可能是编译器)的特殊干预,但我不知道任何C编译器会这样做。

缓存所有计算值会非常昂贵且浪费,因为大多数函数不会使用相同的参数重复调用。并且很难找到一个好的启发式调用,这些调用值得缓存。因此,这些事情留给了程序员,他们希望能够更好地了解缓存哪些函数值。

答案 1 :(得分:2)

gcc本身不会缓存任何先前的结果,但当然,对于许多递归函数,实现缓存先前计算的值非常有意义。

所以,如果他声称,gcc负责这个缓存,他犯了一个错误。我想,他宁愿提到一些具体的实施例,例如:斐波那契函数。

答案 2 :(得分:2)

实际上,memoization已经(在某种程度上)成为C ++ 11的C ++标准的一部分。您可以使用新的C ++ 11功能查看automatic memoization of recursive functions的这个简介。

编辑:

这个问题适用于C而不是C ++。我错过了。这个答案是不适用的;我会删除它,但这里没有其他许多记忆问题,很有可能它会帮助某人。

答案 3 :(得分:0)

不太一样,但我看到gcc执行内联递归函数的报告。以斐波那契函数f(x) = f(x - 1) + f(x - 2)为例;显然gcc可以内联对f(x - 1)的调用,从而产生f(x) = 2f(x - 2) + f(x - 3),然后使用尾递归优化将其转换为循环:f(x) = 2f(x - 2) + 2f(x - 5) + ... + f(x % 3)。当然,那里还有一些递归,但它要少得多。