什么时候无限循环和没有停止条件的递归函数最终会停止?

xsa*_*i3x 3 stack-overflow recursion infinite-loop

我听到一个神话说无限循环或没有停止条件的递归函数将在"堆栈溢出"时停止.这样对吗?

例如 :

void call()
{
call(); 
} 
Run Code Online (Sandbox Code Playgroud)

要么

for(;;){;}
Run Code Online (Sandbox Code Playgroud)

当堆栈溢出时,它们真的会停止吗?

更新:如果它真的停止了,我可以检测多少递归调用?

Mic*_*tta 5

您的第一个示例是递归方法调用 - 每次调用call(在大多数语言和环境中)将创建一个新的堆栈帧,最终您将耗尽堆栈(您将获得堆栈溢出条件).

你的第二个例子不涉及递归方法调用 - 它只是一个循环.不需要创建堆栈帧,堆栈不会溢出.

给你的例子一个镜头 - 第一个例子将导致堆栈溢出比你想象的更快.第二个会让你的粉丝真的快速旋转,但除非你杀了它,否则什么都不会发生.


tem*_*def 5

这实际上取决于语言的选择。

在某些语言中,您的无限递归函数将因基于系统或语言相关条件的堆栈溢出而停止。这样做的原因是许多函数调用和返回的实现会为每个函数调用分配新的空间,当空间耗尽时程序将失败。然而,其他语言(Scheme 和各种 gcc 优化级别)实际上会让这个程序永远运行,因为它们足够聪明,意识到它们可以为每次调用重用空间。

在某些语言中,无限循环将永远运行。您的程序将继续运行,永远不会取得进展。在其他语言中,编译器允许对无限循环进行优化。例如,C++ 标准规定编译器可以假设任何循环要么终止,要么执行一些全局可见的操作,因此如果编译器看到无限循环,它可能只会优化循环不存在,所以循环实际上确实终止了。

换句话说,这真的取决于。这个问题没有固定的答案。

希望这可以帮助!