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

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

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

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

Q&A

解決済

2回答

618閲覧

線状リストの作成中に代入ができません

GAKU_SAY

総合スコア23

C

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

0グッド

0クリップ

投稿2020/06/25 01:20

編集2020/06/25 02:22

質問内容はタイトルと同じです。なぜ、代入ができないのかを教えてください。リストの追加位置はtopの末尾です。

c

1#include <stdio.h> 2#include <stdlib.h> 3 4typedef struct data_ { 5 char key; 6 struct data_ *next; 7}data; 8 9struct queue{ 10 data *top, *rear; 11}; 12 13void enqueue (struct queue *q, char key); 14 15 16 17int main(){ 18 19 struct queue q; 20 21 enqueue(&q, 'a'); 22 23 printf("%c\n",q.top->key); 24 printf("%c\n",q.rear->key); 25 26 return 0; 27} 28 29void enqueue (struct queue *q, char key){ 30 31 data *new = malloc(sizeof(data)); 32 if (new == NULL) { 33 printf("ERROR\n"); 34 exit(1); 35 } 36 new->key = key; 37 q->rear = new; 38 data* tail = q->top; 39 40 while (tail != NULL) { 41 42 tail=tail->next; 43 } 44 45 tail = new;/**代入ができていない**/ 46} 47

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

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

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

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

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

episteme

2020/06/25 02:25

rearはキューの末尾を指してるんですよね? ならばrearのうしろに繋げばいい。tailって必要ですか?
guest

回答2

0

ベストアンサー

原因は大きく分けて3つ有ります

  1. main関数内struct queue q; この時点ではq.top及びq.rearは未初期化です

enqueue()内部でq->topをコピーしたtailNULLを比較していますが、未初期化のために正しく動作しません(未定義動作です)。NULLを初期値として代入しておく必要が有ります(初期化用の関数(もしくは初期化したものを返す関数)を作ると便利です)

  1. tail = new;/**代入ができていない**/ これだとenqueue()のローカル変数tailを書き換えただけなのでqには何の変更も起きないです
  2. enqueue()内でリストが空の場合に場合分けが必要です
  • q->topNULL(リストが空)の場合にはq->topq->rearnewを指すようにしなければなりません
  • それ以外の場合、q->rear->nextnewを指すように、q->rearnewを指すように要素を追加します
  • q->rearがあるのでwhileループでtopから順に末尾要素をたどる必要はありません
    rearを使わない実装であればwhileでたどる必要が有ります。)

以上をまとめるとこんな感じのコードになると思います(初期化関数は面倒だったので作ってないです)
wandbox


ところで、newという語はC++で動的確保の予約語(mallocの代わりみたいなものです)になっていて誤解を招きやすいので、別の変数名に置き換えることをおすすめします

投稿2020/06/25 02:29

編集2020/06/25 02:31
tyu_ru_cpp

総合スコア40

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

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

tyu_ru_cpp

2020/06/25 02:32

ありゃ、他回答者さんとかぶっちゃった
GAKU_SAY

2020/06/25 02:44

わかりやすい解説とアドバイスをありがとうございます。c++でnewが動的確保に使えることは存じております。
guest

0

struct queueu q の q を初期化していないのに、
enqueue の中で q->rear = new; で rear を参照しています。
enqueue の中のローカル変数 tail に何を代入しようと、
enqueue を終了すると tail は無くなります。

data は typedef して、queue は typedef しないのですか?

C

1#include <stdio.h> 2#include <stdlib.h> // malloc, exit 3 4typedef struct data_ { 5 char key; 6 struct data_ *next; 7} data; 8 9typedef struct queue { 10 data *top, *rear; 11} queue; 12 13void enqueue(queue *q, char key); 14 15int main(void) 16{ 17 queue q = { 0 }; // q.top = q.rear = NULL; 18 19 enqueue(&q, 'a'); 20 enqueue(&q, 'b'); 21 enqueue(&q, 'c'); 22 23 printf("%c\n", q.top->key); 24 printf("%c\n", q.rear->key); 25} 26 27void enqueue(queue *q, char key) 28{ 29 data *new = malloc(sizeof(data)); 30 if (new == NULL) puts("ERROR"), exit(1); 31 new->key = key; 32 new->next = NULL; 33 if (q->top == NULL) q->top = q->rear = new; 34 else q->rear = q->rear->next = new; 35}

投稿2020/06/25 02:14

kazuma-s

総合スコア8224

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

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

GAKU_SAY

2020/06/25 02:25

この回答の場合、c\ncと出力されると思います。ただ、今回はリスト内で文字がtopから見てabcとなっていて欲しいです。
episteme

2020/06/25 02:30

a c と出力されますよ?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問