C語言中變數儲存型別和生存週期

2021-08-27 05:56:51 字數 3396 閱讀 9338

本博文基於vc++6.0開發,除錯,執行;

內容來自譚浩強的《c語言程式設計》總結;

資料型別:浮點型,整型,字元型等都是乙個資料型別;

資料儲存型別:資料在記憶體中的儲存方式;(這是本博文要討論的重點)

注意:資料型別和資料儲存型別都是針對於宣告或定義的函式和變數而言的;

靜態儲存型別:變數或函式,在程式執行期間編譯器統一分配記憶體單元,直到程式結束分配的記憶體才被釋放;例如:全域性變數;

使用者區儲存內容

程式區cpu指令

靜態儲存區

全部的全域性變數,區域性靜態變數;

動態儲存區

被呼叫函式的形參;被呼叫函式中非區域性靜態變數;函式呼叫時的現場保護和返回位址等

注:

1. 在平時程式設計過程中,一般對變數和函式的宣告和定義都應同時指定資料型別和資料儲存型別;如果我們沒有對變數進行指定資料儲存型別;

2. 在定義全域性變數和區域性靜態變數時,如果沒有賦初始值,系統會預設為0;而動態變數們竟會被隨機賦值;

1. 自動變數—auto

定義:函式中,包括復合語句內和形式引數在內的變數中,不被static限制的變數;

性質:動態儲存型別,系統呼叫函式時臨時分配記憶體單元;函式執行結束就占用的記憶體釋放;

#include 

int fun1(int a);

void main()

int fun1(int a) //形式引數

return b;

}//動態變數沒賦初始值情況下初始值為隨機的;

執行結果:

注:大多數情況下,自動變數是可以直接省略auto的,系統也會預設為自動變數;

2.靜態區域性變數—static

定義:函式內被靜態static限制的區域性變數;靜態區域性變數在函式執行結束時,記憶體不被釋放,函式下次被執行的時候,此變數的值並不改變;

性質:靜態儲存型別,函式每次被呼叫其值還是上次函式執行時的值,且預設的初始化的值是0;

舉例:

#include 

int fun1(int a);

void main()

int fun1(int a)

輸出結果:

3.暫存器變數—register變數

定義:存放在cpu暫存器中的變數;(暫存器儲存型別也是隨著函式的結束,記憶體被釋放)

形式:register int a = 1; \將定義的a送到暫存器中;

說明:暫存器這個名詞如果是學過微控制器的同志肯定是知道的,對於微控制器功能的實現,基本上都是靠配置暫存器實現的;暫存器是什麼這個問題,我曾經在另外乙個部落格中詳細寫到過;

性質:cpu能夠快速讀寫暫存器變數;

優點:一般來說,程式中定義,宣告的變數是放在記憶體中的,例如全域性變數儲存在靜態儲存器中,對乙個全域性變數的每次讀寫操作都是cpu和記憶體之間的傳輸;但是暫存器變數是把變數儲存在cpu的暫存器中,由於暫存器的讀寫傳輸速度很快,所以非常適合處理一些程式中被高頻使用的變數;

缺點:cpu暫存器數量有限,不適合定義太多暫存器變數;

注意

1.目前計算器處理速度越來越快,加上c語言ide對於**的優化越來越好,所以有時即使我們不去定義或宣告乙個暫存器變數,ide也會把高頻使用的變數預設宣告為暫存器變數;所以在平時的程式設計時,並不用過於強調暫存器變數;

外部變數:定義在函式外的變數,也可以說就是全域性變數;

全域性變數的有效域:自定義處起以下範圍;

舉例:

#include 

void main() //全域性變數a不被main()函式呼叫;

int a=10; //全域性變數a

void fun1() //全域性變數a可以被fun1()呼叫;

1.同檔案內擴充套件外部變數的作用域—extern舉例:

#include 

extern

int a;

void main() //全域性變數a不被main()函式呼叫;

int a=10; //全域性變數a

void fun1() //全域性變數a可以被fun1()呼叫;

在第二行語句以下的函式都可以呼叫變數a;外部變數宣告也可以寫成:」extern a」這種形式,因為a已經是已經定義過的變數;

注意:extern並不是定義變數,而是宣告變數,這個關鍵字就是為了告訴編譯器:本檔案中已經定義這個變數;

2.將外部變數的作用域擴充套件到其他檔案–extern

怎樣擴充套件:乙個大的程式往往是由許多原始檔和標頭檔案組成,當不同檔案要引用同乙個外部變數時,方法是:在任意乙個檔案中定義外部變數,而在另乙個檔案中用extern對其進行「外部變數宣告」;這樣,在編譯連線時編譯器好知道這個變數來自於其他位置;如果說兩個檔案同時用了定義了相同名字的外部變數,那編譯器連線時會報錯;

擴充套件的方式:當程式進行編譯的時候,編譯器遇到extern所宣告的變數後,編譯器會現在本檔案中尋找此變數,如果找到了,就在此處擴充套件有效域,如果找不到,會進入其他檔案進行尋找,找到後將有效域擴充套件其他檔案,如果還找不到就按錯誤處理;

3.靜態外部(全域性)變數–static

定義:定義在函式外部的靜態變數;

優點:被static限制的外部變數,編譯時不會被其他檔案發現,即使不同檔案之間有同名的現象也沒關係;如果確定乙個外部變數不被其他檔案引用,就可以直接加static,這一點很符合c語言模組化的思想,也提高了程式的可移植性;

舉例:

#include 

static

int a; //靜態全域性變數,只能在本檔案中被呼叫;如果在其他檔案被呼叫將會報錯;

void main()

所以:對於static來說,靜態區域性變數說明的是此變數的生存期;靜態外部變數說明的是此變數的作用域;

三個概念:

生存期:乙個變數值在某一時刻是存在的,則這個時期就是這個變數的生存期;

作用域:乙個變數在某個檔案或函式範圍內是有效的,則這個範圍就是這個變數的作用域;

可見性:在乙個變數的作用域可以引用該變數,則說這個變數在這個作用域是可見的,這麼乙個性質就是可見性;

C語言之變數的儲存方式和生存週期

首先明確一下變數的劃分方式。根據變數的作用域,可以劃分為 區域性變數,全域性變數 根據生存週期,可以劃分為 靜態儲存方式,動態儲存方式 include int main int a,b,c 定義外部變數abc,因為是在函式外部定義的所以是外部變數,但是其作用範圍是從此處至之後的函式,main函式在其...

C語言中變數的儲存型別

變數的儲存型別 storage class 是指儲存變數值的記憶體型別。有三個地方可以用於儲存變數 普通記憶體 執行時堆疊 硬體暫存器 用於宣告變數儲存型別的關鍵字 auto static register 在所有 塊之外的變數的預設儲存型別是靜態的 static 儲存於靜態記憶體中,稱為靜態 st...

C 變數生存週期演示

能正確寫出下面 的輸出內容嗎?正確的輸出資訊是 d 全域性對像d初始化 a 函式內區域性對像a初始化 b 函式內區域性對像b初始化 b 函式內區域性對像b刪除.以前一直以為給一條 無故加對花括號是無聊的,或者編譯器會把它乾掉,無聊嗎?c 函式內靜態對像c初始化.注意區域性靜態變數雖然生存週期是整個程...