Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Archives
Today
Total
05-16 20:20
관리 메뉴

nomad-programmer

[Programming/C] 비트 단위로 제어하기 (Struct Bit Field 활용) 본문

Programming/C

[Programming/C] 비트 단위로 제어하기 (Struct Bit Field 활용)

scii 2021. 1. 22. 21:50

비트 필드는 구조체와 흡사하나 구조체는 바이트 단위로 멤버를 사용할 수있지만 비트 필드는 비트 단위로 멤버를 사용할 수 있다. 그래서 많은 상태를 저장하거나 비트별로 제어해야 하는 경우에 비트 필드를 사용한다.
비트 필드의 멤버는 unsigned형(unsigned int형)과 int형의 멤버를 가질 수 있고 비트 필드 변수의 크기는 int형 크기와 같은 4바이트(32비트)이다. signed와 unsigned는 char, short, int, long 등의 자료형 앞에 사용되어 부호가 있는 정수와 부호가 없는 정수를 나타내는 자료형으로 사용되며 signed는 보통 생략하여 사용한다.

비트 필드처럼 unsigned가 단독으로 사용되면 unsigned int형을 간략하게 표현한 형태이다.

비트 필드의 32bit 구조


다음은 비트 필드를 사용하여 1비트씩 제어하는 예제이다.

#include <stdio.h>
#include <string.h>

typedef struct _bitfield{
    unsigned b0 : 1;
    unsigned b1 : 1;
    unsigned b2 : 1;
    unsigned b3 : 1;
    unsigned b4 : 1;
    unsigned b5 : 1;
    unsigned b6 : 1;
    unsigned b7 : 1;
} bitfield;

int main(int argc, const char * argv[]) {
    bitfield bit;
    
    memset(&bit, 0, sizeof(bitfield));
    
    bit.b0 = 1;
    bit.b7 = 1;
    
    printf("%d\n", sizeof(bitfield));
    printf("%08x %d\n", bit, bit);

    return 0;
}

/* 결과
4
00000081 129
*/

32비트 메모리 표현

memset() 함수를 사용하여 bit 변수 4바이트를 0으로 초기화하고 bit.b0와 bit.b7을 1로 만들어 결과는 0x81이 된다. bit 변수는 32비트 중 8비트만을 사용한다.


다음은 비트 필드를 사용하여 원하는 곳의 비트만을 제어하는 예제이다.

#include <stdio.h>
#include <string.h>

typedef struct _bitfield {
    unsigned b0     : 1;
    unsigned        : 7;
    unsigned b8     : 1;
    unsigned        : 7;
    unsigned b16    : 1;
    unsigned        : 7;
    unsigned b24    : 1;
//    unsigned        : 7;
} bitfield;

int main(int argc, const char * argv[]) {
    bitfield bit;
    
    memset(&bit, 0, sizeof(bitfield));
    
    bit.b0 = 1;
    bit.b8 = 1;
    bit.b16 = 1;
    bit.b24 = 1;
    
    printf("%d\n", sizeof(bit));
    printf("%08x %d\n", bit, bit);

    return 0;
}

/* 결과
4
01010101 16843009
*/

32비트 메모리 표현

b0(1비트 사용), b8(1비트 사용), b16(1비트 사용), b24(1비트 사용) 다음의 멤버 이름이 없어 7비트씩을 사용하지 않는다. 따라서 결과는 "0x01010101" 이다.


다음은 비트 필드를 사용하여 4바이트 중 1바이트씩 제어하는 예제이다. 각각 'a', 'b', 'c', 'd' 문자를 입력하면 문자에 해당하는 1바이트씩을 on/off 한다.

#include <stdio.h>
#include <string.h>

typedef struct _bitfield {
    unsigned D : 8;
    unsigned C : 8;
    unsigned B : 8;
    unsigned A : 8;
} bitfield;

int main(int argc, const char * argv[]) {
    char ch = 0;
    int isContinue = 1;
    bitfield bit;
    
    memset(&bit, 0, sizeof(bitfield));
    
    while(isContinue){
        printf("%08X\n", bit);
        fputs("input: ", stdout);
        ch = getchar();
        while(getchar() != '\n');
        switch(ch) {
            case 'a': case 'A':
                bit.A ^= 0xFF;
                break;
            case 'b': case 'B':
                bit.B ^= 0xFF;
                break;
            case 'c': case 'C':
                bit.C ^= 0xFF;
                break;
            case 'd': case 'D':
                bit.D ^= 0xFF;
                break;
            default:
                isContinue = 0;
                break;
        }
    }

    return 0;
}

/* 결과
00000000
input: a
FF000000
input: b
FFFF0000
input: c
FFFFFF00
input: d
FFFFFFFF
input: d
FFFFFF00
input: c
FFFF0000
input: b
FF000000
input: a
00000000
*/

32비트 메모리 표현

main() 함수는 'a', 'b', 'c', 'd' 문자이면 프로그램을 실행하고 아니면 종료한다. bitfield bit의 각 1바이트씩을 문자에 따라 ^ 연산자를 사용하여 on/off 한다.

Comments