一、自定义类型:枚举
枚举,就是一一列举,把可能的取值一一列举出来
1.枚举类型的定义
enum Day
{
Mon, //0
Tues, //1
Wed, //2
Thur, //3
Fri, //4
Sat, //5
Sun //6
};
enum Sex
{
MALE, //0
FEMALE, //1
SECRET //2
};
int main()
{
//星期的表达
enum Day d = Fri;
return 0;
}
上面这样的 enum Day 和 enum Sex 就是枚举类型,{ }里的是枚举类型的可能取值,也叫枚举常量
枚举常量的值默认是从0开始,后面的依次递增1,也可以在定义时赋初值(改变其中一个枚举常量,后面的枚举常量会跟着改变)
可以看出枚举类似使用 #define 定义常量,那枚举有什么优点呢?
枚举的优点:
- 增加代码的可读性和可维护性
- 和 #define 定义的标识符比较枚举有类型检查,更加严谨
- 防止了命名污染(封装)
- 便于调试
- 使用方便,一次可以定义多个常量
2.枚举的使用
例如:在对简易菜单的 switch 选择语句中,可以使用枚举增加代码的可读性
void menu()
{
printf("***** 1.add 2.sub *****\n");
printf("***** 3.mul 4.div *****\n");
printf("***** 0.exit *****\n");
}
enum Option
{
EXIT, //0
ADD, //1
SUB, //2
MUL, //3
SIV //4
};
int main()
{
int input = 0;
do
{
menu();
printf("请选择:");
switch (input)
{
case ADD:
break;
case SUB:
break;
case MUL:
break;
case SIV:
break;
case EXIT:
break;
default:
break;
}
} while (input);
return 0;
}
//可以更直观地看出,case 1后是ADD操作,case 2后是SUB操作......
二、自定义类型:联合(共用体)
1.联合类型的定义
这种类型定义的变量也包含一系列的成员,特征是这些成员共用同一块空间(所以联合也叫共用体)
比如:
//联合类型的声明
union Un
{
char c;//1
int i;//4
};
int main()
{
union Un u;//联合变量的定义
printf("%d\n", sizeof(u));//计算联合变量的大小
printf("%p\n", &u);
printf("%p\n", &(u.c));
printf("%p\n", &(u.i));
return 0;
}
2.联合的特点
联合的成员是共用同一块内存空间的,这样一个联合变量的大小,至少是最大成员的大小(因为联合至少得有能力保存最大的那个成员)
- 联合的成员是共用同一块内存空间
- 当改变一个联合成员的值时,实际上修改了该联合所有成员的值
3.联合的简单应用
判断当前计算机的大小端存储
先不用联合来实现:设计一个函数来实现——先存一个 int 型数据 1,将它的地址强制类型转换为char*
型(访问第一个字节)后解引用,若为1,则是小端存储,若为0,则是大端存储
int check_sys()
{
int a = 1;
if ((*(char*)&a) == 1)
{
return 1;//小端 01 00 00 00
}
else
{
return 0;//大端 00 00 00 01
}
}
int main()
{
int ret = check_sys();
if (ret == 1)
printf("小端\n");
else
printf("大端\n");
return 0;
}
用联合中成员共用同一块内存空间的特点判断
int check_sys()
{
union Un
{
char c;
int i;
}u;
u.i = 1;
return u.c;
//返回1 小端
//返回0 大端
}
int main()
{
int ret = check_sys();
if (ret == 1)
printf("小端\n");
else
printf("大端\n");
return 0;
}
4.联合大小的计算
联合的大小至少是最大成员的大小
当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍
比如:
union Un
{
char c[5];//对齐数:1
int i;//对齐数:4
//总大小:5
//最大对齐数:4
};
int main()
{
printf("%d\n", sizeof(union Un)); //8
return 0;
}