Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Вложенные циклы и двумерные массивы.docx
Скачиваний:
1
Добавлен:
24.11.2019
Размер:
3.51 Mб
Скачать

Конструкция if else if else

В компьютерных программах, как и в жизни, иногда приходится выбирать из бо­лее чем двух вариантов. Оператор C++ if else можно расширить, чтобы он отвеча­ло таким потребностям. Как уже говорилось, за else должен следовать единствен­ный оператор, который может быть и блоком операторов. Поскольку конструкция if else сама является единым оператором, она может следовать за else:

if (ch == 'А' )

a_grade++; // альтернатива # 1

else

if (ch == 'B') // альтернатива # 2

b_grade++; // подальтернатива # 2a

else

soon++; // подальтернатива # 2b

Если значение ch не равно 'A', программа переходит к else. Там второй опе­ратор if else разделяет эту альтернативу еще на два варианта. Свойство свободно­го форматирования C++ позволяет расположить эти элементы в более читабельном виде:

if (ch == 'А')

Вложенные циклы и двумерные массивы 1

Инициализация двумерного массива 3

Использование двумерного массива 4

Операторы Ветвления 7

Оператор if 7

Оператор if else 10

Форматирование операторов if else 13

Конструкция if else if else 15

Условные операции и предотвращение ошибок 16

Логические выражения 17

Операция ?: 27

Оператор switch 29

Использование перечислителей в качестве меток 35

Операторы break и continue 38

Это выглядит как совершенно новая управляющая структура — if else if else. Но на самом деле это один оператор if else, вложенный в другой. Пересмотренный формат выглядит намного яснее и позволяет даже при поверхностном взгляде оце­нить все альтернативы. Вся эта конструкция по-прежнему трактуется как единствен­ный оператор.

8. Любимое число с подсказками.

Условные операции и предотвращение ошибок

Многие программисты превращают более интуитивно понятное выражение переменная == значение в значение == переменная, чтобы предотвратить ошибки, связанные с опечатками, когда вместо операции проверки равенства (==) вводится операция присваи­вания (=). Например, следующее условие корректно и будет работать правильно:

if (3 == myNumber)

Однако если допустить ошибку и ввести оператор, как показано ниже, то компилятор вы­даст сообщение об ошибке, поскольку расценит это как попытку присвоить значение лите­ралу (3 всегда равно 3, и ему нельзя присвоить ничего другого):

if (3 = myNumber)

Предположим, что сделана та же опечатка, но используется обычный формат:

if (myNumber = 3)

В этом случае компилятор просто присвоит значение 3 переменной myNumber, и блок внутри if будет выполнен — очень распространенная ошибка, которую трудно обнаружить. (Однако многие компиляторы будут выдавать предупреждение, на которое разумно обра­тить внимание.)

В качестве общего правила запомните следующее: написать код, позво­ляющий компилятору обнаружить ошибку, гораздо легче, чем разбираться с непонятными мистическими результатами неверного выполнения программ.

Логические выражения

Часто приходится проверять более одного условия. Например, чтобы символ от­носился к прописным буквам, его значение должно быть больше или равно ’ а ’ и меньше или равно ’ 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.

Факты, связанные с логическими операциями

Как упоминалось ранее в этой главе, логические операции “ИЛИ” и “И” в C++ об­ладают более низким приоритетом, чем операции сравнения. Это значит, что такое выражение, как

х > 5 && х < 10

интерпретируется следующим образом:

(х > 5) && (х < 10)

С другой стороны, операция “НЕ” (!) имеет более высокий приоритет, чем любая арифметическая операция и операция сравнения. Таким образом, для отрицания выражения его необходимо заключить в скобки:

! (х > 5) // равно false, если х больше 5

!х > 5 // равно true, если !х больше 5

Кстати, результатом второго из приведенных выражений всегда будет false, т.к. !х принимает значения true или false, что преобразуется, соответственно, в 1 и 0.

Логическая операция “И” имеет более высокий приоритет, чем логическая опера­ция “ИЛИ”. Поэтому следующее выражение:

age > 30 && age <45 | | weight > 300

означает вот что:

(age > 30 && age < 45) | | weight > 300

Здесь первое условие говорит о том, что возраст должен быть от 31 до 44 лет включительно, а второе — что вес должен быть больше 300 (фунтов). Все выражение будет истинным, если истинно одно из выражений или оба сразу.

Разумеется, можно использовать скобки, чтобы явно указать программе, как сле­дует интерпретировать выражение. Например, предположим, что вы хотите использовать && для комбинирования условий о том, что возраст (аде) должен быть больше 50 или вес (weight) — больше 300, с условием, что размер пожертвования (donation) должен быть больше 1000. Для этого часть “ИЛИ” потребуется поместить в скобки:

(аде >50 | | weight > 300) && donation > 1000

Иначе компилятор скомбинирует условие weight с условием donation, вместо того чтобы скомбинировать его с условием age.

Хотя правила приоритетов операций C++ часто позволяют писать составные вы­ражения без использования скобок, все же проще всегда применять скобки для группирования проверок, независимо от того, нужны они или нет. Это улучшает чита­бельность кода, исключает неправильное понимание порядка приоритетов и снижа­ет вероятность ошибки из-за того, что вы не помните точно правил приоритетов.

C++ гарантирует, что когда программа вычисляет логическое выражение, то дела­ет это слева направо, и прекращает вычисление, как только ответ становится ясен.

Альтернативные представления

Не все клавиатуры предоставляют возможность ввода символов, используемых для обозначения логических операций, поэтому в стандарте C++ предусмотрены их альтернативные представления, которые показаны в табл. 6.3. Идентификаторы and, or и not являются зарезервированными словами C++, а это значит, что их нельзя использовать в качестве имен переменных и тому подобного. Они не рассматрива­ются как ключевые слова, потому что являются альтернативными представлениями существующих средств языка. Кстати, они не являются зарезервированными словами в С, но в программах на С они могут применяться в качестве операций только при условии включения заголовочного файла iso646.h. В C++ этот файл не требуется.