思维导图:
1.枚举
1.1 枚举类型的定义
例:
enum Day//星期 { Mon, Tues, Wed, Thur, Fri, Sat, Sun }; enum Sex//性别 { MALE, FEMALE, SECRET }; enum Color//颜色 { RED, GREEN, BLUE };
上述这些,都是枚举的定义。
例:
#include enum Sex { MALE, FEMALE, SECRET }; int main() { printf("%d\n", MALE); printf("%d\n", FEMALE); printf("%d\n", SECRET); return 0; }
输出:
输出:
0
1
2
枚举在定义后,成员的默认值是从0开始,一次递增1。
#include enum Sex//默认递增1//第一个默认是0 { //枚举是可以初始化初始值 MALE=1,//枚举定义的是常量 FEMALE=2, SECRET=4 }; int main() { enum Sex s; printf("%d\n", sizeof(s));//枚举类型的大小是4个字节 printf("%d ", MALE); printf("%d ", FEMALE); printf("%d ", SECRET); //MALE=2;//不能修改 return 0; } 输出:
输出:
4
1 2 4
1.2 枚举的优点
1. 增加代码的可读性和可维护性。
2. 和#define定义的标识符比较枚举有类型检查,更加严谨。
3. 防止了命名污染(封装)。
4. 便于调试。
5. 使用方便,一次可以定义多个常量。
1.3 枚举的使用
我在实现静态通讯录时,
swich语句中的case1、2、3、4、5、6、0可读性较差,
我们可以用枚举使他变得更加直观:
这是原来的实现:
void test() { int input = 0; //创建通讯录con Contact con; //初始化通讯录 InitContact(&con);//分装成函数实现 do { menu();//打印菜单 printf("请选择:>"); scanf("%d", &input);//选择功能 switch(input) { case 1: //增加联系人 AddContact(&con); break; case 2: //删除联系人 DelContact(&con); break; case 3: //查找联系人 SearchContact(&con); break; case 4: //修改指定联系人 ModifyContact(&con); break; case 5: //整理通讯录(按类型排序) SortContact(&con); break; case 6: //显示通讯录的信息 ShowContact(&con); break; case 0: //退出通讯录 printf("通讯录已退出\n"); break; default: printf("选择错误\n"); break; } } while (input); }
我们发现,如果不依靠注释,
我们很难辨别case0~6究竟要实现什么功能。
我们可以创建一个枚举类型:
enum Option { EXIT,//0 ADD, DEL, SEARCH, MODIFY, SORT, SHOW }; void test() { int input = 0; //创建通讯录con Contact con; //初始化通讯录 InitContact(&con); do { menu(); printf("请选择:>"); scanf("%d", &input); switch(input) { case ADD: AddContact(&con); break; case DEL: DelContact(&con); break; case SEARCH: SearchContact(&con); break; case MODIFY: ModifyContact(&con); break; case SORT: SortContact(&con); break; case SHOW: ShowContact(&con); break; case EXIT: printf("通讯录已退出\n"); break; default: printf("选择错误\n"); break; } } while (input); }
这样的话,哪怕我们不依靠注释,
也能清楚的知道不同case应该实现什么样的功能。
2. 联合(共用体)
2.1 联合类型的定义
联合体的成员公用同一块空间(所以联合也叫共用体)。
例:
#include typedef union UN//这是一个联合体 { char c; int i; }UN; int main() { UN un; printf("%d\n", sizeof(un)); printf("%p\n", &un); printf("%p\n", &(un.c)); printf("%p\n", &(un.i)); return 0; }
输出:
4 006FF7D0 006FF7D0 006FF7D0
通过观察可以发现,他们的地址都是相同的。
这是联合体的一个特点:
2.2 联合的特点
联合的成员是共用同一块内存空间的,这样一个联合变量的大小,
至少是最大成员的大小(因为联合至少得有能力保存最大的那个成员)。
2.3 联合大小的计算
联合的大小至少是最大成员的大小。
当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。
例:
#include typedef union Un { char c[5];//5个char类型占用5个字节,对齐后占用8个 int n;//共用内存 }Un; typedef union Un2 { short c[7];//7个short占用14个字节,对齐后占用16个 int n;//共用内存 }Un2; int main() { Un un; Un2 un2; printf("%d\n", sizeof(un)); printf("%d\n", sizeof(un2)); return 0; }
输出:
输出: 8 16
以及,我们可以用联合体计算大小端:
例:
这是我们之前判断的方法:
#include int main() { int a = 1;//0x00 00 00 01 //小端存储的方式: //低地址------>高地址 //0x01 00 00 00 if (*(char*)&a == 1) { printf("小端\n"); } else { printf("大端\n"); } return 0; }
输出:
输出:小端
这是用联合体实现的方法:
利用内存共用的特性:
#include typedef union Un { char c; int i; }Un; int main() { int a = 1; Un un; un.i = 1; if (un.c == 1) { printf("小端\n"); } else { printf("大端\n"); } return 0; }
输出:
输出:小端
写在最后:
以上就是本篇文章的内容了,感谢你的阅读。
如果喜欢本文的话,欢迎点赞和评论,写下你的见解。
如果想和我一起学习编程,不妨点个关注,我们一起学习,一同成长。