0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

结构体、联合体嵌套使用的实用操作

Q4MP_gh_c472c21 来源:嵌入式大杂烩 作者:嵌入式大杂烩 2022-04-18 14:35 次阅读

结构体、联合体是C语言中的构造类型,结构体我们平时应该都用得很多。但是,对于联合体,一些初学的朋友可能用得并不多,甚至感到陌生。我们先简单看一下联合体:

在C语言中定义联合体的关键字是union

定义一个联合类型的一般形式为:

union联合名
{
成员表
};

成员表中含有若干成员,成员的一般形式为:类型说明符 成员名。其占用的字节数与成员中最大数据类型占用的字节数。

下面我们一起看一下结构体、联合体结合使用在C语言、嵌入式中的一些实用技巧。

1、应用于管理不同的数据

示例代码:

enumDATA_PKG_TYPE
{
DATA_PKG1=1,
DATA_PKG2,
DATA_PKG3
};

structdata_pkg1
{
//...
};

structdata_pkg2
{
//...
};

structdata_pkg3
{
//...
};

structdata_pkg
{
enumDATA_PKG_TYPEdata_pkg_type;
union
{
structdata_pkg1data_pkg1_info;
     structdata_pkg2data_pkg2_info;
     structdata_pkg3data_pkg3_info;
}data_pkg_info;
};

这里把struct data_pkg1、struct data_pkg2、struct data_pkg3三个结构体放到了struct data_pkg这个结构体里进行管理,把data_pkg_type与union里的三个结构体建立一一对应关系,我们需要用哪一结构体数据就通过data_pkg_type来进行选中。

在进行数据组包的时候,先给data_pkg_type进行赋值,确定数据包的类型,再给对应的union里的结构体进行赋值;在进行数据解析的时候,通过data_pkg_type来选择解析哪一组数据。

思考一下,如果在union里面再嵌套一层union会怎么样?会变得更复杂?以前的话,我会觉得越嵌套会越复杂,我也很抵制这种不断嵌套的做法。但后来看了我同事鱼鹰的设计之后,我惊呆了!这可太秀了,他就是这么嵌套使用把原本复杂的系统数据管理得明明白白的。我们看他怎么设计的(看个大概的图):

8df7a17c-bed7-11ec-9e50-dac502259ad0.png

可以看到最左边和最右边这就建立起了一一对应关系,我们的模块很多,数据很多,但是在这样的设计中显得很清晰、很容易维护。

2、寄存器、状态变量封装

我们看一看TI的寄存器封装是怎么做的:

8dffe58a-bed7-11ec-9e50-dac502259ad0.jpg

所有的寄存器被封装成联合体类型的,联合体里边的成员是一个32bit的整数及一个结构体,该结构体以位域的形式体现。这样就可以达到直接操控寄存器的某些位了。比如,我们要设置PA0引脚的GPAQSEL1寄存器的[1:0]两位都为1,则我们只操控两个bit就可以很方便的这么设置:

GpioCtrlRegs.GPAQSEL1.bit.GPIO0=3

或者直接操控整个寄存器:

GpioCtrlRegs.GPAQSEL1.all|=0x03

位域相关文章:【C语言笔记】位域

如果不是工作于芯片原厂,寄存器的封装应该离我们很远。但我们可以学习使用这种方法,然后用于我们的实际应用开发中。

下面就看一种实际应用:管理一些状态变量

示例代码:

unionsys_status
{
uint32all_status;
struct
{
boolstatus1:1;//FALSE/TRUE
boolstatus2:1;//
boolstatus3:1;//
boolstatus4:1;//
boolstatus5:1;//
boolstatus6:1;//
boolstatus7:1;//
boolstatus8:1;//
boolstatus9:1;//
boolstatus10:1;//
//...
}bit;
};

之前记得群里有一位小伙伴问系统有几十个状态变量需要管理,怎么做比较好。如上例子就是比较好的一种管理方法。

3、数据组合/拆分、大小端

(1)验证大小端

#include

typedefunsignedintuint32_t;
typedefunsignedcharuint8_t;

unionbit32_data
{
uint32_tdata;
struct
{
uint8_tbyte0;
uint8_tbyte1;
uint8_tbyte2;
uint8_tbyte3;
}byte;
};

intmain(void)
{
unionbit32_datanum;

num.data=0x12345678;

   if(0x78==num.byte.byte0)
   {
    printf("Littleendian
");
   }
   elseif(0x78==num.byte.byte3)
   {
    printf("Bigendian
");
   }else{}

return0;
}

运行结果:

8e0fa132-bed7-11ec-9e50-dac502259ad0.png

(2)数据组合、拆分

这其实也就是上一篇文章《面试题 | 获取整数各个字节》介绍的。在数据组合与拆分之前首先需要确实当前平台的大小端。比如小编使用的平台是小端模式

① 把0x12345678拆分成0x78、0x56、0x34、0x12:

#include

typedefunsignedintuint32_t;
typedefunsignedcharuint8_t;

unionbit32_data
{
uint32_tdata;
struct
{
uint8_tbyte0;
uint8_tbyte1;
uint8_tbyte2;
uint8_tbyte3;
}byte;
};

intmain(void)
{
unionbit32_datanum;

num.data=0x12345678;

printf("byte0=0x%x
",num.byte.byte0);
printf("byte1=0x%x
",num.byte.byte1);
printf("byte2=0x%x
",num.byte.byte2);
printf("byte3=0x%x
",num.byte.byte3);

return0;
}

运行结果:

8e197c0c-bed7-11ec-9e50-dac502259ad0.png

② 把0x78、0x56、0x34、0x12组合成0x12345678:

#include

typedefunsignedintuint32_t;
typedefunsignedcharuint8_t;

unionbit32_data
{
uint32_tdata;
struct
{
uint8_tbyte0;
uint8_tbyte1;
uint8_tbyte2;
uint8_tbyte3;
}byte;
};

intmain(void)
{
unionbit32_datanum;

num.byte.byte0=0x78;
num.byte.byte1=0x56;
num.byte.byte2=0x34;
num.byte.byte3=0x12;

printf("num.data=0x%x
",num.data);

return0;
}

运行结果:

8e241cd4-bed7-11ec-9e50-dac502259ad0.png

但是数据组合与拆分有更好的方法:移位操作。篇幅有限不再贴出代码,详细代码可参考:《面试题 | 获取整数各个字节》《C语言、嵌入式位操作精华技巧大汇总》两篇文章。

4、结构体 & 缓冲区

#defineBUF_SIZE16
unionprotocol_data
{
uint8_tdata_buffer[BUF_SIZE];
struct
{
uint8_tdata1;
uint8_tdata2;
uint8_tdata3;
uint8_tdata4;
//...
}data_info;
};

这种应用得很广泛,用于自定义通信协议。struct里面的内容可以设计得很简单,比如全是有用的数据,或是设计得很复杂,包含一些协议头尾、包长、有效数据、校验等内容。

但无论如何,我们组包发送的过程是填充结构体->发送data_buffer;反之接收数据解析的过程就是接收数据存于data_buffer->使用结构体数据。我们之前分享的《干货 | protobuf-c之嵌入式平台使用》也是这个思路。

5、传输浮点数据

unionf_data
{
floatf;
struct
{
unsignedcharbyte[4];
};
}

类似的,使用这样子的方法可以用于传输浮点数,更具体地不再展开,网络上有很多这一块的资料。感兴趣的朋友可以自己操作验证验证。

END
审核编辑 :李倩

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • C语言
    +关注

    关注

    180

    文章

    7616

    浏览量

    138001
  • 结构体
    +关注

    关注

    1

    文章

    130

    浏览量

    10888

原文标题:结构体、联合体嵌套使用的实用操作

文章出处:【微信号:gh_c472c2199c88,微信公众号:嵌入式微处理器】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    商汤科技与多家厂商共同成立语料终端创新联合体

    近日,由中央广播电视总台、上海市人民政府共同主办的2024科创大会在上海落下帷幕。期间,商汤科技与上海库帕思科技有限公司、上海阡视科技有限公司、以及国产主流芯片等共19家厂商共同成立语料终端创新联合体
    的头像 发表于 12-16 13:46 482次阅读

    拓维信息参与牵头组建!长沙新一代信息技术产教联合体正式获批

    近日,由长沙市教育局和长沙市工业和信息化局联合发布的《2024年长沙市市级市域产教联合体名单》正式公布。其中,由长沙高新区麓谷产业园(长沙信息产业园)、拓维信息、湖南商务职业技术学院共同牵头组建
    的头像 发表于 12-07 01:06 511次阅读
    拓维信息参与牵头组建!长沙新一代信息技术产教<b class='flag-5'>联合体</b>正式获批

    华为亮相2024年5G创新联合体“融创行动”论坛

    近日,由中国移动通信集团研究院、中国移动通信集团江苏有限公司联合主办的2024年5G创新联合体“融创行动”面向工业生产控制的5G-A确定性关键技术研究与应用示范联合创新论坛在无锡太湖新城假日酒店举办。
    的头像 发表于 11-25 10:38 476次阅读

    苏州市人工智能语言计算创新联合体活动圆满举办

    活动伊始,园区企业发展服务中心副主任吴小庆与思必驰副总裁李春梅共同为“益企家”企业服务联络站——人工智能语言计算创新联合体站揭牌。截至目前,园区企服中心已设立20家联络站。未来,联络站将深度赋能联合体成员单位企业,为企业提供“全方位”、“零距离”的服务,助力产业高质量发展
    的头像 发表于 10-14 14:08 351次阅读

    澎峰科技受聘为“主权级大模型”创新联合体学术委员会委员

    日前,“主权级大模型“创新联合体揭牌,澎峰科技CEO受聘为”主权级大模型“创新联合体学术委员会委员。
    的头像 发表于 09-02 17:37 915次阅读

    长沙角逐算力江湖,长沙市新一代智算产业生态联合体成立

    算力正成为数字时代经济发展的新引擎。为大力发展相关产业,8月28日,长沙市新一代智算产业生态联合体正式成立,新一代智算产业生态联合体集聚了北京大学长沙计算与数字经济研究院、湖南大学、华为技术有限公司
    的头像 发表于 08-30 11:14 655次阅读

    普源精电入选“2024苏州民营企业创新100强”与“2024年度苏州市创新联合体

    近日,苏州企业家创新发展大会顺利召开,会上公布了多项奖项,普源精电科技股份有限公司(简称:普源精电)凭借在核心技术领域的突破与创新,先后入选“2024苏州民营企业创新100强”与“2024年度苏州市创新联合体”名单,充分展现硬核科技实力!
    的头像 发表于 08-01 15:44 456次阅读

    摩尔线程加入商飞智能“工业元宇宙创新联合体

    6月18日,商飞智能技术有限公司携手摩尔线程智能科技(北京)有限责任公司、北京蔚领时代科技有限公司、北京智谱华章科技有限公司、厦门雅基软件有限公司在张江人工智能岛签署合作协议,共创工业元宇宙创新联合体。作为联合体成员中的唯一国产GPU算力企业,摩尔线程高级副总裁董龙飞出席
    的头像 发表于 06-20 10:09 772次阅读

    智芯公司入选MEMS器件可靠性试验创新联合体首批成员单位

    近日,MEMS器件可靠性试验创新联合体(以下简称“联合体”)成立大会在京召开,智芯公司、北京大学、清华大学、哈工大、北航、中科院微电子所、中科院空天研究院、中电科三十八所等23家单位入选联合体首批
    的头像 发表于 05-15 18:45 852次阅读
    智芯公司入选MEMS器件可靠性试验创新<b class='flag-5'>联合体</b>首批成员单位

    壁仞科技加入中国移动“融创未来”算力网络创新联合体

    近日,以“算力网络点亮AI新时代”为主题的2024中国移动算力网络大会在苏州举行。作为中国移动的算力合作伙伴,壁仞科技加入“融创未来”算力网络创新联合体,并与多家合作伙伴共同在现场展示聚焦集群算力的产品。
    的头像 发表于 04-30 09:36 1066次阅读
    壁仞科技加入中国移动“融创未来”算力网络创新<b class='flag-5'>联合体</b>

    芯原科技牵头的RISC-V创新联合体获正式认定授牌

    在近日以“临港科创 新质未来”为主题的2024临港科创大会上,芯原科技牵头组建的RISC-V创新联合体正式获得认定授牌。这一创新联合体是由芯原科技联合芯来科技等10家上下游企业及3所高校共同发起,展现了多维度、多层次、多元化的合
    的头像 发表于 03-28 09:19 551次阅读

    天津车联网技术创新联合体,正式成立!

    3月22日,天津经纬恒润有限公司携手12家京津冀三地优质企业及高校共同成立的车联网技术创新联合体举行揭牌仪式。大会介绍了各成员单位的业务情况、研发计划和2024年度联合体的整体工作计划,为联合体
    的头像 发表于 03-26 10:00 589次阅读
    天津车联网技术创新<b class='flag-5'>联合体</b>,正式成立!

    天津经纬携优质企业及高校成立的车联网技术创新联合体举行揭牌仪式

    3月22日,天津经纬恒润有限公司携手12家京津冀三地优质企业及高校共同成立的车联网技术创新联合体举行揭牌仪式。
    的头像 发表于 03-25 10:22 559次阅读
    天津经纬携优质企业及高校成立的车联网技术创新<b class='flag-5'>联合体</b>举行揭牌仪式

    华为联合24家企事业单位发起“大模型应用产业联合体

    华为联合24家企事业单位发起“大模型应用产业联合体” 据央视《新闻联播》报道 日前,华为联合智谱AI、医渡科技、百川智能、中国科学院自动化研究所、中软国际、首都在线、第四范式、格灵深瞳、中科创达、软
    的头像 发表于 03-02 15:55 1375次阅读

    北京24家企事业单位组建&quot;大模型应用产业联合体&quot; 

    据悉,此联合体旨在利用华为鲲鹏硬件底座与软件底层资源,推动人工智能产业生态合作,确立相关行业标准,并实现人工智能产业的快速升级。
    的头像 发表于 03-01 14:44 837次阅读