Iterating Through All Values from N to 0 inclusive for an Unsigned Value
Вопрос
I have this code that works fine for regular signed integers that I am trying to write an equivalent version that will work with size_t (as in that as of now start and count are ints and i need them to be size_t) :
int count,start;
for (start = (count-2)/2; start >=0; start--)
{
someFunction( x, start, count); // x is to illustrate function has other parameters
}
I feel like this code is straight forward enough for a really simple solution but I am drawing a blank.
Решение
You could rewrite it like this:
start = count/2;
while (start > 0){
start--;
someFunction( x, start, count);
}
Otherwise, the only other option I can think of is to do some non-standard compliant casting between signed and unsigned... or to do something with ~(size_t)0
...
Here are some non-standard compliant alternatives:
for (start = (count-2)/2; (ssize_t)start >= 0; start--)
{
someFunction( x, start, count);
}
for (start = (count-2)/2; start != ~(size_t)0; start--)
{
someFunction( x, start, count);
}
Другие советы
size_t cnt, start;
for (start = cnt/2; start-- > 0; ) { ... }
- if cnt=0 : start will start at zero, the loop code will never execute; after the loop, start will be (size_t)-1
- if cnt=1 : the same
- if cnt >=2 : the loop code will execute at least once; on the first iteration, start will be (cnt/2)-1; on the last iteration start will be 0; after the loop start will be (size_t)-1
EDIT if the OP really wants to loop once for cnt=1, a ternary is necessary:
for (start = (cnt==1) ? 1 : cnt/2; start-- > 0; ) { ... }
What about just using a value off by one?
size_t start_plus_one;
for (start_plus_one = (count-2)/2+1; start_plus_one >=1; start_plus_one--)
{
someFunction( x, start_plus_one-1, count); // x is to illustrate function has other parameters
}
You can fix the end condition from your original code. -1/2
is guaranteed to be 0 in C99, which makes the loop body execute once, so you might have to treat count == 1
specially if that's still the required behavior once the types are unsigned.
size_t count = something;
if (count > 1) {
for (size_t start = (count-2)/2; start != SIZE_MAX; --start) {
someFunction(x, start, count);
}
}
This works because we know that the initial value of start
cannot possibly be SIZE_MAX
, because there is no value of size_t
that when divided by 2 yields SIZE_MAX
.
For more general loops, that might need to start at SIZE_MAX
and go all the way down to 0 inclusive, clearly we cannot perform the exit check before the loop body, because we want the loop body to execute once for every value of size_t
, so there is no value on which we can exit. To allow for that case:
size_t count = SIZE_MAX, start = SIZE_MAX;
do {
someFunction(x, start, count);
} while (start-- != 0);
In all cases, SIZE_MAX
can be replaced with -1
, which is more generic in that it converts to the max value of every unsigned type, but leads to confused questions.