代码之家  ›  专栏  ›  技术社区  ›  Sydius

C89、C90或C99中的所有功能都需要原型吗?

  •  43
  • Sydius  · 技术社区  · 17 年前

    6 回复  |  直到 17 年前
        1
  •  40
  •   Fabio says Reinstate Monica MoMoTaur    9 年前

    更符合条件的答案是,如果函数接受变量参数(尤其是 printf() int 不必声明,以及返回除 确实需要显示返回类型的声明,但不需要参数列表的原型。

    但是,请注意,如果函数采用在没有原型的情况下受“正常提升”约束的参数(例如,采用 char 或 short -两者都转换为 int ; 也许更严重的是,一个函数需要 float 而不是 double )然后需要一个原型。标准对此很宽松,允许旧的C代码在符合标准的编译器下编译;较旧的代码并不是为了确保函数在使用前声明而编写的——根据定义,较旧的代码并没有使用原型,因为在有标准之前原型在C中是不可用的。

    C99不允许“隐式int”…这意味着两种奇怪的情况都是 static a; "(一) 默认情况下)以及隐式函数声明。ISO/IEC 9899:1999的前言中提到了这些(以及大约50个其他主要变化), 将该标准与以前的版本进行比较:

    • int

    在ISO/IEC 9899:1990,§6.3.2.2中 规定的:

    如果函数调用中括号参数列表前面的表达式包含 声明的方式与在包含函数调用的最内层块中声明的方式完全相同:

    extern int identifier();
    

    出现。 38

    38 也就是说,具有块作用域的标识符被声明为具有与类型函数的外部链接,而不具有 参数信息并返回 int int ,该行为未定义。

    本段在1999年标准中缺失。我还没有(至今)追踪到措辞上允许的变化 静态a; static int a; )在C99中。

    -Wmissing-prototypes ).

        2
  •  18
  •   Keith Thompson    13 年前

    原型 是指定函数参数类型的函数声明。

    ANSI之前的C语言(1978年第一版Kernighan&Ritchie的“C编程语言”描述的语言)没有原型;函数声明不可能描述参数的数量或类型。由调用方传递正确数量和类型的参数。

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

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

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

        3
  •  14
  •   Artelius    17 年前

    不,功能并不总是需要原型。唯一的要求是在使用函数之前先“声明”它。声明函数有两种方法:编写原型,或编写函数本身(称为“定义”)。定义始终是声明,但并非所有声明都是定义。

        4
  •  2
  •   user1899861 user1899861    11 年前

    在编写新函数时,一个很好的技巧是将它们倒置,main在底部,这样当您改变对函数参数或返回类型的看法时,就不必再修改原型了。不断地修复原型,以及在编译器的警告过期时处理这些警告,都会变得非常乏味。

    一旦您的函数顺利地协同工作,将代码移动到一个命名良好的模块,并将原型放在一个同名的.h文件中。这节省了严肃的时间。这是我5年来发现的最大的生产力援助。

        5
  •  1
  •   Norman Ramsey    17 年前

    是的,每个函数都必须有一个原型,但该原型可以出现在单独的声明中,也可以作为函数定义的一部分。用C89或更高版本编写的函数定义自然有原型,但如果你用经典的K&R风格,因此:

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

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

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

        6
  •  0
  •   2 revs<br/>Anthony Cuozzo&#13;    17 年前

    就我所知(ANSI C89/ISO C90),没有。我不确定C99;然而,我也希望如此。

    个人说明: 我只在。。。

    1. 我需要(当A()调用B()时) 和 B()调用A()),或
    2. 我正在导出函数;否则,这感觉是多余的。