我只是想尝试一下,我想知道这是怎么回事。我有以下代码:
int var1 = 132;
int var2 = 200;
int *secondvariable = &var2;
cout << *(secondvariable+2) << endl << sizeof(int) << endl;
我得到输出
132
4
那么第二个int怎么可能只有2个地址更高?我的意思是不应该是4个地址吗?我目前在WIN10 x64下。
问候
使用cout << *(secondvariable+2)
你不打印指针,你打印secondvariable[2]
的值,这是一个无效的索引并导致undefined behavior。
如果要打印指针,请删除取消引用并打印secondvariable+2
。
虽然你已经远离未定义行为的领域(参见Some programmer dude的answer),因为索引数组超出界限(对于这些问题,单个变量被认为是长度为1的数组),一些技术背景:
对准!允许编译器将变量放在地址上,以便最有效地访问它们。由于您似乎通过将2*sizeof(int)
添加到第二个变量的地址来获得有效输出,您显然已经意外地到达了第一个变量。显然,编译器决定在两个变量之间留一个间隙,这样两者都可以与可分割为8的地址对齐。
但是请注意,您不能保证这种对齐,不同的编译器可能会有不同的决定(或者在另一个系统上使用相同的编译器),并且甚至可能通过编译器标志更改对齐。
另一方面,数组保证占用连续的内存,因此您可以在以下示例中获得预期的结果:
int array[2];
int* a0 = &array[0];
int* a1 = &array[1];
uintptr_t diff = static_cast<uintptr_t>(a1) - static_cast<uintptr_t>(a0);
std::cout << diff;
对uintptr_t
(或者char*
)的演员确保你得到字节差异,而不是int
的大小......
这不是C ++的工作原理。
你不能像这样“导航”你的范围。
这种指针滑稽动作具有完全未定义的行为,不应依赖。
你现在没有在磁带上打孔,你正在写一个程序语义的描述,它被编译器转换成机器可执行的东西。
这些抽象的代码和一切都会好的。