完成@RhythmicFistman 的回答
@RhythmicFistman 的回答缺少一小部分,这是轮班的最后一步。
>> (7-((y)&0x07) 步骤确保您只得到 1 或 0 的结果。使用此代码可以安全地进行如下比较:
if (testbit(varible, 6) == 1) {
// do something
}
如果没有该步骤,testbit 将返回一个位掩码,其中第 6 位将设置为 1 或 0,而所有其他位始终设置为 0。这就是意图,但它没有在什么中实现被认为是一种便携方式,请参阅下面的警告 3。
使用此代码可能出现的问题
现在为其他答案添加一些内容。其他答案没有指出这里应该提到的一些关键字,它们是strict aliasing 和shift arithmetic right。我的详细说明将在下面以警告的形式出现。
警告 1:Endianness
此代码假定您使用的是big endian 架构,或者只希望从字符数组中获取正确的位。
原因是,如果您将int 转换为chars(字节)的数组,您将在big endian 机器和little endian 机器上得到不同的结果。
警告 2:Strict Aliasing
该宏使用(const char*) &(x) 类型转换,旨在更改(x) 的类型,也就是别名,以便更容易获得正确的位。
这是危险的,原因在this SO answer 中有很好的解释。简短的版本是,如果您使用优化编译此代码,可能会发生奇怪的事情。
Aliasing 和 Pointer Aliasing 上的维基百科页面也很有用,应该阅读。
警告 3:Shift Arithmetic Right
除此之外,此代码使用右移运算符>> 的方式可能存在潜在问题。此运算符有两种不同的行为,具体取决于它所操作的变量是 signed 还是 unsigned。只要您从不使用负数,您将是安全的,但此代码不会保护您免受该错误的影响。不过我怀疑,无论如何你不太可能犯这样的错误,所以使用它应该没问题。
另外值得一提的是,您正在使用signed char 并且正在将其正确移动。虽然这可行,但我更喜欢unsigned char,这将提高可移植性,因为当char 和int 的宽度相同时,它不会冒产生算术右移的风险(这在实践中几乎从未发生过,当然)。之所以有效,是因为 char 被提升为 int 以进行轮班,请参阅 this SO answer 以获得解释。