前言
一、联合体(联合体类型的声明和特点以及联合体大小的计算)
二、枚举类型(枚举类型的声明和优点)
一、联合体
1.联合体类型的声明
联合体类型的定义(声明)如下:
union tag//联合体名
{
member-list;//成员变量列表
}variable-list;//联合体变量列表
像结构体⼀样,联合体也是由⼀个或者多个成员构成,这些成员可以是不同的类型。
但是编译器只为最大的成员分配足够的内存空间。联合体的特点是所有成员共用同⼀块内存空间。所以联合体也叫:共用体。
给联合体其中⼀个成员赋值,其他成员的值也跟着变化。
2.联合体的特点和使用
联合体的成员是共用同⼀块内存空间的,这样⼀个联合变量的大小,至少是最大成员的大小(因为联合体至少得有能力保存最大的那个成员)。因为联合体的成员共用同⼀块内存空间的特性,所以给联合体其中⼀个成员赋值(或改变联合体其中⼀个成员的值),其他成员的值也会跟着变化。
示例如下:
#include <stdio.h>
union Un
{
char c;
int i;
};
int main()
{
union Un un = {
0 };
un.i = 0x11223344;
printf("%x\n", un.i);
un.c = 0x55;
printf("%x\n", un.i);
return 0;
}
3.联合体大小的计算
(1)联合体的大小至少是最大成员的大小。
(2)当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。
注:对齐数 = 编译器默认的一个对齐数 与 该成员变量大小的较小值。
(特殊情况:如果该成员变量是数组的话,数组的对齐数 = 编译器默认的一个对齐数 与 该数组中元素的大小的较小值)
-VS 中默认的值为 8
-Linux中 gcc 没有默认对齐数,对齐数就是成员自身的大小
例一:
#include <stdio.h>
union un1
{
char c[5];
int i;
};
int main()
{
printf("union un1的大小 = %zd\n", sizeof(union un1));
return 0;
}
联合体的第一个成员变量 c 是一个字符数组。数组的对齐数 = 编译器默认的一个对齐数 与 该数组中元素的大小的较小值。VS编译器中默认的值为 8,而该数组中元素的大小是1字节,比8小,所以数组 c 的对齐数是1
对齐数 = 编译器默认的一个对齐数 与 该成员变量大小的较小值。VS编译器中默认的值为 8,而 i 的大小是4字节,比8小,所以数组 i 的对齐数是4
因为联合体的大小至少是最大成员的大小,所以这个联合体的大小至少是5字节,但是联合体的大小还应该是最大对齐数4(数组 c 的对齐数是1,i的对齐数是4)的整数倍,所以该联合体的实际大小为8字节。
例二:
#include <stdio.h>
union un2
{
short c[7];
int i;
};
int main()
{
printf("union un2的大小 = %zd\n", sizeof(union un2));
return 0;
}
联合体的第一个成员变量 c 是一个短整型数组。数组的对齐数 = 编译器默认的一个对齐数 与 该数组中元素的大小的较小值。VS编译器中默认的值为 8,而该数组中元素的大小是2字节,比8小,所以数组 c 的对齐数是2
对齐数 = 编译器默认的一个对齐数 与 该成员变量大小的较小值。VS编译器中默认的值为 8,而 i 的大小是4字节,比8小,所以数组 i 的对齐数是4
因为联合体的大小至少是最大成员的大小,所以这个联合体的大小至少是14字节,但是联合体的大小还应该是最大对齐数4(数组 c 的对齐数是2,i的对齐数是4)的整数倍,所以该联合体的实际大小为16字节。
二、枚举类型
1.枚举类型的声明和使用
枚举顾名思义就是⼀⼀列举。把可能的取值⼀⼀列举。
比如我们现实生活中:
一周的星期一到星期日是有限的7天,可以一一列举
性别有男、女、保密,也可以一一列举
月份有12个月,也可以一一列举
三原色,也是可以一一列举
以上这些数据的表示就可以使用枚举了,示例如下:
enum Day//星期
{
Mon,
Tues,
Wed,
Thur,
Fri,
Sat,
Sun
};
enum Sex//性别
{
MALE,
FEMALE,
SECRET
};
enum Color//颜⾊
{
RED,
GREEN,
BLUE
};
以上定义的 enum Day , enum Sex , enum Color 都是枚举类型。
{ }中的内容是枚举类型的可能取值,也叫 枚举常量。
这些枚举常量都是有值的,默认从0开始,依次递增1,当然在声明枚举类型的时候也可以赋初值。 以下示例演示其使用:
例一:
#include <stdio.h>
enum Sex//性别
{
MALE,
FEMALE,
SECRET
};
int main()
{
printf("%d %d %d\n", MALE, FEMALE, SECRET);
return 0;
}
例二:
#include <stdio.h>
enum Sex//性别
{
MALE = 3,
FEMALE,
SECRET
};
int main()
{
printf("%d %d %d\n", MALE, FEMALE, SECRET);
return 0;
}
例三:
#include <stdio.h>
enum Sex//性别
{
MALE = 3,
FEMALE = 0,
SECRET
};
int main()
{
printf("%d %d %d\n", MALE, FEMALE, SECRET);
return 0;
}
2.枚举类型的优点
我们可以使用 #define(一种预处理指令) 定义常量,为什么非要使用枚举?
枚举的优点:
(1)增加代码的可读性和可维护性
(2)和#define定义的标识符比较枚举有类型检查,更加严谨。
(3)便于调试,预处理阶段会删除 #define 定义的符号
(4)使用方便,一次可以定义多个常量
(5)枚举常量是遵循作用域规则的,如果枚举声明在函数内,就只能在函数内使用