HOWTO · C

C에서 typedef enum을 사용하는 방법

이 기사에서는 C에서 typedef enum을 사용하는 방법을 소개하고, 그 이점을 설명하며, 명확한 예를 제공합니다. typedef enum으로 코드 가독성과 유지보수성을 높이는 방법을 배우고, struct에서 사용하는 방법도 알아보세요. 초보자든 기술을 다듬고자 하는 분이든, 이 가이드를 통해 C의 enum을 쉽게 다룰 수 있습니다.

이 페이지의 내용

C에서 enum은 이름이 지정된 정수 상수를 선언하며, typedef는 enum 형식에 더 짧은 이름을 부여할 수 있습니다. 이름을 사용하면 상태 값과 옵션 값을 더 쉽게 읽을 수 있으며, 입력이나 저장된 데이터가 프로그램 외부에서 올 수 있는 곳에서는 해당 값을 명시적으로 처리하세요. enum은 명확성을 높여 주지만, 변수에 할당되는 모든 값을 자동으로 검증하지는 않습니다.

enum 정의하고 값 할당하기

명시적인 값이 없는 열거자는 0부터 시작합니다. 뒤따르는 각 열거자는 이전 값보다 1씩 큽니다. 예를 들어, enum { MONDAY, TUESDAY, WEDNESDAY };는 0, 1, 2를 할당합니다. 기존 형식, 프로토콜 또는 안정적인 코드 집합과 일치해야 하는 경우 값을 명시적으로 할당할 수 있습니다: enum Status { STATUS_READY = 1, STATUS_RUNNING = 4, STATUS_DONE = 8 };. 명시적인 값 다음에 오는 암시적 값은 해당 값보다 1 큽니다.

STATUS_READY와 같은 이름은 정수 상수입니다. 변수가 아닙니다. enum 변수에는 나중에 다른 값을 할당할 수 있으며, C는 일반적으로 해당 선언에 나열된 열거자로만 제한하지 않습니다. 입력, 파일 또는 기타 외부 소스에서 온 값은 사용하기 전에 확인이 필요한 데이터로 취급하세요.

enum에 대한 typedef 별칭 만들기

enum 태그와 typedef 별칭은 관련이 있지만 서로 다른 이름입니다. enum State { ... };를 사용하면 선언에서 enum State를 사용합니다. typedef는 더 짧은 별칭 State를 도입하여 State current;와 같은 선언을 허용할 수 있습니다. 별칭은 동일한 형식을 나타냅니다. typedef는 별개의 형식을 만들지 않습니다. 결합된 표기 typedef enum State { ... } State;는 태그와 별칭을 함께 선언합니다.

이 예제는 정수를 입력하도록 요청하고, 읽기가 성공했는지 확인하며, 값을 State로 변환하여 Job 필드에 저장하기 전에 검증합니다. 성공 경로를 보려면 2를 입력하세요. 프로그램은 프롬프트와 에코된 값을 같은 줄에 출력한 다음, switch가 Running을 출력합니다. 읽기에 실패하거나 숫자가 지원되는 세 가지 상태 범위를 벗어나면, 프로그램은 메시지를 출력하고 변환 전에 중단됩니다.

#include <stdio.h>

typedef enum State {
    STATE_READY = 1,
    STATE_RUNNING = 2,
    STATE_DONE = 3
} State;

typedef struct Job {
    State state;
} Job;

int main(void) {
    int input;
    printf("Input: ");
    if (scanf("%d", &input) != 1) {
        puts("Could not read an integer.");
        return 0;
    }
    printf("%d\n", input);

    if (input != STATE_READY && input != STATE_RUNNING && input != STATE_DONE) {
        puts("Unsupported state.");
        return 0;
    }

    Job job = { (State)input };
    switch (job.state) {
        case STATE_READY:
            puts("Ready");
            break;
        case STATE_RUNNING:
            puts("Running");
            break;
        case STATE_DONE:
            puts("Done");
            break;
        default:
            puts("Unsupported state.");
            break;
    }

    return 0;
}
Input: Could not read an integer.

struct에서 enum 형식 사용하기

위의 Job struct는 상태를 State 필드에 저장합니다. 이렇게 하면 상태가 job을 설명하는 다른 데이터 옆에 유지되며, enum 상수 덕분에 할당과 switch 사례를 읽기 쉬워집니다. typedef 별칭을 정의하지 않기로 한 경우, 필드를 태그를 사용하여 enum State state;로 선언할 수도 있습니다.

struct는 필드에 검증을 추가하지 않습니다. 값이 지원되지 않는 숫자를 제공할 수 있는 소스에서 온 경우, 이를 신뢰하기 전에 확인하세요. default 분기는 저장된 값이 이름이 지정된 상태 중 어느 것과도 일치하지 않을 때 프로그램에 정의된 응답을 제공합니다. 특정 애플리케이션에 더 엄격한 보장이 필요한 경우, 값이 프로그램에 들어오는 경계에서 검증하고 해당 검사를 할당 가까이에 두세요.

enum 값 선택하고 안전하게 사용하기

상수가 내부 레이블이고 숫자 표현이 중요하지 않은 경우 암시적 값을 사용하세요. 다른 인터페이스에서 특정 숫자가 필요한 경우 값을 명시적으로 할당하고, 데이터가 저장되거나 교환되는 경우 해당 할당을 안정적으로 유지하세요. 어느 경우든 이름이 지정된 상수는 설명 없는 정수 리터럴보다 의도를 더 잘 전달하며, 유지보수 담당자가 사용 가능한 레이블을 볼 수 있는 한 곳을 제공합니다.

이러한 이점 때문에 enum 변수가 읽기 전용이 되거나 이름이 지정된 열거자만 포함한다는 보장은 없습니다. 변수는 실행 중에 변경될 수 있으며, 캐스트나 외부 입력으로 인해 대응하는 이름이 없는 값이 생성될 수 있습니다. default 분기가 있는 switch를 사용하거나, 값을 처리하기 전에 허용되는 열거자와 대조하여 검증하세요. 이렇게 하면 예상치 못한 데이터가 알려진 상태를 위한 경로를 조용히 따라가는 것을 방지할 수 있습니다.

요약하면, 이름이 지정된 상수를 위해 enum을 선언하고, 선언을 더 명확하게 만들 때는 typedef 별칭을 추가하며, struct 필드와 함수 매개변수를 포함하여 상태가 속하는 모든 곳에서 결과 형식을 사용하세요. 명시적인 숫자 값은 숫자가 요구사항의 일부인 경우에만 선택하고, 검증은 enum이 제공하는 이름 지정 편의성과 분리하여 유지하세요.