我遇到一个密码,它是这样的:

#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

最佳答案

试试看!

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,这意味着我们在数组中有5个元素。你知道((0xa0-0x8c)/4)是无效的,所以这意味着我们是数组末尾的一个。
所以如果你采取:
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

这就是为什么你得到a[5]

关于c - 指针算术和地址,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12623821/

10-11 21:14