C位数组宏,谁能解释我这些如何工作?

时间:2012-02-12 12:03:30

标签: c macros bitarray

我正在尝试为学校项目实施一些用于测试的方法,我决定使用位数组来实现。在我搜索材料时,我遇到了这3个宏,它们完美无缺,但我无法真正阅读(理解)它们。

#define ISBITSET(x,i) ((x[i>>3] & (1<<(i&7)))!=0)
#define SETBIT(x,i) x[i>>3]|=(1<<(i&7));
#define CLEARBIT(x,i) x[i>>3]&=(1<<(i&7))^0xFF;

请你详细解释一下至少其中一个,我对C中的按位操作有基本的了解(基本上我知道它们“存在”)。

这会在另一个使用不同字节序的架构上工作吗? 提前谢谢。

3 个答案:

答案 0 :(得分:5)

x是一系列字符。 i是位的索引。由于每个char是8位,i的最后3位定义了char中的位,其余位定义了数组中的char。

i>>3向右移动3位,因此您获得了告诉您哪个字符的部分,因此x[i>>3]是包含由i索引的位的字符。

i&7i的最后3位(自710==1112起),因此它是char中位的索引。 1<<(i&7)是一个char(真的是int,但在这个上下文中你可以忽略它的区别),它的位被i打开,其余位被关闭。 (比特的面具)

char&mask是检查位是否打开的常用方法。

char|=mask是改变位置的常用方法。

char&=~mask是关闭位的常用方法,如果mask是char,那么~mask==mask^0xFF

我不认为这些宏是依赖于endiannes的。 (如果您通过将x转换为int[]来获得*char,那就是另一个故事了)

答案 1 :(得分:4)

首先,这些宏假设CHAR_BIT == 8,而i >> 3实际上是i / 8。 (所以这段代码应该说i / CHAR_BIT。)第一个表达式计算包含所需位的字节,因此是数组x中的数组索引(应该是是unsigned char的数组!)。

现在我们已经选择了正确的字节,即x[i >> 3](或者你自己的x[i / CHAR_BIT],更好的代码),我们必须做一点点。同样,i & 7确实希望成为i % CHAR_BIT,并且它只提取位数的剩余部分,它会在字节内提供偏移

示例。使用i = 43请求第44位,并假设CHAR_BIT = 8i / CHAR_BIT为5,因此我们位于第6个字节,{ {1}}是3,所以我们看第六个字节的第四位。

实际的比特摆弄本身就是常见的东西;例如测试给定位以适当的位模式执行逐位AND(即i % CHAR_BIT位的1 << k;设置该位使用逐位OR,并将其归零需要更多的参与(想一想!)。

答案 2 :(得分:-1)

#define ISBITSET(x,i) (((x)[(i) / CHAR_BIT] & (1u << ((i) % CHAR_BIT))) != 0)
#define SETBIT(x,i) (x)[(i) / CHAR_BIT] |= (1u << ((i) % CHAR_BIT);
#define CLEARBIT(x,i) (x)[(i) / CHAR_BIT] &= ~(1u << ((i) % CHAR_BIT))
  • 始终将括号括在宏参数
  • 总是喜欢用于位操作的无符号类型
  • 对于8位平台,
  • (1u&lt;&lt; CHAR_BIT)为256
  • 在最后一个宏
  • 之后有一个exra ;