Ниже есть две петли. Первый работает хорошо, а второй — бесконечный цикл. Зачем?
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
}
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
unsigned int
не может быть меньше нуля (что проверяет условие цикла). когда i
в вашем втором цикле уменьшается от 0, он оборачивается UINT_MAX
и цикл продолжается.
Остальные ответы (пока что) верны; поскольку i
без знака, i >= 0
всегда верно, и поэтому у вас есть бесконечный цикл.
Но это не говорит вам, как это исправить. Если вы хотите выполнить итерацию в диапазоне без знака, скажем, от 3 до 0, то, похоже, не существует простого способа сделать это. Кроме изменения типа i
или направление диапазона (и могут быть причины, по которым вы не можете этого сделать), вы можете сделать это:
for (unsigned int i=3; ; --i)
{
std::cout << "i= " << i << std::endl;
if (i == 0) break;
}
Это не так чисто, как простой for
петля без break
но это делает работу.
В дополнение к ответу Кейта Томпсона, есть еще один способ написать его, который не требует break
внутри цикла:
for (unsigned int i = 3; i--; ) {
std::cout << "i= " << i << std::endl;
}
Обратите внимание, как i--
действует как условие завершения и как последствие, все в одном. Использование оператора декфиксного постфикса важно, потому что он гарантирует, что вы фактически выполняете цикл 3 раза, начиная с 2 на первой итерации и заканчивая на 0, включая.
Минимальное значение для unsigned int i
0; все остальное будет отрицательным и потребует знаковый бит, который конкретно unsigned
int не будет иметь.
Так i >= 0
всегда будет оценивать как истину.
Во втором цикле условие для остановки цикла состоит в том, что i
должно быть меньше 0. Диапазон unsigned int
является 0 to 65535
, так вот unsigned int i
не может быть меньше нуля. Итак, ваше условие всегда верно, в результате цикл становится бесконечным. Используя signed int
может решить проблему.