联合体
联合体(union)是一种特殊的数据类型,可以在同一内存空间中存储不同类型的数据。
联合体和结构体(struct)类似,但不同之处在于结构体的各个成员会分别占用内存空间,而联合体的各个成员共享同一内存空间。鉴于这个特性,联合体也叫做共用体。
联合体的声明
union union_name { data_type member1; data_type member2; // 可以有多个成员 };
联合体的大小
因为共享同一内存空间,那么为了有足够的空间来装下所有的成员,那么联合体大小必须要大于最大成员的大小。
但是需要注意的是,当最大成员大小不是最大对齐数的整数倍的时候,那么此时联合体的大小为了内存对齐要扩大为最大对齐数的整数倍
举例:
#include <stdio.h> union Un1 { char c[5]; int i; }; int main() { //求下⾯输出的结果 printf("%d\n", sizeof(union Un1)); return 0; }
输出结果应该是
8;
因为int类型占四个字节,而c数组占五个字节,那么鉴于5不是最大对齐数的整数倍,所以系统就会自动默认该联合体的大小为8个字节。
联合体的用处
鉴于它共享空间的特性,那么就可以达到节省空间的目的。
例如:
现在商店需要知道商品的一些信息。
商品1:单价,数量,质量
商品2:单价,数量,销售量
商品3:单价,数量,批发价
三种商品共同的属性是单价和数量,这些属性实际上可以共享同一块空间,没有必要再分为三块而浪费两块大小的空间。其他不同的属性再独自占各自的空间。
联合体的实例
要求写一个程序,用联合体的知识来判断机器为大端还是小端
#include <stdio.h> union Endian { int num; char bytes[sizeof(int)]; }; int main() { union Endian e; e.num = 1; if (e.bytes[0] == 1) { printf("当前机器为小端\n"); } else { printf("当前机器为大端\n"); } return 0; }
在这个程序中,定义了一个联合体 Endian
,其中包含一个整型成员 num
和一个字符数组成员 bytes
,大小为整型的大小。
在 main
函数中,将整型变量 num
赋值为1,然后通过字符数组 bytes
的第一个元素来判断当前机器是大端还是小端。
如果 bytes[0]
的值为1,则表示当前机器为小端;如果 bytes[0]
的值为0,则表示当前机器为大端。最后根据判断结果输出相应的信息。
枚举
枚举顾名思义,就是将情况一一列举。
而枚举实际上是根据某个事物包括的情况来列举的。例如一周是有周一到周日七种情况,而身份是有父亲儿子等等多种情况。
枚举要做的就是把情况都列出来。
enum enum_name { constant1, constant2, constant3, // 可以有多个常量 };
需要注意的是,枚举中的可能取值都是常量,它们可以被初始化,但是是不可变的。
enum Weekday { MON = 1, TUE, WED, THU, FRI, SAT, SUN };
枚举的作用
枚举类型可以用于定义变量、函数参数、函数返回值等,以表示某种状态或选项。例如:
enum Weekday today = TUE;
枚举类型还可以与 switch
语句结合使用,方便对不同的枚举值进行处理。例如:
switch (today) { case MON: printf("Today is Monday\n"); break; case TUE: printf("Today is Tuesday\n"); break; // 其他枚举值的处理 }
枚举的优点
- 增加代码可读性:通过使用枚举,可以用有意义的名称来表示一组相关的常量,使代码更易于理解和阅读。
- 提高代码可维护性:枚举可以集中定义相关的常量,当需要修改常量值时,只需修改枚举定义即可,而无需在代码中逐个修改每个常量。
- 相较于#define:枚举可以进行类型检查,更具有严谨性
- 类型安全,使用安全:枚举类型是一种类型安全的数据类型,编译器会检查枚举值的合法性,防止使用未定义的值。并且一次可以定义多个常量
- 提高代码的可移植性:枚举类型可以在不同平台上保持一致,因为枚举值的值是由编译器自动生成的。