一、ANSI C关于函数原型的规则
ANSI C在函数声明中同事说明所使用的的参数类型,即在函数原型中声明返回值类型、参数、参数个数、参数类型
int function(int a, int b); // 形式一
int function(int, int); // 形式二
// 以上两种形式的定义均满足规范要求
好处:编译器可以检查函数调用语句是否和其原型声明相一致,如参数个数是否正确,参数类型是否匹配等;如果有参数类型不匹配但都是数值类型,编译器会把实际参数值转换成形式参数类型相同的值
编译器错误和警告的区别:前者阻止编译继续进行,后者不阻止
示例代码:
#include <stdio.h>
int max_cal(int a, int b);
int main(void)
{
int i = 7;
int j = 3;
float m = 7.0;
float n = 3.0;
// max_cal(7, 3)和max_cal(7.0, 3.0)等价
printf("the larger number is %d \n", max_cal(i, j)); // 实参为int类型,与形参类型一致
printf("the larger number is %d \n", max_cal(m, n)); // 实参为float类型,被转换为int类型
return 0;
}
int max_cal(a, b) // 比较,求较大值
{
if(a > b)
{
return a;
}
else
{
return b;
}
}
运行结果:
二、无参数和不确定参数
为了表示一个函数确实不使用参数,需要在圆括号中加入void关键字
void function(void);
一些函数(printf()函数、scanf()函数等)使用的参数个数是变化的,ANSI C允许使用不确定的函数原型,例如对于printf()函数可以使用函数原型:
int printf(char *, ...); // 该原型表示第一个参数是一个字符串,而其余的参数不能确定
对于参数不确定的函数,C库通过stdarg.h头文件提供了定义该类函数的标准方法
三、函数原型的优点(与ANSI C之前的规范相比)
函数原型是对程序语言的有力补充
有利于编译器主动发现函数使用时可能出现的错误或疏漏
使用函数原型的目的:在编译器第一次调用函数的语句之前向其表明该函数的使用方法
对于一些代码较少的函数,函数原型和函数定义也可以合并,例如上面的示例代码也可以写成以下简洁的形式:
int max_cal(int a, int b) {return a > b ? a : b;} // 函数原型与函数定义合并
// 既是函数的定义,也是函数的原型
int main(void)
{
int i = 7;
int j = 3;
float m = 7.0;
float n = 3.0;
printf("the larger number is %d \n", max_cal(i, j)); // 实参为int类型,与形参类型一致
printf("the larger number is %d \n", max_cal(m, n)); // 实参为float类型,被转换为int类型
return 0;
}