變量的破碎類型是指存儲變量值的內存類型。變量的存儲類型決定變量什麼時候建立、什麼時候銷燬以及它的值將保持多久。函數
有三個地方能夠用於存在變量:普通內存、運行時堆棧、硬件寄存器。優化
變量的缺省存儲類型取決於它的聲明位置。凡是在任何代碼塊以外聲明的變量問題存儲於靜態內存中,也就是不屬於堆棧的內存,這類變量稱爲靜態變量。對於這類變量,你沒法爲它們指定其餘存儲類型。靜態變量在程序運行以前建立,在程序的整個執行期間始終存在。它始終保持原先的值,除非給它賦一個不一樣的值或者程序結束。遞歸
在代碼塊內部聲明的變量的缺省存儲類型是自動的,也就是說它存儲於堆棧中,稱爲自動變量。有一個關鍵字auto就是用於修飾這種存儲類型的,但它極少使用,由於代碼塊中的變量在缺省狀況下就是自動變量。在程序執行到聲明自動變量的代碼塊時,自動變量才被建立,當程序的執行流離開該代碼塊時,這些自動變量便自行銷燬。內存
對於在代碼塊內部聲明的變量,若是給它加上關鍵字static,可使它的存儲類型從自動變爲靜態。具備靜態存儲類型的變量在整個程序執行過程當中一直存在,而不單單在聲明它的代碼塊的執行時存在。注意,修改變量的存儲類型並不表示修改該變量的做用域,它仍然只能在該代碼塊內部按名字訪問。作用域
函數的形式參數不能聲明爲靜態,由於實參問題在堆棧中傳遞給函數,用於支持遞歸。編譯器
最後,關鍵字register能夠用於自動變量的聲明,提示它們應該存儲於機器的硬件寄存器而不是內存中,這類變量稱爲寄存器變量。一般寄存器變量比存儲於內存的變量訪問起來效率更高。可是,編譯器並不必定要理睬register關鍵字,若是有太多的變量被聲明爲register,它只能選取前幾個實際存儲於寄存器中,其他的就按普通自動變量處理。若是一個編譯器本身具備一套寄存器優化方法,字也可能忽略register關鍵字,其依據是由編譯器決定哪些變量存儲於寄存器中比人腦的決定更爲合理一些。編譯
自動變量和靜態變量的初始化存在一個重要的差異。在靜態變量的初始化中,咱們能夠把可執行程序文件想要初始化的值放在當程序執行時變量交付使用的位置。當可執行文件載入到內存時,這個已經保存了正確初始值的位置將賦值給那個變量。完成這個任務並不須要額外的時間,也不須要額外的指令,變量將會獲得正確的值。若是不顯示地指定其初始值,靜態變量將初始化爲0.效率
自動變量的初始化須要更多的開銷,由於當程序連接時還沒法判斷自動變量的存儲位置。事實上,函數的局部變量在函數的每次調用中可能佔據不一樣的位置。基於這個理由,自動變量沒有缺省的初始值,而顯式的初始化將在代碼塊的起始處插入一條隱式的賦值語句。變量
這個技藝形成4種後果。硬件
1)自動變量的初始化較之賦值語句效率並沒有提升。除了聲明爲const的變量以外,在聲明變量的同時進行初始化和先聲明後賦值只有風格之差,並沒有效率之別。
2)這條隱式的賦值語句使自動變量在程序執行到它們所聲明的函數(或代碼塊)時,每次都將從新初始化。這個行爲與靜態變量大不相同,後者只是在程序開始執行前初始化一次。
3)因爲初始化在運行時執行,你能夠用任何表達式做爲初始化值,例如:
int func(int a)
{
int b = a + 3;
}
4)除非你對自動變量進行顯式的初始化,不然當自動變量建立時,它們的值老是垃圾。