C中的字节顺序和指针转换

Endianness and pointer casting in C

我在我的机器上写了一个 C 程序,代码如下:

uint32_t test = 0x01020304;
uint8_t array[4];

memcpy(array, &test, 4);

printf("%02x %02x %02x %02x\n",array[0], array[1], array[2], array[3]);

它打印 04030201 但我预计 01020304

我是否必须得出结论,我工作的机器具有小端架构?

正如 Mohit 所说,是的:输出显示最低有效位在内存中的较低地址,或 "the little endian is first";或 "Little Endian".

这可能有点令人困惑,尤其是对于从左到右书写和阅读的西方人而言。我只能怀疑阅读和书写希伯来语或阿拉伯语的人不会感到困惑。

其中一个后果是位移运算符的工作方式与它们似乎指示的相反"direction"。

关于这两种字节顺序的优点和缺点有很多争论;最后这无关紧要,当然 C 的最大成就是从具体的体系结构中抽象出来,足以消除差异并使程序可移植(但不阻止访问位和字节)。

对于小尾数法,字节中的位仍然从右到左递增(我们写入它们的方式),而字节从左到-递增(如果我们向左写入更高的地址),这有点不直观正确的。

此外,互联网字节顺序是 Big Endian,因此使用 htonl() 和朋友很重要。 (请不要重新实现这些功能。)

little endian 字节顺序的一个很好的特性是,无论您在内存位置采用哪种数据类型,小值都是相同的;如果您将一个值为 23 的 32 位 int 写入地址 x 并稍后将其作为 char 读取它是 23;在大端机器上它将是 0。

Do I have to conclude that the machine on which I work has a little endian architecture?

是的。

考虑以与字节顺序无关的方式复制和打印数据:

#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
#include <string.h>

int main ()
{
  uint32_t test = 0x01020304;
  uint8_t array[4];

  for(size_t i=0; i<sizeof(uint32_t); i++)
  {
    size_t shift = 8 * (sizeof(uint32_t) - 1 - i);
    array[i] = (test >> shift) & 0xFF;
    printf("%.2" PRIx8 " ", array[i]);
  }

  return 0; 
}