如果您正在存储“布尔数组”或设置标志,这可能很有用。例如,您可以一次初始化或比较最多64个值。
这些宏适用于无符号字符、短整型、整型、长长整型等类型,但如果您只选择一种类型(因此您可以使用更安全的静态内联函数),则会显着简化。
#define getbit(x,n) x[n/(sizeof(*x)*8)] & (typeof(*x))1 << (n&((sizeof(*x)*8)-1))
#define setbit(x,n) x[n/(sizeof(*x)*8)] |= (typeof(*x))1 << (n&((sizeof(*x)*8)-1))
#define flpbit(x,n) x[n/(sizeof(*x)*8)] ^= (typeof(*x))1 << (n&((sizeof(*x)*8)-1))
#define clrbit(x,n) x[n/(sizeof(*x)*8)] &= ~( (typeof(*x))1 << (n&((sizeof(*x)*8)-1)) )
要初始化一个大的布尔数组,你只需要这样做:char cbits[]={0,0xF,0,0xFF};
或者对于全零:char cbits[4]={0};
另外还有一个int的例子:int ibits[]={0xF0F0F0F0,~0};
//1111000011110000111100001111000011111111111111111111111111111111
如果你只会访问1种类型的数组,那么最好将宏定义变成适当的函数,例如:
static inline unsigned char getbit(unsigned char *x, unsigned n){
return x[n>>3] & 1 << (n&7);
}
//etc... similar for other types and functions from macros above
你也可以通过使用“|”将多个标志组合在一起并使用“&”掩码进行比较;但是,当超出本机类型时,它会变得更加复杂。
对于你的特定情况,你可以通过以下方式初始化为所有零:
unsigned char flags[128]={0}
将所有数字变为1,方法如下:
uint64_t flags[128] = {~0,~0,~0,~0,~0,~0,~0,~0,~0,~0,~0,~0,~0,~0,~0,~0};
你甚至可以使用枚举来为你的标志命名。
enum{
WHITE,
RED,
BLUE,
GREEN,
...
BLACK
}
if (getbit(flags,WHITE) && getbit(flags,RED) && getbit(flags,BLUE))
printf("red, white and blue\n");
unsigned long long
或uint64_t
之类的类型。位字段偶尔有其用处,但绝对不是这种情况。 - Jonathan Leffler