C语言难点专题——enum, struct 和 Union

本文介绍了C语言中常见的几种数据结构,包括枚举(enum)、结构体(struct)和联合体(union)的基本使用方法及注意事项,适合初学者快速掌握。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

C语言常用的几个数据结构, 做一个小总结, 方便查阅:

一: enum

        enum没有任何神奇的地方,仅仅是让某些整数值变得有意义, 比如说, 电源开,用0表示,电源关,用1表示,

那么我们可以定义一个变量open, 和close, 表示电源的开和关。

 

 

         

        在我看来,枚举值应该可以有多个值可选,比如typeA = sencond, third两个值,但似乎暂时没有看到有人这样用,

需要再斟酌一下这个问题。

 

从枚举值引用的关系可以看出,enum列举出的任何变量,都不允许重复定义:

 

         

 

二: struct

 

  • 声明了一个abc的结构。

            struct abc{

              int   score;

            };

 

 

 

  • 定义结构(需要带上struct):

 

            struct abc  a;//实质上是声明 + 初始化

 

            初始化一个结构:

 

             struct abc  a = {14}; 

 

             a = {10};       //wrong 注意不能被两次初始化

 

  • 当const修饰时:

 

            const struct abc  a;

            a.score = 10;     //不容许再次赋值

 

 

三: union

 

<think>好的,用户现在问的是C语言structunion的区别。之前他们问过enum,可能现在在学习C语言数据结构,想要更全面地了解这些复合数据类型的不同之处。首先,我需要回顾structunion的基本定义用法,然后找出它们的关键区别。 用户可能已经知道structunion都是用来组合多个成员的数据类型,但不太清楚它们内在的区别应用场景。需要从内存分配、成员访问、使用场景等方面进行对比。要注意用例子来说明,这样更直观。 struct每个成员都有独立的内存空间,而union的所有成员共享同一块内存。这点很重要,所以内存占用方面struct是各成员之union是最大成员的大小。比如struct里intchar的话,总大小至少是int的大小加上char的大小,再加上可能的对齐填充。而union的话,只占用最大成员的大小,比如intchar的union,大小就是int的大小。 然后成员的访问上,struct可以同时访问所有成员,union同一时间只能有效存储一个成员的值,修改一个成员会影响其他成员的值。比如例子中的union,修改了i之后,f的值就会被覆盖,可能变成无意义的数据。 接下来要考虑用户可能的疑问,比如什么时候用struct,什么时候用unionstruct适合需要同时保存多个相关数据的情况,比如学生的姓名、年龄、成绩。而union适合需要节省内存或者同一时间只使用一个成员的场景,比如处理不同类型的数据或者做类型转换。 另外,对齐方式的不同可能也是需要注意的地方。struct会有对齐填充,而union的对齐取决于最大成员的对齐需求。不过这部分可能对初学者来说稍微复杂,可以简要提及,重点还是放在内存使用成员访问的区别上。 还要提到初始化的问题,struct可以初始化所有成员,而union只能初始化第一个成员。这在C语言的语法中是一个区别点,需要举例说明。 安全性方面,union因为共享内存,如果错误地访问了未赋值的成员,会导致未定义行为,这也是需要注意的地方。而struct每个成员独立,不会有这种问题。 可能用户在实际使用中会遇到如何选择的问题,所以需要给出明确的场景建议。比如网络协议中的数据包,不同字段同时存在用struct,而同一时间只有一种类型的字段用union。 最后总结两者的区别,帮助用户形成清晰的对比表格,方便记忆。同时提醒用户在使用union时要小心数据覆盖的问题,确保正确的成员被访问。</think>好的!C语言中的 `struct`(结构体) `union`(联合体)都是用于组合多个成员变量的复合数据类型,但它们在内存分配、成员访问方式及使用场景上有显著区别。以下是详细的对比分析: --- ### **1. 内存分配方式** | **特性** | **`struct`** | **`union`** | |--------------|---------------------------------------|---------------------------------------| | **内存分配** | 每个成员拥有独立的内存空间 | 所有成员共享同一块内存空间 | | **总大小** | 各成员大小之(考虑内存对齐) | 等于最大成员的大小(考虑内存对齐) | - **示例**: ```c // struct示例:内存总大小 >= sizeof(int)+sizeof(float)+sizeof(char) struct ExampleStruct { int a; // 4字节 float b; // 4字节 char c; // 1字节 }; // 总大小可能为12字节(对齐到4字节边界) // union示例:内存总大小等于最大成员的大小(float的4字节) union ExampleUnion { int i; // 4字节 float f; // 4字节 char c; // 1字节 }; // 总大小为4字节 ``` --- ### **2. 成员访问** | **特性** | **`struct`** | **`union`** | |--------------|---------------------------------------|---------------------------------------| | **访问方式** | 可同时访问所有成员 | 同一时间只有一个成员有效 | | **覆盖风险** | 无 | 修改一个成员可能覆盖其他成员的值 | - **示例**: ```c union Data { int i; float f; }; union Data data; data.i = 10; // 写入int printf("%d\n", data.i); // 输出10 data.f = 3.14; // 覆盖之前存储的int值 printf("%f\n", data.f); // 输出3.14,但data.i的值已被破坏 ``` --- ### **3. 使用场景** | **特性** | **`struct`** | **`union`** | |--------------|---------------------------------------|---------------------------------------| | **典型场景** | 需要同时存储多个相关数据 | 节省内存,或同一时间仅需一个成员有效 | | **例子** | 学生信息(姓名、年龄、成绩) | 网络协议解析、类型转换、硬件寄存器访问 | - **`struct` 适用场景**: ```c struct Student { char name[20]; int age; float score; }; struct Student s = {"Alice", 18, 95.5}; // 同时存储所有字段 ``` - **`union` 适用场景**: ```c // 处理不同类型的数据(如解析二进制协议) union Packet { int intVal; float floatVal; char bytes[4]; }; union Packet p; memcpy(p.bytes, rawData, 4); // 通过不同成员解释同一段内存 ``` --- ### **4. 初始化与赋值** | **特性** | **`struct`** | **`union`** | |--------------|---------------------------------------|---------------------------------------| | **初始化** | 可初始化所有成员 | 只能初始化第一个成员 | | **赋值** | 各成员独立赋值 | 赋值一个成员会影响其他成员的值 | - **初始化示例**: ```c // struct初始化所有成员 struct Point { int x; int y; }; struct Point p1 = {10, 20}; // 合法 // union只能初始化第一个成员 union Value { int i; float f; }; union Value v1 = {5}; // 合法,i=5,f的值未定义 union Value v2 = {.f=3.14}; // C99后允许指定成员初始化 ``` --- ### **5. 安全性对比** | **特性** | **`struct`** | **`union`** | |--------------|---------------------------------------|---------------------------------------| | **类型安全** | 高(成员独立,无覆盖风险) | 低(需开发者确保成员访问逻辑正确) | | **常见错误** | 对齐问题(填充字节导致空间浪费) | 误用成员导致数据覆盖 | --- ### **总结** - **`struct`**: 适用于需要同时存储多个数据的场景,成员之间相互独立,内存占用较大但安全。 典型应用:对象建模(如学生、坐标)、复杂数据结构(链表、树节点)。 - **`union`**: 适用于节省内存或需灵活解释同一段内存的场景,成员共享内存,需谨慎处理覆盖问题。 典型应用:类型转换、硬件寄存器映射、协议解析。 --- ### **关键区别速查表** | **维度** | **`struct`** | **`union`** | |----------------|-----------------------------|----------------------------| | 内存占用 | 各成员大小之 | 最大成员的大小 | | 成员独立性 | 独立 | 共享 | | 初始化 | 可初始化所有成员 | 只能初始化第一个成员 | | 安全性 | 高 | 低(需手动管理覆盖问题) | | 典型用途 | 数据聚合 | 内存复用或类型转换 | 实际开发中,根据需求灵活选择二者:需要同时保留多个字段用 `struct`,需节省内存或类型转换用 `union`。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值