ポインタの概念をある団地の住人を例にとって考えてみる。 ある5階建の団地の部屋番号が次のようになっていたとしよう。
121 | 122 | 123 | 124 | 125 |
116 | 117 | 118 | 119 | 120 |
111 | 112 | 113 | 114 | 115 |
106 | 107 | 108 | 109 | 110 |
101 | 102 | 103 | 104 | 105 |
これが、「アドレス空間」に該当する。
ここに住人が次のように入っているとする。
藤原 | 青木 | 若槻 | 伊賀 | 小野 |
円 | 宇田川 | 長谷川 | 滋賀 | 前田 |
愛知 | 武田 | 竹田 | 栃木 | 桜井 |
周防 | 石橋 | 香川 | 小島 | 福島 |
宮崎 | 中島 | 山根 | 新潟 | 長崎 |
すると、「普通」住人を特定する場合は、「121号室に住んでいる人」ではなく、「藤原さん」と呼ぶ方が判りやすいと思われる。 この住人の名前が、「変数名」にあたる。(変数の型は「住人」? :-) したがって、会話を行なう場合は、「石橋さんは大学生だ」(== 変数への代入?)とか、 「斎藤さんが怪我をした」(== 変数の参照?)などと使われることになる。 このような使われ方の場合、名前により個人が特定されるため、各住人がどの部屋に住んでいるのかということは、あまり意識されないし、知る必要もない。
&
演算子は何をしていたかというと、例えば「桜井さん」という「変数名」から、部屋番号を求めることに相当する。
つまり、&桜井さん
は115号室を意味するようなものである。
ここに、ポインタ変数として「住人 *i」という変数を導入したとする。 i には、住人型の変数(たとえば、「桜井さん」)のアドレス(== 今の例の場合、部屋番号)を入れることができる。 したがって、
とすると、変数 i
には、115号室という「アドレス」が代入される。
また、* 演算子を使った参照(間接参照) 「*i」は、「115号室の住人」すなわち「桜井さん」という変数の中身(人そのもの)を意味することになる。
もともと、アドレス空間を抽象化するために、変数名をつけたのに、なぜわざわざ変数名からアドレスを求めたりするのかという疑問には、次のような例を考えることが役に立つかも知れない。
「この団地の住人すべての人に対して○○する」という作業、 例えば、写真を撮るという作業を行なうことを考えてみよう。
この作業を「変数名」で考えて、記述すると
take_photo(宮崎さん); take_photo(中島さん); take_photo(山根さん); ... take_photo(斎藤さん);
と繁雑になる。一方、これを部屋番号を使って考えると、
住人 *i; for (i = 101; i < 126; ++i) { take_photo(*i); } }
と記述するだけですべての場合をつくせるので、プログラム的にはすっきりする。
このように、直接変数を参照するのではなく、一旦、別のポインタ変数(i)を通して、指し示しているものという参照を行なう方が便利な場合が存在するために、ポインタという概念が存在するのである。