【C++入門】ポインタと足し算、引き算

前回で、普通の変数、&付き変数、ポインタの三つの変数の違いについて理解した。

かるくおさらいすると、C++では変数の実体は、値とその値が格納されているメモリ上のアドレスの二つの情報で構成されている。

通常の変数は、値の方を指示する名前。
ポインタは、アドレスのほうを指示する名前。
&付き変数は、変数のシノニム(同一の実体を指している変数の別名)である、と。

変数とポインタは相互に変換ができる。
変数→ポインタへは、変数の右に & をつける。
ポインタ→変数へは、ポインタの右に * をつける。

さて、タイトルにあるアドレス(ポインタが指しているもの)に値を足したり引いたりするとどうなるのかと。

結論から言うと、コンパイラは下記のように振舞う。

アドレス同士の場合、アドレスからアドレスを引くことはできるが、それ以外の演算(足し算も)はできない(やったらビルドエラー)

アドレスに整数の加減は行えるが、それ以外の演算はできない(やったらビルドエラー)

このコンパイラの振る舞いを見ると、C++のポインタがもたらす歪んだ言語使用が垣間見れるよね。

アドレスからアドレスを引いた場合、二つのポインタの距離が、そのポインタの型が何個分という形(整数)で返ってくる。これはA地点からB地点までの距離を求めるようなもので、その場合に使うのは引き算だけだ。

A地点までの距離とB地点までの距離を足した値は、意味のある数値にはならない。だから、引き算以外はビルドエラーとなるのだ。たぶん。

ポインタに対する、整数の足し算引き算は、ちょうどこれと逆の操作をするようなものだ。

アドレスに整数を足す(または引く)と、そのアドレスから、そのポインタの型が何個分うしろ(またはまえ)のアドレスが返ってくる。

ということは、ポインタが指すことができるアドレスは、常にそのポインタの型の先頭バイトということになる。

実は似たような振る舞いをする変数がもうひとつあって、それが配列である。

配列の添え字は整数だが、各要素が指しているアドレスは、その配列の型の先頭バイトになっている。

そして、元JAVAプログラマには衝撃の事実がある。

下のコードを見てほしい。このコードはそのままビルドが通る。

void TestMethod(int* pData) {
cout << pData[2] << endl;//いきなり添え字が登場!! } ポインタは、キャストとか何にもしなくても、添え字[]を使って知らないアドレスの値をのぞき見ることができたりする(びっくり) [amazonjs asin="4839926050" locale="JP" title="ロベールのC++入門講座"]

5年前

コメントを残す

メールアドレスが公開されることはありません。