我不熟悉K&R风格的函数声明。
下面是带有警告的编译(仅与使用-Wall
的main的返回值有关),但是使用的变量的数据类型是什么?
main(a, b, c, d){
printf("%d", d);
}
foo(a, b){
a = 2;
b = 'z';
}
如果这是一个询问之前,请提供在评论部分的链接。我找不到类似的东西。
编辑
我刚看到一个模糊的C代码,它使用这些。
但我可以向您保证,我不会在C编程中使用这种语法。
发布于 2013-08-24 19:36:53
"K&R C“是指1978年Kernighan &Ritchie的著作”C编程语言“第一版所定义的语言。
在K&R (即前ANSI) C中,实体通常可以在没有显式类型的情况下声明,并且默认为int
类型。这可以追溯到C的祖先语言B和BCPL。
main(a,b,c,d){
printf("%d", d);
}
这几乎相当于:
int main(int a, int b, int c, int d) {
printf("%d", d);
}
在ANSI C (1989)和ISO C (1990)中,旧语法仍然合法,但过时了,但1999年ISO C标准放弃了“隐式int”规则(同时保留了旧的声明和定义语法)。
请注意,我说过它几乎是等价的。当被看作定义时,本质上是相同的,但作为声明,它不提供参数类型信息。使用旧式定义,不需要诊断带有错误数量或类型的参数的调用;它只是未定义的行为。对于可见的原型,不匹配的参数触发编译时诊断--如果可能,参数被隐式转换为参数类型。
因为这是main
的定义,所以还有另一个问题。标准只为main
指定两种形式(一种没有参数,另一种有两个参数,argc
和argv
)。实现可能支持其他形式,但是有四个int
参数的实现不太可能是其中之一。因此,程序的行为是未定义的。实际上,d
很可能在最初的调用中有一些垃圾值。(是的,C中允许递归调用main
,但这绝不是一个好主意。)
foo(a,b){
a = 2;
b = 'z';
}
这几乎相当于:
int foo(int a, int b) {
a = 2;
b = 'z';
}
(请注意,'z'
是int
类型,而不是char
类型。)
同样,旧表单不提供参数类型检查,因此调用如下:
foo("wrong type and number of arguments", 1.5, &foo);
不需要被诊断。
底线:很好地知道K&R风格的函数声明和定义是如何工作的。仍然有旧代码使用它们,即使在C2011中(尽管没有“隐式int”规则),它们仍然是合法的(但已经过时了)。但是,编写使用它们的代码几乎没有很好的理由(除非您只能使用一个非常老的编译器,但这很少见,而且越来越少见)。
但我可以向您保证,我不会在C编程中使用这种语法。
太棒了!
发布于 2013-08-25 01:49:21
在K&R风格的函数定义中,参数的类型由函数“签名”本身和实际函数体之间的一组专用声明指定。例如,这个函数定义
void foo(a, b, c)
double a;
char b;
{
...
}
使用double
、char
和int
类型的参数。这实际上是“隐式int”规则起作用的位置和方式:由于上面的声明列表没有提到参数c
,所以假定它具有int
类型。
注意重要的细节,我认为其他答案没有足够清楚地说明这一点:参数c
的类型int
不是因为函数参数列表中缺少类型,而是因为它没有在函数“签名”之后的声明符序列中提及(在函数主体之前)。在K&R风格的声明中,函数参数列表中总是缺少类型(这是K&R声明的定义特性),但这并不意味着所有参数都被假定为int
类型。
请注意,C99仍然支持K&R样式声明,但是由于C99宣布“隐式int”规则为非法,它要求您在函数“签名”之后提及声明列表中的所有函数参数。由于这个原因,上面的示例不会在C99中编译。必须将int c
添加到声明列表中。
发布于 2013-08-24 18:27:03
在C89中,默认变量类型是int
:它被定义为隐式int。此规则在C99中已被撤销。
在您的示例中,它被编译为:
main(int a,int b,int c,int d){printf("%d", d);}
foo(int a,int b){a=2; b='z';}
https://stackoverflow.com/questions/18421735
复制相似问题