如何将位用于控制语句表达式

How to use bits for control statement expression?

本文关键字:控制语句 表达式 用于      更新时间:2023-10-16

我使用这个答案中的指令来获取和设置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 printn");
}
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 printedn");
}
....

打印:

必须打印

这不应该打印

很明显,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语句如何使用位表达式呢?

(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);
}

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

但我无法判断这些代码在做什么。出现错误的可能性很高。

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

顺便说一句,如果这是c代码,就不应该强制转换calloc的结果。另一方面,如果是C++代码,则不应该使用C样式的强制转换。