C語言中記憶體四區的詳解

1。 記憶體四區

1。1資料型別本質分析

1。1。1資料型別的概念

●“型別”是對資料的抽象

●型別相同的資料有相同的表示形式、儲存格式以及相關的操作

●程式中使用的所有資料都必定屬於某一種資料型別

1。1。2資料型別的本質

●資料型別可理解為建立變數的模具:是固定記憶體大小的別名。

●資料型別的作用:編譯器預算物件(變數)分配的記憶體空間大小。

●注意:資料型別只是模具,編譯器並沒有分酤空間,只有根據型別(模具)

建立變數(實物),編譯器才會分配空間。

1。2變數的本質分析

1。2。1變數的概念

概念:既能讀又能寫的記憶體物件,稱為變數;若一旦初始化後不能修改的物件則稱為常量。

變數定義形式:型別識別符號,識別符號,…,識別符號;

1。2。2變數的本質

1、程式透過變數來申請和命名記憶體空間int a = 0。

2、透過變數名訪問記憶體空間。

1。3程式的記憶體四區模型

流程說明

1、作業系統把物理硬碟程式碼load到記憶體

2、作業系統把c程式碼分成四個區

棧區( stack):由編譯器自動分配釋放,存放函式的引數值,區域性變數的值等

堆區(heap):一般由程式設計師分配釋放(動態記憶體申請與釋放),若程式設計師不釋放程式結束時可能由作業系統回收

全域性區(靜態區)( statIc):全域性變數和靜態變數的儲存是放在一塊的,初始化的全域性變數和靜態變數在一塊區域,未初始化的全域性變數和未初始化的靜態變數在相鄰的另一塊區域,該區域在程式結束後由作業系統釋放

常量區:字串常量和其他常量的儲存位置,程式結束後由作業系統釋放。

程式程式碼區:存放函式體的二進位制程式碼。

3、作業系統找到main函式入口執行

1。4函式呼叫模型

C語言中記憶體四區的詳解

1。5函式呼叫變數傳遞分析

(1)

C語言中記憶體四區的詳解

(2)

C語言中記憶體四區的詳解

(3)

C語言中記憶體四區的詳解

(4)

C語言中記憶體四區的詳解

(5)

C語言中記憶體四區的詳解

1。5棧的生長方向和記憶體存放方向

C語言中記憶體四區的詳解

相關程式碼:

02_資料型別本質。c

#define _CRT_SECURE_NO_WARNINGS#include#include#include#includeint main(){ int a;//告訴編譯器,分配4個位元組 int b[10];//告訴編譯器,分配4*10個位元組 /* 型別本質:固定記憶體塊大小別名 可以透過sizeof()測試 */ printf(“sizeof(a)=%d,sizeof(b)=%d\n”, sizeof(a), sizeof(b)); //列印地址 //陣列名稱,陣列首元素地址,陣列首地址 printf(“b:%d,&b:%d\n”,b,&b);//地址相同 //b,&b陣列型別不同 //b,陣列首地址元素 一個元素4位元組,+1 地址+4 //&b,整個陣列首地址 一個數組4*10=40位元組, +1 地址+40 printf(“b+1:%d,&b+1:%d\n”, b + 1, &b + 1);//不同 //指標型別長度,32位機器32位系統下長度是 4位元組 // 64 64 8 char********* p = NULL; int* q = NULL; printf(“%d,%d\n”, sizeof(p), sizeof(q));//4 , 4 return 0;}

03_給型別起別名。c

#define _CRT_SECURE_NO_WARNINGS#include#include#include#includetypedef unsigned int u32;//typedef 和結構體結合使用struct Mystruct{ int a; int b;};typedef struct Mystruct2{ int a; int b;}TMP;/*void 無型別1。函式引數為空,定義函式時用void修飾 int fun(void)2。函式沒有返回值:使用void void fun (void)3。不能定義void型別的普通變數: void a;//err 無法確定是什麼型別4。可以定義 void* 變數 void* p;//ok 32位系統下永遠是4位元組5。資料型別本質:固定記憶體塊大小別名6。void *p萬能指標,函式返回值,函式引數*/int main(){ u32 t;//unsigned int //定義結構體變數,一定要加上struct 關鍵字 struct Mystruct m1; //Mystruct m2;//err TMP m3;//typedef配合結構體使用 struct Mystruct2 m4; printf(“\n”); return 0;}

04_變數的賦值。c

#define _CRT_SECURE_NO_WARNINGS#include#include#include#includeint main(){ //變數本質:一段連續記憶體空間別名 //變數相當於門牌號,記憶體相當於房間 int a; int* p; //直接賦值 a = 10; printf(“a=%d\n”, a); //間接賦值 printf(“&a:%d\n”, &a); p = &a; printf(“p=%d\n”, p); *p = 22; printf(“*p=%d,a=%d\n”, *p, a); return 0;}

05_全域性區分析。c

#define _CRT_SECURE_NO_WARNINGS#include#include#include#includeint main(){ //變數本質:一段連續記憶體空間別名 //變數相當於門牌號,記憶體相當於房間 int a; int* p; //直接賦值 a = 10; printf(“a=%d\n”, a); //間接賦值 printf(“&a:%d\n”, &a); p = &a; printf(“p=%d\n”, p); *p = 22; printf(“*p=%d,a=%d\n”, *p, a); return 0;}

06_堆疊區分析。c

#define _CRT_SECURE_NO_WARNINGS#include#include#include#includechar* get_str(){ char str[] = “abcdef”;//內容分配在棧區,函式執行完畢後記憶體釋放 printf(“%s\n”, str); return str;}char* get_str2(){ char* temp = (char*)malloc(100); if (temp == NULL) { return NULL; } strcpy(temp, “abcdefg”); return temp;}int main(){ char buf[128] = { 0 }; //strcpy(buf,get_str()); //printf(“buf = %s\n”, buf);//亂碼,不確定內容 char* p = NULL; p = get_str2(); if (p != NULL) { printf(“p=%s\n”, p); free(p); p = NULL; } return 0;}

07_靜態區域性變數。c

#define _CRT_SECURE_NO_WARNINGS#include#include#include#includeint* getA(){ static int a = 10;//在靜態區,靜態區在全域性區 return &a;}int main(){ int* p = getA(); *p = 5; printf(“%d\n”,); return 0;}

08_棧的生長方向。c

#define _CRT_SECURE_NO_WARNINGS#include#include#include#includeint* getA(){ static int a = 10;//在靜態區,靜態區在全域性區 return &a;}int main(){ int* p = getA(); *p = 5; printf(“%d\n”,); return 0;}