目录
一、结构体内存对齐问题(节省时间)
1.什么是内存对齐
2.需要使用内存对齐的原因
3.内存对齐的规则
4.举例
5.小结
二、结构体实现位段操作(节省空间)
1.位域简介与使用原因
2.位域的定义与使用时的注意事项
3.举例
4.工程应用
一、结构体内存对齐问题(节省时间)
1.什么是内存对齐
内存对齐(Memory Alignment)是指编译器将结构体的每个成员放置在内存中特定位置的过程,以提高CPU访问内存的效率。它会在成员之间插入“填充字节”(padding),使得每个成员的起始地址满足一定的对齐要求。
2.需要使用内存对齐的原因
-
硬件要求:许多CPU架构(如RISC、x86)要求特定类型的数据必须存放在特定地址上,否则会引发硬件异常(如总线错误)或性能急剧下降。例如,32位CPU通常要求int类型的数据地址是4的倍数。
-
访问效率:即使某些CPU允许非对齐访问(如x86),但访问对齐的数据通常更快(可能一次内存访问即可完成,而非对齐可能需要两次内存访问并拼接数据)。
-
原子性保证:对齐的数据可以保证原子操作(在某些平台上),非对齐可能导致操作被拆分。
3.内存对齐的规则
- 确定起点:结构体的第一个成员对齐到和结构体变量起始位置偏移量为0的地址处
- 确定其他成员对齐位置:其他成员变量要对齐到对齐数的整数倍的地址处(对齐数:编译器默认的⼀个对齐数与该成员变量大小的较小值。VS 编辑器中默认的对齐数为 8,Linux中gcc没有默认对齐数,对齐数就是成员自身的大小)
- 确定总大小:结构体总大小为最大对齐数(结构体中每个成员变量都有一个对齐数,所有对齐数中最大的)的整数倍
- 嵌套问题:如果嵌套了结构体的情况,嵌套的结构体成员对齐到自己的成员中最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体中成员的对齐数)的整数倍。
4.举例


5.小结
在设计结构体的时候,我们既要满足对齐,又要节省空间,那么就要让占用空间小的成员尽量集中在⼀起
二、结构体实现位段操作(节省空间)
1.位域简介与使用原因
位域允许我们将结构体成员按位(bit)分配空间,适用于需要精确控制位数、节省内存的场景(如硬件寄存器、网络协议头等)
2.位域的定义与使用时的注意事项
定义:在成员后加冒号和位数
struct Flags {
unsigned int a : 1; // a 占1位
unsigned int b : 2; // b 占2位
unsigned int c : 3; // c 占3位
};
注意事项:
-
位域成员必须是无符号或有符号整数类型(int、unsigned int等)。
-
不能对位域成员取地址(&)。
struct A
{
int _b : 5;
int _c : 10;
int _d : 30;
};int main()
{
struct A sa = {0};
//错误示范
scanf("%d", &sa._b);//正确的示范
int b = 0;
scanf("%d", &b);
sa._b = b;
return 0;
} -
位域的总位数不能超过底层类型的位数(通常为 unsigned int 的位数,如32位)。
-
位段中的成员在内存中从左向右分配,还是从右向左分配,标准尚未定义。
-
当一个结构包含两个位段,第二个位段成员比较大,无法容纳于第一个位段剩余的位时,是舍弃剩余的位还是利用,标准尚未定义。
3.举例

4.工程应用
网络协议中,IP数据报的格式,我们可以看到其中很多的属性只需要几个bit位就能描述,这里使用位段,能够实现想要的效果,也节省了空间,这样网络传输的数据报大小也会较小一些,对网络的畅通是有帮助的。





