Каков наилучший способ сделать обратный цикл for с беззнаковым индексом? - PullRequest
56 голосов
/ 20 марта 2009

Моя первая попытка реверс для цикла , который делает что-то n раз, была что-то вроде:

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

Это завершается с ошибкой , потому что в арифметика без знака i гарантированно всегда будет больше или равна нулю, следовательно, условие цикла всегда будет выполняться К счастью, компилятор gcc предупредил меня о «бессмысленном сравнении», прежде чем мне стало интересно, почему цикл выполняется бесконечно.


Я ищу элегантный способ решения этой проблемы, учитывая, что:

  1. Это должен быть цикл в обратном направлении.
  2. Индекс цикла должен быть без знака.
  3. n является беззнаковой константой.
  4. Он не должен основываться на «неясной» кольцевой арифметике целых чисел без знака.

Есть идеи? Спасибо:)

Ответы [ 20 ]

3 голосов
/ 20 марта 2009
for ( unsigned int i = n; i > 0; i-- ) {
    unsigned int x = i - 1;
    // do whatever you want with x    
}

Конечно, не элегантно, но работает.

2 голосов
/ 07 сентября 2009

Легко, просто остановитесь на -1:

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

редактировать: не уверен, почему это получает отрицание. это работает, и это проще и более очевидно, чем любое из вышеперечисленного.

1 голос
/ 20 марта 2009
unsigned index;
for (unsigned i=0; i<n; i++)
{
    index = n-1 - i; // {i == 0..n-1} => {index == n-1..0}
}
1 голос
/ 20 марта 2009

Hm. Вот ваши варианты:

  1. Используйте i=0 в качестве условия прерывания - цикл не будет выполняться, когда я достигну 0, поэтому выполните 1 итерацию содержимого цикла для i=0 после выхода из цикла.
for ( unsigned int i = n-1; i > 0; i-- ) {
    doStuff(i);
}
doStuff(0);
  1. В цикле проверьте наличие i=0 и break out. Не рекомендуется, потому что теперь вы проверяете значение i дважды в цикле. Использование прерывания в цикле обычно считается плохой практикой.
for ( unsigned int i = n-1; i >= 0; i-- ) {
    doStuff(i);
    if (i=0) break;
}
1 голос
/ 20 марта 2009
for ( unsigned int i = n; i > 0; i-- ) {
    ...     
}

Должно работать нормально. Если вам нужно использовать переменную i в качестве индекса в массиве, сделайте это так:

array[i-1];
0 голосов
/ 20 марта 2009

Так как это не стандарт для цикла, я бы, вероятно, использовал цикл while, например:

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

     if (i == 0)
    {
        break;
    }
    i--;
}
0 голосов
/ 07 сентября 2009

e.z:

#define unsigned signed

for ( unsigned int i = n-1; i >= 0; i-- ) { ... 
}
0 голосов
/ 21 марта 2009

Используйте две переменные, одну для подсчета up , а другую для индекса массива:

unsigned int Index = MAX - 1;
unsigned int Counter;
for(Counter = 0; Counter < MAX; Counter++)
{
    // Use Index
    Index--;
}
0 голосов
/ 20 марта 2009

Это не проверено, но вы могли бы сделать следующее:

for (unsigned int i, j = 0; j < n; i = (n - ++j)) {
    /* do stuff with i */
}
0 голосов
/ 20 марта 2009
for ( unsigned int i = n-1; (n-i) >= 0; i-- ) {
    // n-i will be negative when the loop should stop.
    ...     
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...