【问题标题】:Convert 4 bytes char to int32 in C在C中将4字节char转换为int32
【发布时间】:2011-11-17 19:24:40
【问题描述】:

我先是把一个int32数转成char[4]数组,然后通过(int *)把数组转回int32,但是数和以前不一样了:

unsigned int num = 2130706432;
unsigned int x;
unsigned char a[4];

a[0] = (num>>24) & 0xFF;
a[1] = (num>>16) & 0xFF;
a[2] = (num>>8) & 0xFF;
a[3] = num & 0xFF;

x = *(int *)a;
printf("%d\n", x);

输出为 127。如果我设置 num = 127,则输出为 2130706432。 有人有想法吗?

【问题讨论】:

  • 你的平台是小端还是大端? en.wikipedia.org/wiki/Endianness你平台上一个int的字节顺序可能不是你想象的那样。
  • @Eric J. 哦,我忘了这个。现在已经解决了,谢谢
  • @DavidHeffernan:它被标记为 C。
  • @zwx:我认为x = *(int *)a; 违反了严格的别名规则(尝试在启用警告的情况下进行编译),在现代 C 中你应该使用联合来进行类型双关(但最好这样做通过位移)。见stackoverflow.com/questions/8143857/…
  • @ninjalj:没错。代码实际上是UB。正确的做法是颠倒顺序:unsigned int x; unsigned char * a = (unsigned char*)(&x);

标签: c


【解决方案1】:

颠倒 a[] 索引的顺序,例如,。 a[0] -> a[3]

我认为你的字节序是相反的。

试试这个:

a[3] = (num>>24) & 0xFF;
a[2] = (num>>16) & 0xFF;
a[1] = (num>>8) & 0xFF;
a[0] = num & 0xFF;

【讨论】:

    【解决方案2】:

    要查看会发生什么,请使用

    printf("%x\n", ...);
    

    打印输入和输出数字。

    字节序无关方式:

    x = (a[0] << 24) | (a[1] << 16) | (a[2] << 8) | a[3];
    

    【讨论】:

    • 我不知道为什么会投票赞成。好像它是一种与字节序无关的方式,它也应该在我的 PC 上运行。但我必须做完全相反的uint32_t var2 = (v[3] &lt;&lt; 24) | (v[2] &lt;&lt; 16) | (v[1] &lt;&lt; 8) | v[0];
    • 我使用 vector&lt;unsigned char&gt; 并用 uint32_t 填充它 vars using memcpy: memcpy(&amp;v[0], &amp;var, sizeof var);
    • @rightaway717 所以将它保存在您计算机的字节序中。要做到这一点,你必须像 OP 那样转换 uint32_t -> array 和 array -> uint32_t 像我一样。
    【解决方案3】:

    这条线永远不会在 little-endian 机器上正常工作:

    x = *(int *)a;
    

    在打印出值之前,您需要解压数据。

    【讨论】:

    • 此外,它可能不适用于带有利用严格别名规则的编译器的大端机器。
    【解决方案4】:

    您的代码a[0] = (num&gt;&gt;24) &amp; 0xFF; 从num 中获取最高有效8 位并将它们粘贴在a 的第一个字节中。在小端机器上,第一个字节包含最低有效位。这意味着在小端机器上,此代码获取最高有效 8 位并将它们存储在最低有效位所在的位置,从而更改值。

    2130706432 是十六进制的 0x7F000000,127 是 0x0000007F。

    另外,x = *(int *)a; 会导致未定义的行为。考虑从不正确对齐的地址读取 int 会导致总线错误的硬件。如果 a 碰巧没有与 int 正确对齐,那么程序就会崩溃。

    将字节解释为int 的正确方法是std::memcpy(&amp;x, a, sizeof x);

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-31
      • 2022-01-02
      • 1970-01-01
      • 2019-10-11
      相关资源
      最近更新 更多