我使用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)));
chars
是unsigned long int
那么if语句如何使用位表达式?
答案 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风格的演员表。