在c/c++程式執行時,所使用的記憶體分為**區(code)、堆區(heap)、棧區(stack)、全域性/靜態儲存區(static)、常量儲存區(const)五個分割槽。注意此處的堆和棧並不是指資料結構
這個區域存放程式包含的所有函式體的二進位制**
由使用者**分配/釋放,下面的語句將會分配堆上的儲存空間:
char *p = (char *)malloc(10); //分配一段10位元組的儲存空間由系統自動分配的空間,使用者**無法控制,用於存放區域性變數,下面的**片段建立了三個儲存在棧上的不同型別的變數(或陣列),對應三塊大小不同的儲存空間:
void main()棧區是向下儲存的,每次分配的位址越來越小,堆區是向上儲存的(顧名思義,堆起來),每次分配的位址越來越大在所有函式外部定義的全域性變數,以及通過static修飾的任意位置的變數都儲存在該區域,下面的示例建立了3個儲存在全域性/靜態儲存區的變數
int a=4;上面的例子中a,b,c三個變數都儲存在全域性/靜態儲存區void punc()
void main()
下面的示例有助於我們理解全域性/靜態儲存區和棧區變數的區別,以及static關鍵字的作用
#include
void
test1()
void
test2()
void
main()
}
執行結果:
static b = 1從上面的例子我們不難發現:b = 1
static b = 2
b = 1
static b = 3
b = 1
1.static關鍵字修飾的靜態區域性變數的宣告語句只會在第一次執行的時候初始化,之後即使反覆執行也不會重新初始化
2.普通的儲存在棧上的區域性變數每次執行宣告/賦值語句都會進行一次初始化
3.static關鍵字修飾的變數仍然是區域性變數,無法從外部呼叫,也不會和其他作用域的同名變數起衝突
通過#define
const定義的常量, 源**中以指標形式定義的字串,都儲存在常量儲存區。和主程式的生命週期相同,而且他們的值在編譯時已經確定,一旦建立就無法更改(非正常手段除外)。
下面的例子展示了哪些資料會儲存在常量儲存區
#define pi 3.14上面宣告的變數都儲存在常量儲存區,其中char指標s本身儲存在棧上,他指向的值存放在常量儲存區。乙個很簡單的證據就是*s不可被二次賦值:const int p=3
void main()
(1)就起作用的階段而言: #define是在編譯的預處理階段起作用,而const是在 編譯、執行的時候起作用。引用自: const與#define相比,區別和優點超詳解總結!(2)就起作用的方式而言:
#define只是簡單的字串替換,沒有型別檢查。而const有對應的資料型別,是要進行判斷的,可以避免一些低階的錯誤。
(3)就儲存方式而言:#define只是進行展開,有多少地方使用,就替換多少次,它定義的巨集常量在記憶體中有若干個備份;const定義的唯讀變數在程式執行過程中只有乙份備份。
(4)從**除錯的方便程度而言: const常量可以進行除錯的,define是不能進行除錯的,因為在預編譯階段就已經替換掉了。
const優點:(1)const常量有資料型別,而巨集常量沒有資料型別。編譯器可以對前者進行型別安全檢查。而對後者只進行字元替換,沒有型別安全檢查,並且在字元替換可能會產生意料不到的錯誤。
(2)有些整合化的除錯工具可以對const常量進行除錯,但是不能對巨集常量進行除錯。
(3)const可節省空間,避免不必要的記憶體分配,提高效率
c c 程式的記憶體分割槽模型詳解
我們要想執行我們編寫的c程式,那麼第一步需要對這個程式進行編譯。預處理 巨集定義展開 標頭檔案展開 條件編譯,這裡並不會檢查語法 編譯 檢查語法,將預處理後檔案編譯生成彙編檔案 彙編 將彙編檔案生成目標檔案 二進位制檔案 在沒有執行程式前,也就是說程式沒有載入到 記憶體前,可執行程式內部已經分好3段...
C C 編譯的程式占用的記憶體分割槽
c c 編譯的程式占用的記憶體分割槽 1 棧區 stack 由編譯器自動分配釋放,存放函式的引數值,區域性變數的值等。其操作方式類似於資料結構中的棧。2 堆區 heap 一般由程式設計師分配釋放,若程式設計師不釋放,程式結束時可能由os 注意它與資料結構中的堆是兩回事,分配方式倒是類似於鍊錶,呵呵。...
C 程式的記憶體分割槽
乙個程式本質上都是由.bss段 data段 text段三個組成的。data段包含三個部分 heap 堆 stack 棧 和靜態資料區。text段存放 區。bss裡面裝載了未被初始化的資料 如圖 示例如下 int a 0 全域性初始化區 靜態區 char p1 全域性未初始化區 bss段 int ma...