標籤:c 儲存
C變數和函數的儲存類型
在上一篇《C程式記憶體管理》的文章中,已經知道了C語言編譯後的可執行檔的儲存結構以及運行時的記憶體布局,本文則記錄C語言中變數和函數的儲存類型,以及在記憶體中的一些行為。
C語言中變數的聲明/定義格式如下:儲存類型 類型修飾符 資料類型 變數名;儲存類型:用來指明變數的儲存位置,即運行該變數在哪一段分配記憶體空間,常見的儲存位置有auto、extern、register、static,在一段執行程式中,可以為變數分配儲存空間的有BSS、資料區、棧區、堆區。類型修飾符:用來修飾變數的儲存和表現方式。包括long、short、signed、unsigned、void、const、volatile等。資料類型:用來指明該變數的儲存大小,即一個該類型的變數要佔用多少記憶體空間。基礎資料型別 (Elementary Data Type)有(char、int、float、指標類型)和由基礎資料型別 (Elementary Data Type)組成的使用者自訂類型(struct、enum、typedef、union)
C語言中函數的聲明格式如下:儲存類型 返回資料類型 函數名(參數列表)儲存類型:用來標識該函數的範圍,而不是儲存位置,主要有extern、static兩個,auto和register不用來表示程式的儲存類型。返回資料類型:函數退出時返回給調用者的資料類型。
1、關於auto儲存類型
auto只能用來表示變數的儲存類型,意味自動類型,表示該局部變數儲存在運行時進程的棧地區,一般而言,對於局部變數、auto為預設的儲存類型。所以可以省略不寫。注意,局部變數如果沒有初始化就直接拿來使用,那麼系統會隨機的分配一個值給它,這是不安全的。auto類型的變數每一次調用都會被初始化一次。
2、關於全域變數和extern聲明的資料
extern既可以聲明變數也可以標識函數。對於用來聲明變數,extern聲明在當前檔案中引用的定義在其它檔案中的全域變數。已經初始化的全域變數被儲存在資料區中,所以聲明其他檔案中的全域變數將不會在為其分配記憶體空間。
聲明一個變數和定義一個變數的區別:
定義一個變數:告訴編譯器需要為該變數分配多少空間。
聲明一個變數:告訴編譯器需要使用該變數,但該變數在其他位置被定義。
對於一個函數,儲存類型僅僅標識函數的範圍,預設的儲存類型是extern。
聲明全域變數的兩種方式:
1、在標頭檔中定義,然後引用標頭檔
2、在其他檔案中定義,然後使用extern引用變數。
3、register儲存類型
register關鍵字只能定義局部變數,只能修飾整形或者字元型,主要表示長期被使用的變數。被register定義的局部變數長期存在於寄存器中,寄存器變數被用於迴圈控制是比較理想的。和auto一樣,如果未初始化就直接使用register變數,那麼系統講隨機分配一個變數。
4、static儲存類型
static既可以標識變數也可以標識函數。被定義為靜態類型的變數(無論是全域的變數、還是局部變數)都儲存在資料區域,其生命週期為整個程式。如果是靜態局部變數,其範圍為自身所處的{ }內,如果是靜態全域變數,其範圍為整個當前檔案。
靜態變數如果沒有被初始化,系統講自動初始化為0值,只會被初始化一次。
static定義的函數的範圍只能是當前檔案,因此不能在其他檔案中被調用。對於不需要在其他檔案中被調用的函數,聲明為static是必要的,這樣也在一定程度上避免函數名稱的衝突。
5、常量資料
常量資料存放區在程式碼片段,其生存期為整個程式的已耗用時間,但是其範圍為當前檔案。
C變數和函數的儲存類型