Ready to practice?
Sign up to access interactive coding exercises and track your progress.
Post-Test Loops with Do-While
Execute loop body at least once before checking the continuation condition.
When the body must run first
Some tasks need to happen at least once before you can decide whether to continue. Consider a password prompt:
#include <iostream>
#include <string>
int main()
{
std::string password{};
// We must ask for the password before we can check it
std::cout << "Enter password: ";
std::getline(std::cin, password);
while (password != "secret123")
{
std::cout << "Incorrect. Try again: ";
std::getline(std::cin, password);
}
std::cout << "Access granted!\n";
return 0;
}
This works, but notice the duplication - we prompt and read input twice. Once before the loop and once inside. That's awkward and violates the DRY principle (Don't Repeat Yourself).
The do-while statement
C++ provides a loop that guarantees at least one execution before checking the condition:
do
statement;
while (condition);
The do-while statement executes its body first, then evaluates the condition. If true, it repeats. If false, the loop ends.
Here's the password example rewritten:
#include <iostream>
#include <string>
int main()
{
std::string password{};
do
{
std::cout << "Enter password: ";
std::getline(std::cin, password);
}
while (password != "secret123");
std::cout << "Access granted!\n";
return 0;
}
No duplication. The prompt and input happen once per attempt, and we naturally check afterward whether to continue.
Execution order
The key difference from while loops is when the condition gets checked:
While loop: condition -> body -> condition -> body -> ... Do-while loop: body -> condition -> body -> condition -> ...
This means a while loop might execute zero times (if the condition is initially false), but a do-while always executes at least once.
int count{ 0 };
while (count > 0) // Condition false immediately
{
std::cout << "While: " << count << '\n';
--count;
}
// Prints nothing
do
{
std::cout << "Do-while: " << count << '\n';
--count;
}
while (count > 0); // Condition checked after first execution
// Prints: Do-while: 0
Practical example: rolling dice
Games often need the player to roll until achieving a target. You must roll at least once before knowing the result:
#include <iostream>
#include <random>
int rollDie()
{
static std::mt19937 rng{ std::random_device{}() };
static std::uniform_int_distribution<int> dist{ 1, 6 };
return dist(rng);
}
int main()
{
int roll{};
int attempts{ 0 };
do
{
roll = rollDie();
++attempts;
std::cout << "Rolled: " << roll << '\n';
}
while (roll != 6);
std::cout << "Got a 6 after " << attempts << " attempts!\n";
return 0;
}
Output might be:
Rolled: 2
Rolled: 4
Rolled: 1
Rolled: 6
Got a 6 after 4 attempts!
You can't know whether you rolled a 6 until you actually roll. The do-while captures this "act then check" pattern naturally.
Variable scope matters
Variables declared inside the do block are destroyed before the condition is evaluated:
do
{
int value{ getValue() }; // Created here
process(value);
} // value destroyed here
while (value > 0); // Error: value doesn't exist!
Declare any variable needed in the condition outside the do block:
int value{}; // Declared outside
do
{
value = getValue();
process(value);
}
while (value > 0); // Works: value still exists
This differs from for loops, where the loop variable can be declared in the initialization and used in the condition.
Numeric input validation
Validating user input is a classic do-while use case:
#include <iostream>
int main()
{
int month{};
do
{
std::cout << "Enter month (1-12): ";
std::cin >> month;
if (month < 1 || month > 12)
std::cout << "Invalid month. ";
}
while (month < 1 || month > 12);
std::cout << "You selected month " << month << '\n';
return 0;
}
We must get input before we can validate it. The do-while handles this naturally.
The visibility concern
One criticism of do-while loops is that the condition appears at the bottom, making it less visible:
do
{
// 20 lines of code...
// ...
// ...
processData();
updateState();
// ...
}
while (shouldContinue()); // Easy to miss when scanning code
With a while loop, the condition is immediately visible at the top. Some developers avoid do-while entirely for this reason. Others use it sparingly for cases where it genuinely fits better.
Prefer while loops when either would work. Reserve do-while for cases where you genuinely need the body to execute before the first condition check.
Converting between while and do-while
Any do-while can be converted to a while by duplicating the body before the loop:
// Do-while version
do
{
promptAndRead();
}
while (!isValid());
// Equivalent while version
promptAndRead(); // Duplicated before loop
while (!isValid())
{
promptAndRead();
}
The do-while is cleaner when the body must run first. But if you can initialize your condition variable to a value that causes the loop to enter, a while loop works fine:
bool done{ false }; // Initialize to cause entry
while (!done)
{
// process...
done = checkIfDone();
}
Summary
- Do-while loops execute their body at least once, then check the condition
- Execution order is body -> condition -> body -> condition (unlike while's condition-first approach)
- Variable scope requires declaring condition-dependent variables outside the do block
- Common use cases include input validation and any "act then check" scenario
- Visibility concerns make do-while less popular since the condition is at the bottom
- Prefer while loops when given a choice; use do-while only when guaranteed first execution is genuinely needed
Post-Test Loops with Do-While - Quiz
Test your understanding of the lesson.
Practice Exercises
Input Validation Loop
Use a do-while loop to validate user input, ensuring at least one execution before checking the condition.
Lesson Discussion
Share your thoughts and questions
No comments yet. Be the first to share your thoughts!