我們都知道在C語言中不同類型的變量在內存中的存放位置不同的,從內存角度上講,不同內存塊中存放的代碼或者變量其屬性(主要是作用域、生命周期、鏈接屬性)是不同的。
目前創(chuàng)新互聯(lián)公司已為1000+的企業(yè)提供了網(wǎng)站建設、域名、雅安服務器托管、網(wǎng)站改版維護、企業(yè)網(wǎng)站設計、大渡口網(wǎng)站維護等服務,公司將堅持客戶導向、應用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長,共同發(fā)展。首先我們介紹一下作用域、生命周期已經(jīng)鏈接屬性的概念
1:作用域
作用域也就是指變量其作用的范圍
(1)局部變量為代碼塊作用域(也就是說局部變量的作用范圍是{ })
(2)函數(shù)和全局變量是文件作用域,進一步講其作用范圍就是函數(shù)和全局變量定義或者聲明后的部分。
2:生命周期
生命周期也就是變量的產(chǎn)生時間和消亡時間
(1)棧變量的生命周期:局部變量是被分配到棧上面的(棧變量),其生命周期是臨時的,臨時的意思是按需要去創(chuàng)建、使用、消亡。比如在一個子函數(shù)里面定義了一個局部變量int a;那么當這個子函數(shù)被調用執(zhí)行的時候,局部變量int a;會被創(chuàng)建在棧上面(符號a和棧上面的某個內存相綁定),當這個子函數(shù)被調用結束時,局部變量int a就消亡了(取消符號a和棧上面的某個內存的綁定),很現(xiàn)實的一個例子就是,當我們寫個程序去讀取局部變量的地址時,每次讀取的地址值是不一樣的。
(2)堆變量的生命周期
首先需要明白一點,堆內存空間是客觀存在的,它是由系統(tǒng)維護的一段內存空間,程序員只是向系統(tǒng)申請堆內存,然后釋放,所以堆變量也是有生命周期的,其生命周期就是mallloc(返回申請堆內存的首地址)申請到free釋放,
(3)數(shù)據(jù)段、bss段的生命周期
全局變量的生命周期是永久的,永久的意思是從被定義開始,一直到程序結束。
(4)代碼段、只讀段的生命周期
代碼段存放的是程序執(zhí)行的代碼(也就是函數(shù)),它的生命周期是永久的,但是一般不去研究代碼的生命周期,需要注意的是放在代碼段的還有const修飾的常量和字符常量(const類型的常量、字符串常量有時候放在rodata段,有時候放在代碼段,取決于平臺)
3:鏈接屬性
鏈接屬性是指代碼在鏈接時的屬性,包括外連接、內鏈接、無鏈接三種
(1)外連接:意思是外部鏈接屬性,也就是說可以在整個程序范圍(可以跨文件)內進行鏈接
(2)內鏈接:意思是內部鏈接屬性,也就是說可以在當前c文件范圍內進行鏈接
(3)無鏈接:意思是這個符號本身不參與鏈接,所有的局部變量(auto的,static的)都是無鏈接的
注意這里還涉及一個同名變量屏蔽規(guī)則的問題
(1)問題:編程時,不可避免會出現(xiàn)同名變量。變量同名后不一定會出錯。
(2)首先,如果兩個同名變量作用域不同且沒有交疊,這種情況下同名沒有任何影響。比如兩個子函數(shù)里面都定義了局部變量int a;
(3)其次,如果兩個同名變量作用域有交疊,C語言規(guī)定在作用域交疊范圍內,
作用域小的一個變量會掩蔽掉作用域大的那個(就小范圍原則)。比如定義了一個全局變量int a;又在子函數(shù)定義了局部變量int a;那么在這個子函數(shù)里面起作用的就是局部變量int a;
接下來從變量的類型角度出發(fā),分析代碼這三打要素具體到不同變量中的意義
1:普通局部變量
作用域為代碼塊作用域,生命周期為臨時性生命周期,鏈接屬性為無鏈接
普通局部變量被分配到棧上面,是按需創(chuàng)建、使用、消亡的,棧每次分配給變量是的地址是不確定的(隨機分配)這就決定了其鏈接屬性是無鏈接。
2:靜態(tài)局部變量(static修飾的局部變量)
靜態(tài)局部變量被分配到了數(shù)據(jù)段或者bss段(顯示初始化為非0則被分配到數(shù)據(jù)段,未顯式初始化或者顯式初始化為0則被分配到bss段),作用域為代碼塊作用域,生命周期為永久性生命周期,鏈接屬性為無鏈接(因為它的作用域是代碼塊作用域)。因為靜態(tài)局部變量被分配到了數(shù)據(jù)段或者bss段,所以它的生命周期是永久的,所分配的地址和靜態(tài)局部變量的符號的綁定是不變的,直到程序結束,所以在一個程序中多次使用同一個靜態(tài)局部變量時其實操作的是同一段內存,因為有這一特性,所以靜態(tài)局部變量常用來統(tǒng)計子函數(shù)被調用的次數(shù)。
3:全局變量和普通函數(shù)
作用域為文件作用域,生命周期為永久,鏈接屬性為外連接
需要注意的是全局變量和函數(shù)不要在頭文件中定義,原因是一個程序多處調用這個頭文件(頭文件中的內容在被預處理的時候是在文件中原地展開的)時就會出現(xiàn)重復定義(當然使用inline修飾的函數(shù)是可以放在有文件中的,并且不會城鄉(xiāng)重復定義)。全局變量的外連接屬性就決定了其必須是文件作用域以及永久的生命周期。
另外有需要云服務器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內外云服務器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務器、裸金屬服務器、高防服務器、香港服務器、美國服務器、虛擬主機、免備案服務器”等云主機租用服務以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應用場景需求。