Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
逻辑运算符';C中的优先级 #包括 内部主(空){ int a=0,b=0,c=0; ++a | |++b&++c; printf(“%d%d%d”,a、b、c); 返回0; }_C - Fatal编程技术网

逻辑运算符';C中的优先级 #包括 内部主(空){ int a=0,b=0,c=0; ++a | |++b&++c; printf(“%d%d%d”,a、b、c); 返回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

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运算符
    |
    (以及逻辑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;
    ^^^