我发现了一段输出结果让我无法理解的代码。这段代码是:
int main()
{
int a[] = {1, 2, 3, 4, 5, 6};
int *ptr = (int*)(&a+1);
printf("%d ", *(ptr-1) );
return 0;
}
上述代码的输出结果为6,但我认为应该是1。请解释为什么会是6。
我发现了一段输出结果让我无法理解的代码。这段代码是:
int main()
{
int a[] = {1, 2, 3, 4, 5, 6};
int *ptr = (int*)(&a+1);
printf("%d ", *(ptr-1) );
return 0;
}
&a
是数组 a
的地址。将其加上 1
将使其增加到数组之后的一个位置(增加 24 字节)。转换运算符 (int*)
将 &a+1
转换为指向 int
类型的指针。ptr-1
仅会将 ptr
减少 4
字节,因此它是数组 a
的最后一个元素的地址。对 ptr - 1
进行解引用将给出最后一个元素,即 6
。
&a
和a
在内存中具有相同的地址。区别在于它们的类型以及它们如何反映到指针算术中。很好的答案(看不出任何理由对其进行负投票)。 - Grzegorz Szpetkowski&a
和a
具有相同的_value_”。&a
没有地址。 - chux - Reinstate Monica是的,因为a
是一个类型为int[6]
的数组。因此,&a
给出了类型int (*)[6]
。它不是指向int的指针,而是指向int
数组的指针。
所以,&a + 1
将指针增加了一个数组大小,指向数组的最后一个元素之后。
然后,在ptr
中取地址并执行-1
,将地址减少sizeof(*ptr)
,即sizeof(int)
,这会给出数组中最后一个元素的地址。
最后,对该地址进行解引用,您将得到最后一个元素的值6
。成功。
因为(int*)(&a+1)
将整个数组作为基本类型,并在地址上增加了一个整个数组的大小,即增加了24个字节。
当你执行ptr-1
时,由于ptr
的类型是int,它只会减去4个字节。
在进行指针运算时要记住指针的类型非常重要。
&a+1
只会在内存地址中向前移动一个字节...应该是&a + sizeof(int)
,基本上是这样的。 - Marc Bint *ptr = *(&a+1);
。 - thisint
最终是16位。但它也可以更多。对于典型的32位CPU,它大多数时候是32位(4个八位字节)。 - too honest for this site