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

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

新規登録して質問してみよう
ただいま回答率
85.50%
C

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

Q&A

解決済

1回答

347閲覧

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

退会済みユーザー

退会済みユーザー

総合スコア0

C

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

0グッド

0クリップ

投稿2017/11/21 11:35

以下のプログラムでポインタのポインタがはっきりわかりません。
私なりのコメントをいれています。間違いがありましたらご指摘おねがいします。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である。 } }

気になる質問をクリップする

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

c

1 struct schedule* head; 2 struct schedule** ap = &head; 3 // apが何の略なのかわからなかったので質問文からリストの先頭とみなした 4 5 // 新しい構造体を割り当てる エラーチェック省略 6 p = malloc(sizeof(schedule)); 7 8 // 新データの次は旧先頭データ 9 p->next = *ap; 10 11 // 旧先頭データが存在した場合 12 if (p->next != 0) 13 // 旧先頭データと新データを紐つける 14 p->next->before = p; 15 16 // 新先頭データよりも前にデータはない 17 p->before = 0; 18 19 // 新先頭データを先頭データとする 20 *ap = p; 21}

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 13:54

asm

総合スコア15147

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/11/22 12:48

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問