结构体字节对齐的一些情况

空结构体/空类大小为1字节

在c++中类和结构体一样都需要字节对齐

类中的方法不算做类成员的大小

如果类中的方法是虚方法就不同了因为它会有一个虚表指针,当然即使虚方法有两个但是虚表指针也只会有一个,所以:

class Test1     //按照double对齐
{
public:
    virtual void fun()     
    {};
    virtual void fun1()
    {};
private:
    //__vftp     //4   +4
    int a;      //4     +4
    double b;    //8
    char c;       //1+7
};
void main()
{
    cout << sizeof(Test1) << endl;   //32
}

但是:

//转换成员顺序后
class Test1   //按照double对齐
{
public:
    virtual void fun()     
    {};
    virtual void fun1()
    {};
private:
    //__vftp     //4   +4    
    double b;    //8
    
    int a;      //4
    char c;       //1  +3
};
void main()
{
    cout << sizeof(Test1) << endl;   //24
}

看见嵌套结构体就把里面的结构体当成一个整体,里面是24,因为short和double对齐所以是2+6, 所以Test  大小就是40.

//因为字节对齐效率更快   //空间换时间
typedef struct Test
{
    short a;  //2+6
    struct
    {
        int b;     //4+4
        double c;   //8
        char d;     //1+7
    }
    long e;    //4+4
}Test;

因为设置了按照4字节对齐,根据结构体内部按照double对齐,所以有效值选择最小的4字节来进行 对齐,因为struct dasd{}tt;是一个变量所以开辟空间。

#pragma  pack(4)   //设置按照设置值对齐,但是系统会按照有效值进行对齐,有效值就是选择所要按照对齐大小的最小对齐值
typedef struct Test
{
    short a;   //2+2
    struct dasd
    {
        int b;      //4
        double c;   //8
        char d;    //1+3
    }tt;
    long e;     //4
}Test;
void main()
{
    long a;
    cout << sizeof(a) << endl;  //4
    cout << sizeof(Test) << endl;  //24
}

但是如果内部结构体没有定义变量所以只是一个类型不占空间所以是8个字节

#pragma  pack(4)   //设置按照设置值对齐,但是系统会按照有效值进行对齐,有效值就是选择所要按照对齐大小的最小对齐值
typedef struct Test
{
    short a;   //2+2
    struct dasd   //因为不加tt这就是一个类型没有空间
    {
        int b;      
        double c;   
        char d;    
    };
    long e;     //4
}Test;
void main()
{
    long a;
    cout << sizeof(a) << endl;  //4
    cout << sizeof(Test) << endl;  //8
}
但是下面这么种情况要注意:
typedef struct Test4 
{
    char a : 3;   //位域   意思是一个字节占 3位
    char b : 2;    //占2位
    char c : 1;    //占一位
}Test4;
void main()
{
    cout << sizeof(Test4) << endl;  //1
}

所以总的加起来没有超过8位所以一个字节。

image

   位域

限制条件:

1.如果一个字节无法保存那么就是两个字节,但是超出的那个变量要丢弃第一个字节剩下的位数,在第二个字节重新开始。所以位域是不跨字节存储的

image

2.位域不能跨类型存储(下面举例)

typedef struct Test4 
{
    char a : 3;   //1+3
    int b : 2;    //4
}Test4;
void main()
{
    cout << sizeof(Test4) << endl;  //8
}

因为开辟空间是根据类型开辟空间,所以char a:3意思是开辟一个字节用3个位,但是因为类型不同不能跨类型,所以int b:2,要重新开辟4个字节的空间,虽然只是使用其中的2位。因为两个类型都开辟了空间所以要进行对齐,所以是8个字节。

这是小编学习后的自我总结希望对您有帮助!!!

原文地址:https://www.cnblogs.com/ycw1024/p/11322262.html