2014-01-17 41 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