我在计算机上用以下代码部分编写了一个C程序:
uint32_t test = 0x01020304;
uint8_t array[4];
memcpy(array, &test, 4);
printf("%02x %02x %02x %02x
",array[0], array[1], array[2], array[3]);
它打印04030201,但我希望是01020304。
我是否必须得出结论,我使用的机器具有一点字节顺序架构?
是的你应该。
是的,最近的许多CPU(Intel)中都使用little endian。
顺便说一句,memcpy参数的强制转换是不必要的。
@ PeterA.Schneider在没有演员表的情况下得到警告:warning: passing argument 2 of ‘memcpy’ makes pointer from integer without a cast [-Wint-conversion]
在C ++程序中以编程方式检测字节序的可能重复项
@ Raoul722-当您看到该警告时,您的代码是memcpy(array, test, 4);还是memcpy(array, &test, 4);(注意第二个&)? 第二个示例是正确的,不应警告您。
编译器不应发出警告(gcc 4.9.3不会)。 也许您不经意间删除了&演员?
@ PeterA.Schneider确实,与符号已被删除。 谢谢你的提示!
正如Mohit所说,是的:输出显示最低有效位在内存的较低地址,或"小端优先"。或"小尾数"。
这可能有些令人困惑,尤其是对于从左到右书写和阅读的西方人。我只能怀疑读写希伯来语或阿拉伯语的人会感到困惑。
结果之一是,移位运算符以它们似乎指示的相反的"方向"工作。
关于字节顺序的优缺点已经有很多争论。最后,这无关紧要,当然,C的一项重大成就就是从具体体系结构中抽象出足以平滑差异并使程序具有可移植性(但又不能阻止对位和字节的访问)。
在使用小字节序的情况下,字节中的位仍然从右到左递增(我们写它们的方式),而字节从左到右递增(如果我们写更高的地址),这有点不直观。
另外,互联网字节顺序为Big Endian,因此使用htonl()和朋友很重要。 (请不要重新实现这些功能。)
小尾数字节顺序的一个不错的特性是,无论您在存储单元中采用哪种数据类型,小值都是相同的。如果您将32的int值23写入地址x并稍后以char形式读取,则为23;在大字节序的计算机上,该值为0。
根据字节顺序,移位运算符不会给出不同的结果。 例如,a << n被指定为提供与a乘以2,n倍相同的值。 在某些情况下,移位会带来不确定的/未指定的行为,但这与字节序无关。 也有中端机和混合端机。
@Peter完全正确。 这就是为什么<
Do I have to conclude that the machine on which I work has a little endian architecture?
是。
考虑以与字节序无关的方式复制和打印数据:
#include
#include
#include
#include
int main ()
{
uint32_t test = 0x01020304;
uint8_t array[4];
for(size_t i=0; i
{
size_t shift = 8 * (sizeof(uint32_t) - 1 - i);
array[i] = (test >> shift) & 0xFF;
printf("%.2" PRIx8"", array[i]);
}
return 0;
}