57 열거형 사용하기
열거형은 정수형 상수에 이름을 붙여서 코드를 이해하기 쉽게 해줍니다. 만약 다음과 같이 ValueA, ValueB, ValueC라는 정수형 상수를 선언한다면 두세 개까지는 괜찮지만 개수가 많아지면 일일이 선언하기가 귀찮아집니다.
const int ValueA = 1; const int ValueB = 2; const int ValueC = 3;
열거형을 사용하면 정수형 상수를 좀 더 편하게 정의할 수 있습니다.
57.1 열거형 정의하기
열거형은 enum 키워드를 사용하여 정의하며 열거, 목록을 뜻하는 enumeration에서 따왔습니다.
enum 열거형이름 { 값1 = 초깃값, 값2, 값3 };
열거형은 정의만 해서는 사용을 할 수가 없습니다. 따라서 열거형도 변수로 선언해서 사용합니다.
- enum 열거형이름 변수이름;
열거형으로 요일을 정의해보겠습니다. 다음 내용을 소스 코드 편집 창에 입력한 뒤 실행해보세요.
enum.c
#include <stdio.h> enum DayOfWeek { // 열거형 정의 Sunday = 0, // 초깃값 할당 Monday, Tuesday, Wednesday, Thursday, Friday, Saturday }; int main() { enum DayOfWeek week; // 열거형 변수 선언 week = Tuesday; // 열거형 값 할당 printf("%d\n", week); // 2: Tuesday의 값 출력 return 0; }
실행 결과
2
먼저 enum 키워드 뒤에 열거형 이름을 지정해주고 { } (중괄호) 안에 값을 나열합니다. 여기서 각 값들은 , (콤마)로 구분하며 = (할당 연산자)를 사용하여 값을 할당할 수 있습니다. 마지막으로 열거형을 정의할 때 } (닫는 중괄호) 뒤에는 반드시 ; (세미콜론)을 붙여줍니다.
enum DayOfWeek { // 열거형 정의 Sunday = 0, // 초깃값 할당 Monday, Tuesday, Wednesday, Thursday, Friday, Saturday };
열거형의 값은 처음에만 할당해주면 그 아래에 오는 값들은 1씩 증가하면서 자동으로 할당됩니다(아무 값도 할당하지 않으면 0부터 시작). 따라서 처음에 오는 Sunday에 0을 할당하면 Monday는 1, Tuesday는 2, Wednesday는 3이 됩니다.
문법으로 정해진 규칙은 아니지만 열거형 이름이나 값을 정의할 때 대문자만 사용하는 경우가 많습니다. 특히 단어와 단어 사이에는 _을 주로 사용합니다. 다음은 리눅스 커널의 hdmi.h 헤더 파일에 정의된 열거형인데 열거형 이름은 모두 소문자지만 열거형 값이 모두 대문자입니다.
/include/linux/hdmi.h
enum hdmi_content_type { HDMI_CONTENT_TYPE_GRAPHICS, HDMI_CONTENT_TYPE_PHOTO, HDMI_CONTENT_TYPE_CINEMA, HDMI_CONTENT_TYPE_GAME, };
다음은 Windows 커널의 winddk.h 헤더 파일에 정의된 열거형입니다. 여기서는 열거형 이름이 모두 대문자이고 열거형 값은 단어의 첫 글자만 대문자로 되어 있습니다.
winddk.h
typedef enum _POOL_TYPE { NonPagedPool, PagedPool, NonPagedPoolMustSucceed, DontUseThisType, NonPagedPoolCacheAligned // ... 생략 ... } POOL_TYPE;
이처럼 같은 C 언어 소스 코드라 하더라도 운영체제, 회사, 단체에 따라 스타일이 제각각입니다. 그래서 소스 코드를 작성할 때는 해당 환경에서 사용하는 스타일에 맞춰주는 것이 좋습니다. 이 책에서는 다양한 열거형 스타일을 눈에 익힐 수 있도록 여러 가지 스타일로 열거형을 표현하겠습니다.
정의한 열거형을 사용하려면 열거형 변수를 선언해야 합니다. 이때는 열거형 이름 앞에 반드시 enum 키워드를 붙여줍니다. 다음은 DayOfWeek 열거형 타입의 변수 week를 선언한다는 뜻입니다.
enum DayOfWeek week; // 열거형 변수 선언
보통 열거형 변수에는 미리 정의한 열거형 값을 넣습니다. 열거형 값 대신 정수를 할당해도 상관 없지만 정의하지 않은 열거형 값은 넣을 수 없습니다.
week = Tuesday; // 열거형 값 할당
printf로 week의 값을 출력해보면 Tuesday의 값인 2가 나옵니다.
printf("%d\n", week); // 2: Tuesday의 값 출력
보통 열거형을 정의할 때 처음에 오는 값에만 초깃값을 할당하지만 다음과 같이 모든 값에 정수를 할당할 수 있습니다.
enum Value { ValueA = 1, ValueB = 3, ValueC = 7, ValueD = 11 };
연속되지 않은 불규칙한 값을 사용하려면 모든 열거형 값에 정수를 할당하면 됩니다.
열거형도 typedef로 별칭을 지정하고, 익명 열거형을 정의할 수 있습니다.
먼저 열거형 별칭은 다음과 같이 정의합니다.
typedef enum 열거형이름 { 값1 = 초깃값, 값2, 값3 } 열거형별칭;
typedef_enum.c
typedef enum _DayOfWeek { // 열거형 이름은 _DayOfWeek Sunday = 0, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday } DayOfWeek; // typedef를 사용하여 열거형 별칭을 DayOfWeek로 정의
typedef로 열거형의 별칭을 만들었다면 변수는 다음과 같이 선언합니다.
- 열거형별칭 변수이름;
익명 열거형은 다음과 같이 정의합니다.
typedef enum { 값1 = 초깃값, 값2, 값3 } 열거형별칭;
변수는 열거형 별칭으로 선언하면 됩니다.
- 열거형별칭 변수이름;
typedef_anonymous_enum.c
typedef enum { // 익명 열거형 정의 Sunday = 0, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday } DayOfWeek; // typedef를 사용하여 열거형 별칭을 DayOfWeek로 정의 DayOfWeek week; // 열거형 별칭으로 공용체 변수 선언
다음과 같이 열거형은 정의하는 동시에 변수를 선언할 수 있습니다.
enum 열거형이름 { 자료형 멤버이름; } 변수;
예)
enum_variable.c
enum DayOfWeek { // 열거형 정의 Sunday = 0, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday } week; // 열거형을 정의하는 동시에 변수 week 선언