关于ANSI C函数声明,这是如何从旧的K&R风格改进的?我知道他们之间的差异,我只是想知道使用旧款式会出现什么问题以及新款式如何改进.
特别是旧式函数声明不允许对调用进行编译时检查.
例如:
int func(x, y)
char *x;
double y;
{
/* ... */
}
Run Code Online (Sandbox Code Playgroud)
...
func(10, 20);
Run Code Online (Sandbox Code Playgroud)
当编译器看到调用时,它不知道函数的参数类型func,因此无法诊断错误.
相比之下:
int better_func(char *x, double y) {
/* ... */
}
Run Code Online (Sandbox Code Playgroud)
...
better_func(10, 20);
Run Code Online (Sandbox Code Playgroud)
将导致编译器错误消息(或至少一个警告).
另一个改进:原型使得可以使用类型参数float和比int(3 char种类型和两种short类型)更窄的整数类型的函数.没有原型,float被提升为double,并且窄整数类型被提升为int或者unsigned int.使用原型,float参数作为a传递float(除非函数是可变参数,例如printf,在这种情况下,旧规则适用于可变参数).
在C原理文件讨论这部分6.7.5.3,可能比我更好:
函数原型机制是C语言最有用的补充之一.当然,这一特征在过去25年来的许多Algol派生语言中都有先例.标准中采用的特定形式在很大程度上基于C++.
函数原型提供强大的转换时错误检测功能.在没有原型的传统C实践中,转换器在调用另一个源文件中声明的函数时很难检测错误(错误的数量或类型的参数).在运行时或通过使用辅助软件工具检测到此类错误.
在不在函数原型范围内的函数调用中,整数参数应用了整数提升,并且浮点 参数被加宽为double.在这样的调用中不可能传递未转换的char或float参数.函数原型为程序员提供了对函数参数类型转换的显式控制,因此实现可以抑制参数的通常不适当且有时效率低的默认扩展规则.
还有更多; 去读它.