30

在这个c节目 中

a=8;
main()
{
    printf("%d", a);
}   

变量 a 已被声明为没有任何数据类型,但该程序仍然成功编译并提供所需的输出。
输出 ::

8  

ideone上看到。
但是,当我在 main 中声明相同的变量时,它会给出编译错误。

main()
{
     a=8;
    printf("%d", a);
}  

输出 ::

prog.c:2: warning: return type defaults to ‘int’
prog.c: In function ‘main’:
prog.c:3: error: ‘a’ undeclared (first use in this function)
prog.c:3: error: (Each undeclared identifier is reported only once
prog.c:3: error: for each function it appears in.)
prog.c:4: warning: implicit declaration of function ‘printf’
prog.c:4: warning: incompatible implicit declaration of built-in function ‘printf’  

这里

第一个程序如何工作,但第二个?

4

6 回答 6

28

您在这里看到的是“隐式 Int 规则”在起作用。简单地说,规则说:

“没有显式类型名称声明的变量被假定为类型int。”

请注意,此规则在 c99 标准[Ref 1]中被撤销。但是,根据您的编译器及其设置,第一个示例可能会在编译时出现警告,或者无法编译(使用严格的编译设置

如果您使用遵循 c99 标准的严格设置编译您的第一个示例,编译器会告诉您根本原因。

在这里检查。

cc1:警告被视为错误
prog.c:1:错误:数据定义没有类型或存储类
prog.c:1:错误:在 'a'<br> prog.c 的声明中,类型默认为 'int': 3:错误:返回类型默认为'int'<br> prog.c:在函数'main'中:
prog.c:4:错误:函数'printf'的隐式声明<br> prog.c:4:错误:内置函数'printf'的不兼容隐式声明

编辑:

为什么第一个示例有效,而第二个示例无效?

请注意规则中对“声明的变量”一词的强调。

在第一个示例中,由于语句位于全局范围内,因此将其视为隐式声明,并且将隐式 Int 规则应用于它。

在第二个示例中,该语句充当Assignment 而不是 Declaration。由于没有声明,因此此处不适用隐式 int 规则。在没有任何类型的情况下,编译器无法确定是什么类型a并因此报告错误。


[参考 1]

C99 标准:前言
第 5 段:

本版本取代了以前的版本,经、和ISO/IEC 9899:1990修改和更正。 与上一版相比的主要变化包括: ..... ..... — 删除隐式 int ..... ..... ISO/IEC 9899/COR1:1994ISO/IEC 9899/COR2:1995ISO/IEC 9899/AMD1:1995





于 2012-06-16T14:38:25.900 回答
7

a=8;函数外部看起来像一个声明语句,其中a是声明说明符,= 8是初始化器。C 曾经允许在声明说明符中省略类型,int在这种情况下默认为。(自 C99 起,不再允许这样做。)

但是,在函数中,a=8;看起来像是一个表达式语句(一个赋值表达式)并且符号a没有被解析。(请注意,您没有函数之外的表达式语句。)

例如,如果您尝试这样做,static a = 8;那么它将再次看起来像一个声明,并且应该编译,因为类型将默认为 int。

无论如何,不​​要依赖它 :-) 清楚地写出你的类型。

于 2012-06-16T14:46:22.580 回答
3

这是因为在 C 中,任何变量/函数都是隐式的int

这与您可以使用register代替register int,或unsigned代替unsigned intauto代替auto int,和static代替的原因相同static int。我个人总是用 明确限定我的变量int,但是否这样做是你的选择。

于 2012-06-16T14:41:19.770 回答
0

即使您没有编写数据类型,您的变量也确实具有数据类型 (int)。

利用该功能是不好的做法。

显然,您的编译器不允许在函数内部发生这种情况。这是有道理的,因为如果它确实允许 "a=8;" 在函数中很难捕捉到某些错别字。

于 2012-06-16T14:41:57.440 回答
0

在 C++11 中,有一个auto 关键字。不幸的是,C 和 C++ 是强类型语言,它们需要为每个声明的变量定义一个严格的类型。一些编译器假定 int 为默认值,但这是他们的好主意,不应该使用它,因为它被认为是一种错误的编程习惯。

于 2012-06-16T14:45:04.217 回答
0

甚至函数参数也可以写成隐式 int。例子:

fun(n){printf("%d",n);}

上面的代码可以正常工作,但是一旦参数中包含固定的数据类型,例如

fun(n,char c){ printf("%d",n);}

它显示错误:错误:在'char'之前预期')'|

于 2016-03-15T15:01:03.180 回答