• 正文
    • 1 结构体位域
    • 2 __attribute__((packed))
    • 3 联合使用
  • 相关推荐
申请入驻 产业图谱

结构体位域和__attribute__ ((__packed__))一起用

02/03 08:55
1217
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

1 结构体位域

1.1 位域

位域是一种节省空间的数据结构,是把一个数据类型按照二进制(二进位)划分为几个不同的区域,并说明每个区域的位数。

比如有一个字节,每一位表示一个开关状态,就可以使用位域,解析也方便。

struct test{

unsigned char test1:1;

unsigned char test2:1;

unsigned char test3:1;

unsigned char test4:1

unsigned char test5:1;

unsigned char test6:1;
unsigned char test7:1;
unsigned char test8:1;

}

这样收到1字节数据赋值给test,解析每个位的状态直接使用test.test1.....test.test6就可以,不需要再进行相应的位与操作之类的。还可以节省空间。要注意大小端,小端的test1是低位。

1.2位域的具体存储规则如下:

1) 如果相邻位域字段的类型相同,且其位宽之和小于类型的sizeof大小,则后面的字段将紧邻前一个字段存储,直到不能容纳为止。

2)如果相邻位域字段的类型相同,但其位宽之和大于类型的sizeof大小,则后面的字段将从新的存储单元开始。

struct test{
unsigned char test1:1;
unsigned char test2:4;
unsigned char test3:4;
unsigned char test4:1;
unsigned char test5:1;
unsigned char test6:1;
unsigned char test7:1;
unsigned char test8:1;
}

举例,这个test结构体,成员test3+test2+test1的位宽为9,大于char的8位,那从test3开始就要从第2个字节开始存。

编辑切换为居中

添加图片注释,不超过 140 字(可选)

3)如果相邻的位域字段的类型不同,则各编译器的具体实现有差异,不建议使用,也没啥使用的必要。

4)如果位域字段之间穿插着非位域字段,则不进行压缩。

5)整个结构体的总大小为最宽基本类型成员大小的整数倍,和普通结构体一样。

2 __attribute__((packed))

__attribute__ ((packed)) 的作用就是告诉编译器取消结构在编译过程中的优化对齐,按照实际占用字节数进行对齐,是GCC特有的语法。

__attribute__关键字主要是用来在函数或数据声明中设置其属性。

3 联合使用

对于一些特殊的协议,比如sbus,sbus一个通道占11位,那按照位域的规则,下属代码中的channel3就要在存储在下一个unsigned int中了。就不满足我们直接利用编译器解析数据的目的了。

struct sbus_test

{

unsigned int channel1: 11;

unsigned int channel2: 11;

unsigned int channel3: 11;

unsigned int channel4: 11;

unsigned int channel5: 11;

...

} __attribute__ ((__packed__));

使用__attribute__ ((__packed__))处理,是可以使数据一个挨着一个,直接读取数据了。对于一些这种特殊协议的,这样联合使用比较方便。

 

点赞
收藏
评论
分享
加入交流群
举报

相关推荐

登录即可解锁
  • 海量技术文章
  • 设计资源下载
  • 产业链客户资源
  • 写文章/发需求
立即登录