C++ 如何为控制语句表达式使用位?

C++ 如何为控制语句表达式使用位?,c++,C++,我正在使用应答中的说明来获取和设置字符的位值。设置和获取没有/不应该有任何问题(语义上与链接答案相同) 问题是我不能在控制语句中正确使用它的位值(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(c

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

问题是我不能在控制语句中正确使用它的位值(
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");
}
....
chars
是一个
unsigned long int


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

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

但我无法理解你如何知道这些代码在做什么。有bug的几率很高

我建议编写一些单独的函数来读取/清除/设置数组中的特定位。那么你在做什么就会变得更清楚

顺便说一句,如果这是c代码,您不应该强制转换calloc的结果。另一方面,如果是C++代码,就不应该使用C样式的转换。
(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);
}
//为了清楚起见,没有安全性
无效集(无符号长整型*位,大小为)
{
bits[find_container(which)]|=1>find_bit(which))&1;
}
//范例
如果(!get(marks,k))
{
设置(标记,k);
}

我建议您将整个
((k-3)/2)/(sizeof(char)*8)
表达式放在函数或宏中,这样可能更容易看到您在做什么,也更容易读写代码。表达式也可以稍微简化,因为
sizeof(char)
总是指定返回
1
。该代码是。。。非凡的你在写C还是C++?选择一个。为什么不直接使用
std::bitset
而不是这个让我眼睛流血的代码呢?@BleedingFingers那么,
vector
就可以使用了。甚至在这一阶段,boost::dynamic_bitset
@BleedingFingers,boost库实际上是本地的。他们的许多或大部分课程都进入了标准。
// 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);
}