For vs. while in C programming?
Solution 1:
A while loop will always evaluate the condition first.
while (condition) {
//gets executed after condition is checked
}
A do/while loop will always execute
the code in the do{}
block first
and then evaluate the condition.
do {
//gets executed at least once
} while (condition);
A for loop allows you to initiate a counter variable, a check condition, and a way to increment your counter all in one line.
for (int x = 0; x < 100; x++) {
//executed until x >= 100
}
At the end of the day, they are all still loops, but they offer some flexibility as to how they are executed.
Here is a great explanation of the reasoning behind the use of each different type of loop that may help clear things up. Thanks clyfe
The main difference between the
for
's and thewhile
's is a matter of pragmatics: we usually usefor
when there is a known number of iterations, and usewhile
constructs when the number of iterations in not known in advance. Thewhile
vsdo ... while
issue is also of pragmatics, the second executes the instructions once at start, and afterwards it behaves just like the simple while.
For loops are especially nice because they are concise. In order for this for loop:
for (int x = 0; x < 100; x++) {
//executed until x >= 100
}
to be written as a while loop, you'd have to do the following:
int count = 0;
while (count < 100) {
//do stuff
count++;
}
In this case, there's just more stuff to keep up with and the count++;
could get lost in the logic. This could end up being troublesome depending on where count
gets incremented, and whether or not it should get incremented before or after the loop's logic. With a for
loop, your counter variable is always incremented before the next iteration of the loop, which adds some uniformity to your code.
For the sake of completeness, it's probably meaningful to talk about break
and continue
statements here which come in handy when doing loop processing.
break will instantly terminate the current loop and no more iterations will be executed.
//will only run "do stuff" twice
for (int x = 0; x < 100; x++) {
if (x == 2) {
break;
}
//do stuff
}
continue will terminate the current iteration and move on to the next one.
//will run "do stuff" until x >= 100 except for when x = 2
for (int x = 0; x < 100; x++) {
if (x == 2) {
continue;
}
//do stuff
}
Note that in a for loop, continue
evaluates the part3
expression of for (part1; part2; part3)
; in contrast, in a while loop, it just jumps to re-evaluate the loop condition.
Solution 2:
If there is a strong concern about speed and performance, the best approach is to verify the code produced by the compiler at the assembly level.
For instance, the following code shows that the "do-while" is a bit faster. This because the "jmp" instruction is not used by the "do-while" loop.
BTW, in this specific example, the worst case is given by the "for" loop. :))
int main(int argc, char* argv[])
{
int i;
char x[100];
// "FOR" LOOP:
for (i=0; i<100; i++ )
{
x[i] = 0;
}
// "WHILE" LOOP:
i = 0;
while (i<100 )
{
x[i++] = 0;
}
// "DO-WHILE" LOOP:
i = 0;
do
{
x[i++] = 0;
}
while (i<100);
return 0;
}
// "FOR" LOOP:
010013C8 mov dword ptr [ebp-0Ch],0
010013CF jmp wmain+3Ah (10013DAh)
for (i=0; i<100; i++ )
{
x[i] = 0;
010013D1 mov eax,dword ptr [ebp-0Ch] <<< UPDATE i
010013D4 add eax,1
010013D7 mov dword ptr [ebp-0Ch],eax
010013DA cmp dword ptr [ebp-0Ch],64h <<< TEST
010013DE jge wmain+4Ah (10013EAh) <<< COND JUMP
010013E0 mov eax,dword ptr [ebp-0Ch] <<< DO THE JOB..
010013E3 mov byte ptr [ebp+eax-78h],0
010013E8 jmp wmain+31h (10013D1h) <<< UNCOND JUMP
}
// "WHILE" LOOP:
i = 0;
010013EA mov dword ptr [ebp-0Ch],0
while (i<100 )
{
x[i++] = 0;
010013F1 cmp dword ptr [ebp-0Ch],64h <<< TEST
010013F5 jge wmain+6Ah (100140Ah) <<< COND JUMP
010013F7 mov eax,dword ptr [ebp-0Ch] <<< DO THE JOB..
010013FA mov byte ptr [ebp+eax-78h],0
010013FF mov ecx,dword ptr [ebp-0Ch] <<< UPDATE i
01001402 add ecx,1
01001405 mov dword ptr [ebp-0Ch],ecx
01001408 jmp wmain+51h (10013F1h) <<< UNCOND JUMP
}
// "DO-WHILE" LOOP:
i = 0;
. 0100140A mov dword ptr [ebp-0Ch],0
do
{
x[i++] = 0;
01001411 mov eax,dword ptr [ebp-0Ch] <<< DO THE JOB..
01001414 mov byte ptr [ebp+eax-78h],0
01001419 mov ecx,dword ptr [ebp-0Ch] <<< UPDATE i
0100141C add ecx,1
0100141F mov dword ptr [ebp-0Ch],ecx
01001422 cmp dword ptr [ebp-0Ch],64h <<< TEST
01001426 jl wmain+71h (1001411h) <<< COND JUMP
}
while (i<100);
Solution 3:
For the sake of readability
Solution 4:
They're all interchangeable; you could pick one type and use nothing but that forever, but usually one is more convenient for a given task. It's like saying "why have switch, you can just use a bunch of if statements" -- true, but if it's a common pattern to check a variable for a set of values, it's convenient and much easier to read if there's a language feature to do that
Solution 5:
If you want a loop to execute while a condition is true, and not for a certain number of iterations, it is much easier for someone else to understand:
while (cond_true)
than something like this:
for (; cond_true ; )