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

时间:2017-09-01 19:15:26

标签: c global-variables

void f(void);
int x = 15213;  
int main()  
{
    f();  
    printf("x = %d\n", x); 
    return 0; 
}

/* bar3.c */ 
int x; 
void f()
{ 
    x = 15212;
}

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

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

2 个答案:

答案 0 :(得分:5)

您已在2个翻译单元中使用外部链接定义变量x。因此,程序的行为未定义C11 6.9p5

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

POSIX 系统(Unix,Mac OSX,Linux)上存在一个公共扩展名(C11 J.5.11),导致此类外部变量定义合并< / strong>合而为一:

  

J.5.11多个外部定义

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

然而,其他平台的C编译器不一定遵循此规则。

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

答案 1 :(得分:1)

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

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