我打算把这个问题解释为“函数如何记住函数返回时它正在做什么?”。
C++标准没有说(IIRC它留给执行找到一个有效的解决方案)。但实际上,答案是“堆栈”。
在计算机科学中,堆栈是一种后进先出的数据结构。将序列1,2和3推入一个堆栈,然后执行三次弹出,然后获得3,2然后1.
在早期,编程语言通常不支持递归调用或重入调用。每个函数/过程都拥有一小块内存,它存储它的参数,局部变量和完成后要返回的函数。如果你试图调用一个已经运行的函数,那就意味着将两组局部变量和两个返回地址存储在一个空间中,这是一个错误。
但是,IIRC Algol编程语言的创新之一是支持递归。大约在同一时间,“处理器堆栈”正在成为一件事情。
处理器堆栈(除其他外)允许您使用不同的方法来处理参数,局部变量和返回地址。您不需要为每个函数分配一个永久分配的块 - 当您调用该函数时,您会分配一个块(位于堆栈的顶部)。当前“堆栈帧”的位置是相对于当前的“堆栈指针”。这意味着您可以同时为堆栈中的相同功能设置多个堆栈帧。
所以调用一个函数需要在堆栈的顶部创建一个新的堆栈帧,并调整堆栈指针以适应。并且从函数返回涉及丢弃该堆栈帧并调回堆栈指针,所以顶层堆栈帧现在成为调用者的堆栈帧。这个调用者可能会或可能不会有相同的功能 - 它并不重要,因为每个调用都有自己的堆栈帧存储一组单独的参数,局部变量,单独的返回地址等。
所以就在Recursion (3)
之前调用,堆栈看起来是这样的......
|-------------------+-------------------+
| Recursion Frame 1 | Recursion Frame 2 |
|---------------+---+---------------+---+
| ??? | X | ??? | X |
|---------------+---+---------------+---+
| ??? | 1 | ??? | 2 |
|---------------+---+---------------+---+
^
|
STACK
POINTER
的???
代表“看家”的东西,如返回地址。
任何函数调用后会发生什么?当函数返回时,执行在调用后的下一行继续。 –
你有调试器吗?只是用它来遍历每一行,看看会发生什么 –
使用调试器来了解递归如何工作 – David