关于比特数组 下列宏定义完成什么功能

wendy_welcom 2008-02-19 11:00:26
#define BITMASK(b) (1 << ((b) % 8))
#define BITSLOT(b) ((b) / 8)
#define BITSET(a, b) ((a)[BITSLOT(b)] |= BITMASK(b))
#define BITTEST(a, b) ((a)[BITSLOT(b)] & BITMASK(b))

我一看见位运算就发蒙,愁煞俺也。 请前辈 给我详细讲一下 每一步 都做了什么,完成什么功能 可以么?麻烦各位了。 谢谢。
...全文
512 15 打赏 收藏 举报
写回复
15 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
wendy_welcom 2008-02-20
谢谢 Itc_mouse ^_^
  • 打赏
  • 举报
回复
liufangbj 2008-02-20
路过
  • 打赏
  • 举报
回复
ltc_mouse 2008-02-20
#define BITSET(a, b) ((a)[BITSLOT(b)] |= BITMASK(b))
a 是数组的首地址是么? (a)[BITSLOT(b)] 为什么不写成 a[BITSLOT(b)] ?

---------------
在宏内部,你可以看成a是数组的首地址,从而更容易理解这个宏;实际调用时只要是个地址/指针就可以了
加括号是一种良好的宏定义风格,避免宏展开时发生错误,想必lz在学宏定义时见过这个吧:
#define PRODUCT(x,y) (x)*(y)
教材都会强调(x),(y)的括号问题,是同一个道理

本例中,如下调用是合理的:
int arr[16];
BITSET(arr+1, pos);
如果(a)不加括号,则展开成了arr+1[((pos)/8)] |= (1<<((pos)%8)); 编译错误...

manio的回复中提到b位置,应该是手误了。lz的疑问没错,是b%8位置
  • 打赏
  • 举报
回复
wendy_welcom 2008-02-20
manio 发表于:2008-02-19 11:47:10

//数组a的第b/8个元素的第b位置是否为1,如为1,则表达式为1,为0则表达式为0
#define BITTEST(a, b) ((a)[BITSLOT(b)] & BITMASK(b))


第b位置 还是 第b%8位置 ??
  • 打赏
  • 举报
回复
manio 2008-02-19
领教了
  • 打赏
  • 举报
回复
erwin1984 2008-02-19
1<<2 如果从二进制的角度看,那就是 00000100
这个数字与一个数字c做 | 操作则可以将c第三位置1。
这个数字与一个数字c做 & 操作则可以将c的其余位清0,除了第三位,用来检测第三位是否为1。

因为每个BYTE类型只有8位,b/8则计算出b在整个BYTE数组中的存储偏移字节数,b%8 则计算出 b 在一个BYTE中的存储偏移位数, 即用 b/8 和 b%8 来确定要将数组a的哪个字节及这个字节的哪个位将其置1或0或检测是否为1。

可以将BYTE a[] 看作一个二维的BIT数组。
a[0] 00000000
a[1] 00000000
a[2] 00000000
a[3] 00000000
a[4] 00000000
...
b/8确定行,b%8确定列。
  • 打赏
  • 举报
回复
manio 2008-02-19
#include <stdio.h>

//设置MASK的位置,模8是为了限制最多只能左移7位.
//如BITMASK(2) 的值为0x04
#define BITMASK(b) (1 << ((b) % 8))
//除8相当于将b右移三位
//如BITSLOT(0X08)值为1
#define BITSLOT(b) ((b) / 8)

//将数组a的第b/8个元素的第b位置为1
#define BITSET(a, b) ((a)[BITSLOT(b)] |= BITMASK(b))
//数组a的第b/8个元素的第b位置是否为1,如为1,则表达式为1,为0则表达式为0
#define BITTEST(a, b) ((a)[BITSLOT(b)] & BITMASK(b))

int main(void)
{
unsigned int a[100];
a[BITSLOT(0x17)] = 0x00;
printf("%d\n",BITMASK(0x17));
printf("%d\n",BITSLOT(0x17));

printf("%d\n",BITSET(a,0x17));
printf("%d\n",BITTEST(a,0x17));


system("pause");
}
  • 打赏
  • 举报
回复
wendy_welcom 2008-02-19
1<<2 实现 1*4 的功能
b/8 表示将b除8, 这是操作, 如果从机器内存储的角度讲, 为什么要这么做呢,它实现什么功能?

谢谢
  • 打赏
  • 举报
回复
pptor 2008-02-19


#define BITMASK(b) (1<<((b)%8))//相当于 2^(b)%8) [1左移((b)%8))]
#define BITSLOT(b) ((b)/8) //这个简单了
#define BITSET(a, b) ((a)[BITSLOT(b)]|=BITMASK(b))//数组元素 a[BITSLOT(b)]和BITMASK(b)
//做按位或操作 然后赋值给a[BITSLOT(b)]
#define BITTEST(a, b) ((a)[BITSLOT(b)]&BITMASK(b))
//数组元素 a[BITSLOT(b)]和BITMASK(b)做位与操作
  • 打赏
  • 举报
回复
erwin1984 2008-02-19
典型的位存储Hash,用一个BYTE数组 a 作为Hash桶来标示和测试数字b是否存在。

应用如:

首先定义BYTE数组a,初始化为0。
调用 BITSET(a,b) 来记录标记数字b已存在。
用BITTEST(a,b)来检测数字b是否已经存在。

这个与直接使用一个BYTE数组标识方法来比较可以将存储空间缩小到1/8;
  • 打赏
  • 举报
回复
Supper_Jerry 2008-02-19
具体的目的应当是:
#define BITSET(a, b) ((a)[BITSLOT(b)] ¦= BITMASK(b)) 设置数组a的第BITSLOT(b)个元素的第((b) % 8位为1
#define BITTEST(a, b) ((a)[BITSLOT(b)] & BITMASK(b)) 测试数组a的第BITSLOT(b)个元素的第((b) % 8位
  • 打赏
  • 举报
回复
Supper_Jerry 2008-02-19
#define BITMASK(b) 1<< ((b)%8)) 表示,将b取模8,然后将1左移b取模8的数值,比如b%8 = 2 1<<2 变为00000100
#define BITSLOT(b) ((b) / 8) 表示将b除8
#define BITSET(a, b) ((a)[BITSLOT(b)] ¦= BITMASK(b)) 其中a应当是个数组,取数组的第BITSLOT(b)个元素然后和BITMASK(b)做按位或操作
#define BITTEST(a, b) ((a)[BITSLOT(b)] & BITMASK(b)) 表示取组的第BITSLOT(b)个元素然后和BITMASK(b)做按位与操作
  • 打赏
  • 举报
回复
baihacker 2008-02-19
mark 学习一下
  • 打赏
  • 举报
回复
wendy_welcom 2008-02-19
manio 发表于:2008-02-19 11:47:10

//数组a的第b/8个元素的第b位置是否为1,如为1,则表达式为1,为0则表达式为0
#define BITTEST(a, b) ((a)[BITSLOT(b)] & BITMASK(b))


第b位置 还是 第b%8位置 ??
  • 打赏
  • 举报
回复
wendy_welcom 2008-02-19
#define BITSET(a, b) ((a)[BITSLOT(b)] |= BITMASK(b))

a 是数组的首地址是么? (a)[BITSLOT(b)] 为什么不写成 a[BITSLOT(b)] ?
  • 打赏
  • 举报
回复
相关推荐
发帖
C语言
加入

6.6w+

社区成员

C语言相关问题讨论
申请成为版主
帖子事件
创建了帖子
2008-02-19 11:00
社区公告
暂无公告