Native/C

공용체 Union

aucd29 2013. 10. 2. 18:47
공용체(Union)는 모든 면에서 구조체와 같으며 선언 문법이나 사용하는 방법이 동일하다. 다만 공용체에 속한 멤버들이 기억 장소를 공유한다는 것만 다르다. 기억 장소를 어떻게 공유한다는 것인지 선뜻 이해하기 힘든데 일단 똑같은 모양의 구조체와 공용체를 선언해 놓고 비교해 보도록 하자. 공용체를 선언할 때는 키워드 struct 대신에 union을 사용한다.
구조체는 선언된 멤버가 순서대로 배치되며 a가 4바이트를 차지하고 이어서 b[0]가 2바이트, b[1]이 2바이트를 각각 차지한다. 구조체의 크기는 모든 멤버 크기의 총합과 같으므로 sizeof(st)는 8이 될 것이다. 공용체는 모든 멤버가 기억 장소를 공유하며 a가 있는 자리에 b도 같이 존재한다. 공용체의 크기는 가장 큰 멤버의 크기와 같으며 sizeof(un)은 4가 된다.
공용체의 멤버들은 항상 공용체의 선두 번지와 같은 공간에 배치되는데 a의 번지나 b의 번지나 동일하다. 따라서 a에 어떤 값을 대입하면 같은 기억 공간에 존재하는 b의 값도 덩달아 바뀌게 되며 반대로 b를 변경하면 a도 같이 변경된다. 다음 예제로 이런 동작을 확인해 보자.
왼쪽은 공용체의 이름을 준 것이고 오른쪽은 이름을 주지 않은 것이다. 이름있는 공용체의 멤버를 참조할 때는 Name.a 식으로 소속을 밝혀야 하기 때문에 공용체 바깥에 a라는 다른 변수를 또 선언할 수 있지만 이름없는 공용체의 멤버는 멤버 자신의 이름만으로 참조해야 하므로 바깥에 같은 이름의 다른 변수를 선언할 수 없다. 이름없는 공용체는 주로 구조체 내의 멤버를 선언할 때 사용된다. 다음 예를 보자.

[code]
struct tag_student {
char Name[16];
BOOL Male;
int Grade;
union {
     int HakBun;
     char Jumin[14];
} ID;
};

tag_student boy;
[/code]

이 구조체는 학생 한명의 신상을 기억하는데 Name이 이름, Male이 성별, Grade가 학년이다. 이름은 동명이인이 있을 수 있으므로 개인의 유일한 식별자가 될 수 없는데 이런 목적으로 사용할 수 있는 값으로는 학번과 주민등록번호가 있다. 이 두 정보 중 하나만 기록할 수 있으며 둘 다 기록할 필요가 없다면 Hakbun과 Jumin 멤버를 공용체로 선언하면 된다. ID 멤버를 Hakbun과 Jumin의 공용체로 선언했으므로 ID를 읽고 쓸 때는 다음과 같이 참조한다.

[code]
boy.ID.Hakbun=89123456;
strcpy(boy.ID.Jumin,"700101-1919199");
[/code]

Hakbun이나 Jumin은 구조체에 속한 공용체의 멤버이므로 멤버 연산자를 두번 사용해야 한다. C 컴파일러는 이름없는 공용체를 지원하지 않기 때문에 구조체내에 속해 있는 공용체라도 반드시 이름이 있어야 한다. 그런데 여기서 ID라는 명칭은 Hakbun과 Jumin을 담기 위한 그릇일 뿐이므로 꼭 이름을 줄 필요가 없는데 이럴 때 공용체 변수의 이름을 생략할 수 있다. C++ 컴파일러는 이름없는 공용체를 지원하므로 다음과 같이 구조체 선언을 좀 더 간단하게 할 수 있다.

[code]
struct tag_student {
char Name[16];
BOOL Male;
int Grade;

union {
     int HakBun;
     char Jumin[14];
};                    // 이름이 없음
};

tag_student boy;
[/code]

공용체의 이름을 생략하면 공용체의 멤버들은 바깥의 구조체에 직접 소속된다. 그래서 Hakbun과 Jumin을 읽고 쓸 때 중간의 공용체 이름을 생략하고 멤버 연산자를 한번만 사용하면 된다.

[code]
boy.Hakbun=89123456;
strcpy(boy.Jumin,"700101-1919199");
[/code]

선언할 때 공용체의 이름을 아예 지정하지 않으면 공용체의 멤버들을 마치 구조체에 속한 것처럼 사용할 수 있어 편리하다. 다음 예제의 tag_Part 구조체는 컴퓨터 부품 하나에 대한 정보를 가진다.