Skip to content

50. 열거형(Enum)


1. 키워드

  • 열거형(Enum)
  • 열거형 별칭
  • 익명 열거형


2. 열거형 사용하기

  • 열거형은 정수형 상수에 이름을 붙여서 코드를 이해하기 쉽게 해준다.
  • 만약 다음과 같이 ValueA, ValueB, ValueC라는 정수형 상수를 선언한다면 두세 개까지는 괜찮지만 개수가 많아지면 일일이 선언하기 귀찮아진다.


const int ValueA = 1;
const int ValueB = 2;
const int ValueC = 3;


  • 열거형을 사용하면 정수형 상수를 좀 더 편하게 정의할 수 있다.


3. 열거형 정의하기

  • 열거형은 enum 키워드를 사용하여 정의한다.


enum 열거형이름 {
    값1 = 초깃값,
    값2,
    값3
};


  • 열거형은 정의만 해서는 사용을 할 수가 없다.
  • 따라서 열거형도 변수로 선언해서 사용한다.


enum 열거형이름 변수이름;


  • 열거형으로 요일을 정의해 보자.


#include <stdio.h>

enum DayOfWeek // 열거형 정의
{
    Sunday = 0, // 초깃값 할당
    Monday,
    Tuesday,
    Wednesday,
    Thursday,
    Friday,
    Saturday
};

int main()
{
    enum DayOfWeek week; // 열거형 변수 선언

    week = Tuesday; // 열거형 값 할당

    printf("%d\n", week); // Tuesday의 값 출력

    return 0;
}

// 2


  • 먼저 enum 키워드 뒤에 열거형 이름을 지정해 주고 {}(중괄호) 안에 값을 나열한다.
  • 여기서 각 값들은 ,(콤마)로 구분하며 =(할당 연산자)를 사용하여 값을 할당할 수 있다.
  • 마지막으로 열거형을 정의할 때 }(닫는 중괄호) 뒤에는 반드시 ;(세미콜론)을 붙여준다.


enum DayOfWeek // 열거형 정의
{
    Sunday = 0, // 초깃값 할당
    Monday,
    Tuesday,
    Wednesday,
    Thursday,
    Friday,
    Saturday
};


  • 열거형의 값은 처음에만 할당해 주면 그 아래에 오는 값들은 1씩 증가하면서 자동으로 할당된다.
  • 이때 아무 값도 할당하지 않으면 0부터 시작한다.
  • 따라서 처음에 오는 Sunday0을 할당하면 Monday1, Tuesday2, Wednesday3이 된다.


열거형 이름과 대소문자

  • 문법으로 정해진 규칙은 아니지만 열거형 이름이나 값을 정의할 때 대문자만 사용하는 경우가 많다.
  • 특히 단어와 단어 사이에는 _(언더스코어)를 주로 사용한다.


  • 다음은 리눅스 커널의 hdmi.h 헤더 파일에 정의된 열거형인데, 열거형 이름은 모두 소문자지만 열거형 값이 모두 대문자이다.


enum hdmi_content_type {
    HDMI_CONTENT_TYPE_GRAPHICS,
    HDMI_CONTENT_TYPE_PHOTO,
    HDMI_CONTENT_TYPE_CINEMA,
    HDMI_CONTENT_TYPE_GAME,
};


  • 다음은 Windows 커널의 winddkk.h 헤더 파일에 정의된 열거형이다.
  • 여기서는 열거형 이름이 모두 대문자이고 열거형 값은 단어의 첫 글자만 대문자로 되어 있다.


typedef enum _POOL_TYPE {
    NonPagedPool,
    PagedPool,
    NonPagedPoolMustSucceed,
    DontUseThisType,
    NonPagedPoolCacheAligned
    // ... 생략 ...
} POOL_TYPE;


  • 정의한 열거형을 사용하려면 열거형 변수를 선언해야 한다.
  • 이때는 열거형 이름 앞에 반드시 enum 키워드를 붙여준다.
  • 다음은 DayOfWeek 열거형 타입의 변수 week를 선언한다는 뜻이다.


enum DayOfWeek week; // 열거형 변수 선언


  • 보통 열거형 변수에는 미리 정의한 열거형 값을 넣는다.
  • 열거형 값 대신 정수를 할당해도 상관없지만 정의하지 않은 열거형 값은 넣을 수 없다.


week = Tuesday; // 열거형 값 할당


  • printfweek의 값을 출력해 보면 Tuesday의 값인 2가 나온다.


printf("%d\n", week); // Tuesday의 값 출력


모든 열거형 값에 정수 할당하기

  • 보통 열거형을 정의할 때 처음에 오는 값에만 초깃값을 할당하지만 다음과 같이 모든 값에 정수를 할당할 수 있다.


enum Value
{
    ValueA = 1,
    ValueB = 3,
    ValueC = 7,
    ValueD = 11
};


  • 연속되지 않은 불규칙한 값을 사용하려면 모든 열거형 값에 정수를 할당하면 된다.


typedef와 익명 열거형

  • 열거형도 typedef로 별칭을 지정하고, 익명 열거형을 정의할 수 있다.


  • 먼저 열거형 별칭은 다음과 같이 정의한다.


typedef enum 열거형이름 {
    값1 = 초깃값,
    값2,
    값3
} 열거형별칭;
typedef enum _DayOfWeek // 열거형 이름은 _DayOfWeek
{
    Sunday = 0,
    Monday,
    Tuesday,
    Wednesday,
    Thursday,
    Friday,
    Saturday
} DayOfWeek; // typedef를 사용하여 열거형 별칭을 DayOfWeek로 정의


  • typedef로 열거형의 별칭을 만들었다면 변수는 다음과 같이 선언한다.


열거형별칭 변수이름;


  • 익명 열거형은 다음과 같이 정의한다.


typedef enum {
    값1 = 초깃값,
    값2,
    값3
} 열거형별칭;


  • 변수는 열거형 변수로 선언하면 된다.


열거형별칭 변수이름;
typedef enum // 익명 열거형 정의
{
    Sunday = 0,
    Monday,
    Tuesday,
    Wednesday,
    Thursday,
    Friday,
    Saturday
} DayOfWeek; // typedef를 사용하여 열거형 별칭을 DayOfWeek로 정의

DayOfWeek week; // 열거형 별칭으로 공용체 변수 선언


열거형을 정의하는 동시에 변수 선언하기

  • 다음과 같이 열거형은 정의하는 동시에 변수를 선언할 수 있다.


enum 열거형이름 {
    자료형 멤버이름;
} 변수;
enum DayOfWeek // 열거형 정의
{
    Sunday = 0,
    Monday,
    Tuesday,
    Wednesday,
    Thursday,
    Friday,
    Saturday
} week; // 열거형을 정의하는 동시에 변수 week 선언


4. 열거형을 switch에 활용하기

  • 열거형은 switch 분기문을 사용할 때 유용하다.


switch (열거형변수)
{
case 열거형값:
    실행할코드;
    break;
}


  • 예를 들어 게임을 만든다고 하면 캐릭터의 스킬을 열거형으로 정의할 수 있다.


#include <stdio.h>

enum LuxSkill
{
    LightBinding = 1,
    PrismaticBarrier,
    LucentSingularity,
    FinalSpark
};

int main()
{
    enum LuxSkill skill; // 열거형 변수 선언

    skill = LightBinding; // 열거형 값 할당

    switch (skill)
    {
    case LightBinding: // 열거형 값이 LightBinding일 때
        printf("LightBinding\n");
        break;
    case PrismaticBarrier: // 열거형 값이 PrismaticBarrier일 때
        printf("PrismaticBarrier\n");
        break;
    case LucentSingularity:
        printf("LucentSingularity\n"); // 열거형 값이 LucentSingularity일 때
        break;
    case FinalSpark:
        printf("FinalSpark\n"); // 열거형 값이 FinalSpark일 때
        break;
    default:
        break;
    }

    return 0;
}

// LightBinding


  • 열거형 변수를 switch 분기문에 사용하면 열거형 값에 따라 코드를 실행할 수 있다.
  • 만약 스킬을 1, 2, 3, 4 번호로 외워야 한다면 상당히 갑갑할 것이다.
  • 이때 열거형을 사용하여 LightBinding, PrismaticBarrier, LucentSingularity, FinalSpark와 같이 스킬 이름으로 처리하면 된다.


5. 열거형을 for에 활용하기

  • 열거형을 정의한 뒤 for 반복문에 활용하는 방법도 있다.
  • 예를 들어 프로그램에서 일요일부터 토요일까지 매일 반복되는 알람을 설정한다면 열거형과 반복문을 사용하면 편리하다.


#include <stdio.h>

typedef enum _DayOfWeek // 열거형 이름은 _DayOfWeek
{
    Sunday = 0, // 초깃값을 0으로 할당
    Monday,
    Tuesday,
    Wednesday,
    Thursday,
    Friday,
    Saturday,
    DayOfWeekCount // 열거형 값의 개수를 나타내는 항목 추가
} DayOfWeek;       // typedef를 사용하여 열거형 별칭을 DayOfWeek로 정의

int main()
{
    // 초깃값은 Sunday, i가 DayOfWeekCount보다 작을 때까지만 반복
    for (DayOfWeek i = Sunday; i < DayOfWeekCount; i++)
    {
        printf("%d\n", i);
    }

    return 0;
}

// 0
// 1
// 2
// 3
// 4
// 5
// 6


  • 먼저 다음과 같이 열거형을 정의할 때 초깃값으로 0을 할당한다.
  • 그리고 열거형 값을 나열하다가 맨 마지막에는 DayOfWeekCount와 같이 열거형 값의 개수를 나타내는 항목을 넣어준다.
  • 보통 이름을 지을 때 개수 또는 최대치를 뜻하는 Count, _COUNT, Max, _MAX, Maximum 등을 조합한다.


typedef enum _DayOfWeek // 열거형 이름은 _DayOfWeek
{
    Sunday = 0, // 초깃값을 0으로 할당
    Monday,
    Tuesday,
    Wednesday,
    Thursday,
    Friday,
    Saturday,
    DayOfWeekCount // 열거형 값의 개수를 나타내는 항목 추가
} DayOfWeek;       // typedef를 사용하여 열거형 별칭을 DayOfWeek로 정의


  • for 반복문에서 열거형 별칭으로 변수 i를 선언한 뒤 초깃값으로 Sunday를 넣는다.
  • 그리고 iDayOfWeekCount보다 작을 때까지만 반복한다.


// 초깃값은 Sunday, i가 DayOfWeekCount보다 작을 때까지만 반복
for (DayOfWeek i = Sunday; i < DayOfWeekCount; i++)
{
    printf("%d\n", i);
}


  • 이렇게 하면 열거형 값 Sunday부터 Saturday까지 반복할 수 있다.

References