Wポインタという言葉は聞いたことはありませんが、それがポインタのポインタというなら、それを説明しましょう。
ポインタのポインタは、ポインタの配列の先頭アドレス絵を格納したものです。
その配列の要素それぞれは、ポインタなわけですから、それらもある配列の先頭アドレスをさしています。
要素へのアクセスは、2次元配列と同じように、c[5][7]などとして行います。
しかし、問題なのは変数を宣言しただけではそれぞれが有効なアドレスをさしていないということです。
ここに、どこかで宣言したローカルな配列のアドレスを入れたのでは意味がありません。
通常は、malloc関数やnew演算子が返した、動的なメモリのアドレスを格納します。
さて、使い道です。
2次元配列と似てますから、リストにもなります。
しかし、わざわざ2次元配列を使わないのは、別の目的があるからです。
このリストの列の数、行の数は、実行時に変化しなければなりません。
たとえば、まず、リストの行の数は実行時に8と決定され、さらに、1行目は12列、2行目は4列、3行目はなし、4行目は・・・。
このようなことは、2次元配列の大きさをあらかじめ十分にとっておけばできることです。
1行目は12列全部、2行目は4列しか使わないから5列目から12列目は無視・・・。
しかし、これではデータが多くなったときに、無駄なスペースが増えてしまいます。
そうならないようにするためには、動的なメモリの確保が必要なのです。
もう1つ例。
文字列は、それだけでcharの配列ですから、文字列をたくさん使おうと思ったら、それだけで2次元配列になってしまいます。
char x[7][12];
と宣言すれば、(NULLがあるから)11文字以下の文字列が7個出来上がります。
ただし、これでは各文字列が、必ず12バイト消費する上に、12文字以上を格納することができません。
これを、
char **x;
x = (char**)malloc(7);
x[0] = (char*)malloc(12);
strcpy(x[0], "0123456789a");
x[1] = (char*)malloc(6);
strcpy(x[1], "01234");
x[2] = (char*)malloc(25);
strcpy(x[2], "0123456789abcdefghijklmn");
とやれば、必要な文字列の数も変化させることができ、各文字列の長さも自由自在です。
ちょっと考えれば、文字列の2次元配列(つまり、charの3次元配列)も簡単に扱えるようになります。
注意点としては、動的に確保したメモリは、必ず開放してやらないといけないということです。
・・・さて、リスト関数ってのは私はわからないので悪しからず。
長々と書いてしまいました。
ポインタにはうるさい、はぽるんでした。
お礼
ありがとうございました! なるほど、そのような使い方があったのですね・・・。 とてもわかりやすかったです。 また今後もよかったら教えて下さい!! 本当にありがとう!!