位欄位
可以使用簡單的位欄位來描述可能涉及特定位數的事物。
struct encoderPosition {
unsigned int encoderCounts : 23;
unsigned int encoderTurns : 4;
unsigned int _reserved : 5;
};
在這個例子中,我們考慮一個具有 23 位單精度和 4 位來描述多圈的編碼器。當與輸出與特定位數相關聯的資料的硬體介面時,經常使用位欄位。另一個例子可能是與 FPGA 通訊,其中 FPGA 以 32 位部分將資料寫入儲存器,允許硬體讀取:
struct FPGAInfo {
union {
struct bits {
unsigned int bulb1On : 1;
unsigned int bulb2On : 1;
unsigned int bulb1Off : 1;
unsigned int bulb2Off : 1;
unsigned int jetOn : 1;
};
unsigned int data;
};
};
在這個例子中,我們展示了一個常用的構造,能夠訪問各個位的資料,或者整個資料包的寫入(模擬 FPGA 可能做的事情)。然後我們可以訪問這樣的位:
FPGAInfo fInfo;
fInfo.data = 0xFF34F;
if (fInfo.bits.bulb1On) {
printf("Bulb 1 is on\n");
}
這是有效的,但根據 C99 標準 6.7.2.1,第 10 項:
單元內的位域分配順序(高階到低階或低階到高階)是實現定義的。
以這種方式定義位域時,你需要注意位元組序。因此,可能需要使用預處理程式指令來檢查機器的位元組順序。一個例子如下:
typedef union {
struct bits {
#if defined(WIN32) || defined(LITTLE_ENDIAN)
uint8_t commFailure :1;
uint8_t hardwareFailure :1;
uint8_t _reserved :6;
#else
uint8_t _reserved :6;
uint8_t hardwareFailure :1;
uint8_t commFailure :1;
#endif
};
uint8_t data;
} hardwareStatus;