C程序设计--第7章 函数
1.函数的定义
函数的名字、类型、参数名和类型、功能(函数体)。
2.函数的调用
- 对被调函数进行声明
- 内部声明、外部声明(对整个文件有效)
- 函数调用时的数据传递(虚实结合):实参形参(值传递)。
- 返回值:通过return语句将函数值返回主调函数(或终止执行)。
- 形式参数在函数调用完后将被释放。
3.函数的嵌套调用和递归调用
4.数组作为函数参数
(1)数组元素作函数实参
数组元素可以用作函数实参,不能用作形参。在用数组元素作函数实参时,把实参的值传递给形参,是值传递方式,数据的传递方向是从实参传到形参,单向传递。
(2)一维数组名作函数参数
C语言中数组名作为函数实参时,编译器总是将其解析为指向数组首元素地址的指针(地址调用)。
形参数组可以不指定大小,在定义数组时在数组名后面跟一个空的方括号,效果相同。例如:
float average(float array[ ]);
float average(float array[10]);
这两者是等价的,特别对于第二种定义,不要以为该函数只能接收大小为10的数组,实际实参数组的大小与函数形参数组的大小是没有任何关系的。
(3)多维数组名作函数参数
错误认识:既然一维数组作为参数相当于一个指针,那二维数组作为参数就相当于一个二级指针。
正确认识:二维数组名作为参数时相当于一个数组指针(指向一维数组的指针)。
可以省略第一维的大小说明,如: int array[3][10] 或 int array[ ][10] 二者都是等价且合法的。但是不能把第二维以及其他高维的大小说明省略。如下定义是不合法的:int array[ ][ ] 或 int array[3][ ] 。
形参数组的第一维可以与实参数组不同,但第二维的数目必须要与实参第二维的数目一样。因为二维数组名做实参时,编译器是将其解析为一个指向大小为第二维的数组的指针。
5.局部变量和全局变量
局部变量
只在本函数范围内有效
全局变量
有效范围为从定义变量的位置开始到本源文件结束
函数之外定义的变量称为外部变量
在局部变量的作用范围内,局部变量有效,全局变量被“屏蔽”。
6. 变量的存储方式
静态存储方式
程序运行期间由系统分配固定的存储空间。存放全局变量。
动态存储方式
程序运行期间按需动态分配空间。存放函数形参、自动变量(没有用static声明),函数调用时的现场保护和返回地址等。
局部变量的存储类别
(1)自动变量(动态局部变量,auto可隐含)
auto int b;
(2)静态局部变量
static int b;
-
在函数调用结束后局部变量的值保持不变,即其占用的存储单元不释放。
-
对静态局部变量是在编译时赋初值的,即只赋初值一次。
-
虽然静态局部变量在函数调用结束后仍然存在,但其他函数是不能引用它的。
(3)寄存器变量
全局变量的存储类别
(1)文件内扩展外部变量的作用域
如果外部变量不在文件开头定义,其有效范围仅限于定义处到文件结束,在定义点之前的函数不能引用该外部变量。
要解决这个问题,应在引用之前用extern关键字进行“外部变量声明”,表示将外部变量的作用域扩展到此位置。
(2)作用域扩展到其他文件 做法:在任一文件中定义外部变量 Num,在其他文件中用 extern 对 Num 作外部变量声明。
注意:编译时,遇到 extern 时,先在本文件中找外部变量的定义,若找不到,则在连接时从其他文件中找。
(3)将外部变量的作用域限制在本文件中 加上 static 声明的外部变量,成为静态外部变量
(4)static 在声明中的作用:
- 对局部变量用,把它分配在静态存储区,在程序执行期间不释放存储空间;
- 对全局变量用,则该变量的作用域只限于本文件。
7. 内部函数和外部函数
内部函数(静态函数)
在函数类型前加 static,使作用域仅限于本文件
外部函数(默认)
在函数类型前加 extern
C程序设计(第五版)——谭浩强