• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

increment expression in for loop

 
Greenhorn
Posts: 15
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Seems to be simple, but I did not get it.  Aprreciate any help.



3: for(int i=4; i<10 ; ) {
4:   i = i++;
5:   System.out.println( i);
6: }

Scenario 1:  If line 4 is i = i++; runs into infinite loop
Scenario 2:  If line 4 is replaced by i++;  output displayed from 5 to 9 ... as expected

Issue:  In Scenario 1: first iteration starts with i =4 in line 3,
                                In line 4, i is assigned 4 ---- because of the postunary ++ operator, my expectation was i to be incremented to 5 after assigning to itself.  
                                step 5 - remains at 4 and  runs into an infinite loop.  Increment operation never takes place.

Can any of you pl. help me in interpreting the results?

Thanks
 
Greenhorn
Posts: 19
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
this problem has been answered many times buddy.
you use i = i++; its means:
"first assigi(right) to i(left) then plus"
you should use ++i instead and you will be fine
 
Saloon Keeper
Posts: 27752
196
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
If one MUST do that sort of stuff, the cleaner way would be


Or, remap working values such that you can use post-incrementing, like everyone is accustomed to reading.



As Greg pointed out, the expression

is self-anhilating. You increment i, but the expression itself returns the pre-increment value of i, so the net effect is actually "i = i", and a good optimizing compiler would discard the incrementing operation as useless code. And, with luck, return a warning message.
 
lowercase baba
Posts: 13089
67
Chrome Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
we have a wiki page on this:

https://coderanch.com/wiki/659942/Post-Increment-Operator-Assignment
 
Bartender
Posts: 1205
22
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
[EDIT: I started this response more than 20 minutes ago - back before Tim responded.  Even though it rehashes some material, I think it still adds something to the conversation.]

Greg Sully wrote:this problem has been answered many times buddy.
you use i = i++; its means:
"first assigi(right) to i(left) then plus"
you should use ++i instead and you will be fine



To add a little verbose detail...

There are two unary (single operand) increment operators: ++i and i++.  As with any expression, these each have a value and a possible effect.  In both cases, the effect is to increment i by one.  However, they differ in their value.  ++i has a value equal to the new, incremented value of i.  i++ has a value equal to the old, not-yet-incremented value of i.  

So let's look at awhat happens when...

...is executed when i is initially 4.

1. The i++ expression is evaluated.  This has the effect of incrementing i to 5, but the value of expression is the old value: 4.
2. The value of the right-hand expression, 4, is assigned to i.

So i has the same value before and after the statement is executed, which is what leads to the endless loop.

You have (at least) five "correct" choices (from worst to best):
1. Merely change the i++ to ++i in the assignment statement.  When that gets executed, i is incremented to 5 and the expression value of 5 is then assigned to i.  This solution is correct but redundant.
2. Don't use an increment operator on the right-hand side of your assignment and instead use a plain mathematical expression that has no side-effects: i = i + 1;  
3. Get rid of the explicit assignment and just use i++ alone on a line.
4. Get rid of the explicit assignment and just use ++i alone on a line.  The performance difference between this and the previous choice was small back in the 1980s and is, if I understand correctly, non-existent today.  Currently, the only advantage this has is that when you see the ++ before the i, it's easier to read it as "increment i".
5. Put either i++ or ++i as the "increment" expression in the parens for the for statement();

That's where everyone will be looking for it, so that's where it should go.  This will help improve code maintainability quite a bit.


 
Preethi Chilukuri
Greenhorn
Posts: 15
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks much for your replies and time.
 
Marshal
Posts: 8856
637
Mac OS X VI Editor BSD Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Or consider using Java 8 facilities along with the streams.

i.e.:
Produces output:
4


I think that is a clearest approach today and least error prone.
 
Marshal
Posts: 79153
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Why do you want to throw an Exception? Since the documentation for rangeClosed() says you can get the same effect with a loop (and similarly for range), surely if you pass 3 to that method, it will terminate with no output?

People are scared of Streams because they think Streams are difficult to use and error‑prone. But that isn't true. So it is possible to write complicated code using Streams, but the simpler uses of Streams are easier to read and write than loops, and harder to get wrong.

java SequentialPrinterDemo 1 2 69 4 -1 -2 -69 -4

You will get better results with 7 instead of 69.
 
Ryan McGuire
Bartender
Posts: 1205
22
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:People are scared of Streams because they think Streams are difficult to use and error‑prone. But that isn't true. So it is possible to write complicated code using Streams, but the simpler uses of Streams are easier to read and write than loops, and harder to get wrong.You will get better results with 7 instead of 69.



Sure, nothing is difficult to use when you know how to use it.    If you're in a Beginning Java class and the instructor hasn't gone over streams but HAS gone over for and while loops, then I would bet streams are indeed more difficult to use and error-prone.
 
Liutauras Vilda
Marshal
Posts: 8856
637
Mac OS X VI Editor BSD Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:Why do you want to throw an Exception? Since the documentation for rangeClosed() says you can get the same effect with a loop (and similarly for range), surely if you pass 3 to that method, it will terminate with no output?


Yes, it would print nothing, that is exactly why I throw an exception, because my method says printValuesFromFourTo(int i), meaning it can't go just to vegetable bush, it says it prints something. But since it was only to show an idea with streams, I don't argue I was right.
 
Campbell Ritchie
Marshal
Posts: 79153
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I tried running the sequential code again:-

java SequentialPrinterDemo 3 6 9 -3 -999
Printing from 4 to 3
Using loop:-

Using IntStream#range:-
[]
Using IntStream#rangeClosed:-
[]
Printing from 4 to 6
Using loop:-
4 5
Using IntStream#range:-
[4, 5]
Using IntStream#rangeClosed:-
[4, 5, 6]
Printing from 4 to 9
Using loop:-
4 5 6 7 8
Using IntStream#range:-
[4, 5, 6, 7, 8]
Using IntStream#rangeClosed:-
[4, 5, 6, 7, 8, 9]
Printing from 4 to -3
Using loop:-

Using IntStream#range:-
[]
Using IntStream#rangeClosed:-
[]
Printing from 4 to -999
Using loop:-

Using IntStream#range:-
[]
Using IntStream#rangeClosed:-
[]

If you don't have any elements in the Stream, you get [] as your output; that would allow you to test whether you have a 0‑element Stream.
 
Liutauras Vilda
Marshal
Posts: 8856
637
Mac OS X VI Editor BSD Java
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Ryan McGuire wrote:I would bet streams are indeed more difficult to use and error-prone.


Well, I'm not sure if they are error prone or at least more error prone than programing imperative way. If you get compilable code, it would do exactly what is documented to do. When you dealing with lower level code which you achieve by programming imperative way, this is where errors mainly happen as you are telling program how to do things, and that understanding HOW quite often gets flawed. On the other hand, programming declarative way, you are telling WHAT to do. i.e.:

Imperative way 1 [bad], Imperative way 2 [better]

Declarative way

So you just asking, if names contain "Ryan" and nothing else, you get an answer. You don't need to deal with low level code where you can easily mistype index or similar. Streams are all about declarative programming, which is similar to third example.

Actual streams, as you see it is more verbose than above example, but way better than very top 2 examples. Usually you don't get that luxury in various situation as you have with contains, so streams are very useful.

As you see, once ou got code to compile, you don't have lots of areas where you could slid. And you could read it out loud, which reads as regular English: "is there any match where name would be equal "Ryan".
 
Liutauras Vilda
Marshal
Posts: 8856
637
Mac OS X VI Editor BSD Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
So I agree with Campbell, that streams the sooner get introduced, the better. This is where apparently all programming world shifting now - towards functional programming. And I'm really happy that Java heading towards there too. You don't need to wait 2nd or 3rd year course and introduce them as an advanced topic, not at all. Just need to show them right away, so students would get used to it. Of course along with OO techniques, which all fit very well with functional paradigm.
 
Campbell Ritchie
Marshal
Posts: 79153
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Ryan McGuire wrote:. . . If . . . the instructor hasn't gone over streams . . . I would bet streams are indeed more difficult to use and error-prone.

Which is why we see so many questions about why loops don't work correctly. In order to get a for loop to work, you have to be able to think low‑level about the indices. If you get a Stream wrong, it will be about the types and you will get a compile‑time error, whereas a loop gone wrong will cause an Exception be thrown, if you are lucky. If you are unlucky, it will silently return a wrong result, which is much more dangerous. Which is easier to understand, the imperative form or the functional form? The first is how I had to learn to fill an array with successive ints. The second is what I now think is the correct way to do it.Shorter and easier to read. Once you know what the range() method does, and I think the documentation is helpful here, it will be easier to predict the range of numbers in the array. Also, you don't have the array full of default values (as in line 2 of the first code block). It isn't too bad with 0s, but would be worse for arrays of a reference type, where the elements default to null.

Now tell me whether the contents of numbers will be the same or different if you run those two code blocks.
 
Ryan McGuire
Bartender
Posts: 1205
22
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Liutauras Vilda wrote:

Ryan McGuire wrote:I would bet streams are indeed more difficult to use and error-prone.


Well, I'm not sure if they are error prone or at least more error prone than programing imperative way. ...



I'm calling shenanigans for leaving off the first part of the sentence from my post and thus changing the meaning.  I did not make the unqualified statement that streams are more difficult and error prone.  I said IF (some condition) THEN streams are more difficult and error-prone.
 
Liutauras Vilda
Marshal
Posts: 8856
637
Mac OS X VI Editor BSD Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ryan, I didn't try to make you look... Alright, I might would agree about the part "more difficult", but not about the "error-prone" in either case
 
Ryan McGuire
Bartender
Posts: 1205
22
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Liutauras Vilda wrote:Ryan, I didn't try to make you look... Alright, I might would agree about the part "more difficult", but not about the "error-prone" in either case



That's fine - I didn't really take any offense.  My previous post should have had a
 
reply
    Bookmark Topic Watch Topic
  • New Topic