【C言語入門講座】13章.列挙型とは(使い方からメリットまで)

C言語入門レッスン

☜前の章へ 構造体とは


【C言語入門講座】は全13章から構成される、初心者向けのC言語学習コンテンツです。1章から13章まで学習して頂くことでC言語の基礎を学習することができます。

この記事で分かること
  1. 列挙型とは
  2. 列挙型のメリット
  3. 列挙型の定義
  4. 列挙型の宣言
  5. 列挙型の初期化
  6. 列挙型の表示とループでの表示
  7. 列挙型の文字列を条件分岐で使用する方法
  8. typedefの使い方
  9. 関数の引数での使い方
  10. 列挙子をインクリメントできない理由

ここでは、列挙型とは何か、列挙型のメリットとはから列挙型の基本的な使い方までを習得することができます。

列挙型の基本をまとめているので、是非有効活用してください。

列挙型とは

列挙型とは、整数値に対して意味のある名前を割り当て、定数として1つにまとめた型のことです。

例えば、0なら日本人、1なら中国人、2なら韓国人といったように数値ごとに意味を持たせたい時に使用されます。

配列は各要素に値を格納するだけですが、列挙型は整数値に名前を割り当てる点で違いがあります。

列挙型のメリット

列挙型のメリット
  • 可読性の向上
  • 安全性の向上

列挙型は整数値に意味のある名前を付けることができるため、コードの可読性が向上します
例えば、日本人、中国人などの単語を使って特定の国籍を表現することが出来ます。

列挙型を使用すると、プログラム内で整数値の間違った使用を防ぐことができるため、コードの安全性が向上します
例えば、特定の関数に整数値を渡す代わりに、列挙型を使用することで、その関数が予期しない整数値を受け取る可能性を減らすことができます。

列挙型の基本的な使い方

※上記の青い文字から読みたい項目へ移動することができます

①列挙型の定義

列挙型の定義
  • enum 列挙型名 {
    列挙子名,
    列挙子名,
    列挙子名
    };
#include <stdio.h>

//列挙型の定義
enum Nationality {
    // 自動採番されるためJAPANESEは0
    JAPANESE,
    CHINESE,
    KOREAN,
    // 番号を指定することもできる。CANADAは11になる
    AMERICAN = 10,
    CANADA
};

int main(void) {

    return 0;
}

enumが列挙型を表すものです
enum Nationalityで列挙型Nationalityを定義しています。

列挙型では、文字と数字が関連付けられます

列挙型の定義でJAPANESE、CHINESEなどの単語がありますが、これらを列挙子と呼びます。

JAPANESEには0が対応しており、CHINESEは1が対応しています。

AMERICAN = 10のように指定しないと上から順に、0、1、2、3、4といったように自動採番されていきます

②列挙型の宣言

列挙型の宣言
  • enum 列挙型名 変数名;
#include <stdio.h>

//列挙型の定義
enum Nationality {
    // 自動採番されるためJAPANESEは0
    JAPANESE,
    CHINESE,
    KOREAN,
    // 番号を指定することもできる。CANADAは11になる
    AMERICAN = 10,
    CANADA
};

int main(void) {
    //列挙型の宣言
    enum Nationality nationality;

    return 0;
}

「enum Nationality」は型なので、この型を使いたい場合、「enum Nationality nationality」のように変数nationalityを宣言する必要があります。

③列挙型の初期化

列挙型の初期化
  • enum 列挙型名 変数名 = 列挙子名;
#include <stdio.h>

//列挙型の定義
enum Nationality {
    // 自動採番されるためJAPANESEは0
    JAPANESE,
    CHINESE,
    KOREAN,
    // 番号を指定することもできる。CANADAは11になる
    AMERICAN = 10,
    CANADA
};

int main(void) {
    //列挙型の宣言と初期化
    enum Nationality nationality = JAPANESE;

    return 0;
}

初期化をするためには列挙子を宣言と同時に代入します。

「enum Nationality nationality = JAPANESE;」と初期化しているので、変数nationalityには0が代入されています。

見た目は文字の「JAPANESE」ですが、実態は数字(JAPANESE=0)であるため、nationalityには0が代入されています。

④列挙型の表示(出力)

列挙型の表示(出力)
  • printf(“%d”, 変数名);
#include <stdio.h>

//列挙型の定義
enum Nationality {
    // 自動採番されるためJAPANESEは0
    JAPANESE,
    CHINESE,
    KOREAN,
    // 番号を指定することもできる。CANADAは11になる
    AMERICAN = 10,
    CANADA
};

int main(void) {
    //列挙型の宣言と初期化
    enum Nationality nationality = CHINESE;

    printf("%d\n", nationality);

    return 0;
}

出力結果

1

printf関数で%dと宣言した変数名を使うことで列挙型を表示することができます。

⑤列挙型のループでの表示(出力)

列挙型のループでの表示(出力)
  • for (列挙型の変数名; 列挙型の変数名 <= 列挙子名; 列挙型の変数名++) {
    printf(“%d”, 列挙型の変数名);
    }
#include <stdio.h>

//列挙型の定義
enum Nationality {
    // 自動採番されるためJAPANESEは0
    JAPANESE,
    CHINESE,
    KOREAN,
    // 番号を指定することもできる。CANADAは11になる
    AMERICAN = 10,
    CANADA
};

int main(void) {
    enum Nationality nationality = JAPANESE;

    // ループを使用して列挙型の値を出力
    printf("列挙型 Nationality の値:\n");
    for (nationality; nationality <= CANADA; nationality++) {
        printf("%d\n", nationality);
    }

    return 0;
}

出力結果

0 1 2 3 4 5 6 7 8 9 10 11

ループで列挙型の値を表示することもできます。

ループで列挙型の値を表示したい場合、列挙型の変数名をループでインクリメントし、「nationality <= CANADA」のように、どの列挙子までを表示したいかを指定できます。

列挙型の変数をインクリメントすることはできますが、列挙子自体はインクリメントできないので注意してください。

⑥列挙型の文字列を条件分岐で指定して使用する方法

#include <stdio.h>

//列挙型の定義
enum Nationality {
    // 自動採番されるためJAPANESEは0
    JAPANESE,
    CHINESE,
    KOREAN,
    // 番号を指定することもできる。CANADAは11になる
    AMERICAN = 10,
    CANADA
};

int main(void) {
    //列挙型の宣言と初期化
    enum Nationality nationality = JAPANESE;
    int num;

    printf("該当する国籍に対応する整数値を入力してください。\n日本人:0,中国人:1,韓国人:2,アメリカ人:10,カナダ人:11\n");
    scanf("%d", &num);

    switch (num) {
    case JAPANESE:
        printf("日本人です\n");
        break;
    case CHINESE:
        printf("中国人です\n");
        break;
    case KOREAN:
        printf("韓国人です\n");
        break;
    case AMERICAN:
        printf("アメリカ人です\n");
        break;
    case CANADA:
        printf("カナダ人です\n");
        break;
    }

    return 0;
}

出力結果

該当する国籍に対応する整数値を入力してください。 日本人:0,中国人:1,韓国人:2,アメリカ人:10,カナダ人:11 1 中国人です

switch分の「case JAPANESE:」のように列挙型の文字列を指定して使用することが出来ます。

JAPANESEと書かれていますが、実態は0であるため、「case 0:」と同じ意味になります。

このように、数字ごとに意味を区別し、数字ごとに異なる動作をさせたい場合、文字で数字を表現できるため、パッと見て意味を理解しやすくなります。

列挙型のtypedefの使い方

#include <stdio.h>

// タグ名であるenは省略可能
typedef enum en {
    JAPANESE,
    CHINESE,
    KOREAN,
    AMERICAN = 10,
    CANADA
} Nationality;

int main(void) {
    // 列挙型の宣言と初期化
    Nationality nationality = JAPANESE;

    printf("%d", nationality);

    return 0;
}

列挙型を定義するときに、enumの前にtypedefと書くことで、列挙型の宣言時にenumを省略し列挙型の名前である「Nationarlity」のみで列挙型を宣言することができます。

列挙型を関数の引数に使う方法

#include <stdio.h>

//列挙型の定義
enum Nationality {
    // 自動採番されるためJAPANESEは0
    JAPANESE,
    CHINESE,
    KOREAN,
    // 番号を指定することもできる。CANADAは11になる
    AMERICAN = 10,
    CANADA
};

// 関数の定義
void printNationality(enum Nationality nationality) {
    switch (nationality) {
        case JAPANESE:
            printf("日本人です\n");
            break;
        case CHINESE:
            printf("中国人です\n");
            break;
        case KOREAN:
            printf("韓国人です\n");
            break;
        case AMERICAN:
            printf("アメリカ人です\n");
            break;
        case CANADA:
            printf("カナダ人です\n");
            break;
    }
}

int main(void) {
    //列挙型の宣言と初期化
    enum Nationality nationality = CHINESE;

    printNationality(nationality);

    printNationality(AMERICAN);

    return 0;
}

「printNationality(enum Nationality nationality)」のように、関数の引数に列挙型の変数を定義します。

関数を呼び出し、引数に列挙型の変数を指定するか列挙子を指定することで使用することができます。

列挙型の列挙子をインクリメントできない理由

列挙子は基本的に整数値を表す定数であり、それ自体が変数ではないため、インクリメントやデクリメントの演算子を使用することはできません

定数とは、一度宣言すると変更することができない値です。

そのためインクリメントやデクリメントの演算子を使用することはできません。


練習問題

野球、水泳、テニス、サッカー、バスケを列挙型で宣言します。入力を促し、入力された値をもとにスポーツ名を表示しましょう

#include <stdio.h>

// 列挙型でスポーツを宣言
enum Sports {
    BASEBALL,
    SWIMMING,
    TENNIS,
    SOCCER,
    BASKETBALL
};

int main() {
    // ユーザーにスポーツの選択を促す
    printf("0: 野球, 1: 水泳, 2: テニス, 3: サッカー, 4: バスケットボール\n");
    printf("どのスポーツが好きですか?(1から5の数字を入力してください): ");

    int userChoice;
    scanf("%d", &userChoice);

    // 入力された値に対応するスポーツ名を表示
    switch (userChoice) {
        case BASEBALL:
            printf("あなたの選択: 野球\n");
            break;
        case SWIMMING:
            printf("あなたの選択: 水泳\n");
            break;
        case TENNIS:
            printf("あなたの選択: テニス\n");
            break;
        case SOCCER:
            printf("あなたの選択: サッカー\n");
            break;
        case BASKETBALL:
            printf("あなたの選択: バスケットボール\n");
            break;
        default:
            printf("無効な選択です。\n");
    }

    return 0;
}

☜前の章へ 構造体とは

タイトルとURLをコピーしました