• ベストアンサー

Wポインタを教えて下さい!

Wポインタってどういう時に使うものなのですか? ポインタを使ったリスト関数とどこが違うのですか? Wポインタを使う利点は・・・? 頭がこんがらがってしまいます。 もう半年くらい考えてるんですけどよくわからないのです。 どなたか教えて頂けるとありがたいのですが・・・。

質問者が選んだベストアンサー

  • ベストアンサー
  • haporun
  • ベストアンサー率40% (230/562)
回答No.3

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次元配列)も簡単に扱えるようになります。 注意点としては、動的に確保したメモリは、必ず開放してやらないといけないということです。 ・・・さて、リスト関数ってのは私はわからないので悪しからず。 長々と書いてしまいました。 ポインタにはうるさい、はぽるんでした。

meal
質問者

お礼

ありがとうございました! なるほど、そのような使い方があったのですね・・・。 とてもわかりやすかったです。 また今後もよかったら教えて下さい!! 本当にありがとう!!

その他の回答 (2)

回答No.2

ダブルポインタ(ポインタのポインタ)をよく使う場合は、例えば2次元の配列を関数に渡したいときによく使います。 int arry[3][3]; こんな2次元配列が有るとします。 これをすべて1で初期化する関数は以下のようになります。 void func(a) int **a; { int i,j; for(i=0;i<3;i++) for(j=0;j<3;i++) a[i][j]=1; } これが一番良く使うやり方の例と思います。 関数内での左から一つ目のポインタは、配列の1次元目の先頭アドレスにあたります、2つ目も同様に配列の2次元目の先頭アドレスに対応します。 ふつう1次元配列を関数に渡す場合、ポインタ変数を受け側引数として宣言し、配列の先頭アドレスの値となる配列名を入力引数として渡します。 しかし2次元配列の場合、一つのポインタだけでは配列の1次元目のアドレス値しか受け取ってくれません。そこでこのように2次元目の配列にあたるアドレスを受け取れる様、ポインタをもう1つ付け加えてやっている訳です。 他にも色々有るかと思いますが思い浮かびませんこのくらいにしときます。 ちなみにダブルポインタがわかれば3つや4つも簡単ですが、果たしてそれが万人に受け入れられるかどうかは別の話です。 リスト構造の方が人間的に分かり易いですし、保守も簡単です。今の時代のマシン環境ならリストのオーバーヘッドもあまり気にならないでしょう。 たとえそのプログラムがとてもよく出来ていたとしても、mealさんが悩んだように、後になってそのソースを見る人も半年悩むとしたら時間の無駄になってしまいますしね。 なんだか半分セッキョウになってしまいましたがこんなところです。 参考URLは僕がこのごろ参考にしてるとこで、ダブルポインタを使ったプログラムとセッキョウが載ってたので付けときました。 それでは

参考URL:
http://www.ncad.co.jp/~komata/c-frame.htm
meal
質問者

お礼

ありがとうございます。 Wポインタは、ポインタの配列の、先頭アドレスを指すと考えていいのでしょうか? 参考URLもありがとうございました!! よかったらこれからも教えて下さい!

回答No.1

まず、ポインタを使ったリスト関数というのは何を指しているので しょう?リスト構造のことでしょうか?それを扱う関数のことでしょ うか?それとも全然別物? それから、Wポインタといわれても、何のことかよくわかりません。 双方向リスト構造のことでしょうか? double 型へのポインタってことではなさそうですが… 用語が正確でないと、何を答えていいかもわからなくて答えづらい です。

meal
質問者

お礼

お返事ありがとうございます。 wポインタですが、ポインタのポインタと呼ばれているものです。 リスト構造はポインタを使っていますが、 ポインタのポインタを使ってリスト構造を実現できるそうなのですが、 普通のポインタを使ったリスト構造とどこが違うのでしょうか? わざわざポインタのポインタを使う利点は? というようなことがわからないのですが・・・。 どうぞよろしくお願いします。

関連するQ&A