在 C 中对整数使用逻辑运算符



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,则第二个操作数 不计算操作数

因此,c1得到值,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);

相关内容

  • 没有找到相关文章

最新更新