如果我在C中使用指针[Index]会发生什么?

3bygqnnd  于 2022-12-03  发布在  其他
关注(0)|答案(3)|浏览(135)

我是一个C语言的初学者,我想知道如果我写这样的东西会发生什么:

int *p;
    int b = 4;
    int a = 3;
    p = &a;
    printf("%d", p[1])

我期待的结果是“4”,然而,我得到了一个意外的结果(这是一个随机数)
下面我也做实验:EXP1EXP2显示器
这让我更困惑了。我想要一些解释,谢谢。

igetnqfo

igetnqfo1#

p[1]指向p所指向的对象结尾之外。取消引用此指针是未定义的行为。

falq053o

falq053o2#

编译器不一定要按照定义对象的顺序存储对象。
“如果你递给一个助手一本书、一个盒子和一个瓶子,你让他们把这些东西放在架子上,你认为他们一定会按照这个顺序把它们放在架子上吗?不,他们可能会先拿一个最容易操作的东西放在架子上,然后再放一个。”然后是另一个。如果他们不认为有任何意义,他们也不在乎你把物品交给他们的顺序。
当你给编译器定义对象时,编译器会根据诸如大小和对齐要求之类的属性来管理它们。它不一定按照你定义它们的顺序来保存它们。它可能会在某些数据结构中按字母顺序来存储它们。或者它可能会按散列码的顺序来存储它们。当它开始给项目分配内存位置时,它可能会首先处理具有最严格对齐要求的对象,然后,在每个组中,按字母顺序或通过遍历其自身内部数据结构来检索它们。
所以,b在内存中不一定在a之后。
但是,即使是这样,C标准也没有定义当p指向a时访问p[1]的行为。这意味着编译器在分析代码的含义时,可以决定printf("%d", p[1])没有含义,并可以忽略它。因此,编译器优化可以以令人惊讶的方式转换程序。

4ktjp1zp

4ktjp1zp3#

一个有趣的事情是,当你使用clang来编译它时,你可以得到4(https://tio.run/##S9ZNzknMS///XzkzLzmnNCVVwaa 4JCUzXy/Djiszr 0 QhNzEzT 0 OTq 5 pLQQHE 1 SqwBrIg 7 CQFWwUTBDcRyDWGcAuATLVEKLsIKJmmoaSaoqSjUBBtGKtpzVX 7/z 8A),但是它仍然是一个未定义的行为,不应该像预期的那样使用。

相关问题