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

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

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

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

Q&A

解決済

4回答

2761閲覧

構造体のリストについて

ikuo-biyori

総合スコア56

C

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

2グッド

1クリップ

投稿2017/01/05 01:01

いつもお世話になっています。C言語初心者でただいま勉強中です。構造体について質問させていただきます。

C言語

1typedef struct{ 2 int ID; 3 char name[11]; 4 int score[3]; 5} Record; 6/* struct declaration */ 7 8//struct node { 9 10//int key; 11 12//struct node *next; 13 14//}; 15 16typedef struct node *NodePointer; 17struct node { 18 Record data;/*構造体の入れ子*/ 19 NodePointer next;/*ポインタのメンバ*/ 20}; 21NodePointer head;

ここのNodePointer nextとNodePointer headがどんなメンバを持っているのかがよく分かりません。
自分の考えでは、
Record dataは、data.Id,data.name,data.scoreのメンバにアクセスできる。
NodePointer nextは、node型のポインタのメンバ
NodePointer headは、(*head).data.Id,(*head).data.name,(*head).data.score,(*head).nextのメンバにアクセスできる。
この考えであっていますか?
また、NodePointer nextとNodePointer headの違いも教えて下さい。よろしくお願いします。

luna12, Take-y👍を押しています

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

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

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

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

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

guest

回答4

0

こんにちは。

この考えであっていますか?

概ね合っているのですが、nextは微妙に違っている感じがします。

まず、nextはheadと同じ型ですので、headと同様、(*next).data.Id,(*next).data.name,(*next).data.score,(*next).nextにアクセスできます。

この中の(*next).nextが解りにくいのだと思います。nextもheadもnode型へのポインタと考えると良いです。
リストは複数のデータを管理するデータ構造の一種ですが、提示されたソースのリストは、Record型のデータをnode構造体で管理しています。
一般的なリストでは、下記のようなイメージとなります。

イメージ説明

投稿2017/01/05 01:37

Chironian

総合スコア23272

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

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

ikuo-biyori

2017/01/10 19:39

丁寧な解説ありがとうございます。よく分かりました。
guest

0

この構造体定義だと単方向リストでRecord構造体の値を保持しようとしているようですね。
まず、NodePointer headですが、これは単方向リストの先頭要素を指し、head->nextが
次の要素を指します。
手元にCのコンパイル環境がなく、十数年ぶりに書くので自信ないですが、
以下のようなコードで全ての要素のnameを表示できると思います。
(p = head;の部分とか、怪しいです)

NodePointer *p;

p = head;
while ( 1 ) {
printf( "%s", p->data.name );
if ( p->next == NULL )
break;
p = p->next;
}

Recordメンバーへのアクセスは認識されている通りで合っていますが、上記のように
実際にId,name,scoreにデータを格納/参照するコードを書くとより理解できると
思います。

投稿2017/01/05 01:44

Take-y

総合スコア91

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

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

....

2017/01/07 16:58

残念ながらpとheadは型が違いますね。 ``` for (NodePointer p = head; p != NULL; p = p->next) printf( "%s\n", p->data.name ); ``` 個人的にはtypedefに*を含めるのは好きではありません。 あと、リストを理解するまでは下手にtypedefとかしない方が分かりやすいかと。
....

2017/01/07 16:59

おっと、コメントはmarkdownではないんですね。知らなかった。
guest

0

ベストアンサー

このnode構造体は、メンバーにnode構造体へのポインタを含む再帰構造体です。
自己参照構造体ともいうようです。
struct node {
Record data;//レコード構造体
NodePointer next;//node構造体へのポインタ
};
と注釈を入れると分かりやすいかも知れません。
メンバーnextはポインターですから、格納されるのはアドレスです。
名前からして、リスト構造の次のノード(node構造体)のアドレスでしょう。
ここまではnode構造体のタグ宣言で、実体は未定義です。
次の行で
NodePointer head;
と1つの構造体を宣言しています。
名前は head ですから、リストの先頭ということでしょうか。
そして、リスト構造のノードに対応した構造体を宣言していき、メンバーnextでつないでいくわけです。

投稿2017/01/10 15:35

編集2017/01/10 15:43
HidekoSaeki

総合スコア42

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

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

ikuo-biyori

2017/01/10 19:28

headとnextの違いがよく分かりました。お答えいただきありがとうございます。
guest

0

私もtypedefでポインタ型をポインタでない名前にするのは違和感があります。また、アスタリスクの位置も誤解の元だと思います。もちろん、文法上に問題があるわけではありませんが。

typedef struct node NodePointer;

typedef struct node
NodePointer;

投稿2017/01/07 17:55

HogeAnimalLover

総合スコア4830

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問