1.枚举
枚举顾名思义就是一一列举。
把可能的取值一一列举。
性别 : 男 , 女 , 保密
一年有十二个月,也可以一一列举.
一周有七天,也可以一一列举
1.1枚举的定义
enum Day
enum Day//一周
{
Mon,
Tues,
Wed,
Thur,
Fri,
Sat,
Sun
};
enum Sex//性别
{
MALE,
FEMALE,
SECRET
};
上面的enum Day , enum Sex 都是枚举类型
{}中的内容是枚举类型的可能取值 , 也叫枚举常量
枚举常量 , 默认第一个被赋值为0,往后依次加1. ----- 请看下图就会理解了
当然在定义的时候也可以赋值.
enum Sex//性别
enum Sex//性别
{
MALE = 2,
FEMALE = 4,
SECRET = 6
};
1.2枚举的优点
说了这么多,是不是觉得枚举没有什么用呢,不就是可以定义常量.
我们可以使用 #define 定义常量,为什么非要使用枚举?
枚举的优点:
-
增加代码的可读性和可维护性
-
和#define定义的标识符比较枚举有类型检查,更加严谨。
-
防止了命名污染(封装)
-
便于调试
-
使用方便,一次可以定义多个常量
1.3枚举的使用
大家写通讯录系统时的菜单
#include<stdio.h>
#include<stdio.h>
void menu()
{
printf("************************\n");
printf("********1.Add ********\n");
printf("********2.Del ********\n");
printf("********3.Search********\n");
printf("********4.Modify********\n");
printf("********0.exit ********\n");
printf("************************\n");
}
int main()
{
menu();
int select = 0;
scanf("%d", &select);
switch (select)
{
case 1:
//写什么内容
break;
case 2:
//写什么内容
break;
case 3:
//写什么内容
break;
case 4:
//写什么内容
break;
case 0:
//写什么内容
break;
default:
break;
}
return 0;
}
上面只是随便写了一点
如果我不让你看menu()函数,你能写出switch中的具体实现吗?----显然不行,因为你不是1是什么意思,2是什么意思
如果menu()函数和switch在程序中离的较远,每需要写一个函数,就要去menu()函数中查找它对应的数字是不是很麻烦
看看用了枚举类型后是什么样呢?
#include<stdio.h>
#include<stdio.h>
enum S
{
EXIT,
ADD,
DEL,
SEARCH,
MODIFY
};
void menu()
{
printf("************************\n");
printf("********1.Add ********\n");
printf("********2.Del ********\n");
printf("********3.Search********\n");
printf("********4.Modify********\n");
printf("********0.exit ********\n");
printf("************************\n");
}
int main()
{
menu();
int select = 0;
scanf("%d", &select);
switch (select)
{
case ADD:
//写什么内容
break;
case DEL:
//写什么内容
break;
case SEARCH:
//写什么内容
break;
case MODIFY:
//写什么内容
break;
case EXIT:
//写什么内容
break;
default:
break;
}
return 0;
}
这样是不是比刚刚那样好多了,便于阅读,便于编写程序.
2.联合体(共用体)
2.1联合体的定义
联合也是一种特殊的自定义类型
这种类型定义的变量也包含一系列的成员,特征是这些成员公用同一块空间(所以联合也叫共用体)。
看程序吧.
#include<stdio.h>
#include<stdio.h>
//联合类型的声明
union Un
{
char c;
int i;
};
int main()
{
union Un s;
printf("%d\n", sizeof(s));
return 0;
}
大家觉得输出的是什么呢.
往下看就知道原因了
2.2联合的特点
联合的成员是共用同一块内存空间的所以一个成员用的同时,其他成员无法使用
这样一个联合变量的大小,至少是最大成员的大小(因为联 合至少得有能力保存最大的那个成员)。下面会讲如何计算大小,这只是一个条件
#include<stdio.h>
#include<stdio.h>
union Un
{
int i;
char c;
};
int main()
{
union Un un;
// 下面输出的结果是一样的吗?
printf("%d\n", &(un.i));
printf("%d\n", &(un.c));
//下面输出的结果是什么?
un.i = 0x11223344;
un.c = 0x55;
printf("%x\n", un.i);
}
看下图。
2.3联合体的应用
就这样吗,我也没有发现他有啥用啊。
这个用的不是很多,给大家举个例子吧,就知道它的厉害了。
判断大小端字节序,之前写过的。
之前的
#include<stdio.h>
#include<stdio.h>
int Is_char()
{
int i = 1;
return (char)i;
}
int main()
{
int ret = Is_char();
if (ret == 1)
{
printf("小端\n");
}
else
{
printf("大端\n");
}
return 0;
}
现在的
#include<stdio.h>
#include<stdio.h>
union S
{
int i;
char c;
}s;
int Is_char()
{
s.i = 1;
return s.c;
}
int main()
{
int ret = Is_char();
if (ret == 1)
{
printf("小端\n");
}
else
{
printf("大端\n");
}
return 0;
}
2.4联合体的大小计算
联合的大小至少是最大成员的大小。
当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。
#include<stdio.h>
#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));
printf("%d\n", sizeof(union Un2));
return 0;
}
这个其实和结构体挺像。
小计算
联合的大小至少是最大成员的大小。
当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。
#include<stdio.h>
#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));
printf("%d\n", sizeof(union Un2));
return 0;
}
这个其实和结构体挺像。
先找到最大对齐数,再找出联合体总内存最大类型,再与最大对齐数比较,若是整数倍,便是联合体的大小。若不是,则添加内存到最大对齐数的整数倍。