C ++数组[索引]与索引[数组]

C++ array[index] vs index[array]

本问题已经有最佳答案,请猛点这里访问。

Possible Duplicate:
In C arrays why is this true? a[5] == 5[a]

数组[索引]和索引[数组]都有可能是编译器功能或语言功能。第二个怎么可能?


编译器将

1
index[array]

进入之内

1
*(index + array)

按照正常的语法,它会变为

1
array[index]

进入之内

1
*(array + index)

因此,您可以看到两个表达式的计算值相同。这对于C和C++都适用。


从C的早期开始,表达式a[i]只是在i中加上(按a〔0〕的大小放大)a〔0〕的地址,然后取消引用。事实上,所有这些都是等效的:

1
2
3
a[i]
i[a]
*(a+i)

====

The only thing I'd be concerned about is the actual de-referencing. Whilst they all produce the same address, de-referencing may be a concern if the types of a and i are different.

For example:

1
2
3
4
    int i = 4;
    long a[9];
    long x = a[i]; //get the long at memory location X.
    long x = i[a]; //get the int at memory location X?

I haven't actually tested that behavior but it's something you may want to watch out for. If it does change what gets de-referenced, it's likely to cause all sorts of problems with arrays of objects as well.

====

更新:

您可能可以安全地忽略=====行之间的位。我在Cygwin的测试中用了一个短的和一个长的,看起来还可以,所以我猜我的恐惧是没有根据的,至少在基本情况下是这样的。我仍然不知道更复杂的情况会发生什么,因为这不是我想做的事情。


正如Matthew Wilson在不完美C++中讨论的那样,这可以用来在C++中强制类型安全,通过防止使用EDOCX1×2类类似宏来定义下标操作符的类型的实例,如:

1
2
3
4
5
6
7
8
9
10
11
12
13
#define DIMENSION_OF_UNSAFE(x)  (sizeof(x) / sizeof((x)[0]))

#define DIMENSION_OF_SAFER(x)  (sizeof(x) / sizeof(0[(x)]))

int ints[4];

DIMENSION_OF_UNSAFE(ints); // 4
DIMENSION_OF_SAFER(ints); // 4

std::vector v(4);

DIMENSION_OF_UNSAFE(v); // gives impl-defined value; v likely wrong
DIMENSION_OF_SAFER(v); // does not compile

对于处理指针,还有更多的内容,但是这需要一些额外的模板智能。在STLSOFT库中检查EDOCX1 3的实现,并在不完美C++的第14章中了解这一切。

编辑:一些注释者建议实现不拒绝指针。它可以(以及用户定义的类型),如下面的程序所示。您可以通过未注释的第16行和第18行来验证这一点。(我刚刚在Mac/GCC4上做了这个,它拒绝了这两个表单)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stlsoft/stlsoft.h>
#include <vector>
#include <stdio.h>

int main()
{
    int     ar[1];
    int*    p = ar;
    std::vector<int>        v(1);

    printf("ar: %lu
"
, STLSOFT_NUM_ELEMENTS(ar));

//  printf("p: %lu
", STLSOFT_NUM_ELEMENTS(p));

//  printf("
v: %lu
", STLSOFT_NUM_ELEMENTS(v));

    return 0;
}


在C和C++中(数组是指针或数组),它是一种语言特征:指针算术。其中a或b是指针的操作a[b]转换为指针算术:*(a+b)。当加法是对称的,重新排序不会改变意义。

现在,非指针存在差异。实际上,如果给定的类型A带有重载的运算符[],则[4]是有效的方法调用(将调用::运算符),但相反的方法甚至不会编译。