测试Endianness:为什么以下代码有效?

时间:2011-07-03 18:03:06

标签: c++ c type-conversion endianness

虽然我确实理解字节顺序,但我对下面代码的工作方式略显不清楚。我想这个问题不是关于字节序的,而是更多关于char *指针和int如何工作,即类型转换。另外,如果变量word不是short而只是int,它会有什么不同吗?谢谢!

#define BIG_ENDIAN 0
#define LITTLE_ENDIAN 1

int byteOrder() {
    short int word = 0x0001;
    char * byte = (char *) &word;
    return (byte[0] ? LITTLE_ENDIAN : BIG_ENDIAN);
}

5 个答案:

答案 0 :(得分:17)

short int由两个字节组成,在本例中为0x000x01。在小端系统上,小字节首先出现,因此在内存中它显示为0x01后跟0x00。大端系统自然是颠倒过来的。对于小端系统上的短整数,这就是指针的样子:

----------------------- ----------------------- 
|   0x01   |   0x00   | |          |          | 
----------------------- ----------------------- 
   &word                  &word+1

另一方面,字符指针总是按顺序递增。因此,通过获取整数的第一个字节的地址并将其转换为char *指针,您可以按内存顺序递增整数的每个字节。这是相应的图表:

------------ ------------ ------------ ------------ 
|   0x01   | |   0x00   | |          | |          | 
------------ ------------ ------------ ------------ 
   &byte       &byte+1      &byte+2      &byte+3

答案 1 :(得分:7)

(char *)&word指向char的第一个(最低地址)word(字节)。如果您的系统是little-endian,则这将对应0x01;如果它是big-endian,这将对应0x00

是的,无论wordshortint还是long,这个测试都应该有效(只要它们的大小比{{1}更大})。

答案 2 :(得分:4)

这是一个可爱的小程序。你有一个单词被设置为十六进制文字1.如果你有小端,当你将指针转换为字符指针时,最低有效字节(在这种情况下为0x01)将在字节[0]。因此,如果0x01位于偏移0处,那么您知道它是小端,否则如果0x00位于偏移0处,您知道最低位的字节存储在较高的存储位置(偏移1)。

注意:指针始终指向字/数据结构的最低内存地址等...

答案 3 :(得分:2)

它告诉你short的字节序。至少在某些机器上,short恰好是两个字节。它不一定告诉你intlong的字节顺序,当然,当整数类型大于两个字节时,选择不是二进制。

真正的问题是你想知道的原因。编写代码几乎总是更简单,更健壮,因此无关紧要。 (有一些例外,但它们几乎总是涉及非常低级别的代码,无论如何都只能在一个特定的硬件上运行。如果你知道硬件足以编写那种代码,你就知道了字节顺序。)

答案 4 :(得分:1)

在考虑big-endian vs little-endian时,我用来记住字节顺序的技巧是“名字应该是另一种方式”:

  • 当您手动编写数字时,自然的方法是从左到右书写,从最高位开始,以最低位数结束。在您的示例中,您首先写入最高有效字节(即0),然后写入最低有效字节(即1)。这就是big-endian的工作原理。当它将数据写入存储器(增加字节地址)时,它以最不重要的字节结束 - “小”字节。所以,big-endian实际上以小字节结束。

  • 对于little-endian也是如此:它实际上以最重要的字节结束,即“大”字节。

您的源代码检查第一个字节(即byte [0])是否是最重要的字节(0),在这种情况下,它是'big-startian'或小端字节排序。