概要
自分はrubyからプログラミングに入った。哲学通りenjoy programmingにふさわしいほど快適なプログラミングを出来る。しかし、快適すぎて分かってないのだ。コンピュータのメモリと言われても多いほどいいんでしょ?くらいしかわからない。メモリの構造を理解しないといつまでたっても補助輪付きプログラマーだ。
そこで、料理人というメタファーを用いてメモリの概念を理解してもらいたい。
集合と意味
意味とは集合である。
例えば、「-」これ単体は人間にとって何の意味も成さない。
しかし、「-」が5つの集合を作ることで、「正」という意味を持つ。
しかし、「正」だけでも意味と呼ぶに値しない。
「解」という新たな集合と集合を成すことで、「正解」という言葉という称号、意味を与えられる。
コンピュータの言語を用いても同様に、1bitでは何の意味も成さない。
8bit揃って初めて0~9の何らかの意味を成す。
つまりデータとは、意味であり、集合である。
bitとデータ型
データとは集合である。数々のbitが集まって出来たものである。
bitとは1 or 0の値のことである。つまりデータとは、無限の2進数の数列なのだ。
しかし、"a"と"1"は同じ8bitだが、明らかに人間にとって種類が違う。
そうでないと認識できないのだ。数と文字を同じように考えられる人間などいないだろう。
そこで必要な概念はデータ型。
一方は文字列と名付け、一方は数と名付ける。
1 = 00000001 , a = 1100001だが、なんらかの方法でコンピュータにこれらが人間的に違う種類のモノだと理解させる仕組みが必要である。それが次で説明するメモリというシステムだ。
メモリとまな板
メモリとは集合を保存するための場所であり、1bitの集合から数億bitの集合を保存する事ができる。
コンピュータの目的とは、データを処理して結果を出力することだ。
料理人は食材をまな板の上に具材を載せ、レシピに沿って調理する。
コンピュータも同じだ。メモリとはコンピュータにとってのまな板のようなもの。
料理人がまな板の魚を捌くように、コンピュータはメモリ上のデータを調理する。
しかし、このまな板はとてつもなく広い。さっきも言ったが1bitの集合から数億bitの集合を調理するからだ。これでは料理人も大変だ。魚がどこで野菜がどこにあるのかわかったもんじゃない。
メモリは実は無数のマス目になっている。
そこで左上のマス目は野菜、右下のマス目は肉といったように種類ごとに場所で管理することが必要だ。
これがデータ型の概念。コンピュータにとって野菜も、肉も突き詰めれば原子で出来ている。
しかし、人間にとって野菜と肉は明らかに違う! それをコンピュータにも知らしめる必要があるのだ。
コンピュータは物理には強い。肉と野菜を物理的に同じものだと定義してしまうほどにだ。
そこで、コンピュータにデータを渡すときはデータ型を物理的に定義してとbit列と共に渡す。
野菜は上から1億まで、左から3000万までとする。
「野菜、1000100101110101010〜〜〜。肉、000101001111111101010〜〜〜。 ...」
コンピュータにも人間の種類という概念を入れ込むことが出来た。
これでスムーズに調理することが出来るだろう。
メモリと変数
メモリとはまな板であり、データ型とbit列が必要であるが、まだ料理人は自分の無力さに気づいていない。
そう、料理人にとってまな板はとてつもなく細かい。人間がミドリムシ1億匹で積み木出来ないのと同じだ。
例えば、トマト一つとっただけでお前原子は何個あると思ってるんだ。
炭素12gで6.03×10の23乗個もあるんだぞ。ということで、変数というアイディアを思いついた。つまり。集合に名前を付けること。トマトは、膨大なbit列の集合だが、それらの集合はなんども調理する予定だから、
tomatoと名前を付けてしまおう。
こうすれば、「tomato、すり潰されろ。」と命令するだけでホールトマトが出来てしまうのだ。
ただ、もう一つだけ料理人が気づいていない罠が潜んでいた。
アドレスと値の罠
「tomato、すり潰されろ。」と唱えた呪文で確かにホールトマトができた。
しかし、もう一度「tomato」と呼び出すとホールトマトではなくトマトが出てくるのだ。
なんと可笑しな世界。お前らは無敵かと。
頭の回転は異常に速いが、1と0しかわからん馬鹿者コンピュータにデータ型、変数というアイディアを駆使し、ついに魔法使いのように料理をつくれるかと思いきやの不覚。
「これでは、料理人じゃなくてドラえもんじゃないか。。。」
しかしこの世界にはまだドラえもんなどいない。よって、これはコンピューターの世界固有の事象なのだ。
これを解明するために必要なのが、アドレスという概念。
実は、「tomato、すり潰されろ。」という呪文において、Aという位置にあるトマトを渡しているかとおもいきや、Bという場所に"コピー"されたトマトという集合を潰していたのだ。だから、「tomato」と呼び出すとトマトが出てくる。
データ型は人間の都合のいいようにデータの領域を決めてしまうことかとおもいきや、コンピュータはデータを場所と値で既に管理していたのだ。そして、人間にとって全く同じトマトを複製するのは物理的に不可能だが、コンピュータにとってbit列を複製するのは造作もなくやってのけるのだ。
実は、データとはアドレスと値(とデータ型)のセットで固有なのだ。
「すり潰されろ。」で犠牲になっていたのは、全く同じ顔しているが全然違う場所に住んでいるdummyだったのだ。もちろんAのtomatoには呪文の効果は届いていない。
ポインタの説明。
ここで、あることに気づいた。さっきからトマトという値に注目していたが、コンピュータは値を複製可能なのだ。
データを判別するには、アドレスと値のセットで考えるべき。つまり、Aの位置にいるのは間違いなくtomato。
それに気づいた料理人。
「Aの位置にいるもの。すり潰されろ。」 ホールトマトができた。
そして、、
「tomato」 ホールトマトが出てきた!
つまり、データとは、アドレスと値(とデータ型)のセットである。
アドレスだけが固有なのだ。
通常関数に渡す引数は、値だけで、それはいわばクローンだ。
本体とは直接関係ない。
しかし、変数に値ではなく、アドレスを格納して渡すと、本体に直接攻撃できる。
要は、「あれとって。」という赤ん坊みたいな言葉こそ正確というパラドックス。
このアドレスを示す変数の事をポインタと呼ぶ。
まとめ
意味とは集合である。
データもbit列の集合であり、データ型という概念で種類を判別する必要がある。
メモリとはまな板であり、データ型とbit列を用いて食材を定義する必要がある。
変数とは、集合に名前をつけること。つまりbit列の集合を定義すること。
データとはアドレスと値(とデータ型)のセット。値と変数だけでは固有ではない。
変数にアドレスを指定することも出来る。それをポインタと呼ぶ。
※C言語を理解しているわけではないので、厳密性に欠けている可能性があります。