6. C语言 共用体及typedef

从基础 → 底层实现 → 嵌入式应用 全面掌握这两个概念。


🧩 一、共用体(union)的本质与定义

1️⃣ 基本概念

共用体(union)和结构体(struct)很像 ,但它们在内存上的工作方式 完全不同

特性 struct union
各成员都有独立的内存 ✅ 是 ❌ 否(共享同一段内存)
内存大小 所有成员大小之和 最大成员的大小
同时保存多个值 可以 只能保存一个成员的值

2️⃣ 示例对比

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

struct S {
    int a;
    char b;
};

union U {
    int a;
    char b;
};

int main() {
    struct S s = {65, 'B'};
    union U u;
    u.a = 65;

    printf("struct大小: %zu\n", sizeof(s));
    printf("union大小: %zu\n", sizeof(u));

    u.b = 'B';
    printf("u.a = %d, u.b = %c\n", u.a, u.b);
    return 0;
}

🧠 运行结果(假设 64 位系统)

复制代码
struct大小: 8
union大小: 4
u.a = 66, u.b = B

解释:

  • 共用体的所有成员共享同一块内存
  • u.b = 'B' 时,它其实覆盖了前面的 int 值
  • 所以 u.a 的值被修改了(65 → 66,因为字符 'B' 的 ASCII 是 66)。

3️⃣ 内存图解

text 复制代码
union U {
    int a;   // 占 4 字节
    char b;  // 占 1 字节
}

内存(假设起始地址 0x1000):

地址 内容 说明
0x1000 a 或 b 的值 共用同一位置
0x1001 同上 ...
0x1002 同上 ...
0x1003 同上 ...

⚙️ 二、嵌入式实际用途:硬件寄存器映射

在嵌入式开发中,共用体经常用于:

  • 查看数据的不同表现形式
  • 访问寄存器的不同位段

1️⃣ 多视角访问同一块数据

c 复制代码
union Data {
    int i;
    unsigned char bytes[4];
};

int main() {
    union Data d;
    d.i = 0x12345678;

    printf("bytes: %02X %02X %02X %02X\n",
           d.bytes[0], d.bytes[1], d.bytes[2], d.bytes[3]);
    return 0;
}

✅ 输出(取决于大小端):

复制代码
bytes: 78 56 34 12

📘 用途:

  • 快速查看变量在内存中的布局;
  • 网络协议中做 大小端转换(endian swap)
  • 将一个整数打包成字节流。

2️⃣ 寄存器位操作映射

嵌入式芯片中,寄存器通常是一个 32 位的值,但不同位控制不同功能。

可以这样定义:

c 复制代码
typedef union {
    unsigned int ALL;  // 整体访问寄存器
    struct {
        unsigned int EN      :1;  // bit0: 使能
        unsigned int MODE    :2;  // bit1~2: 模式
        unsigned int STATUS  :1;  // bit3: 状态
        unsigned int RESERVED:28;
    } BIT;
} REG_CTRL;

int main() {
    REG_CTRL reg;
    reg.ALL = 0;         // 清零
    reg.BIT.EN = 1;      // 使能寄存器
    reg.BIT.MODE = 3;    // 模式选择
    printf("寄存器值: 0x%08X\n", reg.ALL);
}

✅ 输出:

复制代码
寄存器值: 0x00000007

🧠 优点:

  • 结构化访问硬件寄存器;
  • 无需复杂位操作;
  • 可读性与安全性都提升。

🔤 三、typedef ------ 类型重命名神器

1️⃣ 基础用法

typedef 是 "type definition" 的缩写,用来 给类型起别名

c 复制代码
typedef unsigned int uint32;
typedef struct {
    int x;
    int y;
} Point;

现在可以写成:

c 复制代码
uint32 a = 10;
Point p = {1, 2};

2️⃣ typedef + struct/union 常用写法

写结构体/共用体时,我们常见三种方式:

c 复制代码
struct A { int x; };          // 方式1:声明结构体类型
typedef struct A AType;       // 方式2:起别名
typedef struct { int x; } B;  // 方式3:匿名结构体 + typedef

方式3 最常用于嵌入式开发:

c 复制代码
typedef struct {
    uint8_t EN;
    uint8_t MODE;
} CTRL_REG;

3️⃣ typedef + 函数指针(非常常见)

c 复制代码
typedef void (*ISRHandler)(void);

现在可以直接定义:

c 复制代码
ISRHandler Reset_ISR;

而不是:

c 复制代码
void (*Reset_ISR)(void);

🧠 四、嵌入式实战案例:结构体 + 共用体 + typedef

c 复制代码
typedef union {
    unsigned int ALL;
    struct {
        unsigned int TXE:1;
        unsigned int RXE:1;
        unsigned int ERR:1;
        unsigned int RESERVED:29;
    } BIT;
} UART_STATUS;

typedef struct {
    UART_STATUS STATUS;
    unsigned char DATA;
} UART_REG;

UART_REG *UART1 = (UART_REG *)0x40011000; // 寄存器基址映射

int main(void) {
    if (UART1->STATUS.BIT.RXE) {
        unsigned char data = UART1->DATA;
        printf("接收数据: %c\n", data);
    }
}

✅ 说明:

  • typedef 让结构体定义更简洁;
  • union 既能按位访问,又能整体访问;
  • 在嵌入式系统中直接映射寄存器地址,效率极高。

📘 五、总结对比表

概念 struct union typedef
内存独立 每个成员独立占空间 所有成员共用空间 不影响内存,仅起别名
用途 数据组织 内存复用、位操作、硬件寄存器 类型简化、可读性提升
嵌入式意义 模块化数据 寄存器映射 统一风格、提高可维护性

相关推荐
2401_861277551 天前
软考程序员2016年上半年二叉排序树案例题解答
c语言·决策树·链表
小龙报1 天前
《DevC++支持C++11等与其软件分辨率低的解决办法》
c语言·c++·windows·蓝桥杯·pat考试·学习方法·dvc++
ivy159868377151 天前
JM20329是一款高性能、低功耗的USB桥接芯片,实现串行接口(如SATA、IDE)与USB接口之间的数据转换。
c语言·开发语言·ide·嵌入式硬件·eureka·音视频·视频编解码
mit6.8241 天前
Foreign Function Interface
c语言
小龙报1 天前
《嵌入式成长系列之51单片机 --- Keil5创建工程》
c语言·开发语言·c++·单片机·嵌入式硬件·51单片机·学习方法
无限进步_1 天前
【C语言】贪吃蛇游戏设计思路深度解析:从零开始理解每个模块
c语言·开发语言·c++·git·游戏·github·visual studio
头发还没掉光光1 天前
C/C++类型转换
c语言·开发语言·c++
爪哇部落算法小助手1 天前
爪哇周赛 Round 1
c语言·c++·算法
CoderBob1 天前
【EmbeddedGUI】简易Page开发模式
c语言·图像处理·单片机
橘色的喵1 天前
C语言面向对象范式:Nginx模块化架构的设计分析
c语言·nginx·架构·面向对象