Little endian与Big endian

时间:2010-02-11 21:12:44

标签: c pointers casting endianness

假设我有4Byte整数,我想将其转换为2Byte短整数。我是对的,在(小端和大端)短整数将包含这个4Byte整数的2个最低有效字节?

第二个问题:
小端和大端处理器中这些代码的结果是什么?

int i = some_number;  
short s = *(short*)&i;

大端程序处理器2中的恕我直言将复制最重要的字节,并且在小端中将复制2个最低有效字节。

5 个答案:

答案 0 :(得分:12)

  

我是对的,在两个短整数中都包含这个4Byte整数的2个最低有效字节吗?

是的,根据定义。

bigE和littleE之间的区别在于最低有效字节是否位于最低地址。在小端处理器上,最低地址是最低有效位,x86就是这样做的。

这些在小E上给出相同的结果。

short s = (short)i;
short s = *(short*)&i;

在大端处理器上,最高地址是最低有效位,68000和Power PC这样做(实际上Power PC可以同时使用,但Apple的PPC机器使用bigE)

这些在大E上给出相同的结果。

short s = (short)i;
short s = ((short*)&i)[1]; // (assuming i is 4 byte int)

因此,正如您所看到的,little endian允许您获取操作数的最低有效位,而不知道它有多大。 little E具有保持向后兼容性的优点。

那么big endian有什么优势呢? 它创建更容易阅读的十六进制转储。

真的,摩托罗拉的工程师认为减轻读取十六进制转储的负担比向后兼容更重要。英特尔的工程师认为恰恰相反。

答案 1 :(得分:2)

  1. 是。转换值时,您不必担心字节序。

  2. 是。当您转换指针时,就可以。

答案 2 :(得分:1)

首先,您可能已经知道了,但我要提一下,int的大小不能保证为4个字节,而且所有平台的大小都是2个字节。

如果在你的第一个问题中你的意思是这样的话:

int i = ...;
short s = (short)i;

然后是,s将包含i的低位字节。

我认为你的第二个问题的答案也是肯定的;在字节级别,系统的字节顺序确实发挥作用。

答案 3 :(得分:1)

你应该知道你的第二个例子

int i = some_number;  
short s = *(short*)&i;

是无效的C代码,因为它违反了严格的别名规则。在某些优化级别和/或编译器下可能会失败。

使用联盟:

union {
   int   i;
   short s;
} my_union;

my_union.i = some_number;
printf("%d\n",my_union.s);

另外,正如其他人所说,你不能假设你的整数是4个字节。当您需要特定尺寸时,最好使用int32_t和int16_t。

答案 4 :(得分:1)

如果你真的想将int转换为short,那就这样做:

short int_to_short(int n) {
  if (n < SHRT_MIN) return SHRT_MIN;
  if (n > SHRT_MAX) return SHRT_MAX;
  return (short)n;
}

您甚至不必担心endian,语言会为您处理。如果您确定n在短的范围内,那么您也可以跳过检查。