【问题标题】:Tail recursion in C and SICPC 和 SICP 中的尾递归
【发布时间】:2016-03-23 12:17:08
【问题描述】:

我对 SICP 中的以下段落感到困惑:

过程和过程之间的区别可能令人困惑的一个原因是,大多数通用语言(包括 Ada、Pascal 和 C)的实现都是以这样一种方式设计的,即任何递归过程的解释 消耗的内存量随着过程调用的数量而增长,即使所描述的过程原则上是迭代的。因此,这些语言只能通过使用特殊用途的“循环结构”来描述迭代过程,例如 do、repeat、until、for 和 while。

据我了解,您实际上可以在 C 中编写尾递归过程(函数):

Tail recursion in C

那么,对上述段落的正确解释是什么?

【问题讨论】:

  • 虽然以链接答案建议的样式编写函数有助于尾递归,但还需要实际的编译器支持,编译器可以检测尾递归,然后重用函数上下文。如果编译器不能这样做,那么你所拥有的只是正常的递归,只是递归调用是在一个特殊的地方进行的。

标签: c


【解决方案1】:

如 cmets 中所述,虽然您可以在 C 中编写尾递归算法,但不能保证生成的代码不会在每次尾调用时分配额外的堆栈内存。这正是过去几乎所有历史 C 实现中都会发生的情况,使得尾递归变得不切实际。

在现代 C 中,这是一个实施质量问题。例如,多年来,GCC 已经能够将许多尾递归实例优化为等效迭代。尽管如此,与 Scheme 相比的主要区别在于,Scheme 保证尾调用消除,而 C 没有而且不太可能这样做。

【讨论】:

  • 有趣。我没有意识到 GCC 做了那个优化。也许 SICP 是在此之前编写的,尽管不能保证优化仍然很重要。
  • @JohnColeman GCC 不仅优化了这一点,它甚至优化了一些 非尾 递归,例如传统的递归阶乘。真的是quite fascinating
猜你喜欢
  • 2011-02-11
  • 2021-08-24
  • 1970-01-01
  • 2011-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-21
相关资源
最近更新 更多