逻辑运算符';C中的优先级 #包括 内部主(空){ int a=0,b=0,c=0; ++a | |++b&++c; printf(“%d%d%d”,a、b、c); 返回0; }
gcc 8.1.0的输出为逻辑运算符';C中的优先级 #包括 内部主(空){ int a=0,b=0,c=0; ++a | |++b&++c; printf(“%d%d%d”,a、b、c); 返回0; },c,C,gcc 8.1.0的输出为1,0,0。&&的优先级应高于| 为什么b和c仍然是0但是,|的右侧只有在++a为0时才被评估,而不是。这里有三个问题: 优先顺序 评价顺序 逻辑运算符短路 优先顺序意味着++a | |++b&&++c被评估为++a | |(++b&&++c) 但是,由于逻辑运算符的短路要求,++a首先进行评估。只有当计算结果为false时,才会计算(++b&&&++c)。在您的情况下,++a的计算结果为true。因此,(++b&&++c)永远不会被计算。逻辑OR运算符|(以及逻辑AN
1
,0
,0
。&&
的优先级应高于|
为什么
b
和c
仍然是0
但是,|
的右侧只有在++a
为0
时才被评估,而不是。这里有三个问题:
++a | |++b&&++c
被评估为++a | |(++b&&++c)
但是,由于逻辑运算符的短路要求,
++a
首先进行评估。只有当计算结果为false
时,才会计算(++b&&&++c)
。在您的情况下,++a
的计算结果为true
。因此,(++b&&++c)
永远不会被计算。逻辑OR运算符|
(以及逻辑AND运算符&&
)是执行短循环操作的少数运算符之一
第6.5.14节说明了逻辑OR运算符的以下内容:
4与按位|
运算符不同,|
运算符保证
从左到右评价;如果对第二个操作数求值,则
第一次和第二次评估之间的序列点
操作数如果第一个操作数比较不等于0,则第二个操作数
未计算操作数。
由于
++a
的计算结果为1,因此|
运算符的结果保证为1,并且不会计算右侧。此外,由于&
的优先级高于| |
,因此|
运算符的右侧是++b&&++c
,这意味着既不计算++b
也不计算++c
,x | | y&&z
的作用类似于x+y*z
:第二个操作符比第一个操作符绑定得更紧密,这些表达式分别等价于x | |(y&&z)
和x+(y*z)
问题中的b
和c
没有递增的原因是,除了优先级之外,逻辑运算也会短路:一旦你已经足够了解结果,表达式的其余部分就会被跳过。||
和&
都从左到右计算它们的参数,因此在a()| b()
和a()&&b()
中,对a()
的调用发生在对b()
的调用之前
在简单的情况下,如果a()
返回true
,那么在表达式a()| b()
中,将不会执行对b()
的调用,因为它不会影响结果。类似地,如果a()
返回false
,则在表达式a()&&b()
中,将不会执行对b()
的调用
在示例中的代码中,将不执行到
b
和c
的增量,因为++a
生成非零值,因此表达式的结果为true
,而无需在++a之后求值,运算符优先级与求值顺序无关。优先级是将不同类型的运算符与其操作数分组的优先级
那么,这个表达式呢
#include <stdio.h>
int main(void) {
int a = 0, b = 0, c = 0;
++a || ++b && ++c;
printf("%d %d %d", a, b, c);
return 0;
}
将被评估为
++a || ++b && ++c;
逻辑AND和逻辑OR运算符构成,因此保证其操作数的计算顺序为从左到右
:
订购
......
- 如果子表达式E1和E2之间存在序列点,
然后对E1的数值计算和副作用进行了分析
在每次数值计算和E2副作用之前进行排序
规则
..…
2) 下列二元运算符的第一个(左)操作数求值后和第二个(右)操作数求值前有一个序列点:&&(逻辑and)、| |(逻辑OR)和(逗号)
逻辑OR操作(expr1 | | expr2)
使用行为。也就是说,如果expr1
符合逻辑1
(true)
,则不会计算expr2
a
、b
和c
的初始值为0
。在表达式中:
++a || (++b && ++c);
++a
->增量前a
这意味着,表达式++a
的值是a
的增量值,它将是1
。由于,|
运算符采用短路行为,因此将不计算|
的右侧表达式。因此,您将获得输出-100
为了更好地理解,只需尝试更改表达式中的++a
->a++
。
增量后运算符也会将操作数的值增加1
,但表达式的值是增量运算之前操作数的原始值。因此,a++
将被计算为0
,并且由于短路行为,|
运算符(++b&&++c
)的右侧表达式将被计算
逻辑AND操作(expr1&&expr2
)也采用短路行为。对于逻辑短路,只有当第一个操作数expr1
不能完全确定结果时,才会对第二个操作数expr2求值。也就是说,exp
++a || ++b && ++c;
a++ || ++b && ++c;
^^^