前言:
在上一章节讲解了结构体的位段,与传参。
浅浅复习一下:
位段的成员名(整型)后边有一个冒号和一个数字,这里的单位是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开始依次递增。
优点
-
代码可读性提升
// 优于直接使用数值 if (status == ERROR_TIMEOUT) {...}
-
编译期类型检查
-
防止无效值赋值(示例错误代码演示)
-
C++强类型枚举(enum class)的优势
-
-
自动取值机制
-
默认从0开始的自增序列
-
断点赋值的传播效应
-
-
调试可视化支持
-
调试器显示符号而非数字
-
错误日志可读性提升(对比数值输出)
-
枚举类型通常用于表示一组有限的选项。例如,在定义性别时,可以使用枚举类型:
enum Gender {
MALE,
FEMALE
};
然后在程序中使用:
enum Gender gender = MALE;
最佳实践与陷阱规避
联合体使用注意事项
-
类型安全访问策略
-
字节序对数据解析的影响
-
内存对齐引发的移植性问题
枚举使用规范
-
命名空间管理技巧
-
枚举范围验证方法
-
C/C++版本差异处理
例如:
这是在C+++下进行的,无法运算。
这个实在C的环境下运行,可以。
这就是 C/C++版本差异处理。
性能与内存优化
-
联合体内存压缩技巧
-
枚举存储优化策略
-
缓存友好的数据结构设计
总结
联合体和枚举作为C/C++的核心特性,在系统编程、嵌入式开发、协议处理等领域具有不可替代的作用。联合体通过内存复用实现紧凑存储,枚举则提升了代码的可维护性和安全性。深入理解其底层机制,结合具体应用场景合理使用,可以显著提升代码质量和执行效率。
本章节讲解完毕,我们下章再见!!
预告:下章节讲述动态内存管理。。
有兴趣的话。关注,点赞,看后续!!