/*************************************************************************
> File Name: point.c
> Author: XXDK
> Email: v.manstein@qq.com
> Created Time: Thu 02 Mar 2017 11:06:13 PM PST
************************************************************************/
#include<stdio.h>
int main()
{
int a[] = {1, 2, 3, 4, 5};
int *ptr1 = (int*)((long)a + 1);
int *ptr2 = (int*)(&a + 1);
printf("a: %p\n", a);
printf("&a: %p\n", &a);
printf("&a[0] %p\n", &a[0]);
printf("*ptr1 = %#x\n", *ptr1);
printf("ptr2[-1] = %#x\n", ptr2[-1]);
return 0;
}
输出:
a: 0x7ffd74dfc4e0
&a: 0x7ffd74dfc4e0
&a[0] 0x7ffd74dfc4e0
*ptr1 = 0x2000000
ptr2[-1] = 0x5
分析:
1. 这里重点是指针的寻址能力,将a[]的地址强转为long类型,然后 + 1, 就是
0x7ffd74dfc4e0 + 1 = 0x7ffd74dfc4e1
然后,将这个long数值,强转为int*, 也就是int类型的指针,我们知道,这里
0x7ffd74dfc4e1 为0x7ffd74dfc4e0 偏移8bit,得到的一个起始地址,从这个起始
地址寻址4字节,则包含了0x7ffd74dfc4e4的末尾的8bit,由于0x7ffd74dfc4e4存
放数组的第二个元素就是2,相当于0x7ffd74dfc4e4末尾为00000010,从而取出
里面的数据是[地址0x7ffd74dfc4e4里面的数据的末尾的8bit <<24 + 地址 0x7ffd74dfc4e0 里面的数据 >> 8bit]
从而得到2^26 = 0x2000000
2. 对于 int *ptr2 = (int*)(&a + 1), 首先&a取的是数组的首地址,那么它的类型就是数组指针,即,int (*)p[5],
也就是指向包含五个整型数组的类型的指针。有了类型,辣么,指针的偏移肯定是以类型为基准所以&a + 1,就是
下一个包含五个整型数组的首地址,也就是a的第五个元素的下一个地址(int类型),将其强转为int*,然后
ptr[-1],就是从ptr指向的位置向前(低地址区)寻址一个int宽度,恰好是a的末尾元素的内存去,故而得: 0x5