tags:

views:

176

answers:

6

Possible Duplicate:
C#: what is the difference between i++ and ++i?

I see this operator (++) very often. I know what it does ultimately, but it seems like there's some rules I don't understand. For example, it seems to matter if you put it before or after the variable you're using it on. Can someone explain this?

+9  A: 

The statement

x++;

is exactly equivalent to

x = x + 1;

except that x is evaluated only once (which makes a difference if it is an expression involving property getters).

The difference between the following two:

DoSomething(x++);   // notice x first, then ++
DoSomething(++x);   // notice ++ first, then x

Is that in the first one, the method DoSomething will see the previous value of x before it was incremented. In the second one, it will see the new (incremented) value.

For more information, see C# Operators on MSDN.

It is possible to declare a custom ++ operator for your own classes, in which case the operator can do something different. If you want to define your own ++ operator, see Operator Overloading Tutorial on MSDN.

Timwi
"except that `x` is evaluated only once" - sorry, you're wrong there. `x++` and `x = x + 1` are actually completely equivalent. Note that in the latter case, `x` is **evaluated** only once as well. It is then **set**, which also happens with x++. (my comment is, of course, referring to using the operator as a statement, not as part of another call, in which case `function(x++)` and `function(x = x + 1)`, obviously, do not behave equally)
Michael
@Michael: You misunderstood what I mean. If you write `myObj.SomeProperty.SomeValue++`, then the `SomeProperty` getter is called only once, but if you write `myObj.SomeProperty.SomeValue = myObj.SomeProperty.SomeValue + 1`, then it is called twice.
Timwi
In this case, you're right, the SomeProperty getter is called twice :-) Just wanted to point out that the SomeValue getter would be called only once. Also a compiler might optimize away the double getter-calling, I think? But this is just a suspicion.
Michael
@Michael: Any compiler that would optimise it away would have a bug. The C# specification is very clear and unambiguous about the expected side-effects. This is not C++ after all :)
Timwi
Thanks for this explanation, it's all clear for me now.
Jouke van der Maas
It is *not* true that x++ and x = x + 1 are exactly the same. Don't believe me? Try it. byte x = 0; x++; vs byte x = 0; x = x + 1; gives different results because *one of them doesn't even compile*.
Eric Lippert
I tried the **byte x = 0; x = x + 1;** in Visual Studio, it told me that I couldn't convert an int to a byte. **x++;** and **x += 1;** did work though.
Kevin
@Kevin: You are correct. In fact x++ and x +=1 are more akin to x = (T)(x + 1), where T is the type of the variable x. This is one of the few places in which the C# language silently inserts an "explicit" conversion that is not in fact explicit at all.
Eric Lippert
@Eric - Suppose our byte was of type int instead, would it still do the conversion?
Kevin
@Kevin: Would it do the conversion from int to int as an identity conversion? Sure, if that's how you like to think about it. I mean, how could you tell whether it did or not? There's no noticable difference between zero, one and a thousand identity conversions.
Eric Lippert
+3  A: 

http://msdn.microsoft.com/en-us/library/36x43w8w(v=VS.80).aspx

The increment operator (++) increments its operand by 1. The increment operator can appear before or after its operand:

The first form is a prefix increment operation. The result of the operation is the value of the operand after it has been incremented.

The second form is a postfix increment operation. The result of the operation is the value of the operand before it has been incremented.

Michael Pakhantsov
+1  A: 

well if you put it like

variable++

It first uses the variable and the increments it (+1) On the otherhand if you

++variable

It first increments the variable and then uses it

andrei
This answer is also not correct. The last statement incorrectly implies that the result is *the value of the variable after incrementing* when in fact the result is *the value assigned to the variable*. The variable is not read a second time.
Eric Lippert
@Eric Lippert You have an eye for detail there, i did not know that.
andrei
A: 

If you put the ++ operator before the variable, it is incremented first. If you put the ++ operator after the variable, it is incremented after.

For example(C#):

int x = 0; Console.WriteLine("x is {0}", x++); // Prints x is 0

int y = 0; Console.WriteLine("y is {0}", ++y); // Prints y is 1

tim
No, `i=i++` means you increment first and then assign the old value back, making the operation useless. `i=++i` has the same effect as simply `++i`.
Timwi
Yeah, was about to write the same. i=i++ and similar examples are very bad for the explanation, because its more confusing the clarifying.
Stefan Steinegger
You shouldn't be copy-pasting answers of others just like that.
Kevin
+3  A: 

If you put the ++ operator before the variable, it is incremented first. If you put the ++ operator after the variable, it is incremented after.

For example(C#):

int x = 0;
Console.WriteLine("x is {0}", x++); // Prints x is 0

int y = 0;
Console.WriteLine("y is {0}", ++y); // Prints y is 1

Hope this cleared it up.

Kevin
Though this is a common answer to this question, it is in fact wrong. The *time* when the increment happens does *not* change depending on whether the operator is prefix or postfix. What changes is *which temporary value computed during the increment is chosen as the result of the operator.* Contrast this answer, which states that the difference is *when the side effect happens* with Michael's answer, that correctly states that the difference is *which value is returned*. This is a subtle but important difference.
Eric Lippert
@Eric - I didn't know about that :). Thanks for explaining!
Kevin
A: 

Another way to see it... here are two functions that do the same as prefix/postfix ++. This illustrates that prefix is, in theory, faster, because no temporary variable is needed to store the "previous" value:

// same as x ++;
int PostfixIncrement(ref int x)
{
    int y = x;
    x = x + 1;
    return y;
}

// same as ++ x;
int PrefixIncrement(ref int x)
{
    x = x + 1;
    return x;
}
tenfour