2010-08-07 3 views

답변

7

char을 사용해보십시오. 예, 8 비트이지만 비트 쉬프트 연산자 (<<>>)를 사용하여 다른 4 비트에 값을 저장할 수 있습니다.

편집

: 아래의 코멘트를, unsigned char는 부호 비트와 문제를 방지 할 char 이상 바람직 사실이다.

+0

비트 연산자를 사용하여 두 개의 4 비트 값을'char'에 저장할 수 있습니다. 그러나'unsigned char'을 사용해야합니다. 그렇지 않으면 부호있는 이동으로 불안정한 동작을 보게 될 것입니다. –

4

구조체에 인접한 숫자가없는 한 bitfield을 사용하여 4 비트를 저장할 수 있지만, 값을 저장할 때 공간을 절약 할 수는 없습니다.

+1

인접 해 있다고해도 컴파일러가 메모리에서 실제로 그런 식으로 정렬하고 그런 식으로 데이터 구조를 압축한다는 것은 확실하지 않습니다. 대부분의 현대 컴파일러는 시도 할지라도 그 구조를 특별히 포장하지 않습니다. 자세한 내용은 내 대답을 참조하십시오. – Simon

+0

또한 조건부를 사용하지 않고 비트 필드를 처리 할 방법이 없습니다. 만약 당신이'unsigned char'에 패킹을 직접한다면, 인덱스의 하위 비트를 간단하게 사용할 수 있습니다. '(i & 1) << 2'를 시프트 피연산자로 사용합니다. –

0

절반 바이트의 용어는 니블입니다. 그래서 여기 :

struct two_nibbles { 
    unsigned a :4; 
    unsigned b :4; 
} 

당신은 당신의 두 변수 x.ax.b 이름 (하지만 무엇에 x 변경)해야하지만, 당신은 약간의 공간을 절약 할 수 있습니다. 하지만 컴파일러가 sizeof(struct two_nibbles) == sizeof(char)을 확신 할 수 있다고 생각하지만, 그렇지 않을 수도 있습니다. 따라서 공간을 확보 할 수 있도록 니블을 더 추가해야 할 수도 있습니다.

+0

a와 b를 부호없는 것으로 정의하면 자동으로 정수가되며 따라서 4 바이트를 차지합니까? – Laz

+0

아니요 - Chris의 여기에 표시된 표기법을 사용하여 구조체의 부호없는 정수와 정확히 일치하는을 지정할 수 있습니다. 위의 예에서 필드 a와 b는 각각 4 비트를 사용합니다. 컴파일러가 이러한 구조체의 끝에 패딩을 추가 할 수도 있다는 것을 기억하는 것이 중요합니다. – gnud

+0

컴파일러 **는 (실제로) 4+ 바이트로 만듭니다. 'unsigned char a : 4;를 사용해야합니다. unsigned char b : 4;'또는 더 나은 아직 비트 필드 (C 언어에서 가장 멍청하고 쓸모없는 것들 중 하나)을 버리고 비트 산술을 직접 해보면 잘 정의 된 동작을 얻을 수 있습니다. 비 휴대 해킹에 대해서는 –

3

하나의 4 비트 변수를 실제로 가질 수는 없지만 2 개의 4 비트 값을 저장하는 8 비트 변수를 가질 수 있지만 임시로 액세스해야합니다. 즉, 공간을 절약하지 못합니다 더이 이상이없는 경우 : unsigned char myOneBitVariable:1; 및 귀하의 경우 '서명 숯불의 MyFourBitVariable을 위해 : 크리스 루츠가 지정된대로

uint8_t var_both; 
uint8_t temp = (var_both >> 4) & 0x0F; // For first value 
temp = var_both & 0x0F; // For second value 
2

, 당신은 변수가 콜론과 그것의 크기를 추가하여 사용하는 비트의 양을 정의 할 수 있습니다 : 4 '. 나는 이 매우 어렵다는 것을 지적하고 싶습니다.을 피해야하는 이유는 무엇입니까?

대부분의 최신 컴파일러는 구조체에 변수 공간을 정렬합니다. 오늘날 가장 일반적인 경우는 4 바이트 또는 8 바이트이지만 플랫폼에 따라 다르며 컴파일러에 따라 다릅니다. 일부 컴파일러에서는 데이터와 멤버의 정렬을 지정할 수 있습니다. GCC에서 키워드는 __attribute__((aligned(x)))이고 MSVC에서는 __declspec(align(x))입니다. 대부분의 경우 컴파일러가 구조체를 얼마나 많이 포장해야하는지 지정해야합니다. MSVC에는 #pragma pack(x) 지시문이 있습니다 (http://msdn.microsoft.com/en-us/library/2e70t5y1(VS.80).aspx). MSVC 정렬에 대해서도 여기에서 읽을 수 있습니다 : http://msdn.microsoft.com/en-us/library/83ythb65(VS.80).aspx. GCC에는 __attribute__ ((__packed__)이라는 자체 구현이 있습니다.이 구현은 주변을 검색해야 할 수도 있습니다. 마이크로 소프트의 컴파일러를 사용하여, 당신이 원하는 당신을 제공하지 않습니다 예 :


#ifndef _MSC_VER 
#error This alignment solution/packing solution is only valid on MSC 
#endif /* ifndef _MSC_VER */ 

#define M_ALIGN(x) __declspec(align(x)) 

struct S64Bits 
{ 
    unsigned char MyOneBitVariable:1; 
    int My32BitInt; 
}; 

// MSVC specific implementation of data-packing in a type. 
#pragma pack(1) 
struct S32Bits 
{ 
    D_ALIGN(1) int My16BitVariable:16; 
    D_ALIGN(1) unsigned char Padding8Bits; 
    D_ALIGN(1) unsigned char MyOneBitVariable1:1; 
    D_ALIGN(1) unsigned char MyOneBitVariable2:1; 
    D_ALIGN(1) unsigned char MyOneBitVariable3:1; 
    D_ALIGN(1) unsigned char MyOneBitVariable4:1; 
    D_ALIGN(1) unsigned char MyFourBitVariable:4; 
}; 
#pragma pack(pop) 

년대는 sizeof (S64Bits는) '가되는, 8해야한다. 'sizeof (S32Bits)'는 인 경우 4가되어야이 아닙니다. msvc에서 후자는 6 바이트입니다. 이 동작은 컴파일러에 따라 다르며 컴파일러 고유의 지시문을 사용하는 경우가 많습니다. 이런 종류의 행동은 당신이 원하는 것을 거의 결코 제공하지 못합니다. 나는 종종 내가 정말 어떤 크기로 필요 구조가 있는지 확인하기 위해 매크로를 사용 :


#define TEST_TYPE_SIZE(Type, Size) assert(sizeof(Type) == Size); 

나는 내가 그들의 정확한 크기를 지정하려고 내 모든 데이터 유형 아래에 사용할 것이다. 그러나 sizeof (mystructure)가 아닌 다른 크기의 구조를 사용하면 오류를 디버그하기가 어려울 수 있습니다.정렬 - 컴파일러 지시문은 데이터를 캐시 라인 크기 및 유사한 효율 문제에 정렬하는 데 가장 적합합니다.

Karl Bielefeldt는 비트 시프트 연산을 사용하여 uint8에 4 비트 값을 저장하는 좋은 자연적 솔루션을 제공합니다.

+0

-1, 가능하다면 비트 필드 사용에 대해서는 -1입니다. 간단히 비트 산술을 직접하십시오. 더 쉽고, 이식성 있으며, 명확하게 정의 된 동작을 나타내며 오류가 발생하지 않습니다. –

+1

비 휴대용 해킹? 필자는 컴파일러 세부 사항에 대해 명확하게 설명합니다. 매너로 데이터를 포장하는 경우 각 컴파일러가 데이터를 포장하고 정렬하는 방법을 알아야합니다. 문제는 공간이 제약이기 때문에 4 비트 만 사용하는 방법이며 원하는 메모리 크기를 정확하게 얻는 데 필요한 정보를 제공하려고합니다. 비판을 조금 더 자세히 설명해 주시겠습니까? – Simon

+0

@R .. : 아마도이 방법을 사용하여 올바른 크기를 얻는 데 따르는 어려움에 관한 제 의견을 읽지 않았습니까? 아니면 구조 크기에 의존하는 것에 관한 본문을 읽지 않았습니까? 나는 그들이 왜 이런 종류의 솔루션을 사용해서는 안되는지 설명했다. 나의 논증은 이러한 솔루션을 사용하는 PRO가 아니 었습니다. – Simon

0

4 비트 값의 주소를 가져 가고 싶습니까? 그렇다면 char과 같은 "적절한"데이터 유형으로 저장해야합니다.

관련 문제