こんにちは。プログラマーのウヤマエです。寒い日が続きますね。
今回はC/C++のポインタとメモリの関係についての理解が深まったという、僕の昔の経験談を披露したいと思います。
最近はandroidや Unityなどの流行でC/C++以外の言語で開発したり、そもそもコードを書かないという場合もありそうなのですが、やはりまだまだゲーム開発においてはC/C++は避けては通れないのではないでしょうか。
C/C++の学習においてはポインタの理解が一つの壁になると言われています。僕の場合、学生時代には主にJavaを使用してプログラミングの勉強をしていたため、ポインタの認識は「ポインタはnewするやつ。ポインタじゃないのはnewしなくていいやつ」という程度でしたが、それなりに使えている感じではありました。
しかしある時、先輩の書いたコードを読んで衝撃を受けました。
int n;
.....
short s0 = ((short *)&n)[0];
short s1 = ((short *)&n)[1];
今となっては、なんということはないコードです。
ですが、当時の僕には、訳が分からない代物でした。
それまで僕の中のポインタのイメージは「メモリ上にint用の領域を確保して、そのアドレスをポインタで保持する」という感じでした。
しかし、先ほど挙げたコードを解読することで「メモリ上にintのサイズ分だけ領域を確保しておき、そのアドレスをint *を通して参照する場合はintとして扱う」、そして「同じアドレスをshort *を通して参照する場合はshortとして扱うこともできる」ということが理解できたのです。目から鱗でした。
そこから発展的にポインタというのは「データを記録する為にメモリ上に確保した領域のアドレス」というよりは「メモリ上のあるアドレスのデータを何と解釈するのか」の方が本質的なのではないかという考え方にたどり着きました。
その時の僕の気持ちを分かりやすく説明すると
わかったよ、K&R兄ィ!!
ポインタが!「言葉」でなく「心」で理解できた!
という感じでした。まあ当時はK&Rという名前を知りませんでしたけど。
皆様のポインタへの理解の参考になれば幸いです。ではまた。
※例示したコードはエンディアンの関係で可搬性が低いなどの問題があって良い使い方とはいえない面もあります。