我试图允许多个案例在switch语句中运行。我有一个位掩码如下:
#define SHOOT_ROCKET 2 << 16
#define MOVE_FORWARD 3 << 16
后来,我做了
switch (int game_action)
我有
case SHOOT_ROCKET:
result = fire_weapon(rl);
我不想“打破”,因为我想要多种行动的可能性。但我正在返回一个名为&#39; result&#39;的值。我将它存储为变量并在最后返回。我可以告诉其他一些情况:即使他们不应该发表声明,因为结果不断变化,如果我加上休息,则不会发生声明;
处理此问题的最佳方法是什么?
更新:我已经被告知要这样做。
我改变了我的&lt;&lt; bitmasks所以他们现在从1开始。
我遇到了一个奇怪的错误
if (game_action->action & SHOOT_ROCKET)
{
game_action->data=5;
}
if (game_action->action & MOVE_FORWARD)
{
game_action->data=64;
}
当我打算将多个if评价为真时,我并不担心game_action会被覆盖
然而:即使我只是尝试射击火箭,似乎MOVE_FORWARD正在发生!
game_action通常是一个无效指针,所以这就是它在函数中的设置方式:
game_action = (game_action) *game_action_ptr;
我已经用
验证了位掩码是否正确printf("%d", game_action->action >> 16) which prints 2.
那么为什么&#39; 3&#39; (前进)发生在我只想射击火箭的时候?
答案 0 :(得分:0)
请更新您的问题。
那么为什么&#39; 3&#39; (前进)发生在我只想射击火箭的时候?
您要看的第一件事是
#define SHOOT_ROCKET 2 << 16
#define MOVE_FORWARD 3 << 16
并考虑评估的内容。它将评估以下二进制数字(Python对于这种东西很方便,0b
只是一个前缀,意味着二进制文件正在跟随):
>>> bin(2 << 16)
'0b100000000000000000'
>>> bin(3 << 16)
'0b110000000000000000'
所以你看到你在#define
中使用了两次(退役忍者已经指出了这一点)。这意味着,如果将game_action->action
设置为位2 << 16
为1
的任何位置,则两个ifs将评估为true,因为两个#define
都将该位设置为1
。
使它们相互排斥,我应该做2,4,8,而不是1,2,3,4?
如果您想轻松跟踪使用哪些位,您可以使用2的幂(1,2,4,8,16等),例如#define MOVE_FORWARD 4
(我忽略了你拥有的<< 16
,如果你愿意,你可以添加它,或者你可以将1
移动一个可变位数,这两个都会导致相同的二进制数:
#define MOVE_LEFT 1 << 0
#define MOVE_RIGHT 1 << 1
#define MOVE_UP 1 << 3
#define MOVE_DOWN 1 << 4
有些合法的情况是位掩码需要设置多个位,例如检查是否设置了多个位中的任何一位:
#define MOVE_LEFT ... (as above)
#define SHOOT_ROCKET 1 << 5
#define SHOOT_GUN 1 << 6
//...
#define ANY_MOVEMENT 0xF
#define ANY_WEAPON_USE 0xF << 4
然后检查:
if (action & ANY_MOVEMENT) { ... }
if (action & ANY_WEAPON_USE) { ... }
答案 1 :(得分:0)
放置parens&#39;(&#39;&#39;)&#39;在值部分(2&lt;&lt;&lt;&lt; 15)类型的值附近,因此文本替换不会引入错误。
即。这个:
'if( (&game_action->action & MOVE_FORWARD) == MOVE_FORWARD)'
成为
'if( (&game_action->action & 2 << 16) == 2 << 16)'
注意发布的代码缺少左边的paren,我添加了。
&#39;&amp;&#39;具有更高的优先级&#39;&lt;&lt;&lt;&lt;&lt;&#所以它(有效地)变成
'if( ( (&game_action->action & 2) << 16) == 2 << 16)'
&#39;&amp;&#39;完成2而不是2 <&lt; 16&lt; / p>