为何memcpy()可实现内存字节数据到浮点数的转换?
关于memcpy实现字节到浮点数转换的疑问解答
场景与代码
你通过串口读取传感器的4个字节数据,存入uint16_t buffer_array[2]数组(合计4字节),填充代码如下:
uint16_t buffer_array[2]; // 两个uint16_t,合计4字节 temp = swSerial.read(); // 读取传感器发来的串口数据 switch(received_counter) { case 3: // 接收传感器的第4个字节 buffer_array[0] = temp; break; case 4: // 接收传感器的第5个字节 buffer_array[0] += temp; break; case 5: // 接收传感器的第6个字节 buffer_array[1] = temp; break; case 6: // 接收传感器的第7个字节 buffer_array[1] += temp; break; default: break; }
之后用这段代码将数组字节转换为浮点数:
float voltage; memcpy(&voltage, &buffer_array, sizeof(float));
疑问拆解与解答
1. memcpy为啥能实现这种"转换"?
memcpy根本没做"转换",它就是原封不动搬运字节。之所以能得到正确的浮点数,是因为传感器输出的这4个字节本身就是按照IEEE 754单精度浮点数的编码规则生成的字节序列。
当你把这4个字节完整复制到float类型变量voltage的内存空间后,CPU读取voltage时会自动按照float的存储规则(IEEE 754)解析这些字节,自然就能得到对应的浮点数值。
2. 有没有隐式类型转换?
完全没有。整个过程不存在任何类型转换操作——memcpy只是字节级的搬运,既不修改字节内容,也不做类型层面的转换。所谓的"转换"其实是内存解析规则的变化:原来存在uint16_t数组里的字节被当作两个16位无符号整数解读,复制到float变量后,这些字节被当作IEEE 754浮点数的编码解读。
3. 有没有遗漏的关键细节?
有几个必须注意的坑:
- 字节序不匹配会直接出错:传感器输出的字节是大端还是小端,必须和目标平台(比如Arduino)的
float存储字节序一致。如果不匹配,直接复制得到的浮点数会完全乱掉,需要先手动反转字节序。 - 当前数组填充代码存在错误:你现在用
buffer_array[0] = temp;之后buffer_array[0] += temp;,这是把两个字节的值相加,而非拼接成16位整数。正确做法是把每个字节放到数组对应字节位置,比如用uint8_t数组存4个字节,或者强制转换buffer_array为字节数组操作:((uint8_t*)buffer_array)[received_counter - 3] = temp;(对应第4到第7字节,索引0到3)。 - 要确认float的长度:大部分平台的单精度浮点数都是4字节,但极少数平台可能例外,若
sizeof(float)不等于4,复制会直接出问题。
内容的提问来源于stack exchange,提问作者user1584421
相关产品推荐
相关产品推荐

