C语言结构体极简教程:重点吃透内存对齐

📅 2026/7/12 18:27:03 👁️ 阅读次数 📝 编程学习
C语言结构体极简教程:重点吃透内存对齐

一、结构体基础

1.1 什么是结构体

结构体(struct)是自定义复合类型,可以把不同类型的数据打包在一起,用来描述一个复杂对象(如学生、用户)。

// 定义结构体类型

struct Student

{ char name[20]; int age; };

1.2 变量创建与初始化

1、创建变量

struct Student s1; // 常用方式

2、初始化方式

struct Student s1 = {"张三", 18}; // 顺序初始化 struct Student s2 = {.age = 20}; // 指定成员初始化(C99)

1.3 成员访问

  • 普通结构体变量:.点运算符

  • 结构体指针:->箭头运算符


二、重点:结构体内存对齐(面试必考)

2.1 核心问题

请看下面代码,请问结构体大小是多少?

struct Test{ char a; // 1字节 int b; // 4字节 };

答案:8字节,不是5字节。

原因:内存对齐,编译器自动填充空洞,并非简单累加字节。

2.2 什么是内存对齐

CPU不会逐字节读取内存,而是整块读取。编译器为了提高CPU读取效率,自动在成员之间补充空闲字节,让数据存放规整,这就是内存对齐。

2.3 内存对齐三大规则(必背)

默认对齐数:8(VS/GCC 默认)

  1. 规则1:第一个成员偏移量为0。

  2. 规则2:后续成员偏移量 =自身大小、默认对齐数较小值的整数倍。

  3. 规则3:结构体总大小 =最大成员、默认对齐数较小值的整数倍。

2.4 手把手推演案例

struct Test{ char a; // 1字节 int b; // 4字节 };
  1. a:偏移0,占用第0字节;

  2. b:自身大小4,偏移量必须是4的倍数;

  3. 补齐1、2、3字节(空洞填充);

  4. b从4开始,占用4~7;

  5. 总大小8,是最大成员4的整数倍,合规。

2.5 成员顺序影响内存大小

// 排布1:空洞大 struct T1{ char a; int b; char c; }; // 占用12字节 // 排布2:空洞小(优化后) struct T2{ char a; char c; int b; }; // 占用8字节

优化原则:把相同字节的成员放在一起。

2.6 手动修改对齐数

嵌入式/网络协议常用,强制压缩内存,消除填充空洞:

#pragma pack(1) // 设置对齐数为1 struct Test{ char a; int b; }; #pragma pack() // 恢复默认对齐

此时结构体大小 =5字节,无多余填充。


三、总结(极简背诵版)

  1. 结构体用来打包不同类型数据;

  2. 访问规则:普通用 . ,指针用 ->

  3. 内存对齐本质:牺牲内存,换CPU读取速度

  4. 熟记三大对齐规则,面试必考;

  5. 优化:相近字节成员集中摆放,减少内存空洞。