让我们从最有趣(也是最不明显)的部分开始:gcc逻辑上会使用-Wlogical-not-parentheses
进行警告。这是什么意思呢?
C语言有两个不同的运算符,它们看起来很相似(但行为不同,目的也非常不同)- &
是按位与,&&
是布尔与。不幸的是,这导致了打字错误,就像当你想要输入==
时却输入了=
一样,会引起问题,因此一些编译器(如GCC)决定警告人们关于“在条件中使用没有括号的&”(即使它是完全合法的),以减少打字错误的风险。
现在...
您正在展示使用&
的代码(并未展示使用&&
的代码)。这意味着some_state
不是布尔值,而是数字。更具体地说,它意味着some_state
中的每个位可能是完全独立和无关的。
举个例子,假设我们正在实现一个吃豆人游戏,并需要一种紧凑的方式来存储每个级别的地图。我们决定地图中的每个方块可能是墙或不是,可能是收集的点或不是,可能是能量药片或不是,可能是樱桃或不是。有人建议这可以是一个字节数组,就像这样(假设地图宽30个方块,高20个方块):
#define IS_WALL 0x01
#define HAS_DOT 0x02
#define HAS_POWER_PILL 0x04
#define HAS_CHERRY 0x08
uint8_t level1_map[20][30] = { ..... };
如果我们想知道一个瓷砖是否可以安全地进入(没有墙壁),我们可以这样做:
if( level1_map[y][x] & IS_WALL == 0) {
相反地,如果我们想知道一个瓷砖是否是墙,我们可以执行以下任何操作:
if( level1_map[y][x] & IS_WALL != 0) {
if( !level1_map[y][x] & IS_WALL == 0) {
if( level1_map[y][x] & IS_WALL == IS_WALL) {
因为它是哪一个都没有区别。
当然(为了避免打错字的风险),GCC可能会(或可能不会)警告其中一些。
if(!some_state&SOME_FLAG)
始终为false,并且可以完全被现代编译器消除。 - aka.nice