for (unsigned char i = 0; i<=0xff; i++) produces infinite loop

天涯浪子 提交于 2019-12-18 09:02:52

问题


Why does the following c code end up in an infinite loop?

for(unsigned char i = 0; i <= 0xff; i++){}

It is the same result with:

for(unsigned char i = 0; i <= 0xff; ++i){}

In which way do I have to modify the code, to get it working as expected (without using int or unsigned int datatype)?


回答1:


A typical for loop relies on being able to detect the termination condition after the last iteration of the loop. In your case, as other answers have pointed out, i <= 0xff is always true (given that i is of type unsigned char and that UCHAR_MAX==0xff, which is typical).

You can run into the same kind of problem near the bounds of any integer type. For example, this:

for (int i = INT_MAX - 9; i <= INT_MAX; i ++) {
    /* ... */
}

is (probably) also an infinite loop (except that overflow for signed integer types has undefined behavior as opposed to the well-defined wraparound semantics for unsigned integers, and an optimizing compiler can take advantage of that and -- but I digress). Just don't do that.

One of many solutions is to move the test to the bottom of the loop, before the increment:

for (unsigned char i = 0; ; i ++) {
    printf("%d\n", i);
    if (i == 0xff) break;
}

The second clause of a for loop is the termination condition, evaluated before each iteration. If you leave it empty, it's treated as always true, giving you an infinite loop (for (;;) is a common idiom for a simple infinite loop). We test whether i is equal to 0xff at the bottom of the loop. If it is then we've just executed the last iteration, and we can break out of the loop.

(Some might prefer to use a while loop here, but I like the for because it lets us combine the declaration of the loop control variable and the increment in a single construct.)

(Strictly speaking the maximum value of unsigned char isn't necessarily 0xff or 255, but it will be on any system you're likely to encounter. Implementations for some DSPs have CHAR_BIT > 8, and thus UCHAR_MAX > 255.)




回答2:


If you really need to use unsigned char then you can use

unsigned char i = 0;
do {
    // ... 
} while(++i);

When an arithmetic operation on an unsigned integer breaks its limits, the behaviour is well defined. So this solution will process 256 values (for 8-bit unsigned char).




回答3:


The range of an unsigned char is 0 to 255 (0xff). Adding 1 to 0xff makes 0x100, which when assigned back to an unsigned char wraps around back to 0.

So the comparison i <= 0xff will always be true. Hence the infinite loop.

If you want the loop to stop after 0xff, use int as the datatype. This is a range of at least -32767 to 32767, and typically more.




回答4:


Because you wraparound. An unsigned char values range between 0-255, and because unsigned arithmetic are well defind, you actually wrap the value of i to 0 and the condition is still met and the iteration continues ad infinitum.

In the case of signed values, it is an undefined behaviour and value stored in i might not be 0. But still it will be smaller than the maximum value you could store in a char and the condition is still met.



来源:https://stackoverflow.com/questions/45493449/for-unsigned-char-i-0-i-0xff-i-produces-infinite-loop

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!