前几天,我的教授说:
当使用相同的值调用函数两次时,函数会重用结果(先前计算的值)。
但是,结果(先前计算的值)在堆内存中分配。
他举了一些例子,例如:斐波那契递归函数。
他犯错了吗?
当使用相同的值调用函数两次时,函数会重用结果(先前计算的值)。
默认情况下,没有。您可以记忆一个函数,以便它重用已经计算的结果,但这需要程序员(或者可能是编译器,但我不知道有任何 C 编译器这样做)的特殊干预。
缓存所有计算值会非常昂贵和浪费,因为大多数函数不会使用相同的参数重复调用。并且很难找到值得缓存的调用的良好启发式方法。因此,这些事情留给了程序员,他们希望对哪些函数值得缓存有更多的了解。
实际上,记忆化已经(在某种程度上)成为 C++11 的 C++ 标准的一部分。您可以查看使用新 C++11 功能自动记忆递归函数的介绍。
编辑:
这个问题是针对 C 而不是 C++。我错过了。这个答案不适用;我会删除它,但这里没有很多其他的记忆问题,而且很有可能它会帮助某人。
gcc
本身不会缓存任何以前的结果,但当然,对于许多递归函数,实现对以前计算的值的缓存是非常有意义的。
所以,如果他声称自己gcc
负责这个缓存,他就犯了一个错误。我想,他宁愿提到一些特定的实现,例如斐波那契函数。
不太一样,但我看到了 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)
. 当然,那里仍然有一些递归,但要少得多。