C++的全域性變數,靜態全域性變數,常全域性變數定義與宣告
標頭檔案中變數如果沒有初始化就是宣告;初始化了就是定義。在C++語言中,變數有且只能有一次定義,但是可以宣告多次,使用變數前必須定義或宣告。
再說到這些變數的宣告與定義前,要知道這些變數的連結性:
外部全域性變數 外部連線性 可以被extern
靜態全域性變數(static) 內部連線性 不能被extern
常全域性變數(const) 內部連線性 在之前加上extern就變成了外部連線性,就可以被其他的檔案extern了
宣告:(可以放在標頭檔案)沒有開闢記憶體的定義,型別定義,比如類的定義,結構體的定義,它是定義一個數據型別而已;
定義:(不可放在標頭檔案)開闢了記憶體的定義,資料定義,比如類物件定義,變數定義
一般來說:
不分配記憶體的,放在標頭檔案
分配記憶體的放在cpp檔案,防止重複定義,當然也要看變數的連線性,內部連線性的可以放在標頭檔案定義。
變數、函式、類,在使用之前都必須宣告,包含標頭檔案,如果a.h包含了b.h,在a.h裡面就對b.h裡面的宣告重新聲明瞭,這也是不能在標頭檔案裡面定義變數與函式的原因(防止重複定義),當然內部連結性的變數和行內函數除外。
C++是不允許在標頭檔案裡定義一個外部全域性變數(宣告可以,比如在原始檔定義,在標頭檔案extern宣告,像int a;這樣不算宣告,是定義,全域性變數預設賦值0),因為當這個標頭檔案被多個別的檔案(.cpp或.h)包含的時候,會重複定義這個全域性變數,而外部
對於static,const全域性變數,則可以定義在標頭檔案裡,因為它們的連線性為內部,它們的地址只有在本檔案裡訪問,即使這個標頭檔案被其他的檔案(.cpp或.h)包含,雖然重複定義,
c++ primer裡講的const變數定義時預設為檔案的區域性變數(內部連線性),當頭檔案中定義了const變數後每個包含該標頭檔案的檔案都有了自己的const變數。這與單一定義規則不矛盾,static也是同樣,但是const的連線性可變,在const變數前面加上extern後,就變成全域性變數,外部連線性,這時候要注意包含的問題。 而在.cpp檔案裡定義的const或者static變數,是不可以被別的檔案訪問的。(注意.h .cpp等之間的包含關係)--------------------------------extern用於互不包含的檔案裡,或者被包含的檔案。
包含意味著重新定義,但是對於互不包含的檔案不可以定義同名的外部全域性變數,外部全域性變數屬於外部連線性,這樣就導致了重定義!當然加上static或者const就可以,這裡有個全域性儲存區的區分------http://blog.csdn.net/u010177010/article/details/50737429,內部連結的變數地址所在的儲存區跟外部連結所在的儲存區是不同的,但是都屬於全域性儲存區!
對於static,const全域性變數,如果在兩個互不包含的檔案裡定義了相同的變數,第三個檔案包含了這兩個檔案,就會出錯,因為包含意味著重定義,同個記憶體塊不可能有兩個相同名字的記憶體。
總之,編譯是否出錯,看的是 變數的連線性以及是否重定義!