看到这里,大概有些初学者已经被上述那些左值右值、对象非对象搞得稀里糊涂了。的确,数组
与指针的复杂性让人望而生畏,不是一朝一夕就能完全掌握的,需要一段较长的时间慢慢消化。因此
笔者才将数组与指针称为一门艺术,是的,它就是艺术!
第二章 数组名是一个指针常量吗?
数组名是一个指针常量这种观点来源于数组名在表达式计算中与指针的结果等效性。例如下面的
代码:
int a[10], *p = a, *q;
q = a + 1;
q = p + 1;
在效果上看,a + 1 与 p + 1 是相同的,这很容易给人一种 a 就是 p 的假象,但,这仅仅是假
象。鉴于指针常量包含了指针和常量两类概念,我们可以把这个问题分开两部分进行讨论。
一、数组名是指针吗?
在《C与指针》一书中,作者用一个著名的例子阐述了数组名与指针的不同。在一个文件中定义:
int a[10];然后在另一个文件中声明:extern int *a; 笔者不在这里重复其中的原理,书中的作
者试图从底层操作上阐述数组名与指针的不同点,但笔者认为这个例子存在一些不足,a 在表达式中
会转换为一个非对象的符号地址,而指针 a 却 是一个对象,用一个非对象去跟一个对象比较,有“偷
跑”的嫌疑,这个例子只是说明了数组名的非对象性质,只能证明对象与非对象实体在底层操作上的
不同,事实上,如上一章所述,指针也有非对象形态。笔者认为,无须从底层的角度上花费那么多唇
舌,仅仅从字面上的语义就可以推翻数组名是一个指针的观点。
首先,在C/C++中,数组类型跟指针类型是两种不同的派生类型,数组名跟指针是两种不同
类型的实体,把数组类型的实体说成“是”另一个类型的实体,本身就是荒谬的;
其次,a + 1 在效果上之所以等同于 p + 1,是因为 a 进行了数组到指针的隐式转换,这是一个
转换的过程,是 converted to 而不是 is a 的过程。如果是两个相同的事物,又怎会有转换的过程
呢?当把 a 放在 a + 1 表达式中时,a 已经从一个数组名转换为一个指针,a 是作为指针而不是数组
名参与运算的;
第三,a + 1 与 p + 1 是等效关系,不是等价关系。等价是相同事物的不同表现形式,而等效是
不同事物的相同效果。把数组名说成是指针实际上把等效关系误解为等价关系。
因此,数组名不是指针,永远也不是,但在一定条件下,数组名可以转换为指针。
二、数组名是一个常量吗?
Generated by Foxit PDF Creator © Foxit Software
http://www.foxitsoftware.com For evaluation only.