數(shù)據(jù)類型的本質
數(shù)據(jù)類型本質:一個固定大小連續(xù)的內存塊卫键。
數(shù)據(jù)類型的作用:分配內存空間大小
變量的本質
變量的本質:一段連續(xù)內存空間的別名
程序運行流程
1.操作系統(tǒng)把物理硬盤的代碼 load到內存中(運行的是 .exe文件)
2.操作系統(tǒng)把C 代碼分成四個區(qū)
3.操作系統(tǒng)找到main 函數(shù)的執(zhí)行入口
內存四驅模型
在 c/c++ 中我們將運行時數(shù)據(jù)恩敌,分為四個區(qū)域分別是:棧區(qū),堆區(qū)晰甚,數(shù)據(jù)區(qū)钙蒙,代碼區(qū):
1.棧區(qū):存放函數(shù)的參數(shù)值,局部變量的值等,由編譯器自動分配釋放。
2.堆區(qū):存放的是一般我們自己malloc()或者new 出來的對象愿吹,一般由程序員分配釋放, 若程序員不釋放惜姐,程序結束時可能由 OS 回收犁跪。malloc對應free,new 對應 delete
3.數(shù)據(jù)區(qū)(靜態(tài)區(qū)/全局區(qū)):存放全局變量椿息、靜態(tài)變量和常量字符串等等。 程序結束后由系統(tǒng)釋放
4.存放函數(shù)體的二進制代碼坷衍。
*1. 棧區(qū)
void change2(int * a){
*a = 200;
}
void change1(int a){
a = 200;
}
void main(){
int a = 100;
int b = 10;
change1(b);
change2(&a);
printf("change1 =%d,change2=%d", b,a);
getchar();
}
//結果:change1 =10,change2=200
從結果上發(fā)現(xiàn)changge1()這個方法并沒有改變b的值寝优,而change2 () 改變了。
當執(zhí)行 到 int a = 100; int b = 10時 棧區(qū)的結構時這樣的
當執(zhí)行到change1(b)函數(shù)體內的時候枫耳,只是把變量a的值給了change1()函數(shù)的a.當該函數(shù)體執(zhí)行完后乏矾,因為棧區(qū)時會自己回收的所以change1()的內存數(shù)據(jù)是會被清空的。所以b的值沒有改變 b=10嘉涌。
當執(zhí)行到change2(&a);函數(shù)體內的時候妻熊,因為是傳遞的是a地址,然后通過地址修改a 的值仑最,當
change2(&a)執(zhí)行完 內存被清空后扔役,a 的值已經發(fā)生改變了。
*2. 全局區(qū)
char * getStr1(){
char *p1 = "aaaaa";
return p1;
}
char *getStr2(){
char *p2 = "aaaaa";
return p2;
}
void main(){
char *p1 = NULL;
char *p2 = NULL;
p1 = getStr1();
p2 = getStr2();
printf("p1:%s , p2:%s \n", p1, p2);
printf("p1:%d , p2:%d \n", p1, p2);
getchar();
// 打印結果:p1:aaaaa , p2:aaaaa p1:10181068, p2 : 10181068
}
從打印結果可以看出p1 和p2 地址相同警医,指向的內容也相同
函數(shù)從main()函數(shù)入口執(zhí)行亿胸,
char *p1 = NULL;
char *p2 = NULL;
對應的四驅模型如圖:
編譯器分別將變量p1,p2在棧區(qū)壓棧,并給定初始值為NULL预皇。
當執(zhí)行getStr1()到函數(shù)體時如圖:
當執(zhí)行 p1 = getStr1()函數(shù)返回值賦給p1的時候侈玄,編譯器會將getstr()函數(shù)在運行期其間申請的所有的棧區(qū)內存進行釋放。內存四區(qū)如下:
同一樣吟温,當執(zhí)行p2 = getStr2();語句時基本的內變化和p1相同序仙,唯一不同的是編譯器會對我我們的代碼進行優(yōu)化,p2指向的內存的值和p1相同時鲁豪,編譯器會只保留一個潘悼。這樣內存四區(qū)如下
*3. 堆區(qū)
char *getMem(){
char *p1 = NULL;
p1 = (char *)malloc(sizeof(char)* 10); //申請內存空間
return p1;
}
void main(){
char *tmp = NULL;
tmp = getMem();
strcpy(tmp, "aaabbb"); //向tmp做指向的內存空間中copy數(shù)據(jù)
printf("tmp:%s.\n", tmp);
getchar();
}