2007年8月18日土曜日

アーグググググググ!アーグブイ!アーグシー! (Was: 配列とポインタ)


念の為に書いておくと、配列とポインタは明確に違うもの。


そのあたりを誤解していると、



void func(int **a);
int a[2][2];
func(a);

がコンパイルエラーになることが理解出来ないんじゃないかな。


もちろん、



void func(int *a);
int a[2];
func(a);

はOKなので、そのへんが混乱のもとなんではないだろうか。


odz buffer - 配列とポインタ

このあたりのことが良く分からない人は、エキスパートCプログラミングを読むといい。特に「4章 なんてこったい!配列とポインタは別物だったのか!」「9章 配列についてもう少し」「10章 ポインタについてもう少し」をね。



エキスパートCプログラミング―知られざるCの深層 (Ascii books)

エキスパートCプログラミング―知られざるCの深層 (Ascii books)



  • 作者: ピーターヴァン・デ・リンデン, Peter van der Linden, 梅原系

  • 出版社/メーカー: アスキー

  • 発売日: 1996/03

  • メディア: 単行本




ちなみに上の問題に対する直接的な答えは10章, p.264にある。



「配列名はポインタ引数に書き換えられる」規則は、再帰的には適用されない。配列の配列は、「ポインタへのポインタ」ではなく、「配列へのポインタ」に書き換えられる。












引数対応するパラメータ
配列の配列char c[8][10];char (*c)[10];配列へのポインタ
ポインタの配列char *c[15];char **c;ポインタへのポインタ
配列へのポインタchar (*c)[64];char (*c)[64];“変化なし”
ポインタへのポインタchar **c;char **c;“変化なし”

char **argvと宣言できるのは、argvが“ポインタ”の配列(char *argv[])だからだ。要素へのポインタへ衰退するため、結果としてポインタへのポインタとなる。もしargvの実体が配列の配列(たとえば char argv[10][15])ならば、それはchar **argvではなく、char (*argv)[15](char配列へのポインタ)に衰退する。



この本を読むのでなければ、前橋さんの「配列とポインタの完全制覇」でもOKよ。


なんにせよ、『なおC言語の配列やポインタなどは,極めてシンプルと言って良いと思う.アレが理解できないのは,単に素質がないだけでは.』とは俺には言えないセリフ。「配列」や「ポインタ」という概念を理解できるかどうかとは別のレベルだとおもた。

0 件のコメント:

コメントを投稿