I am trying to understand how increment (and decrement) operator works based on where they are placed. In the following code, in the end y will contain 3 and x contain 4. But the suffix ++ has higher precedence than assignment operator =. Shouldn't this mean the x++ part be evaluated first to give x=4, and then the assignment gives y=x=4?
Precedence doesn't affect what post-increment does. By definition, although it increments the variable, it evaluates to the value of the variable before the increment. Written as a function:
1 2 3 4 5 6 7
int postinc(int &x) {
int ret = x;
x = x + 1;
return ret; // return the value before the increment
}
y = postinc(x); // y gets x's old value
So the ++ and -- operators are exception to the precedence rule?
No. Not at all. Precedence is just about the default grouping of subexpressions. No matter how they are grouped, post-increment does the same thing. x++ always equals the value of x before the increment. The fact that x is incremented is a side-effect and not part of the expression value at all.
#include <iostream>
usingnamespace std;
void Rev(string& s)
{
int i = 0;
int j = s.size()-1;
while (i < j)
swap(s[i++], s[j--]);
}
int main()
{
string s("Hello World!");
cout << s << endl;
Rev(s);
cout << s << endl;
return 0;
}
Hello World!
!dlroW olleH
It would've been a mistake, without other changes, to try
1 2
while (i++ < j--)
swap(s[i], s[j]);
because what happens is
1. i<j evaluated
2. i++ happens. j-- happens
3. NOW the body of the loop occurs, and already we're off by an index when we didn't want to be.
Edit: example with for.
Similarly, this would be a mistake for the same reason
1 2
for ( ; i++ < j--; )
swap(s[i], s[j]);
But this is fine, since the third part of a for loop is evaluated after the body
@tpb Well, there's a difference between your first example and the other two --
First goes from 10 to 0 , inclusive
But this for (int i = 10; i-- > 0; ) // stops when i WAS zero (on last iteration)
effectively begins its body statements at i=9 down to 0. If i was initialized to something.size() this is fine because we usually subtract one from the end anyway.
Edit: if you wanted to go from 9 to 0, (or from something.size()-1 to 0), I like this one:
Thank you for all the examples, they help me understand better this prefix and postfix increment operators thing. If my understanding is correct, any expression
statement;
containing post-incremented operator will be evaluated until the semicolon using the unincremented value, afterwards the variable followed by the post-increment is affected by this operator.
afterwards the variable followed by the post-increment is affected by this operator
Not quite. Time has nothing to do with it. It's not that "afterwards the variable ... is affected". It could be the case that the variable is incremented before any other part of the statement is executed. It's just that the old value is used in the the expression. It's as simple as that. For instance, that's how the example function I wrote above works. It changes the value of the variable, but returns the old value.
Note that his makes a statement like the following problematic:
y = x++ + x;
What value would the second x have in the expression? In fact, such a statement is an example of what is called "undefined behavior", and it's a mistake to write such a thing. You are not supposed to use the value of a variable modified by a side-effect more than once in a statement.
That is interesting. I ran it with x=5 and I got y=11. But as soon as I swapped the order of the RHS so that y = x + x++;
I got y=10. This means in the first case, the new x value was used whereas in the second case the old one was used. In either case I got warning warning: unsequenced modification and access to 'x' [-Wunsequenced].
Anyway, this makes it as if addition operation is not always commutative in C++.