问题
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