这道题目是我在面试的时候碰到的。当时面试官问我的时候,由于我什么基础都比较差,我听到这个问题的时候整个人都傻了。我心想当时学c语言的时候,我只记得老师说这个都代表a数组的首地址啊,这有什么区别呢?这道题目,我最终没有答出来,都怪我太菜了。今天这篇文章就当做是一个记录吧,也希望能给还不q清楚的同学一点分享。
我们先看一段代码
#include<iostream> using namespace std; int main() { int a[5]={1,2,3,4,5}; int *ptr=(int *)(&a+1); cout<<"*(a+1)="<<*(a+1)<<"*(ptr-1)="<<*(ptr-1); }
我直接给出输出结果:
*(a + 1) = 2 *(ptr – 1) = 5
这是为什么呢?*(a + 1) = 2这个结果我们很好理解,为什么*(ptr – 1) = 5?
原因是a代表数组a的首地址,而&a代表的是整个数组a的地址,因而他们本身的值是一样的。但是当它们分别进行加1的时候,这个就完全不同了。如下图所示:
由上图可以很清晰的看到,由于&a代表的是整个数组的地址,因此&a + 1就到了如图所示的位置。那问题又来了,那为什么*(ptr – 1) = 5呢?加1到了未知的第一点,那减1不应该是回到数组的起始位置了嘛?事实上,这个猜测是错误的,因为&a+1指向未知的第一点,当把其赋值给ptr之后,ptr又退化成了一个普通的指针,就像a一样,减一之后回到了数组的尾部。
好,这样讲,是不是清楚了一些?为了验证我们的判断,下面我们将a和&a等地址值直接打印出来,用数据说话。请看下面一段代码
#include<iostream> using namespace std; int main() { int a[5]={1,2,3,4,5}; cout<<"a="<<a<<endl; cout<<"a+1="<<a+1<<endl<<endl; cout<<"sizeof(*a)="<<sizeof(*a)<<endl; cout<<"sizeof(a)="<<sizeof(a)<<endl; cout<<"a+1="<<a+sizeof(*a)<<endl<<endl; cout<<"&a="<<&a<<endl; cout<<"&a+1="<<&a+1<<endl<<endl; cout<<"sizeof(int)"<<sizeof(int)<<endl; cout<<"&a+1="<<&a+6*sizeof(int)<<endl; return 0; }
结果:
a=0xbfdc272c a+1=0xbfdc2730 sizeof(*a)=4 sizeof(a)=20 a+1=0xbfdc273c &a=0xbfdc272c &a+1=0xbfdc2740 sizeof(int)=4 &a+1=0xbfdc290c
我们来分析一下这个结果,&a和a同样指向数组a的起始地址,&a + 1指向第一个未知。由于数组a有五个数据,一个int型的数据为4个字节,所以&a + 1相比&a而言加了20个字节。后面一样分析,如果是&a + 2那么就加40个字节了。怎么样?清楚了吧???哈哈哈。。。。。
如果你了解到这里已经觉得够了的话,那就不用再往下看了。如果有时间并想了解更多的话,那么你也只需要再话一分钟的时间就可以把下面的内容消化掉。请看一段代码:
#include<iostream> using namespace std; void main() { int a[5]={1,2,3,4,5,6}; int (*p)[5]; cout<<" a type="<<typeid(a).name()<<endl; cout<<" &a type="<<typeid(&a).name()<<endl; cout<<" p type="<<typeid(p).name()<<endl; }
结果:
a type = int *
&a type = int (*)[5]
p type = int (*)[5]
我们再次清楚的认识到,原来&a和p一样是一个指针数组,这下都清楚啦吧。哈哈。。。。。
本文完,有什么问题,欢迎各位留下您宝贵的评论。
参考资料:http://hi.baidu.com/fileslijbpbapsd/item/68b7644efbcdbfacdf2a9fa2
测试平台:www.anycodex.com
机会只留给有准备的人。加油!
原文:http://blog.csdn.net/xiaxia__/article/details/19421401