【问题标题】:parsing bytes (C Windows)解析字节(C Windows)
【发布时间】:2009-07-24 20:00:16
【问题描述】:

我有一个十六进制的 DWORD 值可能如下所示:

DWORD Val = 0xFF01091A

如何读取每个字节?我的意思是,我怎么读FF、01、09和1A?

谢谢!

【问题讨论】:

  • 对这类事情要小心,确保您了解字节的来源以及代码是否有可能转移到字节顺序可能不同的非 Windows 平台(从大端到小端处理器)。

标签: c windows parsing byte


【解决方案1】:

其实不是这样的:

uint8_t Byte1 = (Val>> 0) & 0xFF;
uint8_t Byte2 = (Val>> 8) & 0xFF;
uint8_t Byte3 = (Val>>16) & 0xFF;
uint8_t Byte4 = (Val>>24) & 0xFF;

【讨论】:

  • 你的方式实际上更干净:)
  • 如果您分配给 uint8_t,则不需要“& 0xFF”,但我认为它们可以更清楚地说明您在做什么,并且不应该对性能造成影响,因为编译器应该很聪明足以弄清楚它们是多余的,不会生成额外的汇编指令。
【解决方案2】:
DWORD value;
// casts to `char *` are always ok:
unsigned char * bytes = (unsigned char *)&value;
unsigned char third_byte = bytes[2];

请记住,这将获取放置在内存中的字节:在小端机器上 bytes[0] 将保存最低有效字节,在大端机器上它将保存最高有效字节。

如果您想按重要性获取字节,请按照Efraim's answer 中的建议使用移位。

【讨论】:

  • 漂亮而简单,但在小端和大端系统上的行为不同。我不认为那是意图。
  • @Thorarin:添加了关于字节序的评论
【解决方案3】:
DWORD x1 = (0xFF01091A & 0xFF000000) >> 24;
DWORD x2 = (0xFF01091A & 0x00FF0000) >> 16;
DWORD x3 = (0xFF01091A & 0x0000FF00) >> 8;
DWORD x4 = (0xFF01091A & 0x000000FF) >> 0;

【讨论】:

  • 不过,这不会给出正确的结果;它会返回 0xFF000000、0x00FF0000、0x0000FF00 和 0x000000FF。您还需要对这些值进行位移,因此 x1 >>= 24、x2 >>= 16 和 x3 >>= 8。
  • 您应该左移 24、16、8 和 0 位。
【解决方案4】:

使用联合:

union Bytes {
    char c[4];
    unsigned int n;
};

int main() {
    Bytes b;
    b.n = 0xFF01091A;
    char c = b.c[2];
}

编辑:抱歉,这是 C++ 代码。我太累了,无法将其转换为 C 并对其进行测试,但你明白了吗?

【讨论】:

  • 不需要做太多的转换:在Bytes b; 之前缺少一个union,您应该将main 声明为int main(void)
【解决方案5】:

AraK 的方法行之有效。另一种方法是:

char x1 = *(((char*)&Val) + 0);
char x2 = *(((char*)&Val) + 1);
char x3 = *(((char*)&Val) + 2);
char x4 = *(((char*)&Val) + 3);

但请注意,这种方式会对机器的字节序敏感。

【讨论】:

    【解决方案6】:

    掩码和移位(如上一个答案中所建议)有效;一个有点棘手的替代方案是“指针类型双关语”,即

    xlowbyte = (unsigned char*)(&Val) [0]; /* LSB, 0x1A */
    xmidlowb = (unsigned char*)(&Val) [1]; /* 2nd-LSB, 0x09 */
    

    等 -- 假设您使用的是 little-endian 机器(如果您使用 Windows,则很可能)。

    【讨论】:

      猜你喜欢
      • 2015-09-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-22
      • 2017-11-02
      • 1970-01-01
      相关资源
      最近更新 更多