Принятие решений с помощью if
Программы постоянно реагируют на данные: сдал или не сдал, есть в наличии или распродано, действительно или нет. Оператор if — это то, как C++ выбирает, какой код выполнить, исходя из условия.
if принимает условие в круглых скобках и выполняет блок в фигурных скобках только тогда, когда это условие истинно:
Условие score >= 60 истинно, поэтому сообщение выводится. Строка после закрывающей фигурной скобки выполняется всегда — она находится вне if. Измените score на 40, и строка «passed» будет полностью пропущена.
Условие преобразуется в bool. Сравнения вроде >, >=, ==, != уже дают bool, но C++ также считает любое ненулевое число истинным, а 0 — ложным, так что if (count) означает «если count не равно нулю». Это неявное преобразование удобно, но также является источником нескольких классических ошибок, которые вы увидите ниже.
Добавление else
else даёт вам путь «иначе» — код, который выполняется только тогда, когда условие ложно:
Выполняется ровно один из двух блоков — никогда оба и никогда ни один. У else нет собственного условия; он просто перехватывает всё, что не перехватил if.
Цепочки с помощью else if
Когда исходов больше двух, выстраивайте цепочку условий с помощью else if. C++ проверяет их сверху вниз и выполняет первый блок, условие которого истинно, а затем пропускает остальные:
Порядок имеет значение. Поскольку 84 сначала проверяется на >= 90 (ложь), а затем на >= 80 (истина), он останавливается на B и никогда не проверяет нижние границы. Именно поэтому вам не нужно score >= 80 && score < 90 — достижение второй ветви уже гарантирует, что score был меньше 90. Ставьте самое узкое или наиболее приоритетное условие первым.
Обратите внимание, что в C++ нет ключевого слова elif — else if — это буквально else, телом которого является другой if. Фигурные скобки просто делают так, что это читается как одна лесенка.
Большая ловушка: = против ==
Самая распространённая ошибка в операторе if в C и C++ — написать = (присваивание) там, где имелось в виду == (сравнение):
x = 5 присваивает 5 переменной x, и всё выражение вычисляется в 5, которое преобразуется в true — поэтому ветвь выполняется всегда, и вы незаметно затёрли x. Это компилируется; большинство компиляторов выдают лишь предупреждение. Две меры защиты: включите предупреждения (-Wall), чтобы компилятор это пометил, и подумайте о том, чтобы ставить константу впереди — if (5 == x) — потому что if (5 = x) — это серьёзная ошибка, которую компилятор ловит сразу.
Та же ловушка скрывается с bool: if (ready = true) компилируется и присваивает, тогда как if (ready == true) (или просто if (ready)) сравнивает.
Комбинирование и вложение условий
Комбинируйте условия с помощью && (и), || (или) и ! (не) или вкладывайте один if в другой, когда проверка имеет смысл только после прохождения предыдущей:
&& и || вычисляются по короткой схеме: в a && b, если a ложно, C++ никогда не вычисляет b. Это критически важно для защиты от некорректного доступа к памяти — if (ptr != nullptr && ptr->ready) безопасно, потому что разыменование пропускается, когда ptr равен null. По возможности предпочитайте уплощение с помощью && глубокой вложенности; плоское условие читается яснее, чем пирамида из фигурных скобок.
Остерегайтесь цепочек сравнений, которые означают не то, на что похожи: if (0 < x < 10) не проверяет диапазон. Оно вычисляет 0 < x в bool (0 или 1), а затем сравнивает это с 10 — всегда истина. Вместо этого пишите if (0 < x && x < 10).
Тернарный оператор
Когда всё, что вам нужно, — это выбрать между двумя значениями, тернарный оператор ?: — компактная однострочная конструкция. Читайте condition ? a : b как «если условие, то a, иначе b»:
Тернарный оператор возвращает значение, которое можно присвоить, передать или вывести напрямую — то, что обычный if сделать не может. Приберегите его для простого выбора: если какой-либо ветви нужно несколько операторов или настоящая логика, полный if-else остаётся читаемым там, где вложенный тернарный оператор быстро превращается в головоломку. (Одна тонкость: обе ветви должны иметь общий тип, поэтому не смешивайте, скажем, string и int.)
if с инициализатором (C++17)
Начиная с C++17 вы можете объявить переменную прямо внутри if с областью видимости, ограниченной if/else. Это не даёт короткоживущим вспомогательным переменным просачиваться в окружающий код:
Часть до ; выполняется один раз, и её результат виден как в условии, так и в else. Это отлично подходит для шаблонов «вычислить нечто, а затем ветвиться по этому» — и поскольку преобразование результата происходит один раз заранее, вы избегаете повторных вычислений или случайного использования устаревшего значения позже. Прибегайте к этому всякий раз, когда временная переменная нужна только для ветвления.
Ловушка: проблема висячей скобки
C++ позволяет опускать фигурные скобки, когда в ветви один оператор, но это провоцирует тонкую ошибку — отступ лжёт:
if (loggedIn)
cout << "Welcome\n";
cout << "Loading dashboard\n"; // НЕ является частью if!
Только первая строка управляется if; вторая выполняется всегда, независимо от loggedIn, несмотря на то что отступ намекает на иное. Связанная классика — лишняя точка с запятой: if (x > 0); завершает if с пустым телом, поэтому следующий за ним блок выполняется безусловно. Всегда используйте фигурные скобки — даже для одной строки — и большая часть ошибок этого класса исчезает.
Далее: switch
Цепочки if-else if идеальны, когда каждая ветвь проверяет своё условие. Но когда вы сравниваете одно значение со множеством фиксированных вариантов — выбор в меню, перечисление, код состояния — длинная лесенка else if становится повторяющейся и легко перепутать порядок. Оператор switch создан именно для этого, и о нём следующая страница.
Часто задаваемые вопросы
Как написать оператор if-else в C++?
Поместите условие в круглые скобки после if, код для выполнения в фигурные скобки и необязательный блок else на случай, когда условие ложно: if (score >= 60) { cout << "Pass"; } else { cout << "Fail"; }. Условие преобразуется в bool, поэтому любое ненулевое число считается истинным, а 0 — ложным.
В чём разница между = и == в операторе if в C++?
== сравнивает два значения на равенство, а одиночное = присваивает. Запись if (x = 5) присваивает 5 переменной x, а затем проверяет 5 (всегда истина) — классическая ошибка. Она компилируется лишь с предупреждением, поэтому включите предупреждения и подумайте о том, чтобы писать константу первой: if (5 == x).
Что такое тернарный оператор в C++?
Тернарный оператор condition ? valueIfTrue : valueIfFalse — это компактный if-else, который возвращает значение. Например, string label = age >= 18 ? "adult" : "minor"; выбирает одно из двух значений. Используйте его для простого выбора значения; прибегайте к полному if-else, когда в каждой ветви есть настоящая логика.