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

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

ただいまの
回答率

87.34%

学生追加の連結リスト

受付中

回答 3

投稿

  • 評価
  • クリップ 0
  • VIEW 2,246
退会済みユーザー

退会済みユーザー

大学の問題で
「add関数の内容を実装し、連結リストに学生が追加でき るようにせよ
以下の順番で3パターンの実装を行うこと
▪ パターン1:テンプレートの状態(最初に3名登録されてい る状態を想定)から常に学生をリストの先頭に追加できるよ うにせよ
▪ パターン2:パターン1を改良し、テンプレートの状態(最 初に3名登録されている状態を想定)から常に学生をリスト の末尾に追加できるようにせよ(最後尾の直前の要素を探す アルゴリズムが必要)
▪ パターン3(余裕がある人だけでよい):パターン2を改良 し、登録されている学生が0名の場合でも、既に登録されて いる学生がいる場合も、常にリストの末尾に学生を追加でき るようにせよ」
というものがあります。3まで終わったらそのファイルを提出すればいいとのことです。
パターン1の段階から引っかかってしまい前に進めません。どうすれば実行できますか?

//
//  学生名簿プログラム(リスト使用)
// アルゴリズム応用 第8回課題-1
//

#include <stdio.h>
#include <stdlib.h>

/* 学生の構造体 */
typedef struct Meibo {
    int number;
    char name[10];
    int credits;
    struct Meibo *next; //後続へのポインタ
} Meibo;

Meibo *head = NULL; //リストの先頭へのポインタ

/* 一覧表示 */
void display(){
    Meibo *ptr;
    printf("------------------\n");
    for(ptr = head; ptr != NULL; ptr = ptr->next){
        printf("%-3d%-10s%-3d\n", ptr->number, ptr->name, ptr->credits);
        printf("------------------\n");
    }
}

/* 追加 */
void add(){
    //一人分のメモリを確保する
    Meibo *student;
    student = (Meibo *)malloc(sizeof(Meibo));
    
    if(student != NULL){
        //入力を受け取る
        printf("学績番号\n");
        scanf("a = %d", &student->number);
        printf("氏名\n");
        scanf("b = %s", student->name);
        printf("総取得単位数\n");
        scanf("c = %d", &student->credits);
        
        //リストに追加する
        //ここを考えましょう
    }
}

int main(void){
    //学生の基本情報を設定
    Meibo st1 = { 1, "John", 30 };
    Meibo st2 = { 2, "Paul", 28 };
    Meibo st3 = { 3, "George", 20 };
    Meibo st4 = { a, b, c};
    
    //連結リストを作る
    head = &st4;
    st1.next = &st1;
    st2.next = &st2;
    st3.next = &st3;
    
    // メニューの表示と実行
    char cmd;
    printf("a:追加  d:一覧表示  q:終了\n");
    while((cmd = getchar()) != 'q'){
        switch(cmd){
            case 'a':
                add();
                break;
            case 'd':
                display();
                break;
            case '\n':case ' ':
                break;
            default:
                printf("不正なコマンドです\n");
                break;
        }
    }
    
    printf("名簿プログラムを終了します。\n");
    
    return 0;
}
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 3

+1

こんにちは。

そのものズバリを回答するのは簡単ですが、大学の課題ということですので答えを書くのはまずいかなと思い、ヒントをだそうと思ったのですが、うまくヒントがだせません。

いきなり下記の部分が間違っているのですが、この辺りも元々このようになっていたのでしょうか?
    Meibo st4 = { a, b, c};
    
    //連結リストを作る
    head = &st4;
    st1.next = &st1;
    st2.next = &st2;
    st3.next = &st3;
本来は、この部分を参考にして下記を書けば良いのですが、ここが既に間違っているので説明が難しいのです。

        //リストに追加する
        //ここを考えましょう

後、scanf()での読み出しも入力しづらい方法になってます。
①getchar()はちょっとクセがあります。つい先日似たような回答をしましたので、参考にして下さい。

②scanf("a = %d", ...);のようにすると、a = の部分も入力する必要があり、入力しにくいです。"a = "はscanf()に含めないことをお薦めします。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

0

自分も新人の頃にやらされた研修問題なので、このくらい自分で考えたほうがいいですよ(笑

と言いたいところですが、ひとつ確認です
連結リストを作るところですが、*head にst1のアドレスを設定し、st1.nextにはst2のアドレスを、st2.nextにはst3のアドレスを、st3.nextにはNULLを設定することで、構造体のチェーンを作成するのだと思います
このように構造体のチェーンを作り、常に*headからチェーンを検索していくことで、チェーンの先頭、チェーンの末尾を見つけて処理を行います  

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

0

まず、連結リストを理解しましょう。
データ構造などの教科書には、矢印で繋がれたリストが表現されていると思います。
本題での初期状態は以下のようになります。
★本題での最初の状態★
head ->  st3.next -> st2.next -> st1.next -> END(NULL)
まずこの、この状態を表すにはコードではどの様に書けば良いでしょうか。
回答者の皆様が、言われていますが、最初の連結リストの部分で勘違いされています。
    //連結リストを作る
    head = &st4;
    st1.next = &st1;
    st2.next = &st2;
    st3.next = &st3;
これだと、以下の様になって連結されている状態ではありません。
★連結リストになっていません★
head ->  st4      // st4? これはこれから追加するものを表しているのでしょうか?
st1.next -> st1   //  これでは、自分自身を指していますので、次を指すようにしましょう。
st2.next -> st2   //   以下同じ
st3.next -> st3
パターン1の先頭に追加するには、headからの→を新しく追加するデータを指すようにすれば良いです。
★stXX.next 追加★
head ->  stXX.next -> st3.next -> st2.next -> st1.next -> END(NULL)
では、がんばってください。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

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

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

関連した質問

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