コース一覧
    C言語中級 文字列・構造体
    動的な構造体配列

    C言語中級 文字列・構造体

    C言語の文字列と構造体を学び、複数のデータを整理して扱うコースです。

    1
    文字列処理の実践
    01. strlenを自作する15分
    02. strcpyを自作する15分
    03. バッファオーバーフロー体験15分
    04. 文字列を分解する15分
    05. 動的な文字列15分
    06. つくる 名前入力の安全化15分
    07. 第3章クイズ10分
    2
    構造体とポインタ
    01. 構造体ポインタと->15分
    02. 構造体の動的確保15分
    03. 動的な構造体配列15分
    04. 関数ポインタ15分
    05. qsortで並べ替える15分
    06. つくる 動的Student完成15分
    07. 第4章クイズ10分

    動的な構造体配列

    1 人ぶんが借りられるなら、n 人ぶんも借りられる

    前回は malloc(sizeof(Student)) で構造体を 1 つ借りました。第 2 章で int を n 個借りたときと同じ理屈で、構造体も並べて借りられます。

    c

    Student *list = malloc(sizeof(Student) * n);

    これで Student が n 個ぶん、すきまなく連続して並んだ領域が手に入ります。連続していることが効いてきて、list は先頭の Student を指すポインタなので、そのまま添字が使えます。

    c

    list[0].score = 80;
    list[1].score = 95;

    list[i] は *(list + i) の別の書き方です。list + i は「i バイト先」ではなく「Student i 個ぶん先」に進むので、構造体の大きさを自分で掛ける必要はありません。第 1 章のポインタ演算がそのまま構造体にも効いている、というだけの話です。

    ドットか矢印かは、やはり左側で決まる

    list[i] は実体なのでドット、list + i はポインタなので矢印です。どちらで書いても同じ場所を触ります。

    c

    list[i].score = 80;      /* 左は実体 */
    (list + i)->score = 80;  /* 左はポインタ */

    読みやすいほうを選んでかまいません。一覧を順に処理するときは添字のほうが素直なことが多いです。

    free は 1 回でよい

    n 人ぶんを 1 回の malloc で借りたなら、返すのも free(list) の 1 回だけです。malloc は借りた大きさを内部で覚えているので、こちらが n を伝える必要はありません。逆に free(&list[3]) のように途中の番地を渡してはいけません。free に渡してよいのは malloc が返したその番地だけです。

    前回のように Student を 1 人ずつ別々に malloc していたら、話は変わります。そのときは人数ぶん free が必要です。「何回借りたか」と「何回返したか」を合わせる、という数え方で考えてください。

    人数を先に読む形にする

    入力の 1 行目に人数を置き、その数だけ確保してから読み込むと、何人でも同じコードで動きます。固定長配列のときのように #define MAX 100 を置いて、それを超えた入力を切り捨てる必要はもうありません。

    c

    int n;
    scanf("%d", &n);
    Student *list = malloc(sizeof(Student) * n);

    なお n が 0 以下だと malloc に 0 や負の値を渡すことになります。実務では読み込んだ直後に範囲を確かめますが、今回の課題では 1 以上の値しか来ない前提で進めます。

    要件

    1. 人数を読んでから malloc で人数分の Student を確保する
    2. 確保に失敗したら「確保できませんでした」と表示して return 1 する
    3. 全員を「名前 点数」の形で1行ずつ表示する
    4. 最後に「平均 」に続けて平均点を小数第1位まで表示する
    5. 確保した領域を free する

    ヒント

    確保する大きさは sizeof(Student) * n です

    list はポインタですが list[i].score のように添字とドットで書けます

    平均は int どうしで割ると切り捨てられます。(double)sum / n としてください

    生田 陸人
    監修生田 陸人
    ゆめさくエンジニア / 現役ソフトウェアエンジニア監修者プロフィールを見る →
    編集 ゆめさく編集部·公開 2026/08/07

    関連レッスン

    • 関数ポインタ

      関数そのものを引数として渡せるようになります。

    • qsortで並べ替える

      比較関数を書いて qsort で並べ替えられるようになります。

    • つくる 動的Student完成

      構造体と動的メモリで成績管理を作り直せるようになります。

    • 第4章クイズ

      構造体ポインタと関数ポインタの理解を確認します。

    main.c
    エディタを読み込んでいます

    メモ

    動的な構造体配列

    ⌘S で保存