質問

There are two loops below. The first one works well while the second one is an infinite loop. Why?

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
}
役に立ちましたか?

解決

An unsigned int can never be less than 0. That's what makes it unsigned. If you turn on some warning flags, your compiler should tell you about your problem: i >= 0 is always true for an unsigned value.

Clang, for example, required no special flags at all to warn:

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 required -Wextra:

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

他のヒント

unsigned int cannot be less than zero (which is what loop's condition is checking). When i in your second loop is decremented from 0, it wraps around to UINT_MAX and the loop goes on.

The other answers (so far) are all correct; since i is unsigned, i >= 0 is always true, and so you have an infinite loop.

But that doesn't tell you how to fix it. If you want to iterate over an unsigned range from, say, 3 down to 0, there doesn't seem to be a straightforward way to do it. Other than changing the type of i or the direction of the range (and there may be reasons you can't do that), you could do this:

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

It's not as clean as a simple for loop with no break but it does the job.

In addition to Keith Thompson's answer, there is another way to write it that doesn't require a break inside the loop:

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

Notice how i-- acts both as the termination condition and as the afterthough, all in one. The use of the postfix decrement operator is important because it guarantees you're actually executing the loop 3 times, starting at 2 on the first iteration and ending at 0, included.

The minimum value for unsigned int i is 0; anything else would be negative and require a sign bit which is specifically what an unsigned int won't have.

So i >= 0 will always evaluate to true.

In your second loop ,the condition to stop the loop is that i must be less than 0. The range of unsigned int is 0 to 65535. so, here unsigned int i can't be less than zero. So, your condition is always true as a result the loop become infinite. Using a signed int can solve the problem.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top