跳转到内容
主菜单
主菜单
移至侧栏
隐藏
导航
首页
最近更改
随机页面
MediaWiki帮助
代码酷
搜索
搜索
中文(中国大陆)
外观
创建账号
登录
个人工具
创建账号
登录
未登录编辑者的页面
了解详情
贡献
讨论
编辑“︁
C 语言联合应用
”︁(章节)
页面
讨论
大陆简体
阅读
编辑
编辑源代码
查看历史
工具
工具
移至侧栏
隐藏
操作
阅读
编辑
编辑源代码
查看历史
常规
链入页面
相关更改
特殊页面
页面信息
外观
移至侧栏
隐藏
您的更改会在有权核准的用户核准后向读者展示。
警告:
您没有登录。如果您进行任何编辑,您的IP地址会公开展示。如果您
登录
或
创建账号
,您的编辑会以您的用户名署名,此外还有其他益处。
反垃圾检查。
不要
加入这个!
= C语言联合应用 = == 简介 == '''联合(Union)'''是C语言中一种特殊的数据类型,允许在同一内存位置存储不同的数据类型。与结构体(struct)不同,联合的所有成员共享同一块内存空间,因此同一时间只能存储其中一个成员的值。联合的大小由其最大的成员决定。 联合的主要应用场景包括: * 节省内存空间(尤其在嵌入式系统中) * 实现多类型数据存储(如解析网络协议或文件格式) * 类型转换(通过不同成员访问同一数据) == 基本语法 == 联合的定义方式与结构体相似,使用<code>union</code>关键字: <syntaxhighlight lang="c"> union UnionName { member_type1 member1; member_type2 member2; // ... }; </syntaxhighlight> == 内存布局 == <mermaid> graph TD A[union Data] --> B[int i] A --> C[float f] A --> D[char str[20]] style A fill:#f9f,stroke:#333 style B fill:#bbf,stroke:#333 style C fill:#bbf,stroke:#333 style D fill:#bbf,stroke:#333 </mermaid> 上图中,联合<code>Data</code>的三个成员<code>i</code>、<code>f</code>和<code>str</code>共享同一内存空间,其大小为最大成员(此处为<code>str[20]</code>)的大小。 == 代码示例 == === 基本使用 === <syntaxhighlight lang="c"> #include <stdio.h> #include <string.h> union Data { int i; float f; char str[20]; }; int main() { union Data data; data.i = 10; printf("data.i : %d\n", data.i); data.f = 220.5; printf("data.f : %f\n", data.f); strcpy(data.str, "C Programming"); printf("data.str : %s\n", data.str); return 0; } </syntaxhighlight> '''输出:''' <pre> data.i : 10 data.f : 220.500000 data.str : C Programming </pre> '''注意:''' 最后一次赋值会覆盖之前的值,因为所有成员共享内存。 === 类型转换应用 === 联合可用于实现低级别的类型转换: <syntaxhighlight lang="c"> #include <stdio.h> union Converter { float f; unsigned int u; }; int main() { union Converter conv; conv.f = 3.14f; printf("Float value: %f\n", conv.f); printf("Binary representation: 0x%08X\n", conv.u); return 0; } </syntaxhighlight> '''输出:''' <pre> Float value: 3.140000 Binary representation: 0x4048F5C3 </pre> == 实际应用案例 == === 协议解析 === 在网络协议中,联合常用于解析不同格式的数据包: <syntaxhighlight lang="c"> #include <stdio.h> union IPAddress { unsigned int address; unsigned char octets[4]; }; int main() { union IPAddress ip; ip.address = 0xC0A80101; // 192.168.1.1 printf("IP in hex: 0x%08X\n", ip.address); printf("Dotted format: %d.%d.%d.%d\n", ip.octets[3], ip.octets[2], ip.octets[1], ip.octets[0]); return 0; } </syntaxhighlight> '''输出:''' <pre> IP in hex: 0xC0A80101 Dotted format: 192.168.1.1 </pre> === 硬件寄存器访问 === 在嵌入式系统中,联合常用于访问硬件寄存器: <syntaxhighlight lang="c"> typedef union { struct { unsigned int enable : 1; unsigned int mode : 3; unsigned int reserved : 28; } bits; unsigned int word; } ControlRegister; void setup_hardware() { ControlRegister cr; cr.word = 0; // 初始化 cr.bits.enable = 1; cr.bits.mode = 5; printf("Register value: 0x%08X\n", cr.word); } </syntaxhighlight> == 联合与结构体的区别 == {| class="wikitable" |- ! 特性 !! 联合 !! 结构体 |- | 内存使用 || 共享内存 || 独立内存 |- | 大小 || 最大成员的大小 || 所有成员大小之和(考虑对齐) |- | 同时访问 || 只能访问一个成员 || 可同时访问所有成员 |} == 数学表示 == 联合的内存分配可以表示为: <math> \text{sizeof}(union) = \max(\text{sizeof}(member_1), \text{sizeof}(member_2), \ldots, \text{sizeof}(member_n)) </math> == 注意事项 == * 联合不能包含引用类型的成员(如指针指向的数据不共享) * 使用联合进行类型转换可能引发未定义行为(取决于平台) * 匿名联合(C11特性)可以直接访问成员 * 联合常用于实现变体类型(variant type) == 高级应用:标签联合 == 结合结构体和枚举实现类型安全的联合: <syntaxhighlight lang="c"> #include <stdio.h> typedef enum { INT, FLOAT, STR } Type; typedef struct { Type type; union { int i; float f; char s[20]; } value; } Variant; void print_variant(Variant v) { switch(v.type) { case INT: printf("INT: %d\n", v.value.i); break; case FLOAT: printf("FLOAT: %f\n", v.value.f); break; case STR: printf("STR: %s\n", v.value.s); break; } } int main() { Variant v1 = { .type = INT, .value.i = 42 }; Variant v2 = { .type = FLOAT, .value.f = 3.14f }; print_variant(v1); print_variant(v2); return 0; } </syntaxhighlight> '''输出:''' <pre> INT: 42 FLOAT: 3.140000 </pre> == 总结 == 联合是C语言中强大的特性,特别适用于: * 内存敏感型应用 * 底层硬件编程 * 数据格式转换 * 实现多态数据结构 正确使用联合需要充分理解其内存共享特性,避免意外覆盖数据。结合结构体和枚举可以实现更安全、更高级的编程模式。 [[Category:编程语言]] [[Category:C]] [[Category:C 语言结构体与联合]]
摘要:
请注意,所有对代码酷的贡献均被视为依照知识共享署名-非商业性使用-相同方式共享发表(详情请见
代码酷:著作权
)。如果您不希望您的文字作品被随意编辑和分发传播,请不要在此提交。
您同时也向我们承诺,您提交的内容为您自己所创作,或是复制自公共领域或类似自由来源。
未经许可,请勿提交受著作权保护的作品!
取消
编辑帮助
(在新窗口中打开)