For loop condition to stop at 0 when using unsigned integers?

空扰寡人 提交于 2019-12-05 15:15:23

问题


I have a loop that has to go from N to 0 (inclusively). My i variable is of type size_t which is usually unsigned. I am currently using the following code:

for (size_t i = N; i != (size_t) -1; --i) {
    ...
}

Is that correct? Is there a better way to handle the condition?

Thanks,

Vincent.


回答1:


Yes, it's correct and it is a very common approach. I wouldn't consider changing it.

Arithmetic on unsigned integer types is guaranteed to use modulo 2^N arithmetic (where N is the number of value bits in the type) and behaviour on overflow is well defined. The result is converted into the range 0 to 2^N - 1 by adding or subtracting multiples of 2^N (i.e. modulo 2^N arithmetic).

-1 converted to an unsigned integer type (of which size_t is one) converts to 2^N - 1. -- also uses modulo 2^N arithmetic for unsigned types so an unsigned type with value 0 will be decremented to 2^N - 1. Your loop termination condition is correct.




回答2:


Just because for has a convenient place to put a test at the beginning of each iteration doesn't mean you have to use it. To handle N to 0 inclusive, the test should be at the end, at least if you care about handling the maximum value. Don't let the convenience suck you in to putting the test in the wrong place.

for (size_t i = N;; --i) {
    ...
    if (i == 0) break;
}

A do-while loop would also work but then you'd additionally give up i being scoped to the loop.




回答3:


You can use this:

for (size_t i = n + 1; i-- > 0;)
{
}

Hope that helps.




回答4:


Personally, I would just use a different loop construct, but to each their own:

size_t i = N;
do {
    ...
} while (i --> 0);

(you could just use (i--) as the loop condition, but one should never pass up a chance to use the --> "operator").




回答5:


for ( size_t i = N ; i <= N ; i-- ) { .... }

This would do it because size_t is an unsigned int. Unsigned ints are 32bits. When the variable i has a value of 0, you want your loop to execute the condition. If you perform i--, the computer does

 00000000000000000000000000000000
-00000000000000000000000000000001

Which results in a clear overflow, giving a value of 111111111...1. For a signed two's complement integer, this value is clearly negative. However, the type of i is an unsigned int so the computer will interpret 111111...1 to be a very large positive value.

So you have a few options:

1) Do as above and make the loop terminate when overflow occurs.

2) Make the loop run from i = 0 to i <= N but use (N-i) instead of i in everywhere in your loop. For example, myArray[i] would become myArray[N-i] (off by one depending on what the value of N actually represents).

3) Make the condition of your for loop exploit the precedence of the unary -- operator. As another user posted,

for ( size_t i = N + 1 ; i-- > 0 ; ) { ... }

This will set i to N+1, check to see if the condition N+1 > 0 still holds. It does, but i-- has a side effect, so the value of i is decremented to i = N. Keep going until you get to i = 1. The condition will be test, 1 > 0 is true, the side effect occurs, then i = 0 and it executse.




回答6:


You can use a second variable as the loop counter to make the range of iteration clear to a future reviewer.

for (size_t j=0, i=N; j<=N; ++j, --i) {
    // code here ignores j and uses i which runs from N to 0
    ...
}



回答7:


for (i=N; i+1; i--)



回答8:


Since unsigned integer will roll into its max value when decremented from zero, you can try the following, provided N is less then that maximum value (someone please correct me if this is UB):

for ( size_t i = N; i <= N; i-- ) { /* ... */ }


来源:https://stackoverflow.com/questions/3484474/for-loop-condition-to-stop-at-0-when-using-unsigned-integers

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