要真正符合标准的,必须所有功能在C(除了主要)中有一个原型,即使他们仅使用后他们中的定义相同的翻译单位?

有帮助吗?

解决方案

这取决于你的意思是'真正的符合标准'.然而,简短的回答是"这是一个很好的想法,以确保所有功能原型的范围之前使用"。

一个更有资格回答指出,如果功能接受的变量的参数(值得注意的是的 printf() 家庭的功能),则一个原型必须在范围应严格符合标准。这是真正的C89(ANSI)和C90(从ISO;同C89除了部分的编号).比其他的'varargs'功能,虽然职能,其回报 int 不要宣布和功能返回的东西比一个 int 需要一个宣言,显示回返的类型,但不需要的原型参数清单。

然而,请注意,如果功能需要参数,受到正常的促销活动'在没有原型(例如,一个功能,需要一个 charshort -两者都被转换成 int;更严重的是,也许,一个功能,需要一个 float 而不是一个 double),然后一个原型是必要的。该标准宽松的关于这个允许的老C码来编制在标准符合标准的编译器;旧编码未写的担心确保职能被宣布之前使用过的定义,老年码没有使用原型,因为他们没有成为提供C直到有一个标准。

C99不允许'隐含int'...这意味着这两个古怪的情况下,像'static a;'(一个 int 通过默认)和也隐含的功能的声明。这些都是所提到的(与大约50个其他重大变化)在序言ISO/IEC9899:1999年 其中比较标准的先前版本:

  • 消除隐性的 int
  • 消除隐性功能的声明

在ISO/IEC9899:1990年,§6.3.2.2 功能的电话 说明:

如果在表达之前的带括号的参数列在一个功能包括呼叫 仅仅一个标识符,并且如果没有《宣言》是可见的,对于这种标识,标识是隐含地 声明,正是因为如果在最里面包含块的功能的电话,声明:

extern int identifier();

出现。38

38 也就是说,标识与块范围的宣称有外部联系的类型功能没有 参数的信息和返回 int.如果实际上这不是定义为具有类型的"功能 回 int"的行为是不确定的。

这一段缺失,在1999年的标准。我没有(尚未)行跟踪变化的措辞,允许 static a; 在C90和不允许它(要求 static int a;)在C99。

请注意,如果一个功能是静态的,它可以限定在使用之前,并不需要之前,通过一项宣言。海湾合作委员会就可以说服惠如果一个非静态功能的定义没有《宣言》之前(-Wmissing-prototypes).

其他提示

prototype 是一个函数声明,它指定函数参数的类型。

前ANSI C(1978年第一版Kernighan <!> amp; Ritchie's <!>所描述的语言; C编程语言<!>“)没有原型;函数声明不可能描述参数的数量或类型。由调用者传递正确数量和类型的参数。

ANSI C引入了<!> quot; prototypes <!> quot;,声明指定参数的类型(从早期的C ++中借用的一个特性)。

从C89 / C90(ANSI和ISO标准描述相同的语言)开始,调用没有可见声明的函数是合法的;提供了隐式声明。如果隐式声明与实际定义不兼容(例如,调用sqrt("foo"),则行为是未定义的。此隐式声明和非原型声明都不能与可变参数函数兼容,因此对可变参数函数的任何调用(像printfscanf一样,必须有一个可见的原型。

C99删除了隐式声明。对没有可见声明的函数的任何调用都是违反约束的,需要编译器诊断。但该声明仍然不需要成为原型;它可以是旧式声明,不指定参数类型。

C11在这方面没有发生重大变化。

因此,即使是2011 ISO C标准,仍然允许在符合规范的代码中使用旧式函数声明和定义(自1989年以来一直是<!>“obsolescent <!>”)。

对于可追溯到1989年的所有C版本,作为一种风格问题,没有理由不将原型用于所有功能。保留旧式声明和定义只是为了避免破坏旧代码。

不,功能并不总是需要原型。唯一的要求是函数是<!> quot;声明<!> quot;在你使用它之前。有两种方法可以声明一个函数:编写一个原型,或者编写一个函数本身(称为<!> quot; definition。<!> quot;)定义总是一个声明,但并非所有声明都是定义。

是的,每个函数都必须有一个原型,但该原型可能出现在单独的声明中,也可能出现在函数定义的一部分中。用C89编写的函数定义自然会有原型,但是如果你用经典的K <!> amp; R样式写东西,那么:

main (argc, argv)

  int argc;
  char **argv;

{
  ...
}

然后函数定义没有原型。如果你写ANSI C(C89)样式,那么:

main (int argc, char **argv) { ... }

然后函数定义有一个原型。

编写新函数时,一个很好的提示是将它们颠倒写入,并将main写在底部,这样当您改变主意关于函数的args或返回类型时,您也不必修复原型。不断修复原型,并在它们过时时处理所有编译器的警告变得非常乏味。

让函数顺利运行后,将代码移动到一个命名良好的模块,并将原型放在同名的.h文件中。它节省了大量时间。我在5年内发现的最大生产力援助。

据我所知(在ANSI C89 / ISO C90中),没有。我不确定C99;但是,我希望也一样。

个人注意事项我只在......时编写函数原型。

  1. 我需要(当A()调用B() B()调用A())或
  2. 我正在导出这个功能;否则,感觉多余。
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top