2007-2-25 23:51
shubulo
《再再论指针》 第四章 [ ]运算符的本质
第四章 [ ]运算符的本质 `3hu8D0iz JF.t
数组是存在于人们头脑中的一个逻辑概念,而编译器其实并不知道有数组这个东西,它所知道的,只是[]运算符,当遇到[]运算符的时候,编译器只是简单地把它转换为类似*(*(a+i)+j)这样的等价表达式,之所以是这种表达式,如前几章所述,是因为C语言的数组实现本质上是数组的嵌套。 0@'||\l6n9@
K^d.k7u!iP
由于这种等价关系的存在,会产生一些古零精怪的表达式,例如:
v)_4mN~N(xd!N?c
wfc0g3}F
10[a]
'j%ddb;ZsP'Q
0rn g QV(Q|d/D(E
这个表达式初看上去让人摸不着头脑,它是什么呢?如上所述,编译器会把它转换为*(10+a),把a和10调换一下,就是*(a+10)了,这个就是a[10]。@G9XDU6GLebh
)?5n_:AOT1^n%A
[]运算符之前还可以是一个表达式,例如:(10+20)[a]。
-`
VWa}B
Y
FE6m;w&[
JQ
严格来讲,以上两个表达式是非法的,因为C89对于数组的引用(注意不是数组定义)规定:带下标的数组引用后缀表达式由一个后缀表达式后跟一个括在方括号中的表达式组成。方括号前的后缀表达式的类型必须为“指向T类型的指针”,其中T为某种类型;方括号中表达式的类型必须为整型。这个规定说明,进行数组引用的时候,[]运算符的左边并非必须为数组名,而可以是一个表达式,但这个表达式的类型必须为“指向某类型的指针”。显然10跟(10+20)连地址都不是,因此实际上他们是非法的,编译器在这里并没有严格遵守标准的规定。但如果是:;N)~U:c]_[1O5m
YDD!V;_9B
int a[10], *p = a;
Yx};H5_
L ou*v;`1PT
(p+1)[2]这样就是合法的,因为p+1的结果仍然是一个指针。