一、内存对齐
在计算结构体大小的时候就用到了内存对齐
1.第一个成员在与结构体变量的偏移量为0的地址处
2.其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处
对齐数:编译器默认数与成员变量大小的较小值
3.结构体大小是对齐数最大的倍数!
4.如果嵌套了结构体的情况,嵌套的结构体对齐自己最大的对齐数整数倍,结构体的大小是所有(包裹嵌套的结构体)的最大对齐数的整数倍。
vs编辑器默认值是8
1.引入库
代码如下:
#include<stdio.h>
struct S1
{
char a;//0
int b;//4-7
short c;//8-9
};
int main()
{
struct S1 i;
//结构体的大小是对齐数最大的整数倍
printf("%d\n", sizeof(i));//12
return 0;
}
2.为什么存在内存对齐
处理器对于为对齐的数据要访问两次,对于对齐的数据访问一次。大大的提高了效率。
代码如下:
struct S1
{
char a;//0
int c;//4-7
char b;//8
}d1;//大小是12个字节
struct S2
{
int c;//4-7
char a;//8
char b;//9
}d2;//大小是8个字节
结构成员的位置不同,导致了空间的大小不同,总的来说结构对齐是拿空间换时间。
3.修改对齐数默认值
#pragma pack(默认对齐数)
#pragma pack(2)
struct S1
{
char a;//0
int c;//2-5
char b;//6
}d1;//大小是8个字节
#pragma pack()
默认对齐数不同,结构空间所占大小也不同。
二、位段
结构体实现位段
1.什么是位段
位段的成员名后面跟着冒号和一个数字,数字代表的是它空间占几个位。
位段的成员都是整型家族,如int,short int,unsigned int,char。
如下就是个位段
struct S1
{
int a : 5;
char b : 2;
};
2.位段的内存分配
1.位段的成员变量类型都是整型。
2.位段是按照空间需要以1个字节或者4个字节开辟空间的。
3.位段涉及很多不确定的因素,位段是不跨平台的,注意可移植的程序应该避免使用位段。
代码如下(示例):
struct S1
{
char a : 5;//5个位
char b : 2;//2个位
};
int main()
{
struct S1 d = { 0 };
d.a = 10;//00001010--取右边5个位--01010
d.b = 8;//00001000--取右边2个位--00
printf("%d\n", sizeof(d));//1个字节
return 0;
}
```c
上图:
不难看出a,b共用一个字节,位段的好处就在于节省空间