news 2026/10/26 18:20:32

C语言结构体详解|结构体定义、变量初始化、内存对齐

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C语言结构体详解|结构体定义、变量初始化、内存对齐

前言

我们之前学的char、int、float这些,都是基础类型,一个变量只能存一个数据。 但现实里很多东西是一组相关数据,比如学生:姓名、年龄、学号、分数。 单独用好几个零散变量存很麻烦,结构体(struct)就是用来把一堆不同类型的数据打包在一起的自定义类型。

一、结构体类型怎么定义

语法格式:

struct 结构体名 { 成员1; 成员2; 成员3; };

举个学生的例子:

// 定义一个学生结构体类型 struct Student { char name[20]; // 姓名 int age; // 年龄 float score; // 分数 };

注意:上面这段代码只是创建了一个新类型,没有开辟内存,没有变量,就像是图纸,不是房子。

二、结构体变量的创建和初始化

方式1:定义结构体之后,单独创建变量

struct Student s1; // 初始化 struct Student s2 = {"zhangsan", 18, 92.5f};

方式2:定义结构体的同时直接创建变量

struct Student { char name[20]; int age; float score; } s3, s4; // s3 s4 就是结构体变量

方式3:匿名结构体(没有结构体名字)

只能在这里直接创建变量,后面不能再新建这个类型的变量

struct { int a; char b; } data;

访问结构体成员:.点操作符

#include <stdio.h> struct Student { char name[20]; int age; float score; }; int main() { struct Student s = {"lisi", 19, 88.0f}; printf("名字:%s 年龄:%d 分数:%.1f\n", s.name, s.age, s.score); return 0; }

运行结果:

名字:lisi 年龄:19 分数:88.0

如果是结构体指针,就用->箭头访问成员,这个后面再拓展,本篇重点是内存对齐。

三、重点:结构体内存对齐

很多人以为结构体大小 = 所有成员大小直接相加,这个想法是错的!CPU读取内存的时候,喜欢按固定块读取,对齐就是为了提升读取效率,代价是浪费一点点空间(填充空白字节,叫填充/补齐padding)。

内存对齐三条核心规则(记住这三条就够)

  1. 结构体第一个成员,放在偏移0的位置(最开头)
  2. 后面每个成员,要对齐到自身大小和默认对齐数里较小值的整数倍地址
  3. 结构体的总大小,必须是结构体最大成员大小的整数倍,不够就在末尾补padding

VS默认对齐数是8,Linux gcc默认对齐数也是8

例子1:简单结构体,画图讲解

struct Test1 { char c; // 1字节 int i; // 4字节 };

我们来一步步算,画内存格子(一个格子代表1字节)

地址: 0 1 2 3 4 5 6 7 数据:[c] 空 空 空 [i0][i1][i2][i3]
  • c放在0号地址,占1字节

  • int占4字节,它要放在4的倍数地址,下一个可用地址是1,不是4倍数,所以1、2、3填充空白padding

  • i从地址4开始,占4字节,到7结束

  • 最大成员是int(4字节),总大小要4的倍数,现在一共8字节,刚好满足

sizeof(struct Test1) = 8,不是 1+4=5!

代码验证:

#include <stdio.h> struct Test1 { char c; int i; }; int main() { printf("%zd\n", sizeof(struct Test1)); // 输出 8 return 0; }

例子2:换一下成员顺序,大小直接变了!

struct Test2 { int i; // 4字节 char c; // 1字节 };

内存排布:

地址: 0 1 2 3 4 5 6 7 数据:[i0][i1][i2][i3] [c] 空 空 空
  • int从0开始,占0~3

  • char放地址4,占1字节

  • 最大成员是4字节,总大小必须是4倍数,现在5字节,后面补3个空字节,凑到8

sizeof(struct Test2) = 8

小结论:调整成员顺序,可以减少内存浪费!

例子3:再复杂一点的组合

struct Test3 { char a; // 1 short b; // 2 int c; // 4 };

内存排布:

0:[a] 1:空 2:[b0][b1] 4:[c0][c1][c2][c3]
  • a在0

  • short是2字节,要放到2的倍数地址,地址1不行,地址2可以,1位置补padding

  • int放到4的倍数地址4

  • 总大小8,刚好是最大成员4的倍数 ✅ sizeof = 8 总和直接相加 1+2+4=7,对齐之后变成8

例子4:嵌套结构体对齐(拓展了解)

规则不变,嵌套的结构体,对齐数取它内部最大成员的大小

struct Inner { char ch; int num; }; struct Outer { char x; struct Inner in; };

Inner大小是8,Inner最大成员是4。 in成员要对齐到4的倍数地址。 x在0,1、2、3补padding,in从4开始放,总大小 4+8=12。

四、修改默认对齐数(#pragma pack)

我们可以手动改对齐数,用来省空间,在一些硬件开发里经常用到。

#pragma pack(1) // 设置对齐数为1,关闭对齐,不补padding struct Test { char c; int i; }; #pragma pack() // 恢复默认对齐

pack(1)的时候,上面这个结构体大小就是5,不会补空字节。 不推荐随便改,会降低CPU访问速度,只有特殊场景才用。

五、小结

  1. struct结构体,是C给我们自定义打包数据的工具,把一堆不同类型成员放一起。

  2. 结构体变量创建有三种写法,.访问成员,指针用->。

  3. 结构体大小不能直接成员相加,要遵守三条对齐规则,中间和末尾会填充空白字节padding。

  4. 成员顺序会影响结构体占用内存大小,合理排序可以节省内存。

  5. #pragma pack可以修改对齐数,慎用。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/26 18:19:52

重温STM32基础:定时器(9)- 输入捕获电路和测频方法

文章目录输入捕获简介通用定时器电路概览&#xff1a;输入捕获电路在哪儿&#xff1f;定义STM32F103输入捕获资源分布可配置模式频率测量频率测量方法测频法测周法两种方法比较中介频率代码实现preview输入捕获具体电路分析预告摘要&#xff1a;本文围绕 STM32 定时器的输入捕获…

作者头像 李华
网站建设 2026/10/26 18:17:53

掌握LLM Agent 6大规划范式,成为大厂抢手未来超级架构师!

本文系统梳理了LLM Agent的6大核心规划范式&#xff0c;包括CoT、Self-Consistency、ToT、GoT、Plan-and-Execute、ReAct&#xff0c;并深入分析了它们各自的原理、优缺点和适用场景。同时&#xff0c;文章还探讨了推理层规划与执行层规划的区分&#xff0c;以及如何将它们进行…

作者头像 李华
网站建设 2026/10/26 18:17:08

有音频怎么让数字人对口型:2026音频驱动数字人教程,5款横评实测

有音频怎么让数字人对口型&#xff0c;是短视频矩阵团队与知识博主在批量出片时常遇到的卡点。音频驱动数字人是指通过上传已有录音或配音文件&#xff0c;由 AI 自动生成口型、表情与头部动作匹配的数字人口播视频。鲸剪&#xff08;WhaleClip&#xff09;是一款面向短视频创作…

作者头像 李华
网站建设 2026/10/26 18:15:18

小白程序员如何抓住AI机遇,轻松实现月薪过万?|收藏必备

文章通过对比不同行业薪资涨幅&#xff0c;指出程序员&#xff0c;尤其是AI领域程序员的高薪潜力。强调选对赛道的重要性&#xff0c;并指出AI人才缺口大&#xff0c;企业需求多&#xff0c;为普通人提供了抓住机遇的良机。 先问大家几个问题&#xff1a;你现在工龄几年&#x…

作者头像 李华
网站建设 2026/10/26 18:12:10

PV/PVC 一直 Pending:StorageClass 与绑定条件的 4 个检查点

我不会起名字322 后端 / 算法 / 数据库 &#x1f4d8; 技术栈 &#xff5c; &#x1f9e9; 力扣 Hot100 &#xff5c; &#x1f439; Go 项目 &#xff5c; &#x1f7e5; Redis &#xff5c; &#x1f42c; MySQL 文章目录PV/PVC 一直 Pending&#xff1a;StorageClass 与绑定…

作者头像 李华