[英]c-language initializing global variable inside main(), outside main()
[英]Scope of a variable outside main in C
考慮一下代碼:
#include <stdio.h>
int x;
int main (void)
{ }
main
的x
值為0
。 但那是為什么呢? 我沒有聲明它是static
。 或者它是否為static
因為它在函數之外?
如果上述情況屬實,那么它與extern
不同之處是什么呢?
它既不是static
也不是extern
。 它是一個變量,對於它所在的編譯單元是可見的,並且還可以從聲明x
為extern
變量的所有編譯單元中看到它。
為什么我說它既不是static
也不是extern
?
如果它是extern
,則必須有一個帶有x
聲明的不同編譯單元。 顯然這是你唯一的編譯單元。
如果它是static
則不允許對此編譯單元中定義的x
變量進行extern
引用。 我們知道我們可以輕松地向這里聲明的x
聲明一個extern
變量。
為什么0
分配給x
? 因為,在C中 ,所有全局變量都初始化為0
。 它在C99標准的6.7.8(10)中說明了這一點。
當我們說“靜態存儲持續時間”的變量被隱式初始化為0時,我們並不意味着您需要將“static”關鍵字放在它們前面。
“靜態存儲持續時間”僅僅是對象的特定存儲持續時間,表示其存儲持續整個程序的持續時間。 這種存儲持續時間用於在文件范圍(如您的變量)和本地靜態變量中聲明的變量。
6.2.2 / 5:“如果對象的標識符聲明具有文件范圍而沒有存儲類特定,則其鏈接是外部的。”
但這是聯系 ,而不是范圍 。 您的x
聲明將具有文件范圍。 static
和extern
不影響范圍。 它被初始化為0,因為x
具有靜態存儲持續時間(見6.2.4 / 3和/ 5)。
一般來說,您還必須了解6.2.2./4:
對於在存儲類規范外部聲明的標識符,在該范圍內可以看到該標識符的先前聲明,如果先前聲明指定內部或外部鏈接,則后面聲明中標識符的鏈接與鏈接相同在先前的聲明中具體說明。
因此,使用extern
聲明與沒有存儲類說明符的聲明並不完全相同。 在您的示例中,沒有事先聲明。
這不是一成不變的。 它是全球性的。 您可以在不同的編譯單元中將其聲明為extern
,但在此單元中將為其分配空間。 順便說一下,如果沒有給出初始化器,Globals總是被初始化為0。
您的編譯器將x的值初始化為0。
它是一個全局變量,從main()
可見
x是一個全局變量,它在程序啟動時為它分配空間並初始化為0(通常,你應該有一個顯式的初始化程序)。
'static'關鍵字有兩種不同的含義。
1)
static int x; int main() { }
這將x的范圍限制為單個文件。 雖然它仍然是一個全局變量,但鏈接器將無法從其他文件連接對x的引用。
2)
int main() { static int x; }
這有效地將x轉換為全局變量。 雖然范圍仍在main函數內,但是全局為它分配了空間,並且在調用main()之間保留了它的值。
這感覺就像一個家庭作業問題,但無論如何我會咬人。
要使用您在其他文件的類或函數中定義的x,您可以使用
extern int x;
在你使用x變量之上(比如在標題中),你可以像在main()中一樣使用x。 extern告訴編譯器您正在使用在別處定義/實例化的變量。
如果你希望它在main運行之前存在,那么你使用在main()運行之前處理的static。 換句話說,它在開始任何處理之前用變量加載內存空間(在main中)。
至於為什么它在啟動時為0,那可能只是你的編譯器給它一個基值。 並非所有的編譯器都這樣做,除非我弄錯了,很多人只會給你分配給x的內存空間中的任何內容。 換句話說,它們會事先為您提供內存中包含的任何數據(或部分數據)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.