一、递归函数
概念:递归函数就是一个函数在他体内调用自身。(类似于俄罗斯套娃)每调用一次就进入新的一层。为防止无限调用,递归函数必须有结束条件。
递归函数的两要素:递推关系、结束条件
#include <stdio.h>
int factorial(int n)
{
int result;
if (n<0) //判断例外
{
printf("输入错误!\n");
return 0;
}
else if (n==0 || n==1)
{
result = 1; //回推墙
}
else
{
result = factorial(n-1) * n; //递推关系,这个数与上一个数之间的关系。
}
return result;
}
int main(){
int n = 5; //输入数字5,计算5的阶乘
printf("%d的阶乘=%d",n,factorial(n));
return 0;
}
递归函数的特点
每一级函数调用时都有自己的变量,但是函数代码并不会复制
每次调用都会有1次返回
位于递归给i奥永前的语句和各级被调用的函数具有相同的执行顺序
位于递归调用后的语句 的执行顺序 和各个被调用的函数顺序相反
必须有终止语句
效率
1.系统栈(也叫核心栈、内核栈)
时内存中属于操作系统的一块区域,主要的用途为
①保存中断现场,对于嵌套终端来说,被中断程序的现场信息一次压入系统栈,中断返回时逆序弹出,
②保存操作系统子程序间相互调用的参数、返回值、返回点以及子程序(函数)的局部变量。
2.用户栈
用户栈时用户进程空间中的一块区域,用于保护用户进程的子程序间相互调用的参数、反回值、返回点以及 子程序函数的局部变量
我们编写的递归程序属于用户程序,因此使用的是用户栈。
3.栈溢出
函数调用的参数是通过栈空间来传递的,在调用过程中会占用线程的栈资源。而递归调用,只有走到最后的结束点后函数才能依次退出,而未到达最后的结束点之前,占用的栈空间一直没有释放,如果递归调用次数过多,就可能导致占用的栈资源超过线程的最大值,从而导致栈溢出,导致程序的异常退出。
综上:
函数调用的时候,每次调用时要做地址保存,参数传递等,这是通过一个递归工作栈实现的。具体是每次调用函数本身要保存的内容包括:局部变量、形参、调用函数地址、返回值。那么,如果递归调用N次,就要分配N次局部变量、N次形参、N次调用函数地址、N次返回值,势必效率低.
优点
代码简洁、清晰,易懂
==循环能干的事,递归都能干;递归能干的循环不一定能干==
对于我们,能用循环解决的,尽量不适用递归.
所以说递归不好
————————————————
版权声明:本文为CSDN博主「FlyWine」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/wf19930209/article/details/79341939