0

Why there is a need of 3 different loops : "while", "do-while", and "for" to exist in c/c++, especially when each of them gives you power to do almost anything that the other 2 can do? Other languages lack one or the other.

Is it just for ease of use or to make the code look better in cases, or are there any special purposes that are served by any one of them specifically that can't be accomplished so easily with the other two? If yes, then please mention.

P.S. - In general, do a language support many iteration syntax just to enhance readability?

Piyush Deshmukh
  • 519
  • 1
  • 7
  • 14
  • 1
    Most of the loops can be done with `goto` as well, why not remove all the loop statements? The same reason. – Yu Hao Sep 20 '14 at 04:49
  • 1
    As for other languages, most of the languages I know of have these 3 loop structures, even more, like `repeat .. until`. – Yu Hao Sep 20 '14 at 04:53
  • imo putting `goto` in your code is good unless you are not working in a team. If someone who reads your code encounters a `goto` statement, then he needs to search whole program for where the label is placed, which may not be feasible in large programs! That's why its better to avoid using goto. – Piyush Deshmukh Sep 20 '14 at 04:54
  • That's my point. If you convert a loop like `for (int i = 0; i < 42; i++)` to a equivalent `while` loop, it's less readable, that's enough reason that `for` exists. – Yu Hao Sep 20 '14 at 04:57
  • @qwerty if you aren't using goto, you are going to end up with bug-prone error handling in C. – Cory Nelson Sep 20 '14 at 04:57
  • @CoryNelson , can you please elaborate? – Piyush Deshmukh Sep 20 '14 at 04:58
  • @qwerty see http://stackoverflow.com/q/788903/209199 – Cory Nelson Sep 20 '14 at 05:01
  • Just to answer the C++ part of the question: It was done for compatibility with C. – Ulrich Eckhardt Sep 20 '14 at 06:36
  • @CoryNelson, okay that may be the reason why things like `goto` should remain in a language, I just meant to ask why many types of syntax to perform a single job(iteration here)? – Piyush Deshmukh Sep 20 '14 at 09:02

4 Answers4

2

It's not just readability, it's also the closely-related but distinct maintainability, and concision, and scoping (esp. for files, locks, smart pointers etc.), and performance....

If we consider the for loop, it:

  • allows some variables to be defined - in the for loop's own scope - and initialised,

  • tests a control expression before entering the loop each time (including the first), and

  • has a statement that gets executed after each iteration and before re-testing the control expression, assuming no break/return/throw/exit/failed assert etc., and regardless of whether the last statement in the body executed or whether a continue statement executed; this statement is traditionally reserved for logically "advancing" some state "through" the processing, such that the next test of the control expression is meaningful.

That's very flexible and given the utility of more localised scopes to ensure earlier destructor invocation, can help ensure locks, files, memory etc. are released as early as possible - implicitly when leaving the loop.

If we consider a while loop...

while (expression to test)
    ...

...it's functionally exactly equivalent to...

for ( ; expression to test; )
    ...

...but, it also implies to the programmer that there are no control variables that should be local to the loop, and that either the control "expression to test" inherently "progresses" through a finite number of iterations, loops forever if the test expression is hardcoded true, or more complicated management of "progress" had to bed itself controlled and coordinated by the statements the while controls.

In other words, a programmer seeing while is automatically aware that they need to study the control expression more carefully, then possibly look more widely at both the surrounding scope/function and the contained statements, to understand the loop behaviour.

So, do-while? Well, writing code like this is painful and less efficient:

bool first_time = true;
while (first_time || ...)
{
    first_time = false;
    ...
}
// oops... first_time still hanging around...

...compared to...

do
    ...
while (...);

Examples

While loop:

int i = 23;
while (i < 99)
{
    if (f(i)) { ++i; continue; }
    if (g(i)) break;
    ++i;
}
// oops... i is hanging around

For loop:

for (int i = 23; i < 99; ++i)
{
    if (f(i)) continue;
    if (g(i)) break;
}
Tony Delroy
  • 102,968
  • 15
  • 177
  • 252
0

Well, C++ has goto and you can use it to implement all three loops, but it doesn't mean that they should be removed. Actually it just increases readability. Of course you could implement any of them yourself.

justanothercoder
  • 1,830
  • 1
  • 16
  • 27
0

Some loops are easiest to write using for, some are easiest to write using while, and some are easiest to write using do-while. So the language provides all three.

We have things things like the += operator for the same reason; += doesn't do anything that you can't do with plain +, but using it (where appropriate) can make your code a bit more readable.

Wyzard
  • 33,849
  • 3
  • 67
  • 87
0

In general, when presented with different language constructs that accomplish similar purposes, you should choose the one that more clearly communicates the intended purpose of the code you are writing. It is a benefit that C provides four distinct structured iteration devices to use, as it provides a high chance you can clearly communicate the intended purpose.

for ( initialization ; condition ; iteration-step ) body

This form communicates how the loop will start, how it will adjust things for the next iteration, and what is the condition to stay within the loop. This construct lends itself naturally for doing something N times.

    for (int i = 0; i < N; ++i) {
        /* ... */
    }

while ( condition ) body

This form communicates simply that you wish to continue to perform the loop while the condition remains true. For loops where the iteration-step is implicit to the way the loop works, it can be a more natural way to communicate the intention of the code:

    while (std::cin >> word) {
        /* ... */
    }

do body while ( condition )

This form communicates that the loop body will execute at least once, and then continues while the condition remains true. This is useful for situations where you have already determined that you need to execute the body, so you avoid a redundant looking test.

    if (count > 0) {
        do {
            /* ... */
        } while (--count > 0);
    } else {
        puts("nothing to do");
    }

The fourth iteration device is ... recursion!

Recursion is another form of iteration that expresses that the same function can be used to work on a smaller part of the original problem. It is a natural way to express a divide and conquer strategy to a problem (like binary searching, or sorting), or to work on data structures that self-referential (such as lists or trees).

struct node {
    struct node *next;
    char name[32];
    char info[256];
};

struct node * find (struct node *list, char *name)
{
    if (list == NULL || strcmp(name, list->name) == 0) {
        return list;
    }
    return find(list->next, name);
}
jxh
  • 69,070
  • 8
  • 110
  • 193