C语言---共用体

在C语言中,共用体(Union),也称为联合体,是一种特殊的数据类型,允许在相同的内存位置存储不同的数据类型。

1. 定义与语法

共用体的定义方式与结构体(struct)类似,使用 union 关键字:

bash 复制代码
// 先定义模板,再声明变量
union Data {
    int i;
    float f;
    char str[20];
};

// 定义模板的同时声明变量
union Data {
    int i;
    float f;
} data1, data2;

// 使用 typedef 起别名
typedef union {
    int i;
    float f;
} Value;

Value v1; // 直接使用别名声明

2. 调用与访问方式

2.1、 访问成员(使用点运算符 .)

这是最直接的访问方式,用于普通的共用体变量。

2.2、通过指针访问(使用箭头运算符 ->)

当使用指向共用体的指针时,必须使用 ->。

bash 复制代码
union Data data;
union Data *ptr = &data;

ptr->i = 100;     // 等价于 (*ptr).i = 100;
printf("%d", ptr->i);

2.3、初始化方式

共用体在初始化时,通常只能初始化它的第一个成员。

bash 复制代码
union Data data = {10}; // 正确:初始化了第一个成员 i
// union Data data = {10, 2.5}; // 错误:共用体不能同时初始化多个成员

在 C99 标准中,可以使用"指定初始化器"来初始化特定成员:

bash 复制代码
union Data data = {.f = 1.23f}; 

3. 核心特点

共享内存:共用体中的所有成员都从同一个内存地址开始存储。

内存占用:共用体占用的内存大小等于其最大成员的大小(有时需要考虑内存对齐)。

互斥使用:在同一时刻,只能存储和使用其中一个成员的值。给一个新成员赋值会覆盖掉之前成员的值。

4. 共用体 vs 结构体

特性 结构体 (struct) 共用体 (union)
内存分配 每个成员都有独立的内存空间 所有成员共享同一块内存空间
总大小 所有成员大小之和(含对齐) 最大成员的大小(含对齐)
成员访问 可同时访问所有成员 同一时间只能有效访问一个成员

5. 代码示例

bash 复制代码
#include <stdio.h>
#include <string.h>

union Data {
    int i;
    float f;
    char str[20];
};

int main() {
    union Data data;

    printf("Memory size occupied by data: %lu\n", sizeof(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);

    // 此时访问 i 和 f 会得到错误的结果,因为内存已被 str 覆盖
    printf("data.i after str: %d\n", data.i);

    return 0;
}

6. 主要应用场景

节省内存:当程序中有多个变量但它们不会同时被使用时。

硬件寄存器访问:在嵌入式开发中,常用于将一个长字(word)拆分为多个字节(byte)进行访问。

类型转换(Type Punning):通过共用体观察同一段二进制数据的不同解释方式(例如查看浮点数的位模式)。

相关推荐
another heaven6 分钟前
【C/C++ Ranges 是零开销抽象吗?拆开管道、惰性求值和编译期膨胀】
c语言·开发语言·c++
Code_Solitude9 分钟前
C语言动态内存 + 柔性数组 + 数组名退化
c语言·算法·柔性数组
上海潭龙东海科技有限公司15 分钟前
客运站管控之动态孪生技术方案(新增一屏管控模块
数据仓库·人工智能·算法·重构·动态规划
SomeOtherTime2 小时前
Rust 闭包语法和原理(AI回答)
开发语言·后端·rust
apcipot_rain2 小时前
C++转Java日记(10)
java·开发语言
总要学点什么2 小时前
第105篇:三维特效-流动图片墙体效果——让箭头沿墙长滚,它俩竟是同一份代码
开发语言·javascript·ecmascript·gis·webgl·材质·cesium
YLCHUP3 小时前
【思维&图论建模】题解:债权(debt)_图论_建模_思路转化_思维题目_C++算法竞赛
c++·笔记·算法·数学建模·贪心算法·深度优先·图论
xiaoye-duck3 小时前
《C++ 项目:手写大模型接入 SDK》会话模块整合:内存 SessionManager 与 DataManager 持久化联动
开发语言·数据库·c++·语言模型
思麟呀3 小时前
背包DP(01背包+完全背包)
c++·算法
Zwawa4 小时前
让屏幕动起来:OLED动画效果,丝滑光标、帧动画和一只贪吃蛇
c语言·单片机·嵌入式