Вложенные операторы if-else — важная часть программирования на C++, с ними разработчики создают сложные структуры принятия решений.
Изучим эффективное использование этих операторов, типичные ошибки и реальные сценарии.
Что такое «вложенный оператор If-Else»?
Это всего лишь оператор if-else внутри другого оператора if-else. Такой структурой где в определенном порядке проверяются многочисленные условия, обусловлены более сложные процессы принятия решений.
Вот простой пример:
#include <iostream>
int main() {
int x = 10;
int y = 20;
if (x > 0) {
if (y > 0) {
std::cout << "Both x and y are positive" << std::endl;
} else {
std::cout << "x is positive, but y is not" << std::endl;
}
} else {
std::cout << "x is not positive" << std::endl;
}
return 0;
}
Здесь сначала проверяется, положительно ли x. Если положительно, проверяется, положительно ли y. При такой вложенности создаются более конкретные условия и ответы.
Практические применения вложенного If-Else
Рассмотрим реальные сценарии, в которых вложенные операторы if-else приходятся особенно кстати.
Проверка ввода
Вложенными операторами if-else часто проверяются вводимые данные. Вот пример функции, в которой проверяются имя пользователя и пароль:
#include <iostream>
#include <string>
bool validateCredentials(const std::string& username, const std::string& password) {
if (username.length() >= 4) {
if (password.length() >= 8) {
if (password.find(username) == std::string::npos) {
return true;
} else {
std::cout << "Error: Password cannot contain username" << std::endl;
}
} else {
std::cout << "Error: Password must be at least 8 characters long" << std::endl;
}
} else {
std::cout << "Error: Username must be at least 4 characters long" << std::endl;
}
return false;
}
int main() {
std::string username, password;
std::cout << "Enter username: ";
std::cin >> username;
std::cout << "Enter password: ";
std::cin >> password;
if (validateCredentials(username, password)) {
std::cout << "Credentials are valid" << std::endl;
} else {
std::cout << "Credentials are invalid" << std::endl;
}
return 0;
}
Здесь вложенными операторами if-else проверяются условия: длина имени пользователя, длина пароля а также, содержится ли в пароле имя пользователя. На каждом уровне вложенности предоставляются более конкретные сообщения об ошибках.
Игровая логика
Вложенные операторы if-else часто используются при разработке игр, чтобы справляться со сложными игровыми состояниями. Вот простой пример if-else в текстовой приключенческой игре:
#include <iostream>
#include <string>
int main() {
std::string location = "forest";
std::string item = "";
std::string action;
std::cout << "You are in a forest. You see a cave ahead. What do you do? (enter/stay): ";
std::cin >> action;
if (action == "enter") {
location = "cave";
std::cout << "You enter the cave. It's dark. You see a torch and a sword. Which do you take? (torch/sword): ";
std::cin >> item;
if (item == "torch") {
std::cout << "You pick up the torch. The cave illuminates. You see a dragon sleeping. What do you do? (fight/sneak): ";
std::cin >> action;
if (action == "fight") {
std::cout << "You try to fight the dragon with a torch. It doesn't end well. Game Over." << std::endl;
} else if (action == "sneak") {
std::cout << "You sneak past the dragon and find a treasure chest. You win!" << std::endl;
} else {
std::cout << "Invalid action. The dragon wakes up. Game Over." << std::endl;
}
} else if (item == "sword") {
std::cout << "You pick up the sword. You stumble in the dark and alert the dragon. Game Over." << std::endl;
} else {
std::cout << "Invalid item. You stumble in the dark and fall into a pit. Game Over." << std::endl;
}
} else if (action == "stay") {
std::cout << "You stay in the forest. Nothing happens. Game Over." << std::endl;
} else {
std::cout << "Invalid action. A wild animal attacks you. Game Over." << std::endl;
}
return 0;
}
Так вложенными операторами if-else создается разветвленное повествование, основанное на выборе пользователя.
Типичные ошибки и как их избежать
Но при неосторожном использовании вложенные операторы if-else чреваты проблемами.
Антипаттерн «Стрелка»
Одна из типичных ошибок — антипаттерн «Стрелка», где чрезмерная вложенность чревата кодом, не удобным для восприятия и сопровождения:
if (condition1) {
if (condition2) {
if (condition3) {
// Что-то делается
} else {
// Делается что-то еще
}
} else {
// Делается что-то другое
}
} else {
// Делается еще что-то
}
Чтобы избежать этого:
- Вложенность уменьшается ранними
return. - Где возможно, условия комбинируются.
- Сложная логика выводится в отдельные функции.
Вот доработанная версия примера проверки ввода:
#include <iostream>
#include <string>
bool isValidUsername(const std::string& username) {
if (username.length() < 4) {
std::cout << "Error: Username must be at least 4 characters long" << std::endl;
return false;
}
return true;
}
bool isValidPassword(const std::string& password, const std::string& username) {
if (password.length() < 8) {
std::cout << "Error: Password must be at least 8 characters long" << std::endl;
return false;
}
if (password.find(username) != std::string::npos) {
std::cout << "Error: Password cannot contain username" << std::endl;
return false;
}
return true;
}
bool validateCredentials(const std::string& username, const std::string& password) {
return isValidUsername(username) && isValidPassword(password, username);
}
int main() {
std::string username, password;
std::cout << "Enter username: ";
std::cin >> username;
std::cout << "Enter password: ";
std::cin >> password;
if (validateCredentials(username, password)) {
std::cout << "Credentials are valid" << std::endl;
} else {
std::cout << "Credentials are invalid" << std::endl;
}
return 0;
}
Здесь вложенность уменьшается применением отдельных функций для проверки имени пользователя и пароля, отчего код становится более удобным для восприятия и сопровождения.
Упускаются из виду скобки
Другая типичная ошибка — отсутствие фигурных скобок в однострочных операторах if-else:
if (condition1)
if (condition2)
doSomething();
else
doSomethingElse();
В этом случае else ассоциируется с внутренним if. А что, если задумывалось ассоциировать его с внешним if? Чтобы сделать структуру понятной, всегда используйте фигурные скобки:
if (condition1) {
if (condition2) {
doSomething();
}
} else {
doSomethingElse();
}
Альтернативы вложенному If-Else
Вложенным операторам if-else часто находятся более понятные альтернативы для сложного принятия решений.
Операторы switch
В ситуациях, когда единственная переменная проверяется на соответствие многим значениям, оператор switch предпочтительнее:
#include <iostream>
int main() {
int dayNumber;
std::cout << "Enter a day number (1-7): ";
std::cin >> dayNumber;
switch (dayNumber) {
case 1:
std::cout << "Monday" << std::endl;
break;
case 2:
std::cout << "Tuesday" << std::endl;
break;
case 3:
std::cout << "Wednesday" << std::endl;
break;
case 4:
std::cout << "Thursday" << std::endl;
break;
case 5:
std::cout << "Friday" << std::endl;
break;
case 6:
std::cout << "Saturday" << std::endl;
break;
case 7:
std::cout << "Sunday" << std::endl;
break;
default:
std::cout << "Invalid day number" << std::endl;
}
return 0;
}
Таблицы поиска
Для сценариев посложнее, особенно с многочисленными условиями, воспользуйтесь таблицами поиска:
#include <iostream>
#include <map>
#include <string>
int main() {
std::map<std::string, std::string> fruitColors = {
{"apple", "red"},
{"banana", "yellow"},
{"grape", "purple"},
{"orange", "orange"},
{"kiwi", "brown"}
};
std::string fruit;
std::cout << "Enter a fruit name: ";
std::cin >> fruit;
auto it = fruitColors.find(fruit);
if (it != fruitColors.end()) {
std::cout << "A " << fruit << " is typically " << it->second << std::endl;
} else {
std::cout << "I don't know the color of that fruit" << std::endl;
}
return 0;
}
Такой подход эффективнее и проще в сопровождении, чем нескончаемая вереница операторов if-else.
Заключение
Вложенные операторы if-else — это фундаментальный инструмент программирования на C++ для сложных процессов принятия решений.
Эффективно его используя, избегая типичных ошибок и умело применяя альтернативы, вы сможете написать более чистый и сопровождаемый код.
Попробуйте реализовать рассмотренных выше примеры и не бойтесь экспериментировать с различными подходами к решению сложных задач.
Читайте также:
- C++: подробный разбор count_if
- Перестановка чисел в C++: руководство
- Создание RESTful API-интерфейсов на C++
Читайте нас в Telegram, VK и Дзен
Перевод статьи ryan: Nested If-Else Statements in C++: Comprehensive Guide





