C语言:深入了解(联合体和枚举)

目录

联合体

联合体的类型的声明

联合体的特点

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

联合体大小的计算

联合体的使用举例

联合体的类型:判断联合体是大端还是小端

枚举类型

枚举类型声明

枚举类型的优点

枚举类型的使用


联合体

联合体的类型的声明

像结构体⼀样,联合体也是由⼀个或者多个成员构成,这些成员可以不同的类型。

但是编译器只为最⼤的成员分配⾜够的内存空间。联合体的特点是所有成员共⽤同⼀块内存空间。所

以联合体也叫:共⽤体。

给联合体其中⼀个成员赋值,其他成员的值也跟着变化。

联合体输出的结果为什么是4呢?


联合体的特点

联合的成员是共⽤同⼀块内存空间的,这样⼀个联合变量的⼤⼩,⾄少是最⼤成员的⼤⼩(因为联合

⾄少得有能⼒保存最⼤的那个成员)。

联合体是共⽤同⼀块内存空间的所以不能同时使用联合体,不能同时使用

我们可以看到3个地址都是一样的。

cpp 复制代码
union a
{
	char a;
	int b;
};

int main()
{
	union a p = { 0 };
	printf("%zd\n", sizeof(union a));
	printf("%p\n", &p);
	printf("%p\n", &p.a);
	printf("%p\n", &p.b);

}

相同成员的结构体和联合体对比
cpp 复制代码
struct bp//结构体
{
	char a;
	int b;
};
cpp 复制代码
union ar//联合体
{
	char a;
	int b;
};


联合体大小的计算

联合的⼤⼩⾄少是最⼤成员的⼤⼩。

当最⼤成员⼤⼩不是最⼤对⻬数的整数倍的时候,就要对⻬到最⼤对⻬数的整数倍。


联合体的使用举例

⽐如,我们要搞⼀个活动,要上线⼀个礼品兑换单,礼品兑换单中有三种商品:图书、杯⼦、衬衫。

每⼀种商品都有:库存量、价格、商品类型和商品类型相关的其他信息

图书:书名、作者、⻚数

杯⼦:设计

衬衫:设计、可选颜⾊、可选尺⼨


下面这代码,当我们要描述一个杯⼦的时候,只用到公共属性和设计属性其他属性都没用这样非常浪费空间

cpp 复制代码
struct lx
{
	//公共属性
	int stock_number; //库存量
	double price; //定价
	int item_type; //商品类型
	//特殊属性
	char title[20]; //书名
	char author[20]; //作者
	int num_pages; //⻚数

	char design[30]; //设计

	int colors; //颜⾊
	int sizes; //尺⼨
};

上述的结构其实设计的很简单,⽤起来也⽅便,但是结构的设计中包含了所有礼品的各种属性,这样

使得结构体的⼤⼩就会偏⼤,⽐较浪费内存。因为对于礼品兑换单中的商品来说,只有部分属性信息

是常⽤的。⽐如:

商品是图书,就不需要design、colors、sizes。?

所以我们就可以把公共属性单独写出来,剩余属于各种商品本⾝的属性使⽤联合体起来,这样就可以

介绍所需的内存空间,⼀定程度上节省了内存。

下面这联合体在同一时间只能使用一次结构体,不能同时使用2个

cpp 复制代码
struct lx
{
	//公共属性
	int stock_number; //库存量
	double price; //定价
	int item_type; //商品类型

	//特殊属性
	union //不完全声明只能用一次
	{
		//同一时间只能用一次结构体,不能同时用2个

		struct //不完全声明只能用一次
		{
			char title[20]; //书名
			char author[20]; //作者
			int num_pages; //⻚数
		}shu;

		struct //只能用一次
		{
			char design[30]; //设计
		}bei;

		struct //只能用一次
		{
			int colors; //颜⾊
			int sizes; //尺⼨
		}chens;

	}tssx;

};

联合体的类型:判断联合体是大端还是小端

把1赋值给a,在内存中是小端存放的所以用char类型的来进行判断第一个字节是不是大端小端

cpp 复制代码
union a
{
	int a;
	char b;

};

int main()
{
	union a p = { 0 };
	p.a = 1;// 小端:01 00 00 00
	if (p.b == 1)//判断第1个字节是不是1
	{
		printf("小端\n");
	}
	else
	{
		printf("大端\n");
	}
}

枚举类型

枚举类型声明

枚举顾名思义就是⼀⼀列举。

把可能的取值⼀⼀列举。

⽐如我们现实⽣活中:

⼀周的星期⼀到星期⽇是有限的7天,可以⼀⼀列举?

性别有:男、⼥、保密,也可以⼀⼀列举

⽉份有12个⽉,也可以⼀⼀列举?

三原⾊,也是可以意义列举

cpp 复制代码
enum a//星期
{
	z1 = 1,//周1
	z2,//周2
	z3,//周3
	z4,//周4
	z5,//周5
	z6,//周6
	z7 //周7
};

enum r//性别
{
	nan,
	nv,
	bm
};

enum e//颜色
{
	RED,
	GREEN,
	BLUE
};

下面这枚举我们可以看到不赋值的话,是从0开始的


赋值的话可以打印赋值的数值


给其中一个赋值的话后面的都会递增1


枚举类型的优点

为什么使⽤枚举

我们可以使⽤ #define 定义常量,为什么⾮要使⽤枚举

枚举的优点:

  1. 增加代码的可读性和可维护性

  2. 和#define定义的标识符⽐较枚举有类型检查,更加严谨。

  3. 便于调试,预处理阶段会删除 #define 定义的符号

  4. 使⽤⽅便,⼀次可以定义多个常量

  5. 枚举常量是遵循作⽤域规则的,枚举声明在函数内,只能在函数内使⽤


枚举类型的使用
cpp 复制代码
//打印菜单
cd()
{
	printf("***************************\n");
	printf("****** 1.加法   2.减法 ****\n");
	printf("****** 3.除法   4.乘法 ****\n");
	printf("************ 0.退出 *******\n");
}
//枚举
enum p
{
	tc,//0
	jian,//1
	jia,//2
	chu,//3
	cheng//4
};
jian_ys(int a,int b)//加法
{
	int r = a + b;
	printf("%d\n", r);
}
jia_ys(int a, int b)//减法
{
	int r = a - b;
	printf("%d\n", r);
}
chu_ys(int a, int b)//除法
{
	int r = a / b;
	printf("%d\n", r);
}
cheng_ys(int a, int b)//乘法
{
	int r = a * b;
	printf("%d\n", r);
}
int main()
{
	int a = 0;
	int b = 0;
	int r = 0;
	do
	{
		//打印菜单
		cd();
		scanf("%d", &r);
		switch (r)
		{
		case tc:
			printf("退出\n");
			break;
		case jian://1
			printf("请输入2个数值:\n");
			scanf("%d %d", &a, &b);
			jian_ys(a,b);
			break;//2
		case jia:
			printf("请输入2个数值:\n");
			scanf("%d %d", &a, &b);
			jia_ys(a, b);
			break;
		case chu://3
			printf("请输入2个数值:\n");
			scanf("%d %d", &a, &b);
			chu_ys(a, b);
			break;
		case cheng://4
			printf("请输入2个数值:\n");
			scanf("%d %d", &a, &b);
			cheng_ys(a, b);
			break;
		default:
			printf("输入错误请重新输入\n");
			break;
		}
	} while (r);
}
相关推荐
Fairy_sevenseven11 分钟前
【二十八】【QT开发应用】模拟WPS Tab
开发语言·qt·wps
蜡笔小新星19 分钟前
Python Kivy库学习路线
开发语言·网络·经验分享·python·学习
凯子坚持 c19 分钟前
C语言复习概要(三)
c语言·开发语言
无限大.31 分钟前
c语言200例 067
java·c语言·开发语言
余炜yw33 分钟前
【Java序列化器】Java 中常用序列化器的探索与实践
java·开发语言
无限大.34 分钟前
c语言实例
c语言·数据结构·算法
篝火悟者34 分钟前
问题-python-运行报错-SyntaxError: Non-UTF-8 code starting with ‘\xd5‘ in file 汉字编码问题
开发语言·python
Death20036 分钟前
Qt 中的 QListWidget、QTreeWidget 和 QTableWidget:简化的数据展示控件
c语言·开发语言·c++·qt·c#
六点半88838 分钟前
【C++】速通涉及 “vector” 的经典OJ编程题
开发语言·c++·算法·青少年编程·推荐算法
惜.己38 分钟前
javaScript基础(8个案例+代码+效果图)
开发语言·前端·javascript·vscode·css3·html5