将bytes数组转换为整数

sha*_*ham 2 c

我有一个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)

Gar*_*365 6

为了安全,根据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)


Lun*_*din 5

您的代码不起作用,因为在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或其他实现定义的行为.为什么要编写代码,何时可以编写代码呢?