Iterating Backwards in C
https://www.davidpriver.com/Iterating-backwards-in-C.htmlloading story #50300192
I know it's "too clever", but if I'm writing code no one else will ever see,
while (i --> 0) {
// use array[i]
}
easy to read (if not understand), and correct!loading story #50298845
loading story #50299744
loading story #50299341
loading story #50298889
loading story #50299575
loading story #50299118
loading story #50298806
loading story #50299331
I thought most people used the explicit version:
for (size_t i = count; i > 0; --i) {
// use array[i - 1]
}
You can also do something like: size_t index = i - 1;
to not have to use i-1. I believe the compiler optimizes that out anyway to be identical.loading story #50299552
That's the price of innovation, I guess; before C invented its "for"-loop, other languages had their equivalents generally looking like this:
FOR var = start [DOWN] TO end BY step DO ... END
No custom increment expressions, and "step" even usually was only allowed to be a constant (in which case, the language usually didn't have DOWN specifier and used the step's sign instead). Then Dennis Ritchie invented C, and ditched the traditional "do"-loop (Fortran started that construct with DO, so it was called DO loop; Algol used FOR instead, but most people preferred the Fortran's nomenclature... until C came to dominate, but that wouldn't happen for yet another 20 years) in favour of his invention because he felt that easily iterating through linked lists or strings was a much more pressing concern: for(p=head; p; p=p->next) { ... }
for(s=str; *s; s++) { ... }
The downside, of course, is that now you can't straightforwardly write for size_t i = count - 1 downto 0 do
...
endloading story #50300053
This is why I prefer to use C++ and its reversed iterators. The rbegin and rend accessors are there in the containers from the beginning. It’s less error prone than the C version using indices. (Of course some situations require me to use indices, so I do use the i-->0 trick, but it is much rarer.)
For the uninformed: counting backwards in a for loop is faster because comparing an unsigned integer against 0 is generally faster than comparing it against any other value.
It also says not to use `for (i >= 0)` because any unsigned integer is >= 0, and the loop will never end.
loading story #50299666
loading story #50299606
Why not use the C/C++ idiom of pointer math?
_Bool find_last (size_t count, int *haystack, int needle, size_t *where)
{
for (const int *pos = haystack + count; pos-- != haystack;) {
if (*pos == needle) {
*where = pos - haystack;
return 1;
}
}
return 0;
}loading story #50299381
As long as you make sure the end points are valid, this is most intuitive for me.
Just using i as a backwards step.
for (int i = 1; i <= N; i++) {
array[N-i]
}loading story #50299624
I prefer:
const size_t n = 10;
for (size_t i = n; i --> 0;) {
std::cout << i << "\n";
}loading story #50298746
Cute but wouldn't work with ssize_t :)
VHDL's array/vector syntax actually works a similar way:
-- gives 0, 1, 2, 3:
for i in 0 to 3 loop
-- gives 3, 2, 1, 0:
for i in 3 downto 0 loop
-- Source - https://stackoverflow.com/a/7642026 -- Posted by Kerrek SB -- Retrieved 2026-10-29, License - CC BY-SA 3.0
I've been using this method for more than 30 years!
> Now your index variable is signed, which can cause problems when used in expressions due to C's conversion rules.
Array indices are already signed. This shouldn't be a problem.
loading story #50299627
[flagged]
[flagged]
[dead]