添字演算子: []

構文

postfix-expression [ expression ]

解説

添字演算子 [ ] が続く後置式 (基本式である場合もあります) は、配列インデックスを指定します。

C++/CLI のマネージド配列の詳細については、「配列」を参照してください。

通常、postfix-expression によって表される値はポインター値 (配列識別子など) であり、expression は整数値です (列挙型を含む)。 ただし、構文上必要なのは、一方の式がポインター型で、もう一方が整数型であることです。 したがって、postfix-expression の位置に整数値があり、expression の角かっこ内や添字の位置にポインター値がある可能性もあります。 次の コードがあるとします。

int nArray[5] = { 0, 1, 2, 3, 4 };
cout << nArray[2] << endl;            // prints "2"
cout << 2[nArray] << endl;            // prints "2"

上の例では、式 nArray[2]2[nArray] と同じです。 その理由は、添字式 e1[e2] の結果が以下の式で与えられるからです。

*((e2) + (e1))

式から得られるアドレスは、アドレス e1 から e2 バイトのアドレスではありません。 代わりに、アドレスは、配列 e2 内に次のオブジェクトを生成するようにスケーリングされて数えられます。 次に例を示します。

double aDbl[2];

aDb[0] のアドレスと aDb[1] のアドレスは、8 バイト (double 型のオブジェクトのサイズ) 離れています。 オブジェクト型に基づくこのスケーリングは、C++ 言語によって自動的に行われ、「加法演算子」(ポインター型のオペランドの加算と減算について説明しているトピック) で定義されています。

添字式には、次のように複数の添字がある場合があります。

expression1[expression2] [expression3] ...

添字式は、左から右へ関連付けられます。 左端の添字式、expression1[expression2] が最初に評価されます。 expression1expression2 を加算した結果として得られるアドレスからポインター式が形成され、次にこのポインター式に expression3 が加算されて新しいポインター式が形成されます。このようにして、最後の添字式が加算されるまで処理が行われます。 間接演算子 (*) は、最終的なポインター値が配列型のアドレスを指していない限り、最後の添字式が評価された後で適用されます。

複数の添字を持つ式は、多次元配列の要素を参照します。 多次元配列は、要素が配列である配列です。 たとえば、3 次元配列の最初の要素は 2 次元配列です。 次の例では、文字の単純な 2 次元配列を宣言して初期化しています。

// expre_Subscript_Operator.cpp
// compile with: /EHsc
#include <iostream>

using namespace std;
#define MAX_ROWS 2
#define MAX_COLS 2

int main() {
  char c[ MAX_ROWS ][ MAX_COLS ] = { { 'a', 'b' }, { 'c', 'd' } };
  for ( int i = 0; i < MAX_ROWS; i++ )
     for ( int j = 0; j < MAX_COLS; j++ )
        cout << c[ i ][ j ] << endl;
}

正と負の添字

配列の最初要素は要素 0 です。 C++ 配列の範囲は、array[0] から array[size - 1] です。 ただし、C++ は、正の数の添字と負の数の添字をサポートします。 負の添字は配列の範囲内になる必要があり、そうでない場合、結果は予測不能となります。 次のコードは正および負の配列添字を示します。

#include <iostream>
using namespace std;

int main() {
    int intArray[1024];
    for (int i = 0, j = 0; i < 1024; i++)
    {
        intArray[i] = j++;
    }

    cout << intArray[512] << endl;   // 512

    cout << 257[intArray] << endl;   // 257

    int *midArray = &intArray[512];  // pointer to the middle of the array

    cout << midArray[-256] << endl;  // 256

    cout << intArray[-256] << endl;  // unpredictable, may crash
}

最後の行の負の添字は、配列の起点よりもメモリ内の位置が 256 int 低いアドレスをポイントするので、実行時エラーが生成されることがあります。 ポインター midArrayintArray の中央に初期化されます。したがって正と負、両方の配列インデックスを使用することができます (ただし危険があります)。 配列添字のエラーは、コンパイル時のエラーを生成しませんが、予測できない結果になります。

添字演算子は可換です。 したがって、添字演算子がオーバーロードされない限り、式 array[index] と index[array] は等価であることが保証されます (「オーバーロードされた演算子」を参照)。 最初の形式は、共通のコーディングの推奨事項ですが、どちらの方法でも動作します。

関連項目

後置式
C++ の演算子、優先順位と結合規則
配列
1 次元配列
多次元配列