将 3 字节数组转换为 int32

Cast a 3-byte array to int32

快速提问,
我想将一个 3 字节带符号的二进制补码数组转换为小端 int32
我尝试将 memcpy 的大小设置为 3 并将 +1 设置为目标地址(不要忘记将我的 int32 初始化为零)
这是我的代码:

int main(void) 
{
  // little endian 3 bytes
  __uint8_t n1[]={0,0xFF,0xDE,0x81};
  __uint8_t n2[]={0xFF,0xDE,0x81};
  
  // temp var
  __int32_t tmp1=0;
  __int32_t tmp2=0;
  
  // cast array to int
  memcpy(&tmp1,n1,4);
  memcpy((&tmp2)+1,n2,3);
  
  // printf
  printf("n1 : %d\n",tmp1);
  printf("n2 : %d\n",tmp2);
}

我得到的输出:

n1 : -2122195201
n2 : 0

我想要的输出:

n1 : -2122195201
n2 : -2122195201

我该如何解决这个问题?也许使用 union 更好?

通过执行 (&tmp2)+1,您获取了 tmp2 的地址,它是指向 int32_t 的指针,并且您增加了该指针。因此,您将 4 添加到它的地址。这意味着你的 memcpy 的目标地址是 tmp2 + 4 的地址。你实际上没有修改 tmp2 而是重叠了一些其他变量或内存。

这不是一种转换或转换数据的干净方法,但如果您真的想使用 memcpy,请执行类似(未测试)memcpy((void *)(((char *)&tmp2)+1),n2,3);

我会避免强制转换值,并明确转换(这可能会被内联)

我假设您的字符数组也是小端字节序的。 (否则交换索引)


static int three2four(__uint8_t three[3] )
{
int val;
val = ((unsigned)three[2] << 16) | ((unsigned)three[1] << 8) | (unsigned)three[0] ;
if (three[2] & 0x80) val |= (0xffu << 24);

return val;
}