• ベストアンサー
  • 困ってます

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

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

共感・応援の気持ちを伝えよう!

  • 回答数3
  • 閲覧数3437
  • ありがとう数9

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

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

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

共感・感謝の気持ちを伝えよう!

質問者からのお礼

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

関連するQ&A

  • 関数ポインタの利点

    こんにちは。 C言語初心者ですが今勉強中です。 その中でポインタについては理解できたのですが、 関数ポインタの利点、使うべき所などが理解できません。 ポインタの基本は理解しています。 値渡し、アドレス渡しも理解しています。 関数ポインタを使うと何がいい、またはどんなとき使わなければならないのか 教本を読んでいてもさっぱりわかりません。 サンプルプログラムを打っても何のために使ってるのかわからないです。 どなたか教えていただけませんでしょうか? よろしくお願いします。

  • Voidポインタで受け取った変数の型を調べる方法

    あるライブラリの関数を利用しようとしたのですが、その関数の引数にVoidポインタがあり、どういう型のデータを格納したのかわかりません。このポインタのアドレスに格納されたデータの型を調べる関数なり方法なりというのはあるのでしょうか。 Voidポインタというのは型を問わずに受け取れるというのは利点ですが、受け取ったものがあらかじめなんだかわからない場合はどうするのでしょうか。よろしくお願いします。

  • ポインタで詰まりました;

    こんばんわ、私は今仕事の合間をぬって独学でCとPerlを学んでいます。 まだやりはじめてから程無いのですが、ポインタに入ったところでつまづいてしまいました;(使い方がわからなくてパニックに; 以下の4つの問題、ポインタを使ったらどうやればいいのか教えてもらえないでしょうか? 1) 文字列の長さを求める関数を、ポインタを使って作成。 2) 文字列を比較する関数を、ポインタを使って作成。 一致の際(0)不一致の際は(1)を返す 3) 文字列中に含まれる、指定した文字の個数を求める関数を、ポインタを使って作成。 「what is this.」の場合、指定文字が「w」の場合は個数1を返す 4) 文字列中に含まれる単語の個数(スペースで区切られた部分)を求める関数を、ポインタを使って作成。 「ehat is this.」の場合、個数は3を返す。 私が今どのくらいの実力があるかといいますと、ほんと初心者同然です。 なので出来るだけ分かりやすく書いてくれると嬉しいです; よろしくお願いします(ノД`

その他の回答 (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

共感・感謝の気持ちを伝えよう!

質問者からのお礼

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

  • 回答No.1

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

共感・感謝の気持ちを伝えよう!

質問者からのお礼

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

関連するQ&A

  • ポインタ引数をさらにポインタ引数に渡す方法

    ポインタ引数をさらに関数のポインタ引数として設定するには、 どうしたらよいのでしょうか? イメージとしては、 int 関数A(*a *b) { *a = 5; *b =3; 関数B(*a *b) } またポインタ引数の関数内で、 ポインタ指定せずに変数を使えるのでしょうか? int 関数A(*a *b) { a = 5; b =3; 関数B(*a *b) }

  • voidポインタ

    曖昧な質問になってしまいますが、voidポインタを使うことによって どのような利点があるのかが解りません、あらゆるポインタ型から キャスト可能だということは解るのですが、具体的な使用方法がわかりません よろしくお願いします。

  • C言語のポインタについて

    C言語のポインタ(配列もポインタに含まれるのか?)について質問です。 係数を行列形式で表される状態方程式などの2変数以上の方程式を解くプログラムにおいてよくポインタや配列が使われているのですが、なぜポインタや配列を使うのでしょうか?利点など詳しく教えていただけませんでしょうか。。。 どなたか分かる方よろしくお願いします(*_*)

  • ポインタの参照

    ある関数でポインタをパラメータとして渡し、呼ばれた関数の中でさらにポインタ参照されたもののメンバを参照するにはどうしたらいいのでしょうか? サンプル   intRet = AAA(&p); ←関数を呼びます。   int AAA(TBL **p) { ↑   このポインタの中身を参照したい } どなたかわかる方いらっしゃいましたらお願いします。

  • 関数へのポインタ

    超初心者です。 C言語を使ってsin波を生成して音を鳴らそうとしているのですが・・ネットで調べてもよくワカリマセン・・ 超初心者な私でも理解できるようなサイトを教えて下さい. また、関数へのポインタも勉強しているのですが, char *(*func)(void); といったchar 型へのポインタを返す関数へのポインタというのがあったとして,関数へのポインタは理解できたのですがさらにchar 型へのポインタとなると一体これが何を指しているのかさっぱりで・・・・ ご協力お願いします.

  • 関数の引数でポインタのポインタを渡したいのですが・・・

    関数の引数でポインタのポインタを渡したいのですが、 渡す前後でアドレスが壊れてしまっています。 もし、なにか思い当たることがある人がいましたら、 必要事項があれば補足します。 よろしくお願いします。

  • ポインタのポインタの初期化法

     文字列をポインタを使って扱うとき、例えば、初期化は次のように行えますよね。 #include <stdlib.h> char *s; s = (char *)malloc(1000); (これに続いてscanf("%s", s);など)  これと同様にして、二次元の配列を、ポインタのポインタを使って表したいとき、 char **s; と宣言したものを、malloc()関数を使って初期化することはできるのでしょうか。よろしくお願いします。

  • ポインタのポインタが引数にある関数の使い方。

    ポインタのポインタが引数にある関数の使い方。 現在、このポインタのポインタが引数にある関数の動きがわからず困っています。 int test(int ** head) { int * pTail = (int *)*head; pTail = pTail + 1; } もし、この関数を呼び出して使用した場合どのような動きをするのでしょうか? int * comm_msg; これをグローバルポインタ変数として宣言させて、 test((void **)&comm_msg); このように呼び出したとした場合とさせていただきます。

  • メンバー関数ポインタ

    非常に基礎的なことで申し訳ないですが。 クラスのメンバー関数へのポインタ変数へ 代入しようとすると 関数呼び出しには引数リストがありません。 とエラーがでます。 何がわるいでしょうか? 以下のような感じのコードです。 void (classname::*P_func)() = classname::func; 定義しただけと思いますが。。 VCです。 よろしくお願いします。

  • ポインタ&mallocで困っています(C言語)

    あるローカル関数内でポインタを宣言し、mallocで領域確保します。そのポインタをグローバルで宣言したポインタに渡します。そしてローカル関数を抜ける。 その後、他のローカル関数内で、そのグローバルなポインタを呼び出して、ポインタの実態を参照しているのですが、プログラムが進むうちにそのグローバルポインタの実態の一部が書き換わってしまいます。どういう原因が考えられるでしょうか?