구조체에 대해서 질문드립니다.
글쓴이: thslrtoo / 작성시간: 목, 2014/01/09 - 10:20오후
공부를 하던 도중 책에 이런 구조체 문구가 나오더군요.
typdef struct aaa { ... struct bbb *pB; }AAA, *PAAA; typedef struct bbb { ... PAAA pA; }BBB, *PBBB;
bbb 구조체를 보면 aaa 구조체의 포인터를 멤버로 가지고 있습니다.
bbb 구조체 위에 aaa 구조체 정의가 있으니까 문제가 없겠죠??
근데 제가 궁그한건 aaa 구조체의 pB 멤버입니다.
aaa 구조체가 정의될때는 bbb 구조체를 전혀 모르고있습니다.
물론 포인터형이라서 4Byte 만 할당해주면 되겠지만,
struct bbb 라는 이름 자체를 모르는데 어떻게 저게 가능한지 궁금하네요.
그리고 추가로
PAAA a1; // a1 에 값이 대입되었다고 가정합니다. PBBB b1 = a1->pB;
위 코드에서 b1 = a1->pB 구문은 책에서는 된다고 나와있습니다.
근데 제가 컴파일 해봤을때는 캐스팅(struct bbb *) 을 하지 않고는 컴파일이 되지 않았습니다.
책이 잘못된건가요??
Forums:
실제로 컴파일 해본 소스코드를 올려주세요.
실제로 컴파일 해본 소스코드를 올려주세요.
아.. 소스를 그냥 올려드리는게
아.. 소스를 그냥 올려드리는게 빠르겠군요..^^;;
여기 이 소스입니다.
구조체와 공용체, 배열은 불완전 선언이
구조체와 공용체, 배열은 불완전 선언이 가능합니다.
자세한건 incomplete types로 검색해 보시길 권하며..
구조체에 대한 포인터 같은 경우에는 구조체 내부 구조에 대한 정보가 따로 필요가 없으므로,
불완전한 타입만으로도 그에 대해 포인터를 선언할 수가 있습니다.
위의 경우에는 구조체 aaa 선전 부분의 struct bbb *pB; 부분이
구조체 bbb에 대한 불완전 선언으로 작용합니다.
물론, 선언일 뿐이므로 실제로 해당 객체에 접근하기 위해서는
그 뒤에 불완전한 부분에 대해 제대로 정의를 추가적으로 해 줘야 합니다.
그리고 아래 문제에 대해선, 대입 자체는 되는게 맞습니다.
동일한 타입인데 대입이 안되면 이상한 거지요.
다만 좀 맘에 걸리는건 a1이라는 객체 자체가 존재하지 않는다는 점인데...
정렬제한 문제가 있을 수 있겠군요.
일단 에러 메시지의 내용을 확인해 보시길 권합니다.
그리고 컴파일 에러 질문할땐 제발 에러 메시지좀 같이 올리십시오.
다만 좀 맘에 걸리는건 a1이라는 객체 자체가
다만 좀 맘에 걸리는건 a1이라는 객체 자체가 존재하지 않는다는 점인데...
-> 'a1이 가리키는 객체가'로 바꿔서 읽어주세요.
죄송합니다. 아무 생각없이 질문만
죄송합니다. 아무 생각없이 질문만 해버렸네요..^^;;
소스코드는 길어서 파일로 첨부하였고 (위 답변에..) 에러 코드는 아래과 같이 뜹니다.
일단 말씀해주신 incomplete type 을 한번 찾아봐야겠습니다. ^^
뭔가 원질문의 예와 Graph.cpp의 예는 다른
뭔가 원질문의 예와 Graph.cpp의 예는 다른 상황으로 보입니다.
Graph.cpp의 축약된 버전으로 같은 에러를 보이는 예제를 올려보세요. 그게 어렵다면 압축, 또는 다른 사이트 링크(클라우드 링트 등)으로 올려 보세요. 도움받기 수월할 겁니다.
소스를 보니 그냥 전방 선언이 없네요.
헤더 파일을 다음과 같이 수정하세요
질문과 다른 내용이지만 코드를 보고 느끼면..
질문과 동떨어진 내용인데요..
typedef 가 얼마나 코드 가독성을 헤치는지 이제야 이해가 되네요..
struct aaa
{
...
struct bbb *pb;
};
struct bbb
{
...
struct aaa *pa;
};
이렇게 쉽게 하면 될 것을.. 왜 두세번(혹은 네번 다섯번) 보게 가르켜 주는 걸까요?
질문자가 제시한 상황에서는 typedef 대신 님께서
질문자가 제시한 상황에서는 typedef 대신 님께서 말한대로 한다고 해도
여전히 같은 문제가 발생합니다.
위 문제는 namespace 혹은 scope와 관련이 있습니다.
class 내부에서 선언된 incomplete type인 구조체가
class 외부에서 정의된 구조체와 서로 별개로 취급되기 때문에 생기는 문제입니다.
즉 tagEdge와 CGraph::tagEdge는 서로 별개의 타입입니다.
typedef를 하지 않았다고 해도 크게 달라지는 문제는 아닙니다.
제가 비슷한 에러 메시지가 나오는 상황을 한번 재현해 봤습니다.
그나저나 여기는 비로그인은 로그인이 올린 첨부파일을 볼 수가 없는 모양이군요.
내용은 잘 알겠습니다.
근데 제가 말하고자 한건 typedef 가 가독성을 안 좋게 한다는 대한 내용이지
질문내용에 대한 컴파일 여부는 잘 모르겠네요
선두에 질문과 상관 없지만.. 이라고 적었어요 ㅎㅎ
typedef는 오히려 코드 가독성을 높이는데 유용한
typedef는 오히려 코드 가독성을 높이는데 유용한 기능입니다.
특히 함수 포인터와 관련해서는, 이거 없으면 굉장히 코드가 끔찍해질 겁니다.
만약 typedef가 코드 가독성을 저해한다면
프로그램의 내부 구조가 이해하기 어렵게 만들어져 있거나
타입 이름이 직관적이지 않아서 그렇겠지요.
예를 한번 들어 볼께요
예를 한번 들어 볼께요
struct st_device {
RECV_STATE rst;
TRAN_STATE tst;
};
위와 같은 때
RECV_STATE, TRAN_STATE 가 무슨 타입이지?
그래서 찾아 보시겠죠...
struct st_device {
struct recv_st *rst;
struct tran_st *tst;
};
위와 같을 때
rst,tst 가 구조체의 포인터군.. 바로 아실수 있죠?
C++의 struct는 단지 기본 접근자가
C++의 struct는 단지 기본 접근자가 public인 class에 불과하기 때문에,
그럴 이유가 전혀 없습니다.
우리가 class의 instance를 선언할때마다 그 옆에 THIS IS CLASS!!!라고 적어주던가요?
마찬가지로, struct도 그럴 필요가 없습니다.
struct bbb *pB; 자체에 전방 선언이 들어있기 때문입니다.
저는 이렇게 생각했습니다.
댓글 달기