阅读量:2
导言
在C语言中除了结构体外,联合体和枚举也是自定义类型,联合体主要用于节省空间,在同一块内存存储多种类型的数据,而枚举可以提高代码的可读性、可维护性。
联合体(union)
它还有个更容易理解的名字:“共用体”,它有多个成员,成员可以为不同类型,但是编译器只会给最大的成员分配内存空间,所有成员共用一块空间。
联合体的创建
//联合体的创建 union un { int x; int y; }; int main() { union un tmp = { 0 }; return 0; }
联合体的初始化
联合体的初始化只能对整个联合体进行初始化,因为所有联合成员共用一块内存,初始化后所有的成员都是这个值,不管成员类型是否一致。
联合体的访问与结构体一致,这里不再介绍
联合体的大小
联合体大小计算规则:
●联合体大小最少为最大成员的大小
●当最大成员的大小不为最大对齐数的整数倍时,联合体大小要对齐到最大对齐数的整数倍
示例:
值得注意的是:在计算数组的对齐数时,与默认数比较的不是整个数组的大小,而是数组单个元素的大小。
联合体的运用
1.假如一家商店要进一批货,分别为书、卡牌、玩具。这三样物品都有公共属性和私有属性
公共属性:进货量、价格、生产年份
私有属性:
●书:作者、页数、版号
●卡牌:形状(圆或方)
●玩具:颜色、尺寸
使用结构体定义:
struct goods { //公共属性:进货量、价格、生产年份 int count; int price; int year; //私有属性: //书:作者、页数、版号 char name[20]; int pages; int vn; //卡牌:形状(圆或方) int shape; //玩具:颜色、尺寸 char color[10]; int size; };//占用空间60字节
使用联合体定义:
struct goods { //公共属性:进货量、价格、生产年份 int count; int price; int year; //私有属性: union { struct { //书:作者、页数、版号 char name[20]; int pages; int vn; }book; struct { //卡牌:形状(圆或方) int shape; }card; struct { //玩具:颜色、尺寸 char color[10]; int size; }toy; }item; };//占用空间40字节
在这个例子中使用结构体占用了60字节,使用联合体却只用了40字节,第二种方法声明比较复杂,我们怎么来对它进行初始化呢?
struct goods { //公共属性:进货量、价格、生产年份 int count; int price; int year; //私有属性: union { struct { //书:作者、页数、版号 char name[20]; int pages; int vn; }book; struct { //卡牌:形状(圆或方) int shape; }card; struct { //玩具:颜色、尺寸 char color[10]; int size; }toy; }item; };//占用空间40字节 int main() { struct goods goods_1 = { 10,30,2005,.item.book = {"yuhua",200,1998} }; //这里初始化了结构体goods中,公共属性中的进货量、价格、生产年份, // 以及联合体item中的结构体book三个成员:作者、页数、版号 return 0; }
2.通过联合体其数据类型互换的特性,完成对大小端字节序的判断
union un { char a; int b; //定义一个拥有char型和int型的联合体,来观察其大小端字节序 }; int main() { union un un1 = { 0x11223344 }; //存入16进制数0x11223344来观察,小端存储:0X44332211、大端存储:0X11223344 printf("%#X", un1.a);//使用联合体成员char a,来打印第一个字节内容来观察大小端 return 0; }
运行结果:
小端存储。
枚举(enum)
枚举顾名思义:一一列举。
我们可以为一组数值定义相同类型的符号名(枚举常量),如:
周一到周日、一月到十二月、三原色等。
枚举的创建
//枚举的创建 enum en { monday,//注意枚举常量后面是“,”逗号,从0开始 tuesday, wednesday, thursday, friday, saturday, sunday, };
枚举常量在创建时是有初值的,默认从0开始,步长为1.
也可更改:
枚举的声明以及使用