美文网首页c/c++
c进阶-内存四驱模型

c进阶-内存四驱模型

作者: Peakmain | 来源:发表于2018-09-19 19:30 被阅读5次

    数组参数传递

    代码如下

    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的值

    相关文章

      网友评论

        本文标题:c进阶-内存四驱模型

        本文链接:https://www.haomeiwen.com/subject/vnpinftx.html