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

Bab*_*ker 12 c c++ arrays

可能重复:
在C数组中为什么这是真的?a [5] == 5 [a]

array [index]和index [array]的可能性是编译器功能还是语言功能.第二个怎么可能?

Mar*_*ler 29

编译器将转向

index[array]
Run Code Online (Sandbox Code Playgroud)

*(index + array)
Run Code Online (Sandbox Code Playgroud)

使用正常的语法,它将转向

array[index]
Run Code Online (Sandbox Code Playgroud)

*(array + index)
Run Code Online (Sandbox Code Playgroud)

因此,您会看到两个表达式都评估为相同的值.这适用于C和C++.

  • 这个"转换"图只适用于其中一个变量是指针或数组而另一个是整数类型,即通常的C情况.在C++中,a [b]失去对称性,因为operator []可以是重载的成员函数,而编译器不允许使用*(a + b).*(a + b)可能具有不同的类型和不同的值,或者它可能根本不是有效的表达式. (15认同)

pax*_*blo 6

从C的早期开始,表达式a[i]只是添加到i的[0]的地址(按[0]的大小按比例放大),然后取消引用.事实上,所有这些都是等价的:

a[i]
i[a]
*(a+i)
Run Code Online (Sandbox Code Playgroud)

====

我唯一关心的是实际的解引用.虽然它们都产生相同的地址,但如果类型ai不同,则可以考虑解除引用.

例如:

    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?
Run Code Online (Sandbox Code Playgroud)

我实际上没有测试过这种行为,但这可能是你需要注意的.如果它确实改变了被引用的内容,那么它也可能导致对象数组出现各种问题.

====

更新:

您可以安全地忽略=====行之间的位.我已经在Cygwin下进行了短暂和长时间的测试,看起来没问题,所以我猜我的担心是没有根据的,至少在基本情况下如此.我仍然不知道更复杂的事情会发生什么,因为这不是我可能想要做的事情.

  • 我不认为这是不同的.我的意思是它可以追溯到最初的日子,而不仅仅是在早期. (2认同)

dcw*_*dcw 5

正如Matthew Wilson在Imperfect C++中讨论的那样,这可以用来强制C++中的类型安全,方法是阻止使用DIMENSION_OF()类似于定义下标运算符的类型实例的类似宏,如:

#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
Run Code Online (Sandbox Code Playgroud)

对于处理指针,还有更多内容,但这需要一些额外的模板智能.检查出的实施STLSOFT_NUM_ELEMENTS()STLSoft库,并在第14章读到这一切不完美的C++.

编辑:一些评论者建议实施不拒绝指针.它确实(以及用户定义的类型),如以下程序所示.您可以通过未注释的第16行和第18行来验证这一点.(我只是在Mac/GCC4上执行此操作,它拒绝这两种形式).

#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\n", STLSOFT_NUM_ELEMENTS(ar));

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

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

    return 0;
}
Run Code Online (Sandbox Code Playgroud)