在现有代码中,某些失败案例存在一些“原因”。这些“原因”的定义如下:
#define STRING_NOT_FOUND (1 << 0)
#define STRING_INVALID (1 << 1)
#define STRING_TOO_LARGE (1 << 2)
...etc
这些是使用函数setFailureReason(int reason);
与使用数字相比,在定义这些常量时使用shift运算符有什么好处,如下所示:
#define STRING_NOT_FOUND 1
#define STRING_INVALID 2
#define STRING_TOO_LARGE 4
答案 0 :(得分:4)
当你到达1 << 24
或类似的东西时会更有用,大多数人不知道的是16777216.
在这种特殊情况下,我不确定它为什么是“位域” - 可以STING_NOT_FOUND
与STRING_INVALID
和/或STRING_TOO_LARGE
同时为enum
。
适当的C ++将使用{{1}}(即使在C中,这也是首选)。
答案 1 :(得分:3)
这主要用于错误代码表示其值可以逻辑化的位字段(VALUE_A | VALUE_B)。
使用移位运算符可提高可读性并防止有人使用现有的位组合(例如5位)插入新的错误代码。
可能是错的:
#define STRING_NOT_FOUND 1
#define STRING_INVALID 2
#define STRING_TOO_LARGE 4
#define STRING_SOMETHING_KO 5
可能会更好:
#define STRING_NOT_FOUND (1 << 0)
#define STRING_INVALID (1 << 1)
#define STRING_TOO_LARGE (1 << 2)
#define STRING_SOMETHING_KO (1 << 3)
答案 2 :(得分:2)
当您查看标志时,使用“两个权力”才有意义,其中0..n可能会合并。每个常量(或枚举值)代表在结果十进制数中设置的特定位。
首先,一旦超出某个点,你必须开始进行数学运算,写成小数的“2的幂”就会变得笨拙。 (对我来说,这是8192 x 2. ;-))
例如,硬件文档可能声明“设置寄存器的第4位和第8位”。考虑:
// set bit #4 and #8
reg |= 272;
或者:
// set bit #4 and #8
reg |= 0x110;
与:相比:
// set bit #4 and #8
reg |= ( ( 1 << 4 ) | ( 1 << 8 ) )
答案 3 :(得分:1)
明显不同的是,使用所述运算符,您将具有自然序列(0,1,2,3,4,5,...)与下一个2的幂(1,2,4,8,16)相比,32,......)。第一个更短(log10 n vs log10 2 ^ n),可以说更容易理解。
DevSolar在了解钻头数量方面也提出了非常重要的观点。我个人记得2到16的所有权力,所以我从未真正考虑过它。
另请注意,在C ++中,const或constexpr变量是首选,或者如Mats建议的那样,枚举。