Most of the times, while loop is used when we are checking for an event to happen in the while loop body. And for is mostly used when a "determined" number of iterations is given. Let us assume we need to know the number of iteration we are in, generally speaking:
General While loop:
bool flag = false;
int it = 0;
while (!flag)
{
//... do something using it
++it;
flag = getFlag();
}
General For loop, the iteration number is intrinsic to the loop:
for(int it = 0; it < N; ++it)
{
//... do something using it
if (getFlag())
break;
}
However, for the case where the number of iterations is not set (that is, we are looping until the even occurs) I have never seen something like:
for(int it = 0; !getFlag(); ++it)
{
//...do something using it
}
But I always see something like the first while loop I have written. Is there any real difference? Is it considered a better style the while loop? Because for me, the for loop is more compact and easy to read and follow.
Generally you should use whichever you find the most readable, but beware that there is a difference between these two constructs that may catch you off guard: the behavior of continue.
continue would not increment it using the while construct, but it would increment it using the for construct.
while (!getFlag()) {
// ...
if (something) {
// "it" won't be incremented!
continue;
}
// ...
++it;
}
for(int it = 0; !getFlag(); ++it) {
// ...
if (something) {
// "it" will be incremented!
continue;
}
// ...
}
If you are not using continue then the behavior will be identical, but you can't make the general statement that for (a; b; c) { d; } is exactly equivalent to { a; while (b) { d; c; } } unless you add the restriction that d cannot contain a continue statement.
There is no difference in execution between the while() and for() loops you describe. There is no standard or common convention on which one is better or more elegant. Stick to the one you find more comfortable to work with.
Is there any real difference?
No. Apart from variable scoping and the meaning of continue, these are exactly equivalent:
initialize;
while (condition) {
body;
increment;
}
for (initialize; condition; increment) {
body;
}
Is it considered a better style the while loop?
There are, as you mention, typical use cases for each type of loop:
If you have some initialization, test and increment, use a for loop. Not necessarily for a known number of iterations, either; a typical C++ pattern is to iterate while i != some_container.end(). I think your last example works fine as a for loop.
If you don't need the initialization and increment, use a while loop. Writing for (; condition;) is just silly.
However, there are grey areas, where either type of loop makes sense. It is mostly a matter of personal preference.
All of the above cases are valid, and perfectly OK in my book (assuming that you meant to set flag = true; in the first case, or at least not constant false, since that will never enter the loop).
I sometimes use:
for(int i = 0; ; i++)
{
...
if (getFlag()) break;
...
}
Another favourite is the typical "linked list loop":
for(Node* p = head; p; p = p->next)
{
... Do stuff with p ...
}
To a large degree, it depends on what you are actually trying to express...
The compiler will most likely generate the same, or at least very similar, code for all three.
The fact is that
for (exp1; exp2; exp3) {
statements;
}
is equivalent to
{ // I put the brace, because exp1 may be a declaration of variable local to the loop
exp1;
while (exp2) {
statements; // as long as there is no continue (or if you replace every continue; with { exp3; continue; }
exp3;
}
}
So it's a matter of taste, of having a loop specific initialisation and an increment expression, and of the way of using continue statements .
However your analysis is exact: for is frequently used for iteration, as the c++11 range-for shows :
for (x : container) {
statements;
}
The reason (at least according to B.Stroustrup) is that all control logic for the iteration can easily be regrouped in one visible place, at top of the loop.
Whilst I'll agree with most people there is no major difference (and in fact in most situation they will actually compile down into the same code). I was always taught not to use for loops in situations where internal operations (other than the iterator) could change when the loop ends. This was for readability sake.
Related
If I was going through a loop, say iterating a vector, and I don't want to do an action on some item in the vector, I can do it in two ways:
This is the one I prefer to use:
vector<int> vec;
void loopFunction(int toIgnore) {
for (size_t index = 0; index < vec.size(); index++) {
if (vec[index] == toIgnore) continue;
// do stuff
}
}
This is the one I see most people use:
vector<int> vec;
void loopFunction(int toIgnore) {
for (size_t index = 0; index < vec.size(); index++) {
if (vec[index] != toIgnore) {
// do stuff
}
}
}
I know in the final results there is absolutely no difference. However, is there any difference under the hood since the second way opens a new scope to execute? Is any of these two preferred over the other?
Thanks
As stated in my comment, on a personal level, I prefer the first implementation using continue in order to prevent unnecessary code nesting and scope creation.
The only performance overhead from each, in addition to the normal code that will be implemented, is the evaluation of the expression in the if-statement. Since they both contain an expression to be evaluated, they're the same performance wise.
If you think about how this is compiled, for C/C++, its straight into assembly code. On that level no matter how you nest the code, it compiles into simple jmp and cmp commands. Therefore, regardless of the implementation, on compile, you'll have the ~same assembly code.
Either way you look at it, this is a micro-micro-micro optimization, if at all! Do what you prefer for code formatting and styling.
I was told that a while loop was more efficient than a for loop. (c/c++)
This seemed reasonable but I wanted to find a way to prove or disprove it.
I have tried three tests using analogous snippets of code. Each containing Nothing but a for or while loop with the same output:
Compile time - roughly the same
Run time - Same
Compiled to intel assembly code and compared - Same number of lines and virtually the same code
Should I have tried anything else, or can anyone confirm one way or the other?
All loops follow the same template:
{
// Initialize
LOOP:
if(!(/* Condition */) ) {
goto END
}
// Loop body
// Loop increment/decrement
goto LOOP
}
END:
Therefor the two loops are the same:
// A
for(int i=0; i<10; i++) {
// Do stuff
}
// B
int i=0;
while(i < 10) {
// Do stuff
i++;
}
// Or even
int i=0;
while(true) {
if(!(i < 10) ) {
break;
}
// Do stuff
i++;
}
Both are converted to something similar to:
{
int i=0;
LOOP:
if(!(i < 10) ) {
goto END
}
// Do stuff
i++;
goto LOOP
}
END:
Unused/unreachable code will be removed from the final executable/library.
Do-while loops skip the first conditional check and are left as an exercise for the reader. :)
Certainly LLVM will convert ALL types of loops to a consistent form (to the extent possible, of course). So as long as you have the same functionality, it doesn't really matter if you use for, while, do-while or goto to form the loop, if it's got the same initialization, exit condition, and update statement and body, it will produce the exact same machine code.
This is not terribly hard to do in a compiler if it's done early enough during the optimisation (so the compiler still understands what is actually being written). The purpose of such "make all loops equal" is that you then only need one way to optimise loops, rather than having one for while-loops, one for for-loops, one for do-while loops and one for "any other loops".
It's not guaranteed for ALL compilers, but I know that gcc/g++ will also generate nearly identical code whatever loop construct you use, and from what I've seen Microsoft also does the same.
C and C++ compilers actually convert high level C or C++ codes to assembly codes and in assembly we don't have while or for loops. We can only check a condition and jump to another location.
So, performance of for or while loop heavily depends on how strong the compiler is to optimize the codes.
This is good paper on code optimizations:
http://www.linux-kongress.org/2009/slides/compiler_survey_felix_von_leitner.pdf.
what is the between in writing a loop by branching jump statement and a normal loop
i.e for example
main()
{
int i=0;
while(i<9)
{
//do something
i++;
}
and
main()
{
int i=0;
label:
//do something
i++;
if(i<9)
goto label;
}
is the performance of both of them are equal?
These two loops are not equivalent: the second one is similar to a do/while loop, not a while loop:
main() {
int i=0;
do {
//do something
i++;
} while(i<9);
}
The two should be the same as far as the performance goes; however, the readability of the solution with the goto suffers considerably, so I would refrain from using it in any of your projects.
The difference is that the first one is a lot easier to read, which is why goto is generally avoided. Also as pointed out in dasblinkenlight's answer the semantics are not the same.
The performance should be about the same, since the CPU has to do jumps in order to implement both. Of course, with a higher-level description of intent (as in the first case) the chance of the compiler being able to optimize something increases.
Perhaps not in this particular case, but in general a more high-level description of what you want to do is to be preferred, and then the looping constructs are better than goto.
In this case, compiler should produce an equivalent output. But I don't think these two examples are equivalent - a while first checks the condition and then decides wheter to execute the body. Your example with the goto first executes the body and then checks the conditions - it behaves more like a do while statement.
You shouldn't use goto in this case, as it reduces readability. gotos are valid in only a limited number of scenarios.
We can use for loop and while loop for same purpose.
in what means they effect our code if I use for instead of while? same question arises between if-else and switch-case? how to decide what to use?
for example which one you would prefer?
This code:
int main()
{
int n = 10;
for(int i=0;i<n;i++)
{
do_something();
}
return 0;
}
Or this code:
int main()
{
int n=10,i=0;
while(i<n)
{
do_something();
i++;
}
return 0;
}
if using for or while loop does not effect the code by any means then may I know What was the need to make 2 solution for same problem?
Use whichever one makes the intention of your code clearest.
If you know the number of iterations the loop should run beforehand, I would recommend the for construct. While loops are good for when the loop's terminating condition happens at some yet-to-be determined time.
I try to prefer the for loop. Why? Because when I see a for loop, I can expect all of the loop bookeeping is kept in a single statement. I can insert break or continue statements without worrying about breaking how the loop operates. And most importantly, the body of the loop focuses on what you actually want the loop to be doing, rather than maintaining the loop itself. If I see a while, then I have to look at and understand the entire loop body before I can understand what iteration pattern the loop uses.
The only place I end up using while is for those few cases where the control of the loop is provided by some outside routine (i.e. FindFirstFileW)
It's all a matter of personal opinion though. Lots of people don't like what I end up doing with for loops because the loop statement often ends up spanning multiple lines.
There are some very subtle differences..
scope of loop variable(s), for example, with the for loop i has local scope, with a while this has to be defined before (which means it is available after, of course you can do that with for as well..)
continue, with a for loop, variable will be increment/decremented, with a while, you'd have to insert the operation before continue
Frankly, if you need to increment/decrement, a for loop makes sense, if you don't know the bounds, and there is no real increment/decrement, a while loop makes more sense, e.g.
while(some_stream >> input)
{
// do stuff...
}
In general, a for loop might be preferable for simple loops, since the logic of the loop is contained in a single line:
for (int i = 0; i < 10; ++i) {...}
However, sometimes we need more complex logic or flow control. A while loop allows us to implement more complicated loops. For example, suppose we only want to increment the counter variable under certain conditions:
int i = 0;
while (i < 10)
{
if (some_condition) ++i;
else if (some_other_condition) { ... }
else break;
}
Just use the one that makes the code readable and logical.
In some cases the compiler (gcc at least) will be able to optimize a very slightly better than a for loop doing the same thing. If I remember correctly that optimization is only about few clock cycles so it probably never will have any noticeable affect on the performance.
You cannot write while(int i=0, i < n); that is, you've to define i before the while loop; means i exists inside as well as outside the loop.
However, in case of for loop, you can define i right in the for loop itself; and so i doesn't exist outside the loop. That is one difference. Just because of this difference, I like for more than while. And use while rarely, when for makes thing more cumbersome!
By no means they affect your program the way it works ! Its the matter of ease to understand better.
switch(i) // Once finding your case, you can easily know where the switch ends
// and thus the next statement of execution
{
case 1: break ;
case 2: break ;
// .....
case 10: break ;
default:break ;
}
if( i==1 ) // Here you have the pain of finding where the last else if ends !
{}
else if( i==2)
{}
// ...
else if( i==10)
{}
However, it is a matter of taste. I prefer switch.
Which of the following is better and why? (Particular to c++)
a.
int i(0), iMax(vec.length());//vec is a container, say std::vector
for(;i < iMax; ++i)
{
//loop body
}
b.
for( int i(0);i < vec.length(); ++i)
{
//loop body
}
I have seen advice for (a) because of the call to length function. This is bothering me. Doesn't any modern compiler do the optimization of (b) to be similar to (a)?
Example (b) has a different meaning to example (a), and the compiler must interpret it as you write it.
If, (for some made-up reason that I can't think of), I wrote code to do this:
for( int i(0);i < vec.length(); ++i)
{
if(i%4 == 0)
vec.push_back(Widget());
}
I really would not have wanted the compiler to optimise out each call to vec.length(), because I would get different results.
I like:
for (int i = 0, e = vec.length(); i != e; ++i)
Of course, this would also work for iterators:
for (vector<int>::const_iterator i = v.begin(), e = v.end(); i != e; ++i)
I like this because it's both efficient (calling end() just once), and also relatively succinct (only having to type vector<int>::const_iterator once).
I'm surprised nobody has said the obvious:
In 99.99% of cases, it doesn't matter.
Unless you are using some container where calculating size() is an expensive operation, it is unfathomable that your program will go even a few nanoseconds slower. I would say stick with the more readable until you profile your code and find that size() is a bottleneck.
There are two issues to debate here:
The variable scope
The end condition re-evaluation
Variable scope
Normally, you wouldn't need the loop variable to be visible outside of the loop. That's why you can declare it inside the for construct.
End condition re-evaluation
Andrew Shepherd stated it nicely: it means something different to put a function call inside the end condition:
for( vector<...>::size_type i = 0; i < v.size(); ++i ) { // vector size may grow.
if( ... ) v.push_back( i ); // contrived, but possible
}
// note: this code may be replaced by a std::for_each construct, the previous can't.
for( vector<...>::size_type i = 0, elements = v.size(); i != elements; ++i ) {
}
Why is it bodering you?
Those two alternatives dont see to be doing the same. One is doing a fixed number of iterations, while the other is dependant on the loops body.
Another alternative colud be
for (vector<T>::iterator it=vec.begin();it!=vec.end();it++){
//loop body
}
Unless you need the loop variable outside the loop, the second approach is preferable.
Iterators will actually give you as good or better performance. (There was a big comparison thread on comp.lang.c++.moderated a few years back).
Also, I would use
int i = 0;
Rather than the constructor like syntax you're using. While valid, it's not idiomatic.
Somewhat unrelated:
Warning: Comparison between signed and unsigned integer.
The correct type for array and vector indices is size_t.
Strictly speaking, in C++ it is even std::vector<>::size_type.
Amazing how many C/C++ developers still get this one wrong.
Let's see on the generated code (I use MSVS 2008 with full optimization).
a.
int i(0), iMax(vec.size());//vec is a container, say std::vector
for(;i < iMax; ++i)
{
//loop body
}
The for loop produces 2 assembler instructions.
b.
for( int i(0);i < vec.size(); ++i)
{
//loop body
}
The for loop produces 8 assembler instructions. vec.size() is successfully inlined.
c.
for (std::vector<int>::const_iterator i = vec.begin(), e = vec.end(); i != e; ++i)
{
//loop body
}
The for loop produces 15 assembler instructions (everything is inlined, but the code has a lot of jumps)
So, if your application is performance critical use a). Otherwise b) or c).
It should be noted that the iterator examples:
for (vector<T>::iterator it=vec.begin();it!=vec.end();it++){
//loop body
}
could invalidate the loop iterator 'it' should the loop body cause the vector to reallocate. Thus it is not equivalent to
for (int i=0;i<vec.size();++i){
//loop body
}
where loop body adds elements to vec.
Simple question: are you modifying vec in the loop?
answer to this question will lead to your answer too.
jrh
It's very hard for a compiler to hoist the vec.length() call in the safe knowledge that it's constant, unless it gets inlined (which hopefully it often will!). But at least i should definitely be declared in the second style "b", even if the length call needs to be "manually" hoisted out of the loop!
This one is preferable:
typedef vector<int> container; // not really required,
// you could just use vector<int> in for loop
for (container::const_iterator i = v.begin(); i != v.end(); ++i)
{
// do something with (*i)
}
I can tell right away that the vector
is not being updated
anyone can tell what is happening
here
I know how many loops
v.end() returns pointer one past the
last element so there's no overhead
of checking size
easy to update for different
containers or value types
(b) won't calculate/call the function each time.
-- begin excerpt ----
Loop Invariant Code Motion:
GCC includes loop invariant code motion as part of its loop optimizer as well as in its partial redundancy elimination pass. This optimization removes instructions from loops, which compute a value which does not change throughout the lifetime of a loop.
--- end excerpt --
More optimizations for gcc:
https://www.in.redhat.com/software/gnupro/technical/gnupro_gcc.php3
Why not sidestep the issue entirely with BOOST_FOREACH
#include <boost/foreach.hpp>
std::vector<double> vec;
//...
BOOST_FOREACH( double &d, vec)
{
std::cout << d;
}