正如Joel在Stack Overflow播客#34中指出的,在C编程语言(又名:K&R)中,提到了C:a[5]==5[a]中数组的这个属性

乔尔说这是因为指针运算,但我仍然不明白。为什么a[5]==5[a]?


当前回答

In C

 int a[]={10,20,30,40,50};
 int *p=a;
 printf("%d\n",*p++);//output will be 10
 printf("%d\n",*a++);//will give an error

指针p是“变量”,数组名称a是“助记符”或“同义词”,因此p++有效,而a++无效。

a[2]等于2[a],因为这两者的内部运算都是“指针算术”,内部计算为*(a+2)等于*(2+a)

其他回答

嗯,这是一个只有语言支持才能实现的功能。

编译器将a[i]解释为*(a+i),表达式5[a]的计算结果为*(5+a)。由于加法是可交换的,结果证明两者相等。因此,表达式的计算结果为true。

很好的问题/答案。

我只想指出,C指针和数组并不相同,尽管在这种情况下,差异并不是本质的。

考虑以下声明:

int a[10];
int* p = a;

在a.out中,符号a位于数组开始的地址,符号p位于存储指针的地址,指针在该内存位置的值是数组的开始。

在C数组中,arr[3]和3[arr]是相同的,它们的等价指针符号是*(arr+3)到*(3+arr)。但相反,[arr]3或[3]arr不正确,会导致语法错误,因为(arr+3)*和(3+arr)*不是有效表达式。原因是解引用运算符应该放在表达式产生的地址之前,而不是地址之后。

在c编译器中

a[i]
i[a]
*(a+i)

引用数组中元素的方式不同!(一点都不奇怪)

我知道问题得到了答案,但我忍不住分享了这个解释。

我记得编译器设计原理,假设a是一个int数组,int的大小为2字节,&a的基址为1000。

[5]将如何工作->

Base Address of your Array a + (5*size of(data type for array a))
i.e. 1000 + (5*2) = 1010

So,

类似地,当c码被分解为3地址码时,5[a]将变为->

Base Address of your Array a + (size of(data type for array a)*5)
i.e. 1000 + (2*5) = 1010 

所以基本上这两个语句都指向内存中的相同位置,因此a[5]=5[a]。

这一解释也是数组中负索引在C中工作的原因。

即,如果我访问[-5],它会给我

Base Address of your Array a + (-5 * size of(data type for array a))
i.e. 1000 + (-5*2) = 990

它将在990位置返回我的对象。