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

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

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

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

Null

Nullとは、プログラミング言語やデータベースにおけるデータ表現の一種です。コンテキストによって"空"もしくは"長さ0の文字列"、”未知・不明”を意味します。

ポインタ

ポインタはアドレスを用いてメモリに格納された値を"参照する"変数です。

連結リスト

連結リストとは、データ構造のひとつであるリストの中で、要素が前後の要素の情報を持つことで、要素が連結(リンク)しているリストの事を呼びます。

Q&A

解決済

2回答

2831閲覧

C言語 連結リストセル型へのポインタの初期値がNULL?ランダム値?

rathi

総合スコア22

C

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

Null

Nullとは、プログラミング言語やデータベースにおけるデータ表現の一種です。コンテキストによって"空"もしくは"長さ0の文字列"、”未知・不明”を意味します。

ポインタ

ポインタはアドレスを用いてメモリに格納された値を"参照する"変数です。

連結リスト

連結リストとは、データ構造のひとつであるリストの中で、要素が前後の要素の情報を持つことで、要素が連結(リンク)しているリストの事を呼びます。

0グッド

0クリップ

投稿2020/05/19 02:21

編集2020/05/21 02:55

連結リストの操作について学んでいるので、構造体を以下のように定義しました。

C

1// CELL 型の構造体の定義 2typedef struct _cell { 3 int data; // データ部 4 struct _cell *next; // ポインタ部 5} CELL; 6CELL *head; // head:先頭セルへのポインタ

ここでheadにはNULLが入っているようなので先頭セルへデータdを挿入する以下の関数を作成しました。

C

1void insert_cell_top(int d){ 2 CELL *new_cell; 3 new_cell = (CELL *)malloc(sizeof(CELL)); // 新しいセルnew_cell の作成 4 new_cell->data = d; // new_cell のデータ部= d 5 if(head == NULL) { // 連結リストが空の時 6 new_cell->next = NULL; // 末尾をNULLで定義 7 head = new_cell; // new_cellを先頭セルへ 8 }else{ 9 new_cell->next = head; // new_cell のポインタ部= head が指すセルのポインタ部 10 head = new_cell; // new_cellを先頭セルへ 11 } 12}

連結リストの末尾のセルのポインタはNULLとすると都合がよいそうなのですが、新しいセルを作成したときそのセルのポインタ部にはランダム値が入っているようで、わざわざnew_cell->next = NULL;をする必要がありました。

headとセルの->nextは同じポインタなのに、どうしてheadの初期値はNULLで、セルの->nextはランダムになっているのでしょうか?教えていただきたいです。

質問を追加させてください。
グローバル変数は0で初期化されるのは分かりました。ただ、グローバルで定義したheadはNULLを指しているのですよね。それであればで先頭セルへの挿入は場合分けしなくてもnew_cell->next = headとすることで、new_cell->next = NULLにはなるのではないかと考えましたが、実際ダメみたいでした。場合分けして、わざわざnew_cell->next = NULL;とする必要がある理由説明していただきたいです。


以下の先頭セルの挿入する関数を以下のようにしたとき、動かずに質問していたのですが、今はなぜか場合分けせずとも動くようになっていました。この関数以外の他の場所が間違えていて動いていなかったかもしれません。

C

1void insert_cell_top(int d){ 2 CELL *new_cell; 3 new_cell = (CELL *)malloc(sizeof(CELL)); // 新しいセルnew_cell の作成 4 new_cell->data = d; // new_cell のデータ部= d 5 new_cell->next = head; // new_cell のポインタ部= head が指すセルのポインタ部 6 head = new_cell; // new_cellを先頭セルへ 7}

解答してくれた方々、ありがとうございました。

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

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

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

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

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

jimbe

2020/05/19 10:29

> 実際ダメみたいでした どう修正してどうダメだったのでしょうか
guest

回答2

0

C言語では、グローバル変数には0が入り、ローカル変数はデタラメの値が入ります。
また、mallocで確保された領域のナカミも初期化はされません(なにはいってても文句はいえない)

その変数、あるいはそのナカミはどうなってるのか、どこに属してるのかを考えましょう

投稿2020/05/19 02:24

編集2020/05/19 02:25
y_waiwai

総合スコア88042

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

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

0

ベストアンサー

外部の静的領域は0で初期化される、というのがCの仕様だからです。
同様に next がランダムなのは、malloc()で確保された領域は何が入ってるかは不定です。
つまり、そこは初期化されていないからです。これは malloc() の仕様です。

こういった、規約、仕様をちゃんと読みましょう。ちゃんと書いてある本やサイトを探しましょう。

とは言うものの、 calloc() と言うやつが有ったような気がします。
調べてみてください。

投稿2020/05/19 02:27

nob.

総合スコア711

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

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

maisumakun

2020/05/19 03:06

callocはメモリをゼロクリアするだけで、それが「ポインタとして」NULLであることは必ずしも保証されません。 整数の0をポインタの文脈で使えばヌルポインタとなりますが、それがメモリ上でも0である必要は、実はありません(もっとも、そんな処理系は稀だとは思いますが)。
nob.

2020/05/20 01:21

maisumakunさんのご指摘通りです。 「整数の0をポインタの文脈で使えばヌルポインタ」ですが、外部変数やcalloc()での0クリアはポインタの文脈ではないのでNULLが設定されているとは言えないですね。 そこは、しっかり仕様を理解しとくべきところでした。 学校の課題なら、head も メンバnext も NULL で明示的に初期化するほうがいいでしょう。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問