C语言中连续未分隔的相等性比较的行为是怎样的?
为啥C里
while(line != NULL != 0)这种连续比较会有奇怪的表现? 哈哈,这个问题戳中了C语言里很容易踩的运算符优先级坑!我刚学C的时候也栽过类似的跟头,咱们来一步步把它拆明白:
核心原因:运算符的优先级和结合性
C语言里的运算符不是想当然按你直觉的顺序计算的,这里关键规则有三个:
- 关系运算符(
<、>、<=、>=)的优先级比相等运算符(==、!=)要高 - 同优先级的运算符是左结合的——也就是从左到右挨着算
- 所有布尔判断的结果在C里都是整数:真就是
1,假就是0
现在对着你的测试案例一个个看:
第一个:if(1 != 0 == 1) → 结果为true
!=和==是同优先级,所以按左结合来:
- 先算
1 != 0,结果是1(真) - 再拿这个结果和
1比:1 == 1,结果还是1(真),所以条件成立
第二个:if(1 != 0 == 0) → 结果为false
同样左结合:
- 先算
1 != 0得1 - 再算
1 == 0得0(假),条件就不成立了
第三个:if(1 != 0 > 2) → 结果为true
这个就是你困惑的点!这里>的优先级比!=高,所以先算优先级高的:
- 先算
0 > 2,结果是0(假) - 再算
1 != 0,结果是1(真),所以条件成立
不是按你想的先算左边的1!=0,而是先处理了>这个优先级更高的运算!
你最初的循环:while(line != NULL != 0)
!=是同优先级,左结合,所以等价于:
while( (line != NULL) != 0 )
而line != NULL的结果要么是1(当line非空时),要么是0(line为空时):
- 当line非空时:
1 != 0→1(真),循环继续 - 当line为空时:
0 != 0→0(假),循环停止
所以这个表达式其实和while(line != NULL)效果完全一样,你之前觉得“总是返回true”应该是测试时line还没走到NULL的情况~
避坑建议
为了代码可读性,也为了避免这种优先级陷阱,永远用括号把你的逻辑分组写清楚!比如哪怕你想表达“line既不是NULL也不是0”,也要写成:
while( (line != NULL) && (line != 0) )
(不过这里提一句,多数系统里NULL本质就是0,所以这个表达式其实有点冗余,但重点是括号能让逻辑一目了然,绝不会出错)
内容的提问来源于stack exchange,提问作者lbenedetto
相关产品推荐
相关产品推荐

