數(shù)據(jù)類型的本質(zhì)
數(shù)據(jù)類型本質(zhì):一個(gè)固定大小連續(xù)的內(nèi)存塊。
數(shù)據(jù)類型的作用:分配內(nèi)存空間大小
變量的本質(zhì)
變量的本質(zhì):一段連續(xù)內(nèi)存空間的別名
程序運(yùn)行流程
1.操作系統(tǒng)把物理硬盤的代碼 load到內(nèi)存中(運(yùn)行的是 .exe文件)
2.操作系統(tǒng)把C 代碼分成四個(gè)區(qū)
3.操作系統(tǒng)找到main 函數(shù)的執(zhí)行入口
內(nèi)存四驅(qū)模型
在 c/c++ 中我們將運(yùn)行時(shí)數(shù)據(jù),分為四個(gè)區(qū)域分別是:棧區(qū),堆區(qū),數(shù)據(jù)區(qū),代碼區(qū):
1.棧區(qū):存放函數(shù)的參數(shù)值,局部變量的值等,由編譯器自動(dòng)分配釋放。
2.堆區(qū):存放的是一般我們自己malloc()或者new 出來的對(duì)象,一般由程序員分配釋放, 若程序員不釋放,程序結(jié)束時(shí)可能由 OS 回收。malloc對(duì)應(yīng)free,new 對(duì)應(yīng) delete
3.數(shù)據(jù)區(qū)(靜態(tài)區(qū)/全局區(qū)):存放全局變量、靜態(tài)變量和常量字符串等等。 程序結(jié)束后由系統(tǒng)釋放
4.存放函數(shù)體的二進(jìn)制代碼。
*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();
}
//結(jié)果:change1 =10,change2=200
從結(jié)果上發(fā)現(xiàn)changge1()這個(gè)方法并沒有改變b的值,而change2 () 改變了。
當(dāng)執(zhí)行 到 int a = 100; int b = 10時(shí) 棧區(qū)的結(jié)構(gòu)時(shí)這樣的

當(dāng)執(zhí)行到change1(b)函數(shù)體內(nèi)的時(shí)候,只是把變量a的值給了change1()函數(shù)的a.當(dāng)該函數(shù)體執(zhí)行完后,因?yàn)闂^(qū)時(shí)會(huì)自己回收的所以change1()的內(nèi)存數(shù)據(jù)是會(huì)被清空的。所以b的值沒有改變 b=10。
當(dāng)執(zhí)行到change2(&a);函數(shù)體內(nèi)的時(shí)候,因?yàn)槭莻鬟f的是a地址,然后通過地址修改a 的值,當(dāng)
change2(&a)執(zhí)行完 內(nèi)存被清空后,a 的值已經(jīng)發(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();
// 打印結(jié)果:p1:aaaaa , p2:aaaaa p1:10181068, p2 : 10181068
}
從打印結(jié)果可以看出p1 和p2 地址相同,指向的內(nèi)容也相同
函數(shù)從main()函數(shù)入口執(zhí)行,
char *p1 = NULL;
char *p2 = NULL;
對(duì)應(yīng)的四驅(qū)模型如圖:
編譯器分別將變量p1,p2在棧區(qū)壓棧,并給定初始值為NULL。
當(dāng)執(zhí)行g(shù)etStr1()到函數(shù)體時(shí)如圖:
當(dāng)執(zhí)行 p1 = getStr1()函數(shù)返回值賦給p1的時(shí)候,編譯器會(huì)將getstr()函數(shù)在運(yùn)行期其間申請(qǐng)的所有的棧區(qū)內(nèi)存進(jìn)行釋放。內(nèi)存四區(qū)如下:
同一樣,當(dāng)執(zhí)行p2 = getStr2();語句時(shí)基本的內(nèi)變化和p1相同,唯一不同的是編譯器會(huì)對(duì)我我們的代碼進(jìn)行優(yōu)化,p2指向的內(nèi)存的值和p1相同時(shí),編譯器會(huì)只保留一個(gè)。這樣內(nèi)存四區(qū)如下
*3. 堆區(qū)
char *getMem(){
char *p1 = NULL;
p1 = (char *)malloc(sizeof(char)* 10); //申請(qǐng)內(nèi)存空間
return p1;
}
void main(){
char *tmp = NULL;
tmp = getMem();
strcpy(tmp, "aaabbb"); //向tmp做指向的內(nèi)存空間中copy數(shù)據(jù)
printf("tmp:%s.\n", tmp);
getchar();
}