本文へスキップ
BecomeCoder

C言語コース · 第7章 構造体と共用体 · レッスン28

構造体の配列とネスト構造体 ― たくさんのデータ、入れ子のデータ

ブラウザで完結

導入

3人分、10人分の Person を扱いたいとき、p1, p2, p3変数を増やすのは大変です。構造体は普通の型と同じように配列にできます。また、構造体の中に別の構造体を入れる**ネスト(入れ子)**もよく使われます。

説明

構造体の配列は、int の配列と同じ書き方で作れます。

#include <stdio.h>

struct Point {
    int x;
    int y;
};

struct Rect {
    struct Point topLeft;
    struct Point bottomRight;
};

int main(void) {
    struct Point pts[3] = {{0, 0}, {1, 2}, {3, 4}};
    int i;
    for (i = 0; i < 3; i++) {
        printf("(%d,%d)\n", pts[i].x, pts[i].y);
    }

    struct Rect r = {{0, 0}, {10, 5}};       // 構造体の中に構造体(ネスト)
    int width = r.bottomRight.x - r.topLeft.x;
    int height = r.bottomRight.y - r.topLeft.y;
    printf("width=%d height=%d\n", width, height);
    return 0;
}

struct Rectstruct Point を2つメンバに持つ「入れ子」の構造体です。r.topLeft.x のように . を2回連続で書くと、外側→内側とたどってメンバに届きます。

flowchart LR
  r["struct Rect r"] --> tl["topLeft(struct Point)<br/>x=0, y=0"]
  r --> br["bottomRight(struct Point)<br/>x=10, y=5"]
  tl -->|"r.topLeft.x のように<br/>ドットを2回たどる"| tlx["x = 0"]

やってみよう

pts の要素数を4つに増やしてみたり、Rect の座標を変えて width/height が変わることを確かめましょう。

演習

struct Point pts[3](2,3)(5,7)(-1,4) を入れ、for ループで各点の x + y を合計して total に足し込み、printf("合計=%d\n", total); の形で表示してください(正しく書けると 合計=20 になります)。

ヒント1を見る

struct Point pts[3] = {{2,3},{5,7},{-1,4}}; のように初期化します。

ヒント2を見る

ループの中で total += pts[i].x + pts[i].y; を足していきます。

実際に動かしてみよう

下のエディタにCを書いて「コンパイル & 実行」を押すと、ブラウザ内で本物のCコンパイラ(clang + dlmalloc)がその場でコンパイルして実行し、出力が表示されます。構造体・共用体・malloc/free・関数ポインタ・ファイル入出力などがそのまま動きます。本文の例を書き換えて試しながら進めましょう(初回だけコンパイラの読み込みに時間がかかります。以降はキャッシュされます。この回は標準入力(scanf)は使わず、値はコードに直接書きます)。

C/C++ — ブラウザ内で本物のコンパイラで実行

ブラウザ内で本物のC/C++コンパイラ(clang + libc++ / WebAssembly)を動かします。構造体・malloc/free・std::string・vector・クラス・テンプレート・STL などがそのまま実行できます(初回のみコンパイラの読み込みに時間がかかります。以降はブラウザにキャッシュされます)。
スクロールして表示された時点でも自動で読み込まれます。