3. Глава 3: Условия и сравнения

В этой главе мы познакомимся с основами ветвления программ на языке C: операторы if, else, switch и логические условия. Ветвление позволяет вашей программе принимать решения и выполнять разный код в зависимости от определённых условий. Это делает программы интерактивными и адаптивными к различным входным данным.

3.1. Логические выражения

Условия, также известные как логические выражения, — это выражения, которые принимают значение истина (true) или ложь (false). В отличие от некоторых других языков программирования, в C нет отдельного булевого типа данных (bool до C99 стандарта, который требует подключения <stdbool.h>). Вместо этого C использует целые числа для представления логических значений:

  • ``0`` означает ложь (false).

  • Любое ненулевое значение (например, 1, -5, 100) означает истину (true).

Это очень важная особенность C, которую нужно помнить при работе с условиями.

Примеры условий:

int x = 10;

if (x > 0) { // Условие "x больше 0" истинно, так как 10 > 0.
    printf("x положительное\n"); // Этот код будет выполнен.
}

if (x == 0) { // Условие "x равно 0" ложно.
    printf("x равно нулю\n"); // Этот код не будет выполнен.
}

if (5) { // Условие "5" истинно, так как 5 - ненулевое значение.
    printf("Это всегда будет выполнено!\n");
}

3.2. Операторы сравнения

Операторы сравнения используются для создания логических выражений путем сравнения двух значений. Результатом такого сравнения всегда является 0 (ложь) или 1 (истина).

Оператор

Назначение

Пример и возвращаемое значение(для x=5)

==

Равно

x == 5 возвращает 1 (true) x == 10 возвращает 0 (false)

!=

Не равно

x != 0 возвращает 1 (true) x != 5 возвращает 0 (false)

>

Больше

x > 10 возвращает 0 (false) x > 3 возвращает 1 (true)

<

Меньше

y < 3 возвращает 0 (false) y < 10 возвращает 1 (true)

>=

Больше или равно

a >= b x >= 5 возвращает 1 (true) x >= 10 возвращает 0 (false)

<=

Меньше или равно

a <= b x <= 5 возвращает 1 (true) x <= 3 возвращает 0 (false)

Важно: Не путайте оператор сравнения ``==`` с оператором присваивания ``=``! Ошибка if (x = 0) вместо if (x == 0) очень распространена и приводит к труднообнаружимым багам, так как x = 0 присвоит x значение 0, и затем условие будет интерпретироваться как if (0), что всегда ложно.

3.3. if / else

Конструкции if и else позволяют выполнять блок кода только тогда, когда определенное условие истинно, и другой блок кода, если условие ложно.

  • ``if (условие) { … }``: Блок кода внутри фигурных скобок будет выполнен, только если условие истинно (ненулевое).

  • ``else { … }``: Блок кода внутри else будет выполнен, если условие в соответствующем if ложно (0). else является необязательным.

#include <stdio.h> // Не забываем подключать библиотеку для printf

int main() {
    int age = 18;

    if (age >= 18) { // Если возраст больше или равен 18
        printf("Доступ разрешён\n"); // Этот код выполнится
    } else { // Иначе (если возраст меньше 18)
        printf("Доступ запрещён\n"); // Выполнится этот код
    }

    // Пример с несколькими условиями (if-else if-else)
    int score = 85;
    if (score >= 90) {
        printf("Отлично!\n");
    } else if (score >= 70) { // Если первое условие ложно, проверяем это
        printf("Хорошо\n"); // Этот код выполнится, так как 85 >= 70
    } else { // Если все предыдущие условия ложны
        printf("Удовлетворительно\n");
    }

    return 0;
}

3.4. switch

Оператор switch подходит для выбора одного из нескольких действий в зависимости от значения целочисленной переменной или выражения. Он часто используется как более читабельная альтернатива длинной цепочке if-else if, когда вы сравниваете одну переменную с множеством фиксированных значений.

  • ``switch (выражение)``: Выражение (обычно переменная) должно быть целочисленного типа (int, char, short, long).

  • ``case значение:``: Метки case указывают конкретное значение, с которым сравнивается выражение. Если совпадает, выполнение начинается с этого case.

  • ``break;``: Ключевое слово break очень важно. Оно прерывает выполнение оператора switch и передает управление коду, следующему за switch. Всегда добавляй ``break`` после каждого ``case``, чтобы избежать «проваливания» (fall-through) вниз к следующим case-ам, даже если они не соответствуют условию.

  • ``default:``: Метка default (необязательная) выполняется, если значение выражения не совпадает ни с одной из case-меток. Похоже на секцию else в if-else.

#include <stdio.h> // Не забываем подключать библиотеку для printf

int main() {
    int command = 2;

    switch (command) {
        case 1: // Если command равно 1
            printf("Команда 1\n");
            break; // Выход из switch
        case 2: // Если command равно 2
            printf("Команда 2\n"); // Этот код выполнится
            break; // Выход из switch
        case 3: // Если command равно 3
            printf("Команда 3\n");
            break; // Выход из switch
        default: // Если command не равно ни 1, ни 2, ни 3
            printf("Неизвестная команда\n");
            break; // Выход из switch (хотя здесь break не строго обязателен, хорошая практика его ставить)
    }

    // Пример "проваливания" (fall-through) без break
    char grade = 'B';
    switch (grade) {
        case 'A':
            printf("Отлично!\n");
        case 'B':
            printf("Очень хорошо!\n"); // Этот код выполнится, если grade = 'B'
        case 'C':
            printf("Хорошо.\n");      // И этот код выполнится, если grade = 'B' (из-за отсутствия break)
        default:
            printf("Завершено.\n");
    }
    // Чтобы избежать такого поведения, необходимо использовать 'break;' после каждого 'case'.

    return 0;
}

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

Условия можно объединять с логическими операторами для создания более сложных логических выражений.

Оператор

Назначение

Пример и пояснение

&&

Логическое И (AND) Возвращает истину, если оба операнда истинны.

(age > 18) && (hasLicense == 1) Истинно, если оба условия истинны.

||

Логическое ИЛИ (OR) Возвращает истину, если хотя бы один операнд истинен.

(temp < 0) || (isSnowing == 1) Истинно, если хотя бы одно истинно.

!

Логическое НЕ (NOT) Инвертирует логическое значение операнда.

!(isRaining == 1) Истинно, если условие ложно. !0 (NOT false) равно 1 (true) !1 (NOT true) равно 0 (false)

Пример использования:

#include <stdio.h>

int main() {
    int temperature = 25;
    int isSunny = 1; // 1 означает true

    // Условие: температура от 20 до 30 (включительно) И солнечно
    if ((temperature >= 20) && (temperature <= 30) && (isSunny)) {
        printf("Идеальная погода для прогулки!\n");
    }

    int hour = 2; // Ночь
    // Условие: время до 6 утра ИЛИ после 22 вечера
    if ((hour < 6) || (hour > 22)) {
        printf("Время спать!\n");
    }

    int hasPermission = 0; // 0 означает false
    // Условие: нет разрешения
    if (!hasPermission) {
        printf("Вход запрещён.\n");
    }

    return 0;
}

3.6. Домашнее задание ??????

  1. Напиши программу, которая просит пользователя ввести целое число и определяет: * положительное оно, отрицательное или ноль. Используй конструкцию if-else if-else.

  2. Добавь switch, который печатает день недели по номеру (от 1 до 7). Например, 1 - «Понедельник», 7 - «Воскресенье». Не забудь про default для некорректного ввода.

Примечание

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

Надеюсь, эта расширенная версия главы вам понравится! Я постарался добавить больше примеров, уточнений и комментариев, чтобы сделать материал максимально понятным и полным для справочника.

Что вы думаете об этом? Есть ли что-то еще, что вы хотели бы добавить или изменить в этой главе?