鏈接屬性
標(biāo)識符的鏈接屬性決定如何處理在不同文件中出現(xiàn)的標(biāo)識符
鏈接屬性一共有三種:
- external 外部鏈接屬性 -- 屬于external的標(biāo)識符不論聲明多少次,位于幾個源文件都表示同一個實(shí)體
- internal 內(nèi)部鏈接屬性 -- 屬于internal的標(biāo)識符在同一個源文件內(nèi)的所有聲明中都指向同一個實(shí)體,但位于不同源文件的多個生命則分屬不同的實(shí)體
- none 無鏈接屬性 -- 該標(biāo)識符的多個聲明被當(dāng)做獨(dú)立不同的實(shí)體
只要變量并非聲明于代碼塊或函數(shù)定義內(nèi)部,這個變量的鏈接屬性默認(rèn)為external
關(guān)鍵字static和extern可以修改鏈接屬性。如果聲明本身具有external鏈接屬性,在前面加上static可以使這個聲明的鏈接屬性變?yōu)閕nternal, 這樣可以防止變量被其他源文件調(diào)用
static關(guān)鍵字支隊默認(rèn)鏈接屬性為external的聲明才有改變鏈接屬性的效果(比如,對某一個代碼塊內(nèi)部聲明的變量加上static并不會改變該變量的鏈接屬性,改變的只是這個變量的存儲類型,因?yàn)檫@個變量聲明在函數(shù)內(nèi)部,其默認(rèn)鏈接屬性不是external)extern關(guān)鍵字用于源文件中某個標(biāo)識符的第一次聲明時,它指定該標(biāo)識符具有external鏈接屬性,但是如果用于該標(biāo)識符的第二次或以后的聲明時,它不會更改第一次聲明所指定的鏈接屬性, 例子:
static int i; //internal鏈接屬性
int func() {
extern int i; //并沒有更改上面的i的鏈接屬性,這里聲明的i會隱藏上面聲明的i
}
存儲類型
變量的存儲類型由它的聲明位置所決定
- 任何在代碼塊之外聲明的變量總是存儲于靜態(tài)內(nèi)存中,即不屬于堆棧的內(nèi)存,這類變量被稱為靜態(tài)變量,靜態(tài)變量在程序運(yùn)行之前創(chuàng)建,在程序的整個執(zhí)行期間始終存在,它始終保持原先的值,除非給它賦值新的值或程序結(jié)束
靜態(tài)變量如果不顯示指定其初始值,靜態(tài)變量將初始化為0
- 在代碼塊內(nèi)部聲明的變量存儲于堆棧中,如果給一個位于代碼塊內(nèi)部的變量加上
static關(guān)鍵字,可以將這個變量改為靜態(tài)變量 - 關(guān)鍵字
register可以指示將代碼塊內(nèi)部的變量的存儲在機(jī)器的硬件寄存器而不是內(nèi)存中,這類變量成為寄存器變量,一般來說,寄存器變量比存儲在內(nèi)存的變量訪問效率要高,但這并不意味著可以將每個變量都聲明為register,如果有太多register變量,編譯器只會選取前幾個實(shí)際存儲于寄存器
static關(guān)鍵字總結(jié)
- static用于函數(shù)聲明或者位于代碼塊之外的變量聲明時, static用于修改鏈接屬性,從external改為internal
- static用于代碼塊內(nèi)部的變量時,sttaic用于修改變量的存儲類型,將變量修改為靜態(tài)變量,但不改變鏈接屬性