将bytes数组转换为整数

时间:2016-05-25 07:06:39

标签: c

我有一个类型为uint8_t的4字节数组(数据),表示速度数据整数。我正在尝试将此数组转换为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;

2 个答案:

答案 0 :(得分:6)

为了安全起见,便携式和安全,您应该重新创建数据:

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

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

根据最重要字节的位置选择解决方案

你得到一个&#34;赋值给表达式的数组类型&#34;错误是因为你无法直接分配一个数组:{C}中完全禁止使用data=(uint8_t*)speed;,你绝对不能为左值数组。你必须做反向操作:

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);

或者,根据最重要字节的位置:

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);

修改

在评论和原始答案中不要使用强制转换或memcpy:除了非可移植性问题之外,您还会遇到安全问题,根据某些平台上的对齐限制和别名规则,编译器可以生成错误的代码 - 感谢user694733 |见here - 感谢Lundin

    speed = *((uint32_t *)data); // DANGEROUS NEVER USE IT
    *((uint32_t *)data) = speed; // DANGEROUS NEVER USE IT

答案 1 :(得分:5)

您的代码不起作用,因为在data=(uint8_t*)speed;期间您没有获得&#34;左值&#34;对于数据,您只需获得一个不能用于赋值或任何形式算术的数组类型。同样,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);

这是100%可移植且定义良好的代码。没有隐含的促销活动。此代码不依赖于endianess或其他实现定义的行为。为什么要编写代码,当你可以编写那些没有?

的代码时