Recursion 无限递归可以实现吗?

Recursion 无限递归可以实现吗?,recursion,memory,stack,stack-frame,Recursion,Memory,Stack,Stack Frame,我知道,对于C,至少每次调用递归函数时,堆栈帧和返回地址都会写入堆栈,但是有没有一种模糊的方法使它不会耗尽内存?显然,这纯粹是一个假设问题,因为我无法想象它的用例。您可以使用堆栈模拟递归 与函数调用和静态变量相关的内存部分(在C中用int x;声明)与与与动态分配相关的内存部分(在C中使用malloc())是分开的。只有前一种称为“堆栈”的方法是有限的,它会导致“堆栈溢出”错误。当然,这并不完全正确。后者被称为“堆”,当然,你的计算机不是魔法,如果你真的试图突破它的极限,它会在某个时候耗尽内存

我知道,对于C,至少每次调用递归函数时,堆栈帧和返回地址都会写入堆栈,但是有没有一种模糊的方法使它不会耗尽内存?显然,这纯粹是一个假设问题,因为我无法想象它的用例。

您可以使用堆栈模拟递归

与函数调用和静态变量相关的内存部分(在C中用
int x;
声明)与与与动态分配相关的内存部分(在C中使用
malloc()
)是分开的。只有前一种称为“堆栈”的方法是有限的,它会导致“堆栈溢出”错误。当然,这并不完全正确。后者被称为“堆”,当然,你的计算机不是魔法,如果你真的试图突破它的极限,它会在某个时候耗尽内存

您可以使用尾部递归来避免将层添加到调用堆栈中

堆栈溢出是由于调用堆栈的大小造成的。想象这样一个函数:

intf(intn)
{
int x;
if(n<2)
{
返回1;
}
其他的
{
x=f(n-1);
返回n*x;
}
}
当对
f
进行递归调用时,计算机需要记下一个事实,即一旦递归调用完成,我们需要再进行一次乘法。注意这一点是通过向“调用堆栈”添加一个层来实现的,该层包含一些关于变量值的信息,以及我们在代码中的位置。这需要内存,如果堆栈太大,将导致堆栈溢出

现在与以下代码进行比较:

intf(intn,intacc)
{
if(n<2)
{
返回acc;
}
其他的
{
返回f(n-1,n*acc);
}
}
这次递归调用直接封装在
返回中
,这意味着递归调用之后没有更多的工作要做。想象一下,你让我做一项工作,并向你报告结果;通过递归调用,我将一些工作委托给了我的朋友;然后,我马上离开,告诉我的朋友直接向你汇报,而不是等我的朋友向我汇报,这样我就可以向你汇报。这通过“切割中间人”来节省内存

阅读更多:

在具有惰性求值功能的语言中,您可以编写一个看似无限递归的函数,然后只根据需要求值:


您可以使用用户分配的堆栈来模拟递归。您还可以使用尾部递归来避免填充调用堆栈。在某些语言中,您可以编写一个看似无限递归的函数,但随后“惰性地”对其求值。