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 更安全、可读、可调试,适合表示状态、选项等有限集合。掌握联合和枚举,能编写更高效、更清晰的代码。

相关推荐
练习时长一年3 小时前
LeetCode热题100(二叉树的最大路径和)
算法·leetcode·职场和发展
2401_872418789 小时前
算法入门:数据结构-堆
数据结构·算法
xwz小王子10 小时前
手术机器人登上Science Robotics:2毫米纤细手臂,从3厘米切口完成腰椎神经减压
算法·机器人
黎阳之光11 小时前
视频孪生智护供水生命线:黎阳之光赋能医疗与园区水务高质量升级
运维·物联网·算法·安全·数字孪生
Black蜡笔小新12 小时前
自动化AI算法训练服务器DLTM制造业AI质检工作站助力制造业实现AI智检
人工智能·算法·自动化
嵌入式小能手12 小时前
飞凌嵌入式ElfBoard-进程间的通信之命名管道
linux·服务器·算法
啦哈拉哈12 小时前
Leetcode题解记录-hot100(81-100)
算法·leetcode·职场和发展
csdn_aspnet13 小时前
Java 霍尔分区算法(Hoare‘s Partition Algorithm)
java·开发语言·算法
诸葛务农13 小时前
道路行驶条件下电动汽车永磁电机的有效使用寿命及永磁体的失效和回收再利用(下)
java·开发语言·算法