提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
参考大佬文章:
https://blog.csdn.net/chenlichenforlinux21/article/details/103311310
前言
我们实际生活中,保存的数据一般不会是同一种类型,所以引入了结构体。而结构体的大小也不是成员类型大小的简单相加。需要考虑到系统在存储结构体变量时的地址对齐问题。对齐方式很浪费空间,可按照计算机的访问规则,这种对齐方式提升了效率。
由于存储变量地址对齐的问题,结构体大小计算必须满足两条原则:
- 结构体成员的偏移量必须是成员大小的整数倍(0被认为是任何数的整数倍)
- 结构体大小必须是所有成员大小(数组,结构体除外)的整数倍
首先要知道的是关键字占多少个字节:
- char:1
- int:4
- float:4
- double:8
1、简单结构体
struct s1{
char ch1;
char ch2;
int i;
};
这个结构体的大小容易计算,满足两个原则即可,为8,那么下面这个呢
struct s2{
char ch1;
int i;
char ch2;
};
这个结构体大小是12,为什么呢?仔细看看两个原则,要满足偏移量是成员的整数倍,ch1偏移量是0,i的偏移量不可能是1,因为1不是i大小4的倍数,所以i的偏移量是4,ch2的偏移量就变为了8,所以满足结构体大小是成员大小整数倍,就是12。
2、成员包含数组的结构体
struct s3{
char ch;
int i;
char str[10];
};
这个结构体的大小是20,先看前两个成员,大小是8,毋庸置疑,这个char类型的数组,只需要把它看做十个char连在一起即可,加起来就是18,再满足结构体大小为成员整数倍,所以大小就是20。
3、成员包含结构体的结构体
struct s4{
char ch;
int i;
struct s{
char ch1;
int j;
};
float f;
};
这里需要注意一下,里面的结构体struct s的大小为8。但整体的大小却为12。所以里面的结构体大小并没有算进去。因为里面的结构体没有进行声明
我们来加个声明:
struct s4{
char ch;
int i;
struct s{
char ch1;
int j;
}demo;
float f;
};
加了声明“demo”之后,整个结构体大小为20
4、成员包含联合体的结构体
struct s5{
char ch;
int i;
union{
char ch1;
int j;
};
};
联合体大小就是成员中最大类型的大小,所以这个结构体大小是12.
5、指定对齐大小
(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.