添字演算子: []
構文
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 ] が最初に評価されます。 expression1 と expression2 を加算した結果として得られるアドレスからポインター式が形成され、次にこのポインター式に 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
低いアドレスをポイントするので、実行時エラーが生成されることがあります。 ポインター midArray
は intArray
の中央に初期化されます。したがって正と負、両方の配列インデックスを使用することができます (ただし危険があります)。 配列添字のエラーは、コンパイル時のエラーを生成しませんが、予測できない結果になります。
添字演算子は可換です。 したがって、添字演算子がオーバーロードされない限り、式 array[index] と index[array] は等価であることが保証されます (「オーバーロードされた演算子」を参照)。 最初の形式は、共通のコーディングの推奨事項ですが、どちらの方法でも動作します。