4.9 – Логические (булевы) значения
В реальной жизни часто задаются вопросы, на которые можно ответить «да» или «нет». «Яблоко – это фрукт?». Да. «Тебе нравится спаржа?». Нет.
Теперь рассмотрим аналогичное утверждение, на которое можно ответить «верно/истина» (true) или «неверно/ложь» (false): «Яблоки – это фрукты». Совершенно очевидно, что это истина. Или как насчет «Я люблю спаржу». Абсолютно неверно (фу!).
Такие предложения, которые имеют только два возможных результата: да/истина или нет/ложь, настолько распространены, что многие языки программирования включают в себя специальный тип данных для работы с ними. Этот тип называется логическим (булевым, Boolean) типом (примечание: Boolean на английском правильно пишется с заглавной буквы, потому что этот тип назван в честь своего изобретателя Джорджа Буля).
Логические переменные
Логические переменные – это переменные, которые могут иметь только два возможных значения: true
(истина) и false
(ложь).
Чтобы объявить логическую переменную, мы используем ключевое слово bool
.
bool b;
Чтобы инициализировать или присвоить логической переменной значение истина или ложь, мы используем ключевые слова true
и false
.
bool b1 { true };
bool b2 { false };
b1 = false;
bool b3 {}; // по умолчанию инициализируется значением false
Так же, как унарный оператор минус (-
) может использоваться для превращения положительного числа в отрицательное, логический оператор НЕ (!
) Может использоваться для переключения логического значения с true
на false
или с false
на true
:
bool b1 { !true }; // b1 будет инициализирована значением false
bool b2 { !false }; // b2 будет инициализирована значением true
Логические значения на самом деле не хранятся в логических переменных в виде слов «true» или «false». Вместо этого они хранятся как целые числа: true
становится целым числом 1, а false
становится целым числом 0. Аналогично, когда вычисляются логические значения, они на самом деле не оцениваются как «true» или «false». Они оценивают целые числа 0 (false
) или 1 (true
). Поскольку логические значения фактически хранят целые числа, они считаются целочисленным типом.
Печать логических переменных
Когда с помощью std::cout
мы печатаем логические значения, std::cout
печатает 0 для false
и 1 для true
:
#include <iostream>
int main()
{
std::cout << true << '\n'; // true вычисляется как 1
std::cout << !true << '\n'; // !true вычисляется как 0
bool b{false};
std::cout << b << '\n'; // b равно false, которая вычисляется как 0
std::cout << !b << '\n'; // !b равно true, которая вычисляется как 1
return 0;
}
Вывод этой программы:
1
0
0
1
Если вы хотите, чтобы std::cout
выводил «true» или «false» вместо 0 или 1, вы можете использовать std::boolalpha
. Например:
#include <iostream>
int main()
{
std::cout << true << '\n';
std::cout << false << '\n';
std::cout << std::boolalpha; // выводим логические переменные как true или false
std::cout << true << '\n';
std::cout << false << '\n';
return 0;
}
Эта программа напечатает:
1
0
true
false
Чтобы отключить этот способ вывода, вы можете использовать std::noboolalpha
.
Преобразование целочисленных значений в логические
Вы не можете инициализировать логическое значение целым числом, используя унифицированную инициализацию:
#include <iostream>
int main()
{
bool b{ 4 }; // ошибка: сужающее преобразование запрещено
std::cout << b;
return 0;
}
(примечание: некоторые версии g++ не обеспечивают генерирование этой ошибки)
Однако в любом контексте, где целочисленное значение может быть преобразовано в логическое значение, целое число 0 преобразуется в false
, а любое другое целое число преобразуется в true
.
#include <iostream>
int main()
{
std::cout << std::boolalpha; // выводим логические значения как true или false
bool b1 = 4; // копирующая инициализация допускает неявное преобразование int в bool
std::cout << b1 << '\n';
bool b2 = 0; // копирующая инициализация допускает неявное преобразование int в bool
std::cout << b2 << '\n';
return 0;
}
Эта программа напечатает:
true
false
Ввод логических значений
Ввод логических значений с помощью std::cin
начинающих программистов иногда сбивает с толку.
Рассмотрим следующую программу:
#include <iostream>
int main()
{
bool b{}; // по умолчанию инициализируется значением false
std::cout << "Enter a boolean value: ";
std::cin >> b;
std::cout << "You entered: " << b << '\n';
return 0;
}
Enter a Boolean value: true
You entered: 0
Погодите, что?
Оказывается, std::cin
принимает для логических переменных только два входных значения: 0 и 1 (а не true или false). Любые другие входные данные вызовут молчаливый сбой std::cin
. В этом случае, поскольку мы ввели true, std::cin
молча завершился ошибкой. Неудачный ввод также обнулит переменную, поэтому b
также получит значение false
. Следовательно, когда std::cout
печатает значение b
, он печатает 0.
Чтобы заставить std::cin
принимать в качестве входных данных «false» и «true», необходимо включить параметр std::boolalpha
.
#include <iostream>
int main()
{
bool b{};
std::cout << "Enter a boolean value: ";
// бработка "false" и "true" как логических значений
std::cin >> std::boolalpha;
std::cin >> b;
std::cout << "You entered: " << b << '\n';
return 0;
}
Однако, когда включен std::boolalpha
, «0» и «1» больше не будут обрабатываться как логические значения.
Логические возвращаемые значения
Логические значения часто используются в качестве возвращаемых значений для функций, которые проверяют, является ли что-то истинным или нет. Такие функции обычно называются, начиная со слова is (т.е. «является», например, isEqual
) или has (т.е. «имеет», например, hasCommonDivisor
).
Рассмотрим следующий пример, очень похожий на приведенный выше:
#include <iostream>
// возвращает true, если x и y равны, иначе false
bool isEqual(int x, int y)
{
// operator== returns возвращает true, если x равно y, и false в противном случае
return (x == y);
}
int main()
{
std::cout << "Enter an integer: ";
int x{};
std::cin >> x;
std::cout << "Enter another integer: ";
int y{};
std::cin >> y;
std::cout << std::boolalpha; // выводим логические значения как true или false
std::cout << x << " and " << y << " are equal? ";
std::cout << isEqual(x, y); // вернет true или false
return 0;
}
Ниже показан результат двух запусков этой программы:
Enter an integer: 5
Enter another integer: 5
5 and 5 are equal? true
Enter an integer: 6
Enter another integer: 4
6 and 4 are equal? false
Как это работает? Сначала мы читаем целочисленные значения для x
и y
. Затем вычисляется выражение isEqual(x, y)
. При первом запуске это приводит к вызову функции isEqual(5, 5)
. Внутри этой функции вычисляется 5 == 5
, возвращая значение true
. Значение true
возвращается вызывающей функции для печати с помощью std::cout
. При втором запуске вызов isEqual(6, 4)
возвращает значение false
.
К логическим значениям нужно немного привыкнуть, но как только вы начнете думать о них, они сразу же покажут свою простоту! Логические значения также являются огромной частью языка – вы в конечном итоге будете использовать их чаще, чем все другие базовые типы вместе взятые!
Мы продолжим изучение логических значений в следующем уроке.