Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the best way to do a backwards loop in C/C#/C++?

Tags:

c++

c

c#

People also ask

Can you run a for loop backwards?

Let's discuss certain ways in which this can be done. Method #1 : Using reversed() The simplest way to perform this is to use the reversed function for the for loop and the iteration will start occurring from the rear side than the conventional counting.

Are reverse loops faster?

x, all reverse loops are always faster than all forward loops.


While admittedly a bit obscure, I would say that the most typographically pleasing way of doing this is

for (int i = myArray.Length; i --> 0; )
{
    //do something
}

In C++ you basicially have the choice between iterating using iterators, or indices. Depending on whether you have a plain array, or a std::vector, you use different techniques.

Using std::vector

Using iterators

C++ allows you to do this using std::reverse_iterator:

for(std::vector<T>::reverse_iterator it = v.rbegin(); it != v.rend(); ++it) {
    /* std::cout << *it; ... */
}

Using indices

The unsigned integral type returned by std::vector<T>::size is not always std::size_t. It can be greater or less. This is crucial for the loop to work.

for(std::vector<int>::size_type i = someVector.size() - 1; 
    i != (std::vector<int>::size_type) -1; i--) {
    /* std::cout << someVector[i]; ... */
}

It works, since unsigned integral types values are defined by means of modulo their count of bits. Thus, if you are setting -N, you end up at (2 ^ BIT_SIZE) -N

Using Arrays

Using iterators

We are using std::reverse_iterator to do the iterating.

for(std::reverse_iterator<element_type*> it(a + sizeof a / sizeof *a), itb(a); 
    it != itb; 
    ++it) {
    /* std::cout << *it; .... */
}

Using indices

We can safely use std::size_t here, as opposed to above, since sizeof always returns std::size_t by definition.

for(std::size_t i = (sizeof a / sizeof *a) - 1; i != (std::size_t) -1; i--) {
   /* std::cout << a[i]; ... */
}

Avoiding pitfalls with sizeof applied to pointers

Actually the above way of determining the size of an array sucks. If a is actually a pointer instead of an array (which happens quite often, and beginners will confuse it), it will silently fail. A better way is to use the following, which will fail at compile time, if given a pointer:

template<typename T, std::size_t N> char (& array_size(T(&)[N]) )[N];

It works by getting the size of the passed array first, and then declaring to return a reference to an array of type char of the same size. char is defined to have sizeof of: 1. So the returned array will have a sizeof of: N * 1, which is what we are looking for, with only compile time evaluation and zero runtime overhead.

Instead of doing

(sizeof a / sizeof *a)

Change your code so that it now does

(sizeof array_size(a))

In C#, using Visual Studio 2005 or later, type 'forr' and hit [TAB] [TAB]. This will expand to a for loop that goes backwards through a collection.

It's so easy to get wrong (at least for me), that I thought putting this snippet in would be a good idea.

That said, I like Array.Reverse() / Enumerable.Reverse() and then iterate forwards better - they more clearly state intent.


I would always prefer clear code against 'typographically pleasing' code. Thus, I would always use :

for (int i = myArray.Length - 1; i >= 0; i--)  
{  
    // Do something ...  
}    

You can consider it as the standard way to loop backwards.
Just my two cents...