본문 바로가기
VisualStudio.C++.C#/C . C++

C . union . 공용체 . 비트필드

by i.got.it 2026. 8. 17.

 

 

uinion 

- 유니온의 모든 멤버는 동일한 메모리 주소를 가리킨다.  유니온 메모리 크기는 멤버중 가장 큰 데이터 타입 크기로 할당된다.  

- 비교 : 구조체 의 모든 멤버는 개별적으로 메모리 할당됨. 

- union은 C 언어 시절부터 이어져 온 순수 하드웨어 친화적 문법. 컴파일러의 최적화 옵션 (-o2,-o3 같은것) 에  간섭받지 않고  개발자가 작성한 어셈블리 그대로 매핑

 

union MyUnion {
    char i1;      // 1 바이트
    short i2;     // 2 바이트
    int i4;       // 4 바이트 (가장 큼)
}; // 이 공용체의 전체 크기는 4바이트

 

union 활용예 

- byte 내의 비트 접근시. 

union Register {
    uint8_t byte; // 1바이트 전체 제어
    struct {            // 비트 단위 세부 제어
        uint8_t bit0 : 1; // 먼저 선언한것이 최하위비트 점함 
        uint8_t bit1 : 1;
        uint8_t rsv  : 6;
    } bits;
};

union Register reg;
reg.byte = 0xFF;       // 전체를 1로 세팅
reg.bits.bit0 = 0;     // 특정 비트만 0으로 수정 (동일 메모리이므로 byte 값도 변함)

 

- 참고. 위 코드의 비트필드 

컴파일러는 위 구조체를 보고 다음과 같이 처리함.
  • uint8_t bit0 : 1; ➔ 방금 준비한 1바이트 중 1비트 사용
  • uint8_t bit1 : 1; ➔ 이어서 1비트 사용
  • uint8_t rsv : 6; ➔ 이어서 나머지 6비트 사용
  • 총합: 1 + 1 + 6 = 8비트 (정확히 1바이트)
  (MSB)  ←───────────────────────────────────────── (LSB) 
 ┌───────────┬───────────┬───────────┬───────────┬───────────┬───────────┬───────────┬───────────┐
 │   bit 7   │   bit 6   │   bit 5   │   bit 4   │   bit 3   │   bit 2   │   bit 1   │   bit 0   │
 ├───────────┴───────────┴───────────┴───────────┴───────────┴───────────┼───────────┼───────────┤
 │                         rsv (3번째로 채워짐, 6비트)                   │   bit1    │   bit0    │
 │                                                                       │(2번째)    │(1번째)    │
 └───────────────────────────────────────────────────────────────────────┴───────────┴───────────┘

 

struct OnlyOneBit {
    uint8_t bit0 : 1; 
}; // sizeof(OnlyOneBit)는 컴파일 결과 1바이트.

//////////////////////////////////////////////////////

union CustomRegister {
    uint8_t byte;
    struct {
        uint8_t bit0 : 1; // 사용함 (이름 있음)
        uint8_t      : 6; // 중간 6비트는 건너뜀 (이름 생략, 접근 불가능)
        uint8_t bit7 : 1; // 사용함 (이름 있음)
    } bits;
};

union CustomRegister reg;
reg.bits.bit0 = 1;
reg.bits.bit7 = 0;
// reg.bits. (컨트롤+스페이스를 눌러도 자동완성에 중간 6비트는 뜨지 않음)


//////////////////////////////////////////////////////

Bit 0: EN (활성화 플래그)
Bit 1: IE (인터럽트 허용 플래그)
Bit 2~15: RSV1 (예약 영역)
Bit 16~31: VAL (16비트짜리 데이터 세팅 값)

typedef union {
    volatile uint32_t val32;   // 32비트 전체 통제용 (4바이트)
    
    struct {
        volatile uint32_t EN   : 1;  // Bit 0 (최하위 비트)
        volatile uint32_t IE   : 1;  // Bit 1
        volatile uint32_t      : 14; // Bit 2 ~ 15 (안 쓰는 14개 비트 건너뛰기)
        volatile uint32_t VAL  : 16; // Bit 16 ~ 31 (16비트 데이터 영역)
    } bits;
} UART_CTRL_REG;

 

- 4바이트 단일 데이터 ↔ 4바이트 배열 전환

union DataConverter {
    uint32_t value;
    uint8_t bytes[4];
};

union DataConverter data;
data.value = 0x12345678;
// data.bytes[0]을 보면 엔디안(Endian)에 따라 0x78 또는 0x12를 바로 읽을 수 있음 (포인터 연산 불필요)

 

 

- 메모리 절약 용도  

struct Token {
    int type; // 토큰 종류 (문자열인지, 숫자인지)
    union {
        char* string_val; // type이 문자열일 때만 사용 (8바이트)
        double number_val; // type이 숫자일 때만 사용 (8바이트)
    } data; 
}; // struct였다면 16바이트가 필요하지만, union이라 8바이트만 소모.

 

 

하드웨어 레지스터/비트 제어 시 ➔ volatile union
값이 컴파일러 모르게 하드웨어에 의해 언제든 바뀔 수 있음을 알리는것.  컴파일러는 이 메모리 접근을 절대 최적화로 생략하지 못한다.
typedef union {
    volatile uint32_t WORD;
    struct {
        volatile uint32_t TX_READY : 1;
        volatile uint32_t RX_READY : 1;
        volatile uint32_t RESERVED : 30;
    } BIT;
} UART_STATUS_REG;
 

 

 
 

첫 등록 : 2026.08.17

최종 수정 : 

단축 주소 : https://igotit.tistory.com/


 

댓글



비트코인




            암호화폐/외환/나스닥/골드          
       
현물 |선물 인버스 |선물 USDT , bybit MT5               프랍 트레이딩. MT4,MT5