参照 メモリ わかりやすく
プログラムが動いているあいだ、私たちが作った値はどこかに必ず入っていなければなりません。その場所がメモリです。番号のついたロッカーがずらりと並んだ壁を思い浮かべてください。名札は、そのうちのどのマスかを指すメモです。
値はどこかに入っている
プログラムが動いているあいだずっと、すべての値はメモリのどこかに場所を取っています。
メモリは、番号のついたロッカーがずらりと並んだ壁のようなものです。
値を一つ作ると空いたマスに一つすっと入り、プログラムはその値を「何番のマス」として覚えます。
「値を入れる」を押すと、空いたマスに値が一つ入り、マスの番号が表示されます。
値ごとに自分のマスと番号ができました。
でもコードでは「7番のマス」とは書かず、'a'や「点数」のような名前を使います。
では、その名前とマスの番号はどうつながっているのでしょうか。
名札は場所を指す
名前は値そのものではなく、どのマスかを知っているメモです。
名前 'a' → 3番のマス → その中の7。
だから'a'を使うと、プログラムはメモをたどって3番のマスを開け、7を読みます。これが「指す」ということです。
「aをたどる」を押すと、メモをたどってマスへ行き、中の値を取り出します。
名前がマスを指し、そのマスの中に値があります。
この指し示すメモを、参照と呼びます。
ここからが本当に大事です。「aをbにも渡す」と、何が起きるでしょうか。
小さな値はコピーされる
数のような小さな値をbに渡すと、その値が新しいマスにそっくり複製されます。
これでaは3番のマス、bは5番のマスと、別々のマスです。
だからaを9に変えても、bは7のままです。二つはそれぞれ自分の値を持つ、独立した関係なのです。
「bにコピー」のあと「aを変える」を押すと、bは別のマスなので変わりません。
コピーされた小さな値は互いに影響しないので、すっきりしています。
けれどもオブジェクトのような大きなものは、事情が違います。大きなものをまるごと複製するのは重いからです。
そこでふつうは、コピーのかわりに別のことが起こります。
大きなものは同じ場所をいっしょに指す
オブジェクトをbに渡すときは、オブジェクト全体を複製せず、ふつうはbにも同じマスを指させます。
これで、aとbという二枚のメモが、一つのマスをいっしょに指しています。
だからaでそのオブジェクトを直すと、bから見ても同じように変わっています。一つの物に名前が二つあるからです。
二つの名前が一つのマスを指しているので、片方を直すと両方が変わります。
プログラムを学びはじめたとき、いちばんよく驚くところです。「さわってもいないbが、なぜ変わったの?」
もう答えはわかります。同じマスを指していたからです。
何を指しているかがわかれば、もう迷わない
迷いの正体は、いつも一つです。
名前が自分のコピーを持っているのか、それとも一つの物をいっしょに指しているのか。
小さな値ならコピーなので別々に動き、大きなものなら同じ場所を指していっしょに動きます。
この区別さえ思い出せば、驚くことはなくなります。
「小さな値」と「大きなもの」を選んで同じことをさせると、結果が分かれます。
ここまでが、プログラミングの土台です。
値一つから始めて、まとめ、繰り返し、名前をつけ、オブジェクトに集め、デバッグで直し、機械に動かさせました。
そしていま、そのすべてがどこに入っていて、名前が何を指しているのかまで見たので、しっかりした土台ができたのです。