术语:前向声明与函数原型
Posted
技术标签:
【中文标题】术语:前向声明与函数原型【英文标题】:Terminology: Forward Declaration versus Function Prototype 【发布时间】:2012-01-19 17:50:56 【问题描述】:对我来说,这些术语在使用 C 编程语言时基本上是同义词。在实践中,我可能更喜欢文件内原型的“前向声明”,而不是通过头文件包含的原型的“函数原型”。但是,当您考虑预处理后会发生什么时,即使这是人为的区别。也许我错过了什么。
对于何时使用一个术语与另一个术语是否达成共识?
【问题讨论】:
【参考方案1】:术语“原型”是指特定的声明语法;具体来说,函数参数的数量和类型出现在声明中。给定一个函数定义的
int foo(int a, char *b) ...
您可以拥有以下任何声明:
int foo(); // a declaration, but not a prototype
int foo(a, b); // a declaration, but not a prototype
int foo(int, char *); // a declaration and a prototype
int foo(int a, char *b); // a declaration and a prototype
【讨论】:
您的选项int foo(a, b);
仅在 a
和 b
是已知类型名称时有效,或者如果它后跟函数体 …
而不是分号。【参考方案2】:
我不知道是否有共识,但我认为最干净的方法是:
将所有声明放在头文件中,切勿放在源文件或 .c 文件中。 (我认为当您说前向声明时,您的意思是声明。) 将所有定义放在源文件中我不喜欢将声明放在文件中,因为在 C 中可以有冲突的声明而不会出现错误,这可能会导致段错误,例如:如果 a.c 有
int foo(char *str_one, char *str_two, char *str_three);
b.c 有
int foo(char *str_one, char *str_two);
您不会收到警告或错误,并且从 bc 对 foo() 的调用不会将所有参数放在堆栈中应有的位置,这意味着 foo() 只会从堆栈中抓取一些东西并将其视为 str_three ,可能导致段错误。所以对我来说,声明放在头文件中,定义放在源文件中。
【讨论】:
static
函数的声明应该放在他们在 imho 中定义的 C 文件中,最好放在开头。
@tristopia - 好点,当我在那里使用我的肥皂盒时,我并没有考虑静态函数。我绝对不会在头文件中声明它们。【参考方案3】:
IMO 这些并不是真正的同义词。 对我来说,“函数原型”是指函数名及其参数和返回类型。它不仅适用于您所说的“前向声明”。所有函数都有一个原型。
我们经常在函数声明与其对应的定义之间做出区分。
【讨论】:
+1,尽管使用“原型”这个词来指代声明确实很常见。 我想你和@MatteoItalia 已经总结了。当我应该使用术语声明时,我一直在使用术语原型。【参考方案4】:我使用术语前向声明来表示以下带有定义的struct
声明。
struct Foo;
为了与 1989 年之前的 (K&R) C 兼容,函数声明不必是完整的原型。
char *foo(); // NOT the same as char *foo(void)
【讨论】:
【参考方案5】:我知道的 C 语言中唯一的概念是声明和定义之间的区别。原型是一种声明,可以随时随地发生,并且定义是给定对象的实际实现。按照这个概念,没有什么叫做前向声明,只有一个声明的顺序。
【讨论】:
以上是关于术语:前向声明与函数原型的主要内容,如果未能解决你的问题,请参考以下文章