C 为什么没有参数的函数(与实际函数定义相比)要编译?

C 为什么没有参数的函数(与实际函数定义相比)要编译?,c,parameters,void,function-prototypes,function-parameter,C,Parameters,Void,Function Prototypes,Function Parameter,我刚刚遇到了一些人的C代码,我不明白为什么要编译它。有两点我不明白 与实际功能定义相比,功能原型没有参数 函数定义中的参数没有类型 #包括 int func(); int func(参数) { 返回参数; } int main() { int bla=func(10); printf(“%d”,bla); } 为什么这样做有效? 我已经在几个编译器中对它进行了测试,它工作得很好。在Cfunc()中意味着可以传递任意数量的参数。如果不需要参数,则必须声明为func(void)。传递给函数的

我刚刚遇到了一些人的C代码,我不明白为什么要编译它。有两点我不明白

  • 与实际功能定义相比,功能原型没有参数

  • 函数定义中的参数没有类型


  • #包括
    int func();
    int func(参数)
    {
    返回参数;
    }
    int main()
    {
    int bla=func(10);
    printf(“%d”,bla);
    }
    
    为什么这样做有效?
    我已经在几个编译器中对它进行了测试,它工作得很好。

    在C
    func()
    中意味着可以传递任意数量的参数。如果不需要参数,则必须声明为
    func(void)
    。传递给函数的类型,如果未指定,则默认为
    int

    。如果函数声明没有参数,即为空,则它将使用未指定数量的参数。如果要使其不带任何参数,请将其更改为:

    int func(void);
    
    • 空参数列表表示“任何参数”,因此定义没有错
    • 假定缺少的类型为
      int

    我会考虑任何经过此配置的配置,缺少配置的警告/错误级别,这是没有意义的,允许实际代码。

    <代码> int函数()code>是从没有C标准的日子开始的废弃函数声明,即K&R C的日子(1989年之前,第一个“ANSI C”标准发布的那一年)

    请记住,K&R C中没有原型,关键字
    void
    还没有发明。您所能做的就是告诉编译器函数的返回类型。K&R C中的空参数列表表示“未指定但固定”数量的参数。Fixed表示每次调用函数时必须使用相同数量的参数(而不是像
    printf
    这样的可变函数,每次调用的参数和类型都可能不同)

    许多编译器将诊断此构造;特别是 Gcc-Wrand原型将告诉你“函数声明不是原型”,它是SPOT,因为它看起来像一个原型(尤其是如果你被C++毒死了),但不是。这是一个老式的K&R C返回类型声明

    经验法则:不要将空参数列表声明保留为空,具体使用
    int func(void)

    这将把K&R返回类型声明转换成一个合适的C89原型。编译器很高兴,开发人员很高兴,静态检查器很高兴。但是,C++的^ ^ Wfond误导的人可能会畏缩,因为他们在试图练习外语技能时需要输入额外的字符:-(<)/P> < P>所有其他答案都是正确的,但仅适用于

    函数的声明方式如下:

      return-type function-name(parameter-list,...) { body... }
    
    返回类型是函数返回的变量类型。这不能是数组类型或函数类型如果未给出,则为int 假定为

    函数名是函数的名称


    参数列表是函数采用的参数列表,以逗号分隔如果未给出参数,则函数 不接受任何,应使用空的 带关键字void的括号或。如果前面没有变量类型 对于参数列表中的变量,则假定int。数组和 函数不会传递给函数,但会自动转换 指向指针。如果列表以省略号(,…)结尾,则 没有设置数量的参数。注:标题标准h可以是 用于在使用省略号时访问参数

    为了完整起见。(第179页)

    使用带空括号的函数声明符 原型格式参数类型声明符)已过时 功能


    它是K&R风格的函数声明和定义。来自C99标准(ISO/IEC 9899:TC3)

    第6.7.5.3节功能声明器(包括原型)

    标识符列表仅声明函数参数的标识符。空的 作为函数定义一部分的函数声明器中的列表指定 函数没有参数函数声明符中不属于 该函数的定义指定没有关于函数的数量或类型的信息 提供了参数。(如果两种功能类型都是“旧式”,则不比较参数类型。)

    第6.11.6节功能声明器

    使用带空括号的函数声明符(不是原型格式参数 类型声明器)是一项过时的功能。

    第6.11.7节功能定义

    使用带有单独参数标识符和声明列表的函数定义 (不是原型格式参数类型和标识符声明符)是一项过时的功能。

    旧样式的意思是K&R样式

    例如:

    声明:
    int old_style()

    定义:

    int old_style(a, b)
        int a; 
        int b;
    {
         /* something to do */
    }
    

    关于参数类型,这里已经有了正确的答案,但是如果您想从编译器那里听到它,您可以尝试添加一些标志(无论如何,标志几乎总是一个好主意)

    使用gcc foo.c-Wextra编译程序

    foo.c: In function ‘func’:
    foo.c:5:5: warning: type of ‘param’ defaults to ‘int’ [-Wmissing-parameter-type]
    
    奇怪的是,
    -Wextra
    没有捕捉到这一点,因为
    叮当声
    (出于某种原因,它不识别
    -Wmissing参数类型
    ,可能是出于上述历史原因),但
    -pedantic
    确实:

    foo.c:5:10: warning: parameter 'param' was not declared, 
    defaulting to type 'int' [-pedantic]
    int func(param)
             ^
    1 warning generated.
    
    对于上面再次提到的原型问题,参见
    foo.c:5:10: warning: parameter 'param' was not declared, 
    defaulting to type 'int' [-pedantic]
    int func(param)
             ^
    1 warning generated.
    
    foo.c: In function ‘func’:
    foo.c:6:1: error: number of arguments doesn’t match prototype
    foo.c:3:5: error: prototype declaration
    foo.c: In function ‘main’:
    foo.c:12:5: error: too many arguments to function ‘func’
    foo.c:5:5: note: declared here
    
    foo.c:5:5: error: conflicting types for 'func'
    int func(param)
        ^
    foo.c:3:5: note: previous declaration is here
    int func(void);
        ^
    foo.c:12:20: error: too many arguments to function call, expected 0, have 1
        int bla = func(10);
                  ~~~~ ^~
    foo.c:3:1: note: 'func' declared here
    int func(void);
    ^
    2 errors generated.
    
    int func(int param) { /* body */}
    
    int func(int param);
    
    int func(int);
    
    int func(param);
    
    func();
    
    int myfunc(int param);
    
    cc -Wmissing-variable-declarations -Wstrict-variable-declarations -Wold-style-definition
    
    int f(), *fpi(), (*pfi)();