正如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]?
当前回答
按照字面意思回答问题。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
其他回答
因为避免混淆嵌套非常有用。
你愿意读这个吗
array[array[head].next].prev
或者:
head[array].next[array].prev
顺便说一下,C++对于函数调用具有类似的交换性质。您可以使用成员函数来编写x.f().g(),而不是像在C中那样编写g(f(x))。用查找表替换f和g,您可以编写g[f[x]](函数样式)或(x[f])[g](oop样式)。后者非常适合包含索引的结构:x[xs].y[ys].z[zs]。使用更常见的符号zs[ys[xs[x].y].z]。
C标准对[]运算符的定义如下:
a[b]==*(a+b)
因此,[5]将评估:
*(a + 5)
并且5[a]将评估:
*(5 + a)
a是指向数组的第一个元素的指针。a[5]是距离a更远的5个元素的值,与*(a+5)相同,从小学数学中我们知道它们是相等的(加法是可交换的)。
按照字面意思回答问题。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[5] == *(a + 5)
而且
5[a] == *(5 + a)
因此,a[5]==5[a]是正确的。
它在C语言中的指针和阵列教程中有很好的解释由Ted Jensen撰写。
Ted Jensen解释为:
事实上,这是真的,也就是说,无论你在哪里写一个替换为*(a+i)而没有任何问题。事实上,编译器将在任何情况下创建相同的代码。因此,我们看到了指针算术与数组索引相同。任一语法都会产生同样的结果。这并不是说指针和数组是一样的东西,它们不是。我们这么说只是为了确定对于数组的给定元素,我们可以选择两种语法,一种使用数组索引,另一种使用指针算法产生相同的结果。现在,看看最后一个表达式的一部分..(a+i)是使用+运算符和C的规则声明这样的表达式是交换的。即(a+i)与(i+a)相同。因此,我们可以写*(i+a)和*(a+i)一样容易。但*(i+a)可能来自i[a]!所有这些都带来了好奇如果:字符a[20];写a[3]=“x”;与写作相同3[a]=“x”;