산업 제조
산업용 사물 인터넷 | 산업자재 | 장비 유지 보수 및 수리 | 산업 프로그래밍 |
home  MfgRobots >> 산업 제조 >  >> Industrial programming >> C 언어

C 공용체(Union) 완전 이해: 메모리 공유, 타입 펀칭, 실전 활용

공용체(union)는 여러 멤버가 동일한 메모리 공간을 공유하는 타입입니다. 한 시점에 한 멤버만 유효하며, 크기는 가장 큰 멤버 크기로 결정됩니다.

공용체 정의와 크기

union Data {
    int i;          // 4바이트
    float f;        // 4바이트
    char str[20];   // 20바이트 → 전체 크기 20바이트 (정렬 고려 시 24 가능)
} data;

sizeof(union Data) == 20 (또는 정렬에 따라 24)

멤버 접근과 동작 원리

union Data d;
d.i = 0x41424344;  // 정수 저장 (16진수: 'D','C','B','A' 리틀엔디안)
printf("i: %d (0x%X)\n", d.i, d.i);
printf("f: %f\n", d.f);        // 같은 비트를 float로 해석 (의미 없는 값)
printf("str: %s\n", d.str);    // "ABCD" 출력 (리틀엔디안에서)

d.f = 3.14f;
printf("i: %d\n", d.i);        // float 비트 패턴을 int로 해석

핵심: 마지막에 쓴 멤버만 유효

d.i = 10;
d.f = 3.14f;
strcpy(d.str, "Hello");
// 이제 d.str만 유효, d.i와 d.f 값은 손상됨

공용체 vs 구조체

실전 활용 패턴

1. 타입 펀칭 (Type Punning) - 비트 패턴 재해석

union FloatBits {
    float f;
    uint32_t u;
};

void print_float_bits(float x) {
    union FloatBits fb = {.f = x};
    printf("0x%08X  ", fb.u);
    // 부호(1) | 지수(8) | 가수(23)
    printf("sign=%d exp=%d mantissa=%06X\n",
           (fb.u >> 31) & 1,
           (fb.u >> 23) & 0xFF,
           fb.u & 0x7FFFFF);
}

※ 엄밀히 C 표준상 UB이나, GCC/Clang/MSVC 등 주요 컴파일러에서 지원 (공용체 타입 펀칭은 흔한 관용구)

2. 태그된 공용체 (Tagged Union) - 수학적 합 타입

enum ValueType { INT_VAL, FLOAT_VAL, STR_VAL };

struct Value {
    enum ValueType type;
    union {
        int i;
        float f;
        char *s;
    } data;
};

void print_value(struct Value *v) {
    switch (v->type) {
        case INT_VAL:    printf("int: %d\n", v->data.i); break;
        case FLOAT_VAL:  printf("float: %f\n", v->data.f); break;
        case STR_VAL:    printf("str: %s\n", v->data.s); break;
    }
}

3. 하드웨어 레지스터/네트워크 패킷 매핑

// 네트워크 패킷 헤더 (빅엔디안 가정)
union PacketHeader {
    struct {
        uint16_t version: 4;
        uint16_t type: 4;
        uint16_t flags: 8;
        uint32_t payload_len;
    } fields;
    uint8_t raw[8];  // 바이트 배열로 직접 접근
};

4. 메모리 절약: 상호 배타적 상태 저장

// 이벤트 시스템: 한 번에 한 종류만 발생
struct Event {
    enum { KEY, MOUSE, TIMER } type;
    union {
        struct { int key; int mods; } key;
        struct { int x, y; int button; } mouse;
        struct { uint64_t deadline; } timer;
    };
};

익명 공용체 (Anonymous Union, C11)

struct Widget {
    int id;
    union {  // 태그 없음, 멤버를 구조체 멤버처럼 직접 접근
        int int_val;
        float float_val;
        char *str_val;
    };
};

struct Widget w;
w.int_val = 42;      // w.data.int_val 없이 직접 접근
w.float_val = 3.14f; // 이전 값 덮어씀

공용체 초기화 (C99 지정 초기화자)

union Data d1 = { .f = 3.14f };        // f 멤버 초기화
union Data d2 = { .str = "Hello" };    // str 멤버 초기화
union Data d3 = { 0 };                 // 첫 멤버(i) 0 초기화, 나머지도 0

정렬과 크기

모범 사례와 주의사항

C 언어

  1. 마이크로프로세서: 저장 프로그램 컴퓨팅의 진화
  2. 종합 오피앰프 데이터: National Semiconductor & CA3130 데이터시트
  3. C++ 데이터 타입 이해하기: 기초, 수정자, 모범 사례
  4. C 데이터 타입 완벽 해설: int, float, char 등 완전 가이드
  5. C 공용체(Union) 완벽 이해: 정의, 사용법, 구조체와의 비교
  6. 파이썬 데이터 타입 마스터하기: 실전 가이드
  7. C 데이터 타입 완전 정복: 정수, 실수, void, 파생 타입과 sizeof
  8. C++ 데이터 구조: 배열, 구조체, 포인터로 효율적인 프로그램 만들기
  9. C++ 데이터 추상화 마스터하기: 인터페이스와 구현 분리로 설계 단순화
  10. C++ 데이터 캡슐화: 코드 보호의 핵심 원리
특성구조체 (struct)공용체 (union)
메모리멤버별 독립 공간 (합 + 패딩)공유 공간 (최대 멤버 크기)
동시 사용모든 멤버 동시 유효한 멤버만 유효
용도레코드, 복합 데이터타입 변환, 메모리 절약, 다형성
초기화여러 멤버 가능첫 멤버만 초기화 가능 (C99: 지정 초기화자로 아무 멤버나 가능)