【问题标题】:Shortcircuiting of AND in case of increment / decrement operator在递增/递减运算符的情况下与短路
【发布时间】:2013-11-05 13:24:24
【问题描述】:

在下面的代码中:

#include <stdio.h>

int main()
{
     int a = 1;
     int b = 1;
     int c = a || --b;
     int d = a-- && --b;
     printf("a = %d, b = %d, c = %d, d = %d", a, b, c, d);
     return 0;
}

我期望输出是:

a=0,b=1,c=1,d=0

因为下面一行的短路,即a--返回0,所以其他部分不会被执行对吧?

int d = a-- && --b;

输出是:

a = 0, b = 0, c = 1, d = 0

谁能解释一下?

【问题讨论】:

标签: c logical-operators short-circuiting


【解决方案1】:

第一种情况

int c = a || --b;  

在此之后 a=1b=1c=1

a 的值为 1 ,因为没有执行短路评估 --b

int d = a-- && --b;

a--post decrement 所以减少 a 不会影响表达式 其中--bpre decrement 所以效果在这里

你的情况变成了

   int d= 1 && 0 ; 

a=0;b=0c=1d=0 之后。

【讨论】:

  • 我不明白为什么您的回答被否决(我的回答也是如此)。所以,+1。
  • 感谢您的支持。坦率地说,我没有解释清楚。我被错误地解释了。
  • @Maxime:因为最初是错误的,所以被否决了;它声明--b 首先执行。从那以后它已经被编辑了。
  • @niko 感谢投票,我应得的。它可以帮助我纠正我的答案。
【解决方案2】:
int c = a || --b;

在这一行中,C 标准要求 C 实现首先评估a,如果不为零,则不评估 --b。尽管-- 的优先级高于||,但这只是意味着--b 分组是为了确定表达式的结构,而不是为了评估它。 || 运算符的左侧必须在右侧之前评估,如果左侧为真,则右侧不得评估,即使是部分.

所以,经过上述操作,b 没有改变;它仍然是 1。

int d = a-- && --b;

|| 一样,首先评估&amp;&amp; 的左侧。所以 a-- 被评估。这会将a 更改为 0。但是,a-- 的值在更改之前是 a,所以它是 1。值 0 将阻止评估右侧(因为,一旦我们知道左侧为零,我们知道完整的&amp;&amp; 表达式的值为零)。但是,由于左侧不为零,因此必须评估 --b 以完成 &amp;&amp;。这会将b 更改为 0。“短路”表示首先评估左侧,但在必要时仍会评估右侧。

【讨论】:

  • 是的 - 当我发布我的答案时 - 我完全忽略了一个事实,即有序列点 Between evaluation of the left and right operands of the &amp;&amp; (logical AND), || (logical OR) (as part of short-circuit evaluation), and comma operators
【解决方案3】:

在第一个or操作中,--b没有被执行,因为a等于1:

int c = a || --b;

但是b在这里被递减:

int d = a-- && --b;

因为a 等于 1,并在计算后递减(a-- 等于 1)。换句话说,这一行类似于:

int d = 1 && --b;

b 等于 1,所以现在 b 等于 0。而d 也等于 0,因为--b 返回 0。

【讨论】:

  • 你能告诉我为什么b仍然是0,为什么它不变成-1? .
  • @nico b 此时等于 1。这就是为什么。我也会编辑解释上一行。
【解决方案4】:

下面一行,即a--返回0

不,它没有。它产生 1,因为后减运算符计算为变量的未修改值。你在想的可能是--a

【讨论】:

  • 第一次尝试1 -- the po 让我感到困惑
  • @GrijeshChauhan 够公平的。我已经重新措辞了。
  • 您的回答没有让我们满意.. 能否解释的更清楚
  • @niko 你还需要什么?
【解决方案5】:

c = a || --b

所以起初a is evaluateda 的值是1,即true。所以编译器不会评估--b。所以b的值还是1

现在

d = a-- &amp;&amp; --b

a-- &amp;&amp; --b => 1 &amp;&amp; 0(因为--b = 0)因为b的值是1

为什么1 because a-- is post decrement operator

为什么0 because --b is pre decrement operator

so 1 && 0 返回 0 并且这个值存储在 d 中

所以输出:a = 0, b = 0, c = 1, d = 0

【讨论】:

  • 这里没有关联性。从左到右的关联性意味着a || b || c 被分组为(a || b) || c。这并不意味着在b 之前评估a。这是一个单独的规则。
【解决方案6】:

您将a----a 混淆了。表达式a--的结果是a之前递减,而--aa之后递减;换句话说:

int a = 1;
int b = a--; // b == a == 1
int c = --b; // c == b-1 == 0

因此,您有:

int d = a-- && --b;
// =>   1   && b-1
// =>   1   && 0
// =>   0

【讨论】:

  • 原代码中没有int b = a--;,在原代码对c的赋值中没有对--b求值。
  • 我并没有试图在那里复制他的代码。我认为这很明显,但是 w/e.
猜你喜欢
  • 2011-02-16
  • 1970-01-01
  • 1970-01-01
  • 2015-10-03
  • 2014-03-21
  • 1970-01-01
  • 2015-02-16
  • 1970-01-01
相关资源
最近更新 更多