解析协议时,取得位域的值是一种常见操作,这些宏可以辅助我们工作。
/*
** 将x的第n位置1
**
** x = 0x00000000
** BIT_SET(x, 7) = 0x00000080
*/
#define BIT_SET(x, n) ((x) | (1 << (n)))/*
** 将x的第n位置为0
**
** x = 0x00000080
** BIT_CLR(x, 7) = 0x00000000
*/
#define BIT_CLR(x, n) ((x) & ~(1 << (n)))/*
** 将x的第n到m位置位(使用0U而非0很关键,0的类型是int)
**
** x = 0x00000000
** BITS_SET(x, 8, 15) = 0x0000FF00
*/
#define BITS_SET(x, n, m) ((x) | ((~0U >> (sizeof((x)) * 8 - ((m) - (n) + 1))) << n))/*
** 清除x的第n到m位
**
** x = 0x11223344
** BITS_CLR(x, 8, 15) = 0x11220044
*/
#define BITS_CLR(x, n, m) ((x) & ~((~0U >> (sizeof((x)) * 8 - ((m) - (n) + 1))) << n))/*
** 获取x第n到m位的真值
**
** x = 0x11223344
** BITS_GET(x, 8, 15) = 0x00003300
*/
#define BITS_GET(x, n, m) ((x) & (((1 << ((m) - (n) + 1)) - 1) << (n)))/*
** 获取x第n到m位的数值
**
** x = 0x11223344
** BITS_VAL(x, 8, 15) = 0x00000033
*/
#define BITS_VAL(x, n, m) (((x) & (((1 << ((m) - (n) + 1)) - 1) << (n))) >> n)/*
** 设置x的第n到m位为指定值v
**
** x = 0b110[0111]1
** BITS_PUT(x, 1, 4, 0b1101) = 0b110[1101]1
**
*/
#define BITS_PUT(x, n, m, v) (BITS_CLR(x, n, m) | (v << n))
这是测试程序
int main()
{assert(BIT_SET(0x00000000, 7) == 0x00000080);assert(BIT_CLR(0x00000080, 7) == 0x00000000);assert(BITS_SET(0x00000000, 8, 15) == 0x0000FF00);assert(BITS_GET(0x11223344, 8, 15) == 0x00003300);assert(BITS_VAL(0x11223344, 8, 15) == 0x00000033);assert(BITS_CLR(0x11223344, 8, 15) == 0x11220044);assert(BITS_PUT(0b11001111, 1, 4, 0b1101) == 0b11011011);
}