使用全局变量解释 C 程序的输出


void f(void);
int x = 15213;  
int main()  
{
f();  
printf("x = %dn", x); 
return 0; 
}
/* bar3.c */ 
int x; 
void f()
{ 
x = 15212;
}

在上面的代码中,我得到的输出是 15212。我不明白怎么回事?

首先,主函数调用 f() 在另一个 c 文件中定义。在 f() 中,x 的值从 15213 更改为 15212。然后我们正在打印 x。但是对 x 所做的更改应该只保留在 f 中,对吗?X 的范围应仅限于 f() 。即便如此,它也在打印 15212

您已在 2 个翻译单元中定义了具有外部链接的变量x。因此,程序的行为是不确定的。C11 6.9p5:

    外部定义
  1. 是一个外部声明,也是函数(内联定义除外)或对象的定义。如果在表达式中使用了用外部链接声明的标识符(而不是作为结果为整数常量的 sizeof 或 _Alignof 运算符的操作数的一部分),则在整个程序中的某个地方,标识符应只有一个外部定义;否则,不得超过一个。

有一个通用的扩展(C11 J.5.11),它存在于POSIX系统(Unix,Mac OSX,Linux)上,导致这些外部变量定义合并为一个:

J.5.11 多个外部定义

  1. 对象的标识符可能有多个外部定义,无论是否显式使用关键字 extern;如果定义不一致,或者初始化了多个定义,则行为是未定义的 (6.9.2)。

但是,其他平台的 C 编译器不一定需要遵循此规则。


如果您希望两个文件都有名为x的单独变量,请在每个声明前面加上关键字static,即static int x;.如果您希望它们可移植为一个,请仅在一个文件中使用int x;,在所有其他文件中extern int x;;此externAL 声明可以放入头文件中。

由于x是在任何函数的作用域之外定义的,因此它具有全局作用域。 因此,运行f()来分配其值实际上会更改其值,如图所示。

main()运行时,它做的第一件事是调用f()来更改值(有些人可能会认为这是一种副作用)。 这就是为什么从不使用初始化值 15213 的原因。

相关内容

  • 没有找到相关文章

最新更新