c/c++语言开发共享ANSI C函数声明如何改进旧的Kernigan和Ritchie风格?

关于ANSI C函数声明,这是如何从旧的K&R风格改进的? 我知道它们之间的区别,我只想知道使用旧样式会出现什么问题以及新样式是如何改进的。

    特别是旧式函数声明不允许对调用进行编译时检查。

    例如:

    int func(x, y) char *x; double y; { /* ... */ } 

     func(10, 20); 

    当编译器看到调用时,它不知道函数func的参数类型,因此无法诊断错误。

    相比之下:

     int better_func(char *x, double y) { /* ... */ } 

     better_func(10, 20); 

    将导致编译器错误消息(或至少是警告)。

    另一个改进:原型使得函数可以使用float类型的参数,以及比int更窄的整数类型(3个char类型和两个short类型)。 如果没有原型, float会被提升为double ,而窄整数类型会被提升为intunsigned int 。 使用原型, float参数作为float传递(除非函数是可变参数,如printf ,在这种情况下旧规则适用于可变参数)。

    C Rationale文档在第6.7.5.3节中对此进行了讨论,可能比我更好:

    函数原型机制是C语言最有用的补充之一。 当然,这一特征在过去25年来的许多Algol派生语言中都有先例。 标准中采用的特定forms在很大程度上基于C ++。

    函数原型提供强大的转换时错误检测function。 在没有原型的传统C实践中,转换器在调用另一个源文件中声明的函数时很难检测错误(错误的数量或类型的参数)。 在运行时或通过使用辅助软件工具检测到此类错误。

    在不在函数原型范围内的函数调用中,整数参数应用了整数提升,并且浮点参数被加宽为double 。 在这样的调用中不可能传递未转换的charfloat参数。 函数原型为程序员提供了对函数参数类型转换的显式控制,因此实现可以抑制通常不合适且有时效率低下的参数默认扩展规则。

    还有更多; 去读它。

    K&R中的非定义函数声明如下所示

     int foo(); 

    并引入了一个接受未指定数量的参数的函数。 这种声明风格的问题很明显:它既没有指定参数的数量,也没有指定它们的类型。 编译器无法根据调用点处的参数数量或类型来检查调用的正确性。 在参数类型与预期参数类型不匹配的情况下,编译器无法执行参数类型转换或发出错误消息。

    函数声明用作K&R中函数定义的一部分,如下所示

     int foo(a, b) int a; char b; { ... 

    它指定参数的数量,但仍未指定其类型。 此外,即使参数的数量似乎通过此声明公开,它仍然正式声明fooint foo(); 这意味着将其称为foo(1, 2, 3, 4, 5)仍然不构成约束违规。

    新样式,即原型声明更好,原因很明显:它暴露了参数的数量和类型。 它强制编译器检查调用的有效性(关于参数的数量和类型)。 它允许编译器执行从参数类型到参数类型的隐式类型转换。

    原型声明提供了其他不太明显的好处。 由于函数参数的数量和类型对于调用者和函数本身都是精确已知的,因此可以选择在调用时传递参数(调用约定)的最有效方法,而无需查看函数定义。 如果没有这些信息,K&R实施将被迫遵循所有function的单一预定“一刀切”调用约定。

      以上就是c/c++开发分享ANSI C函数声明如何改进旧的Kernigan和Ritchie风格?相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。

      本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

      ctvol管理联系方式QQ:251552304

      本文章地址:https://www.ctvol.com/c-cdevelopment/545052.html

      (0)
      上一篇 2021年1月10日
      下一篇 2021年1月10日

      精彩推荐