一、枚举 枚举类型的定义 枚举的优点 二、联合 联合类型的定义 联合的特点 联合大小的计算
一、枚举
1.1 枚举类型的定义
在生活中有许多东西的种类可以通过一一列举的方式得到,这样的方法叫做枚举。
比如颜色,性别,学科等等,枚举的用处就是用来列举有限个种类的事物。
c语言中如何声明一个枚举类型呢?直接给出代码:
enum color
{
green,
blue,
yellow,
white,
};
枚举的关键字是enum,它的花括号后面也有一个分号,和结构体一样,不可省略!
内部的成员是枚举常量,在外部修改它们是非法的,但是在枚举内部给他们初始化赋值是可以的,像这样:
enum color
{
green = 6 ,
blue,
yellow,
white,
};
一般来说枚举内部第一个成员的值默认为0,第二个是1,一直递增下去。如果像上面这样修改后,第一个成员的值被初始化为6,下面就是7,8,9。
1.2枚举的优点
像上面一样,green被初始化为6,这时在编译器认为,green就是6,如果我们通过打印它就可以得到6。
这样就相当于给6一个标识一样,提高了代码的可读性。
可以通过赋初值,一次性得到多个常量,比#define定义常量来的方便。
下面总结出枚举的所有优点
1. 增加代码的可读性和可维护性 2. 和 #define 定义的标识符比较枚举有类型检查,更加严谨。 3. 防止了命名污染(封装) 4. 便于调试 5. 使用方便,一次可以定义多个常量
比如在cpp中如果像上面那样给c附上一个初值,就会报错。只有拿枚举常量给枚举变量赋值,才不会报错。
enum Color//颜色
{
RED=1,
GREEN=2,
BLUE=4
};
enum Color clr = GREEN;//只能拿枚举常量给枚举变量赋值,才不会出现类型的差异。
二、联合体
2.1联合体的定义 用联合体判断大小端
联合体也是一种自定义的类型,它的特点是所有的成员共用同一块的空间。
联合体的关键字是union
下面创建一个联合体,来证明它的成员共用同一块的空间,也就是他们的地址是一致的。
union p
{
char c;
int i;
};
int main()
{
union p a;
printf("%pn%p", &(a.c), &(a.i));
return 0;
}
打印的结果
这说明他们确实是同一块的空间。
下面我以两种方式判断当前机器的大小端
1、以指针的方式
int main() { int a = 2; //a 在内存的存储是02 00 00 00 是小端 00 00 00 02是大端 char* ret = (char*)&a; if (*ret) { printf("小端"); } else { printf("大端"); } return 0; }这里把a的地址强制转换成char*的类型,方便得到它的第一个字节位,因为要判断大小端,主要就是第一个字节位到底是02还是00,所以if的判断条件也很好理解了,如果解引用后非0就是小端,反之是小端。
2、使用联合体的方法
union p { char c; int i; }; int main() { union p a; a.i = 1; if (a.c) { printf("小端"); } else { printf("大端"); } return 0; }先创建了一个联合体的变量a,给a中的i赋值1,因为联合体中的成员总是共用同一块的空间,所以char c的空间和i空间的第一个字节重叠了,由此如果char c的大小是1 那么就是小端
否则是大端
2.2 联合体的大小计算
实际上联合体也是有内存对齐的规则的。
1.联合的大小至少是最大成员的大小。 2.当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍
union Un1
{
char c[5];
int i;
};
union Un2
{
short c[7];
int i;
};
//下面输出的结果是什么?
int main()
{
printf("%dn", sizeof(union Un1));
printf("%dn", sizeof(union Un2));
}
un1中第一个成员是一个char 数组,如果union或结构体中有数组,就要拿数组中元素的大小和默认对齐数比较,比如char就要拿1和8比较。char c是第一个成员,它的偏移量为0,从而占0~4的空间,i与它共用同一块的空间,现在空间是5个字节,由第二个规则,要对齐到最大对齐数的整数倍,最大的成员大小是4,所以要对齐到8,故sizeof(union un1) = 8,。
同理可以得到un2的大小是16。
本节完。



