这个程序为什么输出8589934593而不是4294967298?
问题描述:
这是一个滥用void*
ptr(这本身就是一个糟糕的编码习惯)的样本,但是当我查看内存细节时,它会变得很有趣。这个程序为什么输出8589934593而不是4294967298?
#include <iostream>
using namespace std;
typedef struct {
long a;
void print() {
std::cout << a;
}
} st;
int main() {
int t[2] = {1,2};
void* p = t;
st* spt = (st*) p;
spt->print();
return 0;
}
由于long
是64位,并且int
是32位的,在t时的两个整数,{1,2}
弥补了在struct
的long a
的空间。
但我的问题是,既然现在{1,2}
拼成a
,二进制内存走线应00000000000000000000000000000001 00000000000000000000000000000010
,这应该给其十进制格式4294967298
。但是,实际打印输出为8589934593
,即00000000000000000000000000000010 00000000000000000000000000000001
。看起来1
和2
的位置实际上是交换的。
这是怎么发生的?
答
在一个小端机的{ 1, 2 }
阵列在存储器布局为字节
01 00 00 00 02 00 00 00 // addresses increase from left to right
的以下序列当重新解释为一个64位的小端值,它产生8589934593
。
在大端机相同的阵列被布置为
00 00 00 01 00 00 00 02 // addresses increase from left to right
当重新解释为一个64位的大端值,它产生4294967298
。
因此,您的实验只是表明您正在小端机器上运行您的代码。这里的所有都是它的。
答
我重写更便携的方式你的代码,它需要C++ 11:
#include <cstdint>
#include <iostream>
int main()
{
union {
uint32_t t[2];
uint64_t a;
} val;
val.t[0] = 1;
val.t[1] = 2;
std::cout << val.a << ", " << std::hex << val.a << '\n';
}
我的AMD64机器上的输出是:
8589934593,200000001
它似乎完全有效,等于uint64_t(2) << 32 | uint64_t(1)
我想'00000000000000000000000000000001 0000000000000000000000000010'实际上是4294967298 – 2015-11-07 02:06:05
也许是因为你的机器使用小端。 – MikeCAT
这似乎是[endianess]的一个问题(https://en.wikipedia.org/wiki/Endianness)。 – clcto