
PythonやJavaScriptでコーディングの旅を始めた場合、「ポインタ」は白髪のシステムエンジニアだけのための難解な黒魔術のように聞こえるかもしれません。大学でC++を学んだとしても、セグメンテーション違反やメモリリークに苦しんだことを覚えているでしょう。
しかし、ここに秘密があります。ポインタは単なる変数です。魔法ではありません。それは数字です。その数字はたまたま他の何かの住所(アドレス)なのです。
ポインタを本当に理解するには、まずデータが実際にどこに住んでいるかについて話す必要があります。
コードが実行されると、データはどこかに行かなければなりません。一般的に、それはスタックかヒープの2つの場所のどちらかに着地します。
スタックは、机の上の付箋の束のようなものだと想像してください。
int a = 10; という変数がある場合、おそらくここに座っています。きれいで、速く、安全です。
ヒープは巨大な倉庫です。
ポインタは単なる道しるべです。
ヒープ上(アドレス 0x1234)に score = 99 という変数がある場合、ポインタは「データは 0x1234 にある」と言うスタック上の小さな変数にすぎません。
int score = 99; // 実際の値
int *p = &score; // ポインタ 'p' は 'score' のアドレスを保持するp は アドレス(どこにあるか?)です。*p は 値(中身は何か?)です。値をそのまま渡して、言語に面倒を見させればいいのでは?
10MBの画像があるとします。それを関数 process(image) に渡し、言語がその画像をコピーする場合、ピクセルのコピーに10MBのRAMとCPU時間を無駄にすることになります。
ポインタを使えば、アドレス(8バイト)を渡すだけです。関数に「画像はあそこにあるから、見てきて」と伝えるだけです。
変数を値渡しで関数に渡すと、関数はクローンを受け取ります。クローンを変更しても、オリジナルはそのままです。 ポインタを渡すと、関数はオリジナルがどこにあるかを知ります。実際のデータを変更できます。
連結リスト、ツリー、グラフ—これらは他のデータの塊へのポインタを保持するデータの塊にすぎません。参照なしでこれらを簡単に構築することはできません。
ポインタはタダではありません。
ポインタは、あなたのコードとハードウェアの間の架け橋です。高レベルのJavaScriptやPythonを書いていても、オブジェクトは裏では単なる参照(ポインタ!)であることを理解すれば、なぜ a = b が b をコピーするのではなく、a を同じデータに向けるだけなのかが理解できるようになります。
ポインタをマスターすると、コードがどのように実行されるかについてのX線透視能力が得られます。「魔法」が見えなくなり、「メモリ」が見えるようになります。
© Melvin Laplanche - All rights reserved.