比较运算符优先级高于&&和||,因此表达式如y==FLAG_A||y==FLAG_B&&z>0等价于y==FLAG_A||(y==FLAG_B&&z>0);建议用括号明确逻辑、宏定义整体加括号、开启-Wparentheses警告并拆分复杂条件。

比较运算符比 && 和 || 优先级高
在 C 语言中,==、!=、、>、、>= 这些比较运算符的优先级**高于**逻辑与 &&,也**高于**逻辑或 ||。这意味着表达式里不加括号时,比较会先算完,再参与逻辑运算。
例如:a 等价于 (a ,不是 a —— 后者语法虽合法但语义完全不对,且容易引发隐式类型转换问题。
&& 比 || 优先级高
逻辑与 && 的优先级高于逻辑或 ||,所以 a || b && c 实际按 a || (b && c) 执行,而不是 (a || b) && c。
- 这和数学中“乘比加优先”类似,可类比记忆
- 若想强制左结合(比如判断“a 或 b 成立,且 c 也成立”),必须写成
(a || b) && c - 混用时漏括号是常见 bug 来源,尤其在条件分支或宏定义中
容易踩坑的典型场景
以下写法看着自然,但结果常被误判:
立即学习“C语言免费学习笔记(深入)”;
-
if (x == 0 || 1):永远为真,因为1是非零值,||右侧恒真;本意可能是x == 0 || x == 1 -
if (a & b == c):实际是a & (b == c),位与&优先级低于比较,不是你想的“a 和 b 相等且等于 c” -
#define FLAG_CHECK(x) x == FLAG_A || x == FLAG_B:若用于if (FLAG_CHECK(y) && z > 0),会变成y == FLAG_A || y == FLAG_B && z > 0,因&&优先级更高,等价于y == FLAG_A || (y == FLAG_B && z > 0),而非预期的(y == FLAG_A || y == FLAG_B) && z > 0
建议的实操习惯
别依赖优先级表硬记,C 标准里有 15 级,&& 是第 11 级、|| 是第 12 级、比较运算是第 7 级——层级多且易混淆。
- 所有涉及混合运算的表达式,只要超过两个操作符,就加括号
- 宏定义中务必给整个表达式加括号:
#define FLAG_CHECK(x) ((x) == FLAG_A || (x) == FLAG_B) - 用 clang/gcc 编译时开启
-Wparentheses,它会警告“建议加括号以明确优先级”的地方 - 复杂条件拆成中间变量,比如
int is_valid = (a > 0) && (b
括号不是代码噪音,是防止自己和别人掉进优先级陷阱的最低成本防护。











