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

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

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

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

Q&A

解決済

3回答

942閲覧

リストのプログラムでwhile文の中を具体的に説明してくださいませんか

退会済みユーザー

退会済みユーザー

総合スコア0

C

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

0グッド

0クリップ

投稿2017/11/18 11:02

リストのプログラムでwhile(1)文のp->next = head;からあとを説明していただけませんか。p->next = head;はNODE *head = NULL;だからp->next==NULLですよね。
pにはデータを入れるためのメモリ領域の先頭アドレスが入っていて、それのp->nextが
NULLということですよね。head = p;はどうしてこうしているのですか。headにデータを入れていくということかなと思いますが。いやpにデータを入れていますよね。
ここらあたりがこんがらがって、よく理解できません。while(1)文を出た後の、
p = head;はどうしているんでしょうか。実行結果が後から順に表示されていますが、
それと関係ありそうですが、よろしくお願いします。

// リスト構造 #include <stdio.h> #include <stdlib.h> typedef struct node { struct node *next; int data; }NODE; int main(int argc, char *argv[]) { int x; NODE *head = NULL; // 変数headは、NODE型の構造体を指すポインタ変数です。 // リストの始まり位置を記憶させます。初期状態は // ノードがない状態なので、headの内容はNULL //(リストの最後の印)にしておきます。 NODE *p; // 変数pもNODE型構造体を指すポインタ変数です。 typedef struct node { struct node *next; int data; } NODE; while(1){ // while(1)は、継続条件がいつも1(真)なので、59~72行目の // ブロック内を永久に繰り替えします。 printf("data = "); scanf("%d", &x); if(x == -1) break; // 終了条件は、「x == -1」です。-1が入力されると、 // break文が実行され、whileのループから抜け出ます。 p = malloc(sizeof(NODE)); // NODE型構造体に必要な大きさの記憶場所を確保し、そのアドレスを // ポインタ変数pに入れます。 // malloc()関数の戻り値をチェックしなければならないのですが、 // ここでは、省略します。 p->next = head; // 確保したNODE方の記憶場所の中のメンバnextに // 現在のheadに記憶されているアドレスを入れます。 head = p; // headにpに記憶されたアドレスを入れます。 p->data = x; // 整数データをpが指している記憶場所の中のメンバdataに格納します。 } printf("\nアドレスは%p\n\n", p); p = head; while(p) { printf("%d\n", p->data); p = p->next; } } /* C:\MinGW\users\chap09\kadai>gcc -I. -o LST2 LST2.c -Wall C:\MinGW\users\chap09\kadai>LST2 data = 5 data = 9 data = 3 data = 4 data = 7 data = 2 data = -1 アドレスは00681358 2 7 4 3 9 5 C:\MinGW\users\chap09\kadai>

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

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

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

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

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

guest

回答3

0

ベストアンサー

このプログラムは少し変わった振る舞いをします。

次のようなリストを想像してください。

ループn-1: ○ <-- ○

ループn : ○ <-- ○ <-- ○

ループn+1: ○ <-- ○ <-- ○ <-- ○

という風に右に伸びていくけど、左にリンクが貼られるようなリストです。どんどん右に追加されていきます。

ここで新しいデータを付け足すとしましょう。今、4つの○があるとします。headは常に一番右端の○を指します。そこに新しいデータがやってくると、まず、p = malloc(sizeof(NODE));で新しく△を作ります。
この△から一番右端の○すなわちheadにリンクを貼るのがp->next = head;です。

今こういう状態です。

○ <-- ○ <-- ○ <-- ○ <-- △

これで新しいノードが追加されたわけですが、headは常に一番右端を指しておく必要があるので、headを△つまりpの位置に動かします。それが、head = p;です。最後に、pにデータを保存するのを忘れずにp->data = xですね。

投稿2017/11/18 11:53

編集2017/11/18 11:55
Takahito_Ogawa

総合スコア229

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

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

退会済みユーザー

退会済みユーザー

2017/11/18 12:00

ありがとうございました。よく読み直して理解したいと思います。図解してほしいと思っていました。これからもよろしくおねがいします。
guest

0

片方向リストですね

pについては、コードに出てきた時使ってるノードへのポインタです.
個人的にはitとかcurrentとか名付けた方が分かりやすい気がします.

headもpも周回に応じて変化していきます.

Cっぽい疑似コードでデータがどうなるかを表すと

上のwhile1回目:

head = p = &{ next = NULL; data = 5; }; // なお、&{}で構造体へのアドレスを表してるつもりです

上のwhile2回目:

head = p = &{ next = &{ next = NULL; data = 5; }; data = 9; };

上のwhileが終わると今度は下のwhileでpの位置が1つづつ右にずれます

head = &{ next = p = &{ next = NULL; data = 5; }; data = 9; };

といった感じに

なお、上のwhileが終わった後のp = headは入力時に1回目から-1を入力した場合head == Pとは限らないからです
ちなみに、その場合アドレス表示してるとこで未初期化の変数表示しちゃってるのでバグですね

投稿2017/11/18 12:04

asm

総合スコア15147

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

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

退会済みユーザー

退会済みユーザー

2017/11/18 12:20

ありがとうございます。リストの練習をしています。
guest

0

head = p;

headはNODEへのポインターです。pもそうですね。よってこの文は「今mallocで領域を確保したばかりのNODEのアドレスをheadへ覚えておく」という意味です。

投稿2017/11/18 11:45

KSwordOfHaste

総合スコア18392

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

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

退会済みユーザー

退会済みユーザー

2017/11/18 12:01

いつもありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問