hello,各位小伙伴们今天我们来学习一下函数递归。
什么是函数递归呢?简单来说就是函数自己来调用自己。函数递归的主要思想是把大事化小,递归包含两层方面:1、递推 2、回归
在使用函数递归的时候要注意包含两个限制条件:1、递归存在限制条件,当满足这个限制条件时,递归不在继续进行 2、函数在递归的时候要不断接近这个限制条件
练习:求n的阶乘
#include<stdio.h>
//n的阶乘
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);
return 0;
}
让我们画图来演示一下!
顺序打印一个整数中的每一位
例如1234,我们要输出1 2 3 4 ,可以将1234%10得到4,然后在1234/10得到123,在不断重复上述操作,就可以得到4 3 2 1,但这些是逆序打印的!
如果使用递归的话,在回归的时候会顺序打印!
代码实现:
#include<stdio.h>
void Function(int n)
{
if (n / 10 != 0)
{
Function(n / 10);
}
printf("%d ", n % 10);
}
int main()
{
int n = 0;
scanf("%d", &n);
Function(n);
return 0;
}
如果小伙伴仍然难以理解,我们可以试试这样:n=2345
当然代码是只有一份的,在进行函数调用的时候会在栈区申请一段空间,用来保存函数在调用期间各种局部变量,这段空间叫做运行时栈或者函数栈帧。
当了解到函数的调用是在栈区申请空间时,我们就应该注意到函数调用次数不宜过多,否则就会造成栈溢出!
求斐波那契数:
如果使用函数递归的话,我们应该会这样写:
#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 r = Fib(n);
printf("%d", r);
return 0;
}
但这样会造成一个极易忽略的问题:栈溢出!当我们输入50的时候计算机会等1分钟左右才会输出答案,它在疯狂的计算!同时我们打开任务管理器后会发现它几乎占据很大比例的CPU。
由此可以看出并不是使用函数递归就是最好的办法!
如果加上计数器在计算第40位数时候次数非常大!
迭代
#include<stdio.h>
int Fib(int n)
{
int i = 0;
int a = 1;
int b = 1;
int c = 0;
for (i = 0; i < n - 2; i++)
{
c = a + b;
a = b;
b = c;
}
return c;
}
int main()
{
int n = 0;
scanf("%d", &n);
int r = Fib(n);
printf("%d", r);
return 0;
}
虽然没有使用递归但计算上简洁不少!所以并不是所有都要使用递归。
这期C语言小tip就到这里啦,拜拜。