代码的输出-&;在c中
我遇到一个代码,它的输出我无法理解。代码是-代码的输出-&;在c中,c,arrays,pointers,pointer-arithmetic,C,Arrays,Pointers,Pointer Arithmetic,我遇到一个代码,它的输出我无法理解。代码是- int main() { int a[] = {1, 2, 3, 4, 5, 6}; int *ptr = (int*)(&a+1); printf("%d ", *(ptr-1) ); return 0; } 上面代码的输出是6,但我认为应该是1。请解释为什么它是6。是的,因为a是一个类型为int[6]的数组。因此,&a为您提供类型int(*)[6]。它与指向int的指针不同,它是指向int
int main()
{
int a[] = {1, 2, 3, 4, 5, 6};
int *ptr = (int*)(&a+1);
printf("%d ", *(ptr-1) );
return 0;
}
上面代码的输出是6,但我认为应该是1。请解释为什么它是6。是的,因为
a
是一个类型为int[6]
的数组。因此,&a
为您提供类型int(*)[6]
。它与指向int的指针不同,它是指向int
数组的指针
所以,&a+1
将指针增加一个数组大小,指向数组的最后一个元素
然后,在ptr
中获取地址并执行-1
,将地址减少sizeof(*ptr)
,即sizeof(int)
,它给出数组上最后一个元素的地址
最后,取消引用该地址,得到最后一个元素的值,
6
。成功。&a
是数组a
的地址。向其添加1
将使其增量超过数组的1(添加24个字节)。Cast操作符(int*)
Cast&a+1
指向int
类型的指针ptr-1
只将ptr
减少4个字节,因此它是数组a
的最后一个元素的地址。取消引用ptr-1
将给出问题中的最后一个元素6
“&a”是整个数组a[]的地址。如果我们在&a中添加1,则得到“a[]+sizeof(a)的基址”。这个值被类型转换为int*。所以ptr指向6之后的内存。将ptr打印为“int*”,并打印*(ptr-1)的值。由于ptr将内存指向6之后,因此ptr–1指向6。因为(int*)(&a+1)
使用整个数组作为基类型,并将数组的1个完整大小添加到地址,即添加24个字节
当您执行ptr-1
时,因为ptr
类型为int,所以它只减去4个字节。
在进行指针运算时,记住指针的类型非常重要。int是2个字节<代码>&a+1
只向前移动内存地址中的一个字节…它基本上应该是&a+sizeof(int)
。这在技术上是未定义的行为,因为您是从不兼容的指针进行强制转换的,应该是int*ptr=*(&a+1)
@MarcB No,这将指向超出范围的地方。@MarcB:int
是最后16位。然而,它可以是更多的。对于典型的32位CPU,它最多是32位(4个八位字节)的倍数。C中的数组名称给出了第一个元素的地址(sizeof运算符中除外)。将1添加到此地址将给出该地址加上该数组所具有类型的第二个sizeofelement@DeepakTiwari:自动将数组转换为指针有更多例外。看见这实际上包括了你刚才在回答中给出的原因。有趣的是,&a
和a
在内存中都有相同的地址。区别在于它们的类型以及如何反映指针算法。回答不错(看不出有理由否决它)@grzegorzzpetkowski@Grzegorzzpetkowski详图“两个&a
和a
具有相同的值”<代码>&a没有地址。