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.
Related
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.
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.
In a loop like so,
for (int i = 0; i < 5; i++)
{
int i_foo;
i_foo = foo();
if (i < 5)
return; //<-------- Right here
footwo();
}
How would I return that one particular turn of the loop?
I know that I could make footwo() execute under the condition that i >= 5, but I'm wondering if there is a way to make the loop exit (just the once).
For more explanation, I would like the for loop to start back at the beginning and add 1 to i, as if it had just finished that particular "loop" of the loop.
(I could not find an answer to this based on the strange wording, but if there is one just direct me and I will happily take this down.)
Use continue:
if (i < 5)
continue;
This jumps straight to the next iteration of the loop.
I'm not entirely sure what you mean but if you're checking the condition of if (i < 5) then just use the keyword continue. If the expression is true the loop will continue.
I'm not exactly what you're saying, but to clear up a bit of terminology, I think you mean to say "iteration" when you're saying a "turn of the loop" or a "loop of the loop." Common terms allow for better clarity.
As to your issue:
If you use the continue keyword, it allows you to skip to the next iteration. If you use the break keyword, it will skip past the entire iteration structure (out of the for loop entirely). This also works with while statements.
You can use continue to terminate the current iteration of a loop without terminating the loop itself. But depending on how your code is structured, an if statement might be cleaner.
Given your example, you might want:
for (int i = 0; i < 5; i++)
{
int i_foo;
i_foo = foo();
if (i_foo >= 5) {
footwo();
}
}
I'm assuming that you meant to assign the result of foo() to i_foo, not to i.
A continue can be simpler if you need to bail out from the middle of some nested structure, or if you need to bail out very early in the body of the loop and there's a lot of code that would be shoved into the if.
But in the case of nested control structures, you need to remember that continue applies only to the innermost enclosing loop; there's no construct (other than goto) for bailing out of multiple nested loops. And break applies to the innermost enclosing loop or switch statement.
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.
I want to have a while loop do something like the following, but is this possible in c++? If so, how does the syntax go?
do {
//some code
while( expression to be evaluated );
// some more code
}
I would want the loop to be exited as soon as the while statement decides the expression is no longer true( i.e. if expression is false, //some more code is not executed)
You can do:
while (1) {
//some code
if ( condition) {
break;
}
// some more code
}
A little background and analysis: what you're asking for I've heard called a "Dahl loop", named after Ole-Johan Dahl of Simula fame. As Sean E. states, C++ doesn't have them (ima's answer aside), though a few other languages do (notably, Ada). It can take the place of "do-while" and "while-do" loops, which makes it a useful construct. The more general case allows for an arbitrary number of tests. While C++ doesn't have special syntax for Dahl loops, Sean McCauliff and AraK's answers are completely equivalent to them. The "while (true)" loop should be turned into a simple jump by the compiler, so the compiled version is completely indistinguishable from a compiled version of a hypothetical Dahl loop. If you find it more readable, you could also use a
do {
...
} while (true);
Well, I think you should move the condition to the middle of the loop(?):
while (true)
{
...
// Insert at favorite position
if (condition)
break;
...
}
Technically, yes:
for ( ;CodeBefore, Condition; ) {CodeAfter}
The answer is no, you can't have your loop automatically terminate when the condition that the while statement is supposed to evaluate is true until it actually evaluates it at the top (or bottom) of the loop. The while statement can't be placed in the middle of the loop.
A variation on Dahl's loop that does not involve a goto into the middle of a do-while() is to use a switch-default:
switch (0) do {
// some more code
default:
// some code
} while (expression);