What is the best way to do the reverse "for" loop with an unsigned index?

My first reverse attempt for a loop that does something n times was something like:

for ( unsigned int i = n-1; i >= 0; i-- ) { ... } 

This fails because in unsigned arithmetic i always guaranteed to be greater than or equal to zero, so the loop condition will always be true. Fortunately, the gcc compiler warned me of a "pointless comparison" before I had to wonder why the loop was running endlessly.




I am looking for an elegant way to solve this problem, bearing in mind that:

  • It should be a reverse cycle.
  • The loop index must be unsigned.
  • n is a constant constant.
  • It should not be based on the "obscure" ring arithmetic of unsigned integers.

Any ideas? Thank:)

+45
c for-loop
Mar 20 '09 at 11:26
source share
20 answers

What about:

 for (unsigned i = n ; i-- > 0 ; ) { // do stuff with i } 
+80
Mar 20 '09 at 11:35
source share
 for ( unsigned int loopIndex = n; loopIndex > 0; --loopIndex ) { unsigned int i = loopIndex - 1; ... } 

or

 for ( unsigned int loopIndex = 0; loopIndex < n; ++loopIndex ) { unsigned int i = n - loopIndex - 1; ... } 
+11
Mar 20 '09 at 11:30
source share
 for ( unsigned int i = n; i != 0; i-- ) { // do something with i - 1 ... } 

Note that if you use C ++ as well as C, using! = Is a good habit when you switch to using iterators, where <=, etc. may not be available.

+10
Mar 20 '09 at 11:29
source share
 for ( unsigned int i = n; i > 0; i-- ) { ... i-1 //wherever you've been using i } 
+8
Mar 20 '09 at 11:30
source share

I would use

  for ( unsigned int i = n; i > 0; ) { --i; ... } 

it's almost the same as skizz 'answer (it skips the final unnecessary decrement, but the compiler needs to optimize it), and in fact the code review will go through. Each coding standard that I had to work with did not have a mutation in the conditional rule.

+8
Mar 20 '09 at 11:44
source share

Why not just:

 unsigned int i = n; while(i--) { // use i } 

This meets all the requirements listed in the body of the question. It does not use anything that could lead to a failure of code verification or a violation of the encoding standard. The only objection I could see was that the OP really insisted on a for loop, and not on a simple way to generate i = (n-1) .. 0.

+8
May 11 '11 at 7:30
source share

Maybe so? IMHO it is clear and understandable. You can omit if (n> = 1) if it is implicitly known somehow.

 if(n>=1) { // Start the loop at last index unsigned int i = n-1; do { // a plus: you can use i, not i-1 here } while( i-- != 0 ); } 

Another version:

 if(n>=1) { unsigned int i = n; do { i--; } while( i != 0 ); } 

The first code without an if statement will look like this:

 unsigned int i = n-1; do { } while( i-- != 0 ); 
+5
Mar 20 '09 at 11:52
source share

Or you can rely on unsigned int shell behavior if you need to index from n-1 to 0

 for(unsigned int i = n-1; i < n; i--) { ... } 
+4
Mar 20 '09 at 13:05
source share
 for ( unsigned int i = n; i > 0; i-- ) { unsigned int x = i - 1; // do whatever you want with x } 

Of course, not elegant, but it works.

+3
Mar 20 '09 at 11:32
source share
 for (unsigned int i = n-1; i<(unsigned int)-1; i--) 

OK, its "fuzzy ring arithmetic."

+3
Mar 20 '09 at 12:34
source share

The only reason I mention this option is because I did not see it on the list.

 for ( unsigned int i = n-1; i < n; i-- ) { ... } 

Totally against intuition, but it works. the reason it works is because subtracting 1 from 0 gives the largest number that can be represented by an unsigned integer.

In general, I do not think that it is a good idea to work with integers without recharging, as well as when subtracting.

+3
Mar 20 '09 at 13:08
source share

Just, just stop at -1:

 for( unsigned int i = n; i != -1; --i ) { /* do stuff with i */ } 

edit: don't know why this is happening. it works, and it is simpler and more obvious than any of the above.

+2
Sep 06 '09 at 21:56
source share
 for ( unsigned int i = n; i > 0; i-- ) { ... } 

It should work fine. If you need to use the i variable as an index in an array, do the following:

 array[i-1]; 
+1
Mar 20 '09 at 11:31
source share

Hm. Here are your options:

  • Use i=0 as an interrupt condition. The loop will not execute when I reach 0, so do the 1st iteration of the contents of the loop for i=0 after the loop exits.
 for ( unsigned int i = n-1; i > 0; i-- ) { doStuff(i); } doStuff(0); 
  1. In a loop, check i=0 and break . Not recommended, because now you check the value i twice in a loop. Also, using a break in a loop is usually considered bad practice.
 for ( unsigned int i = n-1; i >= 0; i-- ) { doStuff(i); if (i=0) break; } 
+1
Mar 20 '09 at 11:39
source share
 unsigned index; for (unsigned i=0; i<n; i++) { index = n-1 - i; // {i == 0..n-1} => {index == n-1..0} } 
+1
Mar 20 '09 at 14:20
source share

Since this is not a standard for a loop, I would most likely use a while loop, for example:

 unsigned int i = n - 1; while (1) { /* do stuff with i */ if (i == 0) { break; } i--; } 
0
Mar 20 '09 at 12:25
source share

This is not verified, but you can do the following:

 for (unsigned int i, j = 0; j < n; i = (n - ++j)) { /* do stuff with i */ } 
0
Mar 20 '09 at 12:32
source share

Use two variables: one for counting and one for array index:

 unsigned int Index = MAX - 1; unsigned int Counter; for(Counter = 0; Counter < MAX; Counter++) { // Use Index Index--; } 
0
Mar 21 '09 at 17:15
source share
 for ( unsigned int i = n-1; (ni) >= 0; i-- ) { // ni will be negative when the loop should stop. ... } 
-one
Mar 20 '09 at 11:32
source share

ez:

 #define unsigned signed for ( unsigned int i = n-1; i >= 0; i-- ) { ... } 
-one
Sep 06 '09 at 10:20
source share



All Articles