【单片机】指针从缓冲区中直接提取数值
最近期末在做“医疗器械综合课程设计”,我比舍友提前做完了(其实是我小组ddl早两天)……热心的我就来帮舍友的项目指指点点。他们用到一个手机来和蓝牙模块通信,但是在单片机上解析数据包的时候遇到了困难,网上的例程他们想添加数据包内容不会改了。
假设数据包结构:
以下是他们的源码,从蓝牙模块送的例程修改来的:
一看到这代码我就蒙了,从哪循环到哪?移了多少位?为什么要*8?将来怎么扩展数据包😵💫???
数据包缓存就在内存中的某处,要是可以指挥CPU从内存中数据缓冲区中间的一个地址开始读4个字节,然后赋值给另一个变量就好了。凭借着我对C语言指针的认识和对计算机基础的理解,我顿悟了:
char a[] = {0x52, 0xbf, 0x01, 0x00}; // 114514
int b = *(int*)&a[0];
printf("%d\n", b);
结果如同预计的,假设a是缓冲区,从“0”开始读了int(4byte)长度的数据赋值给b。
原理分析
堆栈
栈从高地址往低增长,堆从低往高增长。这里测试代码的平台是X86,也就是小端序,数据低位在低地址。那么这个数据在内存里大概是像这样:
如果在单片机里运行,这个数组顺序应该掉个头,因为ARM平台是大端序。
补充注意:对char类型指针++是-1,而对int类型指针++是-4。
命令解析
&a[0]
数组a长度为4,&a[0]
为数组a第一个char的地址。
(int*)
C语言的类型强制转换。把char类型的指针转换为int类型的指针,这就是精华操做,否则*&a[0]
就是a[0]
本身。
*
提领,也叫解引用,即dereference,返回内存地址中对应的数值。我见到这个词是在《Essential C++》,特别形象。“解引用”解什么?引用怎么解?而“提领”这个词就让人感觉是给我一个名字常威(地址),从牢里(内存)把常威本人(数值)给提领出来。
*(int*)&a[0]
:把a[0]的地址强制转换成指向int类型(4byte)的指针并提领值。
以上的方法可能我在教科书里学过又忘了,而我又凭借着自己的理解顿悟出来。沾沾自喜没几天,我问ChatGPT遇到这种情况怎么办,他是这样做的:
显然这是通用的做法,而且他还给出了详细的文字解释,显得我很呆🥲
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 实操Deepseek接入个人知识库
· 易语言 —— 开山篇
· 【全网最全教程】使用最强DeepSeekR1+联网的火山引擎,没有生成长度限制,DeepSeek本体