
C言語基礎|現実世界と構造体
「現実の“モノ”を、そのままプログラムへ。構造体でデータ設計が自然になる!」
プログラムって、現実世界そのものを扱っているようで、実はちょっと違います。
現実の「人」「商品」「センサー」「注文」みたいな“モノ”を、そのままコードに入れられるわけじゃないんですよね。
だから私たちは、現実のモノから「必要な側面(情報)」だけを抜き出して、変数として表現します。
身長なら height、体重なら weight、という具合です。
でも、現実のモノはたいてい 複数の情報がセットです。
「人」は名前も身長も体重もあるし、「商品」なら名前・価格・在庫がセット。
この“セット感”をプログラムでも自然に表せるのが 構造体なんです。

現実世界 → プログラム世界への「投影」という考え方
ここでは「投影」という言葉を、現実のモノを、プログラムで扱える形に写し取ることとして使います。
図:1つの側面だけに注目すると、変数になる

図の説明
- 現実の「人」そのものはプログラムに持ち込めないので
- 「身長という側面」だけ切り取って
- 数値として変数 height にする、というイメージです
複数の側面をまとめて投影すると「構造体」になる
身長だけでは足りなくて、体重や名前も要るなら…変数が増えて散らかりがちです。
そこで「まとまり」を作ります。
図:人を“ひとまとめ”で投影する

図の説明
- 現実の「人」は、名前・身長・体重がセット
- それをプログラムでもセットで扱うために
- 1つの構造体オブジェクトにまとめる、という考え方です
構造体が「素直なプログラム」を作る理由
構造体を使うと、コードの考え方が現実に近くなります。
| 書き方 | 例 | つらさ/うれしさ |
|---|---|---|
| ばらばらの変数 | name, height, weight が別々 | 同じ人の情報なのに関連が見えにくい |
| 構造体でまとめる | person.name, person.height, person.weight | 同じ人の情報だと一目で分かる |
集成体型(aggregate type)としての配列と構造体
配列と構造体はどちらも「複数のデータをまとめる型」なので、まとめて 集成体型 と呼ばれます。
でも、性格はけっこう違います。
配列と構造体の違い(超重要)
| 観点 | 配列 | 構造体 |
|---|---|---|
| まとめる対象 | 同じ型の集まり | いろいろな型の集まりが得意 |
| 例 | int scores[5] | name(文字列), age(int), height(double) |
| 目的 | 同種データを効率よく | 現実の“モノ”を自然に表現 |
要素型の違い(同じ型 vs 異なる型)
配列は「同じ型」を並べる
- 例:テスト点数、温度ログ、座標のリストなど
構造体は「異なる型」をひとまとめにするのが得意
- 例:人、商品、センサー状態、ユーザー設定など
代入の可否:配列はダメ、構造体はOK
ここ、Cの基本ルールとして押さえておくと強いです。
配列は代入できない
int a[3] = {1,2,3};
int b[3] = {9,8,7};
a = b; // エラー
構造体は同じ型同士なら代入できる
struct Person x, y;
x = y; // OK(メンバがまとめてコピーされる)
なぜ違う?
| 型 | 代入 | ざっくり理由 |
|---|---|---|
| 配列 | できない | 配列名は“配列そのもの”の代入になり、言語仕様で禁止 |
| 構造体 | できる | 構造体は「1つの値」として扱えるので、メンバごとにコピーされる |
サンプルプログラム
元の「人の身長・体重」ではなく、現実世界で分かりやすい センサー機器 を例にします。
表示メッセージも別の日本語に置き換えています。
何をするプログラム?
- センサー機器の情報(名前・温度・電池残量)を構造体でまとめる
- 別の機器へ丸ごと代入でコピーする(構造体代入ができることを体験)
- 結果を表示する
プロジェクト名:chap12-5-1 ソースファイル名:chap12-5-1.c
#include <stdio.h>
#include <string.h>
#define NAME_LEN 16
struct Sensor {
char name[NAME_LEN]; // 機器名
double temp; // 温度
int battery; // 電池残量(%)
};
int main(void)
{
struct Sensor a;
struct Sensor b;
strcpy(a.name, "room");
a.temp = 23.5;
a.battery = 80;
// 構造体は代入でまとめてコピーできる
b = a;
printf("コピーしました。\n");
printf("機器A:%s 温度=%.1f 電池=%d%%\n", a.name, a.temp, a.battery);
printf("機器B:%s 温度=%.1f 電池=%d%%\n", b.name, b.temp, b.battery);
return 0;
}登場する命令(要素)の書式と役割を解説
struct Sensor { ... };
| 要素 | 書式 | 何をする? |
|---|---|---|
| 構造体宣言 | struct Tag { メンバ宣言... }; | 「現実のモノ」を表す型(フォーマット)を作る |
| メンバ宣言 | 型 メンバ名; | 構造体の中に入る項目を定義する |
strcpy
| 項目 | 書式 | 何をする? |
|---|---|---|
| strcpy | strcpy(コピー先, コピー元); | 文字列を配列へコピーする |
説明
Cでは、配列(char name[ ])へ文字列を入れるときに、単純な代入ではなくコピー関数を使うことが多いです。
(実務では安全な入力方法も大事ですが、ここでは構造体の理解が主役なのでシンプルにしています)
構造体の代入(b = a;)
| 項目 | 書式 | 何をする? |
|---|---|---|
| 構造体代入 | 左辺 = 右辺; | 同じ型の構造体なら、メンバをまとめてコピーする |
説明
b = a; を実行すると、a.name, a.temp, a.battery が b 側に一括コピーされます。
「現実世界の“機器カード”を丸ごと複製した」みたいな感覚ですね。
printf
| 項目 | 書式 | 何をする? |
|---|---|---|
| printf | printf(書式文字列, ...); | 画面に文字を表示する |
図:構造体の投影とコピー(このプログラムの見え方)

図の説明
- a は「機器Aの情報を投影したもの」
- b = a で、投影された情報を丸ごと複製できる
- 配列ではこの“丸ごとコピー”ができないので、構造体の気持ちよさが見えます
まとめ:現実のまとまりを、そのままコードへ
- 変数は「現実の一側面」を投影したもの
- 構造体は「現実のまとまり」を投影したもの
- 配列は同じ型の集まり、構造体は異なる型をまとめるのが得意
- 配列は代入できないが、構造体は同型なら代入できる。
- だから構造体は、プログラムを素直で読みやすくしてくれます。
