source

'forward declaration'은 무엇이며 'typeef structure X'와 'structure X'의 차이점은 무엇입니까?

goodcode 2022. 8. 24. 23:52
반응형

'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

반응형