All over the web, code samples have for
loops which look like this:
for(int i = 0; i < 5; i++)
while I used the following format:
for(int i = 0; i != 5; ++i)
I do this because I believe it to be more efficient, but does this really matter in most cases?
We can use one more trick for this.
for (i = 5; i > 0; i--)
I suppose most of the compilers optimize the loops like this. I am not sure. Someone please verify.
FORTRAN's DO loop and BASIC's FOR loop implemented
<
(actually<=
) for positive increments. Not sure what COBOL did, but I suspect it was similar. So this approach was "natural" to the designers and users of "new" languages like C.Additionally,
<
is more likely than!=
to terminate in erroneous situations, and is equally valid for integer and floating point values.The first point above is the probable reason the style got started, the second is the main reason it continues.
Regarding readability. Being a C# programmer who likes Ruby, I recently wrote an extension method for int which allows the following syntax (as in Ruby):
The form
is idiomatic, so it's easier to read for experienced C programmers. Especially when used to iterate over an array. You should write idiomatic code whenever possible as it reads faster.
It is also a little safer in situations when you modify i inside the loop or use an increment different then 1. But it's a minor thing. It's best to carefully design your loop and add some asserts to catch broken assumptions early.
It depends on the language.
C++ texts often suggest the second format as that will work with iterators which can be compared (!=) directly but not with a greater to or less than condition. Also pre increment can be faster than post increment as there is no need for a copy of the variable for comparison - however optimisers can deal with this.
For integers either form works. The common idiom for C is the first one whilst for C++ it is the second.
For C# and Java use I would foreach to loop over all things.
In C++ there is also the std::for_each function requiring a use of a functor which for simple cases is probably more complex than either example here and the Boost FOR_EACH which can look like the C# foreach but is complex inside.
There's actually four permutations on what you give. To your two:
We can add:
On most modern machines with modern compilers it shouldn't be surprising that these will be of exactly the same efficiency. It could be just about possible that you may one day find yourself programming for some small processor where there's a difference between equality comparisons and less-than comparisons.
It may in some case make more sense to a particular mind with a particular case to think of "less than" or of "not equals" depending on the reason why we chose 0 and 5, but even then what makes one seem obvious to one coder may not with another.
More abstractly, these are of the forms:
An obvious difference here is that in two cases
someType
must have a meaning for<
and for the rest it must have a meaning for!=
. Types for which!=
is defined and<
isn't are quite common, including quite a few iterator objects in C++ (and potentially in C# where the same approach as STL iterators is possible and sometimes useful, but neither as idiomatic, directly supported by common libraries nor as often useful since there are rival idioms with more direct support). It's worth noting that the STL approach is specifically designed so as to include pointers within the set of valid iterator types. If you're in the habit of using the STL you'll consider the forms with!=
far more idiomatic even when applied to integers. Personally a very tiny amount of exposure to it was enough to make it my instinct.On the other hand, while defining
<
and not!=
would be rarer, it's applicable to cases where either we replace the increment with a different increase ini
's value, or wherei
may be altered within the loop.So, there's definite cases on both sides where one or the other is the only approach.
Now for
++i
vsi++
. Again with integers and when called directly rather than through a function that returns the result (and chances are even then) the practical result will be exactly the same.In some C-style languages (those without operator over-loading) integers and pointers are about the only cases there is. We could just about artificially invent a case where the increment is called through a function just to change how it goes, and chances are the compiler will still turn them into the same thing anyway.
C++ and C# allow us to override them. Generally the prefix
++
operates like a function that does:And the postfix
++
operates like a function that does:Neither C++ nor C# match the above perfectly (I quite deliberately made my pseudo-code match neither), but in either case there may be a copy or perhaps two made. This may or may not be expensive. It may or may not be avoidable (in C++ we often can avoid it entirely for the prefix form by returning
this
and in the postfix by returning void). It may or may not be optimised away to nothing, but it remains that it could be more efficient to do++i
thani++
in certain cases.More particularly, there's the slight possibility of a slight performance improvement with
++i
, and with a large class it could even be considerable, but barring someone overriding in C++ so that the two had completely different meanings (a pretty bad idea) it's not generally possible for this to be the other way around. As such, getting into the habit of favouring prefix over postfix means you might gain an improvement mayone one time in a thousand, but won't lose out, so it's a habit C++ coders often get into.In summary, there's absolutely no difference in the two cases given in your question, but there can be in variants of the same.