0

我遇到了这样的代码:

#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)

4

3 回答 3

3

的大小a为“5 ints”。所以&a + 1指的是过去所有的第一个内存位置a,因为指针运算是以 的大小为单位完成的a

于 2012-09-27T14:36:34.170 回答
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

于 2012-09-27T14:52:44.660 回答
0

对于类型为 T 的 n 个元素的数组,则第一个元素的地址类型为“指向 T 的指针”;整个数组的地址类型为“指向 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
于 2012-10-01T11:11:46.687 回答