구조체가있는 source.c 파일이있는 경우 :
struct a {
int i;
struct b {
int j;
}
};
이 구조체를 다른 파일 (예 :)에서 어떻게 사용할 수 func.c
있습니까?
새 헤더 파일을 만들고 거기에 구조체를 선언하고 해당 헤더를 포함해야 func.c
합니까?
아니면 내가 헤더 파일에서 전체 구조체를 정의하고 모두 그를 포함해야 source.c
하고 func.c
? extern
두 파일에서 구조체를 어떻게 선언 할 수 있습니까?
그럴까요 typedef
? 그렇다면 어떻게?
답변
이 구조가 다른 파일 func.c에서 사용되는 경우 어떻게해야합니까?
유형이 파일 (예 : func.c 파일)에서 사용되는 경우 표시되어야합니다. 가장 나쁜 방법은 필요한 각 소스 파일에 복사하여 붙여 넣는 것입니다.
올바른 방법은 헤더 파일에 넣고 필요할 때마다이 헤더 파일을 포함하는 것입니다.
새 헤더 파일을 열고 거기에 구조를 선언하고 그 헤더를 func.c에 포함시킬까요?
이것은 코드를 고도로 모듈화하기 때문에 내가 더 좋아하는 솔루션입니다. 구조체를 다음과 같이 코딩합니다.
#ifndef SOME_HEADER_GUARD_WITH_UNIQUE_NAME
#define SOME_HEADER_GUARD_WITH_UNIQUE_NAME
struct a
{
int i;
struct b
{
int j;
}
};
#endif
이 구조를 사용하는 함수를 동일한 헤더 ( “인터페이스”의 “의미 상”부분 인 함수)에 넣습니다.
일반적으로 구조 이름 뒤에 파일 이름을 지정하고 해당 이름을 다시 사용하여 헤더 가드가 정의하는 것을 선택할 수 있습니다.
구조체에 대한 포인터를 사용하여 함수를 선언해야하는 경우 전체 구조체 정의가 필요하지 않습니다. 다음과 같은 간단한 전방 선언 :
struct a ;
충분하고 결합을 감소시킵니다.
또는 헤더 파일에 전체 구조를 정의하고이를 source.c와 func.c 모두에 포함 할 수 있습니까?
이것은 좀 더 쉬우면서도 덜 모듈화 된 또 다른 방법입니다. 구조 만 작동해야하는 일부 코드는 여전히 모든 유형을 포함해야합니다.
C ++에서 이것은 흥미로운 복잡성을 유발할 수 있지만 이것은 주제에서 벗어난 것입니다 (C ++ 태그 없음). 따라서 자세히 설명하지 않겠습니다.
그런 다음 두 파일에서 해당 구조를 extern으로 선언하는 방법. ?
나는 요점을 보지 못했지만 Greg Hewgill은 자신의 게시물에서 How to declare a structure in a header in multiple files in c? .
그럼 어떻게 typedef할까요?
- C ++를 사용하는 경우에는 사용하지 마십시오.
- C를 사용하고 있다면 그렇게해야합니다.
그 이유는 C 구조체 관리가 고통 스러울 수 있기 때문입니다. 사용되는 모든 곳에서 구조체 키워드를 선언해야합니다.
struct MyStruct ; /* Forward declaration */
struct MyStruct
{
/* etc. */
} ;
void doSomething(struct MyStruct * p) /* parameter */
{
struct MyStruct a ; /* variable */
/* etc */
}
typedef를 사용하면 struct 키워드없이 작성할 수 있습니다.
struct MyStructTag ; /* Forward declaration */
typedef struct MyStructTag
{
/* etc. */
} MyStruct ;
void doSomething(MyStruct * p) /* parameter */
{
MyStruct a ; /* variable */
/* etc */
}
구조체의 이름을 유지하는 것이 중요 합니다. 쓰기:
typedef struct
{
/* etc. */
} MyStruct ;
typedef-ed 이름으로 익명 구조체를 생성하고 포워드 선언 할 수 없습니다. 따라서 다음 형식을 유지하십시오.
typedef struct MyStructTag
{
/* etc. */
} MyStruct ;
따라서 struct 키워드를 추가하지 않으려는 모든 곳에서 MyStruct를 사용할 수 있으며 typedef가 작동하지 않을 때에도 MyStructTag를 사용할 수 있습니다 (예 : 정방향 선언).
편집하다:
Jonathan Leffler가 올바르게 언급 한대로 C99 구조체 선언에 대한 잘못된 가정을 수정 했습니다 .
2018-06-01 수정 :
Craig Barnes 는 자신의 의견에서 명확성을 위해 위에서했던 것처럼 구조체 “태그”이름과 “typedef”이름에 대해 별도의 이름을 유지할 필요가 없음을 상기시킵니다.
실제로 위의 코드는 다음과 같이 작성 될 수 있습니다.
typedef struct MyStruct
{
/* etc. */
} MyStruct ;
IIRC, 이것은 실제로 C ++이 C와의 호환성을 유지하기 위해 더 간단한 구조체 선언으로 수행하는 작업입니다.
// C++ explicit declaration by the user
struct MyStruct
{
/* etc. */
} ;
// C++ standard then implicitly adds the following line
typedef MyStruct MyStruct;
C로 돌아가서 두 가지 사용 (별도의 이름과 같은 이름)을 보았지만 내가 아는 단점은 없습니다. 따라서 구조체와 다른 기호에 대해 C 별도의 “네임 스페이스”를 사용하지 않으면 같은 이름을 사용하면 읽기가 더 쉬워집니다. .
답변
둘 이상의 소스 파일에서 사용할 구조 정의의 경우 반드시 헤더 파일에 넣어야합니다. 그런 다음 구조가 필요한 소스 파일에 해당 헤더 파일을 포함합니다.
extern
선언은 구조 정의를 사용하지 않으며, 대신 (즉, 구조 유형 일부 데이터 값을 사용자가 정의한 것을) 변수 선언에 사용됩니다. 둘 이상의 소스 파일에서 동일한 변수를 사용하려면 다음과 extern
같이 헤더 파일에서 선언하십시오 .
extern struct a myAValue;
그런 다음 하나의 소스 파일에서 실제 변수를 정의하십시오.
struct a myAValue;
이 작업을 잊었거나 실수로 두 개의 소스 파일에 정의한 경우 링커가 이에 대해 알려줍니다.
답변
아 :
#ifndef A_H
#define A_H
struct a {
int i;
struct b {
int j;
}
};
#endif
이제이 구조를 사용하려는 파일에 ah를 포함하면됩니다.