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

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

ただいまの
回答率

90.83%

  • C

    3351questions

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

C言語 リスト 新しいノードをリストの最後に追加

受付中

回答 3

投稿

  • 評価
  • クリップ 0
  • VIEW 293

ib2

score 1

C言語 リストについて
↓のプログラムでは入力した数字を逆順に表示

/* list.c */
#include <stdio.h>
#include <stdlib.h>
struct node { 
  int num;
  struct node *next;
};

main()
{
  struct node *head, *p;
  int x;
  head = NULL;

  while(scanf("%d",&x) != EOF) {
    p = (struct node *)malloc(sizeof(struct node));
    p->num = x;

    p->next = head;
    head = p;
  }
  // リストの要素のnumの値を先頭から順に表示する 
  p=head; 
  while(p!=NULL) {
    printf("%d\n" ,p->num);
    p = p->next;

}
}


↑のプログラムを↓のプログラムを使い修正して新しいノードをリストの最後に追加するようにしたいのですがどう書いたら良いのでしょうか?

struct node *q;
q = head;
while(q->next != NULL) q = q->next;
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • 退会済みユーザー

    2017/12/19 23:35

    複数のユーザーから「やってほしいことだけを記載した丸投げの質問」という意見がありました
    「質問を編集する」ボタンから編集を行い、調査したこと・試したことを記入していただくと、回答が得られやすくなります。

回答 3

+2

ビギナはどうしてもやりたいことをすべてmainに詰め込まないと気が済まないみたいだ。
はじめはそれで構わないが、複雑になるになるにつれ見通しが悪くなる。
できるだけ関数に細分化するクセをつけるが吉。
※ 最初っからこんなの↓書けとは言わないし求めてもいない

/* list.c */
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <assert.h>

struct node { 
  int          num;
  struct node* next;
};

/* nodeを確保し、numとnextを初期化して返す */
struct node* node_create(int n) {
  struct node* new_node = (struct node*)malloc(sizeof(struct node));
  assert( new_node != NULL );
  new_node->num = n;
  new_node->next = NULL;
  return new_node;
}

/* headを先頭に、pred(p,arg)がtrueである最初のpを返す
   head == NULL または見つからなければ NULL を返す */
const struct node* node_find(const struct node* head,
                             bool (*pred)(const struct node*,void*),
                             void* arg) {
  const struct node* curr_node = head;
  while ( curr_node != NULL ) {
    const struct node* next_node = curr_node->next;
    if ( pred(curr_node, arg) ) break;
    curr_node = next_node;
  }
  return curr_node;
}

/* pnodeが末尾nodeであればtrueを返す */
static bool node_is_last(const struct node* pnode, void* un_used) {
  return pnode->next == NULL;
}

/* headで示されたリストの先頭にtargetを挿入する 
   挿入後のリストの先頭を返す */
struct node* node_prepend(struct node* head, struct node* target) {
  if ( head != NULL ) {
    target->next = head;
  }
  return target;
}

/* headで示されたリストの末尾にtargetを挿入する 
   挿入後のリストの先頭を返す */
struct node* node_append(struct node* head, struct node* target) {
  struct node* last_node = (struct node*)node_find(head, node_is_last, NULL);
  if ( last_node == NULL ) {
    head = target;
  } else { 
    last_node->next = target;
  }
  return head;
}

static bool node_print(const struct node* pnode, void* arg) {
  const char* format = (const char*)arg;
  printf(format, pnode->num);
  return false;
}

/* headで示されたリストの各要素を formatで指定された書式で
   標準出力(stdout)に出力する */
void node_print_all(const struct node* head, const char* format) {
  node_find(head, node_print, (void*)format);
}

/* pnodeを解放する */
static bool node_destroy(const struct node* pnode, void* un_used) {
  free((void*)pnode);
  return false;
}

/* headで示されたリスト内の全要素を解放し、NULLを返す */
struct node* node_destroy_all(struct node* head) {
  node_find(head, node_destroy, NULL);
  return NULL;
}

/* さて、以上を踏まえてここからが本番
    といっても仕込み万端整ってるから
    必要な関数を適宜呼び出すだけで一丁上がり */

int main() {
  struct node* head = NULL;

  int x;
  while( scanf("%d",&x) > 0 ) {
    /* nodeを末尾に挿入する。 (先頭に挿入なら node_prependせよ) */
    head = node_append(head, node_create(x));
  }

  // リストの要素のnumの値を先頭から順に表示する 
  node_print_all(head, "%d\n");

  // 全nodeを解放する
  head = node_destroy_all(head);

  return 0;
}

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+1

リストの最後に追加するサンプルコードはこんな感じでしょうか

#include <stdio.h>
#include <stdlib.h>
struct node {
  int num;
  struct node *next;
};

int main()
{
  struct node *head, *p, *q;
  int x;
  head = NULL;

  while(scanf("%d",&x) != EOF) {
    p = (struct node *)malloc(sizeof(struct node));
    if( p == NULL ) {
      printf( "momory error\n" );
      return -1;
    }
    if ( head == NULL ){
         head =  p;
    }else{
         q->next = p;
    }
    p->num  = x;
    p->next = NULL;
    q = p;
  }
  // リストの要素のnumの値を先頭から順に表示する

  q = head;
  while(q->next != NULL){
    printf("%d\n" ,q->num);
    q = q->next;
  }
  printf("%d\n" ,q->num);
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

struct node *q;
q = head;
while(q->next != NULL) q = q->next;

これによってqはリストの末尾要素を指す。
その直後に新しいノードを追加せよ。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/12/19 21:53

    実際のプログラムをどう書けば良いのかわからないので教えていただきたいです

    キャンセル

  • 2017/12/19 22:14

    新しくノードを作りそのポインタをpNewとする、
    pNew->num = テキトーな値;
    pNew->next = NULL;
    q->next = pNew;

    キャンセル

  • 2017/12/19 23:08

    そのプログラムを質問に乗せているプログラムの中に書き足したら良いのでしょうか?

    キャンセル

  • 2017/12/20 05:06

    やってみよ。質問はそれから。

    キャンセル

  • 2017/12/20 11:16

    わかりました

    キャンセル

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

  • ただいまの回答率 90.83%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

  • 解決済

    linux 処理時間の表示

    C言語でLinuxを使っています。メモリを確保したりするプログラムなのですが、以下のプログラムを修正して 、5秒間で何回の入れ替えを行えるかを計測できるようにしてもらいたいです。初

  • 解決済

    オーバーフローします...

    前提・実現したいこと アルファベット順に表示したいです どうやったらアルファベット順に表示できますか? もし,このままでいいならオーバーフローを直して欲しいです... アル

  • 解決済

    c言語 リスト構造について...

    前提・実現したいこと 最近C言語でリスト構造を勉強したので自己流でリスト構造のプログラムを作成したのですが正常に作動しません。どなたか解決法を教えてください。 説明不足だったの

  • 解決済

    リストを逆順に表示するための関数が、上手く機能しません。

    前提・実現したいこと Cでノードを使った線形リストを作っており、元からあるリストを逆順に表示するための関数を作っていました。 発生している問題・エラーメッセージ 逆順に表示する

  • 解決済

    線形リストに対して二分探索をしたいのですが,リストから関数への値の渡し方が分かりません。

    前提・実現したいこと C言語で,線形リストに対して二分探索をするプログラムを作りたいです. リストはcsvファイルから読み込んで作成します. 発生している問題・エラーメッセージ

  • 受付中

    リスト構造と待ち行列

    リスト構造と待ち行列をしたいのですが、よくわかりません。 おすすめのサイトや説明おねがいします。 #include <stdio.h> #include <stdlib.h>

  • 解決済

    「ポインタのポインタ」のつなぎ替えをしている部分がわからない

    リストの構造体のデータをソートしているコードがあるんですが、その中の exchange()関数のところを図を使って書こうと思ったのですが、うまくいきません。 その前に書かれているコ

  • 解決済

    "llist.h"の中身がよく理解できません。

    "llist.h"の中身がよく理解できません。図を書いて見るんですがうまく 表現できないので、どなたか説明してもらえませんか。一つわかれば後は分かると思います。 コード //"

同じタグがついた質問を見る

  • C

    3351questions

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