內(nèi)存管理
作用域
C語言中變量的作用域可分為:代碼作用域、函數(shù)作用域、文件作用域
局部變量
局部變量也叫auto自動變量,一般情況下代碼塊{}內(nèi)部定義的變量都是自動變量,它有如下特點:
- 在一個函數(shù)內(nèi)定義,只在函數(shù)范圍內(nèi)有效
- 在復(fù)合語句中定義,只在函數(shù)范圍內(nèi)有效
- 隨著函數(shù)調(diào)用的結(jié)束或復(fù)合語句的結(jié)束局部變量的聲明周期也隨即結(jié)束
- 如果沒有賦初值,內(nèi)容為隨機
靜態(tài)(static)局部變量
- static局部變量的作用域也是在定義的函數(shù)內(nèi)有效
- static局部變量的生命周期和程序運行周期一樣,同時static局部變量的值只初始化一次,但可以賦值多次。
- static局部變量若未賦以初值,則由系統(tǒng)自動賦值:數(shù)值型變量自動賦初值0,字符型變量賦空值。
全局變量
- 在函數(shù)外定義,可被本文件及其它文件中的函數(shù)所共用,若其它文件中的函數(shù)調(diào)用此變量,須用extern聲明。
- 全局變量的生命周期和程序運行周期一樣。
- 不同文件的全局變量不可重名。
extern全局變量聲明
extern int a; 聲明一個變量,這個變量在別的文件中已經(jīng)定義了,這里只是聲明,而不是定義。
全局函數(shù)和靜態(tài)函數(shù)
在C語言中,函數(shù)都是默認全局的,使用關(guān)鍵字static可以將函數(shù)聲明為靜態(tài),函數(shù)定義為static就意味這個函數(shù)的文件中使用,在其他文件中不能調(diào)用,即使在其他文件中聲明這個函數(shù)都沒用。
對于不同文件中的static函數(shù)名字可以相同。
注意:
允許在不同的函數(shù)中使用相同的變量名,它們代表不同的對象,分配不同的單元,互不干擾。
同一源文件中,允許全局變量和局部變量同名,在局部變量的作用域內(nèi),全局變量不起作用。
所有的函數(shù)默認都是全局的,以為著所有的函數(shù)都不能重名,但如果是static函數(shù),那么作用域是文件級的,所以不同的文件static函數(shù)名可以是相同的。
類型 | 作用域 | 聲明周期 |
---|---|---|
auto變量 | 一對 { }內(nèi) | 當(dāng)前函數(shù) |
static局部變量 | 一對 { }內(nèi) | 整個程序運行期 |
extern變量 | 整個程序 | 整個程序運行期 |
static全局變量 | 當(dāng)前文件 | 整個程序運行期 |
extern函數(shù) | 整個程序 | 整個程序運行期 |
static函數(shù) | 當(dāng)前文件 | 整個程序運行期 |
register變量 | 一對 { }內(nèi) | 當(dāng)前函數(shù) |
內(nèi)存分布
內(nèi)存分區(qū)
C程序代碼經(jīng)過預(yù)處理、編譯、匯編、鏈接4步后生成一個可執(zhí)行程序。
在Linux下,程序是一個普通的可執(zhí)行文件。在沒有運行程序前,即程序沒有加載到內(nèi)存前,可執(zhí)行程序內(nèi)部已經(jīng)分為3段信息,分別為代碼區(qū)(text)、數(shù)據(jù)區(qū)(data)和未初始化數(shù)據(jù)區(qū)(bss)。文章來源:http://www.zghlxwxcb.cn/news/detail-435974.html
- 代碼區(qū)
存放CPU執(zhí)行的機器指令。通常代碼區(qū)可是共享的(即另外的執(zhí)行程序可以調(diào)用它),使其可共享的目的是對于頻繁被執(zhí)行的程序,只需要在內(nèi)存中有一份代碼即可。代碼區(qū)通常是只讀的,使其只讀的原因是防止程序意外地修改了它的指令。另外,代碼區(qū)還規(guī)劃了局部變量的相關(guān)信息。 - 全局初始化數(shù)據(jù)區(qū)/靜態(tài)數(shù)據(jù)區(qū)(data)段
該區(qū)包含了在程序中明確被初始化的全局變量、已經(jīng)初始化的靜態(tài)變量(包括全局靜態(tài)變量和局部靜態(tài)變量)和常量數(shù)據(jù)(如字符串常量)。 - 未初始化數(shù)據(jù)區(qū)(bss區(qū))
存入的是全局未初始化變量和未初始化靜態(tài)變量。未初始化數(shù)據(jù)區(qū)的數(shù)據(jù)在程序開始執(zhí)行之前被內(nèi)核初始化為0或者為空NULL。
程序在加載到內(nèi)存前,代碼區(qū)和全局區(qū)(data和bss)的大小就是固定的,程序運行期間不能改變。然后,運行可執(zhí)行程序,系統(tǒng)把程序加載到內(nèi)存,除了根據(jù)可執(zhí)行程序的信息分出代碼區(qū)(text)、數(shù)據(jù)?。╠ata)、和未初始化數(shù)據(jù)區(qū)(bss)之外,還額外增加了棧區(qū)、堆區(qū)。文章來源地址http://www.zghlxwxcb.cn/news/detail-435974.html
- 代碼區(qū)(text segment)
加載的是可執(zhí)行文件代碼段,所有的可執(zhí)行代碼都加載到代碼區(qū),這塊內(nèi)存是不可以在運行期間修改的。 - 未初始化數(shù)據(jù)區(qū)(BSS)
加載的是可執(zhí)行文件BSS段,位置可以分開亦可以緊靠數(shù)據(jù)段,存儲于數(shù)據(jù)段的數(shù)據(jù)(全局未初始化,靜態(tài)未初始化數(shù)據(jù))的生存周期為整個程序運行過程。 - 全局初始化區(qū)/靜態(tài)數(shù)據(jù)區(qū)(data segment)
加載的是可執(zhí)行文件數(shù)據(jù)段,存儲于數(shù)據(jù)段(全局初始化,靜態(tài)初始化數(shù)據(jù),文字常量(只讀))的數(shù)據(jù)的生存周期為整個程序運行過程。 - 棧區(qū)(stack)
棧是一種先進后出的內(nèi)存結(jié)構(gòu),由編譯器自動分配釋放,存放函數(shù)的參數(shù)值、返回值、局部變量等。在程序運行過程中實時加載和釋放。因此,局部變量的生存周期為申請到釋放該段棧空間。 - 堆區(qū)(heap)
堆是一個大容器,它的容量要遠遠大于棧,但沒有棧那樣先進后出的順序。用于動態(tài)內(nèi)存分配。堆在內(nèi)存中位于BSS區(qū)和棧區(qū)之間。一般由程序員分配和釋放,若程序員不釋放,程序結(jié)束時由操作系統(tǒng)回收。
到了這里,關(guān)于C語言-學(xué)習(xí)之路-07的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!