我遇到的代码如下:
#include <stdio.h>
int main(void)
{
int a[5] = { 1, 2, 3, 4, 5};
int *ptr = (int*)(&a + 1);
int *ptr2 = (int*) &a;
ptr2 +=1 ;
printf("%d %d %d \n", *(a + 1),*(ptr - 1) ,*ptr2 );
return 0;
}
除了这一行,指针算术对我来说是这样的:
int *ptr = (int*)(&a + 1);
是不确定的行为?
为什么我们会5
取消引用*(ptr - 1)
?
答案 0 :(得分:3)
a
的大小为“5 int
s”。因此,&a + 1
指的是{em>所有a
的第一个内存位置过去,因为指针算术以a
的大小为单位完成。
答案 1 :(得分:2)
尝试一下!
int a[5] = {1, 2, 3, 4, 5};
printf("%#x, %#x, %#x, %#x\n", a, &a, a+1, &a+1);
0xbfa4038c, 0xbfa4038c, 0xbfa40390, 0xbfa403a0
那告诉我们什么?
0xbfa4038c == 0xbfa4038c
表示a == &a
。这是数组中第一个元素的地址或a[0]
。
我们知道int的大小是4,你知道*(a+1)
== a[1]
(数组中的第二个元素),这证明了:
0xbfa4038c + 0x4 = 0xbfa40390
表示a + one int = address of the next element
因此,如果我们看到&a+1 == 0xbfa403a0
,那意味着我们在数组中有((0xa0-0x8c)/4)
= 5个元素。您知道a[5]
无效,因此这意味着我们已经通过了数组的末尾。
所以,如果你采取:
int *ptr = (int*)(&a + 1); //one passed last element in the array
printf("%d",*(ptr - 1));//back up one, or last element in the array and deference
这就是你得到5
答案 2 :(得分:0)
对于类型为T的n个元素的数组,则第一个元素的地址具有“指向T”的类型; the address of the whole array具有类型'指向类型为T'的n个元素的数组的指针;
int *ptr = (int*)(&a + 1); //&a-> address whole array, size=20 bytes,
//ptr=&a+1: next element =adress of a +20 bytes.
//ptr - 1 = address of a +16 = address of last a's element = address of 5