5.1 函数定义
在C程序设计中,将完成指定功能的C代码定义成函数,变成逻辑上一个相对独立的程序单位。函数定义需要指明函数返回值的类型、函数名、函数的形式参数(常简称形参)和函数体(包括说明和定义及语句序列)。函数定义的一般形式为
存储类型说明符 数据类型说明符 函数名(形式参数表)
形式参数说明序列
{
说明和定义部分
执行语句序列
}
存储类型说明符或省缺,或为static。省缺表示一个全局函数,static表示一个静态函数,只供同一源程序文件中的函数使用。
数据类型说明符用来指定函数返回值类型,可以是基本数据类型、某种指针类型、结构类型等。但不可以是数组类型。特别当函数不返回结果时,可用void明确指明函数不返回值。
数据类型说明符也可省缺,省缺被默认为返回int型值。
函数名是一个标识符。形式参数表是用远号分隔的若干形式参数,用不同的标识符指明各形式参数的名。形式参数说明序列用来说明各形式参数的数据类型,相同数据类型的形式参数可以一起说明。现在编写C程序的习惯是形式参数说明序列直接放在形式参数表中,即在形式参数说明表中顺序列出各形式参数的数据类型和形式参数的名称。如是这样,一般形式的第一行全部内容称为函数头,也称为函数模型。
特别情况,函数可能不设形式参数,也就没有形式参数表和形式参数说明序列。但函数名后的一对圆括号是不可以没有的。
一对花括号括住的部分称为函数体,函数体包括类型说明、变量定义和函数的执行语句序列。在函数体内可以有return语句终止函数的执行。如函数有返回值类型,则return语句中一定要有表达式,作为函数调用的返回值。
函数调用
函数被定义以后,凡要实现函数功能的地方,就可简单地通过函数调用来完成。按函数调用在程序中的作用,有两种不同类型的应用:
(1)函数调用只是利用函数所完成的功能。此时,将函数调用作为一个独立的语句。其调用的一般形式为
函数名(实际参数表);
这种应用不要求或程序不利用函数的返回值。如程序中经常调用格式输入函数scanf()和格式输出函数printf()等。
(2)函数调用是利用函数的返回值。其调用的一般形式为
函数名(实际参数表)
这种应用是利用返回值继续进行表达式的计算,或输出函数返回值等。
函数调用时提供的实际参数按它们出现的顺序与函数定义中的形式参数-一对应,并要求实际参数类型与其对应的形式参数类型相一致。一般情况下,函数调用应为函数定义中的每个形式参数提供实际参数,当有多个实际参数时,实际参数之间用逗号分隔。
函数调用的执行过程描述如下:
(1)为函数的形式参数分配内存空间;
(2)计算实际参数表达式的值,并将实际参数表达式的值赋给对应的形式参数;
(3)为函数的局部变量分配内存空间;
(4)执行函数体内的语句序列;
(5)函数体执行完成,或执行了函数体内的return语句(若return语句带表达式,则计算出该表达式的值,并以此值作为函数的返回值)后,释放为这次函数调用分配的全部内存空间;
(6)将函数值(如果有)返回到函数调用处继续执行。
下面以简单的程序例子说明函数调用的执行过程。
【例6.l】函数调用时,由实际参数向函数形式参数传递值的示意程序。
# include
double x,y,d;
double min(double a,double b)
{double temp;
temp=a> b? b :a;
return temp;
}
void main()
{ printf(“Enter x, y.\n”);
scanf(“%lf%lf”,&x,&y);
d=min(x,y);
printf(“MIN(%.3f,%.3f=%.3f\n”, x, y,d)
}
以上示意程序的大致执行过程如下: