使用位操作来设置一些标志的最佳实践

tig*_*ero 5 bit-manipulation objective-c ios

我想打开/关闭代表难度级别的3颗星.我不想使用几个if条件,是否可以通过使用按位运算来实现?

假设我已经声明了这样的枚举:

enum 
{
    EASY = 0,
    MODERATE,
    CHALLENGING
} Difficulty;
Run Code Online (Sandbox Code Playgroud)

我想找一点操作,让我找到打开或关闭哪颗星:

例如:

level 2 (challenging)
star 0 -> 1
star 1 -> 1
star 2 -> 1

level 1 (moderate)
star 0 -> 1
star 1 -> 1
star 2 -> 0

level 0 (easy)
star 0 -> 1
star 1 -> 0
star 2 -> 0
Run Code Online (Sandbox Code Playgroud)

Eze*_*eki 20

在这种情况下,如果你想有3位来保存你的星星状态,而不是你应该做的三个布尔标志:

typedef enum 
{
    DifficultyEasy = 1 << 0,
    DifficultyModerate = 1 << 1,
    DifficultyChallenging = 1 << 2
} Difficulty;

Difficulty state = 0; // default
Run Code Online (Sandbox Code Playgroud)

设置简易:

state |= DifficultyEasy;
Run Code Online (Sandbox Code Playgroud)

添加挑战:

state |= DifficultyChallenging;
Run Code Online (Sandbox Code Playgroud)

要重置Easy:

state &= ~DifficultyEasy;
Run Code Online (Sandbox Code Playgroud)

要知道具有挑战性的集合:

BOOL isChallenging =  DifficultyChallenging & state;
Run Code Online (Sandbox Code Playgroud)

如果有人需要解释它是如何工作的:

1 << x means set x bit to 1 (from right);
// actually it means move 0b00000001 left by x, but I said 'set' to simplify it 

1 << 5 = 0b00100000; 1 << 2 = 0b00000100; 1 << 0 = 0b00000001;

0b00001111 | 0b11000011 = 0b11001111 (0 | 0 = 0, 1 | 0 = 1, 1 | 1 = 1)

0b00001111 & 0b11000011 = 0b00000011 (0 & 0 = 0, 1 & 0 = 0, 1 & 1 = 1)

~0b00001111 = 0b11110000 (~0 = 1, ~1 = 0)
Run Code Online (Sandbox Code Playgroud)

  • 这帮助了我很多,谢谢你的精彩解释! (2认同)

Tob*_*obi 5

你会想做这样的事情:

typedef enum Difficulty : NSUInteger
{
    EASY = 1 << 0,
    MODERATE = 1 << 1,
    CHALLENGING = 1 << 2
} Difficulty;
Run Code Online (Sandbox Code Playgroud)

然后检查一下:

- (void) setStarsWithDifficulty:(Difficulty)diff
{
    star0 = (diff & (EASY | MODERATE | CHALLENGING));
    star1 = (diff & (MODERATE | CHALLENGING));
    star2 = (diff & CHALLENGING);
}
Run Code Online (Sandbox Code Playgroud)