C 變數儲存類別和記憶體四區

2021-10-05 01:51:50 字數 4121 閱讀 8779

變數儲存類別

變數宣告/定義的一般形式:

儲存類別   資料型別   變數名

儲存類別指的是資料在記憶體中儲存的方法。儲存方法分為靜態儲存動態儲存兩大類。標準c語言為變數、常量和函式定義了4種儲存型別:extern、auto、static、register。根據變數的儲存類別,可以知道變數的作用域儲存期。這4種儲存型別可分為兩種生存期限:永久的(在整個程式執行期都存在)和臨時的(暫時儲存在堆疊和暫存器中)。extern和static用來標識永久生存期限的「變數和函式」,而anto和register用來標識臨時生存期限的"變數"。只有變數才有臨時生存期限。乙個變數和函式只能具有乙個儲存型別,也只能有一種生存期限。

記憶體中供使用者使用的空間有三部分:

變數的宣告分為」定義性宣告「(需建立儲存空間,如:int a;)和」引用性宣告「(不需建立儲存空間,如extern a;)。廣義上講,宣告包括定義,一般為敘述方便,把建立儲存空間的宣告稱定義,而不不需建立儲存空間的宣告稱宣告

auto

函式中的區域性變數,如果不用關鍵字static加以宣告,編譯系統對它們是動態地分配儲存空間的。函式的形參和在函式中定義的變數(包括在復合語句中定義的變數)都屬此類。在呼叫該函式時,系統給形參和函式中定義的變數分配儲存空間,資料儲存在動態儲存區中。在函式呼叫結束時就自動釋放這些空間。如果是在復合語句中定義的變數,則在變數定義時分配儲存空間,在復合語句結束時自動釋放空間。因此這類區域性變數稱為自動變數(auto variable)。自動變數用關鍵字auto作儲存類別的宣告。

對自動變數賦初值,不是在編譯時進行的,而是在函式呼叫時進行。對自動變數來說,若不賦初值,則它的值是乙個不確定的值

int fun(int

a)

register

一般情況下,變數的值是存放在記憶體中的。當程式中用到哪乙個變數的值時,由控制器發出指令將記憶體中該變數的值送到cpu中的運算器。經過運算器進行運算,如果需要存數,再從運算器將資料送到記憶體存放。為提高執行效率,c++允許將區域性變數的值放在cpu中的暫存器中,需要用時直接從暫存器取出參加運算,不必再到記憶體中去訪問。這種變

量叫做暫存器變數,用關鍵字register作宣告。暫存器變數的分配方式是動態分配的。

由於cpu中的通用暫存器數目有限,通常只把少數使用頻繁的變數定義為暫存器變數。對超出暫存器數目的暫存器變數作一般自動變數處理。

只有區域性自動變數和形式引數可作為暫存器變數,其他(如全域性變數、區域性靜態變數等)不行。在程式中定義暫存器變數對編譯系統只是建議性(而不是強制性)的。當今的優化編譯系統能夠識別使用頻繁的變數,自動地將這些變數放在暫存器中。

extern

全域性變數(外部變數)是在函式的外部定義的,它的作用域為從變數的定義處開始,到本程式檔案的末尾。在此作用域內,全域性變數可以為本檔案中各個函式所引用。編譯時將全域性變數分配在靜態儲存區

有時需要用extern來宣告全域性變數,以擴充套件全域性變數的作用域。

1) 在乙個檔案內宣告全域性變數

如果外部變數不在檔案的開頭定義,其有效的作用範圍只限於定義處到檔案終了。如果在定義點之前的函式想引用該全域性變數,則應該在引用之前用關鍵字extern對該變數作外部變數宣告,表示該變數是乙個將在下面定義的全域性變數。有了此宣告,就可以從宣告處起,合法地引用該全域性變數,這種宣告稱為提前引用宣告

用extern宣告外部變數時,型別名可寫可不寫。例如," extern int a , b ; " 也可寫成 " extern a , b ; "。

2) 在多檔案的程式中宣告外部變數

如果乙個程式包含兩個檔案,在兩個檔案中都要用到同乙個外部變數num,不能分別在兩個檔案中各自定義乙個外部變數num。正確的做法是:在任乙個檔案中定義外部變數num,而在另一檔案中用extern對num作外部變數宣告,即 "extern int num " 或 "extern num "

;編譯系統由此知道num是乙個已在別處定義的外部變數,它先在本檔案中找有無外部變數num,如果有,則將其作用域擴充套件到本行開始,如果本檔案中無此外部變數,則在程式連線時從其他檔案中找有無外部變數num,如果有,則把在另一檔案中定義的外部變數num的作用域擴充套件到本檔案,在本檔案中可以合法地引用該外部變數num。

static

所有全域性變數和用關鍵字static作儲存型別說明的區域性變數稱為靜態變數。靜態變數存放在靜態儲存區,一旦為其分配了儲存單元,它們在整個程式執行期間將固定地占用這些儲存單元。若非必要,不要多用靜態區域性變數。

對全域性變數,static使其區域性化(區域性於本檔案),靜態全域性變數僅能為本原始檔中各函式使用,不能為本原始檔以外的其他原始檔使用。

對區域性變數,static使其由動態儲存變為靜態儲存,靜態區域性變數僅能為本函式使用,其他函式不能使用和影響它們。靜態區域性變數是在編譯時賦初值的,且只賦初值一次。如在定義區域性變數時不賦初值的話,則對靜態區域性變數來說,編譯時自動賦初值0(對數值型變數)或空字元(對字元變數)

注:內部函式也稱靜態函式,不能被其他檔案中的函式使用。定義內部函式時,在函式名和函式型別的前面加static即可。

在c語言中,函式前如果無關鍵字extern,隱含其為外部函式。若需在其他檔案的函式中呼叫此外部函式,只需在呼叫的檔案中用extern宣告該外部函式。

記憶體四區

棧區(stack)

由編譯器自動分配釋放,存放函式的引數值區域性變數的值等;其操作方式類似於資料結構中的棧。

堆區(heap)

一般由程式設計師分配釋放(動態記憶體申請與釋放),若程式設計師不釋放,程式結束時可能由作業系統**。注意它與資料結構中的堆是兩回事,分配方式倒是類似於鍊錶。

全域性區/靜態區(static)

全域性變數靜態變數的儲存是放在一起的,初始化的全域性變數和靜態變數在一塊區域,未初始化的全域性變數和未初始化的靜態變數在相鄰的另一塊區域,該區域在程式結束後由作業系統釋放;

常量區:字串常量和其他常量的儲存位置,程式結束後由作業系統釋放。

程式**區(code)

存放函式的二進位制**

函式呼叫模型必須和程式四記憶體區綜合起來考慮:

主調函式分配的記憶體(棧區、堆區、全域性區)都可以在被呼叫函式中使用;

被呼叫函式中分配的記憶體,要分情況:在棧區中分配的記憶體,在主調函式中是不能使用的;

附加說明

c++prime時裡面有句話(p201頁):不要返回區域性物件的指標和引用。(更具體的說不能返回棧中超過棧頂的物件的指標),如果該物件是通過new分配的(處於堆中),或者是static(處於資料段data),或者在函式的呼叫之前建立的區域性物件,則可以返回這種物件的位址。

C 記憶體四區

c語言中,記憶體分為四個區域,區,全域性區,棧區,堆區。我們寫的 會被編譯成機器語言存放在這個區域內。一般存放的是兩種型別的變數 全域性變數,靜態變數,常量。特點是由系統分配空間,直到程式結束才釋放。定義在函式體外面的變數是全域性變數 int func int a 0 這是乙個全域性變數 intma...

C 記憶體四區

c 程式在執行時,將記憶體大方向劃分為4個區域 1.區 存放函式體的二進位制 由作業系統進行管理 存放cpu執行的機器指令 區是共享的,共享的目的是對於頻繁被執行的程式,只需要在記憶體中有乙份即可。區是唯讀的,使其唯讀的原因是防止程式意外的修改了它的意義,2.全域性區 存放全域性變數,靜態變數和全域...

c語言記憶體四區( )

圖1 記憶體四區模型 流程說明 1 作業系統把物理硬碟 load到記憶體 2 作業系統把c 分成四個區 3 作業系統找到main函式入口執行 乙個由c c 編譯的程式占用的記憶體分為以下幾個部分 1 棧區 stack 由編譯器自動分配釋放 存放函式的引數值,區域性變數的值等。其操作方 式類似於資料結...