1

在现有代码中,对于某个失败案例有几个“原因”。这些“原因”的定义如下:

#define STRING_NOT_FOUND   (1 << 0)
#define STRING_INVALID     (1 << 1)
#define STRING_TOO_LARGE   (1 << 2)
...etc

这些是使用函数设置的setFailureReason(int reason);

与使用数字相比,在定义这些常量时使用移位运算符有什么优势,如下所示:

#define STRING_NOT_FOUND   1
#define STRING_INVALID     2
#define STRING_TOO_LARGE   4
4

4 回答 4

4

当你到达1 << 24或类似的东西时,它会变得更有用,大多数人不知道的是 16777216。

在这种特殊情况下,我不确定为什么它根本是一个“位域”——它可以与和/或STING_NOT_FOUND同时出现。STRING_INVALIDSTRING_TOO_LARGE

并且将使用正确的 C++ enum(即使在 C 中,这也是首选)。

于 2013-05-17T07:01:46.720 回答
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)
于 2013-05-17T07:03:34.647 回答
2

仅当您查看flags时,“二的幂”的使用才真正有意义,其中 0..n 可能会组合在一起。每个常量(或枚举值)代表在生成的十进制数中设置的特定位。

一方面,一旦你超过某个点,你必须开始做数学运算,写成小数的“二的幂”就变得笨拙了。(对我来说,这是 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 ) )
于 2013-05-17T07:19:20.050 回答
1

明显的区别是,使用上述运算符,您将拥有自然序列 (0,1,2,3,4,5,...) 与二的下一个幂 (1,2,4,8,16,32, ...)。第一个更短(log10 n vs log10 2^n)并且可以说更容易理解。

DevSolar 还提出了一个非常重要的观点,即知道比特的数量。我个人记得 2 到 16 的所有幂,所以我从来没有真正想过它。

另请注意,在 C++ 中,首选 const 或 constexpr 变量,或者,正如 Mats 建议的那样,枚举。

于 2013-05-17T06:59:39.403 回答