문제

C/C ++에서 정의 명령문과 열거 문을 사용하는 것의 차이점은 무엇입니까 (C 또는 C ++로 사용할 때 차이가 있습니까)?

예를 들어, 언제 사용해야합니다

enum {BUFFER = 1234}; 

~ 위에

#define BUFFER 1234   
도움이 되었습니까?

해결책

enum 구문 요소를 정의합니다.

#define 사전 예비 프로세서 지침입니다 ~ 전에 컴파일러는 코드를보고 C 자체의 언어 요소가 아닙니다.

일반적으로 열거는 유형-안전하고 더 쉽게 발견 할 수 있으므로 선호됩니다. 정의는 찾기가 더 어렵고 복잡한 동작을 가질 수 있습니다. 예를 들어 한 조각의 코드는 #define 다른 사람에 의해 만들어졌습니다. 이것은 추적하기 어려울 수 있습니다.

다른 팁

#define 컴파일러가 코드를보고 기본적으로 텍스트 대체가되기 전에 사전 프로세서가 진술을 처리합니다 (실제로 매개 변수의 사용에 대해 조금 더 지능적).

열거는 C 언어 자체의 일부이며 다음과 같은 장점이 있습니다.

1/ 유형이있을 수 있으며 컴파일러는 유형을 확인할 수 있습니다.

2/ 컴파일러가 사용할 수 있으므로 디버거로 전달할 수있어 디버깅이 더 쉬워집니다.

Define은 전처리 명령입니다. 편집기에서 "모두 교체"를 수행하는 것과 같습니다. 문자열을 다른 문자열로 교체 한 다음 결과를 컴파일 할 수 있습니다.

ENUM은 예를 들어 다음과 같은 특수한 유형의 경우입니다.

enum ERROR_TYPES
{
   REGULAR_ERR =1,
   OK =0
}

error_types라는 새로운 유형이 있습니다. 일반 _err가 1로 생성하지만이 유형에서 int로 캐스팅하면 캐스팅 경고를 생성해야합니다 (컴파일러를 높은 구동성으로 구성하는 경우).

요약 : 그것들은 모두 비슷하지만, Enum을 사용할 때는 유형 확인을 이익하고 정의하면 코드 문자열을 교체하는 것이 좋습니다.

열거는 일반적으로 열거를 사용하는 것이 합리적이든 #define보다 일반적으로 선호됩니다.

  • 디버거는 당신에게 당신에게 상징적 인 이름을 보여줄 수 있습니다 enums 값 ( "openType: OpenExisting", 대신"openType: 2"
  • 당신은 이름 충돌로부터 조금 더 많은 보호를 얻지 만, 이것은 그다지 나쁘지 않습니다 (대부분의 컴파일러는 Re에 대해 경고합니다.#defineITION.

가장 큰 차이점은 열거를 유형으로 사용할 수 있다는 것입니다.

// Yeah, dumb example
enum OpenType {
    OpenExisting,
    OpenOrCreate,
    Truncate
};

void OpenFile(const char* filename, OpenType openType, int bufferSize);

이렇게하면 매개 변수 유형 확인을 제공합니다 (OpenType와 Buffersize를 쉽게 혼합 할 수 없음). 유효한 값을 쉽게 찾을 수있어 인터페이스를 훨씬 쉽게 사용할 수 있습니다. 일부 IDE는 심지어 당신을 줄 수도 있습니다 지적 코드 완료!

가능하면 항상 열거를 사용하는 것이 좋습니다. 열거를 사용하면 컴파일러에 소스 코드에 대한 자세한 정보가 제공되며, 전처리 정의는 컴파일러가 절대로 보지 않으므로 정보가 적습니다.

예를 들어 많은 모드를 구현하려면 열거를 사용하여 컴파일러가 누락 될 수 있습니다. case-예를 들어 스위치의 진료소.

열거는 한 범주로 여러 요소를 그룹화 할 수 있습니다.

enum fruits{ apple=1234, orange=12345};

#define은 관련없는 상수 만 생성 할 수 있습니다.

#define apple 1234
#define orange 12345

#define은 전처리 명령이며, Enum은 C 또는 C ++ 언어입니다.

이런 종류의 경우에 #Define 이상의 열거를 사용하는 것이 항상 좋습니다. 한 가지는 타입 안전입니다. 또 다른 하나는 일련의 값이 있으면 열거에서 시퀀스의 시작 만 제공하면 다른 값은 연속 값을 얻는다는 것입니다.

enum {
  ONE = 1,
  TWO,
  THREE,
  FOUR
};

대신에

#define ONE 1
#define TWO 2
#define THREE 3
#define FOUR 4

부수적으로, #Define을 사용해야 할 경우가 여전히 남아 있습니다 (일반적으로 상수를 포함하는 식별자를 구성 할 수 있어야하는 경우 어떤 종류의 매크로의 경우), 그것은 일종의 거대 흑 마법입니다. 그리고가는 길은 매우 드 rare니다. 이 사지로 가면 C ++ 템플릿을 사용해야하지만 C에 갇힌 경우).

이 단일 상수 만 원한다면 (버퍼 크기를 위해) 열거를 사용하지 않고 정의를 사용합니다. 리턴 값 (다른 오류 조건을 의미)과 같은 물건에 열거를 사용하고 다른 "유형"또는 "케이스"를 구별 해야하는 곳이라면 어디에나 있습니다. 이 경우 열거를 사용하여 기능 프로토 타입 등에서 사용할 수있는 새로운 유형을 만들 수 있으며 컴파일러는 해당 코드를 더 잘 확인할 수 있습니다.

이미 쓰여진 모든 것 외에, 한 사람은 말했지만 보여주지 않았으며 흥미 롭습니다. 예를 들어

enum action { DO_JUMP, DO_TURNL, DO_TURNR, DO_STOP };
//...
void do_action( enum action anAction, info_t x );

액션을 유형으로 고려하면 더 명확 해집니다. Define을 사용하여 작성했을 것입니다

void do_action(int anAction, info_t x);

내가 선호하는 통합 상수 값을 위해 enum ~ 위에 #define. 사용하는 데 단점이없는 것 같습니다 enum (조금 더 타이핑의 작은 단점을 할인) 그러나 당신은 이점이 있습니다. enum 경계 할 수 있습니다 #define 식별자는 모든 것을 tromp하는 글로벌 범위를 가지고 있습니다.

사용 #define 일반적으로 문제는 아니지만 단점이 없기 때문에 enum, 나는 그것과 함께 간다.

C ++에서 나는 또한 일반적으로 선호합니다 enum 에게 const int C ++에도 불구하고 const int 문자 그대로의 정수 값 대신 (C와 달리) 대신 사용할 수 있습니다. enum C로 휴대 할 수 있습니다 (여전히 많이 작동합니다).

상수 그룹이있는 경우 ( "요일"과 같은) 열거가 바람직 할 것입니다. 왜냐하면 그것이 그룹화되었음을 보여주기 때문입니다. 그리고 Jason이 말했듯이, 그들은 유형-안전합니다. 그것이 글로벌 상수라면 (버전 번호와 같은), 그것은 당신이 사용하는 것입니다. #define 을 위한; 이것은 많은 논쟁의 주제이지만.

위에 나열된 좋은 점 외에도 열거 범위를 클래스, 구조 또는 네임 스페이스로 제한 할 수 있습니다. 개인적으로, 나는 한 번에 한 번에 최소 관련 기호를 범위에두고 싶습니다. #defines보다는 열거를 사용하는 또 다른 이유입니다.

정의 목록에 대한 열거의 또 다른 장점은 모든 값이 스위치 문에서 모든 값을 확인하지 않을 때 컴파일러 (최소한 GCC)가 경고를 생성 할 수 있다는 것입니다. 예를 들어:

enum {
    STATE_ONE,
    STATE_TWO,
    STATE_THREE
};

...

switch (state) {
case STATE_ONE:
    handle_state_one();
    break;
case STATE_TWO:
    handle_state_two();
    break;
};

이전 코드에서 컴파일러는 열거의 모든 값이 스위치에서 처리되지는 않는다는 경고를 생성 할 수 있습니다. 국가가 #Define 's로 수행 된 경우 그렇지 않습니다.

열거는 일주일에 며칠과 같이 어떤 종류의 세트를 열거하는 데 더 많이 사용됩니다. 상수 숫자가 하나만 필요한 경우 const int (또는 이중 등)는 Enum보다 확실히 더 좋습니다. 나는 개인적으로 마음에 들지 않습니다 #define (적어도 일부 상수의 정의에 대한 것은 아닙니다) 그것은 나에게 유형의 안전을 제공하지 않기 때문에, 물론 당신에게 더 잘 맞는다면 그것을 사용할 수 있습니다.

열거를 생성하면 리터럴뿐만 아니라 이러한 리터럴을 그룹화하는 유형도 생성합니다. 이것은 컴파일러가 확인할 수있는 코드에 시맨틱을 추가합니다.

또한 디버거를 사용할 때는 열거 리터럴 값에 액세스 할 수 있습니다. #Define의 경우 항상 그런 것은 아닙니다.

위의 몇 가지 답변은 여러 가지 이유로 열거를 사용하는 것이 좋습니다. 정의를 사용하는 것이 인터페이스를 개발할 때 실제 이점이 있다고 지적하고 싶습니다. 새로운 옵션을 도입 할 수 있으며 소프트웨어가 조건부로 사용하도록 할 수 있습니다.

예를 들어:

    #define OPT_X1 1 /* introduced in version 1 */
    #define OPT_X2 2 /* introduced in version  2 */

그런 다음 수행 할 수있는 버전으로 컴파일 할 수있는 소프트웨어

    #ifdef OPT_X2
    int flags = OPT_X2;
    #else
    int flags = 0;
    #endif

열거 된 경우 런타임 기능 탐지 메커니즘 없이는 불가능합니다.

열거 :

1. 일반적으로 여러 값에 사용됩니다

2. ENUM에는 이름이 있고 다른 하나는 이름의 값이라는 이름의 값이 하나 있지만 값은 동일 할 수 있습니다. 값을 정의하지 않으면 값을 정의하지 않으면 열거 값의 첫 번째 값은 0입니다. 지정됩니다.

3. 유형이있을 수 있고 컴파일러가 입력 할 수 있습니다.

4. 디버깅을 쉽게 만드십시오

5. 우리는 그것의 범위를 클래스로 제한 할 수 있습니다.

정의하다:

1. 우리가 하나의 값 만 정의해야 할 때

2. 일반적으로 하나의 문자열을 다른 문자열로 바꿉니다.

3. 범위는 글로벌입니다. 우리는 그 범위를 제한 할 수 없습니다

전반적으로 우리는 Enum을 사용해야합니다

차이는 거의 없습니다. C 표준에 따르면 열거는 적분 유형을 가지며 열거 상수는 INT 유형이므로 오류없이 다른 적분 유형과 자유롭게 혼합 될 수 있습니다. (반면에, 그러한 혼합이 명백한 캐스트없이 허용되지 않았다면, 열거를 신중하게 사용하여 특정 프로그래밍 오류를 잡을 수 있습니다.)

열거의 일부 장점은 숫자 값이 자동으로 할당되고, 디버거가 열거 변수를 검사 할 때 기호 값을 표시 할 수 있고 블록 범위를 준수해야한다는 것입니다. (컴파일러는 또한 열거가 무차별 적으로 혼합 될 때 비 치명적 인 경고를 생성 할 수 있습니다. 왜냐하면 그렇게하는 것은 엄격하게 불법적이지 않더라도 여전히 나쁜 스타일로 간주 될 수 있기 때문입니다.) 단점은 프로그래머가 비 의무적 인 경고를 거의 제어 할 수 없다는 것입니다. 일부 프로그래머는 또한 열거 변수의 크기를 제어 할 수없는 것을 원망했습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top