假设我有 4Byte 整数,我想将它转换为 2Byte 短整数。我是否正确,在(小端和大端)短整数中都将包含这个 4Byte 整数的 2 个最低有效字节?
第二个问题:
这样的代码在小端和大端处理器中会产生什么结果?
int i = some_number;
short s = *(short*)&i;
恕我直言,在大端处理器中,2 个最高有效字节将被复制,而在小端处理器中,2 个最低有效字节将被复制。
假设我有 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 E 在保持向后兼容性方面具有优势。
那么大端有什么好处呢?它创建更易于阅读的十六进制转储。
确实,摩托罗拉的工程师认为减轻读取十六进制转储的负担比向后兼容更重要。英特尔的工程师认为恰恰相反。
是的。转换值时,您不必担心字节顺序。
是的。当您转换指针时,您会这样做。
首先,你可能已经知道了,但让我提一下,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;
}
您甚至不必担心字节序,该语言会为您处理。如果您确定 n 在 short 范围内,那么您也可以跳过检查。