質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

91.36%

  • C

    2537questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

プログラムでポインタのポインタがはっきりわかりません。

解決済

回答 1

投稿 2017/11/21 20:35

  • 評価
  • クリップ 0
  • VIEW 82

sanchu52

score 58

以下のプログラムでポインタのポインタがはっきりわかりません。
私なりのコメントをいれています。間違いがありましたらご指摘おねがいします。p->next = *ap;    で 
*apは*(**ap)ということですか。if (p->next != 0)以下を
わかり易く説明していただけますか。リストに次々に構造体のポインタを入れて、
p->next == 0になるとp->before = 0;にうつるとおもいますが。
どうしてこうしているのですか。さいごに*ap = p;    は*ap がpを指すようにするということですか。というのはこれでリストに追加されたということですかね。
ここらあたりがよくわかりません。また同じような質問だと怒られそうですが
よろしくお願いします。

コード
void list_add(struct address **ap,char *number, char *name, char *address, char *tel) {
  struct address *p;
  if ((p = malloc(sizeof(struct address))) != 0) {
    strcpy(p->number, number);    
    strcpy(p->name, name);        
    strcpy(p->address, address);
    strcpy(p->tel, tel);        

    p->next = *ap;                // *apはheadである。
    if (p->next != 0)
      p->next->before = p;
      //(p->next)->before = p; pの次のメンバーのbeforeにpのアドレスを入れる。

      //p->next->before などとなっています。これはポインタ型の変数 pが
      //さす構造体の next メンバ(これもポインタ型です)がさす
      //構造体の beforeメンバの値、という意味です。
      //つまり (p->next)->beforeと読むのです。括弧内は、
      //before メンバの値を知りたい構造体をさすポインタ値です。
      //この値をどのように得るかというと、括弧内が p->next ですから、
      //変数 p がさす構造体の next メンバの値、ということになります。
      //next メンバの型は struct schedule* ですから、確かに値はポインタです。
      //変数 p の値はstruct addressの先頭要素をさすポインタですから、
      //結局、p->next->before は、先頭から 2 番目の要素(先頭の次)の 
      //beforeメンバの値、となります。

    p->before = 0;
    *ap = p;                    // *apはheadである。
  }
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

    struct schedule* head;
    struct schedule** ap = &head;
    // apが何の略なのかわからなかったので質問文からリストの先頭とみなした

    // 新しい構造体を割り当てる エラーチェック省略
    p = malloc(sizeof(schedule));

    // 新データの次は旧先頭データ
    p->next = *ap;

    // 旧先頭データが存在した場合
    if (p->next != 0)
      // 旧先頭データと新データを紐つける
      p->next->before = p;

    // 新先頭データよりも前にデータはない
    p->before = 0;

    // 新先頭データを先頭データとする
    *ap = p;
}

p->next = *ap;    で 
*apは*(**ap)ということですか。

データ = *ポインタ = **ポインタのポインタ
ポインタのポインタ = &ポインタ = &(&データ)

apが先頭データへのポインタへのポインタならば
*apは先頭データへのポインタ

リストに次々に構造体のポインタを入れて、
p->next == 0になるとp->before = 0;にうつるとおもいますが。

そんな動作は行っていません

どうしてこうしているのですか。

p->before = 0;にしている理由については、このコードだけでは不明だが
推測するに、
bottom(一番最初に割り当てたデータ)からbeforeを辿っていった時に0で初期化しないとどこが終点か分からない

ポインタをマスターするには頭で考えても悩むだけなので

printf("p:%08X\tnext: %08X\tbefore: %08X\n", p, p->next, p->before);
といった感じにポインタを数値で表示してみるといいかもしれません

後はwindowsマシンをお持ちでしたらVisualStudioでソースレベルデバッグでデータを直接見ると分かりやすいです

投稿 2017/11/21 22:54

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/11/22 21:48

    ありがとうございます。そうですね。たまにデバッグしてprintf()をつかっています。
    頭がさえているときは、わかるのですが、ほかの人にお尋ねるといい説明をしてもらえるので、
    たすかっています。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

ただいまの回答率

91.36%

関連した質問

  • 受付中

    C言語 線形リスト

    初歩的な質問で非情に申し訳ないのですがどなたかお力添えをして頂けないでしょうか。 下記のコードの機能を新規作成、追加、ソートに変更したいのですが一向にうまくいかず、詰まっている状

  • 解決済

    c言語 リスト構造の検索

    アドレス帳の検索機能だけのプログラムを作っています。 作りたいプログラムは、  1,検索したい人の名前を入力する  2,事前に登録された情報の中から部分一致検索する 

  • 解決済

    オーバーフローします...

    前提・実現したいこと アルファベット順に表示したいです どうやったらアルファベット順に表示できますか? もし,このままでいいならオーバーフローを直して欲しいです... アル

  • 解決済

    C言語のエラー修正について

    コード #include <stdio.h> #define New (element) RealNew( & element ) #define InputInt( number

  • 解決済

    C 言語strcpyについて

    線形リストを作ってその構造体の中にpathname配列に格納されている文字列を記憶させるプログラムを作っているのですが警告が出てきてうまく動作してくれません。"stack is s

  • 解決済

    線形リストでの単語の並べ替えがうまくいきません。

    前提・実現したいこと 単語の線形リストを作成し、同じ単語には1つのstruct word構造体を用い、単語の出現回数を数える。そして、出現単語を辞書順に並べ替える。 合っているかは

  • 解決済

    C言語で住所録管理ソフトを作成しているが、CSVファイルのデータを構造体にコピーする方法が分からない

    CSVファイルの中身は1行ごとに「名前,電話番号,住所」が記述されていてそれぞれの情報を構造体にコピーする形です。 線形リストで各個人のデータを管理したいと思っています。 構造

  • 解決済

    ダウンロードしたプログラムでエラーが出て実行できない

    ダウンロードしたプログラムでエラーが出て実行できない。 URLはcodepad.org/B83f1FSq です。セグメンテーション違反が出ています。 ダウンロードしたプログラムに名

同じタグがついた質問を見る

  • C

    2537questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。