5

サイズが2ビットと6ビットのデータメンバーを持つ構造体を定義する必要があります。メンバーごとにタイプを使用する必要がcharありますか?または、メモリを無駄にしないために、:2\:6表記のようなものを使用できますか?どうやってやるの?2ビットまたは6ビットタイプのtypedefを定義できますか?

4

3 に答える 3

7

次のようなものを使用できます。

typedef struct {
    unsigned char SixBits:6;
    unsigned char TwoBits:2;
} tEightBits;

次に使用します:

tEightBits eight;
eight.SixBits = 31;
eight.TwoBits = 3;

ただし、正直なところ、アプリケーションの外部にあるパックされたデータに準拠する必要がある場合、またはメモリが非常に限られた状況にある場合を除いて、この種のメモリ節約は通常価値がありません。ビット単位およびビットシフト演算で常にデータをパックおよびアンパックする必要がない場合、コードははるかに高速であることがわかります。


_Boolまた、、signed intまたは以外のタイプの使用はunsigned int実装の問題であることに注意してください。具体的には、unsigned charどこでも機能しない場合があります。

于 2013-01-30T09:06:11.153 に答える
5

このようなものに使用するのがおそらく最善uint8_tです。そして、はい、ビットフィールドを使用してください:

struct tiny_fields
{
  uint8_t twobits : 2;
  uint8_t sixbits : 6;
}

ただし、コンパイラがこれを1バイトにパックするかどうかはわかりません。また、構造体タイプの値が占めるバイト内で、ビットがどのように順序付けられているかを知ることはできません。より詳細な制御が必要な場合は、明示的なマスクを使用することをお勧めします。

于 2013-01-30T09:06:08.267 に答える
2

個人的には、ビットフィールドよりもシフト演算子といくつかのマクロを好むので、コンパイラに「魔法」は残っていません。組み込みの世界では通常の習慣です。

#define SET_VAL2BIT(_var, _val) ( (_var) | ((_val) & 3) )
#define SET_VAL6BIT(_var, _val) ( (_var) | (((_val) & 63)  << 2) )

#define GET_VAL2BIT(_var) ( (_val) & 3)
#define GET_VAL6BIT(_var) ( ((_var) >> 2) & 63 )

static uint8_t my_var;

<...>
SET_VAL2BIT(my_var, 1);
SET_VAL6BIT(my_var, 5);
int a = GET_VAL2BIT(my_var); /* a == 1 */
int b = GET_VAL6BIT(my_var); /* b == 5 */
于 2013-01-30T10:24:05.230 に答える