Часто приходится проверять более одного условия. Например, чтобы символ относился к прописным буквам, его значение должно быть больше или равно ’ а ’ и меньше или равно ’ z ’. Либо же, если вы просите пользователя ответить у или n, то наряду с прописными должны приниматься и заглавные буквы (Yили N).Чтобы обеспечить такие возможности, C++ предлагает три логических операции, с помощью которых можно комбинировать или модифицировать существующие выражения: логическое “ИЛИ” (которое записывается как | | ), логическое “И” (записывается как &&) и логическое “НЕ” (записывается как !).
Рассмотрим каждую из них.
Логическая операция ”ИЛИ”: | |
В английском языке слово “or” (или) означает, что одно из двух условий либо оба сразу удовлетворяют некоторому требованию. Например, вы можете поехать на пикник, устроенный компанией Mega, если вы или ваш(а) супруг(а) работаете в этой компании. Эквивалент логической операции “ИЛИ” в C++ записывается как | |. Эта операция комбинирует два выражения в одно. Если одно или оба исходных выражения возвращают true или не ноль, то результирующее выражение имеет значение true (истина). В противном случае выражение имеет значение false. Ниже показаны некоторые примеры:
Поскольку | | имеет более низкий приоритет, чем операции сравнения, нет необходимости использовать в этих выражениях скобки. В табл. 6.1 показано, как работает операция | |.
В C++ предполагается, что операция | | является точкой следования. Это значит, что любое изменение, проведенное в левой части, вычисляется прежде, чем вычисляется правая часть. Например, рассмотрим следующее выражение:
i++ <6 | | i == j
Предположим, что изначально переменная i имела значение 10. К моменту сравнения с j переменная i получает значение 11. Таким образом, C++ не заботится о правой части выражения, если выражение слева истинно, потому что одного истинного выражения достаточно, чтобы все составное выражение было оценено как истинное.
В листинге используется операция | | внутри if для того, чтобы проверить заглавную и прописную версии символа. К тому же применяется средство конкатенации строк C++ для разнесения одной строки на три строки в коде.
#include <iostream>
int main()
{
using namespace std;
cout << "This program may reformat your hard disk\n"
"and destroy all your data.\n"
"Do you wish to continue? <y/n> ";
char ch;
cin >> ch;
if (ch == 'y' || ch == 'Y') // y or Y
cout << "You were warned!\a\a\n";
else if (ch == 'n' || ch == 'N') // n or N
cout << "A wise choice ... bye\n";
else
cout << "That wasn't a y or n! Apparently you "
"can't follow\ninstructions, so "
"I'll trash your disk anyway.\a\a\a\n";
getchar();
getchar();
return 0;
}
Эта программа читает только один символ, поэтому принимается во внимание только первый символ ответа. Это значит, что пользователь может ввести N0! вместо N,но программа прочитает только N.Но если ей пришлось бы читать еще входные символы, то первым оказался бы символ О.
Логическая операция “И”: &&
Логическая операция “И”, которая записывается как &&, также комбинирует два выражения в одно. Результирующее выражение имеет значение true только в том случае, когда оба исходных выражения также равны true.
Ниже приведены некоторые примеры:
Поскольку && имеет меньший приоритет, чем операции сравнения, нет необходимости использовать скобки. Подобно | |, операция && действует как точка следования, а потому возможны любые побочные эффекты перед тем, как будет вычислено правое выражение. Если левое выражение ложно, то и все составное выражение также ложно, поэтому в таком случае C++ можно не беспокоиться о вычислении правой части. Работа операции && описана в табл. 6.2.
while (i < ArSize && temp >= 0) // 2 quitting criteria
{
naaq[i] = temp;
++i;
if (i < ArSize) // room left in the array,
{
cout << "Next value: ";
cin >> temp; // so get next value
}
}
Установка диапазонов с помощью &&
Операция && также позволяет установить последовательность операторов if else if else,где каждый выбор соответствует определенному диапазону значений. В листинге иллюстрируется такой подход. В нем также демонстрируется полезная техника обработки серии сообщений.
#include <iostream>
int main()
{
using namespace std;
int age;
cout << "Enter your age in years: ";
cin >> age;
int index;
if (age > 17 && age < 35)
index = 0;
else if (age >= 35 && age < 50)
index = 1;
else if (age >= 50 && age < 65)
index = 2;
else
index = 3;
cout << "You qualify for the " << index;
getchar();
getchar();
return 0;
}
Логическая операция "НЕ": !
Операция ! выполняет отрицание, или обращает, истинность выражения, следующего за ней. То есть если expression равно true, то ! expression равно false, и наоборот. Точнее говоря, если expression имеет значение true, или ненулевое, то ! expression будет равно false.
Обычно выражение отношения можно представить яснее без применения операции !:
if ( ! (х > 5) ) //в этом случае if (х <= 5) яснее
Однако операция ! может быть полезна с функциями, которые возвращают значения true/false либо значения, которые могут интерпретироваться подобным образом. Например, strcmp (s1, s2) возвращает не ноль (true), если две строки в стиле С, s1 и s2, отличаются друг от друга, и ноль, если они одинаковы. Это значит, что !strcmp (s1, s2) равно true, если две строки эквивалентны.
В листинге 6.7 используется прием применения операции ! к значению, которое возвращается функцией проверки числового ввода на предмет возможности его присваивания типу int. Пользовательская функция isint (), которая будет рассматриваться позже, возвращает true, если ее аргумент находится в диапазоне допустимых значений для присваивания типу int. Затем программа применяет проверку условия while (! isint (num) ) , чтобы отклонить значения, которые не входят в диапазон.
#include <iostream>
#include <climits>
bool is_int(double);
int main()
{
using namespace std;
double num;
cout << "Yo, dude! Enter an integer value: ";
cin >> num;
while (!is_int(num))//continue while num is not int-able
{
cout << "Out of range -- please try again: ";
cin >> num;
}
int val = int (num); // type cast
cout << "You've entered the integer " << val << "\nBye\n";
getchar();
getchar();
return 0;
}
bool is_int(double x)
{
if (x <= INT_MAX && x >= INT_MIN) // use climits values
return true;
else
return false;
}
Замечания по программе
В случае ввода слишком большого значения при выполнении программы, читающей тип int, многие реализации C++ просто усекают значение, не сообщая о потере данных. Программа в листинге избегает этого за счет того, что читает потенциальное значение int как double. Тип double имеет более чем достаточную точность для того, чтобы сохранить обычное значение int, а его диапазон допустимых значений намного больше. Другим вариантом могло быть сохранение веденного значения в переменной типа long long, предполагая, что этот тип шире, чем int.
Булевская функция isint() использует две символические константы (INT_MAXи INT_MIN),определенные в файле climits,для проверки, что значение ее аргумента находится в допустимых пределах. Если это так, функция возвращает true;в противном случае — false.
В функции main() используется условие цикла для отклонения неправильного ввода пользователя. Можно сделать программу более дружественной за счет отображения допустимых границ int,когда введено неправильное значение. После проверки достоверности введенного значения программа присваивает его переменной типа int.