C變量和函數的存儲類型
在上一篇《C程序內存管理》的文章中(http://www.linuxidc.com/Linux/2015-01/111157.htm),已經知道了C語言編譯後的可執行文件的存儲結構以及運行時的內存布局,本文則記錄C語言中變量和函數的存儲類型,以及在內存中的一些行為。
C語言中變量的聲明/定義格式如下:
存儲類型 類型修飾符 數據類型 變量名;
存儲類型:用來指明變量的存儲位置,即運行該變量在哪一段分配內存空間,常見的存儲位置有auto、extern、register、static,在一段執行程序中,可以為變量分配存儲空間的有BSS、數據區、棧區、堆區。
類型修飾符:用來修飾變量的存儲和表現方式。包括long、short、signed、unsigned、void、const、volatile等。
數據類型:用來指明該變量的存儲大小,即一個該類型的變量要占用多少內存空間。基本數據類型有(char、int、float、指針類型)和由基本數據類型組成的用戶自定義類型(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++ 隱式類類型轉化 Implicit Class-Type Conversions http://www.linuxidc.com/Linux/2013-01/78071.htm
C語言變長數組之剖析 http://www.linuxidc.com/Linux/2013-07/86997.htm
C語言需要注意的問題 http://www.linuxidc.com/Linux/2013-05/84301.htm
C語言位域的使用及其注意點 http://www.linuxidc.com/Linux/2013-07/87027.htm
C語言中簡單的for循環和浮點型變量 http://www.linuxidc.com/Linux/2013-08/88514.htm