我刚刚遇到了一些人的C代码,我很困惑为什么它要编译。有两点我不明白。
与实际函数定义相比,函数原型没有参数。 函数定义中的形参没有类型。
#include <stdio.h>
int func();
int func(param)
{
return param;
}
int main()
{
int bla = func(10);
printf("%d", bla);
}
为什么会这样? 我已经在几个编译器中测试了它,它工作得很好。
我刚刚遇到了一些人的C代码,我很困惑为什么它要编译。有两点我不明白。
与实际函数定义相比,函数原型没有参数。 函数定义中的形参没有类型。
#include <stdio.h>
int func();
int func(param)
{
return param;
}
int main()
{
int bla = func(10);
printf("%d", bla);
}
为什么会这样? 我已经在几个编译器中测试了它,它工作得很好。
当前回答
如果函数声明没有形参,即为空,则它将接受不指定数量的参数。如果你想让它不带参数,那么将其更改为:
int func(void);
其他回答
空参数列表表示“任何参数”,因此定义没有错。 缺失的类型被假定为int型。
我认为任何通过这一点的构建都缺乏配置的警告/错误级别,尽管如此,允许实际代码没有任何意义。
如果函数声明没有形参,即为空,则它将接受不指定数量的参数。如果你想让它不带参数,那么将其更改为:
int func(void);
如果函数返回类型和形参列表上没有给出类型,则C语言假定为int。只有遵循这条规则,才有可能发生奇怪的事情。
函数定义是这样的。
int func(int param) { /* body */}
如果它是一个原型,你写
int func(int param);
在原型中,你只能指定参数的类型。参数名称为非必选项。所以
int func(int);
同样,如果你没有指定参数类型,但名称int被假设为类型。
int func(param);
如果你走得更远,跟着也行。
func();
当你编写func()时,编译器假设int func()。但是不要把func()放在函数体中。这是一个函数调用
关于参数类型,这里已经有了正确的答案,但如果你想从编译器那里听到它,你可以尝试添加一些标志(标志几乎总是一个好主意)。
使用gcc foo.c编译你的程序
foo.c: In function ‘func’:
foo.c:5:5: warning: type of ‘param’ defaults to ‘int’ [-Wmissing-parameter-type]
奇怪的是-Wextra没有捕捉到这个clang(它不识别-Wmissing-parameter-type出于某种原因,可能是上面提到的历史原因),但-pedantic可以:
foo.c:5:10: warning: parameter 'param' was not declared,
defaulting to type 'int' [-pedantic]
int func(param)
^
1 warning generated.
对于原型问题,如上所述,int func()指的是任意参数,除非你明确地将其定义为int func(void),这将给你带来预期的错误:
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.
其他答案都是正确的,但只是为了完成
A function is declared in the following manner: return-type function-name(parameter-list,...) { body... } return-type is the variable type that the function returns. This can not be an array type or a function type. If not given, then int is assumed. function-name is the name of the function. parameter-list is the list of parameters that the function takes separated by commas. If no parameters are given, then the function does not take any and should be defined with an empty set of parenthesis or with the keyword void. If no variable type is in front of a variable in the paramater list, then int is assumed. Arrays and functions are not passed to functions, but are automatically converted to pointers. If the list is terminated with an ellipsis (,...), then there is no set number of parameters. Note: the header stdarg.h can be used to access arguments when using an ellipsis.
为了完整起见。来自C11规范6:11:6(第179页)
使用带有空括号的函数声明器(不是 原型格式参数类型声明器)是过时的 特性。