先来看一个例题,写出下面一段程序输出结果:
int a[]={1,2,3,4,5};
int *pa = a;
int *p = (int*)(&a+1);
printf("%d, %d\n", *(a+1), *(p-3));
结果:2, 3
a中的元素为整形,a是数组名,它是一个指针,故a的类型是 指向整形元素的指针,因为a是数组,所以&a的类型是指向整形数组的指针,这就意味着&a指向的元素是数组,所以&a+1中,这个加1操作应该根据指针指向元素类型来调整它最终在地址上增加的值
int a[]={1,2,3,4,5};
int *pa = a;
printf("%d %d %d %d\n",a,a+1,pa+1,&a+1);
对于a来说,它是指向整形整形元素的指针,整形在32位CPU上站4字节,上面代码输出内容为:
2293492 2293496 2293496 2293512
a+1 的地址想对于a的地址增加了4,即一个整形数据的大小,而&a+1的地址相对于a的地址增加了 5*4=20,这个20 就是a数组中5个整形元素占用的空间,这也就证明了指针与一个整数相加(或相减)后,地址的偏移量与此指针指向的数据类型相关.
再回来看上面那道题,&a+1指向了a数组末尾的后一个地址a[5](非法地址),&a+1又被转换为指向整形数据的指针,所以p=a+5,,故*(p-3) -->*(a+5 - 3)-->*a(a+2)-->a[2],即其值为3