プログラマyasuhoの隠れ家

某ソフトウェア企業に勤務するおじさんプログラマyasuhoです

言語は習うより慣れろ

 ポインタはC/C++言語の特徴的な機能のひとつである。ポインタ(pointer)を直訳すると「指し示すもの」であり、別の変数や文字列定数の場所を指し示すために使う。また、ポインタを指すポインタ(ポインタへのポインタ)というものも存在する。

C/C++のポインタの機能--変数の場所(アドレス) - builder


ロジックの誤りはともかく、もう少し実践的な例題をあげた方が分かりやすくなるんじゃないでしょうか。ポインタとは何かじゃなくて、Cになぜそれが必要で、どんな時に使うと便利といった感じの説明があると、概念はおのずと理解できるような気がします。

そういえばポインタってどうやって覚えたんだっけ


yasuhoの場合、Cを学ぶ以前にPL/I系の言語でポインタを使っていたから、Cを見てもそんな違和感はなかったな。変数や型を間接的に指し示すもの、って感じ!?


ただ、Cはよりポインタを複雑に扱えるところがちょっと戸惑った。例えば

  • charのポインタのポインタ
  • short配列へのポインタの配列
  • intを返す関数へのポインタの配列

とか、言葉で書くと「なんじゃそりゃ」なのがいっぱい。

そうだ、こうやって覚えたんだ


Cプログラムをコンパイルして、展開されたアセンブラリストを見たんだ。


例えばこんな感じ(Visual Studio 2005を使用)

  • charのポインタのポインタ
int _tmain(int argc, char *argv[])
		op = argv[0][1];
0041387C  mov         eax,dword ptr [ebp+0Ch] 	; argv
0041387F  mov         ecx,dword ptr [eax] 
00413881  mov         dl,byte ptr [ecx+1] 
00413884  mov         byte ptr [ebp-15h],dl 
  • short配列へのポインタの配列
	short w[4];
	short *paw[4];
	w[0] = 1;
00413929  mov         word ptr [ebp-34h],1 
	paw[0] = &w[0];
00413929  lea         eax,[ebp-34h] 
0041392C  mov         dword ptr [ebp-4Ch],eax 
  • intを返す関数へのポインタの配列
typedef struct _OPS {
	char	type;
	BOOL	(*ops)(char *s, int *pv);
} OPS, *POPS;

OPS aOps[] = {
	{ 'd',	GetInt },
};
		if (!aOps[i].ops(&argv[0][2], &v))
004138D3  mov         esi,esp 
004138D5  lea         eax,[ebp-0Ch] 
004138D8  push        eax  					; &v
004138D9  mov         ecx,dword ptr [ebp+0Ch] 
004138DC  mov         edx,dword ptr [ecx] 
004138DE  add         edx,2 
004138E1  push        edx  					; &argv[0][2]
004138E2  mov         eax,dword ptr [ebp-24h] 
004138E5  mov         ecx,dword ptr aOps+4 (417058h)[eax*8] 
004138EC  call        ecx  					; call (*ops)()

展開されたアセンブラコードを見ると、ポインタがどんなふうに実行されるのか確認できる。デバッガを使って実際に動きを追ってみるのも効果的だったな。


それにしても最近のコンパイラは効率いいコードを吐くなあ。これ、デバッグ版だから最適化してないはずなんだけど・・・

じゃあどうやって覚えるのがいいのかな?


今流行の言語だとこういうやり方は通用しないだろうね。ただ、個人的に言語を覚える方法として有効だと思う方法はとにかくいろいろ使ってみることじゃないかな。


もちろんドキュメントを読んだりして体系的に覚えることも大事だと思う。けど、言語に限らずコンピュータ関連技術はやってみないと分からない、あるいは使ってみた方が理解できることがとても多い。むしろ、使ってみて初めて身につくと言った方がいいかも。


それは単にプログラムの理解というだけにとどまらなくて「これはどうやって実現しているんだろう」という探求心にもつながっていくと思う。ソースコードを見ることで、さらにその先の技術へというように、知識と経験の幅を広げていくものじゃないかなあ。


まーyasuhoの場合、ドキュメント読むのが不得意ということの言い訳かもしれないけどさ。^^;


[4/8/2008 追記]


参照先の記事へのリンクを入れ忘れてました。最初を読むと何のことか分からないですよね。^^;