使用无符号索引进行反向'for'循环的最佳方法是什么?

Aur*_*ron 56 c for-loop

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

for ( unsigned int i = n-1; i >= 0; i-- ) {
    ...     
}
Run Code Online (Sandbox Code Playgroud)

这是失败的,因为无符号算术 i保证总是大于或等于零,因此循环条件将始终为真.幸运的是,在我不得不想知道为什么循环无限执行之前,gcc编译器警告我"无意义的比较".


我正在寻找一种解决这个问题的优雅方法,请记住:

  1. 它应该是一个倒退的循环.
  2. 循环索引应该是无符号的.
  3. n是无符号常数.
  4. 它不应该基于无符号整数的"模糊"环算术.

有任何想法吗?谢谢 :)

Ski*_*izz 94

怎么样:

for (unsigned i = n ; i-- > 0 ; )
{
  // do stuff with i
}
Run Code Online (Sandbox Code Playgroud)

  • 就我而言,这是反向循环的标准习语,我很惊讶人们之前没有遇到它. (5认同)
  • 你甚至可以把它写成`i - > 0`,它会直观地说出意图;-) (4认同)
  • @HeathHunnicutt - 无符号整数运算具有明确定义的"模数"语义.超出范围的结果将默默包装. (3认同)
  • @HeathHunnicutt 无符号整数在 C 中永远不会溢出或下溢。仅对于有符号整数,下溢和溢出具有未定义的行为。根据标准:“无符号算术不会溢出,因为无法由结果无符号整数类型表示的结果会以比结果无符号整数类型可以表示的最大值大一的数为模进行减少。”。 (3认同)
  • @Auron,n通常是数组的长度,所以在大多数情况下你不希望i == n. (2认同)

Lou*_*nco 12

for ( unsigned int loopIndex = n; loopIndex > 0; --loopIndex ) {
    unsigned int i = loopIndex - 1;
    ...
} 
Run Code Online (Sandbox Code Playgroud)

要么

for ( unsigned int loopIndex = 0; loopIndex < n; ++loopIndex ) {
    unsigned int i = n - loopIndex - 1;
    ...
} 
Run Code Online (Sandbox Code Playgroud)


小智 11

for ( unsigned int i = n; i != 0; i-- ) {
    // do something with i - 1
    ...     
}
Run Code Online (Sandbox Code Playgroud)

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


idz*_*idz 9

为什么不简单:

unsigned int i = n;
while(i--)
{ 
    // use i
}
Run Code Online (Sandbox Code Playgroud)

这符合问题正文中列举的所有要求.它不会使用任何可能导致代码检查失败或违反编码标准的内容.我能看到的唯一反对意见是OP是否真的坚持for循环而不是生成i =(n-1)... 0的简单方法.

  • @Auron 当我学习 C 时,理解 `++i` 和 `i++` 之间的区别并没有被认为是模糊的。时代变了。获得 19 票,这被认为更容易`for (unsigned i = n ; i-- &gt; 0 ; )`...哦! (3认同)

var*_*tec 8

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

  • 我个人认为使用"I-1"而不是"我"并不明显没有大的警告意见,并有可能导致奇怪的错误,当有人在未来本能地用"我"而不是"I-1". (3认同)

Pet*_*ham 8

我倾向于使用

 for ( unsigned int i = n; i > 0; )  {
    --i;
    ...     
 }
Run Code Online (Sandbox Code Playgroud)

它与skizz的答案几乎相同,(它错过了最后的不必要的减量,但编译器应该优化它),实际上将通过代码审查.我必须使用的每个编码标准在条件规则中都没有变异.

  • 现在_that_是一个残缺的构造,被一个while语句迅速取代!为-1. (2认同)

小智 5

也许这样?恕我直言,它清晰可读.如果以某种方式隐式知道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 );
}
Run Code Online (Sandbox Code Playgroud)

另一个版本:

if(n>=1) {
    unsigned int i = n;
    do {
       i--;

    } while( i != 0 );
}
Run Code Online (Sandbox Code Playgroud)

没有if语句的第一个代码如下所示:

unsigned int i = n-1;
do {

} while( i-- != 0 );
Run Code Online (Sandbox Code Playgroud)