c进阶-内存四驱模型
2018-09-19 本文已影响5人
Peakmain
数组参数传递
代码如下
void print(int arr[]){
//获取数组的大小
int length=sizeof(arr)/sizeof(int);
printf("length=%d\n", length);
for (int i = 0; i<length; i++){
printf("%d\n", arr[i]);
}
}
void main(){
int arr[] = { 1, 2, 3, 4, 5, 6 };
//求数组的大小
int size = sizeof(arr) / sizeof(int);
printf("size=%d\n", size);
print(arr);
getchar();
}
情况分析:我们会发现数组作为参数传递的时候获取不到长度,这是为什么呢?这是因为c/c++编译器会将数组作为参数传递,会退化成一个指针,传的实际是首地址。那如果非要数组作为参数传递怎么解决呢呢?,将数组大小传递过去就可以了
void print(int arr[],int length){
//获取数组的大小
/* int length=sizeof(arr)/sizeof(int);*/
printf("length=%d\n", length);
for (int i = 0; i<length; i++){
printf("%d\n", arr[i]);
}
}
void main(){
int arr[] = { 1, 2, 3, 4, 5, 6 };
//求数组的大小
int size = sizeof(arr) / sizeof(int);
printf("size=%d\n", size);
//数组作为参数传递的时候为什么获取不到长度
//数组作为参数传递,会退化成一个指针,传的实际是首地址
// print(arr);
print(arr, size);
getchar();
}
数据类型的本质
数据类型本质:内存上一块连续的固定大小空间
void*代表任意数据类型的指针
int a;//告诉c/c++编译器开辟一块连续大小的4字节的内存空间
int arr[] = {1, 2, 3, 4, 5, 6};//数据类型的内存空间
a=10;
//488, 492, 488 ,512 512=488+4*6==&arr+1 如果是 &arr+2 488+4*6*2
printf("%d, %d, %d ,%d", arr, arr+1, &arr, &arr+1);
getchar();
变量的本质
固定内存空间大小(一块连续大小的内存空间)的别名,通过变量可以去操作一块内存上的数据
变量的三要素:内存大小,名称,作用域
内存四驱模型
程序运行的流程
1.操作系统会把物理硬盘上的代码load到内存
2.加载到内存后会把c的代码分成四个区
3.然后系统会找到main函数的入口去执行
四驱模型
1.栈区:由编译器自动分配的,存放一些局部变量值和函数,这个里面内存是自动进行回收的
2.堆区:一般都是我们自己开辟的,这个里面的内存需要手动进行释放 malloc->free ,new->delete
3.全局区(静态区):静态的一些常量,字符串等等.
4.程序代码区:存放的是函数的二进制代码
案例:
char* getStrl(){
//全局区
char *str="12345";
return str;
}
char* getStr2(){
//全局区
char *str="12345";
return str;
}
char *getStr3(){
//栈区最后会释放内存
char buff[128];
strcpy(buff,"12345");
return buff;
}
char* getStr4(){
// char* buff char* 是4字节的数据类型,存的是堆区开辟的 128 个字节的首地址
char* buff = malloc(128);
strcpy(buff, "12345");
return buff;
}
void main(){
char *str1=NULL;
char *str2=NULL;
char *str3=NULL;
str1=getStrl();
str2=getStr2();
str3=getStr3();
char* str4 = getStr4();
printf("%d , %d, %s, %s",str1,str2,str3,str4);
getchar();
}
栈的开口方向
int a = 10;
int b = 10;
// buffer 数据类型跟栈的开口方向无关(都是向上)
char buff[10];
// buff+1 > buff
//0508 0496 a的地址要大于b的地址 Debug 开口向下 a>b
//016 020 b的地址要大于a的地址 Release 开口向上 b>a
printf("%p , %p, %p, %p", &a, &b, buff, buff + 1);
getchar();
指针强化:指针也是一种数据类型,虽说都是占用4个字节,但是有数据类型,指针存放的是一块内存地址
int a=100;
int* ff = &a;// 虽说是 a 的地址,但是我也可以把 ff 看做一个数组
ff+=1;
最后我们在举个例子分析下内存四驱模型
#include <stdio.h>
void change(int number){//不能修改
number = 300;
printf("%p\n", &number);
}
void change2(int* number){//可以修改
*number = 300;
printf("%p\n", &number);
}
void main(){
int a = 100;
printf("%p\n", &a);//0031F84C
//修改a的值
a = 200;
change(a);//a变量的值赋值给number变量,number是在另一个函数中,number是一个新的变量
printf("a==%d", a);//a=200
change2(&a);//a变量的地址赋值给number变量,number是在另一个函数中,number是一个新的变量
printf("a==%d", a);//a=300
}
上面我们可以知道change(a)的时候并没有修改a的值,这是为什么呢?但是我们调用change2(&a)的时候又改变了a的值,这又是为什么呢?
change.png
我们会发现无论你number修改成什么值,a是不会改变
change2.png
我们可以发现当number此时指向的a的地址,即当number修改了值,会改变赋值给它地址的a的值