What is the difference between i++ and ++i in C#?
Asked Answered
T

7

256

I've seen them both being used in numerous pieces of C# code, and I'd like to know when to use i++ and when to use ++i?
(i being a number variable like int, float, double, etc).

Tineid answered 27/7, 2010 at 18:1 Comment(6)
Except where it makes no difference whatsoever, you should never use either one, because it's just going to cause people to ask the same question you're asking now. "Don't make me think" applies to code as well as design.Nomen
Soooo many duplicates: #467822, #484962, https://mcmap.net/q/88647/-difference-between-i-and-i-duplicate, etc.Oblong
@gnovice: the duplicates you mentioned are about C++, mine is about C#.Tineid
@Dlaor: Did you even read the links in my comment? The first one is about C#, and the second one is language-agnostic with an accepted answer that focuses on C#.Oblong
@gnovice, the first one asks about performance difference while I asked about the actual code-wise difference, the second is about the difference in a loop while I asked the difference in general, and the third is about C++.Tineid
I believe this is not a duplicate of Difference between i++ and ++i in a loop? - as Dloar says in his comment above the other question asks specifically about usage within a loop.Opalopalesce
C
251

Oddly it looks like the other two answers don't spell it out, and it's definitely worth saying:


i++ means 'tell me the value of i, then increment'

++i means 'increment i, then tell me the value'


They are Pre-increment, post-increment operators. In both cases the variable is incremented, but if you were to take the value of both expressions in exactly the same cases, the result will differ.

Cutoff answered 27/7, 2010 at 18:22 Comment(28)
This seems to be at odds with what Eric is sayingCryostat
Neither statement is correct. Consider your first statement. i++ actually means "save the value, increment it, store it in i, then tell me the original saved value". That is, the telling happens after the incrementing, not before as you have stated it. Consider the second statement. i++ actually means "save the value, increment it, store it in i, and tell me the incremented value". The way you said it makes it unclear whether the value is the value of i, or the value that was assigned to i; they could be different.Drida
@Eric, it would seem to me with even your answer, the second statement is categorically correct. Though he excludes a few steps.Cryostat
Eric, thanks for the comment, but I can't see any case in which there would be a noticeable difference in a real C# code example (even under scrutiny) between what I am saying and the physical underlying process?Cutoff
Sure, most of the time the sloppy, incorrect ways of describing the operational semantics give the same results as the precise and correct description. First, I don't see any compelling value in getting the right answers through incorrect reasoning, and second, yes, I have seen production code that gets exactly this sort of thing wrong. I get probably half a dozen questions a year from real programmers about why some particular expression chock-full of increments and decrements and array dereferences doesn't work the way they assumed it did.Drida
By that I mean I'm concentrating on your point 'the telling happens after the incrementing': this is a single expression that is being evaluated, and I'm saying it will either evaluate to the value before the increment or after. No use of the result would occur until after the evaluation of the expression anyway (at least, this is what I think and possibly why I am confused), so whether it's 'told' before or after makes no difference?Cutoff
I'm pretty sure that the C standard explicitly allows the increment to occur at any time between the previous sequence point and the next sequence point. Thus, in the statement "*a = (*b)++", if 'a' and 'b' happen to point to the same variable, the assignment could happen before the increment (in which case the variable will be incremented) or after (in which case the variable would be incremented and then reassigned its old value). Actually, if the compiler's generated code wanted to start printing "99 bottles of beer", I think that would be allowable under the standard too.Marthamarthe
@supercat: The discussion is about C#, not C.Neutrino
@Eric, would appreciate a response if possible, so I can update my answer accordingly if necessary.Cutoff
@Kieren, look at eric's refernced post that caused confusion using this def. #1260727Cryostat
Hi Evan, thanks, I agree with that, I can't see how it's any different to what I'm saying. I don't say that the increment happens after everything else on the line; I simply say the result is either the value before or after the increment. I stand by my statements; 'tell me the value then add 1' doesn't mean 'tell me the value, then evaluate the whole statement, then add 1'. Would welcome some specific feedback though.Cutoff
@Brian - did you read my comments? The lack of response? You truly believe something is misleading - care to share exactly what it is without copy&pasting Eric? Or just another Eric enthusiast who doesn't want to think about it themselves? The guy didn't even reply to me.Cutoff
@Kieren: The misleading part is that you state "i++ means 'tell me the value of i, then increment'" when it really means, 'increment i, then tell me the old value of i'. There are cases where this order matters.Fancy
@Fancy - there are no cases where that applies - where what I say isn't true. As I said, I don't say "tell me the value of i, then evaluate the rest of the statement, then increment": we are saying the same thing, but mine answer is just more succinct!Cutoff
@Fancy - that's what I thought. :)Cutoff
@Kieren: Eric's example (int[] arr = {0}; int value = arr[arr[0]++];) is the simplest one I can think of where this order causes an issue. I can't offer a better one.Fancy
@Fancy - To quote myself, 'i++ means 'tell me the value of i, then increment'. In this example, arr[0]++ says tell me the value of arr[0], then increment. I don't say when it will happen, or allude that it happens before or after anything else is evaluated. Also, Eric's first linked blog post explains the fine details of when evaluations and side-effects occur: but simply put, I don't say anything different!Cutoff
@Kieren: I think your explanation is contradicted by the order of the side effects. Apparently, you do not. :::shrug:::Fancy
Nice to see people still blindly voting me down after giving a clear, concise and correct answer. Bandwagon's getting a bit full though..Cutoff
I put a vote down and I am not blind. Your answer is incorrect. i++ and ++i translate to same events in same order EXCEPT what is returned at the end of the expression evaluation. Your answer seems to suggest otherwise. Please re-read Eric's answer if you are still unclear.Barratry
Downvote. Kieren, you said "I don't say when it will happen, or allude that it happens before or after anything else is evaluated." That is incorrect. "tell me the value of i, then increment" clearly expresses a temporal relationship. Please refer to the definition of "then". You are using the word in its second sense (as listed at that link as of right now); that sense is defined as "After that; next; afterward." Your statement means "tell me the value of i, and after that, increment" and that statement is false.Violation
@Matthew - I clearly say 'tell me the value of i, then increment' - which is correct. My addendum of 'I don't say when' is with regards to anything else the user might care to craft into that statement / line. So, once again, "i++" means "tell me the value of i, then increment". The extra part was to say I don't cover things like "(++i)[j++] = i++ + ++j". I'm saying the difference between i++ and ++i.Cutoff
@Kieren The statement is incorrect. The increment comes before the value of i is returned. "increment, then tell me the previous value of i" would be correct. You don't need to add the extra details in order to make a correct statement.Violation
@KierenJohnstone I edited your answer so that it says the same thing as Eric Lippert (I think). Could you please review?Keelung
@MilanGardian I rolled back your edit. Right or wrong, your edit changed the answer, and that should probably be the OP's decision to make.Armipotent
Regardless of what abyone else says, this is exactly correct. As far as the generated code is concerned, even Eric is wrong. And he and everybody else is pretending that Kierin stated that the increment happens after the rest of the expression. He did not say anything of he sort.Outlook
@KierenJohnstone It's easy to be blasé about the exact sequence of events when 95% of the time it doesn't matter. But being wrong 5% of the time makes your answer wrong. I can't tell you how many convoluted messes I've seen because someone didn't understand the sequence of events when an exception is thrown. The exact point it's triggered, the subsequent flow, and the resulting state. As an example (next comment), your statement implies that a == int.MaxValue in the catch block.Danyelldanyelle
@KierenJohnstone The following code sample shows how claiming that a is "told the value of i" before i is incremented creates the wrong impression about the effect on a: int i = int.MaxValue; int a = 0; try { checked { a = i++; } } catch { Console.WriteLine(a); } The output is 0 because a isn't told anything until after i is incremented. Incrementing i throws an exception and a remains unchanged.Danyelldanyelle
D
525

The typical answer to this question, unfortunately posted here already, is that one does the increment "before" remaining operations and the other does the increment "after" remaining operations. Though that intuitively gets the idea across, that statement is on the face of it completely wrong. The sequence of events in time is extremely well-defined in C#, and it is emphatically not the case that the prefix (++var) and postfix (var++) versions of ++ do things in a different order with respect to other operations.

It is unsurprising that you'll see a lot of wrong answers to this question. A great many "teach yourself C#" books also get it wrong. Also, the way C# does it is different than how C does it. Many people reason as though C# and C are the same language; they are not. The design of the increment and decrement operators in C# in my opinion avoids the design flaws of these operators in C.

There are two questions that must be answered to determine what exactly the operation of prefix and postfix ++ are in C#. The first question is what is the result? and the second question is when does the side effect of the increment take place?

It is not obvious what the answer to either question is, but it is actually quite simple once you see it. Let me spell out for you precisely what x++ and ++x do for a variable x.

For the prefix form (++x):

  1. x is evaluated to produce the variable
  2. The value of the variable is copied to a temporary location
  3. The temporary value is incremented to produce a new value (not overwriting the temporary!)
  4. The new value is stored in the variable
  5. The result of the operation is the new value (i.e. the incremented value of the temporary)

For the postfix form (x++):

  1. x is evaluated to produce the variable
  2. The value of the variable is copied to a temporary location
  3. The temporary value is incremented to produce a new value (not overwriting the temporary!)
  4. The new value is stored in the variable
  5. The result of the operation is the value of the temporary

Some things to notice:

First, the order of events in time is exactly the same in both cases. Again, it is absolutely not the case that the order of events in time changes between prefix and postfix. It is entirely false to say that the evaluation happens before other evaluations or after other evaluations. The evaluations happen in exactly the same order in both cases as you can see by steps 1 through 4 being identical. The only difference is the last step - whether the result is the value of the temporary, or the new, incremented value.

You can easily demonstrate this with a simple C# console app:

public class Application
{
    public static int currentValue = 0;

    public static void Main()
    {
        Console.WriteLine("Test 1: ++x");
        (++currentValue).TestMethod();

        Console.WriteLine("\nTest 2: x++");
        (currentValue++).TestMethod();

        Console.WriteLine("\nTest 3: ++x");
        (++currentValue).TestMethod();

        Console.ReadKey();
    }
}

public static class ExtensionMethods 
{
    public static void TestMethod(this int passedInValue) 
    {
        Console.WriteLine($"Current:{Application.currentValue} Passed-in:{passedInValue}");
    }
}

Here are the results...

Test 1: ++x
Current:1 Passed-in:1

Test 2: x++
Current:2 Passed-in:1

Test 3: ++x
Current:3 Passed-in:3

In the first test, you can see that both currentValue and what was passed into the TestMethod() extension show the same value, as expected.

However, in the second case, people will try to tell you that the increment of currentValue happens after the call to TestMethod(), but as you can see from the results, it happens before the call as indicated by the 'Current:2' result.

In this case, first the value of currentValue is stored in a temporary. Next, an incremented version of that value is stored back in currentValue but without touching the temporary which still stores the original value. Finally that temporary is passed to TestMethod(). If the increment happened after the call to TestMethod() then it would write out the same, non-incremented value twice, but it does not.

It's important to note that the value returned from both the currentValue++ and ++currentValue operations are based on the temporary and not the actual value stored in the variable at the time either operation exits.

Recall in the order of operations above, the first two steps copy the then-current value of the variable into the temporary. That is what's used to calculate the return value; in the case of the prefix version, it's that temporary value incremented while in the case of the suffix version, it's that value directly/non-incremented. The variable itself is not read again after the initial storage into the temporary.

Put more simply, the postfix version returns the value that was read from the variable (i.e. the value of the temporary) while the prefix version returns the value that was written back to the variable (i.e. the incremented value of the temporary). Neither return the variable's value.

This is important to understand because the variable itself could be volatile and have changed on another thread which means the return value of those operations could differ from the current value stored in the variable.

It is surprisingly common for people to get very confused about precedence, associativity, and the order in which side effects are executed, I suspect mostly because it is so confusing in C. C# has been carefully designed to be less confusing in all these regards. For some additional analysis of these issues, including me further demonstrating the falsity of the idea that prefix and postfix operations "move stuff around in time" see:

https://ericlippert.com/2009/08/10/precedence-vs-order-redux/

which led to this SO question:

int[] arr={0}; int value = arr[arr[0]++]; Value = 1?

You might also be interested in my previous articles on the subject:

https://ericlippert.com/2008/05/23/precedence-vs-associativity-vs-order/

and

https://ericlippert.com/2007/08/14/c-and-the-pit-of-despair/

and an interesting case where C makes it hard to reason about correctness:

https://learn.microsoft.com/archive/blogs/ericlippert/bad-recursion-revisited

Also, we run into similar subtle issues when considering other operations that have side effects, such as chained simple assignments:

https://learn.microsoft.com/archive/blogs/ericlippert/chaining-simple-assignments-is-not-so-simple

And here's an interesting post on why the increment operators result in values in C# rather than in variables:

Why can't I do ++i++ in C-like languages?

Drida answered 27/7, 2010 at 18:33 Comment(13)
+1: For the truly curious, could you give a reference as to what you mean by the "design flaws of these operations in C"?Roadwork
@Justin: I've added some links. But basically: in C, you have no guarantees whatsoever about what order things happen in time. A conforming compiler can do any damn thing it pleases when there are two mutations in the same sequence point, and need never tell you that you're doing something that is implementation-defined behaviour. This leads people to write dangerously nonportable code that works on some compilers and does something completely different on others.Drida
Very helpful and interesting. I was in the "increment is done before/after remaining operations" camp. I have now seen the error of my ways. Thanks!!Afternoons
I must say that for the really curious, this is good knowledge, but for the average C# application, the difference between the wording in the other answers and the actual stuff going on is so far below the abstraction level of the language that it really makes no difference. C# is not assembler, and out of 99.9% of the times i++ or ++i are used in code, the things going on in the background are just that; in the background. I write C# to climb to abstraction levels above what's going on on this level, so if this really matters for your C# code, you might already be in the wrong language.Ube
@Tomas: First off, I am concerned about all C# applications, not merely the mass of average applications. The number of non-average applications is large. Second, it makes no difference except in the cases where it makes a difference. I get questions about this stuff based on real bugs in real code probably half a dozen times a year. Third, I agree with your larger point; the whole idea of ++ is a very low-level idea that looks very quaint in modern code. It's really only there because it is idiomatic for C-like languages to have such an operator.Drida
"It is not the case that the value of the postfix version is the new value of x. It is the value that was stored in x." Shouldn't that read "prefix", not "postfix"? (Postfix returns the value that was read, not the value that was written.)Acarid
@Bradley: It's probably a typo.Drida
Great answer Eric, thank you. I dissagree that this could be too low level for C# programming. If you only use it as a standalone statement to increment a value of a variable, fine and good. But as soon as you put this statement into an inline bit of code (like passing it in as a parameter in a method call, you are going to get bitten, unless you realise what you are REALLY doing. Again Eric, thanks a lot!Deus
+1 but I have to tell the truth... It's years and years that the only use of postfix operators I do that is not alone in the row (so that isn't i++;) is in for (int i = 0; i < x; i++)... And I'm very very happy of this! (and I don't ever ever use the prefix operator). If I have to write something that will require a senior programmer 2 minutes to decipher... Well... It's better to write one more line of code or introduce a temporary variable :-) I think that your "article" (I won't call it "answer") vindicates my choice :-)Predella
@Bradley, you're right. It was a typo. However, when I went to correct it, I realized it's actually true for both cases as explained above. See my edits to Eric's original answer (which I made to make it more clear, at least to me and others like me.)Cantata
Is x += 1 equivalent to ++x (in terms of the compiler)?Adamina
@KellenStuart: In general, no. If x is a user-defined type, for instance, then for x += 1 the compiler generates a call to operator+, but for x++ the compiler generates a call to operator++. If you mean for x a variable of type int, does the language require that x+=1 and ++x have the same semantics, yes, it does. If that's not what you meant then please clarify the question or consider asking your question as a question rather than a comment.Drida
How to describe something simple in a complex way.Annelid
C
251

Oddly it looks like the other two answers don't spell it out, and it's definitely worth saying:


i++ means 'tell me the value of i, then increment'

++i means 'increment i, then tell me the value'


They are Pre-increment, post-increment operators. In both cases the variable is incremented, but if you were to take the value of both expressions in exactly the same cases, the result will differ.

Cutoff answered 27/7, 2010 at 18:22 Comment(28)
This seems to be at odds with what Eric is sayingCryostat
Neither statement is correct. Consider your first statement. i++ actually means "save the value, increment it, store it in i, then tell me the original saved value". That is, the telling happens after the incrementing, not before as you have stated it. Consider the second statement. i++ actually means "save the value, increment it, store it in i, and tell me the incremented value". The way you said it makes it unclear whether the value is the value of i, or the value that was assigned to i; they could be different.Drida
@Eric, it would seem to me with even your answer, the second statement is categorically correct. Though he excludes a few steps.Cryostat
Eric, thanks for the comment, but I can't see any case in which there would be a noticeable difference in a real C# code example (even under scrutiny) between what I am saying and the physical underlying process?Cutoff
Sure, most of the time the sloppy, incorrect ways of describing the operational semantics give the same results as the precise and correct description. First, I don't see any compelling value in getting the right answers through incorrect reasoning, and second, yes, I have seen production code that gets exactly this sort of thing wrong. I get probably half a dozen questions a year from real programmers about why some particular expression chock-full of increments and decrements and array dereferences doesn't work the way they assumed it did.Drida
By that I mean I'm concentrating on your point 'the telling happens after the incrementing': this is a single expression that is being evaluated, and I'm saying it will either evaluate to the value before the increment or after. No use of the result would occur until after the evaluation of the expression anyway (at least, this is what I think and possibly why I am confused), so whether it's 'told' before or after makes no difference?Cutoff
I'm pretty sure that the C standard explicitly allows the increment to occur at any time between the previous sequence point and the next sequence point. Thus, in the statement "*a = (*b)++", if 'a' and 'b' happen to point to the same variable, the assignment could happen before the increment (in which case the variable will be incremented) or after (in which case the variable would be incremented and then reassigned its old value). Actually, if the compiler's generated code wanted to start printing "99 bottles of beer", I think that would be allowable under the standard too.Marthamarthe
@supercat: The discussion is about C#, not C.Neutrino
@Eric, would appreciate a response if possible, so I can update my answer accordingly if necessary.Cutoff
@Kieren, look at eric's refernced post that caused confusion using this def. #1260727Cryostat
Hi Evan, thanks, I agree with that, I can't see how it's any different to what I'm saying. I don't say that the increment happens after everything else on the line; I simply say the result is either the value before or after the increment. I stand by my statements; 'tell me the value then add 1' doesn't mean 'tell me the value, then evaluate the whole statement, then add 1'. Would welcome some specific feedback though.Cutoff
@Brian - did you read my comments? The lack of response? You truly believe something is misleading - care to share exactly what it is without copy&pasting Eric? Or just another Eric enthusiast who doesn't want to think about it themselves? The guy didn't even reply to me.Cutoff
@Kieren: The misleading part is that you state "i++ means 'tell me the value of i, then increment'" when it really means, 'increment i, then tell me the old value of i'. There are cases where this order matters.Fancy
@Fancy - there are no cases where that applies - where what I say isn't true. As I said, I don't say "tell me the value of i, then evaluate the rest of the statement, then increment": we are saying the same thing, but mine answer is just more succinct!Cutoff
@Fancy - that's what I thought. :)Cutoff
@Kieren: Eric's example (int[] arr = {0}; int value = arr[arr[0]++];) is the simplest one I can think of where this order causes an issue. I can't offer a better one.Fancy
@Fancy - To quote myself, 'i++ means 'tell me the value of i, then increment'. In this example, arr[0]++ says tell me the value of arr[0], then increment. I don't say when it will happen, or allude that it happens before or after anything else is evaluated. Also, Eric's first linked blog post explains the fine details of when evaluations and side-effects occur: but simply put, I don't say anything different!Cutoff
@Kieren: I think your explanation is contradicted by the order of the side effects. Apparently, you do not. :::shrug:::Fancy
Nice to see people still blindly voting me down after giving a clear, concise and correct answer. Bandwagon's getting a bit full though..Cutoff
I put a vote down and I am not blind. Your answer is incorrect. i++ and ++i translate to same events in same order EXCEPT what is returned at the end of the expression evaluation. Your answer seems to suggest otherwise. Please re-read Eric's answer if you are still unclear.Barratry
Downvote. Kieren, you said "I don't say when it will happen, or allude that it happens before or after anything else is evaluated." That is incorrect. "tell me the value of i, then increment" clearly expresses a temporal relationship. Please refer to the definition of "then". You are using the word in its second sense (as listed at that link as of right now); that sense is defined as "After that; next; afterward." Your statement means "tell me the value of i, and after that, increment" and that statement is false.Violation
@Matthew - I clearly say 'tell me the value of i, then increment' - which is correct. My addendum of 'I don't say when' is with regards to anything else the user might care to craft into that statement / line. So, once again, "i++" means "tell me the value of i, then increment". The extra part was to say I don't cover things like "(++i)[j++] = i++ + ++j". I'm saying the difference between i++ and ++i.Cutoff
@Kieren The statement is incorrect. The increment comes before the value of i is returned. "increment, then tell me the previous value of i" would be correct. You don't need to add the extra details in order to make a correct statement.Violation
@KierenJohnstone I edited your answer so that it says the same thing as Eric Lippert (I think). Could you please review?Keelung
@MilanGardian I rolled back your edit. Right or wrong, your edit changed the answer, and that should probably be the OP's decision to make.Armipotent
Regardless of what abyone else says, this is exactly correct. As far as the generated code is concerned, even Eric is wrong. And he and everybody else is pretending that Kierin stated that the increment happens after the rest of the expression. He did not say anything of he sort.Outlook
@KierenJohnstone It's easy to be blasé about the exact sequence of events when 95% of the time it doesn't matter. But being wrong 5% of the time makes your answer wrong. I can't tell you how many convoluted messes I've seen because someone didn't understand the sequence of events when an exception is thrown. The exact point it's triggered, the subsequent flow, and the resulting state. As an example (next comment), your statement implies that a == int.MaxValue in the catch block.Danyelldanyelle
@KierenJohnstone The following code sample shows how claiming that a is "told the value of i" before i is incremented creates the wrong impression about the effect on a: int i = int.MaxValue; int a = 0; try { checked { a = i++; } } catch { Console.WriteLine(a); } The output is 0 because a isn't told anything until after i is incremented. Incrementing i throws an exception and a remains unchanged.Danyelldanyelle
M
31

If you have:

int i = 10;
int x = ++i;

then x will be 11.

But if you have:

int i = 10;
int x = i++;

then x will be 10.

Note as Eric points out, the increment occurs at the same time in both cases, but it's what value is given as the result that differs (thanks Eric!).

Generally, I like to use ++i unless there's a good reason not to. For example, when writing a loop, I like to use:

for (int i = 0; i < 10; ++i) {
}

Or, if I just need to increment a variable, I like to use:

++x;

Normally, one way or the other doesn't have much significance and comes down to coding style, but if you are using the operators inside other assignments (like in my original examples), it's important to be aware of potential side effects.

Mizzen answered 27/7, 2010 at 18:3 Comment(10)
You could probably clarify your examples by putting the code lines in order - that is, say "var x = 10; var y = ++x;" and "var x = 10; var y = x++;" instead.Ube
This answer is dangerously wrong. When the increment happens does not change with respect to the remaining operations so saying that in one case it is done before remaining operations and in the other case it is done after remaining operations is deeply misleading. The increment is done at the same time in both cases. The thing that is different is what value is given as the result, not when the increment is done.Drida
I have edited this to use i for the variable name rather than var as it is a C# keyword.Intercede
@Eric - Thanks for the correction Eric, I adjusted the answer. Jeff, I think we must have edited at the same time because I don't see the change, but I will modify it, thanks for pointing it out.Mizzen
I'd also argue ++x; and ++i goes against any convention I've seen, but then again, I haven't seen that many...Sadiron
So without assigning variables and just stating "i++;" or "++i;" will give exactly the same results or am I getting it wrong?Tineid
@Tineid - you are correct. It is the same on its own, and the same in the for loop.Sadiron
@Sadiron - I actually didn't start using the ++i syntax until I started doing programming competitions and studying others' code. I noticed many very good coders used it, and I got in the habit of it and now I use it all the time!Mizzen
@Eric: Could you clarify why the original wording is "dangerous"? It does lead to correct usage, even if it the details are wrong.Roadwork
@Justin: Eric's explanation of why the alternative wording is dangerous is mentioned in a comment on Kieren's answer. The short answer is that the original wording is dangerous because coding based on false assumptions means your programs are not doing what you think they are doing. This can easily lead to bugs.Fancy
H
12
int i = 0;
Console.WriteLine(i++); // Prints 0. Then value of "i" becomes 1.
Console.WriteLine(--i); // Value of "i" becomes 0. Then prints 0.

Does this answer your question ?

Hagride answered 27/7, 2010 at 18:5 Comment(1)
One could imagine that the postfix increment and the prefix decrement don't have any effect on the variable :PStruck
O
8

The way the operator works is that it gets incremented at the same time, but if it is before a variable, the expression will evaluate with the incremented/decremented variable:

int x = 0;   //x is 0
int y = ++x; //x is 1 and y is 1

If it is after the variable the current statement will get executed with the original variable, as if it had not yet been incremented/decremented:

int x = 0;   //x is 0
int y = x++; //'y = x' is evaluated with x=0, but x is still incremented. So, x is 1, but y is 0

I agree with dcp in using pre-increment/decrement (++x) unless necessary. Really the only time I use the post-increment/decrement is in while loops or loops of that sort. These loops are the same:

while (x < 5)  //evaluates conditional statement
{
    //some code
    ++x;       //increments x
}

or

while (x++ < 5) //evaluates conditional statement with x value before increment, and x is incremented
{
    //some code
}

You can also do this while indexing arrays and such:

int i = 0;
int[] MyArray = new int[2];
MyArray[i++] = 1234; //sets array at index 0 to '1234' and i is incremented
MyArray[i] = 5678;   //sets array at index 1 to '5678'
int temp = MyArray[--i]; //temp is 1234 (becasue of pre-decrement);

Etc, etc...

Othaothe answered 27/7, 2010 at 18:25 Comment(0)
B
5

Just for the record, in C++, if you can use either (i.e.) you don't care about the ordering of operations (you just want to increment or decrement and use it later) the prefix operator is more efficient since it doesn't have to create a temporary copy of the object. Unfortunately, most people use posfix (var++) instead of prefix (++var), just because that is what we learned initially. (I was asked about this in an interview). Not sure if this is true in C#, but I assume it would be.

Birr answered 27/7, 2010 at 22:43 Comment(1)
That's why I use ++i in c# to when used alone (ie. not in a bigger expression). Whenever I see a c# loop with i++, I weep a little, but now that I know that in c# this is actually pretty much the same code I feel better. Personally I'll still use ++i because habits die hard.Wheelhouse
B
0

I think I'll try answering the question using code. Imagine the following methods for, say, int:

// The following are equivalent:
//     ++i;
//     PlusPlusInt(ref i);
//
// The argument "value" is passed as a reference,
// meaning we're not incrementing a copy.
static int PlusPlusInt(ref int value)
{
    // Increment the value.
    value = value + 1;

    // Return the incremented value.
    return value;
}

// The following are equivalent:
//     i++;
//     IntPlusPlus(ref i);
//
// The argument "value" is passed as a reference,
// meaning we're not incrementing a copy.
static int IntPlusPlus(ref int value)
{
    // Keep the original value around before incrementing it.
    int temp = value;

    // Increment the value.
    value = value + 1;

    // Return what the value WAS.
    return temp;
}

Assuming you know how ref works, this should clear this up really nicely. Explaining it in english is a lot more clunky in my opinion.

Birgitbirgitta answered 30/10, 2022 at 21:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.