11

我不熟悉 K&R 风格的函数声明。

编译后,带有警告(仅与 main 的返回值有关-Wall)但是使用的变量的数据类型是什么?

main(a, b, c, d){
    printf("%d", d);
}

foo(a, b){
     a = 2; 
     b = 'z';
}

如果这是之前提出的问题,请在评论部分提供链接。我找不到类似的东西。

编辑

我刚刚遇到了一个混淆的 C 代码,它使用了这些。
但我可以向你保证,我不会在 C 编程中使用这种语法。

4

4 回答 4

21

“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(一种没有参数,一种有两个参数,argcand 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 编程中使用这种语法。

出色的!

于 2013-08-24T19:36:53.447 回答
6

在 K&R 风格的函数定义中,参数的类型由一组位于函数“签名”本身和实际函数体之间的专用声明指定。比如这个函数定义

void foo(a, b, c)
double a;
char b;
{
  ...
}

使用 和 类型的double参数。这实际上是“隐式 int”规则发挥作用的地方和方式:由于上述声明列表中没有提到参数,因此假定它具有 type 。charintcint

请注意重要的细节,我认为其他答案还不够清楚:参数c具有类型int不是因为函数参数列表中缺少类型,而是因为在函数“签名”之后的声明符序列中没有提到它(在函数体之前)。在 K&R 风格的声明中,函数参数列表中总是缺少类型(这是 K&R 声明的定义特征),但这并不意味着所有参数都被假定为 type int

PS 请注意,C99 仍然支持 K&R 样式声明,但由于 C99 禁止“隐式 int”规则,它要求您在函数“签名”之后提及该声明列表中的所有函数参数。由于这个原因,上面的例子不能在 C99 中编译。int c必须添加到声明列表中。

于 2013-08-25T01:49:21.053 回答
3

默认参数是 C 中的 int 类型,关于 K & R 语法请查看此处此处

于 2013-08-24T18:29:40.380 回答
3

在 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';}
于 2013-08-24T18:27:03.990 回答