在C语言中,声明一个变量多次是有效的吗?

7

我有以下C代码,并期望它会抛出“变量重复声明”的错误,但实际上没有出错。

#include <stdio.h>

int i;        
int i;    

int main()
{
    printf("%d",i);
    return 0;
}

现在的输出结果是0,但为什么呢?

还有一件事,下面的代码会报错,预期是什么?

#include <stdio.h>


int main()
{
    int i;        
    int i;    

    printf("%d",i);
    return 0;
}

O/p 出错,显示 i 的重新声明


我正在使用在线编译器来运行这段代码。 - Amit Singh Tomar
1
编辑后:在第二个片段中,i的定义出现在函数内部(它们不出现在文件作用域),并且不是试探性定义。 - pmg
为什么在块内部出现时不是尝试性定义,因为它只是声明而不是定义? - Amit Singh Tomar
@Amit:在块作用域中声明对象可以使用 external 关键字: external int i;,但最好还是在文件作用域中指定这样的声明。 - pmg
1个回答

18
i 的第一个定义是一个尝试性的定义(第二个也是尝试性的定义)。虽然它们是“事实上”的定义,但它们也作为声明,这一点毫无疑问。
引用自标准文档
6.9.2/2
具有文件作用域且没有初始化程序并且没有存储类别说明符或具有静态存储类别说明符的对象的标识符的声明构成了一种试探性定义。如果一个翻译单元包含一个或多个对于某个标识符的试探性定义,并且该翻译单元不包含该标识符的外部定义,则行为就像该翻译单元包含该标识符的文件作用域声明,其复合类型为翻译单元结束时的复合类型,初始值为0。

谢谢@pmg的回复,但你能不能用简单的方式解释一下呢?我的意思是,我可以有任意多的声明吗? - Amit Singh Tomar
没有初始化器。没有覆盖声明说它在别处。没有冲突。标准规定:“在这种情况下,在此处声明并初始化为零”。 - Donal Fellows
1
@Amit:基本上,没有初始化器(int i;)的定义是试探性定义。C允许一个标识符有多个试探性定义。有初始化器的定义(int i = 0;)不是试探性定义,不能被多次使用。 - pmg
1
非试探性定义称为外部定义 - 您可以有许多相同标识符的试探性定义,但只能有一个外部定义。 - M.M

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接