问题描述
#include <stdio.h>
int main()
{
int i=2;
if(i==3,4)
{
printf("If block");
}
else
{
printf("Else block");
}
return 0;
}
为什么这段代码返回“If block”?``
解决方法
if
语句中的表达式:
(i==3,4)
包含逗号运算符。它评估其左操作数,丢弃其值,然后评估作为其结果的右操作数。此运算符的优先级也低于相等运算符 ==
,因此解析为:
((i==3),4)
所以首先评估 i==3
。由于 i
的值为 2,因此比较结果为 false,导致 i==3
的值为 0。该值被丢弃。然后 4
被评估,它成为整个表达式的值。由于此值非零,因此 if
块为真,因此打印“If 块”。
在if语句的条件下
if(i==3,4)
使用逗号运算符。
来自 C 标准(6.5.17 逗号运算符)
2 逗号运算符的左操作数被评估为空 表达;在它的评估和那个之间有一个序列点 正确的操作数。然后评估正确的操作数;结果 有它的类型和值
就是上面的if语句可以等价地写成
if( ( i==3 ),( 4 ))
因此,根据 C 标准的引用,左操作数 ( i == 3 ) 被评估为 void 表达式,即其结果被丢弃。整个表达式的结果是表达式( 4 )
的右操作数的值。由于此表达式不等于 0,因此整个条件被评估为逻辑真,并执行 if 语句的子语句。
“为什么这段代码返回“If block”?``"
对为什么表达式 if(i==3,4)
导致执行流转到真正分支的解释在其他答案中提供了很好的细节。简而言之,它评估其第一个操作数并丢弃结果,然后使用第二个操作数作为条件进行评估。
但是,有些人可能会问这有用吗?
一种用途是在决定流向哪个分支之前强制执行 side effect。
例如
if (numeric_read(str,&err),!err)
// ^ ^ result 'err' of side effect used in if evaluation.
^
// causes side effect by call function which assigns value to err.
这里的副作用是填充 err
,然后丢弃第一个参数中调用的逻辑结果。然后使用分配给 err
的值来选择分支。