int main() {
int x=1;
int a=2;
int b=3;
if(a++>2 && --b<3)
x=5;
printf("%d %d %d",a,b,x);
}
Shouldn't this code return 3 2 5 respectively, instead of 3 3 1?
a++>2
will return false, since 2 is not greater than 2 (remember, a++ means the old value of a will be returned, not the incremented value). Also, ais now worth 3.
Since the && operator is short-circuiting, the --b<3 part will not be evaluated, so b is still worth 3.
The variable x remains unchanged because the conditional was false.
So you do get "3 3 1"
a++>2 is false, and because of short-circuiting, --b<3 is never evaluated. a++>2 is false because a is initially 2, and 2 is not greater than 2. As a side effect, though, a has become 3. Because the condition was false, x is unchanged. Thus the final values of b and x are the same as their initial values, while a has been incremented.
No. Your code explained:
if(a++>2) // a = 2, so 2 > 2? No.
// So the other condition WILL NOT be checked (--b>3), because it's an && condition.
But, a++ increments the 'a', AFTER the expression. So now:
a = 3
b = 3
The code doesn't enter into the if block. So 'x' will never be changed. Then:
a = 3
b = 3
x = 1
If you did:
if(++a>2 ...
The ++a increments BEFORE the expression. So 'a' would be 3 and the if would check '3 > 2'.
The post-increment will be resolved first, then the comparation. That is because of the Operator Precedence Rules.
If you have two operator with different priority, the one with the greater priority will be invoked first, then the other one. If two operator have the same priority, they will be solved according to the corresponding associativity rule.
You can check operators priority and associativity rules in the next link:
http://en.cppreference.com/w/c/language/operator_precedence
Related
I'm stuck in a question of decrement the code is as follows
#include <stdio.h>
int main()
{
int x = 4, y = 3, z;
z = x-- - y;
printf("%d %d %d\n",x,y,z);
return 0;
}
according to what i know the output should be 4 3 0
the explanation for the value of z according to me is as follows:
first as it's a post decrement so first we'll decrease the value of y from x i.e. 4-3 that's equal to 1 and according to me we'll again decrease 1 from this 1 (or we don't correct me if I'm wrong here) and the output will be 0.
The expression x-- evaluates to the current value of x which is 4. The value of y is then subtracted from this value resulting in 1 which is what is assigned to z.
x is then decremented as a side effect of the postdecrement.
So the output will be 3 3 1.
From the C Standard (6.5.2.4 Postfix increment and decrement operators)
2 The result of the postfix ++ operator is the value of the operand.
As a side effect, the value of the operand object is incremented (that
is, the value 1 of the appropriate type is added to it). See the
discussions of additive operators and compound assignment for
information on constraints, types, and conversions and the effects of
operations on pointers. The value computation of the result is
sequenced before the side effect of updating the stored value of the
operand. With respect to an indeterminately-sequenced function call,
the operation of postfix ++ is a single evaluation. Postfix ++ on an
object with atomic type is a read-modify-write operation with
memory_order_seq_cst memory order semantics.98)
3 The postfix -- operator is analogous to the postfix ++ operator,
except that the value of the operand is decremented (that is, the
value 1 of the appropriate type is subtracted from it).
Thus in this statement
z = x-- - y;
there is used the value of the variable x before the decrement that is 4. So 4 - 3 yields 1.
But the object x itself was decremented and after this statement its value becomes equal to 3.
So as result you will get the following output
3 3 1
By the way you may rewrite this statement
z = x-- - y;
like :)
z = x --- y;
I'm reviewing material on C. I'm not sure why the answer is 12 and 32. In the first printf(), I thought that %d = 2 (i), %d = 2 (j), \n = new line. Can anyone explain this?
#include <stdio.h>
int main(void) {
int i,j;
i=2 && (j=2);
printf("%d%d\n",i,j);
(i=3) || (j=3);
printf("%d%d\n",i,j);
}
For the first expression, i=2 && (j=2); is implicitly evaluated as i = (2 && (j = 2)); because the assignment operator = has lower precedence compared to the logical operators. In the first condition, 2 has the truth value of true, and logical AND && causes all conditions to be evaluated, meaning j = 2 is also evaluated, assigning 2 to j and returning 2 which evaluates to true. So now the actual expression to be evaluated is i = 2 && 2; which is true, or in C's terms, 1. So, i is assigned 1, and the first output is 12.
For the second expression (i=3) || (j=3);, the logical OR || is used, and short circuiting ensures that if the first condition evaluates to true, the overall expression is true and so the second condition is not evaluated. So after i = 3 is evaluated, i is assigned 3 and the entire expression is true, so j = 3 is not evaluated. And so the second output is 32.
Based on precedences, the first expression is evaluated as
i = (2 && (j=2));
So i=1 (true) and j=2. That is why the first output is 12.
The second expression is a logical OR of two assignments.
(i=3) || (j=3);
But since the first evaluation from left is "true" (i=3) the second evaluation is not done. That is why value of j remains 2 and the second output is 32 (not 33).
The reason 12 is printed instead of 22 is because i is assigned the value of 2 && (j=2). First j gets assigned to 2. Then (j=2) returns 2. After that 2 && 2 is evaluated to true, and it returns true. This is because && checks if both sides are true, and 2 is interpreted as true. Since both sides are true, it returns true which is 1.
The || does not evaluate right hand side if left is evaluated to true. The reason is that it is not necessary. It should evaluate to true if at least one of the operators evaluates to true, and i=3 evaluates to 3 which is interpreted as true. That's why 32 is printed instead of 33.
The feature that it does not evaluate right operand if left evaluates to true can be used to do this:
foo() || printf("foo() returned false\n");
And similar for &&, but this operator does not evaluate right operand if left evaluates to false.
foo() && printf("foo() returned true\n");
Note that I'm not suggesting that these tricks should be used. I'm just using them as an example of how || and && may skip evaluating the right operand depending on the value on the left.
I came across this question.
#include <stdio.h>
int main()
{
int k=8;
int x=0==1||k++;
printf("%d %d",x,k);
return 0;
}
The output is 1 9.
As this answer suggests that
Unlike the bitwise | operator, the || operator guarantees left-to-right evaluation; there is a sequence point after the evaluation of the first operand. If the first operand compares unequal to 0, the second operand is not evaluated.
I am unable to understand how the statement int x=0==1||k++ is evaluated,due to which the value of x and k becomes 1,9 respectively.
Can someone explain how such statements are evaluated by the compiler in c ?
"Unlike the bitwise | operator, the || operator guarantees left-to-right evaluation; there is a sequence point after the evaluation of the first operand. If the first operand compares unequal to 0, the second operand is not evaluated."
yes it's true ...
to make it clear first make sure that you are aware of these basics
1) (1 || any_var) is 1
2) Operator precedence is as follows
++
then
==
then
||
NOW coming to your doubt of || vs |
note that | (single pipe) operator ..,will execute both LHS and RHS , no matter what)
whereas
|| (double pipe) evaluates LHS of || first and if it is 1 it need not evaluate RHS (for speed)
RHS of || operator will not be evaluted if LHS comes out to be true.
but here 0==1 is false i.e 0==1 returns 0
hence RHS will be evalauted
so the statement
k++ is executed
but 8 is used (as property of post increment operator says--> first use then increment)
so 0||8 is definitely true (1) so x evaluates to 1
and then k is incremented after sequence point ie k is made equal to 9
hence output x=1 and k=9
I hope it clears your doubt :)
The Operator || (OR) evaluates to true in the cases:
ex: A || B
A is true,
B is true,
Both are true
Because this operation uses Short-Circuit Evaluation if A is evaluated to true, it means that the statement is true already and it won't evaluate B.
In your case 0==1 (0 equals 1) is clearly false, so it will evaluate k++. k++ is a tricky one (in my opinion). In the world of C true/false evaluation is based on being 0 or not (except for the times false means less than 0...) but in true/false evaluation 0 is false, everything else is true.
K++ means evaluate K then increment, so, if K is 0 it will be false and become 1, if it is anything else, it will be true and then increment.
In your case k == 8 so the result of k++ is TRUE and k will become 9. K being true means x evaluation resulted in TRUE (it was FALSE OR TRUE).
So the output is 1(True) 9(8++)
x is 1 because the expression: 0==1||k++ turns out to be true (which is 1 in C land). Why you ask? There are two sequence points here: 0 == 1 and k++. Since the first sequence point evaluates to false (0 in C land), the second sequence point is evaluated (because the short circuit operator is ||). The second sequence returns true (or 1). So, you the entire expression breaks down to: 0 || 1. Hence x is 1.
k is 9 because of k++;
HTH.
I have the following code which produces unexpected results to me:
#include < stdio.h >
int a = 0, value;
int main(void)
{
// Testing the evaluation order of multiple
// conditional operators:
value = (a == 3) ? 3 : (a = 3) ? 5 : 0;
printf("%d\n", value);
return 0;
}
I was expecting for this code to print 3, seeing that the conditional operator evaluates
from right to left and that there is a sequence point at the ? of the first-to-be executed
operation, whereas it actually prints 5.
Is it wrong to assume that side effects of an expression residing between two sequence
points also get calculated when the values of the expressions are?
If i add printf("%d\n" a); i get 3 printed though, so the side effect gets done.
Or is it just that control dosent really pass to the subexpression the value of which
is being calculated "first" officially?
I would rather bet on the latter because changing the value of 'a' to 3 and the rvalue
in the assignment of the second conditional to 4 resulted in short-circuit evaluation
of the first conditional expression, meaning that i got 3 printed for both 'a' and 'value'.
I got the above result on Lubuntu 14.04 with GCC 4.8.2 using the -std=c99 flag.
Thank you for anyone clearing me up on this matter!
The conditional operator does not "evaluate right to left". The standard (C11 6.5.15/4) says:
The first operand is evaluated; there is a sequence point between its
evaluation and the evaluation of the second or third operand
(whichever is evaluated). The second operand is evaluated only if the
first compares unequal to 0; the third operand is evaluated only if the
first compares equal to 0; the result is the value of the second or
third operand (whichever is evaluated)
So the expression (a == 3) ? 3 : (a = 3) ? 5 : 0; evaluates in these steps:
(a == 3) result is 0
(a = 3) result is 3, unequal to 0
5
So 5 is what is assigned to value.
You might be confusing the concept of how the conditional operator is evaluated with how the conditional operator associates (or groups). The syntax of C specifies that the expression:
(a == 3) ? 3 : (a = 3) ? 5 : 0;
associates or groups sub expressions like so:
((a == 3) ? 3 : ((a = 3) ? 5 : 0));
which is often described as 'associates right'. However, this grouping/associativity doesn't affect the fact that the expression is still evaluated left-to-right and that the second conditional expression only evaluates after the first operand in the 'outer' conditional expression is evaluated.
Let's trace through this one part at a time. You have this expression:
value = (a == 3) ? 3 : (a = 3) ? 5 : 0;
Since a starts off at 0, we skip the 3 branch of the first ?: and look at the second branch, which is
(a = 3) ? 5 : 0
The condition here is a = 3, which sets a to 3 and then evaluates to the new value of a, which is 3. Since 3 is nonzero, we take the first branch of the ?:, so the expression evaluates to 5. The net effect is that a is set to 3 and value is set to 5.
The language spec guarantees that the evaluation order is indeed what you think it should be - the "if" and "else" branches of the ?: operator are guaranteed not to execute unless the condition works out as it does, so there are sequence points here. I think you just misunderstood the effect of the a = 3 operation.
Hope this helps!
The conditional operator evaluates left-to-right (evaluating the condition before either of the branches). You may be confusing this with its right-associativity (in which it appears to bind right-to-left).
Your conditional expression essentially results in the following logic:
if(a == 3) {
value = 3;
} else {
if(a = 3) {
value = 5;
} else {
value = 0;
}
}
Note that the conditional doesn't execute a branch until after the condition is evaluated.
I just have a quick question about the conditional operator. Still a budding programmer here.
I am given x = 1, y = 2, and z = 3.
I want to know, why after this statement:
y += x-- ? z++ : --z;
That y is 5. The values after the statement are x = 0, y = 5, and z = 4.
I know the way the conditional operator works is that it is formatted like this:
variable = condition ? value if true : value if false.
For the condition, y += x-- , how does y become 5? I can only see 2 (2 += 0) and 3 (2 += 1)(then x-- becomes zero) as possibilities. Any help is much appreciated. :)
When it evaluates the condition (x != 0) x is still 1 (that is not 0). So it picks z++. Which is still 3. 2 + 3 = 5. At the end of the day x has become 0 and z has become 4.
Take a look here for details. It's important to remember a simple thing: when you say x ++ the current value of x is used and then it is incremented. When you say ++x it is first incremented and then used.
The Operator ?: has higher precedence than the operator +=. So Your expression is evaluated as
y += (x-- ? z++ : --z);
the value of x-- ? z++ : --z expression is the value of the expression z++ (that is 3) because the value of the expression x-- is 1
Just break it down into a similar if statement:
if (x--)
y += z++;
else
y += --z;
In your case, since x is 1, you'll take the "true" side of this if statement. That means you're adding z++ to y, giving 3 + 2, resulting in 5.
Please don't write code like this.
As a budding programmer just know that you should NEVER write anything like this so that way you can forget about it worrying you!
The reason for this is that post-decrement/increment operator (x++ or x--) does the following:
increment or decrement the variable
return the original value.
So the return value of x-- is 1, indicating true, so the statement z++ is evaluated, returning the original value 3.
Since y = 2, y += 3 is 5.
x-- would mean the expression is evaluated at current value of x and after that x is reduced by 1. Same is the case with Z++. This is the other way around for --z, which means this is evaluated at the new value of z.
So at the time of evaluation x is 1, z is 3. and after the evaluation of expression x becomes 0 and z 4; and y = 2 + 3 = 5
Remember that the increment and decrement operators return different things depending on whether they're placed before or after the name of a variable.
In particular, when x-- is evaluated, it decreases x by 1, but returns the unmodified value of x, which in this case is 1. In C, 1 evaluates to true, so the ternary operator will return z++.
And again, because the ++ operator is placed after the variable, the return value of z++ is the unmodified value of z, which is 3.
Thus, this comes down to y += 3, which results in y being 5.
x-- and z++ decrement and increment after they are used.You end up with the following when the ternary operator is evaluated:
y += (1) ? (3) : (--z);
--z never gets called, the conditional evaluates to true and executes the first option in the ternary operator. After use, x is then decremented, and z is incremented.
It is normal because it first "runs" ternary operator then does decrement as your decrement operator (x--) is postfix, so you got z++ which is 3 so you have 5 in y.
The expression x-- evaluates to the current value of x, which is 1. Thus the result of the conditional expression is z++, which evaluates to 3. 3 gets added to y, for a total of 5.
I think your fundamental issue here is that you're assuming y+= x-- is your condition, when in fact your condition is merely x--. There is a return from the conditional operator which makes y += the result of the conditional operation: x-- ? z++ : --z; is 5. Other comments have the reason why it actually evaluates to 5.
y += (x-- ? z++ : --z); so this is your question and the answer is simple................
As we know that something like X-- Or x++ are called post increment or decrement. So according to the rules of post increment or decrement the expression will be evaluated first and then only increment or decrement will come into action. i.e first evaluate and then increase or decrease.....
NOW lets solve your question:
Y+=X--?Z++:--Z....now it is containing three parts i.e left,middle and right...now the point of consideration is:"if left part is true then it will return middle part, otherwise right side part...and execution always starts from left part as it is the condition part"
Now simplify the statement as:Y+=X?Z:Z;....Now see whether left part is having pre or post increment or decrement.....if post ++/-- is der den first evaluate the simplified statement......den go for ++/--.....
Now left part is having post decrement...so lets first evaluate the expression...i.e
y+=1:3:3 //any non zero value in the condition part is a true condition(i.e 1)
so now our condition is true and it will return the middle part and when the control goes to middle part at that time only x value will be decremented i.e it becomes 0....
Now 2nd simplified statement is Y+=Z. (\\as condition is true and we got middle part,compiler will skip rest of the part i.e right part.)
Now observe whether Z is post ++/-- (or)pre ++/--) ...hahh..its post increment ..so simply first evaluate the simplified statement2 and then increase the value of Z....i.e
Y+=Z =>Y=Y+Z
=>Y=2+3 =>y=5
Now the expression is evaluated i.e Y=5,so now increment the value of Z i.e it become 4
As we know operators checks condition if it is true i.e 1 it executes true statement.
If it is false i.e 0 it executes false statement
Being we are initialising value of x to 1 it executes true statement
As a result it exposes result 5 from true part y=(y+z++)