向后工作:
e ++;
cout << e << " " << endl;
如果这打印 0,那么e
在执行此代码之前的值必须是-1
。
int e = &d - c;
所以上面地址减法的结果一定是-1
.
unsigned int a /* = whatever, the value of a doesn't matter */;
unsigned int &b = a;
unsigned int *c = &b;
unsigned int d /* = whatever, the value of d doesn't matter */;
b
是对 的引用a
,所以&b
等价于&a
。
So&d - c
等价于&d - &a
,并且那个减法产生-1
。
结论: 的地址d
是的地址之后的sizeof (unsigned int)
字节。(指针减法按指向类型的大小进行缩放。)a
大概。
事实上,减去指向两个独立定义对象的指针的行为是undefined。该标准几乎没有说明它应该做什么。
在实践中,编译器可能会为指针减法生成最简单的代码,并且该简单代码可能会将不相关的指针视为它们是可比较的,即使语言没有说它们是可比的。
考虑到您的程序的输出,这很可能b
并且d
恰好是彼此相邻分配的。没有说声明的变量必须按照声明它们的顺序分配。如果您希望以定义的顺序在内存中分配对象,请将它们放入 astruct
或使其成为数组的元素。
如果您在不同的系统上运行同一程序,或者在具有不同编译器的同一系统上,或者在具有不同编译器选项的同一编译器的同一系统上运行同一程序,也可能会产生不同的结果。原则上,它甚至可以在一切相同但在不同月相的情况下表现不同。
并且允许编译器假设您的代码的行为已明确定义,并执行仅在该假设下才有效的转换。实际上,通过减去两个不相关的指针,您已经向编译器保证它们都指向同一个数组对象的元素或刚好超过它的末尾(其中单个对象被视为 1 元素数组)(或两者都指向)是空指针;这是 C 和 C++ 之间的一个区别)。你对编译器撒了谎,这意味着它对你没有进一步的义务。
不要那样做。