2014-01-17 44 views
4

运行此代码后:在main之后声明的变量是否有文件范围?

#include <stdio.h> 
int x; 
int main(void) 
{ 
    printf("%d\n",x); 
    return 0; 
} 
int x=5; 

我的预期输出应该是0。由于顺序控制结构的程序int x;应先执行,然后0打印,最后int x=5;应该执行。但它是给出输出5

程序如何访问5xprintf

+2

虽然我得到这个'错误C2086:'int x':redefinition'。需要首先将'int x'更改为'extern int x'来处理它。 – herohuyongtao

+0

但是用'-Wall -Wextra -pedantic -g3 -std = c99'在GCC 4.8.1上编译。 – haccks

回答

7

第一个作为前向声明,后者作为实际定义。

+0

是不是语句顺序执行,它应该打印'0'(因为全局变量设置为“0”)?编辑了这个问题。 – haccks

+1

@haccks全局或静态变量的所有初始化在调用'main'之前完成。事实上,在像你这样的情况下,编译器甚至可以在编译期间设置该值,所以当可执行文件加载到内存时它已经设置好了。 –

+0

@haccks顺便说一句,这是对象和可执行文件中的“数据”段用于存储初始化数据(如变量)的内容。未初始化的数据(就像你没有在你的情况下初始化变量'x'一样)将会在“bss”段中结束,在调用'main'之前将其清零。 –

3

在main函数运行之前,在函数之外声明的变量默认值被设置。所以你看到的是正确的行为。其他源文件中声明的变量也一样。

3

全局变量在main()运行前被初始化。这意味着一个函数完全可以访问该文件后面出现的内容,只要它是可见的(即前向声明)即可。

这样说,你不应该真的有一个文件中的同一个变量的多个声明。它可能会导致混淆(主要是程序员)关于它实际初始化的内容和位置。

编辑:澄清,全局范围内的函数/变量不会像函数内部的语句序列一样执行。函数的声明/定义的位置与其他任何代码的调用时间无关。它只确定周围范围的哪些部分可见。在你的情况下,这意味着main()不会在你的两个int行之间被调用。它在完成所有其他初始化时被运行时调用。

+0

编辑问题更加清晰。 – haccks

+0

@haccks:我编辑了我的答案,以更好地解决问题。 –

+0

很好。但不知道'main'在两个'int'行之间没有调用! – haccks