'forward declaration'은 무엇이며 'typeef structure X'와 'structure X'의 차이점은 무엇입니까?
나는 C프로그래밍의 초보자이고 나는 C프로그래밍의 차이점을 알고 있다.struct
과 " " " 입니다.typedef
우연히 된 은 '정의를 된다'는입니다.struct
들면 다음과 같습니다.
typedef struct {
some members;
} struct_name;
그러면 익명 구조에 별칭을 제공하는 것과 같습니다(태그 이름이 없기 때문에 에일리어스를 제공하는 것과 같습니다.그래서 전향 신고에 사용할 수 없습니다.나는 전향 선언이 무엇을 의미하는지 모른다.
또한 아래 코드에 대해 알고 싶습니다.
typedef struct NAME {
some members;
} struct_alias;
NAME
★★★★★★★★★★★★★★★★★」struct_alias
둘 다 struct_alias
?structure NAME의 입니까?
할 수 ?struct NAME
음음음같 뭇매하다
struct_alias variable1;
및/또는 다음과 같습니다.
struct NAME variable2;
또는 다음과 같습니다.
NAME variable3;
struct
포워드 선언★★★★
struct a {
struct b * b_pointer;
int c;
};
struct b {
struct a * a_pointer;
void * d;
};
struct a
알 수 .struct b
아직입니다만, 참조는 가능합니다.
익명의 구조체를 입력하면 컴파일러는 구조체의 이름을 typedef 앞에 사용할 수 없습니다.
이것은 불법입니다.
struct a {
b * b_pointer;
int c;
};
typedef struct {
struct a * a_pointer;
void * d;
} b;
// struct b was never declared or defined
이것은 합법입니다.
struct a {
struct b * b_pointer;
int c;
};
typedef struct b {
struct a * a_pointer;
void * d;
} b;
// struct b is defined and has an alias type called b
이것도 마찬가지입니다.
typedef struct b b;
// the type b referes to a yet undefined type struct b
struct a {
b * struct_b_pointer;
int c;
};
struct b {
struct a * a_pointer;
void * d;
};
이것은 다음과 같습니다(C에서만, C++에서는 부정).
typedef int b;
struct a {
struct b * struct_b_pointer;
b b_integer_type;
int c;
};
struct b {
struct a * a_pointer;
void * d;
};
// struct b and b are two different types all together. Note: this is not allowed in C++
포워드 선언은 정의할 수 없는 시점에서 컴파일러에게 하는 것을 정의하는 약속입니다.컴파일러는 당신의 단어를 사용하여 다른 선언을 해석할 수 있습니다.
로는 「」를 들 수 있습니다.struct
리스트내의 를 「링크 리스트」에 .노드에 대한 포인터는struct
, 할 수
// Forward declaration
struct element;
typedef struct {
int value;
// Use of the forward declaration
struct element *next;
} element; // Complete definition
그래서 전진 선언에 사용할 수 없습니다.
는 '우리'에게 '우리'를 이었던 것 요.struct
태그는 순방향 선언과 동일합니다.
typedef struct element {
int value;
// No need for a forward declaration here
struct element *next;
} element;
순방향 선언은 실제 정의보다 앞선 선언으로, 일반적으로 정의를 사용할 수 없을 때 선언된 유형을 참조할 수 있습니다.물론 모든 것이 정의되지 않은 선언된 구조로 이루어지는 것은 아니지만, 특정 맥락에서 사용할 수 있습니다.이러한 유형을 불완전이라고 하며, 사용에는 여러 가지 제한이 있습니다.예를 들어 다음과 같습니다.
struct X; // forward declaration
void f(struct X*) { } // usage of the declared, undefined structure
// void f(struct X) { } // ILLEGAL
// struct X x; // ILLEGAL
// int n =sizeof(struct X); // ILLEGAL
// later, or somewhere else altogether
struct X { /* ... */ };
이 방법은 순환 의존성을 해소하거나 컴파일 시간을 단축하는 등의 방법으로 유용할 수 있습니다.정의는 일반적으로 상당히 크고 해석에 더 많은 리소스가 필요하기 때문입니다.
이 예에서는struct NAME
그리고.struct_alias
실제로 동등합니다.
struct_alias variable1;
struct NAME variable2;
정답입니다.
NAME variable3;
C의 경우와 마찬가지로,struct
키워드는 필수입니다.
앞에서 설명한 바와 같이 C/C++에서의 포워드 선언은 실제 정의를 사용할 수 없는 무언가의 선언입니다.컴파일러에 "데이터 타입 ABC가 있다"는 선언입니다.
이것이 어떤 키/값 저장소의 헤더라고 가정합니다.my_dict.h
:
...
struct my_dict_t;
struct my_dict_t* create();
char* get_value(const struct my_dict_t* dict, const char* name);
char* insert(struct my_dict_t* dict, const char* name, char* value);
void destroy(struct my_dict_t* dict);
...
넌 아무것도 몰라my_dict_t
그러나 실제로 스토어를 사용하기 위해서는 알 필요가 없습니다.
#include "my_dict.h"
...
struct my_dict_t* dict = create();
if(0 != insert(dict, "AnEntry", strdup("AValue"))) {
...
}
...
그 이유는 데이터 구조에 대한 POINTER만 사용하고 있기 때문입니다.
POINTER는 숫자에 불과하며, 그것들을 다루기 위해 당신은 그들이 무엇을 가리키고 있는지 알 필요가 없다.
이것은 실제로 접속을 시도했을 경우에만 문제가 됩니다.
struct my_dict_t* dict = create();
printf("%s\n", dict->value); /* Impossible if only a forward decl is available */
따라서 기능을 구현하기 위해서는 실제 정의가 필요합니다.my_struct_t
소스 파일에서 이 작업을 수행할 수 있습니다.my_dict.c
다음과 같이 합니다.
#include "my_dict.h"
struct my_dict_t {
char* value;
const char* name;
struct my_dict_t* next;
}
struct my_dict_t* create() {
return calloc(1, sizeof(struct my_dict_t));
}
이것은 다음과 같은 몇 가지 상황에서 유용합니다.
- 세르게이 L.의 설명과 같이 순환형 의존성을 해결하기 위한 것입니다.
- 위의 예시와 같이 캡슐화의 경우.
남은 질문은 다음과 같습니다.위의 함수를 사용할 때는 왜 포워드 선언을 아예 생략할 수 없는 것입니까?결국 컴파일러는 모든 것을 아는 것으로 충분합니다.dict
포인터입니다.
다만, 컴파일러는 다음의 타입 체크를 실행합니다.그런 일을 하지 않는다는 것을 증명해야 합니다.
...
int i = 12;
char* value = get_value(&i, "MyName");
...
방법을 알 필요는 없습니다.my_dict_t
그런 것 같지만, 알아둘 필요가 있습니다.&i
포인터 타입이 아닙니다.get_value()
예기하고 있습니다.
struct_alias
그리고.struct NAME
같습니다.struct_alias
에일리어스입니다.struct NAME
둘 다 동일하며 허용됩니다.
struct_alias variable1;
struct NAME variable1;
이것은 불법이다
NAME variable3;
언급URL : https://stackoverflow.com/questions/18658438/what-is-forward-declaration-and-the-difference-between-typedef-struct-x-and
'source' 카테고리의 다른 글
페이지피드 통찰력이 "blob" 압축 및 캐시를 수정하도록 요구하는 이유는 무엇입니까? (0) | 2022.08.24 |
---|---|
java.util 복사 방법다른 java.util에 나열합니다.목록. (0) | 2022.08.24 |
이미 초기화된 Sentry.io 설정에 Vue.js 통합을 추가하려면 어떻게 해야 합니까? (0) | 2022.08.21 |
자바 사용법Scala의 String.format? (0) | 2022.08.21 |
Vuex - 변환 유형에 대한 상수이지만 작업 및 Getter에는 해당되지 않습니까? (0) | 2022.08.21 |