下标运算符[]的定义是E1 [E2]与(*((E1)+(E2)))相同。由于适用于二进制+运算符的转换规则,如果E1是一个数组对象(相当于一个指向数组对象初始元素的指针),而E2是一个整数,则E1 [E2]表示E1的第E2个元素E1(从零开始计数)。
—价2015年
更正确地说:访问数组时,数组会衰减为指针。
—12431234123412341234123 '18年
Nitpick:说“*(a + i)是可交换的”是没有意义的。但是,*(a + i) = *(i + a) = i[a]因为加法是可交换的。
—安德烈亚斯·雷布兰德
我认为其他答案缺少一些东西。
是的,p[i]根据定义*(p+i),它等于,(由于加法是可交换的)等于*(i+p),它(同样,由[]运算符的定义)等于i[p]。
(在array[i],数组名隐式转换为指向数组第一个元素的指针。)
但是在这种情况下,加法的可交换性不是很明显。
当两个操作数是同一类型,或者甚至是提升为通用类型的不同数值类型时,可交换性就很有意义:x + y == y + x。
但是在这种情况下,我们专门讨论的是指针算法,其中一个操作数是一个指针,另一个是整数。(整数+整数是一个不同的运算,而指针+指针是无意义的。)
C标准的+操作员说明(N1570 6.5.6)说:
另外,两个操作数都应具有算术类型,或者一个操作数应是指向完整对象类型的指针,另一个操作数应具有整数类型。
可以很容易地说:
另外,两个操作数都应具有算术类型,或者左 操作数应是指向完整对象类型的指针,而右操作数 应具有整数类型。
在这种情况下,两个i + p和i[p]是非法的。
用C ++术语来说,我们实际上有两组重载+运算符,可以将它们粗略地描述为:
pointeroperator+(pointer p, integer i);
和
pointeroperator+(integer i, pointer p);
其中只有第一个是真正必要的。
那么为什么会这样呢?
C ++从C继承了这个定义,而C则从B得到了它(1972年用户参考B明确提到了数组索引的可交换性),而BCPL则得到了它。(1967年手册)得到的,甚至可能从早期语言