我有一个4字节的数组(数据)类型uint8_t,它代表一个速度数据整数.我正在尝试将此数组转换为uint32_t整数(速度),将此速度乘以10,然后将其恢复为4字节数组(数据).数据格式在下面的代码中是清楚的.我总是得到错误:
"使用数组类型赋值给表达式"
代码:
volatile uint8_t data[4] = {0x00 , 0x00, 0x00, 0x00};
volatile uint32_t speed;
speed=( uint32_t)*data;
speed=speed*10;
data=(uint8_t*)speed;
Run Code Online (Sandbox Code Playgroud)
为了安全,根据endianess,便携和安全,您应该重新创建您的数据:
speed = ((uint32_t)data[0]) << 24
| ((uint32_t)data[1]) << 16
| ((uint32_t)data[2]) << 8
| ((uint32_t)data[3]);
Run Code Online (Sandbox Code Playgroud)
要么
speed = ((uint32_t)data[3]) << 24
| ((uint32_t)data[2]) << 16
| ((uint32_t)data[1]) << 8
| ((uint32_t)data[0]);
Run Code Online (Sandbox Code Playgroud)
根据最重要字节的位置选择解决方案
你得到一个"赋值给表达式与数组类型"错误,因为你不能直接分配一个数组:data=(uint8_t*)speed;在C中是完全禁止的,你肯定不能有一个数组用于左值.你必须做反向操作:
data[0] = (uint8_t)((speed >> 24) & 0x00FF);
data[1] = (uint8_t)((speed >> 16) & 0x00FF);
data[2] = (uint8_t)((speed >> 8) & 0x00FF);
data[3] = (uint8_t)(speed & 0x00FF);
Run Code Online (Sandbox Code Playgroud)
或者,根据最重要字节的位置:
data[3] = (uint8_t)((speed >> 24) & 0x00FF);
data[2] = (uint8_t)((speed >> 16) & 0x00FF);
data[1] = (uint8_t)((speed >> 8) & 0x00FF);
data[0] = (uint8_t)(speed & 0x00FF);
Run Code Online (Sandbox Code Playgroud)
编辑
不要使用强制转换或memcpy在评论和原始答案中提及:除了非可移植性问题,你会遇到安全问题,根据对齐限制和某些平台上的别名规则,编译器可能会生成错误的代码 - 感谢user694733 | 看到这里 - 感谢Lundin
speed = *((uint32_t *)data); // DANGEROUS NEVER USE IT
*((uint32_t *)data) = speed; // DANGEROUS NEVER USE IT
Run Code Online (Sandbox Code Playgroud)
您的代码不起作用,因为在data=(uint8_t*)speed;您没有得到数据的"左值"时,您只得到一个不能用于赋值或任何形式算术的数组类型.同样,这speed=( uint32_t)*data;是一个错误,因为它只给你数组中的第一个项目.
你应该这样做的唯一正确方法:
volatile uint8_t data[4] = {0x00 , 0x00, 0x00, 0x00};
volatile uint32_t speed;
speed = (uint32_t)data[0] << 24 |
(uint32_t)data[1] << 16 |
(uint32_t)data[2] << 8 |
(uint32_t)data[3] << 0;
speed=speed*10;
data[0] = (uint8_t) ((speed >> 24) & 0xFFu);
data[1] = (uint8_t) ((speed >> 16) & 0xFFu);
data[2] = (uint8_t) ((speed >> 8) & 0xFFu);
data[3] = (uint8_t) ((speed >> 0) & 0xFFu);
Run Code Online (Sandbox Code Playgroud)
这是100%可移植且定义良好的代码.没有隐含的促销活动.此代码不依赖于endianess或其他实现定义的行为.为什么要编写代码,何时可以编写代码呢?