最近在逛知乎的时候,看到了一种比较特别的数组下标索引的方式,受到一些启发,所以简单的记录一下。
众所周知对于一个整型数组S,访问其内部的元素有几种方式。比如我们想要访问其3个元素可以是以下几种方式:
1. int S[2];
2. int *(S + 2);
这两种是我们很容易想到的表现方式,其本质上都是对地址的访问。我们这里介绍第三种方法,其样式如下:
3. int 2[S];
是不是很奇怪,我刚开始看到的时候也很奇怪,但是只要仔细想想“[“以及”]”的意义就可以明白了。
S[2]的本质是取一个地址,即*(S + 2)也就是我们的第二种表达方式,对于2[S]的表达方式来讲,其本质是*(2 + S)也就是说其实他们取到的是同一个地址!也就不难明白为什么2[S] == S[2]了。
也许这时候有人会说,这种方式没有实际用处!确实,如果它只是另外一种下标表示方法的话,除了一点炫技的用处外没什么大不了的。但是,我要说的是这种用法有一个很大的用处,那就是判断对象S[2]中的S是否是原生数组,还是一个重载了"[]"的对象。其实想想这确实是一个非常简单的方法!我们只需要进行如下判断即可得到我们的结果:
if(S[2] == 2[S])
cout << "S是原生数组!" << endl;
else
cout << "S不是原生数组!" << endl;
这个结果是显而易见的,因为对于重载了"[]"的类来说,比如vector,它的S[2]和2[S]显然是不一样的。对于vector来说S[2] = *(Elems + 2),其中Elems为其存储元素的数据成员的首地址,而2[S] = *(2 + S),这里的S就是对象的首地址,显然他们是不同的地址!
也许有人会说IS_ARRAY方法不是更好吗?关于这一点,我想先不做评论,因为我还不知道IS_ARRAY的具体实现方式,我准备下个星期问问我的数据结构老师,和她讨论过后再来继续更新下文~~