预期的无限递归,没有
无限递归通常是不需要的,当它发生时,通常会导致堆栈溢出或段错误。
但是出于理论和朴素的好奇心,我一直在考虑是否可以有意地创建实际的无限递归。
使用C ++和C工作,通常每个函数调用都会增加堆栈,每个函数都会返回并弹出它处理的堆栈部分。
这是这个想法。 是否有可能强制函数清除它自己的堆栈空间,然后调用另一个函数,以便新函数有效替换第一个函数,而不需要第一个函数需要返回,然后通过循环再次启动。
如果可能的话,我不仅仅将纯循环看作是可能的用途。 循环通常在他们所做的事情上做得很好。 但是如果你用它来通过一个节点网络发送信号,这些信号会在它们自己的进程线程中无限期地继续,直到它们达到一定的条件。 它可能是一个可用于某些问题的工具。
请记住,我并不真正在问是否可行,只有在可能的情况下。 为了科学!
是否有可能强制一个函数清除它自己的堆栈空间,然后调用另一个函数,以便新函数有效地替换第一个函数
这是用于尾巴呼叫优化,所以是的,这是可能的,并在实践中使用。 在像C ++这样的语言中,这是一个很好的特性,因为有时候算法使用递归表达更简单,但是使用循环更有效地实现。 在某些情况下,转换可以由编译器自动完成。
有一种称为蹦床的技术,用于在不使用尾部呼叫优化的情况下实现继续传递式样编程。 如果您认为没有TCO支持的任何语言(如JavaScript)以及该语言的CPS研究解决方案,那么解决方案很可能涉及蹦床。
实质上,在蹦床运动中有一个称为蹦床的功能,它迭代地调用回程功能。
我知道你说“没有第一个函数需要返回然后通过循环再次触发” - 这就是蹦床 - 但考虑到这是C ++,例如,返回范围是C ++核心设计的核心。通过析构函数自动进行资源管理(请参阅:RAII)。 您也可以使用C的setjmp()
/ longjmp()
函数来清除堆栈,但是在确保所有资源都已正确释放时需要非常小心。
这确实让我想起了可以用汇编代码完成的优化。 说你有这个:
call FuncA
call FuncB
您可以将其替换为:
push ReturnAddress
push FuncB
jmp FuncA
ReturnAddress:
这会导致FuncA
结束时的ret
直接跳到FuncB
,而不是返回给调用者,然后返回到FuncB
。 在高级语言中不太可能。
还有这个:
call FuncA
ret
可以将其更改为:
jmp FuncA
链接地址: http://www.djcxy.com/p/80521.html