可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have a part of code that contains the following functions:
void Keyboard(int key)
{
switch (key) {
case GLFW_KEY_A: m_controlState |= TDC_LEFT; break;
case GLFW_KEY_D: m_controlState |= TDC_RIGHT; break;
case GLFW_KEY_W: m_controlState |= TDC_UP; break;
case GLFW_KEY_S: m_controlState |= TDC_DOWN; break;
default: Test::Keyboard(key);
}
}
void KeyboardUp( int key)
{
switch (key) {
case GLFW_KEY_A: m_controlState &= ~TDC_LEFT; break;
case GLFW_KEY_D: m_controlState &= ~TDC_RIGHT; break;
case GLFW_KEY_W: m_controlState &= ~TDC_UP; break;
case GLFW_KEY_S: m_controlState &= ~TDC_DOWN; break;
default: Test::Keyboard(key);
}
}
I know what a switch case is but i dont understand what these parts do.
m_controlState |= TDC_LEFT
m_controlState &= ~TDC_LEFT
m_controlState is an int. The GFLW_KEY's also refere to an int value.
Could someone explain what these parts do an example with input values and results would be nice.
回答1:
Also I think it should be explained what these operators do and are used this way.
m_controlState serves as flags, which means it contains in binary form which of the keys are pressed.
For example if the values of tds constants are chosed like this:
TDS_LEFT = 0x00001
TDS_RIGH = 0x01 << 2 = 0x00010
TDS_UP = 0x01 << 3 = 0x00100
TDS_DOWN = 0x01 << 4 = 0x01000
Then in single integer you can store information which options are set. To do that you just have to check if bit that corresponds on each setting is 1 or 0.
So to set TDS_LEFT option, you have to OR the current state with 0x00001( which is TDS_LEFT), so in code
m_controlState = m_controlState | TDS_LEFT
which is the same as
m_controlState |= TDS_LEFT.
To unset TDS_LEFT option you have to AND it with ~TDS_LEFT. So
m_controlState = m_controlState & ~TDS_LEFT
which is the same as:
m_controlState &= ~TDS_LEFT
You can also check: How to use enums as flags in C++?.
Hope that makes it clearer.
回答2:
&= |= operators in a sense are similar to +=/-= (i.e. a &= b is equivalent to a = a & b). But, they do binary operations. & is doing bitwise and operation, while | is doing bitwise or operation.
Example:
a = 1101
b = 1011
a & b = 1001
a | b = 1111
回答3:
These are bitwise AND and OR operations. The lines you mentioned are equivalent to:
m_controlState = m_controlState | TDC_LEFT;
m_controlState = m_controlState & ~TDC_LEFT
回答4:
x |= y
is equivalent to x = x|y
In general, for any binary operator *
, a *= b
is equivalent to a = a*b
If you want to know what &
and |
are, read about bitwise operators.
回答5:
These two:
m_controlState |= TDC_LEFT
m_controlState &= ~TDC_LEFT
are equivalent to:
m_controlState = m_controlState | TDC_LEFT
m_controlState = m_controlState & ~TDC_LEFT
It works like this with all builtin X= operators.
m_controlState
is most likely treated as a bitset. m_controlState
may be, e.g. 01010000
(realistically, it will be larger than 8 bits).
1) |
is bitwise or, which is equivalent to addition to that bitset.
So if TDC_LEFT is 00000010:
01010000 | 00000010 = 01010010
2) ~
is bitwise negation:
~00000010 = 111111101
And if you do
01010010 & ~(00000010) = 01010000
, it's effectively equivalent to bitset difference.
In short:
bitsetA + bitsetB <=> bitsetA | bitset
bitsetA - bitsetB <=> bitsetA & ~ bitset
回答6:
x |= y
specifically turns on (sets to 1) those bits in x
present in y
, leaving all the others in x
as they were.
x &= ~y
specifically turns off (sets to 0) those bits in x
present in y
, leaving all the others in x
as they were.
回答7:
it's a simple way to set & reset specific bit in a word.
bitword |= MASK is a shorthand of bitword = bitword | MASK which sets the mask bit
bitword &= ~MASK clears that bit (check your boolean algebra notebook to see why)