混淆后增量和逻辑运算符?

时间:2014-05-15 02:10:59

标签: c logical-operators arithmetic-expressions

    #include <stdio.h>
    #include <string.h>

    main()
    {
         int i=-1, j=-1, k=0, l=2,m;
         m = i++&&j++&&k++||l++;
         printf("%d%d%d%d%d", i, j, k, l, m);
    }

输出:

  

00131

我很困惑如何评估表达式。

3 个答案:

答案 0 :(得分:3)

这里真正重要的是||。由于l++求值为布尔值1(true),因此整个语句为真。所以m是1,其余的只是它们的原始值加上一个用于评估它们后的后增量。

您正在评估布尔表达式:

((-1 && -1) && 0) || 2

另外,您对main的定义应为:

int main(void)

答案 1 :(得分:2)

我认为你的问题是关于实际发生的增量。

&安培;&安培;和|| (逻辑和逻辑或)是&#34;短路&#34;操作。他们只评估他们的论据,以确定他们是真还是假。实际上,x && y可以视为x ? y : 0x || y可以视为x ? 1 : y

&安培;&安培;优先于||,所以首先看一下i++ && j++ && k++。首先评估i++,返回-1并将i设置为0。由于返回值为true(非零),我们继续评估j++,再次返回-1(true)并将j递增为0.我们仍然无法证明&&的值,因此我们评估k++,返回0(false)并将k递增为1.该false给出最终的anded值false。

现在我们进入||。实际上,您现在拥有false || l++。错误不足以确定或的结果,因此我们评估l++。返回2(true),同时将l设置为3。这就是强制||的值以及表达式的最终值为true

请注意,如果ijk开始时为0(错误),则后续增量不会发生,因为短路评估会确定它们不是&为了产生结果需要#39; t。 一般情况下,将&&||与副作用混合是一个坏主意,正是因为这个原因 - 它会产生不必要的难以理解的逻辑。 ?:版本 - 或真正的if/then/else声明 - 会使这种互动更加清晰。你应该明白如何阅读这种混乱,因为你会遇到其他程序员的问题。 C代码 - 但你几乎不应该写它。如果你必须,你应该把它记录下来。你节省的理智可能是你自己的。

答案 2 :(得分:0)

使用此规则:

i ++ = post递增i的值,k ++ = post递增k的值,l ++ = post递增l的值,j ++ = post递增j的值

&安培;&安培; - 如果比较的值都是非零的则为真(1)否则为假(0)

|| - 如果比较的值均为零假(0),否则为真(1)

然后应用于表达式m(也读取c中的运算符优先级)