五、函数
1. 降低程序的耦合性(关联度),减少重复代码
2. 让程序模块化,增强代码的复用性。
1. 函数定义
函数的具体实现:
返回值 函数名(形参表)
{
函数体;
}
返回值:类型说明符:int、char、....等基本数据类型、构造数据类型、void
返回函数最终结果
void:空类型,当函数执行完,不再需要有任何结果返回时,可以使用void类型的返回值
函数名: 标识符,遵循标识符的命名规则(尽量 见名知意)
形参表:函数执行过程中需要用到的条件
形式:
数据类型 形参名,数据类型 形参名...........
int a[]; int len;
2. 函数的调用
函数名(实参表)
实参表:传递给函数的具体的条件
1.实参和形参的个数必须一致
2.实参和形参数据类型要一致,或者要相兼容
123----------->int/char
3.实参和形参名字可以相同,也可以不相同
4.函数不被调用则不执行,调用几次执行几次
函数名(实参表);-------->表达式的结果是函数的返回值类型
当函数的返回值有一个明确的返回类型时,必须要return,否则系统会返回一个随机值。
void返回值类型时,不用写return 要不就直接写return即可
主调函数:调用函数的函数称为主调函数(main)
被调函数:被调用的函数
3. 函数的声明
声明:
1. 当被调函数定义在了主调函数的后边,编译器报“implicit declaration”, 可以将该该函数在主调函
数前边进行声明。
2. 多文件使用函数的时候,需要对其声明,允许被其他文件调用
语法:
返回值 函数名(形参表);
4. 函数的调用过程
函数在调用的时候存在保护现场和恢复现场的操作:

保护现场:当函数要被调用的时候,会将函数调用位置的下一条指令地址保存在栈空间;
恢复现场:当被调函数执行完时,通过出栈保护现场的地址,决定cpu继续执行的位置在函数被调用的
下一条指令位置。
5. 函数的传参
1. 函数传参过程,其实是实参向形参拷贝的过程,实参有实参的空间,形参有形参的空间(值传
递)。
2. 值传递:在被调函数中,无法修改主调函数中的变量。
3. 函数传参的顺序:自右向左。
练习:
6. 函数的递归调用
递归调用:函数直接或者间接的调用自己
本质:循环方式
注意: 1. 递归要有递归的出口,否则会成为死循环。
2. 递归调用系统开销比循环大(比如:栈内存)。
练习:
求斐波那契数列的第n项
1,1,2,3,5,8,13.......
7.函数与一维整形数组
传参方式:
定义:
返回值 函数名(int 数组名[], int len)
{
// sizeof(数组名); ----》sizeof(int *) ---->8字节
//外面数组怎么使用,函数内数组就怎么使用
}
调用:
函数名(数组名, 数组长度);
void print_array(int a[], int len)
{
}
print_array(a, len);
数组的数组名是数组的首元素地址。
注意:
1. 数组作为函数参数传递时,形参必须要是数组类型:int a[], []中的常量可以有,也可以省略。
2. 数组作为函数参数传递时,本质传递的是数组的首元素地址,所以形参本质是一个地址,是数组的
起始地址。
3. 由于数组名传参本质传递的是首地址,所以必须要传递整形数组的长度。
4. 数组作为函数参数传递给被调函数后,函数内部的使用方法和外面使用一样,除了sizeof(数组
名);