Do-while-loops are similar to do-loops, but they evaluate the test expression at the bottom or end of the loop after executing the loop body. Some programmers use the shorter name do-loop (without the "-while" part). However, those of us with previous careers as FORTRAN programmers prefer a different name, reserving "do loop" for a FORTRAN control statement more reminiscent of C++'s for-loop.
The do-while-loop syntax is a bit more complex than the while-loop but is still relatively simple. Unlike the previous loops, the syntax consists of two keywords - do and while - plus the test expression placed between parentheses. A do-while-loop runs while the test expression evaluates to true or non-zero. The following figure illustrates the basic pattern of the do-while-loop and its logical behavior:
do
{
statement;
} while (test);
do
{
statement1;
. . .
statement-n;
} while (test);
(a)
(b)
(c)
Basic do-while-loop behavior.
Do-while-loops are a test at the bottom loop, implying that the program reaches and runs the loop body before evaluating the loop test. This sequence implies that the loop body is guaranteed to execute at least once. Do-while-loops are useful when the loop test depends on a value calculated or input in the loop's body. The loop continues while the test evaluates to true or non-zero.
A single-statement do-while-loop. Although the C++ syntax doesn't require the braces, programmers typically include them. Some put the open brace on the same line as the do keyword, and some put the closing brace alone on a line with while below it
A do-while-loop with a compound or block statement
A logic diagram of the do-while-loop
The semicolon, displayed in red, is required.
int count = 10;
do
cout << count-- << endl;
while (count > 0);
int count = 10;
do
cout << count << endl;
count--;
while (count > 0);
do
{
int count = 10;
cout << count-- << endl;
}
while (count > 0);
(a)
(b)
(c)
do-while-loop formatting and scope.
The braces are not strictly required when the loop contains only a single statement. Unlike for- and do-loops, we typically use them because they make the code easier to read by setting the body apart from the two keywords. Furthermore, single-statement bodies are rare with the problems we typically solve with do-while-loops.
It is a syntax error to write multiple statements between the do and while keywords without using braces.
A scoping error: The variable count is defined inside the loop body (a block), goes out of scope when control moves past the closing brace, so it is not in scope for the while test.
Examples
int i = 100;
do
{
cout << i << " ";
i++;
} while (i <= 110);
int i = 100;
do
{
cout << i << " ";
i++;
} while (i <= 10);
100 101 102 103 104 105 106 107 108 109 110
100
Simple do-while-loop examples. Although we could implement these examples more compactly with determinant (i.e., for-) loops, they illustrate the syntax and behavior of do-while-loops if not their typical use.
The program initializes the variable i 100, the output statement runs before the increment takes place, and the test uses <=. So, the loop displays 100 up to 110.
In this example, the test is never true. Nevertheless, the loop outputs one value because the do-while-loop is a test at the bottom loop: the test terminating the loop occurs after the loop-body runs.
While-Loops vs. Do-While-Loops
While-loops are a good choice if all the data needed by the test are available when the loop begins. Alternatively, do-while-loops are useful when at least some test data originates in the loop body, making the data unavailable for testing when the loop begins.
do-while-loop
while-loop
char choice;
do
{
. . . .
choice = ...;
. . . .
} while (choice != 'E');
Data availability determines loop organization. Programmers have a choice when the data needed by the loop test is unavailable when program control enters the loop: they can use a do-while-loop or a slightly more complex logic.
The loop test depends on data entered in the loop's body, forcing programmers to delay the test.
Programmers can still use a do-loop but must provide a "dummy" value to satisfy the loop test before the control enters the loop.