簡體   English   中英

我如何在C中表示位信息?

[英]How do i represent bit info in C?

我需要在0到15之間存儲一個C值,4位就足夠了。 我怎么才能有一個4位的變量? 空間是這里的一個約束

考慮使用char 是的,它是8位,但你可以使用位移運算符( <<>> )來存儲其他4位的值。

編輯:根據下面的注釋,事實上, unsigned char優於char以避免符號位出現問題。

您可以使用位域來存儲4位,但是,除非您在結構中有幾個相鄰,否則不會節省任何空間而不是將值存儲在一個字節中。

你不可能真的有一個4位變量,但你可以有8位變量來存儲兩個4位值,但你必須使用temp訪問它們,這意味着除非你有更多的空間,否則你不會保存任何空間兩個以上:

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

正如Chris Lutz所指定的那樣,您可以通過添加冒號及其大小來定義變量使用的位數: unsigned char myOneBitVariable:1; 對於你的情況'unsigned char MyFourBitVariable:4'。 我想指出這是多么困難以及為什么要避免它

大多數現代編譯器都會在結構中為變量對齊空間。 今天最常見的情況是4個字節甚至8個字節,但這在不同平台和編譯器之間有所不同。 某些編譯器允許您指定數據及其成員的對齊方式。 在GCC上,關鍵字是__attribute__((aligned(x))) ,在MSVC上,它是__declspec(align(x)) 在大多數情況下,您還需要指定編譯器應該打包多少結構。 MSVC具有#pragma pack(x)指令: http//msdn.microsoft.com/en-us/library/2e70t5y1 #pragma pack(x) .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)之外的任何大小的結構都是編碼,可能導致難以調試錯誤。 Alignment-compiler指令最適合用於將數據與高速緩存行大小和類似的效率問題對齊。

Karl Bielefeldt提供了一個很好的自然解決方案,使用位移操作將4位值存儲到uint8中,而不是使用它們。

半字節的術語是半字節。 所以在這里:

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

您必須將兩個變量命名為xaxb (但將x更改為任何變量),但您將節省一點空間。 你可能想檢查一下 - 我認為編譯器會確保sizeof(struct two_nibbles) == sizeof(char)但它可能沒有,所以你可能需要添加更多的半字節以使其值得空間。

你是否想要獲取4位值的地址? 如果是這樣,您需要將它們存儲在“適當的”數據類型中,例如char。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM