unsigned int вызывает бесконечный цикл for

Ниже есть две петли. Первый работает хорошо, а второй — бесконечный цикл. Зачем?

for (unsigned int i=0; i<3; ++i)
{
std::cout << "i= " << i << std::endl; // this gives proper result
}

for (unsigned int i=3; i>=0; --i)
{
std::cout << "i= " << i << std::endl; // infinite loop
}

1

Решение

unsigned int никогда не может быть меньше 0. Вот что делает его неподписанный. Если вы включите несколько флагов предупреждений, ваш компилятор должен сообщить вам о вашей проблеме: i >= 0 является всегда правда для unsigned значение.

Например, Clang вообще не требовал специальных флагов для предупреждения:

example.cpp:5:29: warning: comparison of unsigned expression >= 0 is always true
[-Wtautological-compare]
for (unsigned int i=3; i>=0; --i)
~^ ~
1 warning generated.

GCC требуется -Wextra:

example.cpp: In function ‘int main()’:
example.cpp:5: warning: comparison of unsigned expression >= 0 is always true
12

Другие решения

unsigned int не может быть меньше нуля (что проверяет условие цикла). когда i в вашем втором цикле уменьшается от 0, он оборачивается UINT_MAX и цикл продолжается.

3

Остальные ответы (пока что) верны; поскольку i без знака, i >= 0 всегда верно, и поэтому у вас есть бесконечный цикл.

Но это не говорит вам, как это исправить. Если вы хотите выполнить итерацию в диапазоне без знака, скажем, от 3 до 0, то, похоже, не существует простого способа сделать это. Кроме изменения типа i или направление диапазона (и могут быть причины, по которым вы не можете этого сделать), вы можете сделать это:

for (unsigned int i=3; ; --i)
{
std::cout << "i= " << i << std::endl;
if (i == 0) break;
}

Это не так чисто, как простой for петля без break но это делает работу.

3

В дополнение к ответу Кейта Томпсона, есть еще один способ написать его, который не требует break внутри цикла:

for (unsigned int i = 3; i--; ) {
std::cout << "i= " << i << std::endl;
}

Обратите внимание, как i-- действует как условие завершения и как последствие, все в одном. Использование оператора декфиксного постфикса важно, потому что он гарантирует, что вы фактически выполняете цикл 3 раза, начиная с 2 на первой итерации и заканчивая на 0, включая.

3

Минимальное значение для unsigned int i 0; все остальное будет отрицательным и потребует знаковый бит, который конкретно unsigned int не будет иметь.

Так i >= 0 всегда будет оценивать как истину.

2

Во втором цикле условие для остановки цикла состоит в том, что i должно быть меньше 0. Диапазон unsigned int является 0 to 65535, так вот unsigned int i не может быть меньше нуля. Итак, ваше условие всегда верно, в результате цикл становится бесконечным. Используя signed int может решить проблему.

0
По вопросам рекламы [email protected]