
C言語基礎|列挙体の使い方
「数字のまま選ぶの、もう卒業!列挙体で“意味のある値”を気持ちよく扱おう」
列挙体は“少数の選択肢”を安全に表すための道具
C言語では、状態や選択肢を数字で表すことがよくあります。
でも、0 や 1 や 2 だけだと「それが何を意味する数字なのか」がコードから読み取りにくいですよね。
そこで便利なのが 列挙体(enum) です。
- 扱える値が「限られた集合」になる(選択肢が明確)
- 値に名前が付く(読めば意味が分かる)
- switch と相性がよく、分岐がすっきりする
このページでは、元の「犬・猫・猿」ではなく、もっとシンプルに 天気(晴れ・くもり・雨・終了) を選んで表示する例に置き換えて、列挙体の使い方を表と図で丁寧に説明します。
人物は出さず、最後に図解イラスト用プロンプトも1つだけ付けますね。

列挙体(enum)とは何か
列挙体は「いくつかの決まった値だけを使う」ための型を作る仕組みです。
列挙体で向いているもの
| 例 | 値の候補が少ない? | 数字だけだと分かりにくい? | 列挙体が向く |
|---|---|---|---|
| 曜日 | はい | はい | ◎ |
| メニュー選択 | はい | はい | ◎ |
| ON/OFF | はい | まあまあ | ○ |
| 身長や点数 | いいえ(範囲が広い) | 数字そのものが意味 | △ |
表の説明
「選択肢が少ない」「意味を名前で持たせたい」場合に列挙体がピッタリです。
サンプルプログラム
例:天気を選んでメッセージを表示する
プロジェクト名:chap8-6-1 ソースファイル名:chap8-6-1.c
Visual Studio でこのプログラムを実行するには、SDLチェック設定を変更しておく必要があります。
1.プロジェクト名を右クリックして、「プロパティ」をクリックします。
2.「C/C++」→「全般」→「SDLチェック」を「いいえ」に切り替えて「OK」をクリックします。
#include <stdio.h>
enum weather { Sunny, Cloudy, Rainy, Quit };
//--- 天気を選ぶ ---//
enum weather select_weather(void)
{
int tmp;
do {
printf("0…晴れ 1…くもり 2…雨 3…終了:");
scanf("%d", &tmp);
} while (tmp < Sunny || tmp > Quit);
return (enum weather)tmp;
}
//--- 天気メッセージを表示 ---//
void show_message(enum weather w)
{
switch (w) {
case Sunny:
puts("日差しが気持ちいいですね。");
break;
case Cloudy:
puts("のんびり過ごすのにちょうど良さそうです。");
break;
case Rainy:
puts("傘を忘れずに行きましょう。");
break;
default:
break;
}
}
int main(void)
{
enum weather selected;
do {
selected = select_weather();
if (selected != Quit)
show_message(selected);
} while (selected != Quit);
return 0;
}実行例
0…晴れ 1…くもり 2…雨 3…終了:2
傘を忘れずに行きましょう。
0…晴れ 1…くもり 2…雨 3…終了:0
日差しが気持ちいいですね。
0…晴れ 1…くもり 2…雨 3…終了:3列挙体タグと列挙定数
列挙体の宣言はこうです。
enum weather { Sunny, Cloudy, Rainy, Quit };
図:enum の構造(イメージ)

図の説明
- weather が列挙体タグ(enum の名前のようなもの)
- { ... } の中の Sunny などが列挙定数(選択肢の名前)
- 何も指定しない場合、先頭から 0, 1, 2… と整数値が自動で割り当てられます
列挙型の変数宣言は、int と同じ形
列挙体で作られる型は、enum weather 型 のように enum を付けて呼びます。
変数宣言の形(比較)
int x;
enum weather selected;
説明
どちらも「型名 変数名;」という書き方です。
列挙型でも、宣言の形は普通の変数と同じなので、ここで迷いにくいのが良いところです。
なぜ列挙体を使うと読みやすい?
例えば selected == 2 だと、2 が何なのか毎回思い出す必要があります。
でも selected == Rainy なら、読むだけで意味が分かります。
数字だけ vs 列挙体
| 書き方 | 読みやすさ | 意味の伝わり方 |
|---|---|---|
| if (selected == 2) | 低い | 2 の意味が不明 |
| if (selected == Rainy) | 高い | 雨だと一目で分かる |
select_weather 関数のポイント:入力チェックが書きやすい
入力チェックはこの部分です。
tmp < Sunny || tmp > Quit
do-while で範囲をチェックする理由
| 項目 | 内容 |
|---|---|
| do-while を使う理由 | 1回は必ず表示して入力させたい |
| 範囲チェックの狙い | 0〜3 以外の入力を受け付けない |
| Sunny と Quit を使う利点 | 数字を直書きしないので分かりやすい |
表の説明
0〜3 と数字を直書きするより、Sunny や Quit を使うほうが「宣言と連動」して見通しが良くなります。
最後の列挙定数を Quit にするメリット(拡張に強い)
今回、最後を Quit にしました。これは「終了」用途でも便利ですが、範囲の上限にも使えます。
例えば将来、選択肢を増やしたくなったら…
選択肢を追加してもチェック式を変えにくくする方針
enum weather { Sunny, Cloudy, Rainy, Snowy, Quit };
tmp < Sunny || tmp > Quit
説明
新しい Snowy を追加しても、上限が Quit なのでチェック式をそのまま使えます。
「最後は Quit(または Invalid)」という設計は、拡張に強い定番テクニックです。
列挙定数の型はどうなっている?
Cでは、列挙定数(Sunny など)は実体として整数値です。
そのため、int tmp を enum weather として返すことができますが、あいまいさを減らすためにキャストしています。
return (enum weather)tmp;
キャストを書く理由
| 書き方 | 意味 | おすすめ度 |
|---|---|---|
| return tmp; | int をそのまま返す | ○ |
| return (enum weather)tmp; | enum weather として返す意図を明確化 | ◎ |
switch との相性が最高な理由
列挙体は switch と組み合わせると、分岐がすごく読みやすくなります。
switch が向く理由
| 理由 | 内容 |
|---|---|
| case が選択肢の一覧になる | Sunny/Cloudy/Rainy が並び、見通しが良い |
| 追加・変更が簡単 | 列挙定数を追加したら case を足すだけ |
| if の連鎖より読みやすい | 条件がシンプルに整理される |
登場する命令・構文の書式と役割まとめ
enum の書式
enum タグ名 { 列挙定数1, 列挙定数2, ... };
何をする?
限られた選択肢を名前付きの値として定義します。
変数宣言の書式
enum タグ名 変数名;
何をする?
列挙型の変数を作ります(取れる値が選択肢に限定されるイメージ)。
switch の書式
switch (式) {
case 値:
文;
break;
default:
文;
}
何をする?
式の値に応じて処理を分岐します。列挙定数を case に書くと読みやすくなります。
do-while の書式
do {
文;
} while (条件);
何をする?
最低1回は必ず繰り返します。入力を受け付ける処理でよく使います。
printf / scanf / puts の書式
- printf:表示(書式付き)
- scanf:入力(変数のアドレスへ格納)
- puts:文字列を表示して改行
まとめ:列挙体を使うコツ
- 値の候補が少ないなら、列挙体で名前を付けると読みやすい。
- 入力チェックの上限・下限に列挙定数を使うと保守しやすい。
- switch と組み合わせると選択肢が整理されて気持ちいい。
- 最後に Quit / Invalid を置く設計は拡張に強い。
