关于C中test_bit宏的问题

时间:2011-09-19 12:14:24

标签: c macros bit-manipulation

我在C中使用了以下宏:

#define   test_bit(_n,_p)     !! ( _n & ( 1u << _p))

我研究了宏,但我需要确定宏中双重否定的使用,以及它与宏定义的行为方式不同:

#define   test_bit(_n,_p)     ( _n & ( 1u << _p))

3 个答案:

答案 0 :(得分:10)

考虑测试特定位时会发生什么:

  1111 1111 (0xff)
& 0000 0100 (0x04, bit 2)
  ---- ----
= 0000 0100 (0x04)

如果你这样离开,你的结果就是位掩码本身。

现在考虑对此的双重否定,与什么都不做相同:

!4 -> 0
!0 -> 1

换句话说,!!4为您提供1而不是4,这可以保证您获得0/1真值而不是0/whatever-the-bitmask-was


以下程序显示了这一点:

#include <stdio.h>

#define test_bit0(_n,_p)   (_n & (1u << _p))
#define test_bit1(_n,_p) !!(_n & (1u << _p))

int main (void) {
    printf ("%d %d\n", test_bit0 (0xff, 2), test_bit1 (0xff,2));
    return 0;
}

并输出:

4 1

正如所料。

  

除此之外:现在编写代码的地方很少,因为现代编译器不仅可以自动编写代码并选择最有效的方法来执行((_n & (1u << _p)) != 0)之类的操作。并且不要让我开始使用obtuse变量名,使用numberposition提供的可读性远远超过它在编译时丢失: - )

答案 1 :(得分:2)

如果使用某些算术或按位运算符链接宏,它的行为会有所不同。例如,如果你有

#define   test_bit(_n,_p)     ( _n & ( 1u << _p))

test_bit( whatever, 1 ) | test_bit( whatever, 4 )

结果与

的结果不同
#define   test_bit(_n,_p)     !! ( _n & ( 1u << _p))

双重否定只是another way of writing != 0

答案 2 :(得分:2)

基本上,双重否定的目的是将宏返回的值约束为0和1.在

if(test_bit(x, 5)) x=0; // (1)
array[test_bit(x, 5)] = 0; // (2)

在(1)中,两个定义都相同。在(2)中,第一个定义总是设置array[0]array[1],而第二个定义不设置。