Precedence in C operators == and ( = ) - c

I have to analyze what some code in C does, and I have a doubt about what happens in a certain line. The code is
#define PRINTX printf("%d\n", x)
void problem() {
int x = 2, y, z;
x *= 3 + 2; PRINTX;
x *= y = z = 4; PRINTX;
x = y == z; PRINTX;
x == (y = z); PRINTX; // This line is the problem
}
This code snippet prints the resulting numbers:
10
40
1
1 // This result **
the problem is that I'm still trying to figure out why does the last line prints out x = 1, when the operation is x == (y = z). I'm having trouble finding out what that 1 means and the precedence of the operations. Hope someone can help me! :)

Nothing in the last statement changes the value of x, so its value remains unchanged.
Parens were used to override precedence, forcing the = to be the operand of the ==.
An operator's operands must necessarily be evaluated before the operator itself, so we know the following:
y is evaluated at some point before the =.
z is evaluated at some point before the =.
x is evaluated at some point before the ==.
= is evaluated at some point before ==.
That's it. All of these are valid orders:
z y = x ==
y z = x ==
x y z = ==
etc.
But whenever x, y and z are evaluated, we can count on the following happening:
= assigns the value of z (currently 4) to y and returns it.
== compares the value of x (currently 1) with the value returned by = (4). Since they're different, == returns 0 (which isn't used by anything).
As you see, nothing changed x, so it still has the value it previously had (1).

In the last statement, nothing is changing the value of x. We are testing if x equals something, but we aren't changing it's value.
So it continues having the same value as it had in the previous statement, in particular, a value of 1.

the reason is because the == operator checks if the 2 numbers are equal, and returns 1 if equal and 0 if not equal that is why it returns one you can check by making x= 1 and y=2 and using the == operator between them

The comparison result of x and assignment of y with (y = z) is discarded. Last line could have dropped the compare: y = z; PRINTX;.
The assignment is not subsequently used either, so the line could have been PRINTX;.

Related

How do you evaluate z = x- - == y + 1;

given that
int w = 1;
int x = 6;
int y = 5;
int z = 0;
z = !z || !x && !y;
printf("%d\n", z);
z = x-- == y + 1;
printf("%d\n", z);
Could someone explain how the line below would evaluate to 1 if x-- is 5 and y+1 is 6?
z = x-- == y + 1;
The expression x-- evaluated to the value of x before being decremented.
So x-- == y + 1 is the same as 6 == 5 + 1 which is true, then the value 1 is assigned to z.
The expression
z = x-- == y + 1
will be parsed as
z = ((x--) == (y + 1))
IOW, you are comparing the result of x-- to the result of y + 1, and assigning the result of that comparison to z.
The result of x-- is the current value of x; the side effect is that x is decremented. So, given
x == 6
y == 5
then
x-- == 6
y + 1 == 6
(x-- == y + 1) == 1
so 1 is assigned to z; after this evaluation, x will equal 5.
Note that C does not force left-to-right evaluation in this case - y + 1 may be evaluated before x--. Also be aware that the side effect of the -- operator on x does not have to be applied immediately after evaluation - the whole thing could be evaluated as
t1 <- y + 1
t2 <- x
z <- t2 == t1
x <- x - 1
or
t1 <- x
t2 <- y + 1
x <- x - 1
z <- t1 == t2
or any other order. The update to x and the assignment to z can happen in any order, even simultaneously (either interleaved or in parallel).
While idiomatic C is often a little head-scratchy, this takes things a bit too far. As an academic exercise for learning about operator precedence and side effects it's okay (not great), but anyone who did this in production code could expect some grief over it in a code review. If nothing else it doesn't scan well - just adding some parens (like I did above) would greatly help with readability.
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).
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 expression statement
z = x-- == y + 1;
that may be equivalently rewritten like
z = ( x-- ) == ( y + 1 );
the value of the postfix decrement expression x-- is the value of the variable x before decrementing. That is the value of the expression is equal to 6.
The value of the expression y + 1 is also equal to 6 because the value of y is equal to 5.
And at last (the C Standard, 6.5.9 Equality operators)
3 The == (equal to) and != (not equal to) operators are analogous to
the relational operators except for their lower precedence.108) Each
of the operators yields 1 if the specified relation is true and 0 if
it is false. The result has type int. For any pair of operands,
exactly one of the relations is true
So as the value of the expression x-- is equal to the value of the expression y + 1 then the variable z gets the value 1.
You could get the expected by you result keeping the postfix decrement operator the following way
z = ( x--, x == y + 1 );
by inserting the comma operator. In this case after the comma operator there is a sequence point that means that in second operand of the comma operator x == y + 1 x will be already equal to 5.
On the other hand, if you will write for example the expression like this
z = --x == y + 1;
where instead of the postfix decrement operator there is used unary decrement operator -- then the value of the expression --x will be equal to 5 (the value of the unary decrement operator is the value of its operand after decrementing). In this case the variable z gets the value 0 because 5 is not equal to 6 (the value of the expression y + 1).

Why is the output 1?

#include<stdio.h>
main()
{
int x = 5, y = 10, z = 10;
x = y == z; // This computational expression causes the value of x to be 1. I fail to understand why
printf("%d\n", x); //Why is the value of x 1 here.
}
I fail to understand the statement x = y ==z;
According to me - x = 10 since y == z. z=10 and is stated to be equivalent to y. The value of y is then assigned to x - x = y
You assign the result of the comparison »Is y equal to z« to x, which is 1, i.e. true.
Note the different operators:
x = ... // assignment
y == z // comparison with either 0 (false) or 1 (true) result
Let's break the program down a little bit further:
You initialize x to 5 and y and z to 10.
You perform a comparison (see above) of y and z without caring for the result. So that's a line that can safely be ignored. But it results in 1 since y is equal to z.
You print the current values of all three variables.
You perform the same comparison, this time assigning the result to x. x now has the value »Is y equal to z«, which is 1 in this case.
Because of operators precedence
x = y == z;
is the same as
x = (y == z);
Now as y == z evaluates to 1, so x value is 1 after the statement.
y == z returns 1 if they are the same and 0 if they are not and the result of this is set to x
== is a comparison operator, so will return 1 (true) if both of the operands are equal and 0 (false) if they are not.
The statement x = y == z is equivalent to x = (y == z), because == has a higher precedence than =. Because y is equal to z, this will assign 1 to x.
Please refer to Operator Precedence Table. == (Comparison Operator) has a higher precedence over = (Assignment Operator). So, the y == z gets executed first and then yields result of 1 as y and z are having the same values which results in x being assigned a value of 1.
= is the assignment operator and == is the comparison operator. you compare y and z, they are equal, so the comparison returns true which is 1. this value is assigned to x.
the == operator acts first.
Hence it becomes x= (value of y==z);
now since y and z are the same, the value of y==z is 1 that gets assigned to x.
== has a greater precedence than =.
The expression y == z is evaluated to 1.
The instruction x = y == z puts 1 in x.
The instruction printf("%d\n", x); prints the value of x (1).
The precedence of == operator is higher than = operator.
y==z evaluates to 1; since both are equal.
Thisn value gets assigned to x.

Associativity and Sequence Points in C

Since the associativity of '?' is from right to left,any 2 consecutive '?' operators must be treated as such,Right?
Now,
int x=-1;
int y=x?x++?x:-1:1;
I expect this to be executed as:
int y = x ? (x++?x:-1) : 1;
Now since its being executed from right to left,when encountering the first '?' in the statement,x's value is 0 and the expression is as
int y= x? 0 : 1;
hence i expected y to be 1,but it shows Zero on my dev-cpp.Where am i wrong?
You have the order of evaluation wrong. In a ? b : c, a is always evaluated first, then either b or c is evaluated.
I've marked up your example so that I can identify subexpressions:
c
int y=x?x++?x:-1:1;
a bbbbbbbb
(a) is evaluated, yielding -1, so (b) is evaluated. There, x++ is evaluated, yielding -1 again, so (c) is evaluated. At this point, x is 0.
Or, with more verbose, clearer code, it's as if you said:
int x = -1;
int y;
if (x != 0)
{
int new_x = x + 1;
if (x != 0)
{
y = new_x;
}
else
{
y = -1;
}
}
else
{
y = 1;
}
Operations:
Assign y to value =
if(x): --> x = -1, so true as it is non-zero
{
if(x): --> x = -1 ,so true as x will increment later due to post increment
x= x +1; --> increment x, so x = 0 . This is the value assigned. So y = 0;
else:
-1
}
else:
{
1
}
Hope this helps!
The answer to your question is that in C/C++ int y = x ? (x++?x:-1) : 1; we will hit two sequence points at ?. Any update operations to variable with in a sequence point will be effective after that sequence is over. So lets look at our example in hand.
First sequence point is first ? from left.
x=-1; (Actual Value)
x=-1; (Value used in expression)
y=-1?(x++?x:-1):1;
Second sequence point is second ? from left. As mentioned above the update operations are effective after sequence so even though x++ is there the value used in this sequence is -1 and updated value will be used in following.
x=0; (Actual Value, bcoz of x++)
x=-1; (Value used in expression)
y=-1?x:-1;
Now it will be
x=0; (Actual Value)
x=0; (Value used in expression)
y=x;
y=0;
Hope this make sense now.

Increment and Decrement Operators

#include <stdio.h>
int main()
{
int x = 4, y, z;
y = --x;
z = x--;
printf("%d %d %d", x, y, z);
}
Output: 2 3 3
Can anyone explain this?
And what does i =+ j mean (suppose i = 1 and j = 2)?
y = --x means "decrease x by one, then store the result in y"
z = x-- means "save a temp of x. Decrease x by one. Store the temp value in z"
Hence:
x starts at 4.
It gets decreased by 1 (to 3). 3 is stored in y.
x is saved to a temp. x is decreased again (to 2). then the temp (3) is stored in z.
y and z are printed as 3, x is printed as 2.
The postfix decrement operator (x--) returns the value of the variable before it was decremented.
x = 2, because you've decremented it
twice.
y = 3, because you've assigned
it to the value of x after it was
decremented from 4
z = 3, because you've
assigned it to the value of x
before it was decremented from 3.
simple explanation:
--x or ++x : Value will be modified after.
x-- or x++ : Value will be modified before
Detailed explanation:
--x or ++x: pre-decrement/increment: will first do the operation of decrementing or incrementing first, then it will assign x.
x-- or x++: post:decrement/increment: will first assign the value of x and then it will do the operation of decrementing or incrementing after.
lets write your code in a nicer format and go through your code step by step and annotate it to show you visually what happens:
main() {
//We declare the variables x, y and z, only x is given a value of 4.
int x=4,y,z;
//--x will decrement var x by 1 first THEN it will assign the value of x to y.
//so: x = 3, y = 3 and z = nothing yet.
y = --x;
//x-- will assign the value of x to z first, then var x will be decremented by 1 after.
//so: x = 2, y=3 and z = 3
z = x--;
printf ("\n %d %d %d", x,y,z);
}
You have to understand the notions of post-decrement and pre-decrement operator.
Both will decrement your variable, but one of them will return the original value (x--) and one of them will return the decremented value (--x).
Postfix decrement (x--) is different from prefix decrement (--x).
The former return the value x, then decrements it; the latter decrements and then returns the value.
And if you thing how a postfix is written at low level, you'll find that it is a liiiitle slower than the prefix... :)
y = --x;
X is decremented, then Y is assigned with the value of X (3)
z = x--;
Z is assigned with the value of X (3), the X is decremented (2)
Yes:
x = 4
y = pre-decrement x (basically decrement by 1 and then assign, i.e. y = x-1 = 3
x =3
z = post-decrement x (decrement by 1 after assigning the value, i.e. z = x = 3, then x = x - 1
x = 2
So x = 2, y = 3, z = 3, exactly what you saw.
If the operator is a prefix the incrementation happens before the assignment, if the operator is a postfix the incrementation happens after the assignment.
let ** be an increment/decrement operator. **e means apply ** to e and evaluate the result whereas e** means evaluate e and then apply ** to it.
Ergo, if decrementation and evaluation are seperated, the code reads as:
int x=4,y,z;
x-=1;//3
y = x;//3
z = x;//3
x-=1;//2
which gives you the ouput you have ;)
x++ / x-- is called post increment / decrement (value modified after...)
++x / ++x is called pre increment / decrement (value modified before...)
Here is what happens (roughly) in your example :
int x=4,y,z; // declare x=4, y=0, z=0
y = --x; // decrement x then assign it to y (pre decrement) (y=x=3)
z = x--; // assign x to z then decrement x (post decrement) (z=3 and x=2)
printf ("\n %d %d %d", x,y,z); // output 2 3 3
A pre increment/decrement looks like this in pseudocode
read value
increment/decrement value
write value
assign value
and a post increment/decrement looks like this
read value
assign value
increment/decrement value
write value
#include<stdio.h>
main ()
{
int x=4,y,z;
y = --x;
z = x--;
printf ("\n %d %d %d", x,y,z);
}
output 2,3,3.................................first time x=4 fine. y=--x, means value of x is decremented by 1 and stored in y, thus now y=3 and x is also 3. then z=x-- means value of x is stored in z( z=3) and then x is decremented i.e now x=2 but z=3. when u r printing the value, then printf() prints 2 3 3
Talking about what i=+j; means(given i=1 and j=2)
i=+j; is equivalent to i=i+j; so your expression becomes i=1+2 i.e. i=3

what is the meaning of == sign?

I am trying to figure out what == sign means in this program?
int main()
{
int x = 2, y = 6, z = 6;
x = y == z;
printf("%d", x);
}
The == operator tests for equality. For example:
if ( a == b )
dosomething();
And, in your example:
x = y == z;
x is true (1) if y is equal to z. If y is not equal to z, x is false (0).
A common mistake made by novice C programmers (and a typo made by some very experienced ones as well) is:
if ( a = b )
dosomething();
In this case, b is assigned to a then evaluated as a boolean expression. Sometimes a programmer will do this deliberately but it's bad form. Another programmer reading the code won't know if it was done intentionally (rarely) or inadvertently (much more likely). A better construct would be:
if ( (a = b) == 0 ) // or !=
dosomething();
Here, b is assigned to a, then the result is compared with 0. The intent is clear. (Interestingly, I've worked with C# programmers who have never written pure C and couldn't tell you what this does.)
It is "equals" operator.
In the above example, x is assigned the result of equality test (y == z) expression. So, if y is equal to z, x will be set to 1 (true), otherwise 0 (false). Because C (pre-C99) does not have a boolean type, the expression evaluates to an integer.
Equality. It returns 1 if the operands are equal, 0 otherwise.
== means "is euual to". This operator has higher precedece than = (equal to) operator. So the equation x = y == z; will try to assign result of y==z to variable x. which is 1 in this case.
int main()
{
int x = 2, y = 6, z = 6;
x = y == z;
printf("%d", x);
}
let`s start like this:
x = (6==6)
It asks is 6 equivalent to 6?: true
x = true, but since x is an int, x= 1
The new value of x is 1.
The following is printed:
1
It's saying
X will equal either true/1 or false/0.
another way to look at that line is this:
x = ( is y equal to true? then true/1 or false/0 )
== operator used for equality..
here in u r example
if y is equal to z then x will hav true value otherwise x will hav false
Think about it like this:
= means give something a value.
== means check if it is equal to a value.
For example
int val = 5; //val is 5
//= actually changes val to 3
val = 3;
//== Tests if val is 3 or not.
//note: it DOES NOT CHANGE the value of val.
val == 3;
int new_val = val == 3; //new_val will be 1, because the test is true
//the above statement is the same as
bool is_val_3 = false;
if( val == 3 )
is_val_3 = true;
int new_val;
new_val = is_val_3;
//putting it together,
val = new_val == 2; //sets val to 0. do you understand why now?

Resources