自学内容网 自学内容网

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


前言

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


1. 什么是共用体?

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

共用体与结构体的区别

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

2. 定义共用体

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

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

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

示例:定义共用体变量

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

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

可以使用typedef简化定义:

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

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

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

内存大小计算

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

union Example {
    char c;        // 1字节
    double d;      // 8字节
};

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

字节对齐

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

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

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

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

4. 访问共用体成员

示例:基本访问

#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:节省内存

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

union Person {
    struct {
        char name[20];
        int teacherID;
    } teacher;

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

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

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

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

union Packet {
    struct {
        int id;
        char message[50];
    } text;

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

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

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

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



原文地址:https://blog.csdn.net/wzt001005/article/details/144891140

免责声明:本站文章内容转载自网络资源,如侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!