在 C 中声明两个同名的全局变量

Posted

技术标签:

【中文标题】在 C 中声明两个同名的全局变量【英文标题】:Declaring two global variables of same name in C 【发布时间】:2013-06-27 15:03:26 【问题描述】:

我在 C 中声明了两个同名的全局变量。 它应该给出错误,因为我们不能在同一个存储类中声明同名变量。

我在 C++ 中检查过——它给出了编译时错误,但在 C 中没有。为什么?

以下是代码:

int a;
int a = 25;
int main()


   return 0;

查看:Code Written at Ideone

我想大概是这个原因

Declaration and Definition in C

但在 C++ 中情况并非如此。我认为在 C++ 中,无论是在全局范围内还是在自动范围内声明变量,声明和定义都是同时发生的。

谁能再解释一下。

现在当我定义变量两次给它值两次它给我错误 (而不是一个声明和一个定义)。

代码在:Two definitions now

int a;
int a;
int a;
int a = 25;

int main()

return 0;

【问题讨论】:

@H2CO3 .. 感谢您的建议,但我只是想了解其中发生了什么。但是在某些情况下,您甚至无法避免使用全局变量。 【参考方案1】:

在 C 中,多个全局变量被“合并”为一个。所以你确实只有一个全局变量,多次声明。这可以追溯到 C 中不需要(或者可能不存在 - 不太确定)extern 的时候。

换句话说,由于历史原因,这在 C 中是有效的,因此我们仍然可以编译在 C 有 ANSI 标准之前编写的代码。

虽然,为了允许在 C++ 中使用代码,我建议避免使用它。

【讨论】:

我无法得到语句“多个全局变量被“合并”成一个。我现在也定义了第一个,现在它给出了编译时错误。 换句话说,所有同名的全局变量都将被转换为一个变量——所以你的int a;int a = 25;将指向同一个int大小的内存块. 在 C 中正式称为 暂定定义。您可以在单个翻译单元中尝试任意多次定义一个对象,它们将被“合并”并生成类型是所有暂定定义的组合。在你的情况下,它只是int @KingsIndian 但是当我试探性地 define 在全局范围内具有相同名称的两个变量时,它给了我错误 :: 我假设 `int a; //在全局范围内声明 int a = 12 ; //在全局范围内定义.. ` C 不会将多个全局变量“合并”为一个。声明或暂定定义(未解析为定义)不定义全局变量。问题中的代码仅包含一个全局变量的定义,因此没有要合并的内容。在这种情况下,暂定定义仍然只是一个声明,而不是一个定义。例如,int a = 25; int a = 25; 会产生错误,而不是合并两个 a 对象。【参考方案2】:

Dennis Ritchie 和 Brain Kernighan 的经典著作《The C Programming Language》是这样说的:

    一个对象的外部声明是一个定义,如果它有一个初始化器。

    没有初始值设定项且不包含extern 说明符的外部对象声明是暂定定义

    如果对象的定义出现在翻译单元中,则任何暂定定义都仅被视为冗余声明。

    如果翻译单元中没有对象的定义,则其所有暂定定义将成为具有初始化程序0的单个定义。

例如:


extern int a =123; // this declaration is a definition as a is initialized to 123

int a; //this is a tentative definition

int a;
int a;
int a;
/*all the above the three tentative declarations are redundant*/

int a;
int a;
int a;

在代码中如果没有,在哪里做一些事情就像a=100,我们认为a对应于这个全局范围变量,而不是任何其他具有相同名称和类型的局部变量,然后最终,全局变量a应初始化为0


【讨论】:

以上是关于在 C 中声明两个同名的全局变量的主要内容,如果未能解决你的问题,请参考以下文章

强弱符号关系

C语言面试考点之二

C语言面试考点之二

C到C++的升级

如何在 C 中引用与全局变量同名的局部变量? [复制]

深入理解变量声明提升和函数声明提升