Глава 4: Инструкции управления



 

В этой главе вы узнаете, как управлять ходом выполнения С++‑программы. Существует три категории управляющих инструкций: инструкции выбора (if, switch), итерационные инструкции (состоящие из for‑, while‑ и do‑while‑циклов) и инструкции перехода (break, continue, return и goto).

За исключением return, все остальные перечисленные выше инструкции описаны в этой главе.

 

Инструкция if

 

Инструкция if позволяет сделать выбор между двумя выполняемыми ветвями программы.

Инструкция if была представлена в главе 2, но здесь мы рассмотрим ее более детально. Полный формат ее записи таков.

 

 

Здесь под элементом инструкция понимается одна инструкция языка C++. Часть else необязательна. Вместо элемента инструкция может быть использован блок инструкций. В этом случае формат записи if ‑инструкции принимает такой вид.

 

 

Если элемент выражение , который представляет собой условное выражение, при вычислении даст значение ИСТИНА , будет выполнена if ‑инструкция; в противном случае else ‑инструкция (если таковая существует). Обе инструкции никогда не выполняются. Условное выражение, управляющее выполнением if ‑инструкции, может иметь любой тип, действительный для С++‑выражений, но главное; чтобы результат его вычисления можно было интерпретировать как значение ИСТИНА или ЛОЖЬ .

Использование if ‑инструкции рассмотрим на примере программы, которая представляет собой версию игры "Угадай магическое число" . Программа генерирует случайное число и предлагает вам его угадать. Если вы угадываете число, программа выводит на экран сообщение одобрения ** Правильно ** . В этой программе представлена еще одна библиотечная функция rand() , которая возвращает случайным образом выбранное целое число. Для использования этой функции необходимо включить в программу заголовок <cstdlib> .

 

 

В этой программе для проверки того, совпадает ли с "магическим числом" вариант, предложенный пользователем, используется оператор отношения "==" . При совпадении чисел на экран выводится сообщение ** Правильно ** .

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

 

Условное выражение

 

Иногда новичков в C++ сбивает с толку тот факт, что для управления if‑инструкцией можно использовать любое действительное С++‑выражение. Другими словами, тип выражения необязательно ограничивать операторами отношений и логическими операторами или операндами типа bool. Главное, чтобы результат вычисления условного выражения можно было интерпретировать как значение ИСТИНА или ЛОЖЬ. Как вы помните из предыдущей главы, нуль автоматически преобразуется в false, а все ненулевые значения– в true. Это означает, что любое выражение, которое дает в результате нулевое или ненулевое значение, можно использовать для управления if‑инструкцией. Например, следующая программа считывает с клавиатуры два целых числа и отображает частное от деления первого на второе. Чтобы не допустить деления на нуль, в программе используется if‑инструкция.

 

 

Обратите внимание на то, что значение переменной b (делимое) сравнивается с нулем с помощью инструкции if(b) , а не инструкции if(b!=0) . Дело в том, что, если значение b равно нулю, условное выражение, управляющее инструкцией if , оценивается как ЛОЖЬ , что приводит к выполнению else ‑ветви. В противном случае (если b содержит ненулевое значение) условие оценивается как ИСТИНА , и деление благополучно выполняется. Нет никакой необходимости использовать следующую if‑инструкцию, которая к тому же не свидетельствует о хорошем стиле программирования на C++.

 

 

Эта форма if‑инструкции считается устаревшей и потенциально неэффективной.

 

Вложенные if‑инструкции

 

Вложенные if‑инструкции образуются в том случае, если в качестве элемента инструкция (см. полный формат записи) используется другая if‑инструкция. Вложенные if‑инструкции очень популярны в программировании. Главное здесь – помнить, что else‑инструкция всегда относится к ближайшей if‑инструкции, которая находится внутри того же программного блока, но еще не связана ни с какой другой else‑инструкцией. Вот пример.

 

 

Как утверждается в комментариях, последняя else ‑инструкция не связана с инструкцией if(j) , поскольку они не находятся в одном блоке (несмотря на то, что эта if‑инструкция – ближайшая, которая не имеет при себе "else‑пары" ). Внутренняя else ‑инструкция связана с инструкцией if(k) , поскольку она – ближайшая и находится внутри того же блока.

Вложенная if‑инструкцияэто инструкция, которая используется в качестве элемента инструкция любой другой if‑ или elsе‑инструкции.

Язык C++ позволяет 256 уровней вложения, но на практике редко приходится вкладывать if‑инструкции на "такую глубину". продемонстрируем использование вложенных инструкций с помощью очередного усовершенствования программы "Угадай магическое число" (здесь игрок получает реакцию программы на неправильный ответ).

 

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

 

Очень распространенной в программировании конструкцией, в основе которой лежит вложенная if‑инструкция, является "лестница" if‑else‑if . Ее можно представить в следующем виде.

 

 

Здесь под элементом условие понимается условное выражение. Условные выражения вычисляются сверху вниз. Как только в какой‑нибудь ветви обнаружится истинный результат, будет выполнена инструкция, связанная с этой ветвью, а вся остальная "лестница" опускается. Если окажется, что ни одно из условий не является истинным, будет выполнена последняя else‑инструкция (можно считать, что она выполняет роль условия, которое действует по умолчанию). Если последняя else‑инструкция не задана, а все остальные оказались ложными, то вообще никакое действие не будет выполнено.

"Лестница" if‑else‑ifэто последовательность вложенных if‑else‑инструкций.

Работа if‑else‑if ‑ "лестницы" демонстрируется в следующей программе.

 

 

Результаты выполнения этой программы таковы.

 

 

Как видите, последняя else‑инструкция выполняется только в том случае, если все предыдущие if‑условия дали ложный результат.

 

Цикл for

 

Цикл forсамый универсальный цикл C++.

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

Итак, общий формат записи цикла for для многократного выполнения одной инструкции имеет следующий вид.

 

 

Если цикл for предназначен для многократного выполнения не одной инструкции, а программного блока, то его общий формат выглядит так.

 

 

Элемент инициализация обычно представляет собой инструкцию присваивания, которая устанавливает управляющую переменную цикла равной начальному значению. Эта переменная действует в качестве счетчика, который управляет работой цикла. Элемент выражение представляет собой условное выражение, в котором тестируется значение управляющей переменной цикла. Результат этого тестирования определяет, выполнится цикл for еще раз или нет. Элемент инкремент – это выражение, которое определяет, как изменяется значение управляющей переменной цикла после каждой итерации. Обратите внимание на то, что все эти элементы цикла for должны отделяться точкой с запятой. Цикл for будет выполняться до тех пор, пока вычисление элемента выражение дает истинный результат. Как только это условное выражение станет ложным, цикл завершится, а выполнение программы продолжится с инструкции, следующей за циклом for.

В следующей программе цикл for используется для вывода значений квадратного корня, извлеченных из чисел от 1 до 99 . Обратите внимание на то, что в этом примере управляющая переменная цикла называется num .

 

 

Вот как выглядят первые строки результатов, выводимых этой программой.

 

 

В этой программе использована еще одна стандартная функция C++: sqrt() . Эта функция возвращает значение квадратного корня из своего аргумента. Аргумент должен иметь тип double , и именно поэтому при вызове функции sqrt() параметр num приводится к типу double . Сама функция также возвращает значение типа double . Обратите внимание на то, что в программу включен заголовок <cmath> , поскольку этот заголовочный файл обеспечивает поддержку функции sqrt() .

Важно! Помимо функции sqrt(), C++ поддерживает широкий набор других математических функций, например sin(), cos(), tan(), log(), ceil() и floor(). Помните, что все математические функции требуют включения в программу заголовка <cmath> .

Управляющая переменная цикла for может изменяться как с положительным, так и с отрицательным приращением, причем величина этого приращения также может быть любой. Например, следующая программа выводит числа в диапазоне от 100 до ‑100 с декрементом, равным 5 .

 

 

Важно понимать, что условное выражение всегда тестируется в начале выполнения цикла for. Это значит, что если первая же проверка условия даст значение ЛОЖЬ, код тела цикла не выполнится ни разу. Вот пример:

 

 

Этот цикл никогда не выполнится, поскольку уже при входе в него значение его управляющей переменной count больше пяти. Это делает условное выражение (count < 5 ) ложным с самого начала. Поэтому даже одна итерация этого цикла не будет выполнена.

 

Вариации на тему цикла for

 

Цикл for – одна из наиболее гибких инструкций в С++, поскольку она позволяет получить широкий диапазон вариантов ее использования. Например, для управления циклом for можно использовать несколько переменных. Рассмотрим следующий фрагмент кода.

 

 

Здесь запятыми отделяются две инструкции инициализации и два инкрементных выражения. Это делается для того, чтобы компилятор "понимал", что существует две инструкции инициализации и две инструкции инкремента (декремента). В C++ запятая представляет собой оператор, который, по сути, означает "сделай это и то" . Другие применения оператора "запятая" мы рассмотрим ниже в этой книге, но чаще всего он используется в цикле for. При входе в данный цикл инициализируются обе переменные – х и у . После выполнения каждой итерации цикла переменная х инкрементируется, а переменная у декрементируется. Использование нескольких управляющих переменных в цикле иногда позволяет упростить алгоритмы. В разделах инициализации и инкремента цикла for можно использовать любое количество инструкций, но обычно их число не превышает двух.

Условным выражением, которое управляет циклом for, может быть любое допустимое С++‑выражение. При этом оно необязательно должно включать управляющую переменную цикла. В следующем примере цикл будет выполняться до тех пор, пока пользователь не нажмет клавишу на клавиатуре. В этой программе представлена еще одна (очень важная) библиотечная функция: kbhit() . Она возвращает значение ЛОЖЬ, если ни одна клавиша не была нажата на клавиатуре, и значение ИСТИНА в противном случае. Функция не ожидает нажатия клавиши, позволяя тем самым циклу выполняться до тех пор, пока оно не произойдет. Функция kbhit() не определяется стандартом C++, но включена в расширение языка C++, которое поддерживается большинством компиляторов. Для ее использования в программу необходимо включить заголовок <conio.h> . (Этот заголовок необходимо указывать с расширением .h , поскольку он не определен стандартом C++.)

 

 

На каждой итерации цикла вызывается функция kbhit() . Если после запуска программы нажать какую‑нибудь клавишу, эта функция возвратит значение ИСТИНА, в результате чего выражение !kbhit() даст значение ЛОЖЬ, и цикл остановится. Но если не нажимать клавишу, функция возвратит значение ЛОЖЬ, а выражение !kbhit() даст значение ИСТИНА, что позволит циклу продолжать "крутиться".

Важно! Функция kbhit() не входит в состав стандартной библиотеки C++. Дело в том, что стандартная библиотека определяет только минимальный набор функций, который должны иметь все С++‑компиляторы. Функция kbhit() не включена в этот минимальный набор, поскольку не все среды могут поддерживать взаимодействие с клавиатурой. Однако функцию kbhit() поддерживают практически все серийно выпускаемые C++‑ компиляторы. Производители компиляторов могут обеспечить поддержку большего числа функций, чем это необходимо для соблюдения минимальных требований по части стандартной библиотеки C++. Дополнительные же функции позволяют шире использовать возможности среды программирования. Если для вас не проблематичен вопрос переносимости кода в другую среду выполнения, вы можете свободно использовать все функции, поддерживаемые вашим компилятором.

 


Дата добавления: 2018-09-22; просмотров: 313; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!