ポインタの概念をある団地の住人を例にとって考えてみる。 ある5階建の団地の部屋番号が次のようになっていたとしよう。
21 | 22 | 23 | 24 | 25 |
16 | 17 | 18 | 19 | 20 |
11 | 12 | 13 | 14 | 15 |
6 | 7 | 8 | 9 | 10 |
1 | 2 | 3 | 4 | 5 |
これが、「アドレス空間」に該当する。
ここに住人が次のように入っているとする。
藤原 | 青木 | 若槻 | 伊賀 | 小野 |
円 | 宇田川 | 長谷川 | 滋賀 | 前田 |
愛知 | 武田 | 竹田 | 栃木 | 桜井 |
周防 | 石橋 | 香川 | 小島 | 福島 |
宮崎 | 中島 | 山根 | 新潟 | 長崎 |
すると、「普通」住人を特定する場合は、「21号室に住んでいる人」ではなく、「藤原さん」と呼ぶ方が判りやすいと思われる。 この住人の名前が、「変数名」にあたる。(変数の型は「住人」? :-) したがって、会話を行なう場合は、「石橋さんは大学生だ」(== 変数への代入?)とか、 「斎藤さんが怪我をした」(== 変数の参照?)などと使われることになる。 このような使われ方の場合、名前により個人が特定されるため、各住人がどの部屋に住んでいるのかということは、あまり意識されないし、知る必要もない。
&
演算子は何をしていたかというと、例えば「桜井さん」という「変数名」から、部屋番号を求めることに相当する。
つまり、&桜井さん
は15号室を意味するようなものである。
ここに、ポインタ変数として「住人 *i」という変数を導入したとする。 i には、住人型の変数(たとえば、「桜井さん」)のアドレス(== 今の例の場合、部屋番号)を入れることができる。 したがって、
とすると、変数 i
には、15号室という「アドレス」が代入される。
また、* 演算子を使った参照(間接参照) 「*i」は、「15号室の住人」すなわち「桜井さん」という変数の中身(人そのもの)を意味することになる。
家族の数に比例して、占有できる面積が変わるような団地(?)を考えてみると次のようになる。 (ややこしいので平屋にしてみた。) 単身世帯だと箱1個分、二人家族だと箱2個分、四人家族だと箱4個分を占有することができる。
配列は、同じ人数の家族をまとめたものに相当する。 たとえば新婚さん5組と、夫婦二人と子供二人の家族5組は次のようにあらわすことができる。
もともと、アドレス空間を抽象化するために、変数名をつけたのに、なぜわざわざ変数名からアドレスを求めたりするのかという疑問には、次のような例を考えることが役に立つかも知れない。
「この団地の住人すべての人に対して○○する」という作業、 例えば、写真を撮るという作業を行なうことを考えてみよう。
この作業を「変数名」で考えて、記述すると
take_photo(宮崎さん); take_photo(中島さん); take_photo(山根さん); ... take_photo(斎藤さん);
と繁雑になる。一方、これを部屋番号を使って考えると、
住人 *i; for (i = 1; i < 26; ++i) { take_photo(*i); } }
と記述するだけですべての場合をつくせるので、プログラム的にはすっきりする。
このように、直接変数を参照するのではなく、一旦、別のポインタ変数(i)を通して、指し示しているものという参照を行なう方が便利な場合が存在するために、ポインタという概念が存在するのである。