初识递归
复习c语言,捡起我的算法书,总结摘抄一部分内容放在这里:)
简单了说,递归就是自己用到自己的意思。
简洁而严密就是递归定义的优点。
数学函数也可以递归定义:阶乘

对应的程序为
#include<stdio.h>
int f(int n){
return n==0?1:f(n-1)*n;
}
int main(){
printf("%d\n",f(3));
return 0;
}
这里——三元运算符“?:” o a?b:c的含义是:如果a为真,则表达 式的值是b,否则是c。所以n = 0?1 :f(n-1)*n很好地表达了刚才的递归定义。
C语言支持递归——函数可以直接或间接地调用自己。但要注意为递归函数编
写终止条件,否则将产生无限递归。
由于使用了调用栈,C语言支持递归。在C语言中,调用自己和週用其他函数 并没有本质不同。
在可执行文件中,正文段(Text
Segment)储存指令,数据段(Data Segment) 储存已初始化的全局变量,BSS段(BSS Segment)储存未赋值的全局变量所需的空间。
觉得少了点什么?调用栈在哪里?它并不储存在可执行文件中,而是在运行时创建。 调用栈所在的段称为堆栈段(Stack
Segment)。和其他段一样,它也有自己的大小,不能 被越界访问,否则就会出现段错误(Segmentation
Fault)。
每次递归调用都需要往调用栈里增加一个栈帧,久 而久之就越界了。用术语把它叫做栈溢出(StackOverflow).
在运行时,程序会动态创建一个堆栈段,里面存放着调用栈,因此保存着函数
的调用关系和局部变量。
那么栈空间到底有多大呢?这和操作系统相关。在Linux中,栈大小是由系统命令ulimit 指定的,例如ulimit -a显示当前栈大小,而ulimit-s 32768将把栈大小指定为32MB。但在 Windows中,栈大小是储存在可执行文件的。使用gcc可以这样指定可执行文件的栈大小: gcc-Wl,-stack=16777216,这样栈大小就变为了 16MB,
在Linux中,栈大小并没有储存在可执行程序中,只能用ulimit命令修改;在 Windows中,栈大小储存在可执行程序中,用gcc编译时可以通过-Wl,-stack= 指定。
现在能理解为什么在介绍数组时,建议“把较大的数组放在main函数
外了。别忘了,局部变量也是放在堆栈段的。栈溢出不见得是递归调用太多,也可能 是局部变量太大。只要总大小超过了允许的范围,就会产生栈溢出。
1198

被折叠的 条评论
为什么被折叠?



