写在前面
最近逛知乎发现一个有意思的C++表达式:
[arr](){0;return 0;}()[arr]
乍一看觉得不能编译通过, 后来一想这不是C++11新增的Lambda表达式么?
对于这个写法, 相当于先创建了一个lambda匿名函数, 然后直接调用, 并且取值, 但是这里的取值就显得很奇怪了, 因为这意味着对于一个(C风格的)数组, 可以通过下面的方法进行下标取值:
i[arr]
为什么也可以这样取值呢?
下面来看一段测试代码:
#include <iostream>
#include <vector>
using namespace std;
const int SIZE = 5;
int main(int argc, char const *argv[]) {
int arr[SIZE] = {1, 2, 3};
// vector<int> arr{1, 2, 3}; // error
for (int i = 0; i < SIZE; ++i) cout << i[arr] << " " << arr[i] << endl;
cout <<
[arr]() {
0;
return 0;
}()[arr]
<< endl;
return 0;
}
可以发现arr[i]
和i[arr]
两者没有区别.
C数组索引
后来看到一篇回答1:
In declaration, no. When you use pointer variables, yes:
x[y]
is identical to*(x + y)
. Soa[1]
is the same as*(a + 1)
, which is the same as*(1 + a)
, which is again the same as1[a]
(but please don’t use this last one).
也就是说, 因为数组变量名即为首地址(指针), 所以在i
位置取值(arr[i]
)用指针表示法可以表达为*(arr+i)
, 那么因为加法交换律, *(i+arr)
就也是可以的, 那么这样对应一下, 就得到i[arr]
也是可以的.
虽然有点离谱, 但是这确实是可以的 (只不过最好不要在你的代码中这样写).