Rozważ przypadek, w którym chcemy aby pokazać użytkownikowi menu i poprosić o dokonanie wyboru — a jeśli użytkownik wybierze nieprawidłowy wybór, zapytać go ponownie. Jasne jest, że menu i wybór powinny wejść w pewnego rodzaju pętlę (abyśmy mogli pytać użytkownika, dopóki nie wprowadzi prawidłowych danych), ale jaki rodzaj pętli powinniśmy wybrać?
Ponieważ pętla while ocenia warunek z góry, jest to niewygodny wybór. Moglibyśmy rozwiązać ten problem w ten sposób:
#include <iostream>
int main()
{
// selection must be declared outside while-loop, so we can use it later
int selection {}; // value initialized to 0
while (selection < 1 || selection > 4)
{
std::cout << "Please make a selection: \n";
std::cout << "1) Addition\n";
std::cout << "2) Subtraction\n";
std::cout << "3) Multiplication\n";
std::cout << "4) Division\n";
std::cin >> selection;
}
// do something with selection here
// such as a switch statement
std::cout << "You selected option #" << selection << '\n';
return 0;
}Ale to działa tylko dlatego, że nasza wartość początkowa 0 for selection nie znajduje się w zbiorze prawidłowych wartości (1, 2, 3 or 4). A co jeśli 0 był słusznym wyborem? Musielibyśmy wybrać inny inicjator reprezentujący „nieprawidłowy” -- a teraz wprowadzamy magiczne liczby (5.2 -- Literały) do naszego kodu.
Moglibyśmy zamiast tego dodać nową zmienną do śledzenia ważności, na przykład:
#include <iostream>
int main()
{
int selection {};
bool invalid { true }; // new variable just to gate the loop
while (invalid)
{
std::cout << "Please make a selection: \n";
std::cout << "1) Addition\n";
std::cout << "2) Subtraction\n";
std::cout << "3) Multiplication\n";
std::cout << "4) Division\n";
std::cin >> selection;
invalid = (selection < 1 || selection > 4);
}
// do something with selection here
// such as a switch statement
std::cout << "You selected option #" << selection << '\n';
return 0;
}Chociaż pozwala to uniknąć liczby magicznej, wprowadza nową zmienną, aby zapewnić jednokrotne wykonanie pętli, co zwiększa złożoność i możliwość dodatkowych błędy.
Instrukcje Do while
Aby pomóc w rozwiązaniu problemów takich jak powyższe, C++ oferuje instrukcję do while:
do
statement; // can be a single statement or a compound statement
while (condition);
A do while Instrukcja jest konstrukcją pętlową, która działa podobnie jak pętla while, z tą różnicą, że instrukcja jest zawsze wykonywana co najmniej raz. Po wykonaniu instrukcji pętla do while sprawdza warunek. Jeśli warunek ma wartość true, ścieżka wykonania przeskakuje z powrotem na początek pętli do-while i wykonuje ją ponownie.
Oto nasz przykład z użyciem pętli do-while zamiast pętli while:
#include <iostream>
int main()
{
// selection must be declared outside of the do-while-loop, so we can use it later
int selection {};
do
{
std::cout << "Please make a selection: \n";
std::cout << "1) Addition\n";
std::cout << "2) Subtraction\n";
std::cout << "3) Multiplication\n";
std::cout << "4) Division\n";
std::cin >> selection;
}
while (selection < 1 || selection > 4);
// do something with selection here
// such as a switch statement
std::cout << "You selected option #" << selection << '\n';
return 0;
}W ten sposób uniknęliśmy zarówno magicznych liczb, jak i dodatkowych zmiennych.
Jedyna rzecz, którą warto omówić w powyższym przykładzie, to to, że zmienna selection musi być zadeklarowana poza blokiem do. Jeżeli zmienna selection została zadeklarowana wewnątrz bloku do, zostałaby zniszczona po zakończeniu bloku do, co ma miejsce przed oceną warunku. Potrzebujemy jednak zmiennej w warunku while -- w związku z tym zmienna selection musi być zadeklarowana poza blokiem do (nawet jeśli nie została później użyta w treści funkcji).
W praktyce pętle do-while nie są powszechnie używane. Posiadanie warunku na końcu pętli przesłania warunek pętli, co może prowadzić do błędów. W rezultacie wielu programistów zaleca całkowite unikanie pętli do-while. Zajmiemy łagodniejsze stanowisko i będziemy opowiadać się za preferowaniem pętli while zamiast do-while, gdy mamy równy wybór.
Najlepsza praktyka
Preferujemy pętle while zamiast do-while, gdy mamy równy wybór.

