【C语言】自定义类型:联合和枚举

 前言:

在上一章节讲解了结构体的位段,与传参。

浅浅复习一下:

位段的成员名(整型)后边有一个冒号和一个数字,这里的单位是bit,当一个字节中位置不够一个成员的大小,则会浪费,存储在下一个字节中。

在本章节中为大家讲解联合体

联合体(Union)是C语言中一种特殊的自定义数据类型,其主要特点是多个成员共享同一块内存空间。

目录

 前言:

联合体类型的声明

联合体的特点

联合体的大小计算

枚举类型的声明

优点 

最佳实践与陷阱规避

联合体使用注意事项

 枚举使用规范

性能与内存优化

总结


联合体类型的声明

联合体的声明与结构体类似,但需要使用union关键字代替struct关键字。联合体的声明格式如下:

union 联合体名 
{
    类型 成员1;
    类型 成员2;
    ...
    类型 成员n;
};

例如: 

union SensorData 
{
    int digital;
    float analog;
    char protocol[4];
};

联合体的特点

  • 共享内存:联合体的所有成员共用同一块内存空间,因此它们的地址相同。例如,如果向联合体的一个成员赋值,其他成员的值也会随之改变。

  • 大小计算:联合体的大小等于其最大成员的大小。例如,如果联合体中包含一个char和一个int,则联合体的大小为int的大小(假设为4字节),因为int是两者中占用空间较大的成员。写入新成员会覆盖之前数据(示例演示值覆盖过程)

  • 联合体的大小通常会根据最大成员的对齐要求进行调整。例如,如果最大成员是int,则联合体的大小会是int的对齐倍数(通常是4字节)。这确保了内存访问的效率。

上题目:

下面的代码输出结果如何?

#include <stdio.h>
union u
{
	char s;
	int a;

}u;
int main()
{
	printf("%zd", sizeof(u));
	return 0;
}

这个结果 应该不出各位所料。

内存大小由最大成员决定。

在u中最大的为int,字节为4,所以输出为4.

储存图如下:更方便各位理解

 这个可以更有力的证明,起始地址相同。

联合体的大小计算

联合体的大小由其最大成员的大小决定,并且会根据对齐规则进行调整。例如:

  • 如果联合体包含一个char和一个int,则其大小为int的大小(4字节),因为int是两者中占用空间较大的成员。
  • 如果联合体包含一个char和一个short,则其大小为char的大小(1字节),因为char是两者中占用空间较小的成员。

大家看看一下代码, 

#include <stdio.h>
union u1
{
	char a[5];
	int s;
}u1;
union u2
{
	short a[7];
	char b;

}u2;
union u3
{
	char a[13];    
	double b;      
}u3;
int main()
{
	//union u u1;
	printf("%zd\n", sizeof(u1));
	printf("%zd\n", sizeof(u2));
	printf("%zd\n", sizeof(u3));
	return 0;
}

 u1:

  • 成员 char a[5] 占用 5 字节。

  • 成员 int s 占用 4 字节。

  • 最大成员是 char a[5],占用 5 字节。

  • 由于 int 类型通常需要 4 字节对齐,因此 u1 的大小会被调整为 4 的整数倍,即 8 字节。

 u2:

  • 成员 short a[7] 占用 14 字节(假设 short 类型为 2 字节)。

  • 成员 char b 占用 1 字节。

  • 最大成员是 short a[7],占用 14 字节。

  • 为了满足 int 类型的对齐要求(假设 int 类型为 4 字节),u2 的大小会被调整为 4 的整数倍,即 16 字节。

u3:

  • 成员 char a[13] 占用 13 字节。
  • 成员 double b 占用 8 字节(假设 double 类型为 8 字节)。
  • 最大成员是 double b,占用 8 字节。
  • 由于 double 类型通常需要 8 字节对齐,因此 u3 的大小会被调整为 8 的整数倍,即 16 字节。

枚举类型的声明

枚举类型(Enumeration)是一种用于定义一组命名整数值的数据类型。其声明使用enum关键字,基本语法如下:

enum 枚举类型名 {
    枚举常量1,
    枚举常量2,
    ...
    枚举常量n
};

例如: 

enum Weekday 
{  //枚举类型都是常量
    MONDAY,    // 0
    TUESDAY,   // 1
    WEDNESDAY = 10,
    THURSDAY,  // 11
    FRIDAY     // 12
};

默认情况下,枚举常量从0开始依次递增。 

优点 

  1. 代码可读性提升

    // 优于直接使用数值
    if (status == ERROR_TIMEOUT) {...}
  2. 编译期类型检查

    • 防止无效值赋值(示例错误代码演示)

    • C++强类型枚举(enum class)的优势

  3. 自动取值机制

    • 默认从0开始的自增序列

    • 断点赋值的传播效应

  4. 调试可视化支持

    • 调试器显示符号而非数字

    • 错误日志可读性提升(对比数值输出)

枚举类型通常用于表示一组有限的选项。例如,在定义性别时,可以使用枚举类型:

enum Gender {
    MALE,
    FEMALE
};

然后在程序中使用:

enum Gender gender = MALE;

最佳实践与陷阱规避

联合体使用注意事项

  1. 类型安全访问策略

  2. 字节序对数据解析的影响

  3. 内存对齐引发的移植性问题

 枚举使用规范

  1. 命名空间管理技巧

  2. 枚举范围验证方法

  3. C/C++版本差异处理

例如:

这是在C+++下进行的,无法运算。

 

这个实在C的环境下运行,可以。

这就是 C/C++版本差异处理。

性能与内存优化

  1. 联合体内存压缩技巧

  2. 枚举存储优化策略

  3. 缓存友好的数据结构设计

总结

联合体和枚举作为C/C++的核心特性,在系统编程、嵌入式开发、协议处理等领域具有不可替代的作用。联合体通过内存复用实现紧凑存储,枚举则提升了代码的可维护性和安全性。深入理解其底层机制,结合具体应用场景合理使用,可以显著提升代码质量和执行效率。

本章节讲解完毕,我们下章再见!!

预告:下章节讲述动态内存管理。。

有兴趣的话。关注,点赞,看后续!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值