I have a problem understanding the output of the code. Any explanation please...
#include<stdio.h>
void main()
{
int x=2,y=5;
x*=y+1;
printf("%d",x);
}
The output is as 12. But as per my understanding x*=y+1;is x=x*y+1; but as per operator precedence x*y should be evaluated followed by adding 1 so it should be 10+1=11. But it is 12 — can anyone explain please?
It will be evaluated as
x = x * (y + 1);
so
x = 2 * ( 5 + 1 )
x = 12
What's going on here is how the order of operations happens in programming.
Yes, if you were to have this equation x*y+1 it would be (x * y ) + 1 and result in eleven.
But in programming, the equation to the right of the = sign is solved for prior to being modified by the symbol proceeding the = sign. In this equation it is multiplied.
So x *= y + 1 is actually x = x * ( y + 1 ) which would be 12.
^ In this case, the asterisk(*) is multiplying the entire equation on the right hand side by x and then assigning that outcome to x.
It is translated into : x = x*(y+1);
So very obviously it prints out 12.
Your understanding is correct but it's somthing like this:
x*=y+1; => x = x * (y + 1);
Now apply BODMAS
x *= y + 1 is x = x * (y + 1)
Operator + has higher precedence than operator *=.
x*=y; works like x=x*y;
and here x*=(y+1) is getting expanded like x = x * (y + 1);
*= and similar ones are a type of C assignment operators, i.e. these operators are different from * and alike.
Now from C operator precedence, these operators have lowest precedence (higher than ,) hence y + 1 will be evaluated first, then *= will be evaluated and result will be assigned to x.
It evaluates as
x = x * (y + 1);
so
x = 2 * (5 + 1) = 12
Take a look at Operators order, you will see why in this case it is evaluated like that.
Here from operator procedure in c you can see
Addition/subtraction assignment has lower procedure than simply add operation.
so here
x*=y+1;
+ get executed first.
so
x = x * (6)
so x = 2 * 6
x = 12;
Related
Where would the associativity of the = assignment operator make a difference in an expression? I thought that the associativity relates to operands that share an operator, but in the case of assignment, how would that work? A few examples that (might) be relevant are:
x = 1
x + 2 = y + 3 = z + 5
Does this just mean that, in the assignments above, we would have:
y + 3 = z + 5
Done before, for example:
x + 2 = y + 3
Or what other scenarios are there where assignment associativity 'matters' ?
Your examples don't demonstrate anything, because associativity only comes into play when you have several operators with the same precedence (or the same operator) next to each other.
Consider x = y = 42, which sets both variables to 42.
Because of right-associativity, it's parsed as x = (y = 42), where y = ... returns the new value of y, which is 42.
This is why it works. If = was left-associative and it was parsed as (x = y) = 42, then:
In C it wouldn't compile at all, because x = ... returns an rvalue rather than an lvalue, and those can't be assigned to.
In C++, where assignments return lvalues, it would work like x = y; x = 42;, which is far from being intuitive.
I'm only a casual user of C, when programming for micros like Arduino, but I'm interested in bettering my understanding of the vernacular.
I know that you can shorthand things like x = x % 10 to x %= 10, and x = x + 1 to x += 1. But I couldn't wrap my head around compounding both parts of this:
x = (x + 1) % 10
If that's possible, what does it look like?
(x += 1) %= 10 ? That seems... if not wrong, then confusing.
The expression (x += 1) %= 10 is not legal in C. The result of an assignment operator, whether = or one of the compound assignment operators, is not a lvalue. Loosely speaking, this means it can't appear on the left side of an assignment.
That statement would have to be broken up in two parts:
x += 1;
x %= 10;
As an aside, (x += 1) %= 10 is valid in C++.
Just try x += 1; x %= 10; as an alternative, it will work, but it is not equivalent to the first expression. You cannot wrap both in a single expression[1] as
x op= expression;
means
x = x op (expression); /* look at the parenthesis */
and that forces the evaluation of the expression first. The only case in which
x = (x op1 a) op2 b;
could be converted to an op-assign operation is if the operators are associative and the expression can be converted to:
x = x op1 (a op2 b);
(or if op2 has higher precedence than op1, which means the evaluation order is as above) and then
x op1= a op2 b;
would be possible.
Examples
x = x + a + b; ==> x += a + b; /* this implies a different order of evaluation */
x = x + a * b; ==> x += a * b;
x = x + a % b; ==> x += a % b; /* % has higher precedence than + */
Note [1]: well, you can, but using another operator, the , comma operator, you can convert it to x += 1, x %= 10;
When i compile this code,it showing an error as lvalue required as increment operand
int main(void)
{
int x,y,z;
x=8++;
y=++x++;
z=(x+y)--;
printf("x=%d,y=%d,z=%d",x,y,z;
return 0;
}
When you write something++ or ++something it's roughly equivalent to
something = something + 1
(the difference between something++ and ++something is in what you get when you assign the result to something else).
Because of this, the operand of ++ has to be something you can assign to.
8++ is equivalent to 8 = 8 + 1, but you can't assign to a number.
++x++ would be equivalent to something like (x = x + 1) = (x = x + 1) + 1, I can't even fathom what this could be intended to mean.
(x+y)-- is equivalent to (x + y) = (x + y) - 1. You can't assign to an addition expression (which variable would you be setting)?
You should only use ++ or -- when you actually want to update a variable. It's not a general replacement for + 1 or - 1. So your program should be:
x = 8 + 1;
y = 1 + x + 1;
z = (x + y) - 1;
This will print
x = 9, y = 11, z = 19
constant cannot be changed. 8 is a constant value. (x+y) is also not the value which can be incremented and stored somewhere.
x++ uses the value of x then increments the x. So the lvalue is changed itself not only the result of the operation.
correct is
z=(x+y)-1;
x=8+1;
I have done a ton of research as to how the order of evaluation goes - but cannot figure out how it would go for this equation:
z = !x + y * z / 4 % 2 - 1
My best guess is (from left to right):
z = !x + {[([y * z] / 4) % 2] - 1}
Order of evaluation and operator precedence are two different things.
Your best guess is correct. All the multiplicative operators * / % have the same precedence, and bind left-to-right. The additive operator - has lower precedence. The unary ! operator binds more tightly than the multiplicative or additive operators. And the assignment operator = has very low precedence (but still higher than the comma operator).
So this:
z = !x + y * z / 4 % 2 - 1
is equivalent to this:
z = (!x) + (((y * z) / 4) % 2) - 1
But the operands may legally be evaluated in any order (except for certain operators like &&, ||, ,, which impose left-to-right evaluation). If the operands are simple variables, this probably doesn't matter, but in something like:
z = func(x) * func(y);
the two function calls may occur in either order.
If you can't understand it, rewrite your expression
z = !x + y * z / 4 % 2 - 1
notx = !x; /* you can move this line 1, 2, or 3 lines down */
tmp1 = y * z;
tmp2 = tmp1 / 4;
tmp3 = tmp2 % 2;
tmp4 = notx + tmp3;
tmp5 = tmp4 - 1;
The question is:
int z, x=5, y=-10 ,a=4, b=2;
z = x++ - --y * b / a;
Just wanted to know the output and how --y will work for the negative value of 'y'. What will be the precedence of solving this?
int z, x=5, y=-10 ,a=4, b=2;
z = x++ - --y * b / a;
z = 5++ - --(-10) * 2 / 4 // Suffix ++/-- goes first
z = 5 - --(-10) * 2 / 4 // Prefix ++/-- is next
z = 5 - (-11) * 2 / 4 // and then * and /
z = 5 - (-22) / 4
z = 5 - (-5)
z = 10
Unlike y, x keeps it's value because in suffix notation the operator returns the original value not the modified one. (Someone else linked the operator precedence page so I won't)
It will be evaluated based on the Operator Precedence or "Order of Operations" - http://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B#Operator_precedence
These two are equivelent according to Order of operations
z = x++ - --y * b / a;
z = (x++) - (((--y) * b) / a);
The precedence of the operations is
z = ((x++) - (((--y) * b) / a));
IOW,
The result of --y must be known before computing --y * b;
The result of --y * b must be known before computing --y * b / a (* and / have the same precedence, but are left-associative, so a / b * c would be parsed as (a / b) * c);
The result of x++ must be known before computing x++ - --y * b / a
And finally, the result of x++ - --y * b / a must be known before assigning the result to z.
However...
Note that precedence is not the same thing as order of evaluation. Each of the individual expressions x++, --y, b, and a may be evaluated in any order. The compiler may choose to evaluate x++, then a, then b, then --y. The compiler may choose to evaluate --y * b / a before evaluating x++. The compiler may choose to defer applying the side effects to x++ and --y until after the assignment of the result to z.
y will decrement before the = operation because the -- precedes y and
x will increment AFTER the = operation because the ++ is after the x.
for example:
int i = 2, y = 3, z;
z = ++i + ++y; //3 + 4
or
int i = 2, y = 3, z;
z = --i + --y; //1 + 2
and
int i = 2, y = 3, z;
z = i++ + y++; //2 + 3
Notice in the last example that it is still 2 + 3. That is because the ++ is after i and y so they are incremented after the = statement.
Knowing this, just apply your normal order of operations
(1. Parentheses 2. Exponents 3. Multiplication/Divison 4. Addition/Subtraction) to solve the problem. Since the multiplication and division segments are right next to eachother just read from left to right for that part.
int z, x=5, y=-10 ,a=4, b=2;
z = x++ - --y * b / a;
y = --y
y = -11
z = 5 - -11 * 2 / 4
z = 5 - -22 / 4
z = 5 - -5
z = 10
x = 5++
x = 6
That's my thought process for this: I interperet the values of x and y based off the location of the ++ and -- and then first mulitply -y * b and then divide that value by a and then add that value to x and then finally increment x. Remember when multiplication and division are right next to each-other just read left to right.