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

union(联合体、结构体)的简介与使用以前在学习 C 语言或 C 的时候 只学习了一些常用的语法 对于一些少见的本着后面遇到了再来学的目的 就没有去学习过 今天早上看群里面有人问 float 怎么转换为 4 个字节 我一想 这不是我以前做协议解析时候的问题吗 当时我是用指针强制转换的方法去实现的 方法就像下面那代码片段一样 转换 float 数据到字节数组 unsignedchar floatfloatVa u

以前在学习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。一段时间过去了,并没有人回我(可能是因为太早了,今天早上醒的比较早,看群也比较早)。奈何没人给我讲啊,我就只有自己去百度了。

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


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); }

运行结果截图:

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

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

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

我们都知道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); }

运行结果如下图:

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

这里需要说明一下的是,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 = 0X00; printf("%X\r\n",pix.rgb.Red); printf("%X\r\n",pix.rgb.Green); printf("%X\r\n",pix.rgb.Blue); }

运行结果如下图:

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

由此,可以说明,无论是修改结构体,还是修改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(联合体、结构体)的简介与使用

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

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

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

 

 

如有不足之处或者是更好的处理建议,请与作者联系。: 邮箱 :

谢谢各位的阅读

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/220259.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月17日 下午8:53
下一篇 2026年3月17日 下午8:53


相关推荐

  • srvctl start_执行命令ls>c

    srvctl start_执行命令ls>cSRVCTL概述SRVCTL是ORACLERAC集群配置管理的工具,可以管理Database、Instance、ASM、Service、Listener和NodeApplication,NodeApplication包括GSD,ONS,VIP。srvctl的命令格式为srvctl&lt;command&gt;&lt;target&gt;[options]srvctlUs…

    2025年10月28日
    2
  • 树莓派新手教程_新手入门树莓派必做的四件事

    树莓派新手教程_新手入门树莓派必做的四件事此篇文章獻給所有第一次把玩樹莓派的新手、以及樹莓派的愛好者。&amp;nbsp;ByHerbfargus-Ownwork,CCBY-SA4.0,https://commons.wikimedia.org/w/index.php?curid=47497384&amp;nbsp;目標建立一個省電的家用伺服器&amp;nbsp;小弟選用樹莓派作為家用伺服器,…

    2022年10月14日
    4
  • Spring SpringMVC SpringBoot 常用注解说明

    Spring SpringMVC SpringBoot 常用注解说明SpringSpring 常用注解说明 Spring 注解与 xml 配置的区别不使用注解的案例 Autowired Qualifier Resource Service 使用注解来构造 IoC 容器 Component Controller Service RepositorySp 常用注解汇总 SpringMVC Controller RequestMappi 使用

    2026年3月17日
    3
  • SpringBoot常见面试问题

    SpringBoot常见面试问题博客转载自:https://blog.csdn.net/ityouknow/article/details/96533522随着SpringBoot使用越来越广泛,SpringBoot已经成为Java程序员面试的知识点,很多同学对SpringBoot理解不是那么深刻,经常就会被几个连环跑给干趴下了!比如下面这一段的SpringBoot问答:问:你觉得S…

    2022年6月4日
    42
  • git/github使用完整教程(1)基础

    git/github使用完整教程(1)基础安装git在Linux上安装Git首先输入git,看看系统有没有安装Git:$gitTheprogram’git’iscurrentlynotinstalled.Youcaninstallitbytyping:sudoapt-getinstallgit像上面的命令,有很多Linux会友好地告诉你Git没有安装,还会告诉你如何安装Git。如果是其他Linux版本,可以直接通过源码安装。先从Git官网下载源码,然后解压,依次输入:./config,ma

    2022年5月4日
    61
  • jquery删除添加输入文本框

    效果体验:http://hovertree.com/texiao/jquery/67/效果图:参考:http://hovertree.com/h/bjaf/traversing_each.htm代码如

    2021年12月24日
    50

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号