union(联合体、结构体)的简介与使用

以前在学习C语言或C++的时候,只学习了一些常用的语法。对于一些少见的本着后面遇到了再来学的目的,就没有去学习过。

今天早上看群里面有人问,float怎么转换为4个字节。我一想,这不是我以前做协议解析时候的问题吗,当时我是用指针强制转换的方法去实现的。方法就像下面那代码片段一样。

//转换float数据到字节数组
unsigned char i;
float floatVariable;
unsigned char charArray[4];
(unsigned char) *pdata = ((unsigned char)*)&floatVariable;  //把float类型的指针强制转换为unsigned char型
for(i=0;i<4;i++)
{
    charArray[i] = *pdata++;//把相应地址中的数据保存到unsigned char数组中     
}
//转换字节数组到float数据
float   floatVariable;
unsigned char  i; 
void   *pf;     
pf = &floatVariable; 
(unsigned char) * px = charArray;  
for(i=0;i<4;i++)
{
    *(((unsigned char)*)pf+i)=*(px+i);     
} 

过了一会儿,另一个人在群里说了,联合体的方法非常好用。当然好学的我,又要问了,什么是联合体,什么是union。一段时间过去了,并没有人回我(可能是因为太早了,今天早上醒的比较早,看群也比较早)。奈何没人给我讲啊,我就只有自己去百度了。

下面开始正文,上面全是白扯。。。


union 叫共用体,又叫联合、联合体。“联合体”是一种特殊的类,也是一种构造类型的数据结构。在一个“联合体”内能够定义多种不同的数据类型。一个被说明为该“联合体”类型的变量中。同意装入该“联合体”所定义的不论什么一种数据。这些数据共享同一段内存,以达到节省空间的目的。
说了这么多,到底什么是联合体呢,就是在这个数据结构内,会有多种不同的数据,这些数据共同拥有同一段内存。。。好吧,可能感觉还不是很懂。看下面的代码片段,你可能就懂了。

typedef struct
    {
        unsigned char Red;
        unsigned char Green;
        unsigned char Blue;
    }RGB_Typedef;

    typedef union
    {
        RGB_Typedef rgb;
        unsigned int value;
    }Pix_Typedef;

这就声明了一个结构体和一个联合体,联合体内部包含了一个结构体和一个无符号整形数据(32位的)。刚刚我们说了联合体内部的数据共享同一段内存,意思就是说联合体内部的结构体的首地址和无符号整形数据的首地址是相同的,不信?你看下面的片段。

#include "stdio.h"

typedef struct
{
    unsigned char Red;
    unsigned char Green;
    unsigned char Blue;
}RGB_Typedef;

typedef union
{
    RGB_Typedef rgb;
    unsigned int value;
}Pix_Typedef;

void main()
{
    Pix_Typedef pix;
    printf("%x\r\n",&pix.rgb);
    printf("%x\r\n",&pix.value);
}

运行结果截图:

可以清晰的看到,联合体里面的结构体和无符号整形数据是相同的。

我们知道了联合体的功能了,那么到底会有一些怎么样的应用呢?

我们都知道RGB三原色是有红、绿、蓝各占一个字节(0-255)表示的,有些时候,我们需要单独去R、G、B三个色值,有些时候,又需要合在一起使用。难道我们每一次使用的时候,都对数据进行拆分、融合?这样实在是太麻烦了。我们就可以利用联合体的方式来定义三原色。

声明一个结构体包含三原色,然后在声明一个联合体包含前一个结构体和三原色融合的数值。如下图所示。

typedef struct
{
	unsigned char Red;
	unsigned char Green;
	unsigned char Blue;
}RGB_Typedef;

typedef union
{
	RGB_Typedef rgb;
	unsigned int value;
}Pix_Typedef;

如果我们定义三原色分别为0X11、0X22、0X33,然后不再做任何处理,直接打印value。会是怎么一种情况。代码如下

#include "stdio.h"

typedef struct
{
	unsigned char Red;
	unsigned char Green;
	unsigned char Blue;
}RGB_Typedef;

typedef union
{
	RGB_Typedef rgb;
	unsigned int value;
}Pix_Typedef;

void main()
{
	Pix_Typedef pix;
	pix.rgb.Blue=0X33;
	pix.rgb.Green=0X22;
	pix.rgb.Red=0X11;
	printf("%X\r\n",pix.value);
}

运行结果如下图:

这里需要说明一下的是,unsigned int 是一个4字节数据,而前面我们只定义了三个unsigned char ,只占三个字节。所以MSB自动补齐了。在union中,分配内存空间的大小,等于占内存最大的数据类型字节大小。

在上面,我们已经看到可以直接通过定义R、G、B值,来修改融合后的值。当然,反过来也是可以的。我们首先对value赋值,然后再输出R、G、B值。代码如下:

#include "stdio.h"

typedef struct
{
	unsigned char Red;
	unsigned char Green;
	unsigned char Blue;
}RGB_Typedef;

typedef union
{
	RGB_Typedef rgb;
	unsigned int value;
}Pix_Typedef;

void main()
{
	Pix_Typedef pix;
	pix.value = 0X00123456;
	printf("%X\r\n",pix.rgb.Red);
	printf("%X\r\n",pix.rgb.Green);
	printf("%X\r\n",pix.rgb.Blue);
}

运行结果如下图:

由此,可以说明,无论是修改结构体,还是修改unsigned int ,都会对对方造成影响。因为他们是共享同一段内存

 

上面讲了union在三原色中的应用,现在我们继续来讲如何利用union来做flaot 和 Byte 之间的转换。

首先在union当初定义一个unsigned char 类型的数组,元素为4个,在定义一个float 类型数据。然后再对数组中的每一个元素进行赋值,最后直接打印float数据。代码如下:

#include "stdio.h"

typedef union 
{
	unsigned char Byte[4];
	float Float;
}Float_Byte;

void main()
{
	Float_Byte fb;
	fb.Byte[0] = 0x00;
	fb.Byte[1] = 0x00;
	fb.Byte[2] = 0x48;
	fb.Byte[3] = 0x42;
	printf("%f\r\n",fb.Float);
}

运行结果如图:

由此可见,用union来做float与Byte转换时完全可行,甚至简单的。只需要注意好内存对齐。

由Byte转换为float已经推荐给大家了,至于float转Byte大家可以自己想想。

有点累了,今天起的太早,睡个午觉。。。。。。

 

 

如有不足之处或者是更好的处理建议,请与作者联系。QQ:945116700 邮箱 :duo_lin0119@163.com

谢谢各位的阅读


   


 

  • 91
    点赞
  • 300
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 18
    评论
### 回答1: 结构体(struct)和联合体union)都是C语言中用于定义自定义数据类型的方式,它们的区别在于: 1. 结构体中的各个成员在内存中是分开存储的,而联合体中的各个成员在内存中是共用同一块空间的。 2. 结构体的大小至少是其各个成员大小之和,因为每个成员都需要占用一定的内存空间,而联合体的大小则是其最大成员的大小,因为联合体中只有一个成员会被使用,其它成员则会被浪费。 3. 结构体中的各个成员可以同时被访问和修改,而联合体中只有一个成员可以被访问和修改。 4. 结构体可以存储不同类型的成员,而联合体只能存储同一类型的成员。 总之,结构体适合用于存储多个不同类型的数据,而联合体适合用于存储多个相同类型的数据,且只有一个数据会被使用的情况。 ### 回答2: 结构体struct和联合体union都是在C语言中用来组织多个不同类型的变量的一种方式。它们的区别在于变量的存储方式和内存占用。 结构体struct是一种可以存储不同类型的变量的自定义数据类型。它通过定义多个不同类型的变量,并将它们组合在一起,形成一个新的类型。结构体中的每个成员变量都使用独立的内存空间,大小根据成员变量的类型而定。结构体的成员可以同时存在于内存中,因此结构体可以存储和处理多个不同类型的数据。 联合体union也是一种可以存储不同类型的变量的自定义数据类型。它与结构体不同的是,联合体的成员变量共享同一块内存空间,也就是说,联合体的各个成员变量会在同一时间占用该内存空间。联合体的内存空间大小会根据最大的成员变量类型来决定。而为了节约内存空间,联合体只能同时存储和处理一个成员的数据。 结构体联合体使用方式也不同。结构体通常用于组织多个相关的变量,可以同时访问和修改结构体的各个成员变量。而联合体通常用于存储不同类型的变量,根据不同的需求来访问和修改特定的成员变量。 综上所述,结构体联合体在存储方式、内存占用和使用方式上都有所不同,开发者要根据实际需求选择合适的数据类型。 ### 回答3: 结构体struct和联合体union是C语言中的两种复合数据类型。 结构体struct允许将不同类型的变量(如整型、字符型、浮点型等)组合在一起,形成一个逻辑上的整体。它可以定义多个成员变量,每个成员变量可以有不同的数据类型和名称。通过使用结构体,可以更方便地管理和操作相关的数据。 而联合体union也是用来组合不同类型的变量,不同于结构体的是,联合体的所有成员变量都共享同一块内存空间。联合体的大小取决于成员变量中占用内存空间最大的数据类型。只能同时使用其中的一个成员变量,存取一个成员变量会覆盖之前存入的值。通过使用联合体,可以节省内存空间,但在数据使用时需要小心,确保不会出现意外的数据覆盖。 总结来说,结构体struct和联合体union的区别是: 1. 结构体允许不同类型的成员变量,而联合体中的成员变量必须是相同的类型。 2. 结构体的成员变量占用不同的内存空间,联合体的成员变量共享同一块内存空间。 3. 结构体的大小等于所有成员变量所占内存空间的总和,联合体的大小等于最大的成员变量所占内存空间。 4. 结构体的所有成员变量可以同时使用,而联合体只能同时使用一个成员变量。 5. 结构体适用于存储和操作不同类型的相关数据,联合体适用于节省内存空间、只需存取其中一个成员变量的情况下。
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Lucas_zgp

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值