目录
接上次 函数初步了解(1)http://t.csdn.cn/8TctB
函数初步了解(2)http://t.csdn.cn/BqoAQ
1.递归与迭代
练习:
//写一个函数求n的阶乘
<1>递归
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int Fac(int n)
{
if (n <= 1)
return 1;
else
return n * Fac(n - 1);
}
int main()
{
int n = 0;
scanf("%d", &n);
int ret = Fac(n);
printf("%d\n", ret);
return 0;
}
<2>循环(迭代)
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int Fac(int n)
{
int i = 0;
int ret = 1;
for (i = 1; i <= n; i++)
{
ret *= i;
}
return ret;
}
int main()
{
int n = 0;
scanf("%d", &n);
int ret = Fac(n);
printf("%d\n", ret);
return 0;
//求第n个斐波那契数
<1>递归
#define _CRT_SECURE_NO_WARNINGS
#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;
}
运行起来我们发现,当n很大时(如50),计算便十分缓慢(计算机OS:你在叫我做事??你想累死我??),这时候递归的缺陷:效率低,占用空间大,容易栈溢出 就显露出来了。
若递归效率低或栈溢出,则改为非递归。既然这条路走不通,我们可以用迭代法尝试一下。
<2>循环(迭代)
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int Fib(int n)
{
int a = 1;
int b = 1;
int c = 1;
while (n>2)
{
c = a + b;
a = b;//将b的值赋给a,将c的数字赋给b
b = c;
n--;
}
return c;//return b也可,因为此时b=c
}
int main()
{
int n = 0;
scanf("%d", &n);
int ret = Fib(n);
printf("%d\n", ret);
return 0;
}
当n为50时使用迭代则没有上述问题,照样能跑~
虽然最终的结果不一定对(类型能存储的值有上限),你看它快不快就完事了哈哈(doge)
方法 | 优点 | 缺点 |
递归 | 代码简洁,可读性高 | 效率低,占用空间大,容易栈溢出 |
迭代 | 效率高 | 代码繁琐,可读性低 |
2.函数栈帧
函数栈帧:
每一次函数调用都会为本次函数调用分配内存空间(是在内存的空间),为本次函数调用分配的内存空间叫被称为这次函数调用的栈帧空间。
递归容易栈溢出——解决方法:使用static将局部变量放入静态区,减少栈区压力。
递归经典案例: //汉诺塔问题;//青蛙跳台阶问题(这俩问题之后会单独写两篇文章分析)
栈区:局部变量,形式参数
堆区:动态内存分配
静态区:静态变量,全局变量(少使用,不安全)
全局变量,静态变量:不初始化默认值为零
局部变量:不初始化默认值为随机值
高内聚低耦合:各模块之间尽量独立,自己搞定
函数篇章就要告一段落了,下一个模块再见~~~