C 言語 三種の神技: void*/(cast)/#define ― 2006年05月19日 07時13分03秒
- void *
- ボイドポインタ
- (type)
- タイプキャスト
- #define
- マクロ
C 言語が扱う型は大きく分けると値とメモリ番地だけなのである。値は更に分かれ、int や double などとなるのである。そして、メモリ番地はそれらの値が存在するメモリの位置となる。struct は値の集合体であり、すなわち値である。
さて、お気づきであろうか。void * は全てのメモリ番地を指すことができ、(cast) は如何なる値も cast 型として読むことを指定する。すなわち、この二つが C 言語の根底を示しているのである。
void * は汎用的なライブラリを構築するときに、頻繁に用いられる。汎用的であるがゆえ、型不定で動くように作られているからだ。malloc() や memset() などがよい例だ。read() や write() なども仲間である。その戻り値を適切に (cast) しなおしてやり、作業を続行する。実は void * だと、どのようなポインタにも代入できるので、明示的なキャストは必要ないが、型変換であることには変わりはない。
マクロは、コンパイル前に全て展開されてしまうので、C 言語としてファイルが読み込まれるときには、跡片もない。しかし、その展開の時にすさまじい能力を発揮する。マクロ関数は C 言語の関数とは違い、型という概念がない。何でも引数として渡せるのである。また、シンボルを繋げたり、文字列に変換したりもできる。
この三つの使い方を見ると、ソースコードの質が一目瞭然で分かる。これらを使いこなせないが為に、同じような関数をいくつも作ったり、似たようなコードを何十行も書いたりするのである。何度も似たような事を書き続けるから打ち間違え、余計なバグを生成し、変更するときに広大な範囲をいじらなくてはいけなくなる。
これらはとてつもない力を持つ半面、使い方を誤ると大変辛い目に合う。諸刃の剣だ。これらの本質と使い方を理解することで、器を磨き、鋭い技を繰り出すことができるようになる。
最近のコメント