递归
递归是函数调用自身的一种编程技术。在C语言中,递归的实现会占用内存栈(Call Stack),每次递归调用都会在栈上分配一个新的 “栈帧(Stack Frame)”,用于存储本次调用的函数局部变量、返回地址、参数等信息。简单点说:自己调自己。
顾名思义:
例子:
fun(void)
{
//一定要有结束条件
fun()
}
例子:
从 1 + 2 + 3 + ... + 100
函数递归的缺陷: 非常耗内存 不建议在函数中使用递归,如果将栈的内存耗尽,程序执行会出现报错:Segmetation fault (core dumped)
那么,在递归的过程中到底发生了什么事情呢? 以下将通过文字解析和图示说明递归对内存的占用情况,让大家直观的看见递归的过程。
栈帧(Stack Frame)的组成
每次函数调用(包括递归调用),都会在内存栈区中分配一个栈帧,主要用于存储以下内容:
函数参数:函数调用时传入的参数。
返回地址:函数执行完后需要返回到调用函数的位置,返回地址存储在栈帧中。
局部变量:函数内部定义的局部变量。
其他信息:如寄存器保存、栈指针、帧指针等(具体取决于编译器和硬件架构)。
递归调用时,每次调用都会创建一个新的栈帧,压入到内存栈中。递归结束时,函数逐层返回,栈帧依次弹出释放。
递归的内存占用过程
代码一:(上述示例) 使用递归的方式从 1 + 2 + 3 + … + 100 : 下面举一个更复杂的例子。 代码二:
#include
void recursiveFunction(int n) {
if (n == 0) {
printf("Recursion ends.\n");
return;
}
printf("Entering recursion: n = %d\n", n);
// 递归调用
recursiveFunction(n - 1);
printf("Exiting recursion: n = %d\n", n);
}
int main() {
recursiveFunction(3);
return 0;
}
执行过程分析:
初次调用 recursiveFunction(3),程序会在栈中分配一个栈帧,用于存储 <