union解析及应用

前言

最近的项目中经常要用到共用体这种数据结构,但自己动手去写的时候,心里又毛毛的,好像还并没有完全掌握它。因此写下这篇文章,对这个知识点进行一次归纳整理,后续有想到新东西,再来补充。

union是啥?和共用体是啥关系?

union只是一个关键字,它是用来构成一种全新的变量类型的。这个关键字不能直接与像是int、char这样的关键字进行类比。因为像是char、int这样的关键字表示的就是一种变量类型,它们有确定的内存空间,而与它们相比,union这个关键字并不能明确出一个内存空间,它还需要一些“伙伴”才能明确出要占用多少空间。这些“伙伴”在C语言中我们称之为–成员。union关键字与它的成员结合在一起,构成了新的变量类型,这种新的变量类型,叫做共用体(联合体、联合类型),这个共用体才是能与int、char等关键字平起平坐的

创建一个共用体

创建共用体的意义就是告诉计算机你所规定的一种新的变量类型,这个过程不会开辟内存空间,也没有变量的概念。创建共用体有如下两种方法:

1.直接创建

union my_type
{
	unsigned char mem1;		//成员1
	unsigned int  mem2;		//成员2
	float mem3;				//成员3
};

2.用typedef

typedef union
{
	unsigned char mem1;		//成员1
	unsigned int  mem2;		//成员2
	float mem3;				//成员3
}my_type;

共用体创建的这几行代码可以按照char、int关键字来理解,下面定义的环节会更形象。

定义一个共用体类型的变量

那么如何才能使用一个共用体类型的变量呢?那就需要去定义一个共用体变量了,方法有如下3种:
1.基于直接创建的共用体类型

//1.直接创建一个共用体
union my_type
{
	unsigned char mem1;		//成员1
	unsigned int  mem2;		//成员2
	float mem3;				//成员3
};

//2.定义一个共用体变量variable1
union my_type variable1;

2.基于用typedef创建的共用体

//1.用typedef创建一个共用体
typedef union
{
	unsigned char mem1;		//成员1
	unsigned int  mem2;		//成员2
	float mem3;				//成员3
}my_type;

//2.定义一个共用体变量variable1
my_type variable1;

3.创建与定义同步进行,包含两种方式

//1.不写共用体名称
union
{
	unsigned char mem1;		//成员1
	unsigned int  mem2;		//成员2
	float mem3;				//成员3
}variable1;					//定义一个共用体变量variable1

//2.写共用体名称
union my_type
{
	unsigned char mem1;		//成员1
	unsigned int  mem2;		//成员2
	float mem3;				//成员3
}variable1;					//定义一个共用体变量variable1

以上三个例子中,my_type叫做所创建的共用体的名称(与共用体变量无关),mem1,mem2,mem3为其成员。而variable1为一个共用体变量。

共用体内存空间

这里可以与结构体进行比较,如果把结构体想象为一个小团体,里面就会有小明、小红、小芳等成员,那么共用体更像是一位“人格分裂症患者”,它有时候是小明,有时候是小红,有时候是小芳。本质在于共用体的内部变量占用的是同一块内存空间,由于是同一块内存空间,所以各个变量之间会有相互影响,所以在使用时,要注意使用场景。

共用体使用

我个人使用的场景种类不多,但是用法相对固定,将联合体与结构体以及位域结合使用,构成一种部分与整体联系很紧密的数据结构。比如说在控制多个继电器时,用位域与联合体结合使用,可以达到节省空间,掌控某个以及全部继电器的效果,示例如下:

//1.创建一个共用体
typedef union
{
	unsigned char relay_all;
	struct
	{
		unsigned char relay_0:1;
		unsigned char relay_1:1;
		unsigned char relay_2:1;
		unsigned char relay_3:1;
		unsigned char relay_4:1;
		unsigned char relay_5:1;
		unsigned char relay_6:1;
		unsigned char relay_7:1;
	}realy_single;
}u_realy_tpye;

//2.定义一个共用体变量
u_realy_type my_relay;//尚未初始化

解释一下这个my_relay这个变量,看起来也许有些复杂,没关系,一层层分析就好,2层的小套娃而已。

1.明确my_relay这个变量是一个共用体类型的。
2.这个共用体类型包含了两个成员:无符号字符型变量relay_all以及结构体类型变量realy_single。
3.无符号字符型好理解,重点剖析这个结构体类型的变量,此结构体包含了8个1位位域的无符号字符型变量,整个结构体的内存空间就是8位,也就是1个字节。
4.再回归到这个共用体类型,其包含的两个成员所占空间都是1个字节,是完全共用的空间,所以这个共用体类型所占空间也是1个字节。
tips.定义了my_relay这个变量后,基于它的结构,便可以很方便的控制这个变量所占内存空间的8个位中的任意一位以及整个字节。

共用体初始化

沿用上一部分的例子,来给my_relay进行初始化。
由于共用体的成员共享同一块内存空间,所以修改某一成员的值时,其它值也就决定了且各个成员间会彼此影响,因此共用体的初始化比较特殊:在初始化时,不能同时对所有成员进行初始化。有如下三种初始化手段:

1.默认初始化第一个成员:

u_realy_type my_relay = {0};

具体来讲,此种初始化会将共用体变量中的第一个成员,也就是relay_all这个变量给赋值为0,当然,由于两成员内存空间完全重叠,因此结构体变量realy_single中的每一个位成员变量也都是0。

2.直接用一个共用体初始化另一个共用体:

u_realy_type my_relay = {0};			//以第一种方式初始化的共用体
u_realy_type my_relay1 = my_relay;		//这个才是要介绍的以第二种方式就行的初始化

3.指定初始化成员(C99新特性)

u_realy_type my_relay = {.relay_all = 0};//由于楼主主要进行的是单片机开发,编译环境是MDK,这种方式总是报错,应该是我的编译环境不支持

以上就是共用体的三种初始化方式,我一般只用第一种,了解这种初始化方式后,会让你对成员变量的顺序安排上有更多思考~

总结

本文详细的介绍了union、共用体(联合体、联合类型)间的区别与联系,通过实例的方式对共用体类型的创建、定义以及初始化进行了讲解,以达到读者可以快速上手共用体的目的!
如果本文对你有用,请点个赞吧,这是对我莫大的支持,当然也更欢迎评论区留言讨论以及收藏哦~
祝:变得更强!

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值