结构体大小的计算(学习笔记)
计算需要遵循两条规则
(1)结构体成员的偏移量必须是成员大小的整数倍。(0被认为是任何数的整数倍)
(2)结构体大小必须是所有成员(数组,结构体除外)大小的整数倍。
注:偏移量指的是每个成员相对结构体首地址的位移。
ex:
1.struct s1
{
char ch1; //偏移量为0
char ch2; //偏移量为1
int i; //偏移量为2,不是自身大小的整数倍。所以前边需要补2个字节空位。
};
得出 1+1+2+4=8个字节 s1结构体的大小为8个字节
2.struct s2
{
char ch1; //偏移量为0
int i; //偏移量为1,不是自身大小的整数倍。所以前边需要补3个字节空位。
char ch2; //偏移量为1
};
得出 1+3+4+1=9 但是9不是每个成员大小的整数倍。需要再补3个字节。所以s2结构体大小为12个字节。
3.struct s3
{
char ch; //偏移量为1
int i; //偏移量为1,不是自身大小的整数倍。所以前边需要补3个字节空位。
char str[10]; //偏移量为4
};
得出 1+3+4+10=18,但是18不是int类型的整数倍,所以要补2个字节。所以s3应该为20个字节
4.成员变量包括结构体变量
struct s4{
char ch; //偏移量为1
int i; //偏移量为1,不是自身大小的整数倍。所以前边需要补3个字节空位。
struct { char ch1; //偏移量为1 /*此结构体大小为8*/
int j;} s; //偏移量为4+4+1=9,不是int类型的整数倍,所以需要补3个字节。
float f; //偏移量为9+3=12 /*float类型占4个字节*/
};
得出1+3+4+8+4=20个字节。很明显20不是8的倍数。所以计算结构体大小时是把里面这个结构体就看做是一个char,和一个int,不是看做一个整体,数组同理。
如果结构体中的结构体知识声明,没有定义变量的话那它不占空间。
5.成员变量包括结构体变量,含double类型
struct s4{
char ch; //偏移量为1
int i; //偏移量为1,不是自身大小的整数倍。所以前边需要补3个字节空位。
struct { char ch1; //偏移量为1 /*此结构体大小为4+4+8=16*/
int j; //偏移量为4+4+1+=9,不是int类型的整数倍,所以需要补3个字节。
double d;} s; //偏移量为9+3=12,不是double的倍数,所以补4个字节。
float f; //偏移量为24+4=28,不是8的倍数,所以补4个字节 /*float类型占4个字节*/
};
得出1+3+4+1+3+4+4+8+4+4=32个字节
6.指定对齐大小
(1)对齐值小于最大类型成员值
#pragma pack(4) //指定向4对齐 最大是8
struct s6
{
char ch;
int i;
float f;
double d;
};
如果我们没有指定对齐值,这个结构体大小是24,我们指定向4对齐,所以大小是4的倍数,所以结构体大小是20。
(2)对齐值大于最大类型成员值
#pragma pack(10)
struct s7{
char ch;
int i;
float f;
double d;
};
我们指定的对齐值是10,最大为8,是否就向10对齐?不是,当指定对齐值大于自身对齐值时,向自身对其值对齐,大小是24.
原文链接:https://blog.csdn.net/chenlichenforlinux21/article/details/103311310