看下面的程序,输入什么?
#include<stdio.h>
int main()
{
int a[] = {1, 2, 3, 4, 5};
int *p = (int *)(&a+1);
printf("p = %d\n", *a);
printf("p = %d\n", *(a+1));
printf("p = %d\n", *(p-1));
return 0;
}
结果是:
p = 1
p = 2
p = 5
- a 其实就是一个指针 ,指向第一元素, 所以*a就是1
- a+1是指针的偏移,偏移大小由指针a指向的类型来决定,上例子中,a指向int 型,所以加1就执行下一个整型元素。
- 第3个怎么解释呢。 首先是&a, 是指针的指针, p指向 a偏移了1的位置. 这个1有多大?
那要看a是什么类型,上面定义a的时候是等价于int a[5] = {1, 2, 3, 4, 5}; 所以类似于 int b
把类型和变量分开,b是int类型。 同样,把int a [5]也分开,就是int[5] a 。所以a是 int[5]类型的。那么&a就是指向一个int[5]类型的指针,这个指针加1,这个1的偏移量就是int[5]的大小,也就是5个整型的大小。这样的话p就指向这个数组5本身所在地址的后一个地址了。由于p是指向整型的,所以p-1的这个1是1个int的大小, 所以,p-1就回到了5所在的地址了。所以第三个就是5了
如果p的值成为这样,那么p指向哪里?
int *p = (int *)&a+1;
结果是p指向a[1]的地址
这里涉及一个强制转换的概念, a原本指向的类型是int[5] , 上面的在括号i里加1就直接跳跃5*sizeof(int)个地址。
这里先进行了强制转换,现在a指向的类型是int ,加1就跳跃sizeof(int)个地址,就是a[1]所在的位置