技术的乐趣在于分享,欢迎多多交流,多多沟通。
全部博文(877)
分类: LINUX
2014-04-29 12:11:06
假设有int a[];那么a实际上是数组a的首元素a[0]的首地址,而&a是数组的首地址,其值和&a[0]相等,但是两者的意义不同,这一点可以从指针的移动运算方面得到验证。且看下面程序:
#include
int main()
{
int a[5]={1,2,3,4,5};
int *ptr=(int *)(&a+1);//强制类型转换,将其转换为指向整型变量的指针(也可以不转换)
printf("%#0x,%#0x,%#0x,%#0x,%#0x/n",a,a+1,&a,&a+1,ptr);
printf("%d,%d/n",*(a+1),*(ptr-1));
return 0;
}
上述程序的输出结果为:
0x12ff6c,0x12ff70,0x12ff6c,0x12ff80, 0x12ff80
2,5
对上述结果的分析如下:
对指针进行加1操作,得到的是下一个元素的地址而不是原有地址值直接加1。一个类型为T的指针的移动,以sizeof(T)为移动单位。上述程序中,a是一个一维整型数组,有5个元素。
a是数组a的首元素的首地址相当于&a[0],a+1是数组a的下一元素的地址,即&a[0]+sizeof(int)。&a+1的含义是取数组a的首地址,该地址的值加上sizeof(a)的值,即&a+5*sizeof(int),也就是下一个数组的首地址,显然已经超过了数组的界限。(int *)(&a+1)是把上一步计算出来的地址强制转换为int *类型,赋值给ptr。*(ptr-1)的值怎么算呢?ptr-1实际上指向a[4],因此*(ptr-1)的值为5。
下面是程序调试时,上述各个地址的值。这里有一个问题就是调试窗口显示的&a+1的值为什么和printf打印出来的不一样?原因就是,当你把&a+1放到watch窗口中观察其值时,表达式&a+1已经脱离了它的上下文环境,编译器就很简单地把它解析为&a的值然后加上1byte,而a+1却是正确的,这可能是vc的一个bug。
参考资料:《C语言深度剖析》