一、联合体
联合体类型的声明
像结构体⼀样,联合体也是由⼀个或者多个成员构成,这些成员可以不同的类型。但是编译器只为最 ⼤的成员分配⾜够的内存空间。联合体的特点是所有成员共⽤同⼀块内存空间。所以联合体也叫:共用体。 给联合体其中⼀个成员赋值,其他成员的值也跟着变化。
#include <stdio.h> //联合类型的声明 union Un { char c; int i; }; int main() { //联合变量的定义 union Un un = {0}; //计算连个变量的⼤⼩ printf("%d\n", sizeof(un));//4 return 0; }
联合体的特点
联合的成员是共用同⼀块内存空间的,这样⼀个联合变量的大小,至少是最大成员的大小(因为联合 至少得有能力保存最大的那个成员)。
//代码1 #include <stdio.h> //联合类型的声明 union Un { char c; int i; }; int main() { //联合变量的定义 union Un un = {0}; printf("%p\n", &(un.i)); //001AF85C printf("%p\n", &(un.c)); //001AF85C printf("%p\n", &un); //001AF85C return 0; }
//代码2 #include <stdio.h> //联合类型的声明 union Un { char c; int i; }; int main() { //联合变量的定义 union Un un = {0}; un.i = 0x11223344; un.c = 0x55; printf("%x\n", un.i); //11223355 return 0; }
代码1输出的三个地址⼀模⼀样,代码2的输出,我们发现将i的第4个字节的内容修改为55了。 我们仔细分析就可以画出,un的内存布局图。
相同成员的结构体和联合体对比
再对比⼀下相同成员的结构体和联合体的内存布局情况。
struct S { char c; int i; }; struct S s = {0};
union Un { char c; int i; }; union Un un = {0};
联合体大小的计算
联合的大小至少是最大成员的大小。当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。
#include <stdio.h> union Un1 { char c[5]; int i; }; union Un2 { short c[7]; int i; }; int main() { printf("%d\n", sizeof(union Un1)); //8 printf("%d\n", sizeof(union Un2)); //16 return 0; }
写⼀个程序,判断当前机器是大端?还是小端?
int check_sys() { union { int i; char c; }un; un.i = 1; return un.c; }
二、枚举
枚举类型的声明
枚举顾名思义就是⼀⼀列举。 把可能的取值⼀⼀列举。 比如我们现实生活中: ⼀周的星期⼀到星期⽇是有限的7天,可以⼀⼀列举性别有:男、女、保密,也可以⼀⼀列举月份有12个月,也可以⼀⼀列举三原色,也是可以意义列举 这些数据的表示就可以使用枚举了。
enum Day//星期 { Mon, Tues, Wed, Thur, Fri, Sat, Sun }; enum Sex//性别 { MALE, FEMALE, SECRET }; enum Color//颜⾊ { RED, GREEN, BLUE };
以上定义的 enum Day , enum Sex , enum Color 都是枚举类型。 {}中的内容是枚举类型的可能取值,也叫 枚举常量 。这些可能取值都是有值的,默认从0开始,依次递增1,当然在声明枚举类型的时候也可以赋初值。
enum Color//颜⾊ { RED=2, GREEN=4, BLUE=8 };
枚举类型的优点
为什么使用枚举?
我们可以使⽤#define定义常量,为什么非要使用枚举?
枚举的优点:
1.增加代码的可读性和可维护性
2.和#define定义的标识符⽐较枚举有类型检查,更加严谨。
3.便于调试,预处理阶段会删除#define定义的符号
4.使⽤⽅便,⼀次可以定义多个常量
5.枚举常量是遵循作⽤域规则的,枚举声明在函数内,只能在函数内使用
枚举类型的使用
enum Color//颜⾊ { RED=1, GREEN=2, BLUE=4 }; enum Color clr = GREEN;//使⽤枚举常量给枚举变量赋值
那是否可以拿整数给枚举变量赋值呢?在C语⾔中是可以的,但是在C++是不⾏的,C++的类型检查比较严格
三、总结
结构体(struct):
• 可以将不同类型的数据组合成一个新的复合类型,方便对相关数据进行统一管理和操作。
• 可以灵活地定义成员及其类型。
枚举类型(enum):
• 用于定义一组具有相关联的命名常量,提高代码的可读性和可维护性。
• 每个枚举常量都对应一个整数值。
联合类型(union):
• 允许不同类型的变量共享同一块存储空间。
• 常用于节省存储空间或在不同时间使用不同类型的数据。
通过自定义类型,C 语言可以更好地适应各种具体的编程需求,增强代码的组织性和表达能力。