存儲類別、鏈接和內存管理
C變量作用域:塊作用域、函數作用域、函數原型作用域、文件作用域。
C變量的3種鏈接屬性:外部鏈接、內部鏈接、無鏈接。前三種作用域變量都是無鏈接(僅在作用域內被使用);文件作用域變量根據定義形式來看,如果是static則為內部鏈接(僅在本文件內被使用),否則為外部鏈接(能被多個文件共享)。
存儲期:靜態存儲期(文件作用域變量,存在於整個程序的執行時間內)
線程存儲期(用於並發程序設計,從被聲明到線程結束)
自動存儲期(塊作用域變量,從進入塊到塊結束;VLA變長數組略有不同,是從被聲明到塊結束)
綜合作用域、鏈接屬性和存儲期,可以得到C為變量定義的各種存儲方案:
存儲類別 | 存儲期 | 鏈接屬性 | 作用域 | 聲明方式 |
自動 | 自動 | 無 | 塊 | 塊內,auto(缺省) |
寄存器 | 自動 | 無 | 塊 | 塊內,register |
靜態內部鏈接 | 靜態 | 內部 | 文件 | 所有函數外,static |
靜態外部鏈接 | 靜態 | 外部 | 文件 | 所有函數外 |
靜態無鏈接 | 靜態 | 無 | 塊 | 塊內,static |
1、自動變量
不會自己初始化。
2、寄存器變量
存儲在CPU寄存器中,無法被訪問地址。register的聲明只是作為一種請求,即被聲明的變量不一定就能存儲在CPU寄存器中,因為前提需要CPU寄存器有空間來存放它。
3、靜態無鏈接變量
具有塊作用域,無鏈接,但是靜態存儲期使得它在塊結束後不會消失,下一次進入塊(例如多次的函數調用或者循環結構)時它保留有上次的值。
未被顯式初始化靜態變量時,它們會被預置值為0。
4、靜態外部鏈接變量
在所有函數外部聲明。但本文件內函數中使用時可以用extern表明所使用的時文件作用域變量,也可不用extern;但當一個源代碼文件使用的外部變量定義在另一個源代碼文件中時,必須使用extern。
未被初始化時缺省為0。
5、靜態內部鏈接變量
在所有函數外聲明,使用static。在本文件內部函數使用該變量時可用extern表明使用的是文件作用域變量,也可不用。靜態內部變量不能再被其他文件使用。
未被初始化時缺省為0。
翻譯單元:一個源代碼文件及其頭文件內容組成了一個翻譯單元。
當程序有多個翻譯單元構成時,內部鏈接和外部鏈接的區別才體現出來。
malloc和free函數必須配套使用,防止內存泄漏。
靜態數據(包括字符串字面量)、自動數據、動態分配內存的數據分別在內存中占不同的區域。
存儲類別、鏈接和內存管理