Глиф Учебники

Урок 3. Условия: if, else и switch

Курс «C++» · урок 3 из 10 · 4 минуты чтения

До сих пор программы выполняли все команды подряд. Но часто нужно поступить по-разному: если число чётное — одно, если нечётное — другое. Для этого есть условия.

if и else

C++
#include <iostream>
using namespace std;

int main() {
    int n;
    cin >> n;
    if (n % 2 == 0) {
        cout << "even\n";
    } else {
        cout << "odd\n";
    }
    return 0;
}
Ввод
7
Вывод
odd

В круглых скобках после if — условие. Если оно истинно, выполняется блок в фигурных скобках сразу за ним, иначе — блок после else. Часть с else можно не писать: тогда при ложном условии программа просто идёт дальше.

cin >> n; ввод 7 n % 2 == 0 true cout << "even\n"; false 7 % 2 = 1 cout << "odd\n"; return 0; дальше по порядку
Для n = 7 условие n % 2 == 0 ложно (7 % 2 = 1), поэтому выполняется блок else и выводится odd, блок после if пропускается, а затем программа идёт дальше по порядку.

Сравнения

ЗаписьЗначение
a == bравно
a != bне равно
a < b, a > bменьше, больше
a <= b, a >= bменьше или равно, больше или равно

Результат сравнения — true или false (тип bool).

Равенство проверяется двумя знаками: ==. Один знак = — это присваивание. Запись if (x = 5) не сравнивает, а кладёт в x пятёрку, и условие всегда истинно. С ключом -Wall компилятор предупреждает об этом: suggest parentheses around assignment used as truth value.

Несколько вариантов: else if

Когда вариантов больше двух, условия ставят цепочкой. Они проверяются сверху вниз, и выполняется только первый подошедший блок:

C++
#include <iostream>
using namespace std;

int main() {
    int score;
    cin >> score;
    if (score >= 90) {
        cout << "excellent\n";
    } else if (score >= 70) {
        cout << "good\n";
    } else if (score >= 50) {
        cout << "pass\n";
    } else {
        cout << "fail\n";
    }
    return 0;
}
Ввод
75
Вывод
good

Для 75 первое условие ложно, второе истинно — выводится good, а остальные условия уже не проверяются. Порядок важен: если поставить score >= 50 первым, все от 50 до 100 получат pass.

score = 75 if (score >= 90) true excellent false 75 < 90 else if (score >= 70) true good дальше не проверяется else if (score >= 50) pass else fail что выводится
Условия цепочки проверяются сверху вниз: при score = 75 первое ложно, второе истинно — выводится good, а следующие условия и else уже не проверяются.

Логические операторы

Условия соединяются:

Классический пример — високосный год. Год високосный, если делится на 4, но не на 100, или если делится на 400:

C++
#include <iostream>
using namespace std;

int main() {
    int year;
    cin >> year;
    if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
        cout << "leap\n";
    } else {
        cout << "not leap\n";
    }
    return 0;
}
Ввод
1900
Вывод
not leap

1900 делится на 4 и на 100, но не на 400, поэтому он не високосный, а 2000 — високосный.

&& и || вычисляются сокращённо: если по левой части ответ уже ясен, правая не проверяется. Это удобно: if (b != 0 && a % b == 0) не поделит на ноль, потому что при b == 0 вторая часть не выполнится.

Запись 1 < x < 10 в C++ не значит «x между 1 и 10». Сначала считается 1 < x (это 0 или 1), и результат сравнивается с 10 — условие истинно при любом x. Пишите 1 < x && x < 10.

Фигурные скобки

Если в блоке одна команда, скобки можно не ставить: if (x < 0) x = -x;. Но лучше ставить всегда. Без них легко ошибиться, когда в блок потом добавляют вторую строку: под условием окажется только первая, хотя отступы будут говорить другое. Отступы для компилятора ничего не значат — важны только скобки.

switch

Когда одну переменную сравнивают с несколькими точными значениями, удобен switch:

C++
#include <iostream>
using namespace std;

int main() {
    int day;
    cin >> day;
    switch (day) {
        case 6:
        case 7:
            cout << "weekend\n";
            break;
        case 1:
            cout << "Monday\n";
            break;
        default:
            cout << "workday\n";
            break;
    }
    return 0;
}
Ввод
6
Вывод
weekend

case — вариант значения, default — все остальные. break выходит из switch. Если break забыть, выполнение «проваливается» в следующий case — так здесь нарочно сделано для 6 и 7, но чаще это ошибка.

switch (day) { case 6: case 7: cout << "weekend\n"; break; case 1: cout << "Monday\n"; break; default: cout << "workday\n"; break; } day = 6 в case 6 нет break — выполнение идёт вниз weekend break — выход после switch
При day = 6 switch сразу переходит к case 6; там нет ни команд, ни break, поэтому выполнение идёт вниз в case 7, выводит weekend, а break выходит из switch.

switch работает с целыми числами и символами (char); строки и дробные числа в нём сравнивать нельзя.

Тернарный оператор

Короткая запись «если — то — иначе», которая сама является значением: условие ? если_да : если_нет. «Тернарный» значит «из трёх частей»: условие и два варианта.

C++
#include <iostream>
using namespace std;

int main() {
    int a = 4, b = 9;
    int biggest = (a > b) ? a : b;
    cout << biggest << "\n";
    cout << (a % 2 == 0 ? "a is even" : "a is odd") << "\n";
    return 0;
}
Вывод
9
a is even

Для простых случаев это удобно, но вложенные тернарные операторы читаются плохо — тогда лучше if.

Дробные числа сравнивают осторожно

Дробные числа хранятся приблизительно, поэтому 0.1 + 0.2 == 0.3 — ложь:

C++
#include <iostream>
#include <cmath>
using namespace std;

int main() {
    double x = 0.1 + 0.2;
    cout << (x == 0.3) << "\n";
    cout << (fabs(x - 0.3) < 1e-9) << "\n";
    return 0;
}
Вывод
0
1

Дробные числа сравнивают с допуском: разница меньше маленького числа (здесь 1e-9, то есть 10⁻⁹) считается равенством. fabs — модуль дробного числа, он из <cmath>.

Коротко

Проверьте себя

1. Что делает условие if (x = 0)?
2. Что выведет программа для year = 2000 в примере с високосным годом?
3. Что будет, если в switch после case забыть break?
4. Как правильно записать «x от 1 до 10 включительно»?