【C语言学习】联合体和枚举

AI助手已提取文章相关产品:

一、什么是联合体

联合体(union)同结构体一样,是一种用户自定义数据类型,它允许在同一段内存空间中存储不同类型的数据(如int、float、char等),但同一时间只能存储其中一种类型的值。

二、联合体的声明

像结构体一样,联合体也是由一个或者多个成员构成,这些成员可以不同的类型。但是编译器只为最大的成员分配足够的内存空间。联合体的特点是所有成员共用同一块内存空间。所以联合体也叫:共用体。
给联合体其中某一个成员赋值,其他成员的值也跟着变化。

#include <stdio.h>

struct S
{
	int i;
	char c;
};

union Un
{
	int i;
	char c;
};

int main()
{
	printf("%zu\n", sizeof(struct S));
	printf("%zu\n", sizeof(struct Un));
	return 0;
}

运行结果:
在这里插入图片描述

2.2 联合体的特点

//联合体类型声明
union Un
{
	char c;
	int i;
};
int main()
{
	//联合体变量的定义
	union Un un = { 0 };
	//下面输出的结果一样吗?
	printf("%p\n", &(un.i));
	printf("%p\n", &(un.c));
	printf("%p\n", &un);
	return 0;
}

运行结果:
在这里插入图片描述
分析:
un、un.c、un.i其实是同一个地址。
在这里插入图片描述
分别对i、c进行修改:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.3 相同成员结构体和联合体对比

在这里插入图片描述
s、u在内存中的布局如下:
在这里插入图片描述
在这里插入图片描述

2.4 联合体大小的计算

联合体大小遵循下面规则:
①联合的大小至少是最大成员的大小。
②当最大成员的大小不是最大对齐数的整数倍,就要对齐到最大对齐数的整数倍。

2.5 联合体使用

2.5.1 礼品兑换单

礼品兑换单中有三种商品:图书、杯子、衬衫。 每种商品都有:库存量、价格、商品类型三种性质。另外,它们还有自身特性:
图书:书名、作者、页数
杯子:设计
衬衫:设计、可选颜色、可选尺寸
按照结构体设计:

struct gift_list
{
	//公共属性
	int capacity;
	float price;
	char commodity_type;

	//自身的特性
	//book
	struct book
	{
		char name[50];
		char color[20];
		int num;
	}text;

	//cup
	struct cup
	{
		char design[50];
	}mug;

	//T-shirt
	struct shirt
	{
		char design[50];
		int color[20];
		char size[5]
	}blouse;
};

但是按照这种方式写并不好,结构体的设计中包含了所有礼品的各种属性,这样使得结构体会偏大,比较浪费内存。对于礼品兑换单中的商品来说,只有部分属性是自己的,其他的用不到。把下面的自身属性封装到联合体中会好很多。

struct gift_list
{
	//公共属性
	int capacity;
	float price;
	char commodity_type;

	//自身特性
	//book
	union U
	{
		struct book
		{
			char name[50];
			char color[20];
			int num;
		}text;

	//cup
	struct cup
	{
		char design[50];
	}mug;

	//T-shirt
	struct shirt
	{
		char design[50];
		int color[20];
		char size[5]
	}blouse;
	};
};

2.5.2 判断当前机器的大小端字节序

union U
{
	int n;
	char c;
}u;

int main()
{
	u.n = 1;
	if(u.c == 1)
	{
		printf("小端\n");
	}
	else
		printf("大端\n");
	return 0;
}

u.n = 1相当于把0x00000001存入n中,在联合体u中,c和n共用低地址的空间,通过u.c就能够拿到低地址的内容,如果拿到的是1,说明是小端字节序;反之,如果拿到的结果是0,说明是大端字节序。

二、枚举

2.1 什么是枚举

枚举是一种数据类型,用于定义一组固定、有名称的常量集合,核心是“通过有意义的名称”代替“无意义的数值/字符串”,让代码更易读、更规范。

2.2 枚举的声明

生活中可以列举的值:周一到周天、性别、月份、三原色(RGB)。
枚举关键字:enum

enum day
{
	Mon,
	Tues,
	Wed,
	Thur,
	Fri,
	Sat,
	Sun
};

与结构体不同:大括号里面是可能得取值,是常量。

#include <stdio.h>

int main()
{
	printf("%d", Mon);
	printf("%d", Tues);
	printf("%d", Wed);
	printf("%d", Thur);
	printf("%d", Fri);
	printf("%d", Sat);
	printf("%d", Sun);
}

运行结果:
在这里插入图片描述

2.3 枚举的优点

1.增加代码的可读性和可维护性。
2.和#define定义的标识符相比,枚举有类型检查,更加严谨。
3.便于调试,预处理阶段会删除 #define 定义的符号。
4.使用方便,一次可以定义多个常量。
5.枚举常量是遵循作用域规则的,枚举声明在函数内,只能在函数内使用。
用心感受!

您可能感兴趣的与本文相关内容

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值