我有一小段代码:
int main()
{
unsigned long long x = 0x0000000000008342;
unsigned long long * x_p = &x;
unsigned int * y_p = (unsigned int *)x_p;
unsigned int y = *y_p;
printf("y = %#.8x\n", y);
}使用小端,这就是一个数字的存储方式。
0x00: 42 83 00 00
0x04: 00 00 00 00但是,为什么它打印0x00008342而不是0x00004283?
发布于 2021-10-19 08:18:02
字节序适用于所有大于一个字节的整数类型。我不明白为什么您认为字节顺序只适用于64位整数类型,而不适用于int...这似乎是您困惑的根源。
您的代码的一个主要问题是unsigned int y = *y_p;是未定义的行为。What is the strict aliasing rule?,因此您的程序不能被假定为具有确定性行为。
如果您希望实际打印存储在内存中的字节,则需要逐个字节执行此操作:
for(size_t i=0; i<sizeof x; i++)
printf("%.2X ", ((unsigned char*)&x)[i] );这种转换很好,因为字符类型是严格别名的特殊例外。它会按照预期打印42 83 00 00 00 00 00 00。
这里还有一个小问题:0x0000000000008342。不要像编写64位整数常量那样编写前导零。这个类型实际上是int (32位系统)或unsigned int (8/16位系统)。前导零不做任何事情,你需要附加一个ull后缀。这在这个特定的代码片段中不是问题,但如果您将这种风格应用到实际程序中,可能会成为一个问题。
发布于 2021-10-19 08:24:46
printf("%x\n", unsigned_number);将以十六进制打印unsigned_number的值,就像printf("%u\n", unsigned_number);以十进制打印它一样。
两者都不关心unsigned_number的内部表示。printf("%x",...)不执行十六进制转储(当然,除非您在数据的每个字符上循环调用它)。
https://stackoverflow.com/questions/69626473
复制相似问题