代码之家  ›  专栏  ›  技术社区  ›  GabrielT

将3字节数组强制转换为int32

  •  0
  • GabrielT  · 技术社区  · 4 年前

    快速提问,
    我想把一个3字节有符号2的补码数组转换成一个小的endian 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
    

    我该怎么解决这个问题?也许用联合会更好?

    1 回复  |  直到 4 年前
        1
  •  1
  •   Guillaume Petitjean    4 年前

    通过做 (&tmp2)+1 你的地址是 tmp2 ,这是指向 int32_t ,然后递增此指针。所以你给它的地址加4。这意味着memcpy的目的地址是 tmp2型 + 4. 实际上你没有修改 tmp2型 而是与其他变量或记忆重叠。

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

        2
  •  0
  •   wildplasser    4 年前

    我将避免强制转换值,并使转换显式(这可能是内联的)

    我假设你的角色数组也是小端的。(否则交换索引)


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