vlambda博客
学习文章列表

从编译器角度分析数组名和指针的区别

链接:http://www.spongeliu.com/28.html

前言

数组名和指针是两个往往很容易让人们混淆的概念,很多人以为数组名就是一个指针,也有很多人知道数组名不同于指针但是仅知道数组名的值不能像指针一样改变,例如你可以写出下面这样的代码:

int *p;
p++;

却不能写这样的代码:

int a[];
a++;

那么数组名跟指针之间到底有什么区别呢?

区别一

在声明上,除了作为函数参数的数组名总是编译器转化成指针,其他情况下,数组名就是数组名,指针就是指针,二者不能混淆,你不能在一个文件中定义一个数组,而在另一个文件中把它声明成一个指针。

char a[];  //定义一个数组a
extern char* a; //在另一个文件中将a声明成一个指针

在编译器中,符号表用来存放C语言中有关标识符的属性信息,这些信息集中反应了标识符的特征属性。

等到词法分析到代码声称的各个阶段的时候,编译器需要根据源代码提出的要求,从表中获取不同标识符的不同属性。

值得注意的是,数组标识符的属性和指针是完全不同的。因此,在一个文件中定义一个数组的时候,编译器会把它记录在符号表中,而在编译器分析另一个文件中的声明时,通过符号的语义检查发现不一致。

也许这样的声明可以编译通过(在gcc下通过了),但是把一个数组名当成一个指针来使用,别指望它能运行起来。

区别二

在大多数编译器中,对数组的引用a[i]总是被编译器改写成 * (a+i) 的格式。

那么a的值是什么呢?

正如你可以骑走一辆自行车,但是不能骑走一棵树。另外,C语言把数组下标改写成指针偏移量的根本原因是指针和偏移量是底层硬件所使用的基本模型。

区别三

对数组的引用,如a[i],或 * (a+1) ,需要访存一次;而对指针的引用,如 * (p+1) ,需要访存两次。

区别四

p = a;

另外,sizeof(a)得到的是a所表示的数组的大小,而sizeof(p)得到的是指针的大小。

温馨提示

免责声明:本文来源网络,免费传达知识,版权归原作者所有。如涉及作品版权问题,请联系我进行删除。


猜你喜欢:




从编译器角度分析数组名和指针的区别

文章都看完了不点个吗