正如Joel在Stack Overflow播客#34中指出的,在C编程语言(又名:K&R)中,提到了C:a[5]==5[a]中数组的这个属性
乔尔说这是因为指针运算,但我仍然不明白。为什么a[5]==5[a]?
正如Joel在Stack Overflow播客#34中指出的,在C编程语言(又名:K&R)中,提到了C:a[5]==5[a]中数组的这个属性
乔尔说这是因为指针运算,但我仍然不明白。为什么a[5]==5[a]?
当前回答
在C数组中,arr[3]和3[arr]是相同的,它们的等价指针符号是*(arr+3)到*(3+arr)。但相反,[arr]3或[3]arr不正确,会导致语法错误,因为(arr+3)*和(3+arr)*不是有效表达式。原因是解引用运算符应该放在表达式产生的地址之前,而不是地址之后。
其他回答
对于C中的指针,我们有
a[5] == *(a + 5)
而且
5[a] == *(5 + a)
因此,a[5]==5[a]是正确的。
我知道问题得到了答案,但我忍不住分享了这个解释。
我记得编译器设计原理,假设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位置返回我的对象。
按照字面意思回答问题。x==x并不总是正确的
double zero = 0.0;
double a[] = { 0,0,0,0,0, zero/zero}; // NaN
cout << (a[5] == 5[a] ? "true" : "false") << endl;
印刷品
false
C标准对[]运算符的定义如下:
a[b]==*(a+b)
因此,[5]将评估:
*(a + 5)
并且5[a]将评估:
*(5 + a)
a是指向数组的第一个元素的指针。a[5]是距离a更远的5个元素的值,与*(a+5)相同,从小学数学中我们知道它们是相等的(加法是可交换的)。
因为数组访问是根据指针定义的。a[i]被定义为表示*(a+i),它是可交换的。