指针算术和地址

时间:2012-09-27 14:34:40

标签: c pointers memory-address

我遇到的代码如下:

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

3 个答案:

答案 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