Explanation for this function's output

不打扰是莪最后的温柔 提交于 2019-12-10 14:21:56

问题


I am doing review questions which ask me "What is the output of the following," and I am having some trouble understanding something about this function:

int a = 1, b = 1, c = -1;
c = --a && b++;
printf("%d %d %d", a, b, c);

The output is 010. My question is about line 2, c = --a && b++. How is this line processed, and how does it work/change the values? And if it were c = --a || b++? From my understanding I thought the output would be 020.


回答1:


The key concept to understanding the result is short-circuit evaluation of Boolean operators (&& and ||) -- if, after evaluating the left-hand side of a Boolean operator, the value of the right-hand side cannot affect the overall result, then it will not be evaluated and any side-effects it would produce will not happen.

In the first case, since --a evaluates to 0 (=false) the second part of ... && ... is not evaluated, since "false AND anything" will always be false. Specifically, b++ is never executed, and so its value remains 1 in the output.

In the case of --a || b++, the value of the whole expression cannot be determined by the left-hand side ("false OR something" can still be true) so the b++ is evaluated (and it's side-effect, incrementing b, happens).

The other concept needed to fully understand the results is the difference between pre- and post-increment/decrement operators. If the -- or ++ appears before the variable (as in --a) then the variable is decremented or incremented first and new value is used to evaluate the whole expression. If the -- or ++ appears after the variable (as in b++) then the current value of the variable is used to evaluate the expression and the increment/decrement happens after this has happened.

It should be noted that expressions that try to combine two or more instances of --/++ of the same variable (e.g. a++ + ++a) are quite likely to invoke undefined behaviour -- the result may vary by platform, compiler, compiler and even the time of day.




回答2:


In the expression c = --a && b++, a gets decreased and returned. Now the second argument of the expression --a && b++ is not evaluated because of short circuit evaluation---once we see that --a==0 we already know that the expression will be 0 regardless of what is the other argument---, so b remains unchanged.

Decreased a is 0 and b remains 1.

The output is, as you suggest, 0 1 0.

Regarding the second question, if you write c = --a || b++, the variable a again goes to zero but the expression can still evaluate to true---we must thus evaluate the second part as well, thus executing b++ which returns 1 and increases b. In this case the output would be 0 2 1, because c is assigned the value of 0 || 1 which is 1.

In short, read up on

  • pre- and post-increment in C and C++ and on
  • short circuit evaluation.



回答3:


The thing you need to focus on here first is the properties of prefix and postfix operators and their differences.

  • For Postfix increment and decrement operators, C11, chapter §6.5.2.4, (emphasis mine)

    The result of the postfix ++ operator is the value of the operand. As a side effect, the value of the operand object is incremented [...] The postfix -- operator is analogous to the postfix ++ operator, except that the value of the operand is decremented.

  • For Prefix increment and decrement operators, C11, chapter §6.5.3.1, (emphasis mine)

    The value of the operand of the prefix ++ operator is incremented. The result is the new value of the operand after incrementation. [...] The prefix -- operator is analogous to the prefix ++ operator, except that the value of the operand is decremented.

Now, there comes the property of the Logical AND (&&) operator. From chapter §6.5.13, (again, emphasis mine)

the && operator guarantees left-to-right evaluation; if the second operand is evaluated, there is a sequence point between the evaluations of the first and second operands. If the first operand compares equal to 0, the second operand is not evaluated. [...]

So, in your case,

int a = 1, b = 1, c = -1;
c = --a && b++;

gets evaluated as

c = 0 && .....; // done..., a is decremented to 0, 
                //            so, LHS of && is 0, RHS is not evaluated,
                //            b remains 1
                //            and finally, C gets 0.

On the other hand, if logical OR (||) would have been used, then, as per the property, mentioned in chapter §6.5.14

[...] the || operator guarantees left-to-right evaluation; if the second operand is evaluated, there is a sequence point between the evaluations of the first and second operands. If the first operand compares unequal to 0, the second operand is not evaluated.

So, for the case

int a = 1, b = 1, c = -1;
c = --a || b++;

it will be evaluated as

c = 0 || 1;   //yes, b's value will be used, and then incremented.

So,

printf("%d %d %d", a, b, c);

will be

0 2 1



回答4:


b++ is simply never executed because --a evaluates to false in an and condition. The right side of the and is never executed because not needed. Hence b is never incremented and hence the output you did not expect.




回答5:


c = --a && b++;

In this first --a is evaulated and a becomes 0 , as soon as 1 operand of && is false , b++ is not evaluated , therefore ,b remains 1 and c becomes 0.




回答6:


The line :

c = --a && b++;

decreases a to 0, so the statement 0 && anything else results to 0. This is why a and c result to 0, as it seems you have understood.

Now let's see the part you don't get. When a is evaluated to 0, the right part of && does not need to be evaluated, as no matter what the value of the right part will be calculated to be, the result will be 0. This means that b++ will not be evaluated and therefore b will retain its initial value. This is why you see the value 1 instead of 2, and consequently the output 0 1 0 instead of 0 2 0.




回答7:


--a : mean you decrease a before do the line. b++: increase b after do the line. so that c ( at that time ) = 0+1 =1; then: a =0, b = 2, c =1; OK



来源:https://stackoverflow.com/questions/36788257/explanation-for-this-functions-output

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!