Глава 3: Условия и сравнения ============================= В этой главе мы познакомимся с основами ветвления программ на языке C: операторы ``if``, ``else``, ``switch`` и логические условия. Ветвление позволяет вашей программе принимать решения и выполнять разный код в зависимости от определённых условий. Это делает программы интерактивными и адаптивными к различным входным данным. .. contents:: :local: :depth: 2 --- Логические выражения --------------------- Условия, также известные как логические выражения, — это выражения, которые принимают значение **истина (true)** или **ложь (false)**. В отличие от некоторых других языков программирования, в C нет отдельного булевого типа данных (``bool`` до C99 стандарта, который требует подключения ````). Вместо этого C использует целые числа для представления логических значений: * **``0``** означает **ложь (false)**. * **Любое ненулевое значение** (например, ``1``, ``-5``, ``100``) означает **истину (true)**. Это очень важная особенность C, которую нужно помнить при работе с условиями. Примеры условий: .. code-block:: 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"); } --- Операторы сравнения --------------------- Операторы сравнения используются для создания логических выражений путем сравнения двух значений. Результатом такого сравнения всегда является ``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)``, что всегда ложно. --- if / else ---------- Конструкции ``if`` и ``else`` позволяют выполнять блок кода только тогда, когда определенное условие истинно, и другой блок кода, если условие ложно. * **``if (условие) { ... }``**: Блок кода внутри фигурных скобок будет выполнен, только если ``условие`` истинно (ненулевое). * **``else { ... }``**: Блок кода внутри ``else`` будет выполнен, если условие в соответствующем ``if`` ложно (``0``). ``else`` является необязательным. .. code-block:: c #include // Не забываем подключать библиотеку для 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; } --- 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``. .. code-block:: c #include // Не забываем подключать библиотеку для 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; } --- Логические операторы --------------------- Условия можно объединять с логическими операторами для создания более сложных логических выражений. +----------------+-----------------------------+---------------------------------------------+ | Оператор | Назначение | Пример и пояснение | +================+=============================+=============================================+ | ``&&`` | **Логическое И** (AND) | ``(age > 18) && (hasLicense == 1)`` | | | Возвращает истину, если | Истинно, если **оба** условия истинны. | | | **оба** операнда истинны. | | +----------------+-----------------------------+---------------------------------------------+ | ``||`` | **Логическое ИЛИ** (OR) | ``(temp < 0) || (isSnowing == 1)`` | | | Возвращает истину, если | Истинно, если **хотя бы одно** истинно. | | | **хотя бы один** операнд | | | | истинен. | | +----------------+-----------------------------+---------------------------------------------+ | ``!`` | **Логическое НЕ** (NOT) | ``!(isRaining == 1)`` | | | Инвертирует логическое | Истинно, если условие **ложно**. | | | значение операнда. | ``!0`` (NOT false) равно ``1`` (true) | | | | ``!1`` (NOT true) равно ``0`` (false) | +----------------+-----------------------------+---------------------------------------------+ Пример использования: .. code-block:: c #include 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; } --- Домашнее задание ------------------- 1. Напиши программу, которая просит пользователя ввести целое число и определяет: * положительное оно, отрицательное или ноль. Используй конструкцию ``if-else if-else``. 2. Добавь ``switch``, который печатает день недели по номеру (от 1 до 7). Например, 1 - "Понедельник", 7 - "Воскресенье". Не забудь про ``default`` для некорректного ввода. .. note:: **Условия делают программы умными!** Их использование помогает программам реагировать на любые данные и сценарии, делая их гибкими и интерактивными. Это фундаментальный инструмент для создания сложной логики. --- Надеюсь, эта расширенная версия главы вам понравится! Я постарался добавить больше примеров, уточнений и комментариев, чтобы сделать материал максимально понятным и полным для справочника. Что вы думаете об этом? Есть ли что-то еще, что вы хотели бы добавить или изменить в этой главе?