函数声明:K&R 与 ANSI
K&R 函数声明和 ANSI 函数声明有什么区别?
What are the differences between a K&R function declaration and an ANSI function declaration?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
K&R 函数声明和 ANSI 函数声明有什么区别?
What are the differences between a K&R function declaration and an ANSI function declaration?
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(3)
K&R 语法已过时,您可以跳过它,除非您必须维护非常旧的代码。
K&R syntax is obsolete, you can skip it unless you have to maintain very old code.
旧版 K&R 风格的声明/定义
当 Kernighan 和 Ritchie 首次出版《C 编程语言》时,C 尚未提供完整的函数原型。函数的前向声明是存在的,但其唯一目的是指示返回类型。对于返回 int 的函数,直到 C99 才需要它们。
到了 C89,添加了函数原型的概念,它还指定了参数的类型(以及隐式的参数数量)。由于原型也是函数声明的一种类型,因此非官方术语“K&R 函数声明”有时用于表示不是原型的函数声明。
意外的 K&R 声明
值得注意的是,C 语言的新手在打算使用完整原型时可能会意外地使用 K&R 声明,因为他们可能没有意识到必须将空参数列表指定为
无效
。如果您将函数声明并定义为
...,那么您实际上并没有给出不带参数的函数的原型,而是以 K&R 风格声明了接受未知数量和未知类型的参数的函数。
AnT 在这个答案中指出类似的问题,这种语法已被弃用,但从 C99 开始仍然合法(并且该函数指针指向参数数量和类型未知的函数仍然具有潜在的应用,尽管存在未定义行为的高风险);因此,如果在没有正确原型的情况下声明或调用函数,兼容的编译器最多只会发出警告。
调用没有原型的函数不太安全,因为编译器无法验证您是否以正确的顺序传递了正确数量和类型的参数;如果调用实际上不正确,则会导致未定义的行为。
当然,声明和定义无参数函数的正确方法是:
Legacy K&R-Style Declarations/Definitions
When Kernighan and Ritchie first published "The C Programming Language", C didn't yet offer full function prototypes. Forward declarations of functions existed, but with the sole purpose of indicating a return type. For functions that returned
int
, they weren't required until C99.By C89, the notion of a function prototype, which also specifies the types of the parameters (and, implicitly, their number) had been added. Since a prototype is also a type of function declaration, the unofficial term "K&R function declaration" is sometimes used for a function declaration that is not also a prototype.
The Accidental K&R Declaration
It's worth noting that newcomers to C may accidentally use K&R declarations when they intend to use a full prototype, because they may not realize that an empty parameter list must be specified as
void
.If you declare and define a function as
...then you have not actually given a prototype for a function that takes no parameters, but a declaration in K&R-style for a function that accepts an unknown number of parameters of unknown type.
AnT notes in this answer to a similar question that this syntax is deprecated but still legal as of C99 (and that function pointers to functions with unknown number and type of parameters still have potential applications, though at high risk of undefined behavior); as such, compliant compilers will, at best, produce a warning if a function is declared or called without a proper prototype.
Calling functions without prototypes is less safe, because the compiler cannot verify that you have passed the correct number and types of parameters in the correct order; undefined behavior results if the call is not actually correct.
The correct way to declare and define a parameterless function is, of course:
我只是想在传统的 K & 中添加这一点。返回
int
值的函数的 R 风格类型修饰符甚至不是必需的。考虑一个简单的 HelloWorld 程序的现代 C11 表示法:
这相当于 K & R 表示法风格:
请注意,
main()
之前的int
被忽略,但代码仍然可以编译。这是 K & 的一部分。 R 定义。引用维基百科:
--source: https://en.wikipedia.org/wiki/C_( programming_language)#K.26R_C
这可以说是一种遗留的编码风格,由于清晰度问题应该避免,但旧的算法教科书通常更喜欢这种 K & R风格。
I just want to add that in the traditional K & R style type modifiers for functions that return an
int
value aren't even necessary.Consider the modern C11 notation of a simple HelloWorld program:
This is equivalent to the K & R notation style:
Note that the
int
beforemain()
is ignored, but the code still compiles. That's a part of the K & R definition.Quote Wikipedia:
--source: https://en.wikipedia.org/wiki/C_(programming_language)#K.26R_C
This is arguably a legacy coding-style and should be avoided due to clarity issues, but quite often old algorithm textbooks favour this sort of K & R style.