[c] C에서 열거 형 (enum)을 정의하는 방법은 무엇입니까?

C 열거 형을 사용하기위한 올바른 구문이 무엇인지 잘 모르겠습니다. 다음 코드가 있습니다.

enum {RANDOM, IMMEDIATE, SEARCH} strategy;
strategy = IMMEDIATE;

그러나 이것은 다음 오류와 함께 컴파일되지 않습니다.

error: conflicting types for strategy
error: previous declaration of strategy was here

내가 뭘 잘못하고 있죠?



답변

열거 형 변수 선언은 다음과 같이 수행됩니다.

enum strategy {RANDOM, IMMEDIATE, SEARCH};
enum strategy my_strategy = IMMEDIATE;

그러나 a typedef를 사용하여 다음과 같이 변수 선언을 줄일 수 있습니다 .

typedef enum {RANDOM, IMMEDIATE, SEARCH} strategy;
strategy my_strategy = IMMEDIATE;

유형과 변수를 구별하기위한 명명 규칙을 갖는 것이 좋습니다.

typedef enum {RANDOM, IMMEDIATE, SEARCH} strategy_type;
strategy_type my_strategy = IMMEDIATE;


답변

필요 하지 않음을 지적 할 가치 있습니다 typedef. 다음과 같이하면됩니다.

enum strategy { RANDOM, IMMEDIATE, SEARCH };
enum strategy my_strategy = IMMEDIATE;

당신이 선호하는지 여부는 스타일 질문 typedef입니다. 이것이 없으면 열거 유형을 참조하려면을 사용해야 enum strategy합니다. 그것으로, 당신은 말할 수 있습니다strategy .

두 가지 방법 모두 장단점이 있습니다. 하나는 더 장황하지만 유형 식별자를 일반 식별자와 충돌하지 않는 태그 네임 스페이스에 유지합니다 (생각 struct statstat기능 : 충돌하지 않음). 다른 하나는 짧지 만 형식 식별자를 일반 네임 스페이스로 가져옵니다.


답변

strategy두 번 선언하려고 하면 위의 오류가 발생합니다. 다음은 불만없이 작동합니다 (로 컴파일 됨 gcc -ansi -pendantic -Wall).

#include <stdio.h>

enum { RANDOM, IMMEDIATE, SEARCH } strategy = IMMEDIATE;

int main(int argc, char** argv){
    printf("strategy: %d\n", strategy);

    return 0;
}

위의 경우 대신 두 번째 줄이 다음과 같이 변경되었습니다.

...
enum { RANDOM, IMMEDIATE, SEARCH } strategy;
strategy = IMMEDIATE;
...

경고에서 실수를 쉽게 볼 수 있습니다.

enums.c:5:1: warning: data definition has no type or storage class [enabled by default]
enums.c:5:1: warning: type defaults to int in declaration of strategy [-Wimplicit-int]
enums.c:5:1: error: conflicting types for strategy
enums.c:4:36: note: previous declaration of strategy was here

그래서 컴파일러는 기본 유형으로 strategy = IMMEDIATE불리는 변수의 선언을 취 했습니다.strategyint 했지만 이미이 이름을 가진 변수가 이미 선언되었습니다.

그러나 과제를 main() 함수에 유효한 코드가됩니다.

#include <stdio.h>

enum { RANDOM, IMMEDIATE, SEARCH } strategy = IMMEDIATE;

int main(int argc, char** argv){
    strategy=SEARCH;
    printf("strategy: %d\n", strategy);

    return 0;
}


답변

당신이 말할 때

enum {RANDOM, IMMEDIATE, SEARCH} strategy;

이름없는 열거 형의 ‘strategy’라는 단일 인스턴스 변수를 만듭니다. 이것은 매우 유용한 일이 아닙니다. typedef가 필요합니다.

typedef enum {RANDOM, IMMEDIATE, SEARCH} StrategyType;
StrategyType strategy = IMMEDIATE;


답변

작성된 바와 같이 코드에는 아무런 문제가 없습니다. 다음과 같은 일을하지 않았습니까?

int strategy;
...
enum {RANDOM, IMMEDIATE, SEARCH} strategy;

오류 메시지는 어떤 줄을 가리 킵니까? “이전의 ‘전략’선언이 여기에 있었다”고 할 때 “여기”란 무엇이며 무엇을 보여줍니까?


답변

질문에 대한 그의 의견에 @ThoAppelsin이 올바르다. 질문에 게시 된 코드 스 니펫은 유효하며 오류가 없습니다. c 소스 파일의 다른 위치에 다른 잘못된 구문이 있기 때문에 오류가 발생했습니다. enum{a,b,c};세 개의 기호 상수 (정의 a, b그리고 c값의 정수) 0, 1그리고 2각각을하지만, 우리가 사용할 때 enum우리가 일반적으로 특정 정수 값에 대해 걱정하지 않는다 때문에 우리는 기호 상수 이름의 의미에 대해 더 걱정이다. 이것은 당신이 이것을 가질 수 있음을 의미합니다 :

#include <stdio.h>
enum {a,b,c};
int main(){
  printf("%d\n",b);
  return 0;
}

그리고이 출력 1됩니다.

이것도 유효합니다 :

#include <stdio.h>
enum {a,b,c};
int bb=b;
int main(){
  printf("%d\n",bb);
  return 0;
}

이전과 동일하게 출력됩니다.

이렇게하면 :

enum {a,b,c};
enum {a,b,c};

오류가 발생하지만 이렇게하면 :

enum alfa{a,b,c};
enum alfa;

오류가 없습니다.

당신은 이것을 할 수 있습니다 :

enum {a,b,c};
int aa=a;

aa값을 갖는 정수 변수가 될 것이다 0. 그러나 당신은 또한 이것을 할 수 있습니다 :

enum {a,b,c} aa= a;

및 (인 동일한 효과를 가질 것이다 aa존재 int0값).

당신은 또한 이것을 할 수 있습니다 :

enum {a,b,c} aa= a;
aa= 7;

그리고 가치 aa가있을 것이다 .int7

enum앞에서 언급했듯이를 사용하여 기호 상수 정의를 반복 할 수 없기 때문에 다음을 사용 하여 intvars 를 선언하려면 태그를 사용해야합니다 enum.

enum tag1 {a,b,c};
enum tag1 var1= a;
enum tag1 var2= b;

이를 사용 typedef하면 enum tag1변수를 정의 할 때마다 글을 쓰지 않아도됩니다. 로에게 typedef당신은 입력 할 수 있습니다 Tag1:

typedef enum {a,b,c} Tag1;
Tag1 var1= a;
Tag1 var2= b;

당신은 또한 가질 수 있습니다 :

typedef enum tag1{a,b,c}Tag1;
Tag1 var1= a;
enum tag1 var2= b;

마지막으로 정의 된 기호 상수에 대해 이야기하고 있기 때문에를 사용할 때 대문자를 사용하는 것이 좋습니다 enum. 예를 들면 다음과 같습니다.

enum {A,B,C};

대신에

enum {a,b,c};


답변

언급 할 그것의 가치가 C에서 + + 당신은 타입 정의 문을 필요없이 새로운 유형을 정의하는 “열거”를 사용할 수 있습니다.

enum Strategy {RANDOM, IMMEDIATE, SEARCH};
...
Strategy myStrategy = IMMEDIATE;

이 접근법이 훨씬 더 친숙하다는 것을 알았습니다.

[편집-명확한 C ++ 상태-나는 이것을 원래 가지고 있었고 그것을 제거했다!]