2017-02-27 41 views
0

當我們聲明一個全局變量時,它被初始化爲其默認值。但是,當我們初始化使用extern關鍵字的變量,爲什麼變量保持與它使用extern關鍵字初始化值?當變量已被聲明爲全局變量時,使用extern關鍵字初始化時,變量中存儲的值是什麼?

例如,在下面爲什麼是輸出9,而不是編譯時錯誤的代碼?由於沒有來自任何其他源文件的變量x的外部鏈接,所以x有兩個副本,我們正在初始化變量兩次,所以這應該是錯誤的。請澄清這一點;我對這段代碼的流程感到困惑。

#include <stdio.h> 

extern int x=9; 
int x; 

int main() 
{ 
    printf("%d",x); 
    return 0; 
} 
+0

只要聲明是相同的(信),那麼它的好有多個聲明。它是*定義*你不能有兩個(或更多)。 –

+0

爲什麼不使用'extern int main(void){printf(「%d \ n」,x);返回0; }'?它也可以。 –

回答

1

extern int x = 9;裝置一樣int x = 9;extern關鍵字對已經具有外部鏈接和初始化程序的定義沒有影響。

int x;被稱爲暫定義

這是通過C11 6.9.2充分描述/ 2:

爲具有文件作用域沒有初始化的對象的標識符的聲明,和 沒有存儲類說明或與所述存儲-class說明符static,構成 暫定義。如果翻譯單元包含一個 標識符的一個或多個試探性的定義,和翻譯單元包含該標識符的外部定義,然後 行爲是完全一樣,如果翻譯單元包含 標識符的文件範圍內聲明,與爲0。

本翻譯單元確實包含x外部定義複合類型作爲翻譯單元的端部,具有一個初始化 相等,所以暫定定義沒有任何效果。外部定義是在暫定義之前還是之後並不重要。

「外部定義」是指在文件範圍內非暫定定義 - 不要與extern或「外部鏈接」相混淆,但在你的例子x確實發生有外部鏈接。

所以,你的代碼是完全一樣:

int x = 9; 
+0

我只是有一個困惑,你說「extern」關鍵字對已經具有外部鏈接和初始化程序的定義沒有影響。 「一般來說,聲明是如何翻譯的,首先編譯器是否認爲該變量是全局的,因此它具有外部鏈接,因此x被初始化爲值9,並且在該關鍵字之後考慮了extern。 – stackuser

+0

另外我無法得到這個段落:「如果翻譯單元包含一個或多個標識符的暫定義,並且翻譯單元不包含該標識符的外部定義,那麼行爲就好像翻譯單元包含一個文件該標識符的範圍聲明,以翻譯單元末尾的複合類型,初始值等於0.「,這裏」複合類型「的含義是什麼? – stackuser

+0

@stackuser「複合類型」是指將相同標識符的不同臨時定義的類型組合在一起的結果。在'int x; int x = 9;'例如,複合類型是'int'(這是一個微不足道的情況) –

相關問題