http://www.cs.cf.ac.uk/Dave/C/node13.html#SECTION001320000000000000000
Bit-field是C語言中比較低階的用法, 可以把一個structure中的bits做更細的切割來存取
比如以下的union / struct混合型
union {
uint32_t packed;
struct {
uint8_t flag1: 1;
uint8_t flag2: 1;
uint8_t type: 4;
} bits;
} x;
通常會使用到bit-field的場合:
偷空間
這應該是最主要的理由
某些structure member的值範圍不大, 就可以用bit-field的方式, 將一些member合併在一起
特殊Header structure
以IPv4 header為例
http://en.wikipedia.org/wiki/IPv4#Header
可以用這樣的struct來存取
typedef struct {
uint8_t ver: 4;
uint8_t ihl: 4;
uint8_t dcsp: 6;
uint8_t ecn: 2;
uint16_t total;
...
} ipv4_header_t;
PS: 這是big endian的寫法!
寫driver時
使用bit-field來寫就可以模擬成OOP的方式, 對programmer比較friendly
以8051 TMOD register為例 http://www.8052.com/tuttimer.phtml
可以用這樣的structe來存取
typedef struct {
uint8_t t0m0: 1;
uint8_t t0m1: 1;
uint8_t t0: 1;
uint8_t gate0: 1;
uint8_t t1m0: 1;
uint8_t t1m1: 1;
uint8_t t1: 1;
uint8_t gate1: 1;
} tmod_t;
PS: 這是little endian的寫法!
Boolean flags
通常程式中用的是Boolean flag, 也就是只有true/false兩種值, 但一個flag變數起碼會佔用1 byte的空間 利用bit-field可以合併不同的flag, 省下空間
特別是函數中的local flags, 用這個技巧, 還能降低CPU register使用量, 提高效率
例如:
int func (int arg)
{
union {
uint8_t packed;
struct {
uint8_t isArgValid: 1;
uint8_t isError: 1;
uint8_t isDone: 1;
};
} flags;
flags.packed = 0;
...
if (arg > 0)
flags.isArgValid = 1;
...
if (!flags.isArgValid)
return 0;
...
return 1;
}
沒有留言:
張貼留言