【发布时间】:2014-04-05 08:13:50
【问题描述】:
let rec x1() = x1();()
let rec x2() = x2();;
调用 x1();;调用 x2(); 时产生堆栈溢出;导致程序无限期地运行。这两个函数有什么区别?
【问题讨论】:
标签: recursion stack overflow ocaml
let rec x1() = x1();()
let rec x2() = x2();;
调用 x1();;调用 x2(); 时产生堆栈溢出;导致程序无限期地运行。这两个函数有什么区别?
【问题讨论】:
标签: recursion stack overflow ocaml
let rec x1() = x1();()
这个函数不是尾递归的。它称自己为 x1();当此调用返回时,该函数将返回一个单位()。
let rec x2() = x2();;
这个函数在最后调用自己;因此编译器可以执行尾调用优化——这意味着递归函数调用永远不会用完所有的堆栈空间。
本页解释尾递归:http://ocaml.org/learn/tutorials/if_statements_loops_and_recursion.html#Tailrecursion - 这是函数式编程语言使用的一项基本技术,因此我们可以使用递归来实现循环而不会耗尽内存。
在阅读Smashing The Stack For Fun And Profit时,我第一次了解了进程堆栈;我仍然认为它最好地描述了进程堆栈的全部内容。
【讨论】: