Вложенные операторы 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 {
// Делается еще что-то
}

Чтобы избежать этого:

  1. Вложенность уменьшается ранними return.
  2. Где возможно, условия комбинируются.
  3. Сложная логика выводится в отдельные функции.

Вот доработанная версия примера проверки ввода:

#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++ для сложных процессов принятия решений.

Эффективно его используя, избегая типичных ошибок и умело применяя альтернативы, вы сможете написать более чистый и сопровождаемый код.

Попробуйте реализовать рассмотренных выше примеры и не бойтесь экспериментировать с различными подходами к решению сложных задач.

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

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


Перевод статьи ryan: Nested If-Else Statements in C++: Comprehensive Guide

Предыдущая статьяСоздание многофункционального калькулятора на чистом JavaScript
Следующая статьяРеализация бесконечной прокрутки списка новостей в приложении TrendNow. Часть 4