變數的儲存型別是指儲存變數值的記憶體型別。變數的儲存型別決定變數何時建立、何時銷毀以及它的值將保持多久。
有三個地方可以用於存在變數:普通記憶體、執行時堆疊、硬體暫存器。
變數的預設(預設)儲存型別取決於它的宣告位置。
凡是在任何**塊之外宣告的變數問題儲存於靜態記憶體中,也就是不屬於堆疊的記憶體,這類變數稱為靜態變數。對於這類變數,你無法為它們指定其他儲存型別。靜態變數在程式執行之前建立,在程式的整個執行期間始終存在。它始終保持原先的值,除非給它賦乙個不同的值或者程式結束。
在**塊內部宣告的變數的預設儲存型別是自動的,也就是說它儲存於堆疊中,稱為自動變數。有乙個關鍵字auto就是用於修飾這種儲存型別的,但它極少使用,因為**塊中的變數在預設情況下就是自動變數。在程式執行到宣告自動變數的**塊時,自動變數才被建立,當程式的執行流離開該**塊時,這些自動變數便自行銷毀。
對於在**塊內部宣告的變數,如果給它加上關鍵字static,可以使它的儲存型別從自動變為靜態。具有靜態儲存型別的變數在整個程式執行過程中一直存在,而不僅僅在宣告它的**塊的執行時存在。注意,修改變數的儲存型別並不表示修改該變數的作用域,它仍然只能在該**塊內部按名字訪問。
函式的形式引數不能宣告為靜態,因為實參問題在堆疊中傳遞給函式,用於支援遞迴。
最後,關鍵字register可以用於自動變數的宣告,提示它們應該儲存於機器的硬體暫存器而不是記憶體中,這類變數稱為暫存器變數。
通常暫存器變數比儲存於記憶體的變數訪問起來效率更高。但是,編譯器並不一定要理睬register關鍵字,如果有太多的變數被宣告為register,它只能選取前幾個實際儲存於暫存器中,其餘的就按普通自動變數處理。如果乙個編譯器自己具有一套暫存器優化方法,它也可能忽略register關鍵字,其依據是由編譯器決定哪些變數儲存於暫存器中比人腦的決定更為合理一些。
自動變數和靜態變數的初始化存在乙個重要的差別。
在靜態變數的初始化中,我們可以把可執行程式檔案想要初始化的值放在當程式執行時變數交付使用的位置。當可執行檔案載入到記憶體時,這個已經儲存了正確初始值的位置將賦值給那個變數。完成這個任務並不需要額外的時間,也不需要額外的指令,變數將會得到正確的值。如果不顯示地指定其初始值,靜態變數將初始化為0。
自動變數的初始化需要更多的開銷,因為當程式鏈結時還無法判斷自動變數的儲存位置。事實上,函式的區域性變數在函式的每次呼叫中可能佔據不同的位置。基於這個理由,自動變數沒有預設的初始值,而顯式的初始化將在**塊的起始處插入一條隱式的賦值語句。
這個技巧造成4種後果
int
func(int a)
變數型別
宣告的位置
是否存於堆疊
作用域如果宣告為static
全域性所有**塊之外
否從宣告處到檔案尾
不允許從其他原始檔訪問
區域性**塊起始處
是整個**塊
變數不儲存於堆疊中,它的值在程式整個執行期一起保持
形式引數
函式頭部
是整個函式
不允許
本文摘自:《c和指標》
《C和指標》 儲存型別
變數的儲存型別是指儲存變數值的記憶體型別。變數的儲存型別決定變數何時建立 何時銷毀以及它的值將保持多久。有三個地方可以用於存在變數 普通記憶體 執行時堆疊 硬體暫存器。變數的預設 預設 儲存型別取決於它的宣告位置。凡是在任何 塊之外宣告的變數問題儲存於靜態記憶體中,也就是不屬於堆疊的記憶體,這類變數...
C語言 變數的儲存型別 和 指標(2)
一 變數的儲存型別 1.register int a 1 定義乙個暫存器變數,a存放在暫存器中,暫存器變數不能取位址 2.extern int a 1 宣告乙個外部變數,宣告不用分配空間 定義變數要分配空間 3.static 1 在函式外部 static int a 1 static 修飾全域性變數...
C和指標 3 9作用域 儲存型別示例
1 int a 5 2 extern intb 3static intc 45 int d int e 6 18.1924 25 26 static inti 2730 屬於檔案作用域的宣告在預設情況下為external鏈結屬性,所以第1行的a的鏈結屬性為external。如果b的定義在其他地方,第...