typedef 골대 골 정의 [중복]
이 질문에 이미 답변이 있습니다.
저는 C 프로그래밍의 궁금하지만 typedef
구조를 정의 할 때 사용 하는 것과 사용하지 않는 것의 차이점이 무엇인지 않습니다 typedef
. 정말 차이가없는 것 같고 같은 목표를 달성합니다.
struct myStruct{
int one;
int two;
};
대
typedef struct{
int one;
int two;
}myStruct;
일반적인 관용구는 다음 두 가지를 모두 사용합니다.
typedef struct X {
int x;
} X;
그들은 서로 다른 정의입니다. 토론을 더 명확하게하기 위해 문장을 분할하겠습니다.
struct S {
int x;
};
typedef struct S S;
첫 번째 줄 S
에서는 내 에서 식별자를 정의합니다 (C ++ 의미가 아님). 이를 사용하고 인수 유형을 다음과 같이 정의하여 새로 정의 된 유형의 변수 또는 함수 인수를 정의 할 수 있습니다 struct S
.
void f( struct S argument ); // struct is required here
두 번째 줄 S
은 전역 이름 공간에 유형 을 추가 할 수있는 다음과 같이 사용할 수 있습니다.
void f( S argument ); // struct keyword no longer needed
식별자 이름 공간 두이 다르기 S
때문에 동일한 식별자를 재정의하는 것이 아니라 다른 위치에 다른 식별자를 만드는 것이기 때문에 구조체와 전역 공간에서 모두 정의하는 [해석] 오류가 아닙니다.
차이를 더 명확하게 비용 :
typedef struct S {
int x;
} T;
void S() { } // correct
//void T() {} // error: symbol T already defined as an alias to 'struct S'
식별자가 다른 공간에 보관할 때와 같은 이름으로 함수를 정의 할 때와 같은 typedef
식별자가 충돌 할 수 없습니다 .
C ++에서는 기호를 찾는 규칙이 미묘하게 변경 되었기 때문에 변경되었습니다. C ++는 여전히 두 개의 다른 식별자 공간을 유지하지만 C에서와 달리 클래스 식별자 공간 내에서만 정의 할 때 struct / class 키워드를 제공 할 필요가 없습니다.
// C++
struct S {
int x;
}; // S defined as a class
void f( S a ); // correct: struct is optional
식별자가 정의 된 위치가 아니라 검색 규칙이 어떻게 변경됩니다. 컴파일러는 전역 식별자 테이블을 검색하고 S
찾지 못한 후에 는 S
클래스 식별자 내 검색합니다 .
이전에 제시된 코드는 동일한 방식으로 작동합니다.
typedef struct S {
int x;
} T;
void S() {} // correct [*]
//void T() {} // error: symbol T already defined as an alias to 'struct S'
S
두 번째 줄 함수를 정의한 후에는 S는 컴파일러에 의해 자동으로 해석 될 수있는 인수를 자동으로 생성하거나 해당 유형의 인수를 정의한 결과 struct
키워드 를 포함하여 대체 해야합니다 .
// previous code here...
int main() {
S();
struct S s;
}
struct
와 typedef
매우 다른 두 가지 있습니다.
struct
키워드는 정의, 또는 구조 유형을 참조하는 데 사용됩니다. 예를 들면 다음과 같습니다.
struct foo {
int n;
};
라는 새 유형을 만듭니다 struct foo
. 이름 foo
은 태그입니다 . struct
태그와 기타 식별자가 고유 한 네임 스페이스 에 있기 때문에 키워드 바로 앞에 오는 경우에만 의미 가 있습니다 . (이것은 namespace
s 의 C ++ 개념과 비슷하지만 훨씬 더 제한적 입니다.)
A typedef
는 이름에도 불구하고 새로운 유형을 정의하지 않습니다. 단순히 기존 유형에 대한 새 이름을 만듭니다. 예를 들면 다음과 같습니다.
typedef int my_int;
my_int
의 새 이름입니다 int
. my_int
하고 int
있습니다 정확히 같은 유형입니다. 마찬가지로 struct
위 의 정의가 주어지면 다음과 같이 작성할 수 있습니다.
typedef struct foo foo;
유형에 이미 이름이 struct foo
있습니다. typedef
선언은 동일한 유형의 새 이름을 준다 foo
.
구문은 당신이를 결합 할 수 struct
및 typedef
단일 선언으로 :
typedef struct bar {
int n;
} bar;
이것은 일반적인 관용구입니다. 이제이 구조 유형을로 struct bar
또는 그대로으로 참조 할 수 있습니다 bar
.
typedef 이름은 선언이 끝날 때까지 표시되지 않습니다. 구조에 자신에 대한 포인터가 포함 된 경우 struct
버전을 사용하여 참조해야합니다.
typedef struct node {
int data;
struct node *next; /* can't use just "node *next" here */
} node;
일부 프로그래머는 struct 태그와 typedef 이름에 대해 고유 한 식별자를 사용합니다. 제 생각에는 그럴만 한 이유가 없습니다. 동일한 이름을 사용하는 것은 완벽하게 합법적이며 동일한 유형임을 더 명확하게합니다. 다른 식별자를 사용해야하는 경우 최소한 일관된 규칙을 사용하십시오.
typedef struct node_s {
/* ... */
} node;
(개인적으로는 생략하고 typedef
타입을라고 부르는 것을 선호합니다 struct bar
. typedef
약간의 타이핑을 절약 할 수 있지만 구조 타입이라는 사실을 숨 깁니다. 타입을 불투명하게하고 싶다면 이것은 좋은 일이 될 수 있습니다. 코드는 멤버 n
를 이름 으로 지칭 할 것입니다 . 그러면 불투명하지 않습니다. 눈에 띄는 구조이고 제 생각에는 구조라고 부르는 것이 합리적이라고 생각합니다. 어느 쪽이든 작성된 코드를 읽고 이해할 준비가되었습니다.)
(C ++에는 다른 규칙이 있습니다.를 선언 하면 typedef 없이도 struct blah
유형을 그냥으로 참조 할 수 있습니다 blah
. typedef를 사용하면 C 코드가 C ++와 비슷해집니다.
지적되지 않은 또 다른 차이점은 구조체에 이름 (예 : struct myStruct)을 지정하면 구조체의 전방 선언을 제공 할 수 있다는 것입니다. 따라서 다른 파일에 다음과 같이 작성할 수 있습니다.
struct myStruct;
void doit(struct myStruct *ptr);
정의에 액세스 할 필요없이. 내가 추천하는 것은 두 가지 예를 결합하는 것입니다.
typedef struct myStruct{
int one;
int two;
} myStruct;
이것은보다 간결한 typedef 이름의 편리함을 제공하지만 필요한 경우 전체 구조체 이름을 사용할 수 있습니다.
C (C ++ 아님)에서는 다음과 같은 구조체 변수를 선언해야합니다.
struct myStruct myVariable;
myStruct myVariable;
대신 사용할 수 typedef
있도록 struct 를 사용할 수 있습니다 .
typedef struct myStruct someStruct;
someStruct myVariable;
당신은 결합 할 수 있습니다 struct
정의하고 typedef
익명을 선언 한 성명에서 그것을이야 struct
하고 typedef
그것을이야.
typedef struct { ... } myStruct;
struct
없이 사용 typedef
하면 항상 작성해야합니다.
struct mystruct myvar;
쓰는 것은 불법입니다
mystruct myvar;
를 사용하면 더 이상 접두사 typedef
가 필요하지 않습니다 struct
.
C에서, 구조, 노동 조합 및 열거의 유형 지정자 키워드는 필수 당신은 항상 유형의 이름 (그 앞에해야 즉, 태그를 포함) struct
, union
또는 enum
유형을 참조 할 때.
을 사용하여 키워드를 제거 할 수 있습니다. typedef
은 객체를 선언 할 때 실제 유형이 더 이상 표시되지 않으므로 정보를 숨기는 형태입니다.
따라서 몇 번의 키 입력 만 저장하는 것이 아니라 실제로이 정보를 숨기고 싶을 때만이 작업을 수행 하는 것이 좋습니다 (예 : Linux 커널 코딩 스타일 가이드 , 5 장 참조) .
a를 사용해야하는 경우의 예는 typedef
해당 접근 자 함수 / 매크로에서만 사용되는 불투명 유형입니다.
다음 코드는 별칭이있는 익명 구조체를 만듭니다 myStruct
.
typedef struct{
int one;
int two;
} myStruct;
구조에 대한 식별자를 지정하지 않기 때문에 별칭없이 참조 할 수 없습니다.
.NET과 함께 포워드 선언을 사용할 수 없습니다 typedef struct
.
struct
당신은 앞으로 선언에 실제 이름을하지 않아도 자체는 익명의 유형입니다.
typedef struct{
int one;
int two;
} myStruct;
다음과 같은 전방 선언은 작동하지 않습니다.
struct myStruct; //forward declaration fails
void blah(myStruct* pStruct);
//error C2371: 'myStruct' : redefinition; different basic types
차이점은 struct
.
해야 할 첫 번째 방법 :
struct myStruct aName;
두 번째 방법은 키워드를 제거하는 것 struct
입니다.
myStruct aName;
는 typedef
그것이 다른 구조와 같이, 데이터 형식에 새 이름을 부여하는 데 사용된다. 이 경우 대부분 코드를 더 깔끔하게 만들기 위해 수행됩니다.
struct myStruct blah;
대
myStruct blah;
후자의 예에서는 구조를 사용할 때 struct 키워드를 생략합니다. 따라서 코드의 모든 곳에서 다음과 같이 작성할 수 있습니다.
myStruct a;
대신에
struct myStruct a;
이것은 타이핑을 절약하고 더 읽기 쉬울 수도 있지만 이것은 취향의 문제입니다.
나는 이것에 대해 약간의 설명이 필요하다는 것을 알았다. C와 C ++는 유형을 다르게 정의하지 않습니다. C ++는 원래 C 위에 추가 된 포함 세트에 불과했습니다.
오늘날 거의 모든 C / C ++ 개발자가 갖고있는 문제는 a) 대학이 더 이상 기본 사항을 가르치지 않고 b) 사람들이 정의와 선언의 차이를 이해하지 못한다는 것입니다.
이러한 선언과 정의가 존재하는 유일한 이유는 링커가 구조의 필드에 대한 주소 오프셋을 계산할 수 있기 때문입니다. 이것이 대부분의 사람들이 실제로 잘못 작성된 코드를 사용하지 않는 이유입니다. 컴파일러가 주소 지정을 결정할 수 있기 때문입니다. 문제는 누군가가 대기열이나 연결 목록과 같은 작업을 진행하거나 O / S 구조를 피기 백하려고 할 때 발생합니다.
선언은 'struct'로 시작하고 정의는 'typedef'로 시작합니다.
또한 구조체에는 정방향 선언 레이블과 정의 된 레이블이 있습니다. 대부분의 사람들은 이것을 모르고 정방향 선언 레이블을 정의 레이블로 사용합니다.
잘못된:
struct myStruct
{
int field_1;
...
};
그들은 구조에 레이블을 지정하기 위해 앞으로 선언을 사용 했으므로 이제 컴파일러가이를 인식하고 있지만 실제 정의 된 유형은 아닙니다. 컴파일러는 주소 지정을 계산할 수 있습니다. 그러나 이것은 제가 잠시 보여줄 이유 때문에 의도 된 방식이 아닙니다.
이 선언 형식을 사용하는 사람들은 공식적인 새로운 유형이 아니기 때문에 실제로 모든 참조에 항상 'struct'를 넣어야합니다.
대신 자신을 참조하지 않는 구조는 다음과 같이 선언하고 정의해야합니다.
typedef struct
{
field_1;
...
}myStruct;
이제 실제 유형이며 사용하면 'struct'라는 단어를 앞에 추가하지 않고도 'myStruct'로 사용할 수 있습니다.
해당 구조에 대한 포인터 변수를 원하면 보조 레이블을 포함하십시오.
typedef struct
{
field_1;
...
}myStruct,*myStructP;
이제 그 구조에 대한 포인터 변수가 있습니다.
앞으로 선언-
자, 여기 포워드 선언이 어떻게 작동하는지 멋진 것들이 있습니다. 연결 목록이나 큐 요소와 같이 자신을 참조하는 형식을 만들려면 정방향 선언을 사용해야합니다. 컴파일러는 맨 끝에 세미콜론에 도달 할 때까지 정의 된 구조를 고려하지 않으므로 해당 지점 이전에 선언됩니다.
typedef struct myStructElement
{
myStructElement* nextSE;
field_1;
...
}myStruct;
이제 컴파일러는 전체 유형이 아직 무엇인지 모르지만 앞으로 참조를 사용하여 참조 할 수 있음을 알고 있습니다.
구조를 올바르게 선언하고 typedef하십시오. 실제로 이유가 있습니다.
참고 URL : https://stackoverflow.com/questions/1675351/typedef-struct-vs-struct-definitions
'ProgramingTip' 카테고리의 다른 글
데이터 ID 속성을 얻는 방법은 무엇입니까? (0) | 2020.09.29 |
---|---|
데이터베이스, 테이블 및 열 명명 규칙? (0) | 2020.09.29 |
Bash 펼쳐에서 현재 디렉토리 이름 (전체 경로 없음) 가져 오기 (0) | 2020.09.29 |
if- 문에서의 && (논리 -and)에 해당 (0) | 2020.09.29 |
현재 변경 사항으로 Git 분기 만들기 (0) | 2020.09.29 |