• ベストアンサー

参照の参照、struct record **start, の使い方は?

Linked List を作ってるのですが、 addRecord のプロトタイプが以下のようになってます。 int addRecord(struct record **start, char name[], char address[], int age); こうなると start->age = age; start.age = age; *start->age = age; ともコンパイルエラーになるのですが、対処法ありますでしょうか? ちなみに、これはポインタのアドレスを示すものですよね? これを参照の参照と呼ぶのかは確かではありませんが。。。

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

  • ベストアンサー
  • Werner
  • ベストアンサー率53% (395/735)
回答No.1

明示的にかかれていませんが、struct recordにageというメンバがあるのですね? それならageにアクセスするには、 (*start)->age とする必要があります。 (**start).age でも同じ。 *start->ageではアロー演算子の優先順位が高いために *(start->age)と解釈されてしまいます。 参照の参照でも間違いではないと思いますが、 C言語ならポインタのポインタで良いと思います。

yasu182
質問者

お礼

できました! いろいろ調べたんですが 今見ても 自分の本には載ってなく、ほんとに助かりました。 もう一つリンクリストについてお伺いしたいのですが、 この code の修正の仕方をご存知でしょうか? while((*start)->next != NULL) *start = (*start)->next; list = (struct record *) malloc(sizeof(struct record)); if (list == NULL) { printf("malloc error\n"); exit(1); } strcpy(list->name, name); strcpy(list->address, address); list->age = age; (*start)->next = list; 3つの record を追加すると最後の2つだけが残ってしまいます。 *start = (*start)->next; 恐らくこれのおかげで start が変わるためだとは思うんですが、 うまく修正できません。 まだポインタのポインタの使い方に慣れてないので。。。

その他の回答 (5)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.6

「リストの末尾にデータを追加する」場合でも, ポインタのポインタを使って「リストの末尾」を覚えておくと無駄な時間を使わなくていいので便利~.

yasu182
質問者

お礼

そういう使い方もあるんですね。 ありがとうございます!

回答No.5

  >あえて「ポインタのポインタ」を使うメリットはなんでしょうか?  提示されたソースのように、リストの末尾にDATAを追加する方法では、 メリットはありません。 しかし、リストの先頭に追加する方法だと"ポインタのポインタ"を使えば、 関数内でのリストの変更が、呼び出しもとの関数に直接反映されます。 この場合でも、変更後のリストの先頭のポインタを関数の戻り値にしてやれば、 "ポインタのポインタ"を使う必要はありません。  

yasu182
質問者

お礼

勉強になりました。 ありがとうございます!

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.4

基本的には次のようにすればいいんだけど.... while (*start) { start = &(*start)->next; } *start = malloc(sizeof(struct record)); /* (*start)->age など設定 */ (*start)->next = NULL; なお, 「新たなデータはリストの最後に追加する」ということであれば, 毎回「リストの最後」を探すのは (O(n^2) 時間かかるので) 無駄です. そのためには「リストの最後」を示す変数を作っておくのが得策. もちろん, そのような変数を作るのであれば, 「リスト」という構造体を作ることも検討した方がよいかと.

yasu182
質問者

お礼

Big-O notation ですね。 ありがとうございます。

  • a-saitoh
  • ベストアンサー率30% (524/1722)
回答No.3

長さ0のリストに最初の1コをaddするとき(*start==NULL の場合)の処理も必要では?

yasu182
質問者

お礼

忘れてました (^^; ありがとうございます。

回答No.2

  >この code の修正の仕方をご存知でしょうか? struct record *work; work = *start; 以下、"*start"を"work"に変更。  

yasu182
質問者

補足

できました! ありがとうございます。 ちなみに、自分は Java から入ったのですが ポインタのポインタにまだなじめず、軽く解説 していただけないでしょうか? http://www9.plala.or.jp/sgwr-t/c/sec15-5.html 例えばこのサイトでは「ポインタのポインタ」でなく 「ポインタ」でリンクリストを作ってるわけですが、 あえて「ポインタのポインタ」を使うメリットはなんでしょうか? それと、**start が示すものは 「start に対するポインタ」の アドレスですよね? 呼ぶ時はこうだったので。 struct record *start = NULL; addRecord(&start, name, address, age); * を使うことでそのアドレスの value を取得した時があったので、 あるいは start の value を取得してるのかな、と思ったのですが。

関連するQ&A