Циклы while  —  фундаментальные строительные блоки программирования на C++. Рассмотрим их практическое применение с четкими примерами и реальными сценариями.

Базовый синтаксис цикла while

Начнем со структуры цикла:

#include <iostream>

int main() {
int count = 0;

while (count < 5) {
std::cout << count << " ";
count++;
}
std::cout << std::endl;
// Вывод: 0 1 2 3 4

return 0;
}

Цикл продолжается, пока условие count < 5 не становится true. На каждой итерации выводится текущее значение и увеличивается счетчик.

Проверка ввода циклами while

Циклы while отлично справляются с проверкой ввода:

#include <iostream>

int getValidAge() {
int age;

while (true) {
std::cout << "Enter age (0-120): ";
std::cin >> age;

if (std::cin.fail()) {
std::cin.clear();
std::cin.ignore(10000, '\n');
std::cout << "Invalid input. Please enter a number.\n";
continue;
}

if (age >= 0 && age <= 120) {
break;
}

std::cout << "Age must be between 0 and 120.\n";
}

return age;
}

int main() {
int userAge = getValidAge();
std::cout << "Valid age entered: " << userAge << std::endl;
return 0;
}

В этом примере показано, как обрабатываются недопустимые типы вводимых данных и значения вне допустимого диапазона.

Обработка файлов циклами while

Вот как циклом while построчно считывается файл:

#include <iostream>
#include <fstream>
#include <string>

int countWords(const std::string& filename) {
std::ifstream file(filename);
std::string word;
int wordCount = 0;

if (!file.is_open()) {
std::cerr << "Error opening file: " << filename << std::endl;
return -1;
}

while (file >> word) {
wordCount++;
}

file.close();
return wordCount;
}

int main() {
std::string filename = "sample.txt";
int words = countWords(filename);

if (words >= 0) {
std::cout << "Word count: " << words << std::endl;
}

return 0;
}

Программы, управляемые из меню

Циклы while идеальны для создания интерактивных меню:

#include <iostream>
#include <string>

class Calculator {
private:
double result;

public:
Calculator() : result(0) {}

void showMenu() {
std::cout << "\nCurrent value: " << result << std::endl;
std::cout << "1. Add\n";
std::cout << "2. Subtract\n";
std::cout << "3. Multiply\n";
std::cout << "4. Divide\n";
std::cout << "5. Clear\n";
std::cout << "6. Exit\n";
}

void run() {
int choice;
double number;

while (true) {
showMenu();
std::cout << "Enter choice (1-6): ";

if (!(std::cin >> choice)) {
std::cin.clear();
std::cin.ignore(10000, '\n');
std::cout << "Invalid input\n";
continue;
}

if (choice == 6) break;

switch (choice) {
case 1:
std::cout << "Enter number to add: ";
std::cin >> number;
result += number;
break;

case 2:
std::cout << "Enter number to subtract: ";
std::cin >> number;
result -= number;
break;

case 3:
std::cout << "Enter number to multiply by: ";
std::cin >> number;
result *= number;
break;

case 4:
std::cout << "Enter number to divide by: ";
std::cin >> number;
if (number != 0) {
result /= number;
} else {
std::cout << "Cannot divide by zero\n";
}
break;

case 5:
result = 0;
break;

default:
std::cout << "Invalid choice\n";
}
}
}
};

int main() {
Calculator calc;
calc.run();
return 0;
}

Пример из геймдева

Циклы while важны в разработке игр. Вот простая игра на угадывание чисел:

#include <iostream>
#include <random>
#include <chrono>

class NumberGame {
private:
int targetNumber;
int attempts;
int maxAttempts;

int generateRandomNumber(int min, int max) {
auto seed = std::chrono::steady_clock::now().time_since_epoch().count();
std::default_random_engine generator(seed);
std::uniform_int_distribution<int> distribution(min, max);
return distribution(generator);
}

public:
NumberGame(int max = 100, int maxTries = 7)
: maxAttempts(maxTries), attempts(0) {
targetNumber = generateRandomNumber(1, max);
}

void play() {
int guess;
bool won = false;

std::cout << "Guess a number between 1 and 100\n";

while (attempts < maxAttempts) {
std::cout << "\nAttempts left: " << (maxAttempts - attempts) << std::endl;
std::cout << "Enter your guess: ";

if (!(std::cin >> guess)) {
std::cin.clear();
std::cin.ignore(10000, '\n');
std::cout << "Please enter a valid number\n";
continue;
}

attempts++;

if (guess == targetNumber) {
won = true;
break;
} else if (guess < targetNumber) {
std::cout << "Too low!\n";
} else {
std::cout << "Too high!\n";
}
}

if (won) {
std::cout << "\nCongratulations! You won in " << attempts << " attempts!\n";
} else {
std::cout << "\nGame Over! The number was: " << targetNumber << std::endl;
}
}
};

int main() {
NumberGame game;
game.play();
return 0;
}Data Processing with While Loops

Вот пример обработки числовых данных, пока не введено контрольное значение:

#include <iostream>
#include <vector>
#include <numeric>

class DataAnalyzer {
private:
std::vector<double> numbers;

public:
void inputData() {
double num;
std::cout << "Enter numbers (-1 to stop):\n";

while (true) {
if (!(std::cin >> num)) {
std::cin.clear();
std::cin.ignore(10000, '\n');
std::cout << "Invalid input. Please enter a number.\n";
continue;
}

if (num == -1) break;
numbers.push_back(num);
}
}

void showStats() {
if (numbers.empty()) {
std::cout << "No data entered.\n";
return;
}

double sum = std::accumulate(numbers.begin(), numbers.end(), 0.0);
double mean = sum / numbers.size();

double max = numbers[0];
double min = numbers[0];

for (double num : numbers) {
if (num > max) max = num;
if (num < min) min = num;
}

std::cout << "\nStatistics:\n";
std::cout << "Count: " << numbers.size() << std::endl;
std::cout << "Sum: " << sum << std::endl;
std::cout << "Mean: " << mean << std::endl;
std::cout << "Min: " << min << std::endl;
std::cout << "Max: " << max << std::endl;
}
};

int main() {
DataAnalyzer analyzer;
analyzer.inputData();
analyzer.showStats();
return 0;
}

Альтернатива в виде цикла do-while

Иногда предпочтительнее цикл do-while:

#include <iostream>
#include <string>

std::string getPassword() {
std::string password;

do {
std::cout << "Enter a password (minimum 8 characters): ";
std::getline(std::cin, password);
} while (password.length() < 8);

return password;
}

int main() {
std::string password = getPassword();
std::cout << "Valid password set!\n";
return 0;
}

Циклом do-while гарантируется минимум одно выполнение тела цикла.

Заключение

Циклы while необходимы в программировании на C++. Особенно кстати они приходятся для:

  1. Проверки ввода.
  2. Обработки файлов.
  3. Программ, управляемых из меню.
  4. Разработки игр.
  5. Обработки данных.
  6. Взаимодействия с пользователями.

Обобщим ключевые моменты:

  1. Всегда указывайте способ выхода из цикла.
  2. Корректно обрабатывайте недопустимые входные данные.
  3. Когда требуется минимум одна итерация, воспользуйтесь do-while.
  4. Применяйте простое и понятное условие цикла.
  5. Используйте пригодные названия переменных и четкую логику.

Читайте также:

Читайте нас в Telegram, VK и Дзен


Перевод статьи ryan: C++ While Loops: Comprehensive Guide

Предыдущая статьяКак поразить интервьюеров умением инспектировать App Bundle
Следующая статьяКак мы создавали автоматизированное тестирование с помощью Playwright