C 中整数的逻辑 OR 和逻辑 AND 运算符
你能解释一下为什么a,b,c的值分别是11,10,1吗? 为什么 b 的值与 10 相同?
#include <stdio.h>
int main()
{
int a,b,c;
a=b=c=10;
c = a++ || ++b && ++c;
printf("%d %d %d",a,b,c);
return 0;
}
首先,让我们看一下操作的顺序。 逻辑 AND 运算符&&
的优先级高于对数 OR 运算符||
,因此表达式解析如下:
c = a++ || (++b && ++c);
其次,||
和&&
都是短路运营商。 这意味着首先评估左侧有侧,如果结果可以仅由此确定,则不评估右侧。
因此a
从值 10 开始。a++
计算结果为当前值 (10(,同时递增a
作为副作用。 这意味着值 10 是||
的左侧。 由于这是一个非零值,因此整个表达式的值为 1,并且不计算右侧++b && ++c
。 然后将此结果分配给 1。
因此,最终结果是a
递增到 11,c
赋值 1,因为这是||
表达式的值,并且b
保持不变。
此表达式
c = a++ || ++b && ++c;
可以等效地重写,例如
c = ( a++ ) || ( ++b && ++c );
由于表达式 a++ 不等于 0,因此不计算第二个子表达式( ++b && ++c )
。
逻辑运算符 || 和 && 的值为 1(真(或 0。
来自 C 标准(6.5.14 逻辑 OR 运算符(
3 如果 || 运算符的任一操作数比较,则其应生成 1 不等于 0;否则,它产生 0。结果的类型为 int。
和
4 与按位 | 运算符不同,|| 运算符保证 从左到右的评估;如果计算第二个操作数,则 第一个和第二个评估之间的序列点 操作。如果第一个操作数比较不等于 0,则第二个操作数 不计算操作数。
因此,c
1
得到值,a
增加了。
稍微扩展一下其他答案,你必须了解你的陈述实际上在做什么。
a=b=c=10;
c = a++ || ++b && ++c;
逻辑运算符自然采用布尔操作数,所以你的语句是(隐式(:
c = ( a++ != 0 ) || ( ++b != 0 ) && ( ++c != 0 );
请注意,有趣的是,优先级顺序使 AND 运算符高于 OR 运算符 - 这意味着应该执行++b
。
但是,给定逻辑OR的短路操作,已知第一项true
因此c = 1 (ie true)
。
--
当然,普通读者会希望我在回答中添加MISRA的倾向......
MISRA C:2012规则13.5涵盖了这一确切情况...它指出逻辑&&
或||
运算符的右操作数不得包含持续的副作用
因此,您的代码的 MISRA 兼容版本将是:
a=b=c=10;
a++;
b++;
c++; // This is actually *dead code*
c = a || ( b && c );
printf("%d %d %d",a,b,c);