1. Тип bool и идея «сравнение возвращает значение»
Если программа умеет только считать 2 + 2 и печатать результат — это уже неплохо (калькулятор в кармане, классика). Но почти любая реальная программа рано или поздно должна принимать решения: «пароль верный?», «возраст подходит?», «число больше нуля?», «команда пользователя — "exit"?». Все эти решения — это вопросы формата да/нет.
И вот тут появляется ключевой герой сегодняшней лекции: тип bool и операторы сравнения. С их помощью мы превращаем данные (числа, строки) в понятный компьютеру ответ «истина/ложь». В следующей лекции мы начнём использовать эти ответы, чтобы выполнять разные ветки кода, но сегодня сначала научимся получать ответы.
Тип bool: два значения и никакой драмы
Тип bool в C++ — это логический тип данных. Он создан для того, чтобы хранить результат «истина/ложь», а не для того, чтобы изображать число или строку. У него всего два возможных значения: true (истина) и false (ложь). Это приятно: вариантов мало — ошибаться вроде бы негде… но программисты умеют находить приключения даже в двух вариантах.
Важно понимать: bool — такой же тип, как int. Это значит, что можно объявить переменную bool, присваивать ей значения, передавать её куда-то и выводить.
Небольшой пример “в лоб”:
#include <iostream>
int main() {
bool ok = true;
bool failed = false;
std::cout << ok << '\n'; // 1
std::cout << failed << '\n'; // 0
}
Да, по умолчанию std::cout часто показывает true как 1, а false как 0. Это не «ошибка», а нормальный режим вывода для простых примеров. Позже можно научиться печатать красиво словами, но сегодня нам важнее понять механику.
Сравнение — это выражение, которое даёт bool
Одна из самых важных идей дня звучит так: сравнение в C++ — это выражение. То есть оно вычисляется и возвращает значение. Только возвращает не число, а bool.
Например, 10 > 7 — это не «команда сравнить», а выражение, которое вычисляется в true. Поэтому его можно сохранить в переменную, вывести или использовать как часть более сложного вычисления.
Посмотрим минимальный пример:
#include <iostream>
int main() {
int a = 10;
int b = 7;
bool greater = (a > b);
std::cout << greater << '\n'; // 1
}
Скобки вокруг (a > b) не обязательны, но на первых порах они помогают мозгу: вы глазами видите «вот сравнение, вот его результат».
3. Операторы порядка: <, <=, >, >=
Когда мы сравниваем числа, чаще всего нас интересует порядок: меньше, больше, «не меньше» (то есть больше или равно), «не больше» (меньше или равно). Для этого в C++ есть четыре оператора:
- < — строго меньше
- <= — меньше или равно
- > — строго больше
- >= — больше или равно
Здесь особенно важно слово «строго». Оно означает «без границы». Например, x > 10 не включает 10, а x >= 10 включает.
Пример, который показывает разницу на границе:
#include <iostream>
int main() {
int x = 10;
std::cout << (x > 10) << '\n'; // 0
std::cout << (x >= 10) << '\n'; // 1
}
Если вы когда-нибудь увидите баг «всё работает, кроме случая ровно на границе» — знайте: где-то рядом прячется > вместо >= или наоборот.
Табличка‑памятка
Чтобы не держать всё в голове, полезно иметь маленькую таблицу. Её не нужно заучивать как стихотворение — достаточно понимать смысл.
| Оператор | Читаем по‑русски | Пример | Смысл примера |
|---|---|---|---|
|
меньше | |
истина |
|
меньше или равно | |
истина |
|
больше | |
истина |
|
больше или равно | |
ложь |
4. Равенство и сравнение строк: ==, !=
Равенство — это ==, а не =
Вторая группа операторов отвечает не за порядок, а за равенство:
- == — равно
- != — не равно
И вот тут есть один момент, который кажется мелочью, но на практике спасает нервы: в C++ равенство — это ==, а не =. Один знак = — это присваивание (изменение переменной). Два знака == — сравнение.
Проверка равенства чисел:
#include <iostream>
int main() {
int x = 5;
int y = 5;
std::cout << (x == y) << '\n'; // 1
std::cout << (x != y) << '\n'; // 0
}
Равенство и неравенство работают не только для чисел, но и для строк — и это суперудобно, когда вы читаете «команду» пользователя.
Сравнение строк: «команда совпала или нет»
На вашем текущем уровне со строками лучше всего использовать именно сравнение на равенство/неравенство: s == "..." и s != "...". Это понятная модель: строка либо совпала с образцом, либо нет.
Сделаем мини‑пример «псевдокомандного режима» (пока без if, просто печать результата):
#include <iostream>
#include <string>
int main() {
std::string cmd;
std::cin >> cmd;
bool is_exit = (cmd == "exit");
std::cout << is_exit << '\n'; // если ввели exit, будет 1, иначе 0
}
Смысл простой: пользователь вводит слово, мы проверяем, является ли оно словом "exit". Позже (в следующей лекции) мы научимся делать «если "exit", то завершай программу», но фундамент — вот он: сравнение возвращает bool.
Даем проверкам имена: bool как «ярлык смысла»
Когда вы только начинаете, хочется писать всё «в одну строку»: сравнение прямо внутри std::cout. Это нормально для маленьких примеров. Но очень быстро выражения становятся длиннее, и код начинает походить на ребус. В этот момент помогает простая привычка: сохранить результат сравнения в bool с понятным именем.
Сравните два варианта. Сначала “в лоб”:
#include <iostream>
int main() {
int age = 0;
std::cin >> age;
std::cout << (age >= 18) << '\n'; // 1 если возраст подходит
}
А теперь тот же смысл, но читается «человечески»:
#include <iostream>
int main() {
int age = 0;
std::cin >> age;
bool is_adult = (age >= 18);
std::cout << is_adult << '\n'; // 1 если взрослый
}
Во втором варианте мозг перестаёт «парсить символы» и начинает понимать намерение. Это очень полезно, особенно когда условий станет несколько.
5. Мини‑проект: анкета на вход в клуб
Давайте начнём маленькое приложение, которое мы будем постепенно развивать в следующих лекциях. Пусть это будет «анкета на вход в клуб» (не обязательно ночной; можно книжный, шахматный или клуб любителей C++ — это ещё страшнее). Пользователь вводит возраст и кодовое слово, а программа считает несколько логических признаков.
Пока мы не умеем if, мы просто выведем результаты как 0/1. Не очень «пользовательски», но честно и полезно для обучения.
#include <iostream>
#include <string>
int main() {
int age = 0;
std::string code;
std::cin >> age >> code;
bool is_adult = (age >= 18);
bool is_vip = (code == "VIP");
std::cout << is_adult << ' ' << is_vip << '\n'; // например: 1 0
}
Обратите внимание на важный момент: мы ничего не «решаем», мы только вычисляем факты. Это как собрать показания датчиков: «температура выше нормы?» — да/нет. Решение «что делать дальше» появится позже, когда у нас будет ветвление.
6. Полезные нюансы и ловушки
Ловушка «как в математике»: почему a < b < c почти всегда ошибка
Есть запись, которая выглядит суперлогично для человека с математическим бэкграундом: a < b < c. В математике это читается как «a меньше b и b меньше c». Но в C++ это работает иначе, потому что сравнение возвращает bool.
Разберём по шагам. Сначала вычисляется (a < b). Результат — bool (true или false). А потом этот bool сравнивается с c (числом). Это уже совсем не то, что вы хотели.
Правильная запись (и сегодня мы ограничимся именно ей) — это два сравнения отдельно:
#include <iostream>
int main() {
int a = 1;
int b = 2;
int c = 3;
bool increasing = (a < b) && (b < c);
std::cout << increasing << '\n'; // 1
}
Здесь появился оператор && («И») — это уже тема следующей лекции про логические операции. Я использовал его только чтобы показать «правильную форму» записи. Если && ещё кажется новым, просто запомните главное: цепочки как в математике в C++ писать нельзя, нужно делать сравнения отдельно.
Маленькая схема: как данные превращаются в bool
Чтобы у вас сложилась «картинка в голове», полезно увидеть, что происходит в программе концептуально. Мы читаем данные, применяем к ним операторы сравнения, получаем bool, а потом уже можем либо вывести, либо (чуть позже) использовать в if.
flowchart LR
A[Ввод данных: числа / строки] --> B[Сравнение: < <= > >= == !=]
B --> C["Результат: bool (true/false)"]
C --> D[Вывод или использование в условиях]
Эта схема — почти весь «скелет логики» будущих программ. Сначала факты, потом решения.
Небольшой исторический факт
Комитет C++ иногда фиксит такие вещи, которые выглядят как «капитан Очевидность», но на самом деле помогают убрать неоднозначности. Например, в истории правок стандарта отдельно отмечали, что в C++ нельзя делать декремент -- для bool (и вообще bool — не «маленькое число для трюков», а логический тип).
Это хороший повод запомнить мысль дня: bool — про смысл «да/нет», а не про арифметику.
7. Типичные ошибки при работе со сравнениями и bool
Ошибка №1: путаница «строго» и «включая границу».
Очень легко случайно написать age > 18, когда по смыслу нужно «18 и старше», то есть age >= 18. Такие ошибки обычно проявляются только на одном значении (ровно 18), поэтому их особенно неприятно ловить. Спасает привычка проговаривать условие словами: «строго больше» или «больше либо равно».
Ошибка №2: попытка писать «математические цепочки» a < b < c.
Глаз видит красиво, мозг радуется, а C++ делает не то. Причина в том, что (a < b) возвращает bool, и дальше сравнение идёт уже не с b, а с логическим значением. Надёжный способ — разбивать на два сравнения и (когда вы изучите логические операторы) соединять их через &&.
Ошибка №3: сравнение без понимания, что это выражение.
Иногда новички воспринимают сравнение как «операцию, которая что-то делает», и удивляются, что x > y; само по себе ничего не меняет. Сравнение лишь вычисляет значение true/false. Если результат нигде не используется (не сохранён в переменную и не выведен), он просто пропадёт — как чек из магазина, который вы не взяли.
Ошибка №4: сравнение строк «не тем способом».
Если вы читаете команду пользователя, сравнивайте её с ожидаемой строкой явно: cmd == "exit". Не стоит пытаться сравнивать «по частям» или надеяться, что "Exit" и "exit" — одно и то же. На текущем уровне считайте, что сравнение строк чувствительно к регистру и к точному совпадению символов — это не придирка, это строгость формата.
Ошибка №5: отсутствие «имени» у проверки, из-за чего код становится нечитаемым.
Пока условие короткое, std::cout << (a > b); выглядит нормально. Но как только проверок станет несколько, код превращается в набор скобок. Привычка сохранять результат в bool с говорящим именем (is_adult, is_exit) делает программу понятнее даже вам самим через пару часов, не говоря уже о преподавателе.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ