结构体位域和__attribute__ ((__packed__))

一、结构体位域

1.1、 位域

  位域是一种节省空间的数据结构,是把一个数据类型按照二进制(二进位)划分为几个不同的区域,并说明每个区域的位数。
  比如有一个字节,每一位表示一个开关状态,就可以使用位域,解析也方便。

struct test{
    
    
uint8_t test1:1;
uint8_t  test2:4;
uint8_t  test3:4;
uint8_t  test4:4;
uint8_t  test5:4;
uint8_t  test6:4;
uint8_t  test7:4;
}

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

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

  1) 如果相邻位域字段的类型相同,且其位宽之和小于类型的sizeof大小,则后面的字段将紧邻前一个字段存储,直到不能容纳为止。
  2)如果相邻位域字段的类型相同,但其位宽之和大于类型的sizeof大小,则后面的字段将从新的存储单元开始。
  3)如果相邻的位域字段的类型不同,则各编译器的具体实现有差异,不建议使用,也没啥使用的必要。
  4)如果位域字段之间穿插着非位域字段,则不进行压缩。
  5)整个结构体的总大小为最宽基本类型成员大小的整数倍,和普通结构体一样。

二、attribute((packed))

   attribute ((packed)) 的作用就是告诉编译器取消结构在编译过程中的优化对齐,按照实际占用字节数进行对齐,是GCC特有的语法。
  __attribute__关键字主要是用来在函数或数据声明中设置其属性。

3、 联合使用

struct test{
    
    
uint8_t test1:1;
uint8_t  test2:4;
uint8_t  test3:4;
uint8_t  test4:4;
uint8_t  test5:4;
uint8_t  test6:4;
uint8_t  test7:4;
}__attribute__ ((__packed__));

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

猜你喜欢

转载自blog.csdn.net/xxxx123041/article/details/131612962