C++ 配列 [インデックス] とインデックス [配列]

コンパイラが変わります

index[array]

*(index + array)

通常の構文では、次のようになります

array[index]

*(array + index)

したがって、両方の式が同じ値に評価されることがわかります。これは、C と C++ の両方に当てはまります。


C の初期の頃から、式 a[i] 単に a[0] のアドレスを i に追加し (a[0] のサイズだけ拡大)、逆参照しただけです。実際、これらはすべて同等でした:

a[i]
i[a]
*(a+i)
    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?

更新:

上記の ===== の間のビットは、おそらく安全に無視できます。 行。 Cygwin で short と long を使ってテストしたところ、問題ないように見えたので、少なくとも基本的なケースでは、私の懸念は根拠がなかったと思います。もっと複雑なものがどうなるかはまだわかりません.

Matthew Wilson が Imperfect C++ で議論しているように 、これは DIMENSION_OF() の使用を防止することにより、C++ でタイプ セーフを強制するために使用できます。 次のように、添字演算子を定義するタイプのインスタンスを持つマクロのようなマクロ:

#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_NUM_ELEMENTS() の実装を確認してください STLSoft ライブラリで、Imperfect C++ の第 14 章ですべてを読んでください。 .

編集:一部のコメンターは、実装がポインターを拒否しないことを示唆しています。次のプログラムに示すように、(ユーザー定義型と同様に) 実行されます。これは、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;
}