昨天简单的学习了函数的定义和调用,今天主要学习如何设计函数及函数递归
设计函数:
1.能拆成函数的尽量拆成函数
2.函数设计时,尽可能考虑健壮性、扩展性
函数调用的关系
调用者
被调用者
int main(void)
{
printf("%d\n",getMonthDays())
return 0;
}
这个里面:
main —— 成为调用者 ——main函数是整个程序的入口,只能是调用者
getMonthDays() ——在此处是被调用者
getMonthDays()
{
isLeapYear();
} //函数的嵌套调用
注:
函数不支持嵌套定义,但是可以嵌套调用
函数名 —— 函数的入口地址
函数调用的本质:
实际是利用栈的结构 —— 先进后出 — 保证了函数可以层层嵌套调用
栈:
数据结构 —— 表示数据的组织形式
特点:先进后出 (First In Last Out)//FILO
C语言角度的栈
1.本质上是一块内存空间
2.只是按照栈这种数据结构来处理和使用的
栈:局部变量 // 空间 自动申请 自动释放
C语言程序
把内存划分了5个区域
栈 //主要用来存放自动变量或函数调用的数据
堆 //空间大 堆上的空间 手动申请,手动释放
字符串常量区 //"hello"只读
静态区(全局区) //全局变量和静态变量
代码区 //只读的
程序 = 代码 + 数据
特殊嵌套调用 —— 递归
递归:自己调用自己
直接递归
间接递归
类似循环 —— 递归是一种特殊的循环
递归思路:
要求问题n
依赖于问题n-1的解决
递归代码的实现思路:
1.递推关系
怎么从问题n到问题n-1
sum(100) => sum(99)+100
sum(99) => sum(98)+99
sum(n) = sum(n - 1)+n
2.递推结束条件
n = 1
3.代码
int sum(int n)
{
if(n == 1)
{
return 1;
}
else
{
return sum(n-1) + n;
}
}
接下来做了一个小练习,用函数递归给处斐波那契数列第n项的值
#include<stdio.h>
int Fipolacci(int n)
{
if(n == 1 || n == 2)
{
return 1;
}
else
{
return Fipolacci(n-1) + Fipolacci(n-2);
}
}
int main()
{
int n;
scanf("%d",&n);
printf("%d\n",Fipolacci(n));
}
数组作为函数参数
1.数组元素作为函数参数
2.数组本身作为函数参数
总结:
1.一维整形数组做函数参数
形参 —— 写成数组形式 还需要数组长度
实参 —— 数组名,数组长度
int a[10];
数组名 代表类型 ---int [10] 这种数组类型
数组名 代表的值 --- 首元素的地址 // 数组所占内存空间的首地址
eg:
#include<stdio.h>
void PrintArray(int a[],int len) //数组打印
{
int i;
for(i = 0;i < len;i++)
{
printf("a[%d] = %d\n",i,a[i]);
}
}
void Select(int a[],int len) //选择排序
{
int i,j;
int temp;
for(i = 0;i < len -1;i++)
{
for(j = i + 1;j < len;j++)
{
if(a[j]<a[i])
{
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}
return;
}
int main()
{
int a[]={5,7,2,4,9,3,1,8,6};
int len;
len = sizeof(a)/sizeof(a[0]);
PrintArray(a,len); //函数调用
Select(a,len);
PrintArray(a,len);
return 0;
}