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

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

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

bool f, q = true, k = false;
cout.setf(ios::boolalpha);
cout << true << endl;
f = k;
cout << q << " " << f << 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;

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

cout << (a == b) << endl;
cout << bool(a = b) << endl;

В этом фрагменте последняя инструкция будет выводить значения true в любом случае, если b != 0. Понимать эту инструкцию нужно следующим образом: вначале переменной a присваивается значение b. Затем результат преобразуется к типу bool (любое ненулевое значение будет рано true).
Поле шахматной доски определяется парой натуральных чисел, не превосходящих 8: первое число x — номер горизонтали (при счете слева направо), второе число y — номер вертикали (при счете снизу вверх). Даны натуральные числа x1 и y1 - позиция фигуры слона. Записать условие, при котором он угрожает полю (x2, y2).

Программа 6.1

#include <iostream>
#include <cmath>
using namespace std;

int main() {
	int x1, x2, y1, y2;
	cout << "Введите позицию слона:\n"
		 << "x1 = ";
	cin >> x1;
	cout << "y1 = ";
	cin >> y1;
	cout << "Введите тестируемое поле:\n"
		 << "x2 = ";
	cin >> x2;
	cout << "y2 = ";
	cin >> y2;
	cout << boolalpha
		 << (abs(y2-y1) == abs(x2 - x1))
		 << endl;
	return 0;
}

Идея алгоритма заключается в следующем: если абсолютные значения разности соответствующих координат по х: x1 и x2 и по y: y1 и y2 будут равны, то слон будет угрожать этому полю (выводится значение true).

Примечание. Обратите внимание, что boolalpha здесь не флаг форматирования, а манипулятор.

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

Операция &&
Логическая операция "И" (конъюнкция, логическое умножение) обозначается &&. Эта операция бинарная, т. е. имеет два операнда, в качестве которых могут выступать, например, операции отношения. Результат логического выражения 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;

Логическое "НЕ" удобно применять как для отрицания больших логических выражений, так и для сокращения логического выражения. Среди остальных операций - логическое отрицание обладает высшим приоритетом, поэтому скобки обязательны.
Программа 6.2
Дана точка A с координатами (x, y). Составить программу, которая печатает true, если точка принадлежит закрашенной области, и false в противном случае.

#include <iostream>
using namespace std;

int main() {
	float x, y;
	cout << "x = "; cin >> x;
	cout << "y = "; cin >> y;
	cout.setf(ios::boolalpha);
	cout << ((y <  x + 5 &&
			  y > -x - 5 &&
			  x < 0) ||
			 (x * x + y * y < 25 &&
			  x > 0 &&
			  y > 0))
		 << endl;
	return 0;
}

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

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

Условие ? Выражение_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).
Даны два числа a и b. Определить какое из чисел больше. Определить является ли a кратным b. Определить имеют ли a и b один и тот же знак.
Программа 6.3

#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;
}

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

#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

Comments are closed.