我不熟悉 K&R 风格的函数声明。
编译后,带有警告(仅与 main 的返回值有关-Wall
)但是使用的变量的数据类型是什么?
main(a, b, c, d){
printf("%d", d);
}
foo(a, b){
a = 2;
b = 'z';
}
如果这是之前提出的问题,请在评论部分提供链接。我找不到类似的东西。
编辑
我刚刚遇到了一个混淆的 C 代码,它使用了这些。
但我可以向你保证,我不会在 C 编程中使用这种语法。
我不熟悉 K&R 风格的函数声明。
编译后,带有警告(仅与 main 的返回值有关-Wall
)但是使用的变量的数据类型是什么?
main(a, b, c, d){
printf("%d", d);
}
foo(a, b){
a = 2;
b = 'z';
}
如果这是之前提出的问题,请在评论部分提供链接。我找不到类似的东西。
编辑
我刚刚遇到了一个混淆的 C 代码,它使用了这些。
但我可以向你保证,我不会在 C 编程中使用这种语法。
“K&R C”指的是由 Kernighan & Ritchie 的 1978 年第一版《The C Programming Language》所定义的语言。
在 K&R(即 pre-ANSI)C 中,实体通常可以在没有显式类型的情况下声明,并且默认为 type 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
and argv
)。一个实现可能支持其他形式,但一个有四个int
参数的不太可能是其中之一。因此程序的行为是未定义的。在实践中,很可能d
在初始调用时会有一些垃圾值。(是的,在 C 中允许递归调用main
,但这绝不是一个好主意。)
foo(a,b){
a = 2;
b = 'z';
}
这几乎等同于:
int foo(int a, int b) {
a = 2;
b = 'z';
}
(请注意,它'z'
是 type int
,而不是 type char
。)
再一次,旧形式没有给你参数类型检查,所以调用如下:
foo("wrong type and number of arguments", 1.5, &foo);
不需要确诊。
底线:很高兴知道 K&R 风格的函数声明和定义是如何工作的。仍然有使用它们的旧代码,即使在 C2011 中它们仍然是合法的(但已过时)(尽管没有“隐式 int”规则)。但是几乎没有充分的理由编写使用它们的代码(除非您使用非常旧的编译器,但这种情况很少见并且越来越少。)
但我可以向你保证,我不会在 C 编程中使用这种语法。
出色的!
在 K&R 风格的函数定义中,参数的类型由一组位于函数“签名”本身和实际函数体之间的专用声明指定。比如这个函数定义
void foo(a, b, c)
double a;
char b;
{
...
}
使用 和 类型的double
参数。这实际上是“隐式 int”规则发挥作用的地方和方式:由于上述声明列表中没有提到参数,因此假定它具有 type 。char
int
c
int
请注意重要的细节,我认为其他答案还不够清楚:参数c
具有类型int
不是因为函数参数列表中缺少类型,而是因为在函数“签名”之后的声明符序列中没有提到它(在函数体之前)。在 K&R 风格的声明中,函数参数列表中总是缺少类型(这是 K&R 声明的定义特征),但这并不意味着所有参数都被假定为 type int
。
PS 请注意,C99 仍然支持 K&R 样式声明,但由于 C99 禁止“隐式 int”规则,它要求您在函数“签名”之后提及该声明列表中的所有函数参数。由于这个原因,上面的例子不能在 C99 中编译。int c
必须添加到声明列表中。
在 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';}