19. C语言 共用体(Union)详解

本章目录


前言

在C语言中,共用体(union)是一种特殊的复合数据类型,与结构体(struct)类似,但具备独特的内存共享特性。本文将从共用体的基本概念入手,结合读者笔记中的见解,深入探讨共用体的使用方法、内存布局及实际应用场景,帮助读者掌握这一高效的数据结构。


1. 什么是共用体?

共用体是一种允许多个成员共享同一块内存空间的数据结构。在任何时刻,共用体的所有成员只能有一个成员存储有效数据。这种特性使得共用体特别适合在需要节省内存的场景下使用。

共用体与结构体的区别

特性 结构体 (struct) 共用体 (union)
内存分配 每个成员分配独立的内存空间 所有成员共享同一块内存空间
占用内存大小 所有成员的内存大小之和 最大成员的内存大小
成员访问 可以同时访问多个成员 只能在任一时间访问一个成员

2. 定义共用体

共用体的定义语法类似于结构体,但成员共享内存。例如:

c 复制代码
union Data {
    int i;       // 占用4字节
    float f;     // 占用4字节
    char str[20]; // 占用20字节
};

在这里,Data共用体的大小为其最大成员(char str[20])的大小,即20字节。

示例:定义共用体变量

共用体定义后,可以通过以下方式声明变量:

c 复制代码
union Data data;      // 定义单个变量
union Data dataArr[5]; // 定义共用体数组

可以使用typedef简化定义:

c 复制代码
typedef union {
    int i;
    float f;
    char str[20];
} Data;

Data data; // 定义共用体变量

3. 共用体的内存布局和对齐规则

内存大小计算

共用体的内存大小取决于其最大成员的大小。例如:

c 复制代码
union Example {
    char c;        // 1字节
    double d;      // 8字节
};

此共用体的大小为8字节,因为double占用的空间最大。

字节对齐

内存对齐规则会影响共用体的实际大小。例如:

c 复制代码
union AlignedData {
    char c;        // 1字节
    double d;      // 8字节
    char str[9];   // 9字节
};

在大多数编译器中,该共用体会占用16字节,因对齐规则要求以8字节对齐。

内存对齐原则
  1. 数据成员对齐 :每个成员的对齐规则为其自身大小与#pragma pack指定值的较小者。
  2. 共用体整体对齐 :以最大成员大小与#pragma pack指定值的较小者对齐。
  3. 结构体嵌套对齐:嵌套结构体的对齐以其内部最大成员的对齐要求为准。

4. 访问共用体成员

示例:基本访问

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;
}

注意:由于共用体成员共享内存,修改一个成员会覆盖其他成员的值。因此,共用体应在任何时刻仅使用一个成员。


5. 共用体的实际应用场景

场景1:节省内存

如果有两个结构体,分别表示教师和学生信息,而两者不会同时使用,共用体可以节省内存开销:

c 复制代码
union Person {
    struct {
        char name[20];
        int teacherID;
    } teacher;

    struct {
        char name[20];
        int studentID;
    } student;
};

此共用体的大小为name[20]studentID(或teacherID)总大小的最大值,而非两者之和。

场景2:网络通信数据包解析

通信协议中,接收的数据包可能有多种格式。使用共用体,可以根据实际格式解析数据:

c 复制代码
union Packet {
    struct {
        int id;
        char message[50];
    } text;

    struct {
        int id;
        float value;
    } sensorData;
};

场景3:判断系统是大端还是小端

利用共用体的内存共享特性,可以方便地判断系统的字节序:

c 复制代码
#include <stdio.h>

union CheckEndian {
    int data;
    char byte;
};

int main() {
    union CheckEndian check;
    check.data = 0x01020304;

    if (check.byte == 0x01) {
        printf("Big-endian system\n");
    } else {
        printf("Little-endian system\n");
    }

    return 0;
}

6. 高效使用共用体的技巧

  1. 只在成员互斥使用时选择共用体

    共用体适用于明确知道同时只会使用一个成员的场景。

  2. 注意字节对齐问题

    使用共用体时,确保对齐规则与平台一致,避免未定义行为。

  3. 结合结构体实现复杂数据结构

    在共用体中嵌套结构体,可灵活处理不同数据格式。


总结

共用体是C语言中功能强大的数据结构,通过共享内存实现了高效的数据管理。本文从共用体的定义、内存模型到高级应用场景,全面解析了这一概念。了解并掌握共用体的使用,可以帮助开发者在内存敏感的场景中设计更高效的程序。希望本文对您有所帮助!


相关推荐
埃伊蟹黄面10 分钟前
深入理解STL关联容器:map/multimap与set/multiset全解析
开发语言·c++
Python算法实战17 分钟前
平安大模型面试题:Self-Attention 原理与多头注意力设计
人工智能·算法·自然语言处理·大模型·面试题
可观测性用观测云22 分钟前
云原生架构下微服务接入 SkyWalking 最佳实践
java
Python算法实战33 分钟前
腾讯送命题:手写多头注意力机制。。。
人工智能·算法·面试·大模型·强化学习
dot to one35 分钟前
Centos 7 环境下mysql的安装及配置
linux·mysql·centos
「QT(C++)开发工程师」40 分钟前
C++语言编程规范-风格
linux·开发语言·c++·qt
前端小刘哥1 小时前
现场直播的技术革新者:视频直播点播平台EasyDSS在现场直播场景中的技术应用
算法
草莓工作室1 小时前
数据结构9:队列
c语言·数据结构·队列
-指短琴长-1 小时前
CGroups资源控制实战【Linux】
linux·运维·服务器
violet-lz1 小时前
数据结构八大排序:堆排序-从二叉树到堆排序实现
数据结构·算法