函数
-
从本质意义上来说,函数就是用来完成一定的功能。
-
函数就是功能,每一个函数用来实现一个特定的功能,函数的名字应反映其代表的功能。
-
在程序设计中要善于利用函数,以减少重复编写程序段的工作量。
-
所有的函数都是平行的,即在定义函数时是分别进行的,是互相独立的。
-
函数间可以互相调用,但不能调用main函数,main函数是被操作系统调用的。
用户使用的角度看,函数有两种:
-
库函数,由系统提供
-
用户自己定义的函数,用以解决用户专门需要的函数
对于C编译系统提供的库函数,是由编译系统事先定义好的,只需用 # include 指令把有关的头文件包含到本文件模块。
函数的定义
所有的函数必须“先定义,后使用”
定义函数应包括以下几个内容:
-
指定函数的名字
-
指定函数的类型,即函数返回值的类型
-
指定函数的参数名字和类型
-
函数的功能
定义函数的方法
1、定义无参函数
类型名 函数名() { 函数体 } 或 类型名 函数名(void) { 函数体 } 函数体包括声明部分和语句部分 void 表示空,即函数没有参数
2、定义有参函数
类型名 函数名(形式参数表列) { 函数体 } 例如: int max( int x,int y) { int z; z = x > y ? x : y; return(z); }
3、定义空函数
类型名 函数名() { } 例如: void dummy() { }
函数的调用
一、函数调用的形式
函数名(实参表列)
如果实参表列包含多了实参,则各参数间用逗号隔开。
按函数调用在程序中的出现的形式和位置,可以分为以下三种:
-
函数调用语句
把函数调用单独作为一个语句,例如:printf_star();
-
函数表达式
函数调用出现在另一个表达式中,例如:
c = max (a,b);
-
函数参数
函数调用作为另一个函数调用时的实参,例如:
m = max (a,max ( a , b ) );
二、函数调用时的数据传递
-
形式参数和实际参数
在调用有参函数时,主调函数和被调用函数之间有数据传递关系。
在定义函数时,函数名后面括号中的 变量称为:“形式参数”(简称 形参)或者“虚拟函数”。
在主调函数中调用一个函数时,函数名后面括号中的参数称为:“实际参数”(简称 实参),实际参数可以是常量、变量或表达。
-
实参和形参间的数据传递
在调用函数过程中,系统会把实参的值传递给被调用函数的形参。或者说
形参从实参得到一个值。
在调用函数过程中发生的实参与形参间的数据传递称为:“虚实结合”。
-
函数的返回值是通过函数中的return 语句获得的
return z; 与 return (z); 是等价的
-
如果函数值的类型和return 语句中表达式的值不一致,则以函数类型为准,即为 函数类型决定返回值的类型。
-
对于不带回值的函数,应当用定义函数“void 类型”(或称为空类型)
三、对被调用函数的声明和函数原型
在一个函数中调用另外一个函数(即被调用函数 )需要具备以下条件:
-
首先,被调用的函数必须是已经定义的函数(库函数或者用户自己定义的函数)
-
如果使用库函数,应该在本文件开头用 # include 指令将调用有关库函数时所需用到的信息。
-
如果使用用户自己定义的函数,而该函数的位置在调用它的函数(即主调函数)的后面(同一文件中),应该在主调函数中对被调用函数作声明
声明的作用:把函数名、函数参数的个数和参数类型等信息通知编译系统
-
编译系统只关心和检查参数个数和参数类型
函数声明的一般形式有两种:
1、 函数类型 函数名 (参数类型1,参数名1 ...参数类型n 参数名 n); 2、 函数类型 函数名(参数类型1,参数类型2....参数 类型n)
函数的嵌套调用与递归调用
一、嵌套调用
-
在C语言中,函数的定义是互相独立的、平行的,也就是说,在定义函数时,一个函数内不能再定义另一个函数,即不能嵌套定义;
-
但可以嵌套调用的函数,即在调用一个函数的过程中,又调用另一个函数;
二、递归调用
在调用一个函数的过程中又出现直接或间接地调用该函数的本身,称为函数的递归调用。
数组作为函数的参数
一、数组元素作函数的实参
-
数组元素可以作函数实参,但是不能作形参。(因为形参是在函数被调用时临时分配存储单元);
-
在用数组作函数实参时,把实参的值传递给形参,是“值传递”的方式
-
数据传递的方向是从实参传到形参,单向传递
二、一维数组名作函数参数
用数组元素作实参时,向形参变量传递的是数组元素的值,而用数组名作函数实参时,向形参(数组名或指针变量)传递的是数组首元素的地址
三、多维数组名作函数参数
可以用多维数组名作为函数的实参和形参,在被调用函数中对形参数组定义可以指定每一维的大小,也可以省略第一维的大小说明;
例如: int array[3][10]; 与 int array[][10] 两者都是合法且等价的,但是不能把第2维以及其他高维的大小说明省略
在内存中,数组是按行存放的,因此,在定义二维数组时,必须指定列数
局部变量和全局变量
每一个变量都有一个作用域问题
定义变量可以有3中情况:
-
在函数的开头定义;——局部变量
-
在函数内部的复合语句内定义;——局部变量
-
在函数的外部定义;——全局变量
局部变量
-
在一个函数内部定义的变量只能在本函数范围内有效;
-
在复合语句内定义的变量,只在本复合语句范围内有效,只有在本复合语句内才能引用它们;在该复合语句之外是不能使用这些变量
以上这些称为局部变量
说明:
-
主函数中定义的变量也只在主函数有效,主函数也不能使用其他函数中定义的变量
-
不同函数中可以使用同名的变量
-
形式参数也是局部变量
-
在一个函数内部,可以在复合语句中定义变量,这些变量只能在本复合语句有效,这种复合语句也称为“分程序”或“程序块”
全局变量
-
在函数之外定义的变量称为外部变量,外部变量是全局变量(也称全程变量)
-
它的有效范围是从定义变量的位置开始到本源文件结束;
-
注意:在函数内定义的变量是局部变量,在函数之外定义的变量是全局变量
-
设置全局变量的作用是增加了函数间数据联系的渠道