C/C++中的變量
在定義變量時,C與C++ 有明顯的區別。這兩種語言都要求變量使用前必須定義,但是C(和許多其他傳統過程語言)強制在作用域的開始處就定義所有的變量,以便在編譯器創建一個塊時,能夠給所有的這些變量分配空間。(這個說法已經是老皇歷了,現在的編譯器即使是不在開始處定義變量也是可以做優化的,所以寫C程序時完全可以像C++那樣在任何方便的地方定義變量)。在C/C++中變量與函數在內存中是分開存放的。
全局變量
全局變量時在所有函數體的外部定義的,程序的所有部分(甚至其他文件中的代碼)都可以使用。全局變量不受作用域的影響,總是可用的(即全局變量的生命期一直到程序的結束)。如果在一個文件中使用extern關鍵字來聲明另一個文件中存在的全局變量,那么這個文件可以使用這個數據。全局變量會被分配在內存的堆上。
局部變量
局部變量出現在一個作用域內,是局限於一個函數的。局部變量經常被稱為自動變量(automatic variable),因為是進入作用域時自動生成,離開作用域時候自動消失。關鍵字auto可以顯示的說明這個問題,但是局部變量默認為auto,所以沒有必要聲明為auto。局部變量的內存中會被放在棧上。
寄存器變量:是一種局部變量。關鍵字register告訴編譯器“盡可能快地訪問這個變量”。加快訪問速度取決於實現,但是,正如名字所暗示的那樣子,這經常是通過在寄存器中放置變量來做到的。這並不能保證將變量放置在寄存器中,甚至也不能保證提高訪問速度,這只是對編輯器的一個暗示(所以說register關鍵字的意義在哪里啊喂!這么多年來我一直以為是直接放在寄存器里的啊)使用register的限制:不可能得到或計算register變量的地址,register變量只能在一個塊中聲明(不能有全局的或靜態的register變量);但是可以作為形參;總之,盡量不要使用register變量。
靜態變量
關鍵字static有一些特殊的意義。
靜態局部變量:當在一個塊內定義了靜態局部變量之后,局部變量不會隨着作用域的結束而自動的被銷毀,會一直存在,如果下一次再調用這個塊,那么靜態局部變量的值回保留上次執行之后的結果。靜態局部變量雖然不會隨着作用域的結束而銷毀,但是在作用域之外是不可見的(這也符合“局部變量”這個名號)。之所以不會被銷毀是因為靜態局部變量分配在內存的靜態存儲區上。
靜態全局變量,靜態函數:static關鍵字修飾全局變量與修飾函數時候功能都一樣,意思是“在文件的外部不可以使用這個名字”,即函數或變量時局部於文件的,具有文件作用域(file scope)。如果其他文件使用extern關鍵字來引用一個static類型的變量或函數會導致編譯器報錯。
靜態類成員函數、靜態類數據成員:表示這個數據成員或者這個成員函數是為整個類所共享的,訪問時候不需要用對象名,直接用類名即可訪問。
外部變量
extern關鍵字告訴編譯器存在一個函數或者變量,即使不在當前的文件中也會在其他文件中。
volatile變量
限定詞const告訴編譯器“這個不會改變的”,這就允許編譯器執行額外的優化;而限定詞volatile則告訴編譯器“不知道何時回改變”,防止編譯器依據變量的穩定性做任何優化。
C/C++中的常量
舊版本的C中,定義常量必須使用預處理器,如
# define PI 3.14
這種方式僅僅是做了一個替換。此時不能對PI 進行類型檢查,不能得到PI的地址(所以不能向PI傳遞一個指針或引用),PI不能是用戶定義的類型。PI的意義是從定義它的地方直到文件結束;因為預處理器並不識別作用域。
后來在C/C++中引入了關鍵字const,用來定義命名常量,命名常量如同變量一樣,只不過其值不能改變;const告訴編譯器這個名字表示常量。無論內部還是用戶定義的數據類型都可以定義為const;也可以獲得命名常量的地址;也有作用域;
Const 由C++ 采用,並且加入到標准C中,但是在C中使用const和C++中使用const是完全不一樣的。在C中,編譯器對待const如同變量一樣,只不過不會改變其值;且會為其分配存儲空間,所以在兩個不同文件中(或在頭文件中)定義多個同名const時候,連接器會生成發生沖突的消息。另外,在C++中,一個const必須有初始值,而C則不是這樣(因為C把const當做變量對待?)。總之,在C++中使用const會更好。