一劍霜寒十四州——淺析內存分區(淺顯)

 

以上是我們對內存區域的一個簡單的劃分,其中包括:代碼段、全局(靜態)變量區、棧以及堆,接下來讓我們看看一些常見的內容分別位於哪個區域內,並對其生命週期、作用域、默認值、鏈接屬性進行總結。

 

一、全局變量:定義在函數外部的變量

生命週期:從程序運行開始創建,程序結束銷燬(太佔內存)

作用域:從定義該變量開始,一直到文件的結束

默認值:0

內存區域:全局(靜態)變量區

鏈接屬性:外部

 

全局變量可以在其他的源文件中使用,例如:

 

 

首先在test_01 中定義一個全局變量a,並將其賦值爲50

 

然後在另一個源文件test_02中,我們可利用extern 來使用全局變量 a。

 

注:extern 是計算機語言中的一個關鍵字,可置於變量或者函數前,以表示變量或者函數的定義在別的文件中。提示編譯器遇到此變量或函數時,在其它模塊中尋找其定義,另外,extern也可用來進行鏈接指定。

 

可以順利運行

 

二、靜態全局變量:

生命週期:從程序運行開始創建,程序結束銷燬

作用域:從定義該變量開始,一直到文件的結束

默認值:0,

內存區域:全局(靜態)變量區

鏈接屬性:內部

 

當我們在全局變量前加關鍵字 static 時,就變成了靜態全局變量,靜態全局變量具有以下特點:

(a)不必擔心其它源文件使用相同變量名,彼此相互獨立。

(b)在某源文件中定義的靜態全局變量不能被其他源文件使用或修改。

   (c) 只能在本文件中使用!不允許在其他文件裏調用;

 

 

例如:

 

 

還是繼續運行 test_02 ,運行失敗是可預見的

 

 

 

三、局部變量:定義在函數內部的變量,包括形參。

生命週期:進入函數時創建,函數退出時銷燬

作用域:只在函數內部有效

默認值:隨機值

內存區域:棧

 

 

鏈接屬性:無

 

 

例:

 

此程序運行的結果如下:

 

這是因爲,局部變量在它的生命週期結束時,它的內存也隨之消失,再次使用時再次申請空間,並且每次重新定義和初始化。

 

 

 

四、靜態局部變量:

生命週期:第一次進入函數時創建,程序結束時銷燬

作用域:只在函數內部有效

默認值:0

內存區域:全局(靜態)變量區

鏈接屬性:——

 

 

 

例:

 

我們把 a 定義成一個靜態局部變量,雖然只加了一個關鍵字 static ,但結果會有很大差異

 

 

 

 

產生這種結果的原因是:靜態局部變量所在的函數在多調用多次時,只有第一次才經歷變量定義和初始化,以後多次在調用時不再定義和初始化,而是維持之前上一次調用時執行後這個變量的值。本次接着來使用。靜態局部變量的這種特性,和全局變量非常類似。它們的相同點是都創造和初始化一次,以後調用時值保持上次的不變。不同點在於作用域不同。

 

五、動態內存:(下篇博客會具體介紹)

生命週期:調用動態內存創建函數時創建,free時銷燬

作用域:在未free該動態內存前,只要獲得該動態內存的首地址就可以使用

默認值:——

內存區域:堆

鏈接屬性:——

 

六、函數:

 

 

有時候我們需要從別的源文件中引用其中的函數,我們有以下兩種做法。當然前提是該函數不是 static 函數

 

 

第一種方法,我們直接用extern關鍵字來引用這個函數,如:

 

test_01 中定義了一個 add 函數,接下來在test_02中引用它:

 

可以正常運行。其結果爲:

 

 

 

 

 

另一種方法就是自己創建一個頭文件(add .h),在其中對所需函數進行聲明。如下:

 

 

 

然後我們就可以在需要使用這個函數的源文件中引用這個頭文件:

 

 

這個也是可以順利運行的,其結果和第一種方法的運行結果一樣。

這裏插個題外話,#include後面可以是 < > 或者 “ ”,這兩個是有一點區別的。

< > 是隻從系統的標準路徑查找頭文件

“ ”  是首先在自己的工程裏查找文件,找不到後,再去系統裏找

 

 

 

再說回函數,和靜態全局變量一樣,static函數也是不能被外部引用的,也就是說以上的兩種方法都會運行不了。如:

 

最後對函數總結一下,如果我們將來會在不同的源文件中使用很多相同的函數,大可以創建一個頭文件,然後在其中對所需函數進行聲明,這樣每個源文件只需要引用這個頭文件就可以了,而不需要去重複定義一個函數。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章