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
答案 0 :(得分:5)
您已在2个翻译单元中使用外部链接定义变量x
。因此,程序的行为未定义。 C11 6.9p5:
- 外部定义是外部声明,它也是函数(内联定义除外)或对象的定义。如果在表达式中使用通过外部链接声明的标识符(除了作为sizeof或_Alignof运算符的操作数的一部分,其结果是整数常量),整个程序中的某处应该只是一个外部定义< / strong>用于标识符;否则,不得超过一个。
醇>
POSIX 系统(Unix,Mac OSX,Linux)上存在一个公共扩展名(C11 J.5.11),导致此类外部变量定义合并< / strong>合而为一:
J.5.11多个外部定义
- 对象的标识符可能有多个外部定义,有或没有明确使用关键字extern;如果定义不一致,或者初始化了多个,则行为未定义(6.9.2)。
醇>
然而,其他平台的C编译器不一定遵循此规则。
如果您希望两个文件都有名为x
的单独变量,请在每个声明前加上关键字static
,即static int x;
。如果您希望它们可以移植一个,请仅在一个文件中使用int x;
,在所有其他文件中使用extern int x;
;此extern
声明可以放入头文件中。
答案 1 :(得分:1)
因为x
是在任何函数范围之外定义的,所以它具有全局范围。因此,f()
运行以分配其值实际上会更改其值,如图所示。
当main()
运行时,它所做的第一件事是调用f()
来改变值(有些人可能认为是副作用)。这就是为什么,从未使用15213的初始化值。