如何使用位来控制语句表达式?

时间:2014-11-07 12:12:21

标签: c++

我使用this answer中的说明来获取和设置char的位值。设置和获取没有/不应该有任何问题(在语义上与链接的答案相同)。

问题是我无法在控制语句(if)中正确使用它的位值。

我遇到问题的相关代码:

unsigned long int find_container(unsigned long int k){
  return (k)/(sizeof(char)*8);
}

unsigned long int find_bit(unsigned long int k){
  return (k)%(sizeof(char)*8);
}

....
if (~(marks[find_container((k-3)/2)] >> (find_bit((k-3)/2)&1))){
  printf("must print\n");
}
marks[find_container((k-3)/2)] |= 1<<find_bit((k-3)/2);

if (~(marks[find_container((k-3)/2)] >> (find_bit((k-3)/2)&1))){
  printf("this shouldn't have been printed\n");
}
....

打印:

  

必须打印

     

这不应该打印

很明显,if语句不会采用位值表达式。

好吧,我尝试将位值转换为bool~(bool)((marks[find_container((k-3)/2)] >> (find_bit((k-3)/2)&1))),但它没有改变这种行为。

最初marks数组中的所有值都设置为零

marks = (char *)calloc( chars, (sizeof(char)));

charsunsigned long int

那么if语句如何使用位表达式?

2 个答案:

答案 0 :(得分:1)

(find_bit((k-3)/2)&1)

是0或1。

我认为你错了你的括号而你正在寻找

(marks[find_container((k-3)/2)] >> find_bit((k-3)/2)) & 1

我建议您添加用于操作位的抽象函数,它使代码更易读,更不容易出错。
这样的事情。

// No safety, for clarity
void set(unsigned long int* bits, size_t which)
{
   bits[find_container(which)] |= 1 << find_bit(which);
}

bool get(unsigned long int* bits, size_t which)
{
   return (bits[find_container(which)] >> find_bit(which)) & 1;
}

// example
if (!get(marks, k))
{
    set(marks, k);
}

答案 1 :(得分:0)

嗯,是的,你可以在if中使用任何值,并且不等于零的值被认为是真的。

但是你怎么知道所有代码在做什么都超出了我。有错误的可能性很高。

我建议编写一些单独的函数来读取/清除/设置数组中的特定位。然后你应该更清楚你正在做什么。

顺便说一下,如果这是c代码,你不应该转换calloc的结果。另一方面,如果它是C ++代码,你不应该使用C风格的演员表。