第五章 函数
Ps: 函数的语法本身并不复杂,真正需要编程者去理解和体会的往往是如何用函数来拆解问题,使用函数的水平直接反映在编程者能够组织多大规模的程序
1.C语言中的main( )函数
main( )函数可以调用任何C语言函数;
但任何C语言函数都不能调用main( )函数,main( )函数通常在其所属的程序执行时被操作系统调用。
2.C语言函数的组成
返回值类型说明符 函数名( 参数 )
{
函数体;
}
1)函数的返回值
如果被调函数是无返回值的,那么函数内可以有return语句,也可以没有return语句;但如果被调函数是有返回值的,那么函数体内就必须包含return语句
如果一个函数中有很多return语句,执行第一条return语句时,函数都将返回到主函数中,此后的其他语句都不会继续执行
2)C语言规定:凡是不加返回值类型说明符的,一律默认为返回值类型为整型
3)return语句可以是一个常量、变量、表达式、但必须保证它必须要有一个确定的值
几点说明:
一、返回值类型与函数类型不同的3种情况:
1)没有影响,如:声明为int, 返回为char
2) 精度丢失, 声明的精度是低精度(如float),返回的为教声明高精度(double)
3) 编译出错(与具体情况,具体编译器有关)
规范做法:
显式地声明函数类型 按照函数声明的类型返回相应类型的值
二、函数的参数
1)形式参数声明时前面的数据类型不能省略
2)实际参数可以是值,也可以是用来表示值的表达式
3.函数的调用:
1)函数可以出现在表达式中,但这时函数必须要返回一个确定的值参与运算
2)函数可以作为实参来使用 printf( "%d \n ", display(3,4) );
3) 编译环境决定实参的求值顺序 要尽量避免这样的语句 func( i, i++ );
4) C语言允许函数之间进行嵌套调用,但是不允许函数的嵌套定义。
4.变量的作用域:可以访问某个变量的代码区域
1)局部变量的作用域:
1>主函数中的变量也只能在主函数中使用,不能在其他函数中使用
2>复合语句中定义变量,其作用域也只在复合语句范围内
注: sum的作用域只有在那个大括号中
5.全局变量
1)如果在某个函数中定义了一个和全局函数同名的变量,那么该同名局部变量就会在函数内部屏蔽全局变量的影响
2)全局变量最主要的一个作用就是允许多个函数能对某个变量进行修改,但破坏了函数的独立性
3)全局变量在程序执行过程中始终占用存储单元,而局部变量只有在使用的时候才分配存储空间
6.变量的存储类型
I.静态存储:在变量定义时就为其分配固定的存储单元并一直保持不变,直到整个程序结束(全局变量)
II.动态存储:仅当需要的时才临时性地分配存储单元,并且在使用完毕后,动态存储的变量也立即被释放(局部变量)
1) auto变量(auto 通常可以省略):采用动态存储;作用域仅限于定义该变量的函数或是复合语句中
2)全局变量与静态局部变量:采用静态存储;如全局变量,如果程序员想把函数中的局部变量在函数调用结束后不消失而保留原值,在函数下次调用时保存的仍然是上次的值,那就把这个变量定义为static(静态局部变量是在编译的时候赋值的,且只被赋值一次,默认为0,所在函数结束后,仍然存在,但其他函数是不能引用它,)
注:如果希望一个变量的值能够在修改后保存,并在程序执行期间内被某个可能反复调用的函数持续访问,又希望对其他函数隐藏这个变量, 静态变量是个不错的选择
3)register变量
C语言提供了一个帮助程序员利用CPU寄存器的语法,使用关键字register来声明局部变量时,该变量就是寄存器变量,寄存器变量的值就会被存放在CPU寄存器中(适用在局部变量被频繁使用时使用)
注:不能定义任意多个寄存器变量
只有局部自动变量和形式参数才能被定义为寄存器变量
4)extern变量
作用I:extern是用来修饰外部变量,能扩展外部变量的作用域:extern int n; extern n 都可以(外部已经有类型名了)
作用II:实现变量的跨文件访问:
编译器总是从使用extern进行外部变量声明的地方开始在本文件中查找外部变量的定义,如果没有,就会从工程中的其他文件中查找
注意: 使用了这个关键字,不同文件或函数中的值就会彼此产生连带效应,这种错误很隐蔽,增加了调试的难度
static外部变量
这里的static作用是这个变量仅限于本文件
在file2.c文件中,声明了两个外部变量a和变量b,并在func()中使用了它们,因此编译器会在其他文件中去查找,在file1.c中发现这两个变量被static所修饰,不能使用,所以编译器出错
7.多文件程序中函数的调用方法:
C语言根据函数是否能被其他源文件中的函数调用分为: 内部函数和外部函数
内部函数:
只能被本文件的其他函数使用
static 类型说明符 函数名(参数表 )
{
函数体;
}
与静态变量不同,这里的static不是指存储方式,而是对函数的作用域仅限于本文件。
内部函数的使用可以增加函数的访问限制,加强了程序的安全性,不同的人编写不同的函数时,也不会影响函数的编译
外部函数:
可以被其他文件中的其他函数所调用(extern可以省略),不同文件通过#include来包含进来
extern 类型说明符 函数名 (参数表)
{
函数体;
}