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):通过共用体观察同一段二进制数据的不同解释方式(例如查看浮点数的位模式)。

相关推荐
荒诞硬汉1 分钟前
面向对象(三)
java·开发语言
郝学胜-神的一滴3 分钟前
深入理解Linux中的Try锁机制
linux·服务器·开发语言·c++·程序人生
liliangcsdn3 分钟前
bash中awk如何切分输出
开发语言·bash
无限码力4 分钟前
华为OD机试真题双机位C卷 【运维日志排序】C语言实现
c语言·华为od·华为od机考·华为od机试真题·华为od机试双机位c卷·华为od机考双机位c卷·华为od上机考试
菜鸟233号9 分钟前
力扣416 分割等和子串 java实现
java·数据结构·算法·leetcode
csbysj20209 分钟前
JSON.parse() 方法详解
开发语言
奔波霸的伶俐虫12 分钟前
redisTemplate.opsForList()里面方法怎么用
java·开发语言·数据库·python·sql
Swift社区14 分钟前
LeetCode 469 凸多边形
算法·leetcode·职场和发展
chilavert31817 分钟前
技术演进中的开发沉思-298 计算机原理:算法的本质
算法·计算机原理
小郭团队22 分钟前
未来PLC会消失吗?会被嵌入式系统取代吗?
c语言·人工智能·python·嵌入式硬件·架构