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

C 비트필드로 메모리 최적화: 플래그 압축과 하드웨어 매핑

비트필드(Bit-field)는 구조체 멤버의 비트 폭을 명시하여 메모리를 비트 단위로 압축하는 기능입니다. 플래그 집합, 하드웨어 레지스터 매핑, 프로토콜 헤더 파싱에 유용합니다.

비트필드 문법

struct {
    타입 멤버명 : 폭;
};

기본 예제: 플래그 압축

// 8개 불리언 플래그 → 1바이트로 압축
struct Flags {
    unsigned int read    : 1;
    unsigned int write   : 1;
    unsigned int execute : 1;
    unsigned int hidden  : 1;
    unsigned int system  : 1;
    unsigned int archive : 1;
    unsigned int : 2;   // 예약/패딩 2비트
};

struct Flags f = {0};
f.read = 1;
f.write = 1;
if (f.read && f.write) { ... }

// 크기 확인
printf("%zu\n", sizeof(struct Flags));  // 보통 4바이트 (int 크기로 정렬)

비트필드 메모리 레이아웃 (구현 의존적)

레이아웃 예시 (리틀엔디안, 32비트 int 기준)

struct {
    unsigned int a : 4;  // 비트 0-3
    unsigned int b : 4;  // 비트 4-7
    unsigned int c : 8;  // 비트 8-15
    unsigned int d : 16; // 비트 16-31
} packed;  // 크기 4바이트, 패딩 없음

struct {
    unsigned int a : 4;
    unsigned int : 0;    // 32비트 경계로 강제 이동
    unsigned int b : 4;  // 다음 워드 비트 0-3
} aligned;  // 크기 8바이트

실전 활용 예제

1. 파일 권한 비트 (유닉스 style)

struct FilePerm {
    unsigned int other_exec : 1;
    unsigned int other_write : 1;
    unsigned int other_read : 1;
    unsigned int group_exec : 1;
    unsigned int group_write : 1;
    unsigned int group_read : 1;
    unsigned int user_exec : 1;
    unsigned int user_write : 1;
    unsigned int user_read : 1;
    unsigned int sticky : 1;
    unsigned int setgid : 1;
    unsigned int setuid : 1;
    unsigned int : 4;  // 패딩
};

2. 네트워크 프로토콜 헤더 (TCP 플래그)

struct TCPFlags {
    unsigned int fin : 1;
    unsigned int syn : 1;
    unsigned int rst : 1;
    unsigned int psh : 1;
    unsigned int ack : 1;
    unsigned int urg : 1;
    unsigned int ece : 1;
    unsigned int cwr : 1;
};  // 1바이트에 8개 플래그

3. 하드웨어 레지스터 매핑

// GPIO 제어 레지스터 (가상 예시)
struct GPIO_Reg {
    unsigned int pin0  : 1;
    unsigned int pin1  : 1;
    unsigned int pin2  : 1;
    unsigned int pin3  : 1;
    unsigned int pin4  : 1;
    unsigned int pin5  : 1;
    unsigned int pin6  : 1;
    unsigned int pin7  : 1;
    unsigned int mode  : 4;   // 0=입력, 1=출력, 2=대체기능...
    unsigned int pull  : 2;   // 0=없음, 1=풀업, 2=풀다운
    unsigned int : 6;         // 예약
};  // 32비트 레지스터 1개에 매핑

4. 압축된 데이터 구조

// 날짜 저장: 년(12비트: 0~4095), 월(4비트: 1~12), 일(5비트: 1~31) = 21비트
struct CompactDate {
    unsigned int year  : 12;
    unsigned int month : 4;
    unsigned int day   : 5;
};  // 4바이트 (32비트 정렬) vs 구조체 12바이트 절약

제약사항과 주의점

비트필드 vs 비트 연산 수동 구현

// 비트필드 (가독성 좋음, 레이아웃 제어 제한)
struct { unsigned int flag : 1; } bf;
bf.flag = 1;

// 수동 비트 연산 (완전 제어, 이식성 높음)
#define FLAG_BIT 0
unsigned int flags = 0;
flags |= (1 << FLAG_BIT);     // 설정
flags &= ~(1 << FLAG_BIT);    // 해제
bool is_set = flags & (1 << FLAG_BIT); // 검사

모범 사례

C 언어

  1. C# 비트 연산자와 시프트 연산자 완전 정복: 종합 가이드
  2. C 사용자 정의 함수 4가지 검증된 패턴
  3. C 언어에서 1차원 및 2차원 배열을 함수에 전달하는 방법 – 실전 가이드
  4. C 구조체와 포인터 마스터하기: 실전 가이드
  5. Java this 키워드 완벽 가이드: 용도, 생성자, 실전 예제
  6. Java 캡슐화 마스터: 데이터 은닉 실전 가이드
  7. C++ 구조체(struct) 완벽 가이드: 선언, 인스턴스, 포인터, 함수 인자 전달
  8. C 함수 마스터: 선언, 정의, 호출, 인자 전달(값/참조), 재귀
  9. C 언어 가변 인자 마스터하기: 실전 가이드
  10. MATLAB 적분 마스터: 부정적분부터 리만 합, 정적분 응용까지
제약설명
주소 연산 불가&bitfield 컴파일 에러
배열 불가비트필드 배열 선언 불가
포인터 불가비트필드 포인터 선언 불가
타입 제한int, unsigned int, _Bool만 표준 보장 (컴파일러 확장 가능)
부호 있는 비트필드음수 표현 가능하나 구현 의존적 (2의 보수 일반적)
오버플로 동작폭 초과 값 대입 시 구현 정의 (보통 잘림)
스레드 안전성인접 비트필드 동시 수정 시 경쟁 발생 (RMW 연산)