【C语言】(18)自定义类型——联合和枚举

目录

一、联合体(共用体)

(1)联合体类型的声明

(2)联合体类型的特点

(3)联合体和结构体的比较

(4)联合体大小的计算

(5)联合体的应用

二、枚举类型

(1)枚举的声明

(2)枚举的优点

(3)枚举类型的使用


 

一、联合体(共用体)

(1)联合体类型的声明

        形式上跟结构体相似,只不过把 struct 改为 union:

union U
{
	char c;//1 
	int i; //4
};

(2)联合体类型的特点

  •  只为需要空间最大的成员分配足够的空间。
  •  成员共用一个空间(因此,联合体又叫共用体)。

3e413c415d8a4e1ca220971f07061c66.png

        以上代码,联合体大小是成员 i (所需空间最大的成员)的大小;联合体、每个成员的地址都是 004FFA90(成员共用一个空间)。如下所示:

e46803cca57042e4aab097c20170b4aa.png

        更改成员 c 的值,成员 i 的值也会改变:

97892722ff0b4dd68b206e0ee0bb0fa3.png

78d6eaee026d46f5b19f3549425dc515.png

(3)联合体和结构体的比较

// 结构体
struct S
{
 char c;
 int i;
};

// 联合体
union Un
{
 char c;
 int i;
};

        内存对比:

5dc3e5b59261499ab3c04d4153a19d22.png

        看应用场景选择使用结构体还是联合体,应用见(5)。

(4)联合体大小的计算

  •  联合体的大小至少是最大成员的大小。
  •  当联合体大小不是最大对齐数的整数倍时,就需要对齐到最大对齐数的整数倍。

        例子:

b1712ad28ecf49fdaa3c77af98cd55b7.png

(5)联合体的应用

        联合体适用于不需要给每个成员开辟空间,且成员不需要同时使用的场景,可以节省空间。例1:存储商品的信息,如下(蓝色部分是三种商品共有的信息):

9ee16a6788c54ab9b495dbe79a87b9d5.png

        如果直接用结构体类型存储,如下:

struct gift_list
{
	//公共属性
	int stock_number;//库存量
	double price; //定价
	int item_type;//商品类型

	//特殊属性
	char title[20];//书名
	char author[20];//作者
	int num_pages;//⻚数

	char design[30];//设计
	int colors;//颜色
	int sizes;//尺寸
};

        定义商品变量时,图书不需要设计、颜色、尺寸信息;杯子不需要书名、作者、页数等信息。使用结构体类型,会浪费很多空间。

        我们可以把共有的信息单独写出来,三种特殊的信息用联合体存储(只为最大的特殊信息开辟空间),就能节省空间,如下:

struct gift_list
{
	int stock_number;//库存量
	double price; //定价
	int item_type;//商品类型

    // 只给 item.book 分配空间
	union {
		struct
		{
			char title[20];//书名
			char author[20];//作者
			int num_pages;//⻚数
		}book;
		struct
		{
			char design[30];//设计
		}mug;
		struct
		{
			char design[30];//设计
			int colors;//颜⾊
			int sizes;//尺⼨
		}shirt;
	}item;
};

例2:判断当前机器是大端还是小端。

方法1:

int check_sys()
{
    // 1的十六进制(int为4字节):0x00 00 00 01
    // 地址从左向右递增
    // 大端:00 00 00 01(低位数据放高地址)
    // 小端:01 00 00 00(地位数据放低地址)
	int a = 1;
	if (*(char*)&a == 1) // 取最低的一个字节数据
		return 1; // 01,小端
	else
		return 0; // 00,大端
}

方法2(用联合体):

dc739562fb6642728a4c76044e6b6dfb.png

二、枚举类型

(1)枚举的声明

        枚举就是 一 一 列举,其声明形式如下:

enum Day//星期
{
	Mon, // 枚举常量
	Tues,
	Wed,
	Thur,
	Fri,
	Sat,
	Sun
};

enum Sex//性别
{
	MALE,
	FEMALE,
	SECRET
};

        包含的内容是枚举类型可能的取值,称为枚举常量(只能是整数)。枚举常量的取值,默认从0开始依次递增,也可以赋初值:

aff313905f144536b9f4da36bfd2feb3.png

2827d2ffdb4f45cd92c2ff4fda6bb93a.png

e26faa9f747b443c82be0d41c88ad7ca.png

(2)枚举的优点

  •  增加了代码的可读性和可维护性。
// 如果用变量代表性别
int sex = 0; // 0 表示男,1表示女,2表示保密
// 判断是否是男性
if(sex == 0)
    printf("yse");
// 明显,0、1、2 的含义不直观


// 如果用枚举代表性别
enum Sex
{
	MALE, 
	FEMALE,
	SECRET
};
enum Sex sex = MALE;
// 判断是否是男性
if(sex == MALE)
    printf("yse");
// MALE就是男,可读性明显增强
  •  和 #define 定义的标识符比较,枚举有类型检查,更加严谨,不易出错。
#define MALE 0
#define FEMALE 4
// 宏定义只是在编译时,用 0 替换 MALE,MALE 没有类型

enum Sex
{
	MALE, 
	FEMALE,
	SECRET
};
// 而枚举中的 MALE 有类型,就是 enum Sex
  •  使用方便,一次可以定义多个常量。
#define MALE 0
#define FEMALE 1
#define SECRET 2
// 宏定义要多次写 #define,并且值也要自己设置

enum Sex
{
	MALE, 
	FEMALE,
	SECRET
};
// 而枚举只需要在一个枚举类型里,加一个枚举常量名,自动赋值。
  •  枚举常量是遵循作用域规则的,枚举声明在函数内,只能在函数内使用(宏定义只能全局)。

(3)枚举类型的使用

        在 C 语言中可以拿整数给枚举变量赋值;但 C++ 的类型检查更严谨,不能拿整数给枚举变量赋值。

        C 中:

0f5ab75cc3ce4ae0a99d58ad0cd5cede.png

        C++ 中:

5a7141fedf4e43d39ab9eed34d5b229c.png

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值