一、函数实现
1.函数定义
类型标识符 函数名 (形式参数)
{
函数体;
}
(1)类型标识符:返回值类型说明符。这个类型说明符是用来规定返回值的类型的
基本类型--整型,浮点型,字符型注意: 数组类型--不能做函数返回值类型
说明:如果带出的结果的类型和返回值类型说明符不一致,最终结果的类型以返回值类型说明符为准。返回值类型如果不写 ,默认相当于是int型
(2)函数名:是个标识符,用来表示是哪个函数
注意:定义符合标识符命名规则,要求见名知意,有字母数字下划线组成,不能由数字开头,不能与关键字重名,不要和库函数以及预处理命令重名。
(3)形式参数:是函数获得数据的入口,函数要处理的数据,可以通过形式参数获取到。每个形参都必须指明类型,即使类型相同也要分开写。形参的语法: 类型 变量名1,类型 变量名2, ....
说明:实参到形参是赋值的过程,所以要求实参和形参要求类型相同,个数匹配,一一对应。如果函数不需要传数据给它,可以不用形参,此时形参可以不写或写成void 。
(4)函数体:实现函数功能的那部分代码。
注意:函数的定义位置一般写在main函数前面。如果写在main函数后面,需要提前给编译说明一下即函数声明。复制函数头 加上分号 就是函数声明,此时函数声明必须要放到使用之前。
2.函数实现
step1. 先根据功能 确定函数名
step2. 从 输入--处理 --输出 这个模型出发,考虑函数需要哪些数据,以及数据的类型
step3:考虑 如何处理数据 (函数体)
step4:考虑 结果 要不要带回 或者输出
(1)要带回结果:考虑返回值类型说明符,带出结果的语句:return 表达式;
(2)不带回结果:返回值类型说明符 void (空类型)
3.函数调用
(1)语法:函数名(实际参数);
(2)方式:直接调用,充当参数,函数调用表达式。
4.函数实现的本质
函数实现调用的本质:是因为有栈空间进行了现场保护和恢复 。
函数调用的实现依托进程栈内存。发起函数调用时,CPU 将调用处的寄存器现场、函数返回地址、参数压入栈完成现场保护;随后跳转至被调函数,在栈上创建独立栈帧管理局部变量;当函数执行完毕,通过出栈操作恢复寄存器现场,读取栈中保存的返回地址,使程序回到调用位置继续执行。栈的先进后出特性天然支持多层函数嵌套调用的现场管理。
二、C语言在内存中存放内存空间划分
a.栈——平常定义的局部变量都是放在栈空间 ,局部变量的空间 是自动申请,自动释放,栈空间是由大小限制的,当超出栈空间时会出现段错误。特点: 符合栈的先进后出的特点
默认是8M但是可以更改大小。
b.堆——需要程序员手动申请,手动释放 , 数据量比较大的时候 考虑使用 特点: 大
c.全局区(静态区):存放全局变量
d.字符串常量区:存放字符串
e.代码区:存放就是程序代码指令
三、递推
函数的嵌套调用:特殊的嵌套,递归(自己调用自己 )
1.直接递归
f1()
{
f1();
}
2.间接递归
f2()
{
f1();
}
f1()
{
f2();
}
3.递归实现逻辑
int sum(int n)
{
判断是否得到了递归结束条件
是 返回 此时的结果
否继续递归 下去
}
四、数组作为函数参数
1.数组元素做函数参数a[0]
2.数组本身做函数参数
函数能不能访问到整个数组
注意:整型的一维数组作为函数参数
形参 :void printArray(int a[10]) 形式上,可以写成数组形式
void printArray(int *a) 本质上 编译器是理解成int *指针
所以,如果想访问到整个数组中的数据,必须还要传一个数组的长度
形参:void printArray(int a[10],int len) 形参需要一个数组形式的参数 一个是数组长度
实参:printArray(a,len);