记录一下自己对于枚举类型和联合体的理解;
枚举:故名思意就是将可能出现的事情一一列举出来;
比如:性别:男、女、保密;
星期:星期一、星期二、星期三、星期四、星期五、星期六、星期日;
enum Day//星期
{
Mon,
Tues,
Wed,
Thur,
Fri,
Sat,
Sun
};
enum Sex//性别
{
MALE,
FEMALE,
SECRET
};
enum Color//颜色
{
RED,
GREEN,
BLUE
};
C语言给我们提供了enum关键字来定义枚举类型,enum的使用方法与结构体的使用方法是一样的;
以上定义的enum Day、enumSex、enum Color都是枚举类型,我们{}中的内容是枚举类型的可能取值,也叫 枚举常量 。;
既然是一个类型我们,就可以利用该类型去定义变量;
比如:

既然是常量,那一定是有值的,我们将这些值打出来,看看:

我们可以看到,这些枚举常量的值是连续的;事实上呢,{ }里面的枚举常量都是从0开始的,然后后面依次增长1,但是我们可以重新进行赋值,让它们从某一个特定的值开始增长,比如:

我们我们修改了RED的初始值,后面也就会依次从10开始增长;
同时我们也可以对每一个值进行重新赋值:
比如:


都是可以的;

实际上枚举类型是并不会存入所有枚举事件,只会存一个,从我们列举的对象中,选一个出来给我们使用;就是我列举了所有可能,但是我最终只会用其中的一种可能,所以我们只需开辟存储一种可能的大小的空间就行了;
C语言下面,enum大小是一个整型大小,但是C下整型有很多种,char、long int和short int等,具体哪一种呢?
enum类型的大小是由编译器根据定义值的大小来选择合适的整数类型,所以enum类型的大小并不是固定的,还是取决于编译器的;
为什么使用枚举?
我们可以使用 #define 定义常量,为什么非要使用枚举?枚举的优点:
- 增加代码的可读性和可维护性
- 和#define定义的标识符比较枚举有类型检查,更加严谨。
- 防止了命名污染(封装)
- 便于调试
- 使用方便,一次可以定义多个常量
联合也是一种特殊的自定义类型,这种类型定义的变量也包含一系列的成员,特征是这些成员公用同一块空间(所以联合也叫共用体)。
比如:
union un
{
char a;
int b;
}
其中a和共用同一块空间:

我们再来从地址上认识一下:

我们可以发现联合体与a、b的首元素地址两两相等,从地址方面我们也说明了a、b共用同一块空间;
那我们该如何计算联合体的大小?
根据上面的理论我们直到联合体的成员共享同一块空间,那是不是联合体的大小就等于最大的成员变量的大小呢?
不完全正确,也不完全错误:
比如:
union un
{
char a[5];
int n;
}
该联合体的大小是5吗?
看看运行结果:

我们可以清楚的看到结果并不是预期的那样;
为什么?
主要是因为,我们在得到联合体的初步大小(也就是最大成员变量的大小)还需判断一下该大小是否是该联合体最大对齐数的整数倍?如果不是,则还需继续往后开辟空间,直到满足该条件即可;如果是,则改大小就是还联合体的最终大小;
上述联合体,初步大小是5,最大对齐数是4,5不是4的整数倍,则需要继续往后开辟,直到位8个字节才结束,故最终该结构体的大小就是8字节;
通过联合体的特点我们可以直到里面的成员变量是共用同一块空间的,因此我们可以根据该特点来判断一下当前机器是大端还是小端:
思路:
我们设计一个联合体:
union un
{
char a;
int b;
}s;
s.b=1;
我们呢据此可以取出a的值,我们来判断一下a是否等于1,如果等就是小端;
如果不等就是大端;
代码具体实现:
int check_duan()
{
union
{
char a;
int b;
}s;
s.b = 1;
return s.a;
}
int main()
{
if (check_duan())
printf("当前机器为小端\n");
else
printf("当前机器为大端\n");
return 0;
}
