天天看點

C 變量的存儲類型

積木網絡|C語言中的變量具有兩種屬性:一個是資料類型,一個是存儲類型。根據變量所存放的資料的性質不同而分為各種資料類型;根據變量的存儲方式不同而分為各種存儲類型。變量的資料類型決定了該變量所占記憶體單元的大小及形式;變量的存儲類型規定了該變量所在記憶體中的存儲區域,因而規定了該變量作用時間的長短,這種性質又稱為“存在性”。變量在程式中聲明的位置決定了該變量的作用域,即在什麼範圍内可以引用該變量,“可引用”又稱為“可見”,是以這種性質又稱為“可見性”。

計算機的記憶體和CPU中的寄存器都可以存放資料, 變量究竟存放在何處則由存儲類型來決定。變量的存儲類型用來說明變量的作用域、生存期、可見性和存儲方式。

1)什麼是作用域?

作用域是該變量在其中有定義的程式部分,通俗的說,是該變量起作用的程式中的某個區域。

2)什麼是變量的生存期?

變量的生存期是指它從産生到消亡的存在時間,即變量從定義開始到所占有的存儲空間被系統收回為止的這段時間。

3)什麼是變量的可見性?

在某個程式區域,若可以對某個變量進行通路操作,則稱為該變量在該區域為可見的,否則為不可見的。

4)什麼是全局變量和局部變量?

在一個函數内部或複合語句内部定義的變量稱為内部變量,又稱為“局部變量”。在函數外定義的變量稱為外部變量,又稱為全局變量。

5)什麼是動态存儲變量和靜态存儲變量?

在程式運作期間,所有的變量均需占用記憶體,有的是臨時占用記憶體,有的是程式運作過程中從頭到尾占用記憶體。在程式運作期間,根據需要進行臨時性動态配置設定存儲空間的變量稱為動态存儲變量,永久性占用記憶體的變量稱為靜态存儲變量。

對于一個 正在運作的程式,可将其使用記憶體從上到下分為三個區域:

1)程式代碼區:程式的指令代碼存放在程式代碼區。

2)靜态存儲區:靜态存儲變量存放區包括全局變量。

3)動态存儲區:存放局部自動變量、函數的形參以及函數調用時的現場保護和傳回位址等。

變量的定義的一般形式為

<存儲類型><資料類型>變量名表;

存儲類型包括:

auto, 自動型

register,寄存器型

extern,外部參照型

static,靜态型

自動變量用auto聲明,在函數内或複合語句中定義自動變量時auto可以預設。自動變量隻在定義它的函數或複合語句内有效。 當在程式開頭聲明時,它做為一個全局變量,但對函數内部再次聲明同名的變量的值不影響。

寄存器型變量register在函數内或複合語句内定義,是以它也是局部變量,存儲在CPU的通用寄存器中,因為資料在寄存器中操作比在記憶體中快,是以通常把程式中使用頻率最高的少數幾個變量定義為register型。但并不是使用者定義的寄存器型變量都被放入CPU寄存器中,能否真正把它們放入CPU寄存器中是由編譯系統根據具體情況做具體處理的。

配置設定寄存器的條件是:

1)有空閑的寄存器;

2)變量所表示的資料的長度不超過寄存器的位長。

外部參照型變量extern(全局變量)

extern型變量一般用于在程式的多個編譯機關之間傳送資料,在這種情況下指定為extern型的變量是在其它編譯機關的源程式中定義的,它的存儲空間在靜态資料區,在程式執行過程中長期占用空間。若 要通路另一個檔案中定義的跨檔案作用域的全局變量,則發必須進行extern說明。如果在程式的開頭部分定義了extern變量,則是告訴編譯器,這個變量是外部參照變量,應該在本程式之外去尋找它的定義。也就是說,通過extern可以把全局變量擴充到另一個程式檔案中。如果全局變量不在程式的開頭部分定義,則這個全局變量的作用範圍隻限于從定義處到程式的結束。

靜态型變量static

靜态型變量既可以在函數或複合語句内聲明,也可以所有函數之外聲明。在函數或複合語句内部定義的靜态變量稱為局部靜态變量,在函數外部定義的靜态變量稱為全局靜态變量。 有時希望函數中的局部變量的值在函數調用結束後不消失而保留原值,即其占用的存儲單元不釋放,在下次調用該函數時,該變量已有值,其值就是上一次函數調用結束時的值,這時應該指定該局部變量為靜态局部變量,用關鍵字static進行聲明。

靜态型變量的生存期是全局的,其意思就是一但定義了靜态變量,那麼隻有到整個程式結束,這個變量的生存期才結束,它的記憶體才被釋放。唯一不同的是它的作用域分局部和全局。

注意事項:

1)靜态局部變量屬于靜态存儲類型,在靜态存儲區内配置設定存儲單元。在程式整個運作期間都不釋放。而自動變量(動态局部變量)屬于動态存儲類型,占動态存儲空間而不占靜态存儲空間,函數調用結束後即釋放。

2)對靜态局部變量隻賦初值一次,以後每次調用函數時不再重新賦初值而隻是保留上次函數調用結束時的值。而對自動變量賦初值,每調用一次函數就重新給一次初值,相當于執行一指派語句。

3)在定義局部變量時不賦初值,則 對靜态局部變量來說,編譯時自動指派初值0(對數值型變量)或空字元(對字元變量)。而對自動變量來說,如果不賦初值,則它的值是一個不确定的值。這是由于每次函數調用結束後存儲單元已釋放,下次調用時又重新另配置存儲單元,而所配置設定的單元中值是不确定的。

4)有時在程式設計中希望某些外部變量隻限于被本檔案引用,而不能被其他檔案引用,這時可以在定義外部變量時加一個static聲明。

小結:

1)類型說明。關鍵字auto,static,register用于定義變量的存儲類型說明,其中auto通常預設。而關鍵字extern則不然,它不是用于定義變量,而是用于說明某個變量,是已在本函數之外或其他源檔案中定義過的外部變量。extern說明有“延伸外部參照型變量作用域”的作用。

2)變量的作用域和生存用周期

auto,register,局部static型 是局部變量,auto,register,具有局部生存周期,而局部static變量具有的全局生存周期;全局static型,外部參照型是全局變量,具有全局生存周期。

由上面兩點可以看出,隻要是static型變量,不管它是全局的還是局部的,其生存期都是全局生存期,所占用的記憶體空間隻有到程式結束才釋放。

3)變量的初始化

對外部參照變量的初始化不能在進行extern說明時進行。對于全局變量和靜态變量來說編譯時自動指派初值0(對數值型變量)或空字元(對字元變量)。