本章主要讲述C语言的函数
c语言由函数作为构建块,函数使c语言更加模块化,函数是完成特定任务的独立程序代码单元,在程序多次完成某项任务时,通过函数可以减小代码块的重复,只需编写一个合适的函数,就可以在需要时使用这个函数,也方便后期的修改和完善。每个c程序都至少有一个函数,即主函数 main() ,c语言有许多标准库函数,也可以自己创建函数。
定义函数:函数和变量一样,有很多数据类型,使用函数之前需声明该函数的返回类型,参数的数量以及每个参数的类型。定义函数时,函数头括号内声明的变量被称为形式参数,此参数也是局部变量,在进入函数时被创建,退出函数时被销毁,每次调用函数时,就会给这些变量赋值。当函数被调用时,主调函数向参数传递一个值,这个值被称为实际参数,可以是常量也可以是变量甚至表达式,该值被赋给作为形式参数的变量。参数列表包括函数参数的类型、顺序、数量。参数是可选的,函数可能不包含参数。函数名和参数列表一起构成了函数签名,所以可以出现参数列表不同但是函数名相同的函数。当调用函数时,编译器会找到该函数的定义并执行其中的内容,执行完函数中的代码后,返回主调函数继续执行下一行。调用函数时,传递所需参数,如果函数返回一个值,则可以存储返回值,函数的返回值可以把信息从被调函数传回主调函数。利用此传值调用的方法来传递参数,由于值传递是单向传递,传递过程中只是改变了形参的数值,并未改变实参的数值,所以函数内的代码并不会改变用于调用函数的实际参数。
void fun(void) //函数头
{
... //函数体
}
//定义了一个函数名为fun的void类型(没有返回值)的函数,括号中的void表明函数不带参数
fun(); //调用此函数
声明函数:
函数声明会告诉编译器函数名称及如何调用函数。函数的实际主体可以单独定义。 使用方式为将定义函数的第一行加上分号,称其为函数原型,大部分时候将其放在main()前面,即在调用函数的文件顶部声明函数,但也可以放在main()里面的声明变量处,即第一次调用函数的前面。
int max(int num1, int num2); //声明函数max
int max(int, int); //在函数声明中,参数的名称并不重要,可以省略,只有每个参数的类型是必需的,此声明也有效(函数定义时不可省略参数名)
递归:c语言允许函数调用它自己,这种调用过程称作递归,可以使用循环的地方通常都可以使用递归,递归方案更简洁,但效率却没有循环高,而且递归不方便阅读和维护。每次函数调用都会返回一次,当函数执行完毕后,控制权将会被传回上级递归递归调用就相当于又从头开始执行函数的代码。递归函数中位于递归调用之前的语句,均按被调函数的顺序执行,递归函数中位于递归调用之后的语句,均按被调函数相反的顺序执行。递归函数必须包含能让递归调用停止的语句,一般调用函数的参数每次均是有规律的递增或递减 ,并且能够在适当的地方结束递归调用。
最简单的递归形式是把递归调用置于函数的末尾,即正好在return语句之前,这种形式的递归被称为尾递归,尾递归是最简单的递归形式,因为它相当于循环。
void fun()
{
...
fun(); //函数调用自身
...
}
内联函数:用inline关键字修饰,在类内定义的函数被默认成内联函数。内联扩展是用来消除函数调用时的时间开销,它通常用于频繁执行的函数。有以下要求:
1.递归函数不能定义为内联函数
2.内联函数一般适合于不存在while和switch等复杂的结构且只有1~5条语句的小函数上,否则编译系统将该函数视为普通函数。
3.内联函数只能先定义后使用,否则编译系统也会把它认为是普通函数。
4.对内联函数不能进行异常的接口声明。
注意:
1.一个函数可以返回一个值,也可以只执行所需操作而不返回值,当然,也可以在一个函数内使用多个return语句。
2.在函数中定义的变量为局部变量,该变量只属于此函数。
3.函数原型中使用变量名并没有实际创建变量,调用函数时,创建了声明为形式参数的变量并初始化为实际参数的求值结果。
4.函数中私有的局部变量再外界使用同名变量它们之间互不影响,相互独立。
5.声明函数时,带返回值的函数类型应该与其返回值类型相同。
6.将函数定义直接放在main()前,它本身就相当于函数原型。
7.c语言规定,如果在定义函数时省略 extern,则默认为外部函数,可供其它文件调用,在需要调用此函数的其他文件中,对此函数作声明时,要加关键字 extern,表示该函数是在其他文件中定义的外部函数。若要定义内部函数(静态函数),在函数名和函数类型的前面加 static,使其只能被本文件中其他函数所调用。使用内部函数,可以使函数的作用域只局限于所在文件,即使在不同的文件中有同名的内部函数,也互不干扰,提高了程序的可靠性。
8.在c语言中,每个函数与其它函数都是平等的,每个函数都可以调用其它函数,或被其它函数调用 。main()也可以被自己或其它函数递归调用,但尽量不要这么做。