关于蓝牙报文可能的类型转换方式

本文介绍了蓝牙报文在超过单字节范围时如何通过位操作、宏定义和union关键字进行合并。内容包括按位与实现合并的原理,宏定义在合并中的应用,以及union在大小端存储下的使用,同时还探讨了union的其他用法,如给数组元素赋值和利用位域进行状态判断。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

为什么要写这篇

按位与来实现合并

使用宏定义来合并

使用union关键字来合并

关于union的其它用法

给数组元素赋值

使用union 和位域来做状态判断


为什么要写这篇

一个契机就是我看到的一篇判断大小端的文章,后面再解释和我要写的关系。 蓝牙发送报文是按照一个字节一个字节进行发送,能表示的范围有限,但是不少含义的数据是超过这个数值的,比如角度值范围为0~360°,一个字节能达到的最大数值是255。那怎么办呢?肯定是两个字节或多个字节来表示一个数据。合并目前的我理解看来有三种方法,1. 按位与来实现合并  2.使用宏  3.基于union联合体关键字来实现合并。

按位与来实现合并

也是最常用的一种。举例来说:关于4字节数组合并成32位无符号整数

uint8_t  _pBuf[4];

uint32_t return_value = (((uint32_t)_pBuf[3] << 24) | ((uint32_t)_pBuf[2] << 16) | ((uint32_t)_pBuf[1] << 8) | _pBuf[0]);  

可能有些小伙伴并不是这样写的,觉得差不多。比如我,在看到这之前,我的写法是:

uint8_t  _pBuf[4];

uint32_t return_value = (uint32_t)(_pBuf[3] << 24) | _pBuf[2] << 16) | _pBuf[1] << 8) | _pBuf[0]);  

我不太确定后一种结果怎么样,但我确定前一种结果肯定对。

为什么呢?和运算符优先级有点儿关系,优先级越高越先运算。来自C陷阱与缺陷的截图

()是最高优先级,(type)表示强制类型转换,在次高优先级。运算的结果比如(_pBuf[3] << 24)会先将结果保存在一个临时位置(可能是个寄存器),最终会将这个临时运算值抛弃。第一种写法显式的说明要放在uint32_t类型的临时变量。然后四个uint32_t类型的临时变量相或,得到的结果肯定是uint32_t类型数据。而第二种写法,强制类型转换在括号外部,(_pBuf[3] << 24)因为_pBuf[3]是个uint8_t类型的值,左移24位,我知道原来的8位肯定变为0了,左移16位,左移8位同理,(_pBuf[3] << 24) | _pBuf[2] << 16) | _pBuf[1] << 8) | _pBuf[0])有没有可能保存在uint8_t类型里,结果是_pBuf[0]然后又被强制类型转换成uint32_t类型呢?我不清楚。

后来了解到这是属于C语言隐式类型转换规则,可以去网上搜一搜。有一条是:(类型提升)在表达式中char和unsigned char、short 和 unsigned

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值