4.1什么是函数
4.1.1为什么需要函数
function 函数 顾名思义 一个函数就是一个功能。
4.1.2函数的调用
4.1.3函数的调用
4.1.3函数的分类
- 系统函数,库函数
- 自定义函数
- 无参函数
- 有参函数
4.2函数的定义
有参形式
无参形式
4.3函数的参数的值
4.3.1形参与实参
形参:定义函数的时候,函数名后面括号里的参数
实参:主函数调用函数时,函数名后面括号里的参数
说明:
- 形参在函数为调用的时候不占用内存,只有调用发生的时候才占用内存,调用结束后,形参所占用的内存单元也被释放。
- 形参与实参类型要相同
- 实参对形参的数据传递是“值传递”,单向传递。在调用函数时,系统临时给形参分配内存空间,实参单元与形参单元是不同的单元,调用结束后形参被释放,实参仍维持原来的值。
4.3.2函数的返回值
返回值以函数的类型为准,即函数的类型决定函数的返回值类型。
return
4.4函数的调用
函数声明 declaration,函数在未定义的情况下,事先将函数的有关信息通知给编译系统,是编译能正常进行。
- 函数的定义是对函数功能的确立。
- 函数的声明的作用只是将函数的名字,参数等信息通知编译器。声明时可以只写类型名,不写参数名
- 函数原型 :在函数生命中不写形参名,而只写形参类型,如:
int add(int ,int);
函数原型的作用是在程序编译阶段对调用函数的合法性进行检察。
- 如果被调动的函数的定义出现在主调函数之前,可以不加以声明。
4.5 函数的嵌套调用
C++不允许嵌套定义函数,但是可以嵌套调动函数。
4.6 函数的递归调用
在调用一个函数的过程中又出现直接或间接的调用该函数本身,称为函数的递归调用。
包含递归调用的函数称为递归函数。
4.7内联函数
函数的调用需要一定的时间和空间的开销,C++提供了一种高效的方法,即在编译时将所调用的代码直接其嵌入到主调函数中,而不是将流程转出去。这类函数称为内联函数(inline function)。
可以在声明函数时,在声明前加上inline。如:
inline int max(int ,int);
一般将小规模和频繁使用的函数适合声明为内联函数。
4.8函数的重载
C++允许同一个函数名定义多个函数,而这些函数的参数个数和参数类型可以不同,这称为函数重载。所谓重载即“一物多用”。
不仅函数可以重载,运算符也可以重载。
从在函数的参数个数,参数类型,参数顺序必须至少有一项不同,否则编译系统无法判断应该调用哪个函数。
4.9函数模板
函数重载需要分别定义每一个重载的函数,能否对此进行简化呢?C++提供了一种函数模板的机制。
所谓函数模板,实际上是建立了一个通用的函数,其函数类型与参数类型不具体指明,用一个虚拟的类型来代表,这个通用的函数称为函数模板。
定义函数模板的一般形式:
template <typename T> //T为一个类型名,现在并未指明他的类型。
通用函数定义
函数模板适用于函数体相同,函数参数个数相同,但参数类型不同的情况。函数参数个数不同,不能使用函数模板。
4.10有默认参数的函数
给形参一个默认值,这样调用时就不必一定要从实参取值了。如:
float area(float r =1 );
形参和实参的结合是从左到右进行的,第一个实参必然与第一个形参结合,因此制定默认值的参数应放在参数列表的的最有端,否则会出错。
4.11局部变量与全局变量
每个变量都有其有效的作用范围,这就是变量的作用域。
4.11.1 局部变量
在函数内部定义的变量是内部变量,它只在本函数内有效。在复合语句中定义的变量只在复合语句中有效,这些内部变量称为局部变量。
形参也是局部变量。
4.11.2 全局变量
在函数外定义的变量是外部变量,称为全局变量。全局变量的作用域从定义变量的位置开始到本源文件结束。
建议:不在必要的时候,尽量不要使用全局变量,原因如下:、
- 全局变量在程序的全部执行过程中都占用内存。
- 全局变量降低了函数的通用性,因为在执行函数时会受到外部变量的影响。
- 过多的全局变量会降低程序的清晰性,各个函数都可以改变全局变量的值,容易出错。
同一源文件中,全局变量与局部变量同名,则全局变量会被局部变量屏蔽。
变量有四中作用域:文件作用域,函数作用域,块作用域,函数原型作用域。
文件作用域是全局的,其余都是局部的。
4.12变量的存储类别
4.12.1动态存储方式与静态存储方式
变量还有另一个属性——存储期。
存储器是指变量在内存中存在的周期。
存储期分为静态存储期和动态存储期。
- 静态存储方式:系统对变量分配固定的存储空间
- 动态存储方式:系统对变量动态的分配存储空间
内存空间可分为
- 程序区
- 静态存储器
- 动态存储器
全局变量全部存放在静态存储区
动态存储区放:
- 函数的形参,调用函数时给形参分配存储空间。
- 函数中定义的变量(未加static)
- 函数调用时的现场保护和返回地址
C++中变量还有存储类别的属性。
- 自动 auto
- 静态的 static
- 寄存器 register
- 外部 extern
4.12.2 自动变量
不加static的局部变量
auto 可以不写,默认自动存储类别,属于动态存储方式。
4.12.3用static声明静态变量
该变量下次调动时保留上次调用结束时的值,这类变量成为静态局部变量。
- 静态局部变量在静态存储区分配内存单元。
- 自动变量在动态存储区分配内存单元。
静态局部变量 自动赋0 或空字符、自动变量赋随机值。
静态局部变量仍对其他函数不可见。
4.12.4寄存器变量
当今的优化编译系统能够识别使用频繁的变量,从而自动的将这些变量放在寄存器中。
4.12.5 用extern声明外部变量
利用extern关键字声明全局变量,以扩展全局变量的作用域。
extern只是声明,而不是定义。
4.12.6用static声明静态外部变量
用static修饰后,只能用于本文件。
4.13变量小结
变量的三种属性:
- 存储类别:auto static register externa
- 作用域
- 存储期
存储期与作用域
static是变量采用静态存储方式存储
4.14变量的声明与定义
函数的声明是函数的原型,函数的定义是函数功能的确立。
static对局部变量和全局变量的作用不同。
4.15内部函数与外部函数
内部函数:只被本文件中其他函数做调用。
static 类型标识符 函数名 (参数列表)
外部函数:可供其他文件调用
用extern修饰,extern可省略,默认为外部函数。
4.16头文件
头文件一般包含哪些内容?
- 对类型的声明
- 函数的声明
- 内联函数的定义
- 宏定义
- 全局变量
- 外部变量声明
- 其他头文件
头文件是源文件之间的接口。