一、设计函数
能拆成函数的尽量拆成函数
函数设计时尽可能考虑健壮性扩展性
二、函数调用的关系
int main(void)
{
printf("%d\n",getMonthDays());
return 0;
}
这个里面:
main ---成为调用者 ---main函数是整个程序的入口,只能调用者
getMonthDays --- 在此处是 被调用者
getMonthDays()
{
isLeapYear();
} //函数的嵌套调用
main -->getMonthDays --> isLeapYea
注:
函数不支持 嵌套定义,但是可以嵌套调用
函数名 --- 函数的入口地址
函数调用的本质:
实际是利用的栈的结构 ---先进后出 --保证了函数可以层层嵌套调用
栈:
数据结构 --- (表示数组组织形式)
特点:先进后出 ;局部变量 空间 自动申请 自动释放
c语言角度的栈:
1.本质上是一块内存空间
2.只是按照 栈 这种数据结构 来处理和使用的
C语言程序:把内存划分了5个区域
栈 //主要 用来存放, 自动变量 或 函数调用的数据
堆 //空间大 堆上的空间 ,手动申请,手动释放
字符串常量区 // "hello" (只读)
静态区(全局区) // 全局变量 和 静态变量
代码区 // 只读的
三、特殊嵌套调用
递归:自己调用自己 ,类似循环 --- 递归是一种特殊的循环
直接递归
间接递归
递归思路:
要求问题n
依赖于问题n-1的解决
用递归求解1~100求和
递归代码实现思路:
1.递推关系
怎么从 问题 n 到 问题n-1
sum(100) => sum(99)+100
sum(99) => sum(98)+99
sum(n) = sum(n-1)+n;
2.递推结束条件
n = 1
3.具体代码
#include<stdio.h>
int sum(int n)
{
if(n == 1)
{
return 1;
}else
{
return sum(n-1) + n;
}
}
int main(void)
{
int ret;
scanf("%d",&ret);
ret = sum(ret);
printf("ret = %d\n",ret);
return 0;
}
4.练习:
斐波拉契数列
1 1 2 3 5 8
求斐波拉契数列第n项
思路:
fibo(5)
|--fibo(4)+fibo(3)
| |-- fibo(2) + fibo(1)
|--fibo(3) + fibo(2)
|-- fibo(2) + fibo(1)
1 1
#include<stdio.h>
int feibo(int n)
{
if(n==1 || n==2)
{
return 1;
}else
{
return feibo(n-1)+feibo(n-2);
}
}
int main(void)
{
int a;
scanf("%d",&a);
printf("%d\n",feibo(a));
return 0;
}
四、数组作为函数参数
1.数组元素作为函数参数
nt a[10] = {1,2,3};
int add(int a,int b)
{
return a + b;
}
add(a[0],a[1])
2.数组本身作为函数参数
printArrray(int a[],int len) //形参
printArrray (int *a,int len) ---编译器最终理解的形式
调用:
printArray(a,len)
int a[10];
数组名 代表类型 ---int[10] 这种数组类型
数组名 代表的值 ---首元素的地址 //(数组所占内存空间的首地址)
一维整型数组 做函数 参数
形参 --写成数组形式 还需要 数组长度
实参 --数组名,数组长度
形参与实参的对应
在C语言中,形参的定义方式可以是数组形式 int a[],也可以是指针形式 int *a。实际上,这两种方式在函数调用时都可以接受数组作为参数,因为在函数调用过程中,数组名会被隐式转换为指向数组首元素的指针。
所以,无论是使用 int a[] 还是 int *a,在函数调用时都可以传递一个整型数组 a,同时需要传递数组的长度 len