第七章
定义函数
- 定义没有参数的函数,
类型名 函数名() 类型名 函数名(void)
{ {
函数体 或 函数体
} }
函数体包括函数的声明部分和语句部分
定义函数时,要用类型名指定函数的类型,就是指定函数带回来的值的类型,
- 定义有参函数
{
函数体
}
函数体包括函数的声明部分和语句部分
- 定义空函数
类型名 函数名()
{ }
函数体是空的,调用这个函数是什么也不做。
调用函数
函数调用的一般形式:函数名(实参表列) 如果调用无参函数,那么实参表列可以没有,但是不可以省去那对小括号。如果包含多个实参,那么各个参数间应该用逗号隔开,主要有以下三种函数调用的形式。
- 函数调用语句,把函数调用单独作为一个语句,只要求函数完成一定的操作。
- 函数表达式,函数调用出现在另外一个表达式中,如c=max(a,b);max(a,b)是一次函数调用,他是赋值表达式的一部分,这时要求函数带回一个确定的值来参加表达式的运算
- 函数参数,函数调用作为另一个函数调用时的实参,如:m=max(a,max(b,c));
说明:调用函数并不一定要求后面有分号,只有作为函数调用语句才需要有分号。如果作为函数表达式或者函数参数,函数调用本身是不必有分号的。就是说:只有第一种情况用加分号,其他情况下都不用。
调用函数时的信息传递
形式参数:在定义函数时函数名后面括号中的变量
实际参数:在调用函数时,函数名后面括号中的参数
再调用函数的过程当中,系统会自动把函数实参的值传递给调用函数的形参,就是间的的复制粘贴,把实参的值复制粘贴到形参那里。
函数调用的过程:
- 定义函数时出现的形参,在没有出现函数的调用时,系统并没有为他们分配存储空间,发生函数的调用时,才临时分配存储单元。
- 将实参的值传递给位置相对应的形参,传递的时候,实参与形参个数相等,类型一致,按照顺序一一对应,实参表的求值顺序,因系统而定,大部分是自右向左。
- 执行函数体的时候,由于形参有值,就可以利用形参进行相关的运算
- 通过return语句将函数的值带回到main函数里面,注意函数的返回值类型应当与函数类型一样,如果类型不一样,就按照函数类型为准,自动转换。一个函数可以有多个return语句,但是最好只有一个。
函数的声明以及函数的原型
调用的必须是已经存在的函数,额日期额函数的调用也遵循先说明后谁用的原则。使用库函数应该加上对应的预编译指令,若果是用户自定义函数,加上函数类型说明,在驻点函数中说明被调函数的类型。
一般是都是这个样子,函数类型 函数名(形参类型 [形参名],….. );
或 函数类型 函数名();
作用是为了告诉编译系统函数类型,参数个数以及类型,以便检验,以下几种情况可以哦不做函数的说明,
- 函数的返回值是int或char,系统自动按照int处理
- 被调函数出现在主调函数之前,有些系统也要求指出函数的返回值类型和形参类型,并对int和void函数进行说明
函数参数及其传递方式
形式参数:定义函数时函数名后面括号中的变量名
实际参数:调用函数时函数名后面括号中的表达式
几点说明:
实参可以是常量、变量或表达式,且实参必须有确定的值
形参必须指定名字和数据类型
形参是函数的内部变量,只在函数内部才有意义;
形参与实参类型一致,个数相同
若形参与实参类型不一致,自动按形参类型转换——函数调用转换
形参在函数被调用前不占内存;函数调用时为形参分配内存;调用结束,内存释放
参数的传递方式:调用一个函数时,调用函数和被调用函数之间会发生数据的传递,一种是传值,另一种就是传地址
值传递方式:
调用函数的时候,为形参分配内存空间,并将实参的值复制到形参当中,调用结束,形参的内存单元就被释放了,实参单元保留并维持原来的值。
特点:形参和实参占据不同的内存单元。而且它们之间的传递是单向传递。
经典题目:
地址传递:
函数调用的时候,将数据的存储地址作为函数的参数传递给形参
特点:
形参与实参占据相同的存储单元
他们之间时双向传递
实参和形参必须是地址常量或者是变量,总之一定是地址。
函数的嵌套调用与递归调用
嵌套调用:
C语言规定,函数可以嵌套调用,但是不可以嵌套定义
递归调用:
函数直接或者间接的调用自身。C的编译系统对递归函数的自调用次数没有限制,但是每调用函数一次,在内存堆栈区分配空间,用于存放函数变量、返回值等信息,所以递归次数过多,可能引起堆栈溢出,导致结果出错
数组作为函数参数
数组元素作为函数的形参进行的是值传递
数组名作为函数的参数进行的是地址传递,此时在主调函数和被调函数当中分别定义数组,且类型一致,形参数组大小(多维数组的第一维)可以不指定,其中形参当中的数组名是地址变量
变量的存储属性:
变量是对程序中数据的存储空间的抽象,编译或函数调用时为其分配内存单元
属性:
数据类型:int double float
存储属性:
存储器类型:寄存器、静态存储区、动态存储区
生存期:变量在什么时候存在——静态变量与动态变量
作用域:变量在哪一部分有效——局部变量与全局变量
变量的存储类型:
auto -----自动型
register-----寄存器型
static ------静态型
extern -----外部型
一些变量的作用域:局部变量,全局变量,寄存器变量,外部变量
变量定义格式: [存储类型] 数据类型 变量表;
局部变量—内部变量
定义:在函数内定义,只在本函数内有效
说明:
main中定义的变量只在main中有效
不同函数中同名变量,占不同内存单元
形参属于局部变量
可定义在复合语句中有效的变量
局部变量可用存储类型:auto register static(默认为auto)
全局变量—外部变量
定义:在函数外定义,可为本文件所有函数共用
有效范围:从定义变量的位置开始到本源文件结束,及有extern说明的其它源文件
外部变量说明:extern 数据类型 变量表
外部变量定义与外部变量说明不同
若外部变量与局部变量同名,则外部变量被屏蔽
外部变量可用存储类型:缺省 或 static
尽量避免使用全局变量
动态变量与静态变量
存储方式
静态存储:程序运行期间分配固定存储空间
动态存储:程序运行期间根据需要动态分配存储空间
静态变量:从程序开始执行到程序结束
动态变量:从包含该变量定义的函数开始执行至函数执行结束