4分33秒的なるもの「ポスト・ポストモダン」なんて言うヤツのことは信用しなくていい

2016年07月15日

できるだけわかりやすく説明してみるという実験:みんな苦手なポインター

この世界には2種類のプログラマーがいる。
ポインターが分かっているプログラマーと、ポインターが分かっていないプログラマーだ。



前者はそこまで行くのに随分と遠回りをしたものだが、いざ分かってしまうと、なぜあの頃は分からなかったのだろう?と思ってしまう。
後者は結構いい感じでC言語を学んでいたのだが、いざポインターのところまで来たらそこでつまずいてしまって、「C言語なんて年寄りがするものだ」などと捨て台詞を吐いたまま、もう二度とC言語に戻ってくることはなかった。

後者がポインターを理解できずに挫折することの理由は、「ポインターとは何か?」ということが概念的につかめていなかったからである。

ポインターとはひとことで言えば、「実体を指し示すもの」である。「実体」そのものではない。
と、いうことさえ分かってしまえば、後は簡単なものだったのに。。。

あるプログラムで、データ1からデータnまでのn個のデータを扱う、とする。
pointer1-1

この「n個」とは、実際はとてつもなく大きな数字だったりする。100万個とか。
つまり100万個のデータを扱うプログラムだ。多分足立区の住民管理システムだろう。(実際の足立区の人口は何人だろう?と思って調べてみたら、67万人だとか。テキトーに言ってみたが結構いいところいってたな。)
つまり、ひとつのデータがあるひとりを表している。

これらを扱うのに、それぞれをメモリ上の位置(これを"番地"と呼ぶ)を決めておけばいいだろうか?
pointer1-2
データ1は001番地、データ2は002番地、、、というように、そのデータのメモリ上の位置を決めておく。
ヘタに「足立区の住民管理システム」などといらんことを言ってしまったからややこしくなってしまったが、ここでの「番地」とは、そのデータが指す住民の住所ではなく、メモリ上の位置を表すものだ、と考えてほしい。

このとき、あるデータが削除された場合、たとえばデータ2の住民が引っ越して足立区民ではなくなった場合、そのデータ2があった番地、002番地は空になってしまう。
新しく足立区に引っ越してきた人は、その空きになっている002番地に置きたいが、そうするとその新しいデータの番号と番地がそろわなくなる。
つまり、データ番号とデータが置かれているメモリ上の番地をそろえる、というアイデアは破綻する。

そこで、各データにIDをつけることにする。
このIDはユニーク(IDがかぶることはない)なものである。このIDによってデータは特定される。
これは番地とは違って、別にデータがなくなったあとでも再利用する必要もない。
pointer2

こうすることで何がいいのか、といえば、それがどこに置かれているのかを気にすることなく、データをメモリ上のどこに置いてもよい、ということである。

ただし、あるデータを必要とする時に、そのあるデータをどうやってみつけるか?という問題がある。
100万個のデータのうち、「IDが123,456のもの」はたったひとつしかないはずなのだが、それをどうやって見つけるか?
もし最初にあげた、「番地=データ番号」というルールでメモリ上に置いておくのであれば、123,456番地からデータを取ればよい。
しかし今回は、各データにIDをつけた代わりにメモリ上のどこに置いてもよい、ということにしてしまった。。。

いちばん簡単な方法は、メモリ上をかたっぱしから調べていくことである。
かたっぱしからデータを見て、そのIDが123,456かどうかを見ていけばよい。これで確実にみつかるはずだ。
だが、この方法では、最悪の場合、100万個のデータをかたっぱしから見ていくことになる。
これは効率が悪すぎる。

そこで、「インデックステーブル」という概念を登場させる。
「インデックス」とは日本語に訳せば「索引」である。
「テーブル」は日本語に訳すと「机」。ウソ、ごめん、「表」のことである。
つまり、「索引表」ということだ。

このインデックステーブルは、ひとつのデータあたり一行を使ってID順に並べられている。なので目的のIDが書かれた行を探せばよい。この「目的の行を探す」ことはそんなに難しくない。結構簡単に高速な方法で実現することができる。
そして、その目的のデータの行にきたら、そこに目的のデータが置かれている、、、のではなくて、そのデータが置かれているメモリ上の番地が書かれている。
 
pointer3
これにより、それぞれのデータはメモリ上のどこに置かれていてもよい、ということになる。
このインデックステーブル上の各行に書かれた、「実際のデータが書かれている番地」をポインタと言う。
つまり、インデックステーブルの各行に、実際のデータが置かれているのではなくて、「そのデータのありか」が記されている。
これにより、もしデータのメモリ上での置き場所に変更があった場合でも、このインデックステーブルの番地(=ポインタ)を書き換えてやるだけでよい。
pointer4-2
「ポインタ」とはすなわち、データの実体そのものではなく、「データが置かれている場」を表す何らかの情報(番地)のことである。

この「ポインタ」という概念はプログラミングだけのものではなく、日常でも使われている。
たとえば本を読んでいて、そこに他の人が他の本で書いた文を引用する場合。
まず、その分を丸々引用して書くという方法がある。
もうひとつの方法として、「◯◯の△△ページ参照」と書いて、実際の文はそこには書かない、という方法もある。

一般に実データが置かれている場所を指す「ポインタ」は、実データよりも充分小さな容量しか必要としないので、扱いも随分楽なものである。

ただし、ポインタのところでC言語に挫折した者にとっては「ポインタ」という言葉は地雷になりうるので、十分注意したほうがよい。 

OLランキングで1位になりたい!賛同していただける方は下記をクリック!
にほんブログ村 OL日記ブログ ドジOLへ

コメントする

名前
 
  絵文字
 
 
4分33秒的なるもの「ポスト・ポストモダン」なんて言うヤツのことは信用しなくていい