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

相关推荐
-Excalibur-4 小时前
形象解释关于TCP/IP模型——层层封装MAC数据帧的过程
linux·c语言·网络·笔记·单片机·网络协议·tcp/ip
想唱rap5 小时前
C++ list 类的使用
c语言·开发语言·数据结构·c++·笔记·算法·list
是苏浙8 小时前
零基础入门C语言之深入了解指针3
c语言·开发语言
侯小啾9 小时前
【09】C语言中的格式输入函数scanf()详解
c语言·开发语言
hope_wisdom10 小时前
C/C++数据结构之用链表实现栈
c语言·数据结构·c++·链表·
GilgameshJSS11 小时前
STM32H743-ARM例程30-Modbus
c语言·arm开发·stm32·单片机·嵌入式硬件
散峰而望11 小时前
基本魔法语言分支和循环 (二) (C语言)
c语言·开发语言·github·visual studio
草莓工作室11 小时前
mbedtls哈希值计算
c语言·哈希算法·mbedtls
用户61204149221313 小时前
C语言做的智能家居控制模拟系统
c语言·后端·敏捷开发