본문 바로가기
C 자료구조와 알고리즘

공용체

by yunchanlee 2024. 10. 11.

공용체(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;  // 공용체 멤버 설정

공용체에서 RGBPLT같은 메모리 공간을 공유하기 때문에, PLT를 초기화하면 기존에 RGB 구조체가 차지하고 있던 메모리를 덮어쓴다. 이 때문에 RGB의 멤버 값들이 변경되어 예상과 다른 출력 결과가 나온다.

메모리 상태 분석

  1. RGB 구조체를 초기화했을 당시의 메모리는 다음과 같이 설정된다 (예시로 가정한 값):

비트 위치76543210

0 0 1 1 0 1 1 1

이 값은 각 필드를 정상적으로 초기화한 결과이다.

  • dummy1: 1
  • LSYS: 1
  • DCM: 3 (즉, 11)
  • LSYE: 1
  • LSYM: 1 (즉, 001)
  1. 하지만 이후 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

댓글