zoukankan      html  css  js  c++  java
  • C/C++ 类型内存占用详解

    最近做一些面试题目碰到了很多次考察C/C++类型内存占用的题目,主要考察队C/C++的指针、类型等的熟悉程度。
    本blog为了方面大家参考,总结了常见的类型内存占用的情况,能力所限,若有问题,请指出!

    1. 基本类型

    C/C++的基本类型包括int/long等等,这些基本类型在内存中的字节数一般是固定的(当然根据不同bit的系统有所调整),下表是基本类型的占用字节数。


    PS: 1byte=8bit, byte通常写成大写B, bit一般写为小写b

    下表单位均为Byte

    System char short int long long long float dobule void *
    (任意类型指针)
    32bit 1 2 4 4 8 4 8 4
    64bit 1 2 4 8 8 4 8 8

    不信?我们以代码说话:

    #include <iostream>
    
    using namespace std;
    
    int main()
    {
    
        cout<<"sizeof(char)="<<sizeof(char)<<endl;
        cout<<"sizeof(short)="<<sizeof(short)<<endl;
        cout<<"sizeof(int)="<<sizeof(int)<<endl;
        cout<<"sizeof(unsigned int)="<<sizeof(unsigned int)<<endl;
        cout<<"sizeof(long)="<<sizeof(long)<<endl;
        cout<<"sizeof(long long)="<<sizeof(long long)<<endl;
        cout<<"sizeof(float)="<<sizeof(float)<<endl;
        cout<<"sizeof(double)="<<sizeof(double)<<endl;
    
        //Poiter type
        cout<<endl;
        cout<<"sizeof(void *)="<<sizeof(void *)<<endl;
        cout<<"sizeof(char *)="<<sizeof(char *)<<endl;
        cout<<"sizeof(int *)="<<sizeof(int *)<<endl;
        cout<<"sizeof(float *)="<<sizeof(float *)<<endl;
        cout<<"sizeof(double *)="<<sizeof(double *)<<endl;
    
        return 0;
    }
    

    结果如下(我的系统是64bit的):
    mark


    可以看到,任意类型的指针的位数皆为8byte,即与系统位数保持一致,因此,判断系统的位数我可以直接用sizeof(void *).

    2. 复杂类型

    编程时,有时我们会碰到如下情况:

    • int *p[n]
    • int (*p)[n]

    以上两者到底有什么区别呢?
    下面我们先看一下代码:

    #include <iostream>
    
    using namespace std;
    
    struct A
    {
        int a;
        int b;
        long c;
        long d;
    };
    
    int main()
    {
        //Complex type
        cout<<endl;
    
        int p1[5] = {1,2,3,4,5};    //①.P1相关
        //int *p1 = &p1+1;      //It's warning in c but error in C++
        cout<<"sizeof(p1)="<<sizeof(p1)<<endl;
        cout<<"sizeof(&p1)="<<sizeof(&p1)<<endl;
        cout<<"*(p1+1) = "<<*(p1+1)<<endl;
    
        cout<<endl;
        int *p2[3];             //②.P2相关
        int a[10] = {0};
        int b[10] = {0};
        int c[10] = {0};
        p2[0] = a;
        p2[1] = b;
        p2[2] = c;
    
        cout<<"int *p2[3], sizeof(p2)="<<sizeof(p2)<<endl;
        cout<<"int *p2[3], sizeof(&p2)="<<sizeof(&p2)<<endl;
    
        cout<<endl;
        int (*p3)[4];       //③.P3相关
        int d[3][4]={0};
        p3=d;
        cout<<"sizeof(p3)="<<sizeof(p3)<<endl;
        cout<<"sizeof(p3[0])="<<sizeof(p3[0])<<endl;
    
        return 0;
    }
    

    ①. P1 : 数组

    • p1为一维数组的数组名,包含五个int型元素
    • p1虽然数值上与&p1[0]相等,但是两者不是一个东西(&p1[0]是第一个元素的地址)
    • p1+1 其实就是 &p1[1]

    ②. P2 : 数组指针 (int *p2[n])

    []的优先级高于*,因此先p2[3],即p2先是一个数组,然后与*结合,*p2[n]即成了数组指针(数组内部存放的内容皆为指针)
    mark

    ③. P3 : 指针数组(int(*p3)[n])

    int (p3)[n],由于()优先级大于[],所以先(p3),后为数组,即p3所指向的对象是有n个int型元素的数组,即p3是指向一维数组的指针;p3的值即为该一维数组的地址。


    以上,相当于二维数组。

    mark

    结果:

    根据以上讲解,你是否已经得出答案?
    mark

    3. 函数相关

    有的时候,我们还会遇到以下的情况:

    • int *p() : 返回指针的函数
    • int (*p)() : 指向函数的指针

    ①. int *p() 指针函数

    实际上,它就是一个函数,只不过返回类型为指针而已,和普通函数没什么区别的。

    #include <iostream>
    #include <cstring>
    
    using namespace std;
    
    char *array()
    {
        auto ptr = new char(10);
        ptr="hello";
        return ptr;
    }
    
    int main()
    {
        char *pt = array();
        cout<<pt<<endl;
    
        return 0;
    }
    

    ②. int (*p)(): 函数指针

    指向函数的指针变量,其本质是一个指针。

    int (*fptr)(int x); /*声明一个函数指针*/
    fptr = func; /*将func函数的首地址赋给该指针*/

    每个函数都有一个入口地址,将该入口地址赋值给一个指针,通过该指针即可以调用这个函数。

    #include <stdio.h>
    
    void (*ptr)(char *str);
    
    void prt1(char *str)
    {
        printf("ptr1 string=%s
    ", str);
        return ;
    }
    
    void prt2(char *str)
    {
        printf("ptr2 string=%s
    ", str);
        return ;
    }
    
    int main()
    {
        ptr = prt1;
        (*ptr)("hello");
    
        ptr = prt2;
        (*ptr)("world");
    
        return 0;
    }
    

    特别类似于C++的多态是不是?

    ③. 函数的形式参数

    有时候,我们函数的形参需要为指针,这个时候,其实我们可以有多重写法

    • void *func(char *str)
    • void *func(char str[])
    • void *func(char str[n])

    以上三种写法一个意思,即使n小于实参的字节数也无妨,此处的n只是一个提示作用而已。

  • 相关阅读:
    共享onload事件
    如何让背景图片平铺满整个浏览器页面
    Jmeter-配置环境资源池(如何设置HTTP请求默认值)
    Navicat 15下载教程
    Navicat 15 最新破解版下载_永久激活注册码(附图文安装教程)
    Dynamics CRM记录页面上隐藏子网格“+”标识
    Dynamics CRM 开发模板使用手册(插件开发)
    Dynamics CRM 常用 C# 方法集合
    Microsoft Dynamics CRM 2016 增强版的解决方案(CRM新特性,开发者的福利)
    Dynamics CRM 2016 使用Plug-in Trace Log调试插件
  • 原文地址:https://www.cnblogs.com/Jimmy1988/p/8338131.html
Copyright © 2011-2022 走看看