ポインタの演算

提供: Appmethod Topics
移動先: 案内検索

ポインタ:インデックス への移動

ポインタの演算は,加算,減算,比較に限定されています。「type へのポインタ」型のポインタが指すオブジェクトに対する算術演算では,type のサイズ,つまり type オブジェクトを格納するために必要なバイト数が自動的に計算されます。

ポインタに対して行われる内部演算は,指定されたメモリモデルとそれをオーバーライドするポインタ修飾子の存在に依存します。

ポインタを用いて演算が行われるときは,そのポインタはオブジェクトの配列を指すものとみなされます。したがって,type を指すポインタが宣言された場合,そのポインタに整数値を加えると,ポインタを(type のオブジェクト数×その整数値)バイト進めることになります。たとえば,type のサイズが 10 バイトだとすると,type を指すポインタに整数 5 を加えると,メモリ上ではポインタを 50 バイト進めることになります。2 つのポインタの差は,その 2 つのポインタ値を隔てる配列の要素数になります。たとえば,ptr1 が配列内の 3 番目の要素を,ptr2 が 10 番目の要素を指している場合,ptr2 - ptr1 は 7 になります。

2 つのポインタの差は,その 2 つが同じ配列を指しているときにのみ意味を持ちます。

整数値が「type へのポインタ」に加算される,あるいは「type へのポインタ」から減算される場合,得られる値の型もやはり「type へのポインタ」型です。

「最後の要素の 1 つ先を指すポインタ」のような要素はもちろんありません。ただし,ポインタがこのような値を持つと仮定することは認められています。P が配列の最後の要素を指している場合,P + 1 は正当ですが,P + 2 は未定義です。P が最後の 1 つ先の要素を指している場合には,P - 1 は正当で,ポインタは最後の要素を指すことになります。ただし,間接演算子 * を「最後の要素の 1 つ先を指すポインタ」に用いると,未定義の動作を引き起こしてしまいます。

わかりやすく言えば,ポインタが有効な範囲内(最初の要素から最後の要素の次まで)にある限りは,P + n によってポインタは(n * sizeof(type))バイト進むと考えることができます。

同じ配列オブジェクトの各要素を指す 2 つのポインタ間で減算を行うと,stddef.h で定義されている ptrdiff_t 型の整数値が得られます。この値は,ptrdiff_t の範囲内であれば,参照される 2 つの要素の添字の差を示します。P1 と P2 の型が type へのポインタ(あるいは限定子の付いた type へのポインタ)であるとすると,P1 - P2 という式において,P1 と P2 は実在する要素あるいは最後の要素の次を指していなければなりません。ポインタ P1 が i 番目の要素を,またポインタ P2 が j 番目の要素を指す場合,P1 - P2 は i - j の値を持ちます。