0

我有一个“无符号短”数组,即 C 中每个元素 16 位。我有两个“无符号短”值,它们应该以小端顺序写回数组中,这意味着最不重要的元素将首先出现。例如,如果我有以下值:

unsigned int val = 0x12345678;

它应该存储在我的数组中:

unsigned short buff[10];
buff[0] = 0x5678;
buff[1] = 0x1234;

我编写了一个代码来一次写入值,而不是提取 int 值的高低 16 位并分别编写它们,因为可能存在原子性问题。我的代码如下所示:

typedef unsigned int UINT32;
*((UINT32*)(buff)) = (value & 0xffff0000)  + (value & 0xffff);

令人惊讶的是,上面的代码可以正常工作,结果将是:

buff[0] is 0x5678;
buff[1] is 0x1234;

问题是,如图所示,我以大端顺序保存“无符号短”值,而不是我希望的小端。换句话说,当我将指针从“unsigned short*”转换为“unsigned int*”时,16 位元素会自动交换!有谁知道这里发生了什么以及为什么数据被交换?

4

1 回答 1

1

您的平台以 little endian 格式表示数据,并且通过将 buff 转换为 (UINT32 *),您告诉编译器现在必须将 buff 解释为指向 unsigned int 的指针。该指令

*((UINT32*)(buff)) = (value & 0xffff0000)  + (value & 0xffff);

只是说“将 (value & 0xffff0000) + (value & 0xffff) 写入这个无符号整数 (buff)”。这就是他所做的,他如何存储它不是你的事。您不应该访问低 16 位或高 16 位,因为它取决于平台,哪个先出现。

您所知道的是,如果您将 buff 作为 unsigned int 访问,您将获得与之前存储在其中的相同值,但假设任何特定的字节顺序是不安全的。

所以基本上你的代码有未定义的行为。

于 2013-09-24T22:19:13.313 回答