一,函数递归
递归是一种解决问题的方法,在C语言中,递归就是函数自己调用自己。
#include<stdio.h>
int main()
{
printf("haha\n");
main();
return 0;
}
此代码会进入死循环,出现
2,递归的限制条件:
递归在书写的时候,有两个必要条件:
递归存在限制条件,当满足这个限制条件的时候,递归便不再继续。
每次递归调用结束之后越来越接近这个限制条件。
//求n的阶乘
//5!=1*2*3*4*5,n!=n*(n-1)!
//阶乘函数Fact(n)=n*Fact(n-1)
#include<stdio.h>
int Fact(int n)
{
if (n<=0)
return 1;
else
return n*Fact(n-1);
}
int main ()
{
int n = 0;
scanf("%d",&n);
int ret =Fact(n);
printf("%d\n",ret);
return0;
}
从哪个窗口进来,就从哪个窗口返回。函数自己调用自己是有条件的。
//输入一个整数,按顺序打印各个位上的数字,
#include<stdio.h>
void Print()
{
if(n>9)
Print(n/10);//先调用个位的前几位,要从最高位开始打印
printf("%d",n%10);
}
int main ()
{
int n =0;
scanf("%d",&n);
Print(n);
return 0;
}
Fact函数可以产生正确的结果,但是再递归函数调用的过程中涉及一些运行时的开销。在C语言中每一次函数调用,都需要为本次函数调用在栈区申请一块内存空间来保存函数调用期间的各种局部变量的值,这块空间被称为运行时堆栈,或者函数栈帧。
函数不返回,函数对应的栈帧空间就一直占用,所以如果函数调用中存在递归调用的话,每一次递归函数调用都会开辟属于自己的栈帧空间,直到函数递归不再继续,开始回归,才逐层释放栈帧空间。
所以如果采用函数逆归的方式完成代码,递归层次太深,就会浪费太多的栈帧空间,也可能引起栈溢出(Stack over flow)的问题。
#include<sedio.h>
//递归层次太深,出现了溢出现象,死递归
void test (int n)
{
if(n <=10000)
{
printf("%d\n",n);
test(n+1);
}
}
int main()
{
test(1);
return 0;
}
想要避免这种情况,可以用迭代或循环
#includ<stdio.h>
int main()
{
int n = 0;
scanf("%d",&n);
int i = 0;
int ret =1;
for(i =1;i<=n ;i++)
{
ret = ret * i;
}
printf("%d\n",ret);
return 0;
}
eg.斐波那契数列
1 1 2 3 5 8 13 21 34 55,,,,,
Fib(n)=当n<=2时,==1;当n>2时,==Fib(n-2)+Fib(n-1);
//递归方法
#include<stdio.h>
int Fib(int n)
{
if (n<=2)
return 1;
else
return Fib(n-1)+Fib(n-2);
int main()
{
int n=0;
scanf("%d",&n);
int ret = Fib(n);
printf("%d\n",ret);
return 0;
}
//循环赋值
#include<stdio.h>
int Fib(int n)
{
int a =1;
int b =1;
int c =1;//c不能是0,如果n=1的话,返回到c就是0了
while(n>2)
{
c = a+b://下面这两个代码不能反,如果先把c赋给b 然后b再赋给a,那么a,b,c就相同了。
a =b;//先把b的值放给a,所以b就空了,然后c的值给 b
b =c;
n--;
}
return c;
}
int main()
{
int n =0;
scanf("%d\n",&n);
printf("%d\n",ret);
return 0;
}