Little endian与Big endian
假设我有4Byte整数,我想将它转换为2Byte短整数。 我是对的,在(小端和大端)短整数将包含这个4Byte整数的2个最低有效字节?
第二个问题:
小端和大端处理器中这些代码的结果是什么?
int i = some_number; short s = *(short*)&i;
在大端处理器2中的恕我直言,将复制最重要的字节,在小端,将复制2个最低有效字节。
我是对的,在两个短整数中都包含这个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有什么优势呢? 它创建更容易阅读的hex转储。
实际上,摩托罗拉的工程师认为减轻读取hex转储的负担比向后兼容更重要。 英特尔的工程师相反。
-
是。 转换值时,您不必担心字节序。
-
是。 当你转换指针时,你做到了。
首先,您可能已经知道了,但我要提一下,int的大小不能保证为4个字节,而且所有平台的大小都是2个字节。
如果在你的第一个问题中,你的意思是这样的:
int i = ...; short s = (short)i;
那么是的, s
将包含i
的低位字节。
我认为你的第二个问题的答案也是肯定的; 在字节级别,系统的字节顺序确实起作用。
你应该知道你的第二个例子
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。
如果你真的想将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在短的范围内,那么您也可以跳过检查。