공용체(union)와 구조체(struct)의 차이점
공용체(union) 와 구조체(struct) 는 여러 값을 담을 수 있는 데이터 타입이다. 하지만 메모리를 사용하는 방식에 큰 차이가 있다.
구조체(struct) 는 각 멤버마다 고유한 메모리 공간을 가지며, 서로 독립적으로 값을 유지한다. 공용체(union) 는 모든 멤버가 같은 메모리 공간을 공유한다. 그래서 한 멤버의 값을 바꾸면 다른 멤버들의 값도 바뀔 수 있다. 공용체는 메모리를 절약하고 싶을 때 유용하다.
#include <stdio.h>
#include <stdint.h>
typedef unsigned char U08;
typedef union {
struct {
U08 dummy1 : 1;
U08 LSYS : 1;
U08 DCM : 2;
U08 LSYE : 1;
U08 LSYM : 3;
} RGB;
struct {
U08 PLTI_0 : 8;
} PLT;
} COLOR;
void init_COLOR(COLOR* a) {
a->RGB.dummy1 = 1;
a->RGB.LSYS = 1;
a->RGB.DCM = 1;
a->RGB.LSYE = 1;
a->RGB.LSYM = 1;
a->PLT.PLTI_0 = 15; // 공용체 멤버 설정
}
void print_COLOR(const COLOR* a) {
printf("RGB.dummy1: %u\n", a->RGB.dummy1);
printf("RGB.LSYS: %u\n", a->RGB.LSYS);
printf("RGB.DCM: %u\n", a->RGB.DCM);
printf("RGB.LSYE: %u\n", a->RGB.LSYE);
printf("RGB.LSYM: %u\n", a->RGB.LSYM);
printf("PLT.PLTI_0: %u\n", a->PLT.PLTI_0);
}
int main() {
COLOR a;
init_COLOR(&a);
print_COLOR(&a);
}
출력 결과
RGB.dummy1: 1
RGB.LSYS: 1
RGB.DCM: 3
RGB.LSYE: 0
RGB.LSYM: 0
PLT.PLTI_0: 15
결과 분석
초기화 코드를 보면 공용체의 마지막에 PLT의 구조체 필드를 초기화한 것을 알 수 있다.
a->PLT.PLTI_0 = 15; // 공용체 멤버 설정
공용체에서 RGB와 PLT는 같은 메모리 공간을 공유하기 때문에, PLT를 초기화하면 기존에 RGB 구조체가 차지하고 있던 메모리를 덮어쓴다. 이 때문에 RGB의 멤버 값들이 변경되어 예상과 다른 출력 결과가 나온다.
메모리 상태 분석
- RGB 구조체를 초기화했을 당시의 메모리는 다음과 같이 설정된다 (예시로 가정한 값):
비트 위치76543210
값 | 0 | 0 | 1 | 1 | 0 | 1 | 1 | 1 |
이 값은 각 필드를 정상적으로 초기화한 결과이다.
- dummy1: 1
- LSYS: 1
- DCM: 3 (즉, 11)
- LSYE: 1
- LSYM: 1 (즉, 001)
- 하지만 이후 PLT** 구조체를 초기화**하면서 공용체의 같은 메모리 공간이 덮어씌워진다. PLT.PLTI_0 = 15는 이진수로 0000 1111이다.
- 이로 인해 기존의 RGB 구조체의 메모리 값들이 덮어씌워지고, 아래와 같은 새로운 메모리 값이 설정된다:
비트 위치 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
값 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 |
변경된 결과의 이유
이렇게 변경된 메모리를 바탕으로 RGB 구조체의 각 필드를 읽어오면 다음과 같은 결과가 나온다:
- dummy1은 1비트를 차지하므로 1로 읽힌다.
- LSYS도 1비트를 차지하여 1로 읽힌다.
- DCM은 2비트를 차지하며, 메모리 상에서 11이 되어 3으로 읽힌다.
- LSYE는 1비트를 차지하지만, 덮어씌워진 메모리 값으로 인해 0으로 읽힌다.
- LSYM 역시 덮어씌워져 0이 된다.
이처럼 공용체에서 다른 멤버를 초기화하면, 같은 메모리 공간을 공유하기 때문에 이전의 값들이 모두 덮어씌워질 수 있다는 점을 주의해야 한다.
'C 자료구조와 알고리즘' 카테고리의 다른 글
전처리기 토큰 결합 연산자 (3) | 2024.10.10 |
---|---|
주소의 형 변환 (0) | 2024.10.10 |
자료구조와 알고리즘 (0) | 2024.07.15 |
댓글