§5 Логический тип данных. Логические выражения. Тернарная операция

Логический тип данных

В языке C++ существует логический тип данных bool. Переменные этого типа могут содержать всего два значения – true (истина) и false (ложь). true и false являются логическими константами. В С++ true интерпретируется, как 1, а false как 0. Логический тип относится к целым типам. Этот тип данных назван в честь Дж. Буля, разработавшего математическое представление законов логики. Поэтому переменные этого типа часто называются булевскими или логическими.
По умолчанию значения логических переменных выводятся в числовом представлении. Для вывода в текстовом виде необходимо использовать манипулятор или флаг форматирования boolalpha:

bool l, q = true, k = false;
cout.setf(ios::boolalpha);
cout << true << endl;
l = k;
cout << q << " " << l << endl;
cout.unsetf(ios::boolalpha);
cout << k << endl;

Примечание. Здесь мы использовали флаг форматирования boolalpha, который устанавливается с помощью функции setf. Отключить флаг можно путем вызова функции unsetf() с указанием отключаемого флага.

Операции отношения (сравнения)

Операции отношения сравнивают два значения. В С++ определены следующие операции сравнения:

<   меньше
<=  меньше либо равно
>   больше
>=  больше либо равно
==  равно
!=  не равно

Результатом сравнения двух выражений является true или false. Примеры:

int a = 10, b = 5;
cout.setf(ios::boolalpha);
cout << (a > b) << "\n"      // (true)
     << (b % a == 0) << "\n" // (false)
     << (b * a != 0) << "\n" // (true)
     << (b / a >= 2) << "\n" // (false)
     << (a / b != 0) << "\n" // (true)
     << (b == 2 * a)         // (false)
     << endl;

Сравниваться могут константы, переменные и выражения. Сравниваться могут также и объекты пользовательского типа. Поскольку операции сравнения имеют более низкий приоритет, чем операция "<<" - использование скобок обязательно.
Примечание. Обратите внимание на то, что операции "=" и "==" часто путают. Но для C++ применение операции = в условиях - допустимо! Например:

int a = 1, b = 5;
cout << (a == b) << endl;
cout << bool(a = b) << endl;

В этом фрагменте последняя инструкция всегда будет выводить значения true (при b != 0). Понимать эту инструкцию нужно следующим образом: вначале переменной a присваивается значение b. Затем результат преобразуется к типу bool (любое ненулевое значение будет рано true).

Логические операции && (И), || (ИЛИ), ! (НЕ)

Операция &&
Логическая операция "И" (конъюнкция, логическое умножение) обозначается &&. Эта операция бинарная, т. е. имеет два операнда, в качестве которых могут выступать, например, операции отношения. Результат логического выражения true, если оба операнда истинны. Пример:

cout.setf(ios::boolalpha);
int a = 2, b = 4;
cout << (a < b && b != 0) << "\n"           //  (true)
     << (a % 2 == 0 && b % a != 0) << "\n"  //  (false)
     << (b == 4 && a == b / 2) << "\n"      //  (true)
     << (b < a && b * b == a)               //  (false)
     << endl;

Поскольку приоритет операций сравнения выше, то их не нужно заключать в круглые скобки (в выражениях с && и ||).
Операция ||
Логическая операция "ИЛИ" (дизъюнкция, логическое сложение) обозначается ||. Эта операция, тоже является бинарной. Результат логического выражения false, если оба операнда ложны. Пример:

cout.setf(ios::boolalpha);
int a = 2, b = 4;
cout << (a > b || b == 0) << "\n"           //  (false)
     << (a % 2 == 0 || b % a != 0) << "\n"  //  (true)
     << (b == 2 || a == b / 2) << "\n"      //  (true)
     << (b < a || b * b == 3)               //  (false)
     << endl;

Операция !
Логическое "НЕ" или логическое отрицание (инверсия) является операцией унарной. Это означает, что в выражении с этой операцией участвует только один операнд. Обозначается !. Результат true, если операнд имеет значение false, и наоборот. Например:

cout.setf(ios::boolalpha);
cout << !(x > 5) << "\n"  // "не больше 5", иначе x <= 5
     << !(x == 7) // "не равно 7", что эквивалентно x != 7
     << endl;

Логическое "НЕ" удобно применять как для отрицания больших логических выражений, так и для сокращения логического выражения. Среди остальных операций - логическое отрицание обладает высшим приоритетом, поэтому скобки обязательны.

Тернарная операция (условная операция : ?)

В языке С++ существует одна тернарная операция. Называется она так потому, что в выражении участвуют три операнда. Также эта операция носит название условной операции. С помощью данной операции можно в компактной форме реализовать алгоритмическую структуру ветвление, т. е. ввести варианты выполнения алгоритма в зависимости от поставленного условия. Условием является логическое выражение построенное с помощью операций сравнения и логических операций. Общий синтаксис тернарной операции таков:

Условие ? Выражение_1 : Выражение_2

Выражение_1 будет выполнено в том случае, если Условие истинно, в противном случае будет выполняться Выражение_2.
Например:

int c = a > b ? a : b;

Тернарная операция позволяет придать выражению более лаконичных характер нежели при использовании условной инструкции if (которая будет рассмотрена на следующем уроке). Значение тернарной операции можно присваивать другим переменным и использовать его в любом выражении, как слева так и справа, где допускается использование переменной. В этом заключается различие между условной инструкцией (if) и условной операцией. Примеры использования:

min = (a < b) ? a : b;                // присвоить минимальное
cout << (!(j % 2) ? ' ' : 'x');       // вывод в зависимости от кратности
(i != j ? i: j) = 10;                 // i и j должны быть одного типа!
a > b ? cout << a : cout << b;        // выводим максимальное

Вы обратили внимание на стр. 2 в примере выше? C++ интерпретирует любое выражение отличное от нуля как истину. Поэтому операции сравнения часто опускают. В данном случае выражение означает "j является чётным" (!(j % 2) эквивалентно j % 2 == 0).
Задача1. Даны два числа a и b. Определить какое из чисел больше. Определить является ли a кратным b. Определить имеют ли a и b один и тот же знак.
Программа 5.1

#include <iostream>
using namespace std;

int main() {
    int a, b;
    cout << "a = "; cin >> a;
    cout << "b = "; cin >> b;
    cout << (a > b ? "A больше B" : "B больше A") << endl;
    a % b == 0 ?
    cout << "A кратно B" :
    cout << "A некратно B";
    cout << endl;
    cout << "Числа имеют "
         << (a * b > 0 ? "равные знаки" :
                         "разные знаки")
         << endl;

    return 0;
}

Задача2. Дано двузначное число n. Действительно ли, что сумма разрядов числа является четным числом, а произведение, кратно 3.
Программа 5.2

#include <iostream>
using namespace std;

int main() {
    int n;
    cout << "n = "; cin >> n;
    (n / 10 + n % 10) % 2 == 0 &&
    ((n / 10) * (n % 10)) % 3 == 0 ?
    cout << "Утверждение истинно" :
    cout << "Утверждение ложно";
    cout << endl;

    return 0;
}

Вопросы

  1. Почему в условии можно опустить операции сравнения?
  2. Можно ли заменить (a % 3 == 0) на (!(a % 3))? Аргументируйте свой ответ.

Практические задания

1. На числовой оси расположены три точки: A, B, C. Определить, какая из двух последних точек (B или C) расположена ближе к A, и вывести эту точку и ее расстояние от точки A.
2. Даны координаты точки, не лежащей на координатных осях OX и OY. Определить номер координатной четверти, в которой находится данная точка.


Print Friendly, PDF & Email

Добавить комментарий