什么是最好的方式做一个无符号索引的“循环”?

我第一次尝试反向循环 ,做了n次的事情是这样的:

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

这个失败,因为在无符号算术 i保证总是大于或等于零,因此循环条件将永远是真实的。 幸运的是,在我不得不想知道为什么循环无限执行之前,gcc编译器提醒我“无意义的比较”。


我正在寻找一个解决此问题的优雅方法,牢记:

  1. 它应该是一个倒退的循环。
  2. 循环索引应该是无符号的。
  3. n是无符号常量。
  4. 它不应该基于无符号整数的“模糊”环形algorithm。

有任何想法吗? 谢谢 :)

怎么样:

 for (unsigned i = n ; i-- > 0 ; ) { // do stuff with i } 
 for ( unsigned int loopIndex = n; loopIndex > 0; --loopIndex ) { unsigned int i = loopIndex - 1; ... } 

要么

 for ( unsigned int loopIndex = 0; loopIndex < n; ++loopIndex ) { unsigned int i = n - loopIndex - 1; ... } 
 for ( unsigned int i = n; i != 0; i-- ) { // do something with i - 1 ... } 

请注意,如果您使用C ++以及C,那么在切换到使用迭代器时,使用!=是一个好习惯,其中<=等可能不可用。

 for ( unsigned int i = n; i > 0; i-- ) { ... i-1 //wherever you've been using i } 

我倾向于使用

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

它几乎和skizz的答案一样,(它错过了最后一个不必要的递减,但是编译器应该优化它),而且实际上会通过代码审查。 我必须使用的每个编码标准在条件规则中都没有变化。

为什么不简单:

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

这符合问题主体列举的所有要求。 它不会使用任何可能的代码审查失败或违反编码标准。 我可以看到的唯一的反对意见是,如果OP真的坚持一个for循环,而不是一个简单的方法来产生i =(n-1).. 0。

也许这样? 恕我直言,其清晰可读。 如果以某种方式隐含知道,则可以忽略if(n> = 1)。

 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 ); } 

另一个版本:

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

没有if语句的第一个代码看起来像:

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

或者,如果您需要从n-1到0的索引,则可以依赖unsigned int的包装行为

 for(unsigned int i = n-1; i < n; i--) { ... } 
 for ( unsigned int i = n; i > 0; i-- ) { unsigned int x = i - 1; // do whatever you want with x } 

当然不是优雅的,但它的作品。

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

好吧,它的“晦涩的响铃算术”。

我提到这个选项的唯一原因是因为我没有在列表中看到它。

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

完全反对直觉,但它的作品。 它工作的原因是因为从0减1产生可以由一个无符号整数表示的最大数字。

一般来说,我不认为这是一个好主意,使用无符号整数和关节,特别是当减去。

简单,只需停在-1:

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

编辑:不知道为什么这是downvoted。 它工作,比上述任何一个都更简单,更明显。

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

应该工作正常。 如果你需要使用ivariables作为数组的索引,可以这样做:

 array[i-1]; 

嗯。 这里是你的select:

  1. 使用i=0作为你的中断条件 – 当我到达0时,循环将不会执行,所以在循环退出后执行循环内容的迭代1次。
 for ( unsigned int i = n-1; i > 0; i-- ) { doStuff(i); } doStuff(0); 
  1. 在循环中,testingi=0break 。 不推荐,因为现在你正在循环中testing两次我的值。 在循环中使用中断通常也是不好的做法。
 for ( unsigned int i = n-1; i >= 0; i-- ) { doStuff(i); if (i=0) break; } 
 unsigned index; for (unsigned i=0; i<n; i++) { index = n-1 - i; // {i == 0..n-1} => {index == n-1..0} } 

这是未经testing的,但你可以做以下几点:

 for (unsigned int i, j = 0; j < n; i = (n - ++j)) { /* do stuff with i */ } 

使用两个variables,一个用于计数,另一个用于数组索引:

 unsigned int Index = MAX - 1; unsigned int Counter; for(Counter = 0; Counter < MAX; Counter++) { // Use Index Index--; } 

由于这不是循环的标准,我可能会使用while循环,例如:

 unsigned int i = n - 1; while (1) { /* do stuff with i */ if (i == 0) { break; } i--; } 
 for ( unsigned int i = n-1; (ni) >= 0; i-- ) { // ni will be negative when the loop should stop. ... } 

EZ:

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