C语言结构体与共同体(联合体)学习笔记

发布时间:2026/10/10 2:15:04

C语言结构体与共同体(联合体)学习笔记 1. 引言今天学习了 C 语言中的结构体struct和共同体union也叫联合体这是 C 语言中非常重要的复合数据类型。结构体让我们能把不同类型的数据打包成一个整体而共同体则让多个成员共享同一块内存。这篇笔记记录一下今天的学习心得和关键知识点。2. 结构体struct结构体是一种用户自定义的复合数据类型它把若干个不同类型的成员组合在一起形成一个整体。2.1 定义与声明structStudent{charname[20];intage;floatscore;};定义结构体后就可以用它来声明变量structStudentstu1;structStudentstu2{张三,18,89.5};2.2 访问成员通过点运算符.访问结构体变量的成员printf(姓名%s\n,stu1.name);stu1.age19;2.3 结构体数组结构体也可以作为数组的元素structStudentclass[50];class[0].age18;2.4 结构体指针用指针访问结构体成员时使用箭头运算符-structStudent*pstu1;p-age20;// 等价于 (*p).age 20;2.5 结构体大小与内存对齐结构体的大小并不一定等于所有成员大小之和因为存在内存对齐机制。内存对齐是编译器为了提高 CPU 访问内存的效率而采取的一种策略CPU 读取内存时按固定字节数如 4 字节或 8 字节进行如果数据没有对齐可能需要多次读取才能取到完整数据。2.5.1 对齐规则内存对齐遵循以下几条核心规则每个成员都有自己的对齐数成员的对齐数等于其自身大小如char为 1int为 4double为 8但不超过编译器的默认对齐数如 32 位下默认 464 位下默认 8。成员存放的起始地址必须是对齐数的整数倍编译器会在成员之间插入填充字节padding来满足这一要求。结构体总大小必须是对齐数的整数倍结构体末尾也可能有填充字节以保证结构体数组相邻元素也能对齐。结构体的对齐数取所有成员对齐数的最大值。2.5.2 示例分析structExample{chara;// 1 字节对齐数 1intb;// 4 字节对齐数 4};在 32 位系统上sizeof(struct Example)通常是 8 而不是 5a占第 0 字节b需要从 4 的整数倍地址开始因此第 1~3 字节被填充b占第 4~7 字节总大小为 8正好是最大对齐数 4 的整数倍。2.5.3 成员顺序影响大小成员顺序不同结构体大小也可能不同structOrder1{charc;// 1 字节inti;// 4 字节chard;// 1 字节};// sizeof(struct Order1) 12structOrder2{inti;// 4 字节charc;// 1 字节chard;// 1 字节};// sizeof(struct Order2) 8Order1中int需要对齐c后填充 3 字节末尾再填充 3 字节而Order2把int放前面两个char紧挨着只填充 2 字节。因此把占用空间大的成员放在前面可以减小结构体大小。#includestddef.h#includestdio.hintmain(){printf(a 的偏移%zu\n,offsetof(structExample,a));// 0printf(b 的偏移%zu\n,offsetof(structExample,b));// 4printf(结构体大小%zu\n,sizeof(structExample));// 8return0;}3. 共同体union共同体是一种特殊的复合数据类型它的所有成员共享同一块内存空间。共同体的大小等于最大成员的大小同一时刻只能有一个成员的值是有效的。3.1 定义与声明unionData{inti;floatf;charstr[20];};定义共同体后就可以用它来声明变量unionData data;data.i10;// 此时 data 中有效的是 int 成员data.f3.14;// 写入 float 会覆盖之前的 int 值3.2 共同体的大小共同体的大小等于最大成员的大小printf(%zu\n,sizeof(unionData));// 输出 20即最大成员 str 的大小3.3 结构体与共同体的区别3.3 结构体与共同体的区别对比项结构体 struct共同体 union内存分配各成员独立分配内存所有成员共享一块内存大小约等于各成员大小之和含对齐填充等于最大成员的大小成员有效性所有成员同时有效同一时刻只有一个成员有效典型用途描述一个对象的多个属性节省内存、类型转换、协议解析4. 典型应用场景4.1 结构体学生信息管理下面用一个更完整的案例综合运用结构体数组、结构体指针、函数传参和内存对齐等知识点实现一个简单的学生成绩管理系统#includestdio.h#includestring.h#defineMAX_STUDENTS50structStudent{charname[20];intage;floatscore;};// 录入一个学生信息通过指针修改结构体voidinputStudent(structStudent*stu){printf(请输入姓名);scanf(%s,stu-name);printf(请输入年龄);scanf(%d,stu-age);printf(请输入成绩);scanf(%f,stu-score);}// 打印一个学生信息voidprintStudent(conststructStudent*stu){printf(姓名%s年龄%d成绩%.1f\n,stu-name,stu-age,stu-score);}// 计算全班平均分floataverageScore(conststructStudentclass[],intn){floatsum0;for(inti0;in;i){sumclass[i].score;}returnn0?sum/n:0;}// 找出最高分学生返回其下标intfindTopStudent(conststructStudentclass[],intn){inttop0;for(inti1;in;i){if(class[i].scoreclass[top].score){topi;}}returntop;}intmain(){structStudentclass[MAX_STUDENTS];intcount0;// 录入 3 名学生for(inti0;i3;i){printf(录入第 %d 名学生\n,i1);inputStudent(class[i]);count;printf(\n);}// 打印所有学生printf( 学生名单 \n);for(inti0;icount;i){printStudent(class[i]);}// 统计信息printf(\n 统计信息 \n);printf(全班平均分%.1f\n,averageScore(class,count));inttopfindTopStudent(class,count);printf(最高分学生);printStudent(class[top]);printf(\n结构体大小%zu 字节\n,sizeof(structStudent));return0;}这个案例把前面学到的知识点串了起来结构体数组class[50]用来存储多个学生结构体指针作为函数参数避免拷贝整个结构体提高效率const修饰表示函数只读不改防止误修改数据sizeof查看结构体实际占用内存体会内存对齐的影响。运行效果示例录入第 1 名学生 请输入姓名张三 请输入年龄18 请输入成绩89.5 录入第 2 名学生 请输入姓名李四 请输入年龄20 请输入成绩92.5 录入第 3 名学生 请输入姓名王五 请输入年龄19 请输入成绩78 学生名单 姓名张三年龄18成绩89.5 姓名李四年龄20成绩92.5 姓名王五年龄19成绩78.0 统计信息 全班平均分86.7 最高分学生姓名李四年龄20成绩92.5 结构体大小28 字节4.2 共同体判断大小端共同体常用来检测系统的大小端字节序#includestdio.hunionEndian{inti;charc;};intmain(){unionEndian e;e.i1;if(e.c1){printf(小端序\n);}else{printf(大端序\n);}return0;}5. 总结今天主要掌握了结构体把不同类型的数据组合成一个整体成员各自独立占用内存共同体让多个成员共享内存节省空间但同一时刻只有一个成员有效结构体常用于描述对象的多个属性共同体常用于节省内存和底层数据处理结构体存在内存对齐机制计算大小时要注意填充字节。结构体和共同体是 C 语言中非常实用的复合类型后续在链表、文件读写、网络协议解析等场景中还会大量用到值得反复练习巩固。
延伸阅读

更多相关文章

2026/10/10 2:10:04

思科ACI APIC手动安装与离线升级实战指南

简介:本资源是一份面向网络工程师与ACI初学者的思科APIC手动安装与跨版本升级实战指南,聚焦实验环境中绕过原厂TAC支持、纯自主完成系统重装与2.2→4.2→5.x多阶段升级的完整路径。内容直击vKVM引导卡死、TPM激活失效、RAID引导盘错配、HTTP镜像上传失败…

2026/10/10 2:10:04

SpringBoot整合MyBatis实战:从依赖配置到动态SQL与事务避坑指南

简介:一份面向Java开发者的Spring Boot与MyBatis整合实战指南,适合正在搭建持久层、或需要快速上手XML Mapper配置的中级程序员阅读。资源以PDF文档形式,从pom.xml引入mybatis、mybatis-spring及MySQL驱动等依赖开始,依次讲解在ap…

2026/10/10 3:20:10

WaveDrom编辑器v2.3.2:用文本描述时序图,支持Git版本管理

简介:Wavedrom Editor v2.3.2 Windows 64位版是一款面向FPGA开发者与电子工程师的本地时序图绘制工具,适合需要离线绘图、快速生成信号波形图的用户。它基于简洁的文本语法描述波形,支持上升沿、下降沿、脉冲、注释与颜色标注,并提…

2026/10/10 3:20:10

jxbrowser-7.19 实战:Java 桌面端内嵌 Chromium 浏览器完整指南

简介:这份资源是 jxbrowser-7.19 全系组件包,面向需要在 Java 桌面应用中嵌入浏览器内核的开发者,尤其适合使用 Swing、SWT、JavaFX 等界面框架、希望快速集成 Chromium 渲染能力的中高级工程师。压缩包共 1359 个文件,以 1345 个…

2026/10/10 3:20:10

Flutter CustomPainter在OpenHarmony上做小游戏渲染的实践与优化

最近在做一个小游戏Demo,把Flutter的CustomPainter渲染管线跑在了OpenHarmony设备上,算是把自定义绘制玩明白了。Flutter本身是UI框架,但它的CustomPainter暴露了底层Canvas能力,做轻量级游戏画面渲染完全能胜任,尤其适…

2026/10/10 3:20:10

SpringBoot3多数据源实战:从选型配置到避坑指南

做后端这些年,只要业务稍微复杂一点,“一个应用连一个库”的理想状态基本撑不住。用户数据放用户库、订单数据放订单库、日志又要独立一套,再加上读写分离和多租户隔离的需求,所有问题都指向同一个核心:一个SpringBoot…

2026/10/10 3:15:10

Flutter for OpenHarmony 多语言切换实战:从资源管理到系统适配

做了这么久跨端开发,接到“Flutter for OpenHarmony 教育百科”这种项目时,我第一反应不是技术栈能不能跑通,而是“语言切换”这种看似基础的功能,在鸿蒙生态里到底要趟多少坑。教育百科这个场景很典型:词条多、分类杂…

2026/10/8 10:03:18

Jev+Agent接管浏览器:browser-use实战与jev-ultrafast性能优化

1. 从“Jev”说起:为什么我要把Agent接进浏览器“Jev”这个词最近在圈子里出现的频率越来越高,很多人第一次听到会以为是某个新模型的名字,其实它更像是一种思路——把Jev模型的能力当作底座,通过Agent的方式去接管浏览器&#xf…

2026/10/9 20:15:56

多智能体集群实战:DeepAgents编排、MCP与A2A协议及Skills体系

1. 从"单兵作战"到"集群协同":多智能体编排到底在解决什么问题如果你最近在折腾 Agent 相关的东西,大概率会有一种感觉:单个 Agent 能做的事情,其实很快就摸到天花板了。你给它一个提示词,挂几个工…

2026/10/8 6:05:44

无源低通滤波器设计实战:从RC到LC,手把手教你避开那些坑

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 0:04:53

从逻辑门到计算机:数字电路核心原理与全加器搭建实战

如果你拆过一台旧电脑的主板,盯着那些黑乎乎的小芯片看上一会儿,可能会冒出同一个疑问:这堆引脚密集的元件,到底是怎么“变”出那么复杂的应用的?答案并不在某个神秘的部件里,而是在所有芯片内部都在反复使…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑