C语言自定义类型:联合和枚举完全指南

C语言自定义类型:联合和枚举完全指南

联合(共用体)和枚举是C语言中两种重要的自定义类型。联合体所有成员共享同一块内存,而枚举用于定义一组命名的整数常量。本文将系统讲解联合体的声明、特点、大小计算,以及枚举的声明、优点和使用方法,并通过实例帮助读者灵活运用。

目录


一、联合体类型的声明

联合体(union)与结构体类似,由多个不同类型的成员组成,但所有成员共用同一块内存空间 ,因此联合体也叫共用体。编译器只为最大的成员分配足够的内存。

c 复制代码
union Un {
    char c;
    int i;
};

int main() {
    union Un u;
    printf("%zu\n", sizeof(u));  // 输出4(int占4字节)
    return 0;
}

二、联合体的特点

  • 所有成员的地址相同,即它们从同一个内存位置开始存储。
  • 修改一个成员会影响其他成员的值。

验证地址相同

c 复制代码
union Un { char c; int i; };
union Un u;
printf("%p\n", &u);    // 联合体地址
printf("%p\n", &u.c);  // 与上面相同
printf("%p\n", &u.i);  // 与上面相同

修改成员相互影响

c 复制代码
u.i = 0x11223344;
u.c = 0x55;
printf("%x\n", u.i);  // 输出0x11223355(低字节被修改)

小端 机器上,u.c 修改了 u.i 的低地址字节(即最低有效字节)。这一特性可用于判断字节序(大小端):

c 复制代码
int check_sys() {
    union { int i; char c; } u;
    u.i = 1;
    return u.c;  // 返回1为小端,0为大端
}

三、联合体大小的计算

联合体的大小至少是最大成员的大小,但需满足对齐要求总大小必须是所有成员对齐数的最大值的整数倍

c 复制代码
union Un1 {
    char c[5];  // 5字节,对齐数为1
    int i;      // 4字节,对齐数为4
};  // 最大对齐数4,总大小须为4的倍数 → 8

union Un2 {
    short c[7]; // 14字节,对齐数为2
    int i;      // 4字节,对齐数为4
};  // 最大对齐数4,总大小须为4的倍数 → 16

printf("%zu %zu\n", sizeof(union Un1), sizeof(union Un2));  // 8 16

实际应用:节省内存的礼品单设计

使用结构体时,所有属性都占用空间,造成浪费。利用联合体,不同商品共享特殊属性区域,可大幅节省内存:

c 复制代码
struct gift_list {
    int stock_number;
    double price;
    int item_type;
    union {
        struct { char title[20]; char author[20]; int num_pages; } book;
        struct { char design[30]; } mug;
        struct { char design[30]; int colors; int sizes; } shirt;
    } item;
};

四、枚举类型的声明

枚举(enum)用于将可能的值一一列举,定义一组命名的整数常量。

c 复制代码
enum Day { Mon, Tue, Wed, Thu, Fri, Sat, Sun };
enum Sex { MALE, FEMALE, SECRET };
enum Color { RED, GREEN, BLUE };
  • 默认情况下,枚举常量从 0 开始,依次递增。
  • 可显式指定初始值:
c 复制代码
enum Color { RED = 2, GREEN = 4, BLUE = 8 };

五、枚举类型的优点

相比 #define 定义常量,枚举具有以下优势:

  1. 增强代码可读性和可维护性:含义明确的名称比数字更直观。
  2. 类型检查更严格:枚举变量只能接受枚举值(C中允许整数赋值,但C++禁止)。
  3. 便于调试 :枚举符号在调试器中可见,而 #define 宏在预处理阶段被替换,难以追踪。
  4. 一次定义多个常量 ,无需重复使用 #define
  5. 遵循作用域规则:枚举声明在函数内,则仅在该函数内有效。

六、枚举类型的使用

c 复制代码
enum Color clr = GREEN;  // 使用枚举常量赋值

// 在switch语句中非常清晰
switch (clr) {
    case RED:   printf("红色\n"); break;
    case GREEN: printf("绿色\n"); break;
    case BLUE:  printf("蓝色\n"); break;
}

在C语言中,可以将整数值赋给枚举变量(虽然不推荐),但在C++中不允许,这体现了C++更强的类型安全。


总结:联合体通过共享内存节省空间,适合存储互斥的成员;其大小需满足对齐要求。利用联合体可以巧妙实现字节序判断。枚举定义命名的整数常量,比 #define 更安全、可读、可调试,适合表示状态、选项等有限集合。掌握联合和枚举,能编写更高效、更清晰的代码。

相关推荐
绿算技术18 分钟前
大模型本地化的经济账:DeepSeek V4 Flash 部署实测
人工智能·科技·算法·spark
翟天保Steven29 分钟前
用于提升CBCT低对比度组织分辨率的三维图像后处理方法
算法·计算机视觉·图像重建·图像后处理
FII工业富联科技服务30 分钟前
GW级AI数据中心怎么建?Omniverse、CFD、液冷与BMS技术路径拆解
服务器·人工智能·算法·能源·制造
roman_日积跬步-终至千里42 分钟前
【算法五】从斐波那契到动态规划:自顶向下、自底向上与状态压缩
算法·动态规划
从零开始的嵌入式之旅1 小时前
day31
linux·c语言·经验分享·笔记·嵌入式硬件
Horn Still Sounds1 小时前
Linux系统编程进阶:进程回收、程序替换与多线程并发模型
linux·运维·服务器·c语言
wuyk5551 小时前
9.冒泡排序:像鱼缸泡泡一样的简单排序算法
开发语言·stm32·单片机·算法·排序算法
无限码力3 小时前
8.26华为OD机试真题 新系统【字符串回文判断】
算法·华为od·华为od机考·华为od机试·华为od上机考试真题·华为od最新机试真题题解·华为od机试真题题库
玖玥拾5 小时前
LeetCode 125 验证回文串
算法·leetcode
xu_wenming9 小时前
嵌入式软件架构中的6种解耦艺术
c语言·驱动开发·嵌入式硬件·架构