2009-02-05 21 views
5

나는 ++ 쉽게 언제 typedef가 필요하지 않습니까?

enum eEnum { c1, c2 }; 
struct MyStruct { int i; double d; }; 

이 있다는 사실인가요 쓸 수

typedef enum eEnum { c1, c2 } tagEnum; 

typedef struct { int i; double d; } tagMyStruct; 

나는 이러한 구조는 C에서 C.에서 데이트 소문을 듣고 읽는 몇 가지 코드를 발생? 첫 번째 변종은 언제 필요합니까?

답변

10

먼저 두 선언은 C 및 C++에서 모두 유효합니다. 그러나 C에서는 약간 다른 의미가 있습니다. (특히 구조체를 참조하는 방식은 나중에 다릅니다.)

이해해야 할 핵심 개념은 C에서 구조체가 별도의 네임 스페이스에 존재한다는 것입니다. typedef는 물론 모든 기본 제공 유형이 "기본"네임 스페이스에 있습니다. 즉, int을 입력하면 컴파일러는이 "기본"네임 스페이스 만 확인합니다. 귀하의 예제에서 "tagMyStruct"를 입력하면 컴파일러는이 하나의 네임 스페이스 만 검사합니다. 그러나 어떤 유형의 선언을 사용 하느냐에 따라 구조체가 해당 네임 스페이스에 존재하지 않을 수 있습니다.

구조체가 다르며 별도의 네임 스페이스에 있습니다. 그래서 나는 다음과 같은 선언을 할 경우 :

struct mystruct {}; 

내가 하지 단순히 MYSTRUCT로 참조 할 수 있습니다.장기적으로 조금 자세한 어색 얻을 수

void foo(struct mystruct bar); // Declare a function which takes a mystruct as its parameter 

대신, 나는 구조체 네임 스페이스에 존재하는 MYSTRUCT을 원하는 지정해야합니다.

typedef struct mystruct mystruct; // From now on, 'mystruct' in the normal namespace is an alias for 'mystruct' in the struct namespace 

지금, 내 기능은 간단한 방법으로 선언 할 수 있습니다 :

void foo(mystruct bar); 

그래서 첫 번째 예는 단순히이 두 단계를 함께 병합 대신, 기본 네임 스페이스로를 형식 정의를 할 수 선언 구조체를 만들고, 일반 네임 스페이스에 별칭을 추가합니다. 그리고 물론, 우리는 어쨌든 그것을 typedeffing하기 때문에, 우리는 구조체를 익명으로 만들 수 있도록 "원래"이름이 필요하지 않습니다. 그래서 선언

typedef struct { int i; double d; } tagMyStruct; 

후 우리는 기본 네임 스페이스에 'tagMyStruct'에 형식 정의 된 어떤 이름을 가진 구조체를 가지고있다.

이것이 C가 처리하는 방법입니다. 두 가지 유형의 선언이 모두 유효하지만 "기본"네임 스페이스에 별칭을 만들지 않으므로 유형을 참조 할 때마다 struct 키워드를 사용해야합니다.

C++에서는 별도의 구조체 네임 스페이스가 없으므로 같은 의미입니다. (그러나 더 짧은 버전이 선호됩니다).

편집 C는 네임 스페이스가 없습니다. 보통 의미는 아닙니다. C는 미리 정의 된 두 개의 네임 스페이스 중 하나에 식별자를 저장합니다. 구조체 (및 열거 형)의 이름은 하나에 배치되고 다른 모든 식별자는 다른 구조체에 배치됩니다. 엄밀히 말하자면 이름 공간은 충돌을 피하기 위해 이름이 배치 된 별도의 "컨테이너"이기 때문에 이름 공간이지만 C++/C#의 의미에서 네임 스페이스가 아닙니다.

+0

멋진 설명 – Eclipse

+0

그래서 C _does_는 네임 스페이스를 가지고 있습니다! :) 고마워, 그 많은 것들을 명확히. – xtofl

+0

xtofl : 아니,별로. C++의 의미는 아닙니다. 구조체와 기본 제공 형식은 별도의 네임 스페이스에 있지만 그 이상의 경우에는 없습니다. 새로운 네임 스페이스를 선언 할 수도없고, 다른 어떤 것도 기대할 수 없습니다. 그래서 이것은 약간 특별한 경우입니다. "C가 네임 스페이스"를 가지고 있다고 생각하는 것은 나쁜 생각 일 것입니다.) – jalf

1

그냥 축약 형입니다. 두 번째 인스턴스에서

, 그래서 당신이 할 거라고 구조체를 선언 : 또한

tagMyStruct a; 
+0

C의 약식입니다. 또는 C++ 만 참조합니까? – xtofl

0

두 번째 변형 : 첫 번째 변형에서

struct MyStruct a; 

, 당신이 그렇게 할 것

tagEnum myFunc(tagMyStruct * myArg); 
0 : 당신은 예를 들어, 당신의 유형을, 이름을 지정할 때마다

당신은 첫 번째 변종을 사용 C.에 존재
0

첫 번째 것은 C++에서 불편할 수 있습니다. 헤더 파일에서 선언 할 수 없으므로 불편할 수 있습니다. C에서

10

, 해당 유형을 참조하고 싶어 할 때마다

struct MyStruct { int i; double d; }; 

를 작성한다면, 당신은 당신이 구조체에 대해 얘기했다 지정해야 할 것 다음으로

struct MyStruct instanceOfMyStruct; 
struct MyStruct *ptrToMyStruct; 

타입 정의 버전 :

typedef struct { int i; double d; } tagMyStruct; 

만 작성해야합니다 :

tagMyStruct instanceOfMyStruct; 
tagMyStruct *ptrToMyStruct; 

typedef'd 버전의 다른 큰 이점은 C 및 C++에서 구조체를 동일한 방식으로 참조 할 수 있다는 것입니다. 반면 두 번째 버전에서는 C++보다 C에서 다르게 언급됩니다.

+0

은 "작성해야만"버전이 "tagMyStruct ..."가됩니다. "iso"MyStruct "? 아니면이게 맞습니까? (반 직관적 인 ...) – xtofl

관련 문제