• sizeof()计算


    本节包含sizeof()计算结构体,位域,数组,字符串,指针,c++中的class等类型的大小,sizeof()计算的大小都是以字节为单位。

    一 计算基本类型的长度

    sizeof(char): 1

    sizeof(short): 2

    sizeof(int): 4

    sizeof(long): 4(win X86 和 win X64长度都为4, Linux X86长度为4,Linux X64为8)

    sizeof(float):4

    sizeof(double):8

    sizeof(bool):1(在C++里长度为4)

    sizeof(BOOL):4 (在windows平台长度为4)

    sizeof(p):指针类型在X86长度为4,X64长度为8,如char *p

    二 计算结构体的长度

      要正确计算sizeof(结构体)的大小,需要理解和掌握数据对齐的概念。数据对齐的概念在前面内存中的数据对齐  和 自然对齐和强制对齐有介绍。

     关键是记住自然对齐和强制对齐的对齐规则,计算sizeof(结构体)的大小就很简单了。

    三 计算数组长度

      char str[] = "hello";  sizeof(s)大小是多少

    1 普通情况

      str是字符数组,由字符串"hello"初始化,"hello"; 共5个字符,又字符串以 '' 结尾。所以str数组的长度是6

      sizeof(s)为6

    2 str数组做函数参数

      在函数里,数组str作为参数传进来,在函数内部str是指针的形式。所以:

      sizeof(s)为4  X86平台

      sizeof(s)为8  X64平台

    四 计算union的长度

      在使用sizeof计算union类型的时候,整个union结构的大小等于union中最大成员的大小,并且必须是最大类型的整数倍。

    例如:
    typedef union 
    {
        long i; 
        int k[5];
        char c;
    } DATE;
    struct data 
    {
        int cat; 
        DATE cow; 
        double dog;
    } too; 
    DATE max; sizeof(struct data) = ?sizeof(max))=?
    分析:
    由于max是union DATE类型,那么其中最大的成员为k,所以sizeof(MAX)=k成员的长度=5*sizeof(int)=20
    对于struct data结构体,按照自然对齐方法,计算出结果为:sizeof(struct data)=4+20+8=32

    五 计算位域结构的大小

      位域结构的大小在位域(位段)有介绍。

    六 计算类和对象的大小 (C++中)

    class A
    {
    public:
        A();
        ~A();
    
    private:
    
    };
    
    void main()
    {
        printf("sizeof(A): %d
    ", sizeof(A));
        getchar();
    }

    sizeof(A) = 1。因为类的实例化就是给每个实例在内存中分配一块内存地址。空类被实例化时,会由编译器隐含得添加一个字节,所以为1。

    class B
    {
        void fn1();
        void fn2();
    protected:
        char a;
        char b;
        int c;
        static int d;
    };

    sizeof(B) = 8。
    类B中最大类型是int。a长度1字节,b长度1字节,int型c内存地址必须可以被4整除,static变量d不影响类的大小。

    所以sizeof(B) = 变量a的长度1 + b的长度1 + 对齐2字节 + 变量c的长度4字节 = 8

    class A
    {
    protected:
        int a;
    private:
        int b;
    };
    class B :public A
    {
    private:
        int c;
    };

    sizeof(B) = 12  B继承A,所以B中包含了A中的所有数据,大小为A内的大小8+B内的大小4 = 12 

    class C
    {
        virtual void fun(){}
    };

    sizeof(C) = 4   因为类C中包含一个指向虚函数表的指针。

    class D
    {
        virtual void fun1()    {}
    
        virtual void fun2() {}
    };

    sizeof(D) = 4 多个虚函数只需要一个指向虚函数表的指针

    七 sizeof与strlen

    char *p1 = "12345678"; 
    char p2[] = "12345678"; 
    char p3[1024]="12345678"; 
    char p4[] = {'1','2','3','4','5','6','7','8'}; 

    sizeof(p1)=? 
    sizeof(p2)=? 
    sizeof(p3)=? 
    sizeof(p4)=? 

    strlen(p1)=? 
    strlen(p2)=? 
    strlen(p3)=? 
    strlen(p4)=? 

    分析: 
    p1是一个字符指针,指向了静态常量区的一个常量字符串,"12345678"。所以,sizeof(p1)=指针的长度=4;strlen(p1)=字符串"12345678"的长度(不含''),所以是8。 
    p2是一个字符数组,由静态常量区的"12345678"进行初始化。所以sizeof(p2)是计算数组p2的长度,所以结果为"12345678"的所有字符的长度(含''),所以是9。 strlen(p2)也是在计算"12345678"的长度(不含''),所以是8。 
    p3是一个字符数组,由静态常量区的"12345678"进行初始化,但长度为1024。 所以,sizeof(p3)=1024;strlen(p3)为字符串"12345678"的长度(不含''),所以是8。 
    p4是一个字符数组,由字符'1','2','3','4','5','6','7','8'进行初始化, 这样初始化与"12345678"进行初始化的区别是 前者不包含''。因此,sizeof(p4)=8。由于p4作为一个字符数组,并不以''结尾, 所以strlen(p4)在计算字符串长度的时候,找不到结束符'',会发生字符串溢出。 
    所以,最后答案为: 
    sizeof(p1)=4 
    sizeof(p2)=9 
    sizeof(p3)=1024 
    sizeof(p4)=8 
    strlen(p1)=8 
    strlen(p2)=8 
    strlen(p3)=8 
    strlen(p4)=字符串溢出,值不确定,甚至会引起程序崩溃 

    八 sizeof其它

    题目1:请设计一个宏,用来计算数组的长度。
    解:#define ARRAYLEN(a) sizeof(a)/sizeof(a[0])

    题目2:sizeof是函数吗?是在程序编译的时候计算的还是运行时?
    解:sizeof是操作符而不是函数。sizeof是在程序编译的时候就计算完成了,而不是在程序运行的时候计算。

      

      

  • 相关阅读:
    SpringMVC的入门示例
    [PTA] 数据结构与算法题目集 6-1 单链表逆转
    [PTA] L3-015 球队“食物链”
    [PTA] 1001. 害死人不偿命的(3n+1)猜想 (Basic)
    [PTA] 1002. 写出这个数 (Basic)
    [opengl] 画一个可移动的自行车 二维几何变换(平移、旋转、缩放)
    css inline-block 水平居中
    css 图片裁剪显示
    [leetcode] 19. Remove Nth Node From End of List (Medium)
    [leetcode] 20. Valid Parentheses (easy)
  • 原文地址:https://www.cnblogs.com/fengxing999/p/10921891.html
Copyright © 2020-2023  润新知