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 逻辑与或与递增优先级_C_If Statement_Logical Or - Fatal编程技术网

C 逻辑与或与递增优先级

C 逻辑与或与递增优先级,c,if-statement,logical-or,C,If Statement,Logical Or,我想问一个关于下面代码的问题 int a=1, b=3, c=1; if((a||c--)&&(c&&b--)) printf("%d",b); printf("%d %d %d",a,b,c); 为什么代码打印的是“21 2 1”而不是“12 0” 感谢您的帮助。由于or在(a | | c--)中立即求值为true,因此永远不会求值c--。编译器会这样做。如果一句话一下子是真的,那么它就不会费心去评估其余的。因此,c永

我想问一个关于下面代码的问题

int a=1, b=3, c=1;

if((a||c--)&&(c&&b--)) printf("%d",b);
printf("%d %d %d",a,b,c);
为什么代码打印的是“21 2 1”而不是“12 0”


感谢您的帮助。

由于or在(a | | c--)中立即求值为true,因此永远不会求值c--。编译器会这样做。如果一句话一下子是真的,那么它就不会费心去评估其余的。因此,c永远不会随着or的右侧而递减。

因为or在(a | | c--)中立即被求值为true,所以c--永远不会被求值。编译器会这样做。如果一句话一下子是真的,那么它就不会费心去评估其余的。所以,c永远不会在右边递减,或者永远不会被计算。

你可以想象这个if语句

if((a||c--)&&(c&&b--)) printf("%d",b);
if ( a )
else if ( c-- )
下面的方法

if ( a )
{
    if ( c )
    {
        if ( b-- )
        {
            printf("%d",b);
        }
    }
}
else if ( c-- )
{
    if ( c )
    {
        if ( b-- )
        {
            printf("%d",b);
        }
    }
}
所以如果第一个if语句中的表达式

if((a||c--)&&(c&&b--)) printf("%d",b);
if ( a )
else if ( c-- )
计算为逻辑true,然后执行此if语句

if((a||c--)&&(c&&b--)) printf("%d",b);
if ( a )
else if ( c-- )
永远无法控制

来自C标准(6.5.14逻辑或运算符)

4与按位|运算符不同,| |运算符保证 从左到右评价;如果对第二个操作数求值,则 第一次和第二次评估之间的序列点 操作数如果第一个操作数比较不等于0,则第二个操作数 未计算操作数


你可以想象这个if语句

if((a||c--)&&(c&&b--)) printf("%d",b);
if ( a )
else if ( c-- )
下面的方法

if ( a )
{
    if ( c )
    {
        if ( b-- )
        {
            printf("%d",b);
        }
    }
}
else if ( c-- )
{
    if ( c )
    {
        if ( b-- )
        {
            printf("%d",b);
        }
    }
}
所以如果第一个if语句中的表达式

if((a||c--)&&(c&&b--)) printf("%d",b);
if ( a )
else if ( c-- )
计算为逻辑true,然后执行此if语句

if((a||c--)&&(c&&b--)) printf("%d",b);
if ( a )
else if ( c-- )
永远无法控制

来自C标准(6.5.14逻辑或运算符)

4与按位|运算符不同,| |运算符保证 从左到右评价;如果对第二个操作数求值,则 第一次和第二次评估之间的序列点 操作数如果第一个操作数比较不等于0,则第二个操作数 未计算操作数


||
&&
强制从左向右评估-首先评估LHS并应用所有副作用,然后根据结果评估RHS

两个操作员短路:

  • 对于
    a | | b
    ,如果
    a
    为非零,则表达式的结果为
    1
    ,与
    b
    的值无关,因此不计算
    b
  • 对于
    a和
    ,如果
    a
    为零,则表达式的结果为
    0
    ,而与
    b
    的值无关,因此不计算
    b
&
的优先级高于
|
,因此
a | | b&&c
被解析为
a | |(b&&c)

把所有这些放在一起,
(a | | c--)和&(c&&b--)
的评估如下:

  • a | | c--
    的评估如下:
  • a
    被评估-其结果为
    1
    ,因此
  • c--
    未被评估;因此,
    c
    的值没有改变,并且
  • 表达式的结果是
    1
  • c&b--
    的评估如下:
  • c
    进行评估-其结果为
    1
    ,因此
  • b--
    被评估-其结果为
    3
    ;作为副作用,
    b
    减小,并且
  • 表达式的结果是
    1
  • a | | c--
    c&b--
    计算为
    1

    a
    c
    的值保持不变(
    1
    1
    ),而
    b
    已减小,其值现在为
    2

    这两个
    |
    &
    力从左到右评估-首先评估LHS,并应用所有副作用,然后根据结果对RHS进行评估

    两个操作员短路:

    • 对于
      a | | b
      ,如果
      a
      为非零,则表达式的结果为
      1
      ,与
      b
      的值无关,因此不计算
      b
    • 对于
      a和
      ,如果
      a
      为零,则表达式的结果为
      0
      ,而与
      b
      的值无关,因此不计算
      b
    &
    的优先级高于
    |
    ,因此
    a | | b&&c
    被解析为
    a | |(b&&c)

    把所有这些放在一起,
    (a | | c--)和&(c&&b--)
    的评估如下:

  • a | | c--
    的评估如下:
  • a
    被评估-其结果为
    1
    ,因此
  • c--
    未被评估;因此,
    c
    的值没有改变,并且
  • 表达式的结果是
    1
  • c&b--
    的评估如下:
  • c
    进行评估-其结果为
    1
    ,因此
  • b--
    被评估-其结果为
    3
    ;作为副作用,
    b
    减小,并且
  • 表达式的结果是
    1
  • a | | c--
    c&b--
    计算为
    1

    a
    c
    的值保持不变(
    1
    1
    ),而
    b
    已递减,其值现在为
    2

    开始处的附加数字或0是哪个部分让您困惑?请解释你期望的结果背后的原因。或使用衬衫进行评估circuit@MrTux也许是裤子回路?哪个部分让你困惑,起始处的附加数字还是0?请解释你期望的结果背后的原因。或使用衬衫进行评估circuit@MrTux也许是巡回赛?