【重新上本科】从一道笔试题来看数组和指针的区别(c++)

今天整理笔试题,将来作为我们这些人笔试、面试新同学的参考。题目的来源多种多样,有的有参考答案,有的没有。没有的,我就自己想想,填上去,然后发给大家校对。有道题目我没有做对,是考察c/c++的指针和数组的,组内同学指出后,我又尝试了下、想了想,现在想通了,记录下来。

哎,手艺荒废好久,也要时常捡一捡。或者当初就是没弄扎实,那就每天进步一点点。感谢二师兄的指正!


题目是这样的:

对于short int数组a[10],a[8]的地址是?

A. a

B. a + 8

C. a + 16

D. a + 32


我想了想,short类型的变量占两个字节,a[8]是第8个元素,那么总共就是16个字节的距离,所以选择C。不过二师兄告诉我,应该是B,而且在windows上和在linux上他都验证过了。我用visual studio,用c++编译器和c编译器编译出程序都尝试了一下,运行时a[8]的地址果然与‘a+8‘是一致的。这是怎么回事?

数组名字‘a‘本身就是一个内存地址,a[8]也好还是a + 8也好,都是在计算距离地址‘a‘的偏移。数组中存储的数据类型不同,偏移也不同。不过,对于不同类型的数组,short也好、int也好,运行时a[8]的地址始终和‘a+8‘保持一致。很”智能“啊。而且,既然c++和c的编译器编译出的程序运行结果都一样,说明这种貌似的”智能“不是c++语言特性所带来的,而是更为基本的概念。平时在面试新同学的时候,我也爱问c语言中指针和数组的区别,最近半年很少问了,看来要再回想下这部分了。

边想边上网上搜,现在想明白怎么回事了。

不兜圈子了,上面的”智能“是谁干的?答案是编译器干的。咋干的?这就引申到我们最初的问题,c语言中,数组和指针啥区别?

当然,两者都是表示地址。不过还有个关键区别。数组的地址在编译的时候是确定的,是个常量。数组名字+偏移,或者是传统的方括号写法,如:a[8],无论哪种写法,数组变量的地址都是在编译的时候由编译器计算好的。编译器当然知道数组中存储的元素是什么类型、占多大存储空间,所以自然很”智能“的能够正确计算出数组中元素的偏移地址。所以‘a+8‘就是数组a中第8个元素的地址。而指针呢?指针是变量,在编译的时候我们无法确定变量的值(否则就是常量了),只有在运行的时候,才能确定指针的值,也才能确定相对这个指针指向的地址,它的偏移的值。如果写代码:

short int * pbase = 0x0010;
short int * pshift = pbase + 8;
那么pshift的值原则上在程序运行的时候才能够得到(不排除某些编译器增加优化选项后,在编译的时候计算出这个值)。而且,cpu要取得a[8]的值,只要按照编译器计算好的地址去获取就行;而指针pshift指向地址的值*pshift,cpu在获取的时候,首先要获得pshift的值,然后才能按图索骥获得*pshift的值,也就是说,要两次访问内存。从这个角度来看,数组在运行的时候更快一些。


在网上找到一篇从编译器角度来看数组和指针的区别的文章,感觉讲的不错,大家可以参考:http://www.spongeliu.com/28.html


完。


转载请注明出处:http://blog.csdn.net/xceman1997/article/details/19857209


郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。