为什么两个相同值的整数指针指向同一个东西(via ==)?

kga*_*dis 4 c pointers integer

int *x = 3;
int *y = 3;

if (x == y) "this statement evaluates to true" (pointer equality statement)
if (*x == *y) "this statement evaluates to true"
Run Code Online (Sandbox Code Playgroud)

是指针等式语句变为真的原因,仅仅是因为COMPILER看到两个"静态"数字"3"并且说,嘿指向同一个地方?或者一般来说整数有一些魔力.

显然,冗余引用整数指针与未解除引用相同(在本例中).

我已经看到了一些与字符串相关的问题的例子(两个指针的地址是相同的),但是想要澄清它.

Kei*_*son 10

int *x = 3;
Run Code Online (Sandbox Code Playgroud)

这是无效的(违反约束),并且需要符合标准的编译器来发出诊断,并且可以完全拒绝它.您不能使用整数值来初始化指针(除了特殊情况0,它是一个空指针常量).

如果编译器碰巧接受它,它可能会将其视为等效于:

int *x = (int*)3;
Run Code Online (Sandbox Code Playgroud)

这会导致指针x指向3内存中的地址.这几乎肯定是荒谬的.

鉴于x并且y使用相同的表达式进行初始化(假设您的代码未被拒绝),这并不奇怪x == y.

解除引用x具有未定义的行为; (int*)3很可能不是一个有效的地址,因为它超出了程序的合法寻址空间和/或因为它未对齐.但如果 *x碰巧"工作"并产生价值,那么这也就不足为奇了*x == *y.编译器可能认识到了这一点x == y并因此得出结论*x == *y.您可以通过检查生成的代码来确定.但这真的没关系; 一旦你的程序的行为未定义,完全可以发生任何事情(或者更确切地说,语言标准允许任何事情发生;物理定律可能还有别的东西可以说).

您应该已经收到两个声明的警告.如果你这样做,你应该留意它.如果没有,您应该了解如何增加编译器的警告级别.

  • @anon:对,问题是`3`不是指针值.使用例如`(int*)0xdeadbeef`的例子,虽然明确表示这只是一个例子而不一定是有效的地址,但可能更清楚地说明了这一点.有一个共同的态度,整数和指针"真的"是一样的东西,但恕我直言,最好保持概念不同. (2认同)

Mar*_*c B 6

你只需要为两个指针硬编码一个固定的内存地址3.有理由认为这个简单的地址是相同的,并且无论数据实际上是哪个AT地址都是相同的.

这就像你的冰箱上有两个粘滞便笺.两人都说"钥匙在门上".通过jove,当你去门口看时,有你的钥匙.两个不同的指针,都指向同一件事.

  • 你假设`int*x = 3;`相当于`int*x =(int*)3;`.目前尚不清楚这是真的.无论如何,这是违反约束的行为. (2认同)