C语言自定义类型:联合体和枚举
C语言自定义类型:联合体和枚举
1.联合体
2.枚举
1.联合体
联合体类型的声明
像结构体一样,联合体也是由一个或者多个成员构成,这些成员可以是不同的类型。联合体的特点是所有成员共用同一块内存空间,编译器只为最大的成员分配足够的内存空间,所以联合体又叫“共用体”。
#include<stdio.h>
union Un //联合体类型的声明
{char c;int i;
};
int main()
{union Un u={0}; //联合体变量的定义return 0;
}
联合体的特点
- 联合体中所有成员共用一个内存,联合体的大小至少是最大成员的大小。
我们可以通过下面的代码看到,联合体变量u、联合体成员c、i的地址相同,且联合体的大小为4个字节。
#include<stdio.h>
union Un
{char c;int i;
};
int main()
{union Un u={0};printf("%p %p %p\n",&u.c,&u.i,&u);printf("%zd\n",sizeof(u)); return 0;
}
我们看下面代码:
#include<stdio.h>
union Un
{char c;int i;
};
int main()
{union Un u = { 0 }; u.i = 0x11223344;printf("%c %d\n", u.c, u.i);return 0;
}
把联合体成员 i 赋值为16进制的11223344,由于vs中数据在内存中是小端字节序存放,即内存中数据存放为44332211,联合体成员 c 占1个字节,所以 c 中存放的数据是16进制的44,而 i 中存放的数据还是16进制的11223344。
我们把联合体成员 c 赋值为0x55,代码和结果如下:
#include<stdio.h>
union Un
{char c;int i;
};
int main()
{union Un un = { 0 }; u.i = 0x11223344;u.c = 0x55;printf("%c %d\n", un.c, un.i);return 0;
}
这个时候内存中存放的数据就由44332211变为55332211,即 i 中存放的数据变为16进制的55332211,如图所示:
联合体大小计算
- 联合体的大小至少是最大成员的大小。
- 当成员的大小不是最大对齐数的整数倍时,要对齐到最大对齐数的整数倍。
例如:
#include <stdio.h>
union Un1
{char c[5];int i;
};
union Un2
{short c[7];int i;
};
int main()
{printf("%zd\n", sizeof(union Un1));printf("%zd\n", sizeof(union Un2));return 0;
}
分析Un1,联合体成员c占5个字节,c为char类型,i 为int类型,最大对齐数为4,所以联合体应占4的倍数即8个字节。
分析Un2,联合体成员c占14个字节,c为short类型,i为int类型,最大对齐数为4,所以联合体应占4的倍数即16字节。
联合体的使用
使用联合体是可以节省空间的,例如:礼品兑换单中有三种商品:图书、杯子、衬衫。
每⼀种商品都有:库存量、价格、商品类型和商品类型相关的其他信息。
- 图书:书名、作者、页数
- 杯子:设计
- 衬衫:设计、可选颜色、可选尺寸
我们把商品公共属性单独写出来,商品本身属性使用联合体,这样就能在一定程度上节省了内存。
struct Gift
{int stock_number; //库存量double price; //定价int item_type; //商品类型union Un{struct Book{char title[20]; //书名char author[20]; //作者int num_pages; //⻚数}b;struct Mug{design[30];}m;struct Shirt{char design[30]; //设计int colors; //颜⾊int sizes; //尺⼨}s;}item;
};
2.枚举
枚举类型就是把可能的值一一列举。例如列举三原色红绿蓝:
enum Color
{RED;GREEN;BLUE
};
花括号内的是枚举类型的可能取值,也叫枚举常量。枚举常量默认从0开始,依次递增1,当然在声明枚举类型的时候也可以赋初值。例如,把GREEN赋值为5,则RED为0,BLUE为6。
拙作一篇,望诸位同道不吝斧正。