Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 术语:前向声明与功能原型_C_Terminology_Forward Declaration_Function Prototypes - Fatal编程技术网

C 术语:前向声明与功能原型

C 术语:前向声明与功能原型,c,terminology,forward-declaration,function-prototypes,C,Terminology,Forward Declaration,Function Prototypes,对我来说,这些术语在使用C编程语言时基本上是同义的。实际上,对于通过头文件包含的原型,我可能更喜欢文件内原型的“转发声明”,而不是“函数原型”。但是,当你考虑预处理后会发生什么时,这也是一种人为的区分。也许我遗漏了什么 关于何时使用一个术语与另一个术语,是否存在共识?我使用术语向前声明来表示以下类型的struct声明及其定义 struct Foo; 为了与1989年以前的(K&R)C兼容,函数声明不需要是完整的原型 我所知道的C语言中唯一的概念是声明和定义之间的区别。原型是一种声明,可以在任何

对我来说,这些术语在使用C编程语言时基本上是同义的。实际上,对于通过头文件包含的原型,我可能更喜欢文件内原型的“转发声明”,而不是“函数原型”。但是,当你考虑预处理后会发生什么时,这也是一种人为的区分。也许我遗漏了什么


关于何时使用一个术语与另一个术语,是否存在共识?

我使用术语向前声明来表示以下类型的
struct
声明及其定义

struct Foo;
为了与1989年以前的(K&R)C兼容,函数声明不需要是完整的原型


我所知道的C语言中唯一的概念是声明和定义之间的区别。原型是一种声明,可以在任何地方、任何时间发生,并且定义是给定对象的实际实现。根据这一概念,没有所谓的前向声明,只有声明的顺序。

依我看,这些并不是真正的同义词。 对我来说,“函数原型”是指函数名及其参数和返回类型。它不仅适用于你们所谓的“远期申报”。所有函数都有一个原型


我们通常会在函数声明与其对应的定义之间进行区分

我不知道是否存在共识,但我认为最干净的方法是:

  • 将所有声明放在头文件中,不要放在源文件或.c文件中。(我想你说的远期申报是指申报。)
  • 将所有定义放置在源文件中
我不喜欢将声明放在文件中,因为在C中可能有冲突的声明而没有错误,这可能会导致segfults,例如:if a.C

int foo(char *str_one, char *str_two, char *str_three);
b.c

int foo(char *str_one, char *str_two);
您将不会收到警告或错误,并且从b.c对foo()进行的调用不会将所有参数放在堆栈上它们应该放在的位置,这意味着foo()只会从堆栈中获取一些内容并将其视为str_三,可能会导致segfault。所以对我来说,声明转到头文件,定义转到源文件。

术语“原型”指的是特定的声明语法;具体来说,函数的参数数量和类型出现在声明中。给出了

您可以有以下任何声明:


+1,虽然用“原型”一词来指代声明是很常见的,但我认为你和@MatteoItalia已经总结了这一点。当我应该使用术语声明时,我一直在使用术语原型。
静态
函数的声明应该放在C文件中,它们是在imho中定义的,最好是在开始时。@tristopia-好的一点,当我在我的soapbox上时,我没有考虑静态函数。我绝对不会在头文件中声明它们a
b
是已知的类型名,或者如果它后面跟的是函数体
{…}
,而不是分号,则code>才有效。
int foo(char *str_one, char *str_two);
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