什么是最好的方式做一个无符号索引的“循环”?
我第一次尝试反向循环 ,做了n次的事情是这样的:
for ( unsigned int i = n-1; i >= 0; i-- ) { ... }
这个失败,因为在无符号算术 i
保证总是大于或等于零,因此循环条件将永远是真实的。 幸运的是,在我不得不想知道为什么循环无限执行之前,gcc编译器提醒我“无意义的比较”。
我正在寻找一个解决此问题的优雅方法,牢记:
- 它应该是一个倒退的循环。
- 循环索引应该是无符号的。
- n是无符号常量。
- 它不应该基于无符号整数的“模糊”环形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-- ) { ... }
应该工作正常。 如果你需要使用i
variables作为数组的索引,可以这样做:
array[i-1];
嗯。 这里是你的select:
- 使用
i=0
作为你的中断条件 – 当我到达0时,循环将不会执行,所以在循环退出后执行循环内容的迭代1次。
for ( unsigned int i = n-1; i > 0; i-- ) { doStuff(i); } doStuff(0);
- 在循环中,testing
i=0
并break
。 不推荐,因为现在你正在循环中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-- ) { ... }