Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лафоре Р. - Объектно-ориентированное программир...doc
Скачиваний:
49
Добавлен:
01.04.2025
Размер:
40.77 Mб
Скачать

Рис. 3.8. Исполнение оператора if

Несколько операторов в теле if

Как и для циклов, тело ветвления if может состоять как из одного оператора, что было продемонстрировано в программе IFDEMO, так и из нескольких операторов, заключенных в фигурные скобки. Пример, иллюстрирующий использование блока операторов в теле if, называется IF2 и приводится ниже.

// if2.cpp

// использование нескольких операторов в теле цикла if #include <iostream> using namespace std;

int main() {

int x;

cout << "Введите число: "; cin >> x;

if(x > 100) {

cout << "Число " << x; cout << " больше, чем 100\n";

}

return 0;

}

Вот возможный результат работы программы IF2:

Введите число: 12345 Число 12345 больше, чем 100

If внутри циклов

Циклы и ветвления можно использовать совместно. Вы можете помещать ветв- ления внутрь цикла и наоборот, использовать вложенные ветвления и вложен- ные циклы. В следующем примере под названием PRIME ветвление if находится внутри цикла for. Программа определяет, является ли вводимое число простым

или нет (простым называется число, которое делится только на единицу и на само себя. Примерами простых чисел являются 2, 3, 5, 7, 11, 13 и 17).

// prime.cpp

// применение цикла if для определения простых чисел #include <iostream> using namespace std;

#include <process.h> // для exit()

int main() {

unsigned long n, j; cout << "Введите число: ";

cin >> n; // ввод проверяемого числа

for(j = 2; j <= n / 2; j++) // деление на целые числа, if(n % j == 0) // начиная с 2; если остаток

{ // нулевой, то число не простое

cout << "Число не простое: делится на " << j << endl; exit(0); // выход из программы

}

cout << "Число является простым\n"; return 0;

}

В этом примере пользователь вводит значение, которое присваивается пере- менной n. Затем программа при помощи цикла for делит число n на все числа от 2 до n/2. Делителем является переменная j, служащая счетчиком цикла. Если чис- ло n разделится без остатка на какое-либо из значений j, то оно не будет прос- тым. Условием того, что одно число делится на другое без остатка, является равенство остатка от деления нулю. Поэтому в условии для if участвует опера- ция остатка от деления %. Если число оказывается не простым, то мы выводим соответствующее сообщение и выходим из программы.

Ниже приведен результат работы программы для трех последовательно вве- денных чисел:

Введите число: 13

Число является простым

Введите число: 22229

Число является простым

Введите число: 22231

Число не простое: делится на 11

Обратите внимание — тело цикла не заключено в фигурные скобки. Это объ- ясняется тем, что оператор if и операторы тела ветвления на самом деле явля- ются одним оператором. Для того чтобы улучшить читаемость кода, вы можете добавить фигурные скобки, но это не является обязательным для правильной работы компилятора.

Функция exit()

Когда программа PRIME получает число, не являющееся простым, она завершает- ся, поскольку нет необходимости несколько раз проверять, является число прос- тым или нет. Библиотечная функция exit() производит немедленный выход из

программы независимо от того, в каком месте она находится. Эта функция не возвращает значения. Ее единственный аргумент (в нашем случае 0) возвращается вызывающему окружению после того, как программа завершается (эта величина часто используется в пакетных файлах, которые запрашивают значение, возвра- щаемое функцией exit(). Как правило, возвращаемое значение 0 говорит об успеш- ном завершении программы; ненулевые значения сигнализируют об ошибках).

Оператор if...else

Оператор if позволяет совершать действие в том случае, если выполняется неко- торое условие. Если же условие не выполняется, никакого действия не выполня- ется. Однако можно представить такую ситуацию, когда нам необходимо совер- шить одно действие в случае выполнения условия и другое действие в случае невыполнения этого условия. Здесь оказывается полезным ветвление if...else. Оно состоит из оператора if, за которым следует блок операторов, и ключевого слова else, за которым следует еще один блок операторов. Синтаксис ветвления показан на рис. 3.9.

Рис. 3.9. Синтаксис if...else

Изменим программу if, добавив к ветвлению else-часть:

// ifelse.cpp

// применение конструкции if...else #include <iostream> using namespace std;

int main() {

int x;

cout << "\nВведите число: "; cin >> x; if(x > 100)

Рис. 3.10. Исполнение оператора if...else

Функция getche()

Следующий наш пример CHCOUNT демонстрирует использование ветвления if...else внутри цикла while. Кроме того, в нем используется библиотечная функция getche(). Программа подсчитывает количество слов и символов в строке, вводи- мой пользователем с клавиатуры.

// chcount.cpp

// подсчет числа слов и символов в строке #include <iostream> using namespace std;

#include <conio.h> // для getche()

int main() {

int chcount = 0; // число непробельных символов

int wdcount = 1; // число пробелов

char ch = 'a'; // ch должна иметь определенное значение

cout << "Введите строку: ";

while(ch != '\r') // цикл, пока не будет нажата клавиша Enter

{

cout << "Это число больше, чем 100\n";

else

cout << "Это число не больше, чем 100\n";

return 0;

}

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

Введите число; 300

Это число больше, чем 100

Введите число: 3

Это число не больше, чем 100

Функционирование ветвления if...else показано на рис. 3.10.

ch = getche(); // считывание символа

if(ch == ' ') // если символ является пробелом,

wdcount++; // то инкрементируем число слов

else // в противном случае

chcount++; // инкрементируем число символов

} // вывод результатов на экран

cout << "\nCлов: " << wdcount << endl;

cout << "Букв: " << (chcount - 1) << endl;

return 0;

}

До сих пор мы использовали для ввода только объект cin и операцию >>. Такой способ вводить значения предполагает, что после ввода значения пользо­ватель нажмет клавишу Enter. Это верно и в отношении отдельных символов: пользователь вводит символ, а затем нажимает Enter. В данном случае програм­ме необходимо обрабатывать каждый введенный символ сразу после его появ­ления, не дожидаясь нажатия клавиши Enter. Такую возможность обеспечивает библиотечная функция getche(). Эта функция не имеет аргументов, а ее описание содержится в заголовочном файле CONIO.H. Значение, возвращаемое функцией getche(), присваивается переменной ch (функция getche(), кроме возвращения значения, печатает это значение на экране; такой ввод называется ввод с эхом (echo), что отражено в названии функции буквой е на конце. Другая функция под названием getch() похожа на функцию getche(), но, в отличие от нее, не ото­бражает вводимый символ на экране.

Ветвление if...else увеличивает на единицу значение переменной wdcount в том случае, если с клавиатуры вводится пробел, и значение переменной chcount, если введен не пробел. Таким образом, программа считает за букву любой сим­вол, не являющийся пробелом. Разумеется, этот алгоритм примитивен и дает ошибочный результат уже при введении нескольких пробелов между словами. Взаимодействие с программой может осуществляться следующим образом:

Введите строку: For while and do

Слов: 4

Букв: 13

Условие цикла while проверяет, не является ли нажатая клавиша клавишей Enter, что соответствует выдаче функцией getche() символа, соответствующего управляющей последовательности '\r'. При нажатии клавиши Enter цикл и про- грамма завершаются.

Условия с присваиванием

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

Приведем измененную версию предыдущей программы, названную CHCNT2:

// chcnt2.cpp

// подсчет числа слов и символов в строке

#include <iostream>

using namespace std;

#include <conio.h> // для getche()

int main()

{

int chcount = 0;

int wdcount = 1; // пробел между двумя словами

char ch;

while((ch = getche()) != '\r') // цикл, пока не нажата клавиша Enter

{

if(ch == ' ') // если введен пробел,

wdcount++; // инкрементировать счетчик слов

else // иначе

chcount++; // инкрементировать число символов

} // вывод результатов

cout << "\nСлов: " << wdcount << endl;

cout << "Букв: " << chcount << endl;

return 0;

}

Значение, возвращаемое функцией getche(), присваивается переменной ch, как и раньше, но сама операция присваивания находится прямо внутри условия цикла while. Присвоенное значение сравнивается с '\r' для того, чтобы выяснить, продолжать выполнение цикла или нет. Эта конструкция работает правильно, потому что операция присваивания значения сама получает это значение. Если, к примеру, функция getche() возвращает символ 'a', то при этом не только про- исходит присваивание значения 'a' переменной ch, но само выражение

(ch = getche())

получает значение, равное 'a', которое участвует в проверке.

Тот факт, что операции присваивания имеют собственное значение, приме- няется при множественном присваивании, таком, как

int x, y, z; x = у = z = 0;

Подобные конструкции являются абсолютно корректными в C++. Сначала переменной z присваивается значение 0, которое затем присваивается перемен- ной у. После этого выражение y = z = 0 получает значение 0, которое присваивается переменной x.

Внешние круглые скобки в выражении

(ch = getche())

необходимы, поскольку операция присваивания = имеет более низкий приори- тет, чем операция отношения !=. Если бы скобки отсутствовали, то выражение

while((ch = getche()) != '\r')

присваивало бы истинное или ложное значение переменной ch, что было бы не- правильно для нашего алгоритма.

Таким образом, оператор while в программе CHCNT2 выполняет много полез- ных действий. Он не только проверяет, является ли значение переменной ch символом '\r', но еще получает символ с клавиатуры и присваивает его перемен- ной ch. Непросто с одного взгляда понять все действия этого оператора.

Вложенные ветвления if...else

Возможно, вам приходилось видеть приключенческие игры, предназначенные для ранних версий MS DOS. Их суть заключалась в следующем: играющий дви- гал своего «героя» по воображаемому ландшафту и замкам среди волшебников, сокровищ и т. д., нарисованных с помощью текстовых символов. Следующая программа, ADIFELSE, напоминает небольшую часть такой приключенческой игры.

// adifelse.cpp

// приключенческая игра с применением ветвления if...else #include <iostream> using namespace std;

#include <conio.h> // для getche()

int main() {

char dir = 'a';

int x = 10, y = 10;

cout << "Нажмите Enter для выхода...\n";

while(dir != '\r') // пока не будет нажата клавиша Enter

{

cout << "\nВаши координаты: " << x << ", " << y;

cout << "\nВыберите направление (n, s, e, w): ";

dir = getche(); // ввод символа

if(dir == 'n') // движение на север

y--;

else

if(dir == 's') // движение на юг

y++;

else

if(dir == 'e') // движение на восток

x++;

else

if(dir == 'w') // движение на запад

x--;

} // конец цикла while

return 0;

} // конец функции main()

Когда игра начинается, вы оказываетесь на бесплодном участке земли. Вы можете передвигаться на север, юг, запад и восток, а программа будет следить за вашими передвижениями и сообщать ваши текущие координаты. Начало дви­жения находится в точке с координатами (10, 10). С вашим героем не будет происходить ничего интересного, куда бы он ни пошел; пустая земля простира­ется во всех направлениях, как видно на рис. 3.11. Позже мы внесем в эту игру немного разнообразия.

Вот пример взаимодействия с нашей игрой:

Ваши координаты: 10, 10

Выберите направление (n,s,e,w): n

Ваши координаты: 10, 9

Выберите направление (n,s,e,w): e

Ваши координаты: 11, 9

Выберите направление (n,s,e,w):