递归在计算机中是如何实现的 ? 换句话说,它最终被编译成什么样的机器语言 ? 这就要从函数调用说起。实际上,一台典型的32位计算机采用 “堆栈结构”
来实现函数调用,它在汇编语言中,把函数所需的第k个,第k - 1个,..第1个参数依次入栈,然后执行call(address)指令。该指令把返回地址(当前语句的下一条语句的地址)入栈,然后跳转到address位置的语句。在函数返回时,它执行ret指令。该指令把返回地址出栈,并跳转到该地址继续执行。
对于函数中定义的C + 局部变量,在每次执行call与ret指令时,也会在“栈”中相应地保存与复原,而作用范围超过该函数的变量,以及通过new和malloc函数动态分配的空间则保存在另一块称为 “堆”(注意, 这个堆与我们所说的二“寄存器 , 完成。的概念)的结构中。栈指针、 返回值、局部的运算会借助CPU的 ”寄存器“
完成
- 局部变量在每层递归中都占有 - 份空间, 声明过多由此我们可以得知 : 或递归过深就会超过“栈”
所能存储的范围,造成栈溢出。 - 非局部变量对于各层连归都共享同份空间,需要及时维护、还原现场,以防止在各层递归之间存储和读取的数据互相影响。
了解了递归的机器实现之后,我们就可以使用模拟的方法,把递归程序改写为非递归程序。具体来说,我们可以使用一个数组来模拟栈,使用变量来模拟栈指针和返回值,使用 switch / case
或者goto / label
来模拟语句跳转。