수색…
소개
비트 필드는 C 및 C ++ 구조를 단단히 묶어 크기를 줄입니다. 이것은 어려움없이 나타납니다. 멤버의 비트 수를 지정하면 컴파일러가 비트를 공동으로 작업합니다. 이 제한은 비트 필드 멤버가 공동으로 저장되기 때문에 비트 필드 멤버의 주소를 가져올 수 없다는 것입니다. sizeof()
도 허용되지 않습니다.
비트 필드의 비용은 액세스가 느려지므로 메모리를 검색하고 멤버 값을 추출하거나 수정하기 위해 비트 연산을 적용해야합니다. 이러한 작업은 실행 가능 크기에 추가됩니다.
비고
비트 연산은 얼마나 비쌉니까? 간단한 비 비트 필드 구조를 가정 해보십시오.
struct foo {
unsigned x;
unsigned y;
}
static struct foo my_var;
나중에 코드에서 :
my_var.y = 5;
sizeof (unsigned) == 4
이면 구조체의 시작 부분에 x가 저장되고 y는 4 바이트로 저장됩니다. 생성 된 어셈블리 코드는 다음과 유사 할 수 있습니다.
loada register1,#myvar ; get the address of the structure
storei register1[4],#0x05 ; put the value '5' at offset 4, e.g., set y=5
이것은 x가 y와 공존하지 않기 때문에 간단합니다. 그러나 비트 필드를 사용하여 구조를 재정의한다고 상상해보십시오.
struct foo {
unsigned x : 4; /* Range 0-0x0f, or 0 through 15 */
unsigned y : 4;
}
x
와 y
는 모두 4 비트로 할당되어 단일 바이트를 공유합니다. 따라서 구조체는 8 대신에 1 바이트를 차지합니다. 어셈블리가 y
를 설정하도록 고려합니다. 상위 nibble에서 끝나는 것으로 가정합니다.
loada register1,#myvar ; get the address of the structure
loadb register2,register1[0] ; get the byte from memory
andb register2,#0x0f ; zero out y in the byte, leaving x alone
orb register2,#0x50 ; put the 5 into the 'y' portion of the byte
stb register1[0],register2 ; put the modified byte back into memory
이러한 구조가 수천 또는 수백만 개에 이르면 좋은 트레이드 오프가 될 수 있으며, 캐시에 메모리를 유지하거나 스왑 핑을 방지하는 데 도움이되거나 이러한 문제를 악화시키고 처리 속도를 저하시킬 수있는 실행 파일을 부 풀릴 수 있습니다. 모든 것과 마찬가지로 좋은 판단을 사용하십시오.
장치 드라이버 사용 : 비트 필드를 장치 드라이버에 대한 영리한 구현 전략으로 사용 하지 마십시오. 비트 필드 저장 레이아웃은 컴파일러간에 반드시 일관성이 없으므로 이러한 구현을 이식 할 수 없게 만듭니다. 설정 값에 대한 읽기 - 수정 - 기록은 예상치 못한 동작을 야기하는 장치가 기대하는 것을 수행하지 않을 수 있습니다.
선언 및 사용
struct FileAttributes
{
unsigned int ReadOnly: 1;
unsigned int Hidden: 1;
};
이 두 필드는 각각 메모리에서 1 비트를 차지합니다. 다음에 의해 지정됩니다 : 1
변수 이름 뒤에 : 1
표현식. 비트 필드의 기본 유형은 모든 정수 유형 (8 비트 int에서 64 비트 int)이 될 수 있습니다. unsigned
유형을 사용하는 것이 좋습니다. 그렇지 않으면 놀라움이 올 수 있습니다.
더 많은 비트가 필요한 경우 "1"을 필요한 비트 수로 대체하십시오. 예 :
struct Date
{
unsigned int Year : 13; // 2^13 = 8192, enough for "year" representation for long time
unsigned int Month: 4; // 2^4 = 16, enough to represent 1-12 month values.
unsigned int Day: 5; // 32
};
전체 구조는 22 비트를 이용하고, 정상 컴파일러 설정 상태 sizeof
이 구성 4 바이트 일 것이다.
사용법은 매우 간단합니다. 그냥 변수를 선언하고 일반 구조처럼 사용하십시오.
Date d;
d.Year = 2016;
d.Month = 7;
d.Day = 22;
std::cout << "Year:" << d.Year << std::endl <<
"Month:" << d.Month << std::endl <<
"Day:" << d.Day << std::endl;