views:

134

answers:

6

I have a for loop of the form:

for (int i = from; i < to; i++) {
  // do some code (I don't know exactly what, it is subject to change)
}

And I want to convert it to a while loop (mostly because I want to play with the value of i inside the loop to go backwards and forwards and my co-worker thinks that doing this in a for loop is prone to problems. I tend to agree with him). So I wrote something like this:

int i = from;
while (i < to) {
  try {
    // do some code (I don't know exactly what, it is subject to change)
  } finally {
    i++;
  }
}

Which prompted some some loud comments. My reasoning is that you don't know what the code inside the loop does - it may (and does) have multiple continue commands.

As a response he wrote this:

int i = from - 1;
while (++i < to) {
  // do some code (I don't know exactly what, it is subject to change)
}

Granted its less lines, but I still think my code is more elegant - what do you think?

+3  A: 

And I want to convert it to a while loop (mostly because I want to play with the value of i inside the loop to go backwards and forwards and my co-worker thinks that doing this in a for loop is prone to problems. I tend to agree with him).

This is perfectly acceptable in most languages. There is no reason to avoid a for loop.

Reed Copsey
@Reed, and @Joseph - you are both correct, but as the code gets updated and becomes more complex, using a while loop reduces apparent complexity and allows better understanding of the execution flow - there by mitigating future bugs. Obviously its not that important unless you play with the indexer.
Guss
For me, it completely depends. If you're working in a manner where a for loop would be more common, it's less confusing to me to keep it as a for loop, and "tweak" the indexer internally. If you, logically, aren't iterating through something, then make it a while loop with a conditional flag, since you shouldn't be using the indexer as a condition in that case anyways.
Reed Copsey
@Reed I second that. If you're logically doing a for loop structure, it's going to be easier to read it that way.
Joseph
@Reed - seconded (again)
Brian Agnew
+5  A: 

Playing with the value of your index while in a looping structure is prone to problems, no matter what the looping structure is.

It's not going to matter if it's a for loop or a while loop, the point is will the indexer eventually lead you to make a decision of loop termination?

If you're confident that you're indexer will eventually cause your exit condition to be achieved, then that is all you should be concerned with, not whether to use a for or a while.

Joseph
While I agree that in common you shouldn't do this, many dynamic algorithms require that your index change dramatically to promote efficiency.
icco
@icco No argument here. I was just stating that you should always be careful when you start changing the index.
Joseph
I agree with Joseph. Bad idea.
ChadNC
A: 

The easiest way to do this would be to not convert into a while loop, such as below.

for (int i = from; i < to; ) {
  // do some code (I don't know exactly what, it is subject to change)
  i += rand()*10;
}
icco
The main problem of this simple case is that if the loop code does a `continue` (which it does), then the indexer does not get incremented.
Guss
That wouldn't change the above example. Notice you still need to increment. At least in Java and C, I can guarantee the above does exactly what you want.
icco
+2  A: 

It seems to me that it may be easier and more readable to convert it to:

while (condition == true) {
   // do stuff
   // set the condition flag appropriately
}

and thus separate the termination of the loop from the variable incrementation.

If I see a loop with a limit check (e.g. i < limit) I would tend to assume that there's a variable that is being modified in a (reasonably) consistent fashion. There's no reason why you can't do what you want, but I would lean towards the more readable and more expected behaviour.

Brian Agnew
The question was mostly about the location for incrementing the indexer (in a safe way) - a question you avoided completely :-). -1 because you didn't take any side nor offered another solution, sorry.
Guss
I suggested removing it from the loop condition check. Beyond that it should be fairly obvious that it resides in the loop
Brian Agnew
or even: while (condition) { // do stuff }
Seth
@Brian - but where?
Guss
I like this. By taking the incrementation out of the looping construct, it becomes clear that something more than simple linear iteration is going on.
Annabelle
@Guss - I don't care! That's dependent on the complexity of the logic surrounding the limit checking. That may be encapsulatable in one statement, or many.
Brian Agnew
@Seth - point taken. I'm trying to be explicit in a language-agnostic fashion, but perhaps I'm being too verbose
Brian Agnew
A: 

To answer the question about which code I would select; I choose your longer code. Its MUCH easier to read the first(longer) loop. And yes I can read the second but even if you have lots of experience you have to look twice to know what that loop does. Plus the compiler will optimize the code well enough.

Johan
+1  A: 

Why bother with silly loops when you can do the same (and much more!) with the uber-powerful goto?

i = fro;
my_loop:
//all your stuff here
i++;
if (i < to) goto my_loop;

If you are one of those faint hearted programmers that diminish the goto, then you can try with this:

i = fro;
while(1) {
    //your stuff here
    if (++i < to) break;
}
fortran
:-p . Again the expected use of `continue` (or additional `goto`s in your case) is expected to break your code.
Guss
yeah, I didn't expect you to take it seriously, the answer was humoristic ^_^
fortran