数据类型的本质
数据类型本质:一个固定大小连续的内存块。
数据类型的作用:分配内存空间大小
变量的本质
变量的本质:一段连续内存空间的别名
程序运行流程
1.操作系统把物理硬盘的代码 load到内存中(运行的是 .exe文件)
2.操作系统把C 代码分成四个区
3.操作系统找到main 函数的执行入口
内存四驱模型
在 c/c++ 中我们将运行时数据,分为四个区域分别是:栈区,堆区,数据区,代码区:
1.栈区:存放函数的参数值,局部变量的值等,由编译器自动分配释放。
2.堆区:存放的是一般我们自己malloc()或者new 出来的对象,一般由程序员分配释放, 若程序员不释放,程序结束时可能由 OS 回收。malloc对应free,new 对应 delete
3.数据区(静态区/全局区):存放全局变量、静态变量和常量字符串等等。 程序结束后由系统释放
4.存放函数体的二进制代码。
*1. 栈区
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
从结果上发现changge1()这个方法并没有改变b的值,而change2 () 改变了。
当执行 到 int a = 100; int b = 10时 栈区的结构时这样的
当执行到change1(b)函数体内的时候,只是把变量a的值给了change1()函数的a.当该函数体执行完后,因为栈区时会自己回收的所以change1()的内存数据是会被清空的。所以b的值没有改变 b=10。
当执行到change2(&a);函数体内的时候,因为是传递的是a地址,然后通过地址修改a 的值,当
change2(&a)执行完 内存被清空后,a 的值已经发生改变了。
*2. 全局区
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 地址相同,指向的内容也相同
函数从main()函数入口执行,
char *p1 = NULL;
char *p2 = NULL;
对应的四驱模型如图:
编译器分别将变量p1,p2在栈区压栈,并给定初始值为NULL。
当执行getStr1()到函数体时如图:
当执行 p1 = getStr1()函数返回值赋给p1的时候,编译器会将getstr()函数在运行期其间申请的所有的栈区内存进行释放。内存四区如下:
同一样,当执行p2 = getStr2();语句时基本的内变化和p1相同,唯一不同的是编译器会对我我们的代码进行优化,p2指向的内存的值和p1相同时,编译器会只保留一个。这样内存四区如下
*3. 堆区
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数据
printf("tmp:%s.\n", tmp);
getchar();
}