目录
一、枚举类型(关键字enum)
在C语言中还藏着一个不常用的类型枚举类型:
enum Week
{
MON,
TUE,
WED,
THUR,
FRI,
SAT,
SUN,
};
例如上面的枚举类型Week,里面包含了星期一(MON)到星期天(SUN)一个星期的缩写。
1.枚举类型的定义
在上述枚举类型Week中,MON-SUN每个成员叫枚举的可能取值(也就意味着每个枚举类型都有着其相对应的值)。
在我们使用枚举类型时,我们可以让一种枚举类型一一列举我们所需要的所有东西,如上述的Week包含了星期一(NON)到星期天(SUN)一个星期的缩写。例如我们也可以定义一种PrimaryColour(三原色)类型,枚举的可能取值有RED(红)、GREEN(绿)、BLUE(蓝):
(反正用字母定义自己想定义的就行~)
enum PrimaryColou
{
RED,
GREEN,
BLUE
};
2.枚举类型的意义
在上面的枚举类型PrimaryColour中,我们可以在主函数中这样使用:
int main()
{
enum PrimaryColor C = BLUE;
return 0;
}
但是如BLUE这些枚举的可能取值到底有何意义呢?
我们来看一下这些枚举的可能取值到底是多少:
分别为0、1、2 ,在系统中默认将第一个枚举的可能取值赋值为0,后面的每一个枚举的可能取值在前一个枚举的可能取值上加1。
从上述例子中我们可以看出这些枚举的可能取值都是有真实的值的,这些值从本质上还是整型,也就是说枚举的可能取值别看他们都是字母但是其本质上还是整型。并且在主函数中不可修改:
但是我们可以在定义时就将其值初始化:
部分初始化:
如:
如:
全部初始化:
但是我们要避免在初始化的时候将多个枚举的可能取值赋值成相同值,这样是无意义的:
如:
3.枚举类型的优点
1.增加代码的可读性和可维护性。
2.和#define定义的标识符(#define定义的常量是无类型的)比较枚举有类型检查,更加严谨。
3.防止了命名污染(封装)(#deine定义一个常量时会将系统中出现的所有的定义符都替换为常量,而枚举类型不会)。
4.便于调试。
5.使用方便,一次可以定义多个常量。
4.枚举类型的运用举例
在我们使用Switch选择语句时:
switch (input)
{
case 1:
AddContact(&con);
break;
case 2:
DelContact(&con);
break;
case 3:
SearchContact(&con);
break;
case 4:
ModifyContact(&con);
break;
case 5:
ShowContact(&con);
break;
case 6:
SortContact(&con);
break;
case 0:
printf("退出\n");
break;
default:
printf("选择错误\n");
break;
}
我们经常会通过输入的值来判断所要进入的函数,这样容易让人混淆,表示不直观。
下面我们这样修改一下:
enum Choose
{
EXIT,
ADD,
DEL,
SEARCH,
MODIFY,
SHOW,
SORT
};
switch (input)
{
case ADD:
AddContact(&con);
break;
case DEL:
DelContact(&con);
break;
case SEARCH:
SearchContact(&con);
break;
case MODIFY:
ModifyContact(&con);
break;
case SHOW:
ShowContact(&con);
break;
case SORT:
SortContact(&con);
break;
case EXIT:
printf("退出\n");
break;
default:
printf("选择错误\n");
break;
}
现在进入Switch选择时会更加直观明了我们所要进入运行的函数,增加了程序的可读性。
二、联合体(共用体)(关键字union)
1.联合体的定义
联合体(也称共用体)是一种特殊的自定义类型,这种自定义类型和结构体一样包含自己的成员,但是这些成员共用一块空间。
如:
union ST
{
int a;
char b;
double c;
}L;
2.联合体的特点
我们用printf函数(%p的实质即为将所指向的数据地址以十六进制的形式输出。)打印它们每个成员的储存地址,发现完全一样,证明了它们都是使用同一块空间的。
3.联合体的运用场景
因为在联合体的存储空间中所有成员共用同一空间,所以当我们改变一个成员时其他的成员可能也会收到影响,以至于联合体中成员不能同时存在,所以只适合在某一时间只使用其中单个成员时使用。
例如在判断大小端存储时,我们可以使用联合体:
int main()
{
union
{
int a;
char b;
}L;
L.a = 1;
if (L.b == 1)
printf("小端\n");
else
printf("大段\n");
return 0;
}
运行结果:
因为在同一空间中int类型的a成员存储方式无非就这两种:
而和a成员共用同一块空间的char类型b成员只能读取一字节的数据:
此时b无非就1和0两种取值,即:为1是小端存储,为0是大端存储。
4.联合体的内存计算
从联合体的特点中我们可以知道,一个联合体的大小至少是它所包含成员的最大内存的大小。
但是联合体和结构体一样也需要内存对齐
>当最大成员大小不是最大对齐数的整数倍的时候,联合体的存储空间就要对齐到最大对齐数的整数倍。
注:最大对齐数是联合体成员中所占空间最大的类型的字节大小
如:
union
{
int a;
char b[6];
}L;
此处a成员占4字节,b【6】成员占6字节,所以此联合体最小所占空间为6字节,但是int类型a成员的对齐数为4,char类型b【5】成员别看它占了6字节但是它的对齐数还是要看char类型本身为1,所以此联合体最大对齐数为4,内存空间应是4的整数倍,所以最终所占空间应该由6字节增加到8字节:
本次的博客又要和各位看官告一段落了,欢迎大家在评论区指出有误和不足的地方,谢谢您嘞!