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

Инструкции

ОО-нотация, разработанная в этой книге, императивна: вычисления специфицируются через команды (commands), также называемые инструкциями (instructions). (Мы избегаем обычно применимого термина оператор (предложение) (statement), поскольку в слове есть оттенок выражения, описывающего факты, а хотелось подчеркнуть императивный характер команды.)

Для имеющих опыт работы с современными языками инструкции выглядят как хорошие знакомые. Исключение составляют некоторые специальные свойства циклов, облегчающие их верификацию. Вот список инструкций: Вызов процедуры, Присваивание, Условие, Множественный выбор, Цикл, Проверка, Отладка, Повторное выполнение, Попытка присваивания.

Вызов процедуры

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

Вызов может быть квалифицированным или неквалифицированным. Для неквалифицированного вызова подпрограммы из включающего класса в качестве цели используется текущий экземпляр класса. Этот вызов имеет вид:

r (без аргументов), или

r (x, y, …) (с аргументами)

Квалифицированный вызов явно называет свою цель, заданную некоторым выражением. Если a — выражение некоторого типа, C — базовый класс этого типа, а — q одна из программ C, то квалифицированный вызов имеет форму a.q. Опять же, за q может следовать список фактических аргументов; a может быть неквалифицированным вызовом функции с аргументами, как в p (m).q (n), где p(m) — это цель. В качестве цели можно также использовать более сложное выражение при условии заключения его в скобки, как в (vector1 + vector2).count.

Также разрешаются квалифицированные вызовы с многоточием в форме: a.q1q2 …qn, где a, так же, как и qi, может включать список фактических аргументов.

Экспорт управляет применением квалифицированных вызовов. Напомним, что компонент f, объявленный в классе B, доступен в классе A ( экспортирован классу ), если предложение feature, объявляющее f, начинается с feature (без дальнейшего уточнения) или feature {X, Y,… }, где один из элементов списка {X, Y,…} является A или предком A. Имеет место:

Правило Квалифицированного Вызова

Квалифицированный вызов вида b.q1. q2…. qn, появляющийся в классе C корректен, только если он удовлетворяет следующим условиям:

  1. Компонент, стоящий после первой точки, q1, должен быть доступен в классе C.
  2. В вызове с многоточием, каждый компонент после второй точки, то есть каждое qi для i > 1, должен быть доступен в классе C.

Чтобы понять причину существования второго правила, отметим, что a.q.r.s — краткая запись для

которая верна только, если q, r и s доступны классу C, в котором появляется этот фрагмент. Не имеет значения, доступно ли r базовому классу типа q, и доступно ли s базовому классу типа r.

Вызовы могут иметь инфиксную или префиксную форму. Выражение a + b, записанное в инфиксной форме, может быть переписано в префиксной форме: a.plus (b). Для обеих форм действуют одинаковые правила применимости.

Присваивание (Assignment)

Инструкция присваивания записывается в виде:

где x — сущность, допускающая запись (writable), а e — выражение совместимого типа. Такая сущность может быть:

  • неконстантным атрибутом включающего класса;
  • локальной сущностью включающей подпрограммы. Для функции допустима сущность Result.

Сущности, не допускающие запись, включают константные атрибуты и формальные аргументы программы — которым, как мы видели, подпрограмма не может присваивать новое значение.

Создание (Creation)

Инструкция создания изучалась в предыдущих лекциях3См. «Инструкция создания» и «Процедуры создания»,
«Динамические структуры: объекты»
. Один из вариантов рассмотрен в «Полиморфное создание»,
«Введение в наследование»
.
в двух ее формах: без процедуры создания, как в create x, и с процедурой создания, как в create x.p (…). В обоих случаях x должна быть сущностью, допускающей запись.

Условная Инструкция (Conditional)

Эта инструкция задает различные формы обработки в зависимости от выполнения определенных условий. Основная форма:

if boolean_expression then
   instruction; instruction; ...
else
   instruction; instruction; ...
end

где каждая ветвь может иметь произвольное число инструкций (а возможно и не иметь их).

Будут выполняться инструкции первой ветви, если boolean_expression верно, а иначе — второй ветви. Можно опустить часть else, если второй список инструкций пуст, что дает:

if boolean_expression then
   instruction; instruction; ...
end

Когда есть более двух возможных случаев, можно избежать вложения (nesting) условных команд в частях else, используя одну или более ветвей elseif, как в:

if c1 then
   instruction; instruction; ...
elseif c2 then
   instruction; instruction; ...
elseif c3 then
   instruction; instruction; ...
...
else
   instruction; instruction; ...
end

где часть else остается факультативной. Это дает возможность избежать вложения

if c1 then
   instruction; instruction; ...
else
   if c2 then
      instruction; instruction; ...
   else
      if c3 then
         instruction; instruction; ...
...
      else
         instruction; instruction; ...
      end
   end
end

Когда необходим множественный разбор случаев, более удобна инструкция множественного выбора inspect, обсуждаемая ниже.

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

Множественный выбор

Инструкция множественного выбора (также известная, как инструкция Case ) производит разбор вариантов, имеющих форму: e = vi, где e — выражение, а vi — константы того же типа. Хотя условная инструкция (if e = v1 then …elseif e = v2 then…) работает, есть две причины, оправдывающие применение специальной инструкции, что является исключением из обычного правила: «если нотация дает хороший способ сделать что-то, нет необходимости вводить другой способ». Вот эти причины:

  • Разбор случаев настолько распространен, что заслуживает особого синтаксиса, увеличивающего ясность, позволяя избежать бесполезного повторения » e = «.
  • Компиляторы могут использовать особенно эффективную технику реализации, — таблицу переходов ( jump table ), — неприменимую к общим условным инструкциям и избегающую явных проверок.

Что касается типа анализируемых величин (тип e и vi ), то инструкции множественного выбора достаточно поддерживать только целые и булевы значения. Согласно правилу, они фактически должны объявляться либо все как INTEGER, либо как CHARACTER. Общая форма инструкции такова:

inspect
   e
when v1 then
   instruction; instruction; ...
when v2 then
   instruction; instruction; ...
...
else
   instruction; instruction; ...
end

Все значения vi должны быть различными; часть else факультативна; каждая из ветвей может иметь произвольное число инструкций или не иметь их.

Инструкция действует так: если значение e равно значению vi (это может быть только для одного из них), выполняются инструкции соответствующей ветви; иначе, выполняются инструкции в ветви else, если они есть.

Если отсутствует else, и значение e не соответствует ни одному vi, то возникает исключительная ситуация («Некорректно проверяемое значение»). Это решение может вызвать удивление, поскольку соответствующая условная инструкция в этом случае ничего не делает. Но оно характеризует специфику инструкции множественного выбора. Когда вы пишете inspect с набором значений vi, нужно включить ветвь else, даже пустую, если вы понимаете, что во время выполнения значения e могут не соответствовать никаким vi. Если вы не включаете else, то это эквивалентно явному утверждению: «значение e всегда является одним из vi «. Проверяя это утверждение и создавая исключительную ситуацию при его нарушении, реализация оказывает нам услугу. Бездействие в данной ситуации — означает ошибку — в любом случае, ее необходимо устранить как можно раньше.

Одно из частых приложений инструкции множественного выбора — анализ символа, введенного пользователем4Это элементарная схема. О более сложных технических приемах обработки пользовательских команд см. лекцию 3 курса «Основы объектно-ориентированного проектирования«.
:

inspect
   first_input_letter
when 'D' then
   "Удалить строку"
when 'I' then
   "Вставить строку"
...
else
   message ("Неопознанная команда; введите H для получения справки")
end

Когда значения vi целые, то они могут быть определены как уникальные (unique values), концепция которых рассмотрена в следующей лекции. Это делает возможным в объявлении определить несколько абстрактных констант, например, Do, Re, Mi, Fa, Sol, La, Si: INTEGER is unique, и затем анализировать их в инструкции: inspect note when Do then…when Re then…end.

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

Циклы

Синтаксис циклов описан при обсуждении Проектирования по Контракту (
«Проектирование по контракту: построение надежного ПО»
):

from
   initialization_instructions
invariant
   invariant
variant
   variant
until
   exit_condition
loop
   loop_instructions
end

Предложения invariant и variant факультативны. Предложение from требуется, хотя и может быть пустым. Оно задает инициализацию параметров цикла. Не рассматривая сейчас факультативные предложения, выполнение цикла можно описать следующим образом. Вначале происходит инициализация, и выполняются initialization_instructions. Затем следует «циклический процесс», определяемый так: если exit_condition верно, то циклический процесс — пустая инструкция ( null instruction ); если условие неверно, то циклический процесс — это выполнение loop_instructions, затем следует (рекурсивно) повторение циклического процесса.

Проверка

Инструкция проверки рассматривалась при обсуждении утверждений (
«Проектирование по контракту: построение надежного ПО»
). Она говорит, что определенные утверждения должны удовлетворяться в определенных точках:

check
   assertion -- Одно или больше предложений
end

Отладка

Инструкция отладки является средством условной компиляции. Она записывается так:

debug instruction; instruction; ... end

В файле управления (Ace-файле) для каждого класса можно включить или отключить параметр debug. При его включении все инструкции отладки данного класса выполняются, при отключении — они не влияют на выполнение.

Эту инструкцию можно использовать для включения специальных действий, выполняющихся только в режиме отладки, например, печати некоторых величин.

Повторение вычислений

Инструкция повторного выполнения рассматривалась при обсуждении исключительных ситуаций (
«Когда контракт нарушается: обработка исключений»
). Она появляется только в предложении rescue, повторно запуская тело подпрограммы, работа которой была прервана.

Повторение вычислений

Повторение вычислений

Инструкция повторного выполнения рассматривалась при обсуждении исключительных ситуаций (лекция 12). Она появляется только в предложении rescue, повторно запуская тело подпрограммы, работа которой была прервана.

Читайте также

2.2. Повторение (операторы цикла)

2.2. Повторение (операторы цикла)
Циклом называется группа операторов, которая выполняется повторно. После каждого повторения проверяется условие, называемое условием окончания цикла, по которому принимается решение продолжать повторение или закончить

20. Квадратный трехчлен, или Пакет Для Алгебраических Вычислений

20.
Квадратный трехчлен,
или Пакет Для Алгебраических Вычислений
Основная трудность, с которой сталкивается программист в большинстве языков программирования, — необходимость при записи вычислений разбивать свои уравнения на мелкие части. Так, если требуется

Выполнение вычислений в запросах

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

Повторение с помощью циклов

Повторение с помощью циклов
Управляющие структуры типа «цикл» используются тогда, когда необходимо повторить выполнение некоторого блока программного кода несколько раз. Повторение одного или нескольких операторов является главным средством выполнения многих

Повторение под управлением циклов For…Next

Повторение под управлением циклов For…Next
Если уже перед выполнением цикла известно, сколько раз он должен выполняться, используйте цикл For. . . Next. Число проходов цикла задается значениями начало и коней, которые могут быть целыми числами, переменными и даже сложными

12. Кодирование параллельных вычислений

12. Кодирование параллельных вычислений
РезюмеЕсли ваше приложение использует несколько потоков или процессов, следует минимизировать количество совместно используемых объектов, где это только можно (см. рекомендацию 10), и аккуратно работать с

31. Не пишите код, который зависит от порядка вычислений аргументов функции

31. Не пишите код, который зависит от порядка вычислений аргументов функции
РезюмеПорядок вычисления аргументов функции не определен, поэтому никогда не полагайтесь на то, что аргументы будут вычисляться в той или иной очередности.ОбсуждениеНа начальных этапах развития

5.3. Выполнение вычислений с датами и временем

5.3. Выполнение вычислений с датами и временем
ПроблемаТребуется узнать количество времени, прошедшего между двумя точками даты/времени.РешениеЕсли обе временные точки находятся между 1970 и 2038 годами, то используйте тип time_t и функцию difftime, определенную в заголовочном

Повторение и свобода

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

Повторение пройденного

Повторение пройденного
Примеры доступа к объектам Pocket Outlook рассматривались применительно к карманным компьютерам. Но теперь надо воссоздать их, опираясь уже на смартфоны. Сам код примеров останется практически неизменным. Но при этом изменится логика управления

Отмена и повторение изменений

Отмена и повторение изменений
Многие действия, произведенные над проектом, можно отменить. Выполняется это с помощью команды меню Монтаж ? Отменить <действие>. Вместо <действие> после слова Отменить в названии пункта меню записано, какое конкретно действие будет

27 Повторение и вознаграждение

27
Повторение и вознаграждение
Многие вещи, начиная от сумок для покупок и заканчивая картриджами, мы используем повторно. Почему бы тогда не попробовать применять повторно код? Почему бы не использовать повторно макеты и модели вместо того, чтобы создавать их заново?

Повторение

Повторение
Вполне возможно, что из 20 кадров прекрасной водяной белой лилии у вас как минимум 15 соответствуют всем требуемым стандартам и вы можете сократить число снимков, в которые влюблены, максимум до 10. Ну и пусть ракурс практически везде одинаковый, она ведь такая

Объектно-ориентированный стиль вычислений

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

Повторение программы, толерантной к неисправностям

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

Инструкция действует так: если значение e равно значению vi (это может быть только для одного из них), выполняются инструкции соответствующей ветви; иначе, выполняются инструкции в ветви else, если они есть.

Если отсутствует else, и значение e не соответствует ни одному vi, то возникает исключительная ситуация («Некорректно проверяемое значение»). Это решение может вызвать удивление, поскольку соответствующая условная инструкция в этом случае ничего не делает. Но оно характеризует специфику инструкции множественного выбора. Когда вы пишете inspect с набором значений vi, нужно включить ветвь else, даже пустую, если вы понимаете, что во время выполнения значения e могут не соответствовать никаким vi. Если вы не включаете else, то это эквивалентно явному утверждению: «значение e всегда является одним из vi«. Проверяя это утверждение и создавая исключительную ситуацию при его нарушении, реализация оказывает нам услугу. Бездействие в данной ситуации — означает ошибку — в любом случае, ее необходимо устранить как можно раньше.

Одно из частых приложений инструкции множественного выбора — анализ символа, введенного пользователем13.4):

inspect

first_input_letter

when 'D' then

"Удалить строку"

when 'I' then

"Вставить строку"

...

else

message ("Неопознанная команда; введите H для получения справки")

end

Когда значения vi целые, то они могут быть определены как уникальные (unique values), концепция которых рассмотрена в следующей лекции. Это делает возможным в объявлении определить несколько абстрактных констант, например, Do, Re, Mi, Fa, Sol, La, Si: INTEGER is unique, и затем анализировать их в инструкции: inspect note when Do then…when Re then…end.

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

Циклы

Синтаксис циклов описан при обсуждении Проектирования по Контракту (лекция 11):

from

initialization_instructions

invariant

invariant

variant

variant

until

exit_condition

loop

loop_instructions

end

Предложения invariant и variant факультативны. Предложение from требуется, хотя и может быть пустым. Оно задает инициализацию параметров цикла. Не рассматривая сейчас факультативные предложения, выполнение цикла можно описать следующим образом. Вначале происходит инициализация, и выполняются initialization_instructions. Затем следует «циклический процесс», определяемый так: если exit_condition верно, то циклический процесс — пустая инструкция (null instruction); если условие неверно, то циклический процесс — это выполнение loop_instructions, затем следует (рекурсивно) повторение циклического процесса.

Проверка

Инструкция проверки рассматривалась при обсуждении утверждений (лекция 11). Она говорит, что определенные утверждения должны удовлетворяться в определенных точках:

check

assertion -- Одно или больше предложений

end

Отладка

Инструкция отладки является средством условной компиляции. Она записывается так:

debug instruction; instruction; ... end

В файле управления (Ace-файле) для каждого класса можно включить или отключить параметр debug. При его включении все инструкции отладки данного класса выполняются, при отключении — они не влияют на выполнение.

Эту инструкцию можно использовать для включения специальных действий, выполняющихся только в режиме отладки, например, печати некоторых величин.

Повторение вычислений

Инструкция повторного выполнения рассматривалась при обсуждении исключительных ситуаций (лекция 12). Она появляется только в предложении rescue, повторно запуская тело подпрограммы, работа которой была прервана.

Выражения

Выражение задает вычисление, вырабатывающее значение, — объект или ссылку на объект. Выражениями являются:

[x]. неименованные (манифестные) константы;

[x]. сущности (атрибуты, локальные сущности, формальные аргументы, Result);

[x]. вызовы функций;

[x]. выражения с операторами (технически — это специальный случай вызова функций);

[x]. Current.

Манифестные константы

Неименованная или манифестная константа задается значением, синтаксис которого позволяет определить и тип этого значения, например, целое 0. Этим она отличается от символьной константы, чье имя не зависит от значения.

Булевых констант две, — True и False. Целые константы имеют обычную форму, например:

453 -678 +66623

В записи вещественных (real) констант присутствует десятичная точка. Целая, либо дробная часть может отсутствовать. Может присутствовать знак и экспонента, например:

52.5 -54.44 +45.01 .983 -897. 999.e12

Символьные константы состоят из одного символа в одинарных кавычках, например, ‘A’. Для цепочек из нескольких символов используется библиотечный класс STRING, описанный ниже.

Вызовы функций

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

b.f

b.g(x, y, ...)

b.h(u, v).i.j(x, y, ...)

Правило квалифицированного вызова, приведенное для процедур, применимо также к вызовам функций.

Текущий объект

Зарезервированное слово Current означает текущий экземпляр класса и может использоваться в выражении. Само Current — тоже выражение, а не сущность, допускающая запись. Значит присваивание Current, например, Current := some_value будет синтаксически неверным.

вернуться

анализ символа, введенного пользователеманализ символа, введенного пользователем 13.4

Инструкции

ОО-нотация, разработанная в этой книге, императивна: вычисления специфицируются через команды (commands), также называемые инструкциями (instructions). (Мы избегаем обычно применимого термина оператор (предложение) (statement), поскольку в слове есть оттенок выражения, описывающего факты, а хотелось подчеркнуть императивный характер команды.)

Для имеющих опыт работы с современными языками инструкции выглядят как хорошие знакомые. Исключение составляют некоторые специальные свойства циклов, облегчающие их верификацию. Вот список инструкций: Вызов процедуры, Присваивание, Условие, Множественный выбор, Цикл, Проверка, Отладка, Повторное выполнение, Попытка присваивания.

Вызов процедуры

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

Вызов может быть квалифицированным или неквалифицированным. Для неквалифицированного вызова подпрограммы из включающего класса в качестве цели используется текущий экземпляр класса. Этот вызов имеет вид:

r (без аргументов), или

r (x, y, …) (с аргументами)

Квалифицированный вызов явно называет свою цель, заданную некоторым выражением. Если a — выражение некоторого типа, C — базовый класс этого типа, а — q одна из программ C, то квалифицированный вызов имеет форму a.q. Опять же, за q может следовать список фактических аргументов; a может быть неквалифицированным вызовом функции с аргументами, как в p (m).q (n), где p(m) — это цель. В качестве цели можно также использовать более сложное выражение при условии заключения его в скобки, как в (vector1 + vector2).count.

Также разрешаются квалифицированные вызовы с многоточием в форме: a.q1q2 …qn, где a, так же, как и qi, может включать список фактических аргументов.

Экспорт управляет применением квалифицированных вызовов. Напомним, что компонент f, объявленный в классе B, доступен в классе A ( экспортирован классу ), если предложение feature, объявляющее f, начинается с feature (без дальнейшего уточнения) или feature {X, Y,… }, где один из элементов списка {X, Y,…} является A или предком A. Имеет место:

Правило Квалифицированного Вызова

Квалифицированный вызов вида b.q1. q2…. qn, появляющийся в классе C корректен, только если он удовлетворяет следующим условиям:

  1. Компонент, стоящий после первой точки, q1, должен быть доступен в классе C.
  2. В вызове с многоточием, каждый компонент после второй точки, то есть каждое qi для i > 1, должен быть доступен в классе C.

Чтобы понять причину существования второго правила, отметим, что a.q.r.s — краткая запись для

которая верна только, если q, r и s доступны классу C, в котором появляется этот фрагмент. Не имеет значения, доступно ли r базовому классу типа q, и доступно ли s базовому классу типа r.

Вызовы могут иметь инфиксную или префиксную форму. Выражение a + b, записанное в инфиксной форме, может быть переписано в префиксной форме: a.plus (b). Для обеих форм действуют одинаковые правила применимости.

Присваивание (Assignment)

Инструкция присваивания записывается в виде:

где x — сущность, допускающая запись (writable), а e — выражение совместимого типа. Такая сущность может быть:

  • неконстантным атрибутом включающего класса;
  • локальной сущностью включающей подпрограммы. Для функции допустима сущность Result.

Сущности, не допускающие запись, включают константные атрибуты и формальные аргументы программы — которым, как мы видели, подпрограмма не может присваивать новое значение.

Создание (Creation)

Инструкция создания изучалась в предыдущих лекциях3См. «Инструкция создания» и «Процедуры создания»,
«Динамические структуры: объекты»
. Один из вариантов рассмотрен в «Полиморфное создание»,
«Введение в наследование»
.
в двух ее формах: без процедуры создания, как в create x, и с процедурой создания, как в create x.p (…). В обоих случаях x должна быть сущностью, допускающей запись.

Условная Инструкция (Conditional)

Эта инструкция задает различные формы обработки в зависимости от выполнения определенных условий. Основная форма:

if boolean_expression then
   instruction; instruction; ...
else
   instruction; instruction; ...
end

где каждая ветвь может иметь произвольное число инструкций (а возможно и не иметь их).

Будут выполняться инструкции первой ветви, если boolean_expression верно, а иначе — второй ветви. Можно опустить часть else, если второй список инструкций пуст, что дает:

if boolean_expression then
   instruction; instruction; ...
end

Когда есть более двух возможных случаев, можно избежать вложения (nesting) условных команд в частях else, используя одну или более ветвей elseif, как в:

if c1 then
   instruction; instruction; ...
elseif c2 then
   instruction; instruction; ...
elseif c3 then
   instruction; instruction; ...
...
else
   instruction; instruction; ...
end

где часть else остается факультативной. Это дает возможность избежать вложения

if c1 then
   instruction; instruction; ...
else
   if c2 then
      instruction; instruction; ...
   else
      if c3 then
         instruction; instruction; ...
...
      else
         instruction; instruction; ...
      end
   end
end

Когда необходим множественный разбор случаев, более удобна инструкция множественного выбора inspect, обсуждаемая ниже.

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

Множественный выбор

Инструкция множественного выбора (также известная, как инструкция Case ) производит разбор вариантов, имеющих форму: e = vi, где e — выражение, а vi — константы того же типа. Хотя условная инструкция (if e = v1 then …elseif e = v2 then…) работает, есть две причины, оправдывающие применение специальной инструкции, что является исключением из обычного правила: «если нотация дает хороший способ сделать что-то, нет необходимости вводить другой способ». Вот эти причины:

  • Разбор случаев настолько распространен, что заслуживает особого синтаксиса, увеличивающего ясность, позволяя избежать бесполезного повторения » e = «.
  • Компиляторы могут использовать особенно эффективную технику реализации, — таблицу переходов ( jump table ), — неприменимую к общим условным инструкциям и избегающую явных проверок.

Что касается типа анализируемых величин (тип e и vi ), то инструкции множественного выбора достаточно поддерживать только целые и булевы значения. Согласно правилу, они фактически должны объявляться либо все как INTEGER, либо как CHARACTER. Общая форма инструкции такова:

inspect
   e
when v1 then
   instruction; instruction; ...
when v2 then
   instruction; instruction; ...
...
else
   instruction; instruction; ...
end

Все значения vi должны быть различными; часть else факультативна; каждая из ветвей может иметь произвольное число инструкций или не иметь их.

Инструкция действует так: если значение e равно значению vi (это может быть только для одного из них), выполняются инструкции соответствующей ветви; иначе, выполняются инструкции в ветви else, если они есть.

Если отсутствует else, и значение e не соответствует ни одному vi, то возникает исключительная ситуация («Некорректно проверяемое значение»). Это решение может вызвать удивление, поскольку соответствующая условная инструкция в этом случае ничего не делает. Но оно характеризует специфику инструкции множественного выбора. Когда вы пишете inspect с набором значений vi, нужно включить ветвь else, даже пустую, если вы понимаете, что во время выполнения значения e могут не соответствовать никаким vi. Если вы не включаете else, то это эквивалентно явному утверждению: «значение e всегда является одним из vi «. Проверяя это утверждение и создавая исключительную ситуацию при его нарушении, реализация оказывает нам услугу. Бездействие в данной ситуации — означает ошибку — в любом случае, ее необходимо устранить как можно раньше.

Одно из частых приложений инструкции множественного выбора — анализ символа, введенного пользователем4Это элементарная схема. О более сложных технических приемах обработки пользовательских команд см. лекцию 3 курса «Основы объектно-ориентированного проектирования«.
:

inspect
   first_input_letter
when 'D' then
   "Удалить строку"
when 'I' then
   "Вставить строку"
...
else
   message ("Неопознанная команда; введите H для получения справки")
end

Когда значения vi целые, то они могут быть определены как уникальные (unique values), концепция которых рассмотрена в следующей лекции. Это делает возможным в объявлении определить несколько абстрактных констант, например, Do, Re, Mi, Fa, Sol, La, Si: INTEGER is unique, и затем анализировать их в инструкции: inspect note when Do then…when Re then…end.

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

Циклы

Синтаксис циклов описан при обсуждении Проектирования по Контракту (
«Проектирование по контракту: построение надежного ПО»
):

from
   initialization_instructions
invariant
   invariant
variant
   variant
until
   exit_condition
loop
   loop_instructions
end

Предложения invariant и variant факультативны. Предложение from требуется, хотя и может быть пустым. Оно задает инициализацию параметров цикла. Не рассматривая сейчас факультативные предложения, выполнение цикла можно описать следующим образом. Вначале происходит инициализация, и выполняются initialization_instructions. Затем следует «циклический процесс», определяемый так: если exit_condition верно, то циклический процесс — пустая инструкция ( null instruction ); если условие неверно, то циклический процесс — это выполнение loop_instructions, затем следует (рекурсивно) повторение циклического процесса.

Проверка

Инструкция проверки рассматривалась при обсуждении утверждений (
«Проектирование по контракту: построение надежного ПО»
). Она говорит, что определенные утверждения должны удовлетворяться в определенных точках:

check
   assertion -- Одно или больше предложений
end

Отладка

Инструкция отладки является средством условной компиляции. Она записывается так:

debug instruction; instruction; ... end

В файле управления (Ace-файле) для каждого класса можно включить или отключить параметр debug. При его включении все инструкции отладки данного класса выполняются, при отключении — они не влияют на выполнение.

Эту инструкцию можно использовать для включения специальных действий, выполняющихся только в режиме отладки, например, печати некоторых величин.

Повторение вычислений

Инструкция повторного выполнения рассматривалась при обсуждении исключительных ситуаций (
«Когда контракт нарушается: обработка исключений»
). Она появляется только в предложении rescue, повторно запуская тело подпрограммы, работа которой была прервана.

Когда значения vi целые, то они могут быть определены как уникальные (unique values), концепция которых рассмотрена в следующей лекции. Это делает возможным в объявлении определить несколько абстрактных констант, например, Do, Re, Mi, Fa, Sol, La, Si: INTEGER is unique, и затем анализировать их в инструкции: inspect note when Do then…when Re then…end.

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

Циклы

Синтаксис циклов описан при обсуждении Проектирования по Контракту (лекция 11):

from initialization_instructions invariant

invariant variant variant until

exit_condition loop loop_instructions end

Предложения invariant и variant факультативны. Предложение from требуется, хотя и может быть пустым. Оно задает инициализацию параметров цикла. Не рассматривая сейчас факультативные предложения, выполнение цикла можно описать следующим образом. Вначале происходит инициализация, и выполняются initialization_instructions. Затем следует «циклический процесс», определяемый так: если exit_condition верно, то циклический процесс — пустая инструкция ( null instruction ); если условие неверно, то циклический процесс — это выполнение loop_instructions, затем следует (рекурсивно) повторение циклического процесса.

Проверка

Инструкция проверки рассматривалась при обсуждении утверждений (лекция 11). Она говорит, что определенные утверждения должны удовлетворяться в определенных точках:

check

assertion — Одно или больше предложений end

Отладка

Инструкция отладки является средством условной компиляции. Она записывается так:

debug instruction; instruction; … end

В файле управления (Ace-файле) для каждого класса можно включить или отключить параметр debug. При его включении все инструкции отладки данного класса выполняются, при

отключении — они не влияют на выполнение.

Эту инструкцию можно использовать для включения специальных действий, выполняющихся только в режиме отладки, например, печати некоторых величин.

Повторение вычислений

Инструкция повторного выполнения рассматривалась при обсуждении исключительных ситуаций (лекция 12). Она появляется только в предложении rescue, повторно запуская тело подпрограммы, работа которой была прервана.

Соседние файлы в папке books

  • #
  • #
  • #

Цикл for/in

Еще одной важной инструкцией языка Python является цикл for/in, который можно смело назвать универсальным
итератором последовательностей, поскольку он позволяет выполнять обход элементов в любых объектах, поддерживающих возможность совершения итераций. При этом сюда относятся как встроенные объекты, например, строки,
списки или словари, так и объекты, создаваемые с помощью классов (о них чуть позже).

В общем виде для цикла for используется следующий синтаксис:

 for <Переменная> in <Итерируемый объект>:
    <Тело цикла>
 else:
    <Дополнительный блок инструкций> 

В ходе выполнения цикла for интерпретатор один за другим присваивает переменной заголовка элементы итерируемого объекта и выполняет для них инструкции
тела цикла (см. пример №1). Если цикл нужно прервать, используется ключевое слово break, которое передает управление
инструкции, следующей сразу за циклом. Кроме того, в цикле for разрешается использовать необязательный блок else,
набор инструкций которого выполняется только после удачного завершения цикла (т.е. при отсутствии ошибки или прерывания за счет использования инструкции
break).

# Формируем список.
li = [2, 5, 9, 4]
    
# Задаем начальную сумму.
sum = 0

# Запускаем цикл по элементам списка.
for elem in li:
    
    # Если сумма чисел меньше 8,
    if sum < 8:
        # наращиваем ее.    
        sum += elem
        # Выводим для наглядности на экран.
        print(sum)
    # Иначе
    else:    
        # выводим предупреждение и
        print("Превышен лимит суммы эл-тов!")                 
        # прерываем цикл.
        break
        
# Если цикл не был прерван.
else:
    # Выводим итоговое сообщение.
    print("Сумма эл-тов равна:", sum)
	
# Выводим сообщение о завершении проверки.
print("Проверка списка завершена!")
2
7
16
Превышен лимит суммы эл-тов!
Проверка списка завершена!






















		
			

Пример №1. Использование цикла for (часть 1).

В примере с помощью инструкции цикла for список проверяется на превышение лимита суммы его элементов. Для этого используется знакомая нам вложенная
условная инструкция if/else, которая и проверяет сумму на достижение лимита. Если в ходе очередной итерации цикла сумма не достигает указанного предела,
значение счетчика суммы sum увеличивается на значение переменной заголовка цикла elem, т.е.
sum += elem. После этого цикл переходит к следующей итерации и присваивает переменной elem значение следующего элемента
списка. И так до тех пор, пока не будет завершен обход всех элементов списка или не будет достигнут лимит суммы. Если лимит суммы достигнут не будет, сработает набор инструкций блока
else цикла, т.е. итоговая сумма будет выведена на экран. После этого будет выполнена инструкция, следующая за циклом. В случае достижения лимита,
сработает набор инструкций блока else условной инструкции if, т.е. будет выведено предупреждение, а цикл будет
прерван инструкцией break, которая передаст управление инструкции, опять же, следующей за циклом.

Обратите внимание, что в нашем примере были использованы два блока else: один принадлежит условной инструкции if,
а другой – инструкции цикла for/in. Отличить их легко по уровню отступов. Оба блока не являются обязательными в своих конструкциях, но в нашем
случае конструкция for/else, позволяет выводить итоговое сообщение не всегда, а только в случае успешного завершения цикла.

Также стоит помнить, что значение переменной заголовка цикла elem при каждой новой итерации обновляется, поэтому после завершения цикла в ней
будет храниться значение, присвоенное в ходе последней итерации.

Давайте рассмотрим еще несколько наглядных вариаций цикла for/in, чтобы увидеть, как он используется на практике (см. пример
№2).

# Выводим символы строки.
name = 'Григорий'
for s in name: print(s, end=' ')
print('', end='nn')

# Используем функцию range(a, b, step).
for n in range(1, len(name), 2): 
    # Выводим каждую вторую букву имени. 
    print(name[n], end=' ')         
print('', end='nn')        

# Выводим ключи и значения словаря.
d = {'one': 1, 'two': 2}
for key in d: print(key, '->', d[key])                
print('', end='n')        

# Используем распаковывание кортежей.
d = [(1, 2), (3, 4), (5, 6)]
for x, y in d: print(x + y, end=' ')                
print('', end='nn')        

# А здесь расширенный синтаксис распаковывания.
d = [(1, 2, 3), (4, 5, 6)]
for x, *y in d: print(x, y, end=' ')
Г р и г о р и й 

р г р й 

one -> 1
two -> 2

3 7 11 

1 [2, 3] 4 [5, 6] 












		
			

Пример №2. Использование цикла for (часть 2).

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

Цикл while

Инструкция цикла while представляет собой универсальный цикл общего назначения. Он служит для повторного выполнения кода, расположенного в его теле,
до тех пор, пока условие цикла остается истинным, т.е. имеет значение True. В общем случае синтаксис цикла while в
Python можно представить в следующем виде:

 while <Условное выражение>:
    <Тело цикла>
 else:
    <Дополнительный блок инструкций> 

Работает цикл while следующим образом: каждый раз перед выполнением новой итерации, т.е. перед очередным выполнением блока инструкций в теле
цикла, происходит проверка его условия и, если результат будет иметь значение True, код в теле цикла выполняется; далее интерпретатор возвращается в начало цикла
и снова проверяет его условие, повторяя все процедуры заново до тех пор, пока условие цикла не вернет значение False; в этом случае интерпретатор прерывает
выполнение цикла и, пропустив блок инструкций в его теле, передает управление либо необязательному ключевому слову else, выполняя дополнительный блок
инструкций, либо инструкции, следующей за циклом. При этом следует иметь в виду, что набор инструкций блока else выполняется только тогда, когда выход из
цикла производится не инструкцией break (см. пример №3).

# Формируем список.
li = [2, 5, 9, 4]
    
# Задаем начальную сумму.
sum = 0

# Устанавливаем счетчик итераций.
k = 0
# Запускаем цикл по элементам списка.
while k < len(li):
    
    # Если сумма чисел меньше 8,
    if sum < 8:
        # наращиваем ее.    
        sum += li[k]
        # Отслеживаем показания счетчика и суммы.
        print(k, ':', sum)                
        # Счетчик увеличиваем на 1.
        k += 1
    # Иначе
    else:    
        # выводим предупреждение и
        print("Превышен лимит суммы эл-тов!")                 
        # прерываем цикл.
        break
        
# Если цикл не был прерван.
else:
    # Выводим итоговое сообщение.
    print("Сумма эл-тов равна:", sum)
    
# Выводим сообщение о завершении проверки.
print("Проверка списка завершена!")
0 : 2
1 : 7
2 : 16
Превышен лимит суммы эл-тов!
Проверка списка завершена!


























		
			

Пример №3. Использование цикла while (часть 1).

В нашем примере цикл совершил три итерации. На первых двух итерациях сумма элементов списка наращивалась, но не достигла допустимого предела. В результате этого цикл пошел на третий виток,
где сумма элементов все-таки превысила лимит. Это привело к тому, что цикл был прерван инструкцией break, а интерпретатор начал обрабатывать выражение
вызова функции print(), следующее за циклом. Если бы общая сумма всех элементов списка оказалась меньше допустимого лимита, цикл продолжил бы работу до
тех пор, пока переменная счетчика не стала бы равной четырем, а условие цикла не вернуло бы False. Далее интерпретатор пропустил бы блок инструкций тела
цикла и стал бы обрабатывать дополнительный набор инструкций его блока else. Попробуйте уменьшить значение элементов списка и убедитесь в этом.

Стоит заметить, что в языке Python отсутствует цикл do/while, имеющийся в других языках программирования. Однако его
можно имитировать, добавив в конец тела цикла условную инструкцию одновременно с инструкцией break (см. пример №4).

# Устанавливаем счетчик.
k = 1

# Запускаем бесконечный цикл.
while True:
    
    # Выводим номер итерации.
    print(k, end=' ')               
    # Счетчик увеличиваем на 1.
    k += 1
                
    # Имитируем условную часть цикла do/while.
    if k > 5: break
1 2 3 4 5 












Пример №4. Использование цикла while (часть 2).

Как видим, в данной имитации тело цикла при любом значении счетчика будет выполнено как минимум один раз, что является побочным эффектом проверки условия в конце цикла свойственного
реальной конструкции do/while.

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

Инструкции break и continue

Инструкции break и continue используются только внутри циклов и выполняют примерно те же функции, что и
в других языках программирования: break прерывает объемлющий цикл и передает управление следующей за циклом инструкции, а continue
прерывает только текущую итерацию и производит переход в начало цикла, т.е. в строку заголовка. При этом обе инструкции могут появляться в любом месте внутри тела цикла, но как правило,
их используют во вложенных в цикл условных инструкциях if, чтобы выполнить необходимое действие в ответ на некоторое условие (см. пример
№5).

# Устанавливаем счетчик.
k = 1

# Запускаем бесконечный цикл.
while True:
    
    # Задаем условие прерывания цикла.
    if k > 10: 
        # Прерываем цикл и идем дальше.
        break            
                
    # Отсеиваем четные числа.
    if k%2 == 0: 
        # Счетчик обязательно увеличиваем.
        k += 1
        # Пропускаем дальнейшие инструкции
        # и возвращаемся в заголовок цикла.
        continue
    
    # Выводим нечетные числа на экран.
    print(k, end=' ')               
    # Счетчик увеличиваем на 1.
    k += 1                        
      
# Инструкция после цикла.
print('nВывод нечетных чисел окончен!n')       


        
# Допустим, что имеется список чисел от 1 до 20.
li = list(range(1, 21))

# Запускаем цикл по элементам списка.
for k in li:
    
    # Задаем условие прерывания цикла.
    if k > 10: 
        # Прерываем цикл и идем дальше.
        break            
                
    # Отсеиваем четные числа.
    if k%2 == 0: 
        # Счетчик обязательно увеличиваем.
        k += 1
        # Пропускаем дальнейшие инструкции
        # и возвращаемся в заголовок цикла.
        continue
    
    # Выводим нечетные числа на экран.
    print(k, end=' ')               
    # Счетчик увеличиваем на 1.
    k += 1                        
      
# Инструкция после цикла.
print('nВывод нечетных чисел окончен!')
1 3 5 7 9 
Вывод нечетных чисел окончен!

1 3 5 7 9 
Вывод нечетных чисел окончен!
















































		
			

Пример №5. Использование инструкций break и continue (часть 1).

Здесь хотелось бы обратить внимание на то, что все виды циклов в Python могут иметь другие вложенные циклы и условные инструкции, позволяя нужным образом
изменять дальнейший ход выполнения программы. Но дело в том, что каждая отдельная инструкция break или continue
относится только к одному ближайшему объемлющему циклу. Поэтому, например, выйти сразу из всех внешних циклов при помощи всего лишь одной инструкции break
расположенной в самом глубоком вложенном цикле не получится, нужно использовать инструкцию во всех циклах текущей иерархии (см. пример №6).

# Задаем стартовое значение счетчика.
y = 1                   
 
# Внешний цикл.
for x in range(1, 11):

    # Умножение на 1 пропускаем.
    if x == 1:          
        # Переходим в начало цикла for.
        continue 
  
    # Внутренний цикл.
    while True:         
        
        # Умножение на 1 пропускаем.
        if y == 1:          
            # Увеличиваем счетчик на единицу.
            y += 1    
            # Переходим в начало цикла while.
            continue                                     
                                      
        # Выводим произведение чисел.
        print('{} x {} = {}'.format(x, y, x*y))
        
        # При достижении значения y == 5.
        if y == 5:          
            # Переходим на новую строку.
            print()                     
            # Сбрасываем значение счетчика.
            y = 2                     
            # А внутренний цикл прерываем (внешний нет).
            break        
        
        # Увеличиваем счетчик на единицу.
        y += 1              
    
    # При достижении значения x == 5.
    if x == 5:          
        # Прерываем и внешний цикл.
        break            
  
# Выводим сообщение о завершении циклов.
print('Таблица умножения от 2 до 5 распечатана!')
2 x 2 = 4
2 x 3 = 6
2 x 4 = 8
2 x 5 = 10

3 x 2 = 6
3 x 3 = 9
3 x 4 = 12
3 x 5 = 15

4 x 2 = 8
4 x 3 = 12
4 x 4 = 16
4 x 5 = 20

5 x 2 = 10
5 x 3 = 15
5 x 4 = 20
5 x 5 = 25

Таблица умножения от 2 до 5 распечатана!




















		
			

Пример №6. Использование инструкций break и continue (часть 2).

В Python отсутствует возможность использования конструкций вида break n или continue n,
где n указывало бы на количество прерываний внешних циклов. Вместо этого необходимо использовать собственные инструкции для каждого из
n циклов по отдельности.

Краткие итоги параграфа

  • Для обхода элементов в любых объектах, поддерживающих возможность совершения итераций, в Python предназначен цикл
    for/in. В ходе выполнения этого цикла интерпретатор один за другим присваивает переменной заголовка элементы итерируемого объекта и выполняет для них
    инструкции тела цикла.
  • Для многократного повторного выполнения кода (не только обхода элементов) служит универсальный цикл общего назначения while, который выполняет блок
    инструкций, расположенный в его теле, до тех пор, пока условие цикла остается истинным, т.е. имеет значение True.
  • При необходимости в циклах for и while разрешается использовать необязательный блок
    else, набор инструкций которого выполняется только после удачного завершения цикла (т.е. при отсутствии ошибки или прерывания за счет использования
    инструкции break).
  • При использовании счетчиков следует инициализировать их вне циклов, чтобы при каждой новой итерации их значения не сбрасывались циклом в первоначальное состояние.
  • Для прерывания циклов в Python используется инструкция break, которая прерывает объемлющий цикл и передает управление
    следующей за циклом инструкции. Если нужно прервать только текущую итерацию, необходимо использовать инструкцию continue, которая после прерывания
    итерации производит переход в начало цикла, т.е. в строку заголовка. Обе инструкции могут появляться в любом месте внутри тела цикла, но как правило, их используют во вложенных
    в цикл условных инструкциях if, чтобы выполнить необходимое действие в ответ на некоторое условие.
  • Следует помнить, что в Python разрешается использовать многоуровневые вложенные циклы, однако при этом отсутствует возможность использования конструкций
    вида break n или continue n, где n указывало бы на количество прерываний внешних
    циклов. Вместо этого необходимо использовать собственные инструкции для каждого из n циклов по отдельности.

Вопросы и задания для самоконтроля

1. Для чего в программировании используются циклы? Какие виды циклов присутствуют в арсенале языка Python?

Показать решение.

Ответ. Циклы в программировании используются для организации многократного исполнения набора инструкций. В языке
Python циклы представлены конструкциями for/in и while: основным предназначением
цикла for является обход элементов итерируемого объекта, а while представляет собой универсальный цикл общего назначения.
Стоит заметить, что с помощью инструкции while можно сымитировать в том числе и счетный цикл for, однако программный код,
как хорошо видно из наших примеров выше, получится менее компактным и может выполняться медленнее.

2. Допустимо ли в Python использование вложенных друг в друга циклов?

Показать решение.

Ответ. В Python разрешается использовать как вложенные циклы, так и вложенные условные инструкции
if.

3. Обязательно ли использование блока else в циклах? При каких условиях он выполняется?

Показать решение.

Ответ. Блок инструкций оператора else в циклах не является обязательным, а его инструкции выполняются только
после удачного завершения цикла (т.е. при отсутствии ошибки или прерывания за счет использования оператора break).

4. В чем заключается основное отличие инструкции break от инструкции continue?

Показать решение.

Ответ. Инструкция break полностью прерывает объемлющий цикл и передает управление следующей за циклом
инструкции, в то время как инструкция continue прерывает только текущую итерацию и производит переход в начало цикла, т.е. в строку его заголовка.

5. Выведите все элементы списка [10, 20, 30] на экран сперва при помощи цикла for, а
затем и цикла while.

Показать решение.

# Сохраняем список в переменной.
li = [10, 20, 30]                   
 
# Организуем цикл по эл-там списка.
for elem in li:
    # Выводим значения на экран.
    print(elem, end=' ')              

# Сделаем отступ для цикла while.
print() 
              
# Инициализируем счетчик для цикла.  
k = 0
# Узнаем требуемое количество итераций.  
i = len(li)        

# Организуем цикл по эл-там списка.
while k < i:
    # Выводим значения на экран.
    print(li[k], end=' ')
    # Наращиваем значение счетчика.
    k += 1	
10 20 30 
10 20 30



















			

6. Дополнительные упражнения и задачи по теме расположены в разделе
«Циклы for и while»
нашего сборника задач и упражнений по языку программирования Python.

Быстрый переход к другим страницам

Повторение вычислений

Повторение вычислений

Инструкция повторного выполнения рассматривалась при обсуждении исключительных ситуаций (лекция 12). Она появляется только в предложении rescue, повторно запуская тело подпрограммы, работа которой была прервана.

Читайте также

2.2. Повторение (операторы цикла)

2.2. Повторение (операторы цикла)
Циклом называется группа операторов, которая выполняется повторно. После каждого повторения проверяется условие, называемое условием окончания цикла, по которому принимается решение продолжать повторение или закончить

20. Квадратный трехчлен, или Пакет Для Алгебраических Вычислений

20.
Квадратный трехчлен,
или Пакет Для Алгебраических Вычислений
Основная трудность, с которой сталкивается программист в большинстве языков программирования, — необходимость при записи вычислений разбивать свои уравнения на мелкие части. Так, если требуется

Выполнение вычислений в запросах

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

Повторение с помощью циклов

Повторение с помощью циклов
Управляющие структуры типа «цикл» используются тогда, когда необходимо повторить выполнение некоторого блока программного кода несколько раз. Повторение одного или нескольких операторов является главным средством выполнения многих

Повторение под управлением циклов For…Next

Повторение под управлением циклов For…Next
Если уже перед выполнением цикла известно, сколько раз он должен выполняться, используйте цикл For. . . Next. Число проходов цикла задается значениями начало и коней, которые могут быть целыми числами, переменными и даже сложными

12. Кодирование параллельных вычислений

12. Кодирование параллельных вычислений
РезюмеЕсли ваше приложение использует несколько потоков или процессов, следует минимизировать количество совместно используемых объектов, где это только можно (см. рекомендацию 10), и аккуратно работать с

31. Не пишите код, который зависит от порядка вычислений аргументов функции

31. Не пишите код, который зависит от порядка вычислений аргументов функции
РезюмеПорядок вычисления аргументов функции не определен, поэтому никогда не полагайтесь на то, что аргументы будут вычисляться в той или иной очередности.ОбсуждениеНа начальных этапах развития

5.3. Выполнение вычислений с датами и временем

5.3. Выполнение вычислений с датами и временем
ПроблемаТребуется узнать количество времени, прошедшего между двумя точками даты/времени.РешениеЕсли обе временные точки находятся между 1970 и 2038 годами, то используйте тип time_t и функцию difftime, определенную в заголовочном

Повторение и свобода

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

Повторение пройденного

Повторение пройденного
Примеры доступа к объектам Pocket Outlook рассматривались применительно к карманным компьютерам. Но теперь надо воссоздать их, опираясь уже на смартфоны. Сам код примеров останется практически неизменным. Но при этом изменится логика управления

Отмена и повторение изменений

Отмена и повторение изменений
Многие действия, произведенные над проектом, можно отменить. Выполняется это с помощью команды меню Монтаж ? Отменить &lt;действие&gt;. Вместо &lt;действие&gt; после слова Отменить в названии пункта меню записано, какое конкретно действие будет

27 Повторение и вознаграждение

27
Повторение и вознаграждение
Многие вещи, начиная от сумок для покупок и заканчивая картриджами, мы используем повторно. Почему бы тогда не попробовать применять повторно код? Почему бы не использовать повторно макеты и модели вместо того, чтобы создавать их заново?

Повторение

Повторение
Вполне возможно, что из 20 кадров прекрасной водяной белой лилии у вас как минимум 15 соответствуют всем требуемым стандартам и вы можете сократить число снимков, в которые влюблены, максимум до 10. Ну и пусть ракурс практически везде одинаковый, она ведь такая

Объектно-ориентированный стиль вычислений

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

Повторение программы, толерантной к неисправностям

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

Цикл for/in

Еще одной важной инструкцией языка Python является цикл for/in, который можно смело назвать универсальным
итератором последовательностей, поскольку он позволяет выполнять обход элементов в любых объектах, поддерживающих возможность совершения итераций. При этом сюда относятся как встроенные объекты, например, строки,
списки или словари, так и объекты, создаваемые с помощью классов (о них чуть позже).

В общем виде для цикла for используется следующий синтаксис:

 for <Переменная> in <Итерируемый объект>:
    <Тело цикла>
 else:
    <Дополнительный блок инструкций> 

В ходе выполнения цикла for интерпретатор один за другим присваивает переменной заголовка элементы итерируемого объекта и выполняет для них инструкции
тела цикла (см. пример №1). Если цикл нужно прервать, используется ключевое слово break, которое передает управление
инструкции, следующей сразу за циклом. Кроме того, в цикле for разрешается использовать необязательный блок else,
набор инструкций которого выполняется только после удачного завершения цикла (т.е. при отсутствии ошибки или прерывания за счет использования инструкции
break).

Код
Результат
pythonCodes

# Формируем список.
li = [2, 5, 9, 4]
    
# Задаем начальную сумму.
sum = 0

# Запускаем цикл по элементам списка.
for elem in li:
    
    # Если сумма чисел меньше 8,
    if sum < 8:
        # наращиваем ее.    
        sum += elem
        # Выводим для наглядности на экран.
        print(sum)
    # Иначе
    else:    
        # выводим предупреждение и
        print("Превышен лимит суммы эл-тов!")                 
        # прерываем цикл.
        break
        
# Если цикл не был прерван.
else:
    # Выводим итоговое сообщение.
    print("Сумма эл-тов равна:", sum)
	
# Выводим сообщение о завершении проверки.
print("Проверка списка завершена!")
2
7
16
Превышен лимит суммы эл-тов!
Проверка списка завершена!






















		
			

Пример №1. Использование цикла for (часть 1).

В примере с помощью инструкции цикла for список проверяется на превышение лимита суммы его элементов. Для этого используется знакомая нам вложенная
условная инструкция if/else, которая и проверяет сумму на достижение лимита. Если в ходе очередной итерации цикла сумма не достигает указанного предела,
значение счетчика суммы sum увеличивается на значение переменной заголовка цикла elem, т.е.
sum += elem. После этого цикл переходит к следующей итерации и присваивает переменной elem значение следующего элемента
списка. И так до тех пор, пока не будет завершен обход всех элементов списка или не будет достигнут лимит суммы. Если лимит суммы достигнут не будет, сработает набор инструкций блока
else цикла, т.е. итоговая сумма будет выведена на экран. После этого будет выполнена инструкция, следующая за циклом. В случае достижения лимита,
сработает набор инструкций блока else условной инструкции if, т.е. будет выведено предупреждение, а цикл будет
прерван инструкцией break, которая передаст управление инструкции, опять же, следующей за циклом.

Обратите внимание, что в нашем примере были использованы два блока else: один принадлежит условной инструкции if,
а другой – инструкции цикла for/in. Отличить их легко по уровню отступов. Оба блока не являются обязательными в своих конструкциях, но в нашем
случае конструкция for/else, позволяет выводить итоговое сообщение не всегда, а только в случае успешного завершения цикла.

Также стоит помнить, что значение переменной заголовка цикла elem при каждой новой итерации обновляется, поэтому после завершения цикла в ней
будет храниться значение, присвоенное в ходе последней итерации.

Давайте рассмотрим еще несколько наглядных вариаций цикла for/in, чтобы увидеть, как он используется на практике (см. пример
№2).

Код
Результат
pythonCodes

# Выводим символы строки.
name = 'Григорий'
for s in name: print(s, end=' ')
print('', end='\n\n')

# Используем функцию range(a, b, step).
for n in range(1, len(name), 2): 
    # Выводим каждую вторую букву имени. 
    print(name[n], end=' ')         
print('', end='\n\n')        

# Выводим ключи и значения словаря.
d = {'one': 1, 'two': 2}
for key in d: print(key, '->', d[key])                
print('', end='\n')        

# Используем распаковывание кортежей.
d = [(1, 2), (3, 4), (5, 6)]
for x, y in d: print(x + y, end=' ')                
print('', end='\n\n')        

# А здесь расширенный синтаксис распаковывания.
d = [(1, 2, 3), (4, 5, 6)]
for x, *y in d: print(x, y, end=' ')
Г р и г о р и й 

р г р й 

one -> 1
two -> 2

3 7 11 

1 [2, 3] 4 [5, 6] 












		
			

Пример №2. Использование цикла for (часть 2).

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

Цикл while

Инструкция цикла while представляет собой универсальный цикл общего назначения. Он служит для повторного выполнения кода, расположенного в его теле,
до тех пор, пока условие цикла остается истинным, т.е. имеет значение True. В общем случае синтаксис цикла while в
Python можно представить в следующем виде:

 while <Условное выражение>:
    <Тело цикла>
 else:
    <Дополнительный блок инструкций> 

Работает цикл while следующим образом: каждый раз перед выполнением новой итерации, т.е. перед очередным выполнением блока инструкций в теле
цикла, происходит проверка его условия и, если результат будет иметь значение True, код в теле цикла выполняется; далее интерпретатор возвращается в начало цикла
и снова проверяет его условие, повторяя все процедуры заново до тех пор, пока условие цикла не вернет значение False; в этом случае интерпретатор прерывает
выполнение цикла и, пропустив блок инструкций в его теле, передает управление либо необязательному ключевому слову else, выполняя дополнительный блок
инструкций, либо инструкции, следующей за циклом. При этом следует иметь в виду, что набор инструкций блока else выполняется только тогда, когда выход из
цикла производится не инструкцией break (см. пример №3).

Код
Результат
pythonCodes

# Формируем список.
li = [2, 5, 9, 4]
    
# Задаем начальную сумму.
sum = 0

# Устанавливаем счетчик итераций.
k = 0
# Запускаем цикл по элементам списка.
while k < len(li):
    
    # Если сумма чисел меньше 8,
    if sum < 8:
        # наращиваем ее.    
        sum += li[k]
        # Отслеживаем показания счетчика и суммы.
        print(k, ':', sum)                
        # Счетчик увеличиваем на 1.
        k += 1
    # Иначе
    else:    
        # выводим предупреждение и
        print("Превышен лимит суммы эл-тов!")                 
        # прерываем цикл.
        break
        
# Если цикл не был прерван.
else:
    # Выводим итоговое сообщение.
    print("Сумма эл-тов равна:", sum)
    
# Выводим сообщение о завершении проверки.
print("Проверка списка завершена!")
0 : 2
1 : 7
2 : 16
Превышен лимит суммы эл-тов!
Проверка списка завершена!


























		
			

Пример №3. Использование цикла while (часть 1).

В нашем примере цикл совершил три итерации. На первых двух итерациях сумма элементов списка наращивалась, но не достигла допустимого предела. В результате этого цикл пошел на третий виток,
где сумма элементов все-таки превысила лимит. Это привело к тому, что цикл был прерван инструкцией break, а интерпретатор начал обрабатывать выражение
вызова функции print(), следующее за циклом. Если бы общая сумма всех элементов списка оказалась меньше допустимого лимита, цикл продолжил бы работу до
тех пор, пока переменная счетчика не стала бы равной четырем, а условие цикла не вернуло бы False. Далее интерпретатор пропустил бы блок инструкций тела
цикла и стал бы обрабатывать дополнительный набор инструкций его блока else. Попробуйте уменьшить значение элементов списка и убедитесь в этом.

Стоит заметить, что в языке Python отсутствует цикл do/while, имеющийся в других языках программирования. Однако его
можно имитировать, добавив в конец тела цикла условную инструкцию одновременно с инструкцией break (см. пример №4).

Код
Результат
pythonCodes

# Устанавливаем счетчик.
k = 1

# Запускаем бесконечный цикл.
while True:
    
    # Выводим номер итерации.
    print(k, end=' ')               
    # Счетчик увеличиваем на 1.
    k += 1
                
    # Имитируем условную часть цикла do/while.
    if k > 5: break
1 2 3 4 5 












Пример №4. Использование цикла while (часть 2).

Как видим, в данной имитации тело цикла при любом значении счетчика будет выполнено как минимум один раз, что является побочным эффектом проверки условия в конце цикла свойственного
реальной конструкции do/while.

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

Инструкции break и continue

Инструкции break и continue используются только внутри циклов и выполняют примерно те же функции, что и
в других языках программирования: break прерывает объемлющий цикл и передает управление следующей за циклом инструкции, а continue
прерывает только текущую итерацию и производит переход в начало цикла, т.е. в строку заголовка. При этом обе инструкции могут появляться в любом месте внутри тела цикла, но как правило,
их используют во вложенных в цикл условных инструкциях if, чтобы выполнить необходимое действие в ответ на некоторое условие (см. пример
№5).

Код
Результат
pythonCodes

# Устанавливаем счетчик.
k = 1

# Запускаем бесконечный цикл.
while True:
    
    # Задаем условие прерывания цикла.
    if k > 10: 
        # Прерываем цикл и идем дальше.
        break            
                
    # Отсеиваем четные числа.
    if k%2 == 0: 
        # Счетчик обязательно увеличиваем.
        k += 1
        # Пропускаем дальнейшие инструкции
        # и возвращаемся в заголовок цикла.
        continue
    
    # Выводим нечетные числа на экран.
    print(k, end=' ')               
    # Счетчик увеличиваем на 1.
    k += 1                        
      
# Инструкция после цикла.
print('\nВывод нечетных чисел окончен!\n')       


        
# Допустим, что имеется список чисел от 1 до 20.
li = list(range(1, 21))

# Запускаем цикл по элементам списка.
for k in li:
    
    # Задаем условие прерывания цикла.
    if k > 10: 
        # Прерываем цикл и идем дальше.
        break            
                
    # Отсеиваем четные числа.
    if k%2 == 0: 
        # Счетчик обязательно увеличиваем.
        k += 1
        # Пропускаем дальнейшие инструкции
        # и возвращаемся в заголовок цикла.
        continue
    
    # Выводим нечетные числа на экран.
    print(k, end=' ')               
    # Счетчик увеличиваем на 1.
    k += 1                        
      
# Инструкция после цикла.
print('\nВывод нечетных чисел окончен!')
1 3 5 7 9 
Вывод нечетных чисел окончен!

1 3 5 7 9 
Вывод нечетных чисел окончен!
















































		
			

Пример №5. Использование инструкций break и continue (часть 1).

Здесь хотелось бы обратить внимание на то, что все виды циклов в Python могут иметь другие вложенные циклы и условные инструкции, позволяя нужным образом
изменять дальнейший ход выполнения программы. Но дело в том, что каждая отдельная инструкция break или continue
относится только к одному ближайшему объемлющему циклу. Поэтому, например, выйти сразу из всех внешних циклов при помощи всего лишь одной инструкции break
расположенной в самом глубоком вложенном цикле не получится, нужно использовать инструкцию во всех циклах текущей иерархии (см. пример №6).

Код
Результат
pythonCodes

# Задаем стартовое значение счетчика.
y = 1                   
 
# Внешний цикл.
for x in range(1, 11):

    # Умножение на 1 пропускаем.
    if x == 1:          
        # Переходим в начало цикла for.
        continue 
  
    # Внутренний цикл.
    while True:         
        
        # Умножение на 1 пропускаем.
        if y == 1:          
            # Увеличиваем счетчик на единицу.
            y += 1    
            # Переходим в начало цикла while.
            continue                                     
                                      
        # Выводим произведение чисел.
        print('{} x {} = {}'.format(x, y, x*y))
        
        # При достижении значения y == 5.
        if y == 5:          
            # Переходим на новую строку.
            print()                     
            # Сбрасываем значение счетчика.
            y = 2                     
            # А внутренний цикл прерываем (внешний нет).
            break        
        
        # Увеличиваем счетчик на единицу.
        y += 1              
    
    # При достижении значения x == 5.
    if x == 5:          
        # Прерываем и внешний цикл.
        break            
  
# Выводим сообщение о завершении циклов.
print('Таблица умножения от 2 до 5 распечатана!')
2 x 2 = 4
2 x 3 = 6
2 x 4 = 8
2 x 5 = 10

3 x 2 = 6
3 x 3 = 9
3 x 4 = 12
3 x 5 = 15

4 x 2 = 8
4 x 3 = 12
4 x 4 = 16
4 x 5 = 20

5 x 2 = 10
5 x 3 = 15
5 x 4 = 20
5 x 5 = 25

Таблица умножения от 2 до 5 распечатана!




















		
			

Пример №6. Использование инструкций break и continue (часть 2).

В Python отсутствует возможность использования конструкций вида break n или continue n,
где n указывало бы на количество прерываний внешних циклов. Вместо этого необходимо использовать собственные инструкции для каждого из
n циклов по отдельности.

Краткие итоги параграфа

  • Для обхода элементов в любых объектах, поддерживающих возможность совершения итераций, в Python предназначен цикл
    for/in. В ходе выполнения этого цикла интерпретатор один за другим присваивает переменной заголовка элементы итерируемого объекта и выполняет для них
    инструкции тела цикла.
  • Для многократного повторного выполнения кода (не только обхода элементов) служит универсальный цикл общего назначения while, который выполняет блок
    инструкций, расположенный в его теле, до тех пор, пока условие цикла остается истинным, т.е. имеет значение True.
  • При необходимости в циклах for и while разрешается использовать необязательный блок
    else, набор инструкций которого выполняется только после удачного завершения цикла (т.е. при отсутствии ошибки или прерывания за счет использования
    инструкции break).
  • При использовании счетчиков следует инициализировать их вне циклов, чтобы при каждой новой итерации их значения не сбрасывались циклом в первоначальное состояние.
  • Для прерывания циклов в Python используется инструкция break, которая прерывает объемлющий цикл и передает управление
    следующей за циклом инструкции. Если нужно прервать только текущую итерацию, необходимо использовать инструкцию continue, которая после прерывания
    итерации производит переход в начало цикла, т.е. в строку заголовка. Обе инструкции могут появляться в любом месте внутри тела цикла, но как правило, их используют во вложенных
    в цикл условных инструкциях if, чтобы выполнить необходимое действие в ответ на некоторое условие.
  • Следует помнить, что в Python разрешается использовать многоуровневые вложенные циклы, однако при этом отсутствует возможность использования конструкций
    вида break n или continue n, где n указывало бы на количество прерываний внешних
    циклов. Вместо этого необходимо использовать собственные инструкции для каждого из n циклов по отдельности.

Вопросы и задания для самоконтроля

1. Для чего в программировании используются циклы? Какие виды циклов присутствуют в арсенале языка Python?
Показать решение.

Ответ. Циклы в программировании используются для организации многократного исполнения набора инструкций. В языке
Python циклы представлены конструкциями for/in и while: основным предназначением
цикла for является обход элементов итерируемого объекта, а while представляет собой универсальный цикл общего назначения.
Стоит заметить, что с помощью инструкции while можно сымитировать в том числе и счетный цикл for, однако программный код,
как хорошо видно из наших примеров выше, получится менее компактным и может выполняться медленнее.

2. Допустимо ли в Python использование вложенных друг в друга циклов?
Показать решение.

Ответ. В Python разрешается использовать как вложенные циклы, так и вложенные условные инструкции
if.

3. Обязательно ли использование блока else в циклах? При каких условиях он выполняется?
Показать решение.

Ответ. Блок инструкций оператора else в циклах не является обязательным, а его инструкции выполняются только
после удачного завершения цикла (т.е. при отсутствии ошибки или прерывания за счет использования оператора break).

4. В чем заключается основное отличие инструкции break от инструкции continue?
Показать решение.

Ответ. Инструкция break полностью прерывает объемлющий цикл и передает управление следующей за циклом
инструкции, в то время как инструкция continue прерывает только текущую итерацию и производит переход в начало цикла, т.е. в строку его заголовка.

5. Выведите все элементы списка [10, 20, 30] на экран сперва при помощи цикла for, а
затем и цикла while.
Показать решение.

Решение
Результат
pythonCodes

# Сохраняем список в переменной.
li = [10, 20, 30]                   
 
# Организуем цикл по эл-там списка.
for elem in li:
    # Выводим значения на экран.
    print(elem, end=' ')              

# Сделаем отступ для цикла while.
print() 
              
# Инициализируем счетчик для цикла.  
k = 0
# Узнаем требуемое количество итераций.  
i = len(li)        

# Организуем цикл по эл-там списка.
while k < i:
    # Выводим значения на экран.
    print(li[k], end=' ')
    # Наращиваем значение счетчика.
    k += 1	
10 20 30 
10 20 30



















			

6. Дополнительные тесты по теме расположены в разделе
«Циклы for и while» нашего сборника тестов.

7. Дополнительные упражнения и задачи по теме расположены в разделе
«Циклы for и while»
нашего сборника задач и упражнений.

Быстрый переход к другим страницам

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

if (выражение) инструкция;

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

if (выражение)

{

последовательность инструкций

}

else

{

последовательность инструкций

}
Если элемент выражение, который представляет собой условное выражение, при вычислении даст значение ИСТИНА, будет выполнена if-инструкция; в противном случае else-инструкция (если таковая существует). Обе инструкции никогда не выполняются. Условное выражение, управляющее выполнением if-инструкции, может иметь любой тип, действительный для С++-выражений, но главное; чтобы результат его вычисления можно было интерпретировать как значение ИСТИНА или ЛОЖЬ.
Использование if-инструкции рассмотрим на примере программы, которая представляет собой версию игры «Угадай магическое число». Программа генерирует случайное число и предлагает вам его угадать. Если вы угадываете число, программа выводит на экран сообщение одобрения ** Правильно **. В этой программе представлена еще одна библиотечная функция rand (), которая возвращает случайным образом выбранное целое число. Для использования этой функции необходимо включить в программу заголовок <cstdlib>.

// Программа «Угадай магическое число».

#include <iostream>

#include <cstdlib>

using namespace std;

int main ()

{

int magic; // магическое число

int guess; // вариант пользователя

magic = rand (); // Получаем случайное число.

cout << «Введите свой вариант магического числа: «;

cin >> guess;

if (guess == magic) cout << «** Правильно **»;

return 0;

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

// Программа «Угадай магическое число»:

// 1-е усовершенствование.

#include <iostream>

#include <cstdlib>

using namespace std;

int main ()

{

int magic; // магическое число

int guess; // вариант пользователя

magic = rand (); // Получаем случайное число.

cout << «Введите свой вариант магического числа: «;

cin >> guess;

if (guess == magic) cout << «** Правильно **»;

else cout << «…Очень жаль, но вы ошиблись.»;

return 0;

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

// Деление первого числа на второе.

#include <iostream>

using namespace std;

int main ()

{

int a, b;

cout << «Введите два числа: «;

cin >> a >> b;

if (b) cout << a/b << ‘\n’;

else cout << «На нуль делить нельзя.\n»;

return 0;

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

if (b != 0) cout << а/b << ‘\n’;
Эта форма if-инструкции считается устаревшей и потенциально неэффективной.
Вложенные if-инструкции
Вложенные if-инструкции образуются в том случае, если в качестве элемента инструкция (см. полный формат записи) используется другая if-инструкция. Вложенные if-инструкции очень популярны в программировании. Главное здесь — помнить, что else-инструкция всегда относится к ближайшей if-инструкции, которая находится внутри того же программного блока, но еще не связана ни с какой другой else-инструкцией. Вот пример.

if (i) {

if (j) statement1;

if (k) statement2; // Эта if-инструкция

else statement3; // связана с этой else-инструкцией.

}

else statement4; // Эта else-инструкция связана с if (i).
Как утверждается в комментариях, последняя else-инструкция не связана с инструкцией if (j), поскольку они не находятся в одном блоке (несмотря на то, что эта if-инструкция — ближайшая, которая не имеет при себе «else-пары»). Внутренняя else-инструкция связана с инструкцией if (k), поскольку она — ближайшая и находится внутри того же блока.
Вложенная if-инструкция— это инструкция, которая используется в качестве элемента инструкция любой другой if- или elsе-инструкции.
Язык C++ позволяет 256 уровней вложения, но на практике редко приходится вкладывать if-инструкции на «такую глубину». продемонстрируем использование вложенных инструкций с помощью очередного усовершенствования программы «Угадай магическое число» (здесь игрок получает реакцию программы на неправильный ответ).

// Программа «Угадай магическое число»:

// 2-е усовершенствование.

#include <iostream>

#include <cstdlib>

using namespace std;

int main ()

{

int magic; // магическое число

int guess; // вариант пользователя

magic = rand (); // Получаем случайное число.

cout << «Введите свой вариант магического числа: «;

cin >> guess;

if (guess == magic) {

cout << „ ** Правильно **\n“;

cout << magic << „ и есть то самое магическое число.\n“;

}

else {

cout << „…Очень жаль, но вы ошиблись.“;

if (guess > magic) cout <<»Ваш вариант превышает магическое число.\n»;

else cout << « Ваш вариант меньше магического числа.\n»;

}

return 0;

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

if (условие)

инструкция;

else if (условие)

инструкция;

else if (условие)

инструкция;

.

.

.

else

инструкция;
Здесь под элементом условие понимается условное выражение. Условные выражения вычисляются сверху вниз. Как только в какой-нибудь ветви обнаружится истинный результат, будет выполнена инструкция, связанная с этой ветвью, а вся остальная «лестница» опускается. Если окажется, что ни одно из условий не является истинным, будет выполнена последняя else-инструкция (можно считать, что она выполняет роль условия, которое действует по умолчанию). Если последняя else-инструкция не задана, а все остальные оказались ложными, то вообще никакое действие не будет выполнено.
«Лестница» if-else-if— это последовательность вложенных if-else-инструкций.
Работа if-else-if — «лестницы» демонстрируется в следующей программе.

// Демонстрация использования «лестницы» if-else-if.

#include <iostream>

using namespace std;

int main ()

{

int x;

for (x=0; x<6; x++) {

if (x==1) cout << «x равен единице.\n»;

else if (x==2) cout << «x равен двум.\n»;

else if (x==3) cout<< «x равен трем.\n»;

else if (x==4) cout << «x равен четырем.\n»;

else cout << «x не попадает в диапазон от 1 до 4.\n»;

}

return 0;

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

х не попадает в диапазон от 1 до 4.

х равен единице,

х равен двум,

х равен трем,

х равен четырем.

х не попадает в диапазон от 1 до 4.
Как видите, последняя else-инструкция выполняется только в том случае, если все предыдущие if-условия дали ложный результат.
Цикл for
Цикл for — самый универсальный цикл C++.
В главе 2 мы уже использовали простую форму цикла for. В этой главе мы рассмотрим этот цикл более детально, и вы узнаете, насколько мощным и гибким средством программирования он является. Начнем с традиционных форм его использования.
Итак, общий формат записи цикла for для многократного выполнения одной инструкции имеет следующий вид.

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

fоr (инициализация; выражение; инкремент)

{

последовательность инструкций

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

#include <iostream>

#include <cmath>

using namespace std;

int main ()

{

int num;

double sq_root;

for (num=1; num<100; num++) {

sq_root = sqrt ((double) num);

cout << num << » » << sq_root << ‘\n’;

}

return 0;

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

1 1

2 1.41421

3 1.73205

4 2

5 2.23607

6 2.44949

7 2.64575

8 2.82843

9 3

10 3.16228

11 3.31662
В этой программе использована еще одна стандартная функция C++: sqrt (). Эта функция возвращает значение квадратного корня из своего аргумента. Аргумент должен иметь тип double, и именно поэтому при вызове функции sqrt () параметр num приводится к типу double. Сама функция также возвращает значение типа double. Обратите внимание на то, что в программу включен заголовок <cmath>, поскольку этот заголовочный файл обеспечивает поддержку функции sqrt ().
Важно! Помимо функции sqrt (), C++ поддерживает широкий набор других математических функций, например sin (), cos (), tan (), log (), ceil () и floor (). Помните, что все математические функции требуют включения в программу заголовка <cmath>.
Управляющая переменная цикла for может изменяться как с положительным, так и с отрицательным приращением, причем величина этого приращения также может быть любой. Например, следующая программа выводит числа в диапазоне от 100 до -100 с декрементом, равным 5.

#include <iostream>

using namespace std;

int main ()

{

int i;

for (i=100; i>=-100; i=i-5) cout << i << ‘ ‘;

return 0;

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

for (count=10; count<5; count++)

cout << count; // Эта инструкция не выполнится.
Этот цикл никогда не выполнится, поскольку уже при входе в него значение его управляющей переменной count больше пяти. Это делает условное выражение (count < 5) ложным с самого начала. Поэтому даже одна итерация этого цикла не будет выполнена.
Вариации на тему цикла for
Цикл for — одна из наиболее гибких инструкций в С++, поскольку она позволяет получить широкий диапазон вариантов ее использования. Например, для управления циклом for можно использовать несколько переменных. Рассмотрим следующий фрагмент кода.

for (x=0, у=10; х<=10; ++х, —у)

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

#include <iostream>

#include <conio.h>

using namespace std;

int main ()

{

int i;

// Вывод чисел на экран до нажатия любой клавиши.

for (i=0; !kbhit (); i++)

cout << i << ‘ ‘;

return 0;

}
На каждой итерации цикла вызывается функция kbhit (). Если после запуска программы нажать какую-нибудь клавишу, эта функция возвратит значение ИСТИНА, в результате чего выражение !kbhit () даст значение ЛОЖЬ, и цикл остановится. Но если не нажимать клавишу, функция возвратит значение ЛОЖЬ, а выражение !kbhit () даст значение ИСТИНА, что позволит циклу продолжать «крутиться».
Важно! Функция kbhit () не входит в состав стандартной библиотеки C++. Дело в том, что стандартная библиотека определяет только минимальный набор функций, который должны иметь все С++-компиляторы. Функция kbhit () не включена в этот минимальный набор, поскольку не все среды могут поддерживать взаимодействие с клавиатурой. Однако функцию kbhit () поддерживают практически все серийно выпускаемые C++- компиляторы. Производители компиляторов могут обеспечить поддержку большего числа функций, чем это необходимо для соблюдения минимальных требований по части стандартной библиотеки C++. Дополнительные же функции позволяют шире использовать возможности среды программирования. Если для вас не проблематичен вопрос переносимости кода в другую среду выполнения, вы можете свободно использовать все функции, поддерживаемые вашим компилятором.
Отсутствие элементов в определении цикла
В C++ разрешается опустить любой элемент заголовка цикла (инициализация, условное выражение, инкремент) или даже все сразу. Например, мы хотим написать цикл, который должен выполняться до тех пор, пока с клавиатуры не будет введено число 123. Вот как выглядит такая программа.

#include <iostream>

using namespace std;

int main ()

{

int x;

for (x=0; x!=123; ) {

cout << «Введите число: «;

cin >> x;

}

return 0;

}
Здесь в заголовке цикла for отсутствует выражение инкремента. Это означает, что при каждом повторении цикла выполняется только одно действие: значение переменной х сравнивается с числом 123. Но если ввести с клавиатуры число 123, условное выражение, проверяемое в цикле, станет ложным, и цикл завершится. Поскольку выражение инкремента в заголовке цикла for отсутствует, управляющая переменная цикла не модифицируется.
Приведем еще один вариант цикла for, в заголовке которого, как показано в следующем фрагменте кода, отсутствует раздел инициализации.

cout << «Введите номер позиции: «;

cin >> х;

for ( ; х<limit; х++) cout << ‘ ‘;
Здесь пустует раздел инициализации, а управляющая переменная х инициализируется значением, вводимым пользователем с клавиатуры до входа в цикл.
К размещению выражения инициализации за пределами цикла, как правило, прибегают только в том случае, когда начальное значение генерируется сложным процессом, который неудобно поместить в определение цикла. Кроме того, раздел инициализации оставляют пустым и в случае, когда управление циклом осуществляется с помощью параметра некоторой функции, а в качестве начального значения управляющей переменной цикла используется значение, которое получает параметр при вызове функции.
Бесконечный цикл
Бесконечный цикл — это цикл, который никогда не заканчивается.
Оставив пустым условное выражение цикла for, можно создать бесконечный цикл (цикл, который никогда не заканчивается). Способ создания такого цикла показан на примере следующей конструкции цикла for.

for (;;)

{

//…

}
Этот цикл будет работать без конца. Несмотря на существование некоторых задач программирования (например, командных процессоров операционных систем), которые требуют наличия бесконечного цикла, большинство «бесконечных циклов» — это просто циклы со специальными требованиями к завершению. Ближе к концу этой главы будет показано, как завершить цикл такого типа. (Подсказка: с помощью инструкции break.)
Циклы временной задержки
В программах часто используются так называемые циклы временной задержки. Их задача — просто «убить время». Для создания таких циклов достаточно оставить пустым тело цикла, т.е. опустить те инструкции, которые повторяет цикл на каждой итерации. Вот пример:

for (x=0; х<1000; х++);
Этот цикл лишь инкрементирует значение переменной х и не делает ничего более. Точка с запятой (в конце строки) необходима по причине того, что цикл for ожидает получить инструкцию, которая может быть пустой (как в данном случае).
Прежде чем двигаться дальше, не помешало бы поэкспериментировать с собственными вариациями на тему цикла for. Это вам поможет убедиться в его гибкости и могуществе.
Инструкция switch
Инструкция switch— это инструкция многонаправленного ветвления, которая позволяет выбрать одну из множества альтернатив.
Прежде чем переходить к изучению других циклических С++-конструкций, познакомимся с еще одной инструкцией выбора — switch. Инструкция switch обеспечивает многонаправленное ветвление. Она позволяет делать выбор одной из множества альтернатив. Хотя многонаправленное тестирование можно реализовать с помощью последовательности вложенных if-инструкций, во многих ситуациях инструкция switch оказывается более эффективным решением. Она работает следующим образом. Значение выражения последовательно сравнивается с константами из заданного списка. При обнаружении совпадения для одного из условий сравнения выполняется последовательность инструкций, связанная с этим условием. Общий формат записи инструкции switch таков.

switch (выражение) {

case константа1:

последовательность инструкций

break;

case константа2:

последовательность инструкци

break;

case константа3:

последовательность инструкций

break;

.

.

.

default:

последовательность инструкций

}
Элемент выражение инструкции switch должен при вычислении давать целочисленное или символьное значение. (Выражения, имеющие, например, тип с плавающей точкой, не разрешены.) Очень часто в качестве управляющего switch-выражения используется одна переменная.
Инструкция break завершает выполнение кода, определенного инструкцией switch.
Последовательность инструкций default-ветви выполняется в том случае, если ни одна из заданных case-констант не совпадет с результатом вычисления switch-выражения. Ветвь default необязательна. Если она отсутствует, то при несовпадении результата выражения ни с одной из case-констант никакое действие выполнено не будет. Если такое совпадение все-таки обнаружится, будут выполняться инструкции, соответствующие данной case-ветви, до тех пор, пока не встретится инструкция break или не будет достигнут конец switch-инструкции (либо в default- , либо в последней case-ветви).
Инструкции default-ветви выполняются в том случае, если ни одна из case констант не совпадет с результатом вычисления switch-выражения.
Итак, для применения switch-инструкции необходимо знать следующее.
■ Инструкция switch отличается от инструкции if тем, что switch-выражение можно тестировать только с использованием условия равенства (т.е. на совпадение switch-выражения с заданными case-константами), в то время как условное if-выражение может быть любого типа.
■ Никакие две case-константы в одной switch-инструкции не могут иметь идентичных значений.
■ Инструкция switch обычно более эффективна, чем вложенные if-инструкции.
■ Последовательность инструкций, связанная с каждой case-ветвью, не является блоком. Однако полная switch-инструкция определяет блок. Значимость этого факта станет очевидной после того, как вы больше узнаете о C++.
Согласно стандарту C++ switch-конструкция может иметь не более 16 384 case-инструкций. Но на практике (исходя из соображений эффективности) обычно ограничиваются гораздо меньшим их количеством.
Использование switch-инструкции демонстрируется в следующей программе. Она создает простую «справочную» систему, которая описывает назначение for- , if- и switch-инструкций. После отображения списка предлагаемых тем, по которым возможно предоставление справки, программа переходит в режим ожидания до тех пор, пока пользователь не сделает свой выбор. Введенное пользователем значение используется в инструкции switch для отображения информация по указанной теме. (Вы могли бы в качестве упражнения дополнить информацию по имеющимся темам, а также ввести в эту «справочную» систему новые темы.)

// Демонстрация switch-инструкции на примере простой «справочной» системы.

#include <iostream>

using namespace std;

int main ()

{

int choice;

cout << «Справка по темам:\n\n»;

cout << «1. for\n»;

cout << «2. if\n»;

cout << «3. switch\n\n»;

cout << «Введите номер темы (1-3): «;

cin >> choice;

cout << „\n“;

switch (choice) {

case 1:

cout << „for — это самый универсальный цикл в С++.\n“;

break;

case 2:

cout << „if — это инструкция условного ветвления.\n“;

break;

case 3:

cout <<»switch — это инструкция многонаправленного ветвления.\n»;

break;

default:

cout << «Вы должны ввести число от 1 до З.\n»;

}

return 0;

}
Вот один из вариантов выполнения этой программы.

Справка по темам:

1. for

2. if

3. switch

Введите номер темы (1-3) : 2
if — это инструкция условного ветвления.
Формально инструкция break необязательна, хотя в большинстве случаев использования switch-конструкций она присутствует. Инструкция break, стоящая в последовательности инструкций любой case-ветви, приводит к выходу из всей switch-конструкции и передает управление инструкции, расположенной сразу после нее. Но если инструкция break в case-ветви отсутствует, будут выполнены все инструкции, связанные с данной case-ветвью, а также все последующие инструкции, расположенные под ней, до тех пор, пока все-таки не встретится инструкция break, относящаяся к одной из последующих case-ветвей, или не будет достигнут конец switch-конструкции.
Рассмотрим внимательно следующую программу. Попробуйте предугадать, что будет отображено на экране при ее выполнении.

#include <iostream>

using namespace std;

int main ()

{

int i;

for (i=0; i<5; i++) {

switch (i) {

case 0: cout << «меньше 1\n»;

case 1: cout << «меньше 2\n»;

case 2: cout << «меньше 3\n»;

case 3: cout << «меньше 4\n»;

case 4: cout << «меньше 5\n»;

}

cout << ‘ \n’;

}

return 0;

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

меньше 1

меньше 2

меньше 3

меньше 4

меньше 5

меньше 2

меньше 3

меньше 4

меньше 5

меньше 3

меньше 4

меньше 5

меньше 4

меньше 5

меньше 5
Как видно по результатам, если инструкция break в одной case-ветви отсутствует, выполняются инструкции, относящиеся к следующей case-ветви.
Как показано в следующем примере, в switch-конструкцию можно включать «пустые» case-ветви.

switch (i) {

case 1:

case 2:

case 3: do_something ();

break;

case 4: do_something_else ();

break;

}
Если переменная i в этом фрагменте кода получает значение 1, 2 или 3, вызывается функция do_something (). Если же значение переменной i равно 4, делается обращение к функции do_something_else (). Использование «пачки» нескольких пустых case-ветвей характерно для случаев, когда они используют один и тот же код.
Вложенные инструкции switch
Инструкция switch может быть использована как часть case -последовательности внешней инструкции switch. В этом случае она называется вложенной инструкцией switch. Необходимо отметить, что case-константы внутренних и внешних инструкций switch могут иметь одинаковые значения, при этом никаких конфликтов не возникнет. Например, следующий фрагмент кода вполне допустим.

switch (ch1) {

case ‘А’: cout <<«Эта константа А — часть внешней инструкции switch»;

switch (ch2) {

case ‘A’: cout <<«Эта константа A — часть внутренней инструкции switch»;

break;

case ‘В’: // …

}

break;

case ‘В’: // …
Цикл while
Инструкция while — еще один способ организации циклов в C++.
Общая форма цикла while имеет такой вид:

while (выражение) инструкция;
Здесь под элементом инструкция понимается либо одиночная инструкция, либо блок инструкций. Работой цикла управляет элемент выражение, который представляет собой любое допустимое С++-выражение. Элемент инструкция выполняется до тех пор, пока условное выражение возвращает значение ИСТИНА. Как только это выражение становится ложным, управление передается инструкции, которая следует за этим циклом.
Использование цикла while демонстрируется на примере следующей небольшой программы. Практически все компиляторы поддерживают расширенный набор символов, который не ограничивается символами ASCII. В расширенный набор часто включаются специальные символы и некоторые буквы из алфавитов иностранных языков. ASCII-символы используют значения, не превышающие число 127, а расширенный набор символов— значения из диапазона 128-255. При выполнении этой программы выводятся все символы, значения которых лежат в диапазоне 32-255 (32 — это код пробела). Выполнив эту программу, вы должны увидеть ряд очень интересных символов.

/* Эта программа выводит все печатаемые символы, включая расширенный набор символов, если таковой существует.

*/

#include <iostream>

using namespace std;

int main (){

unsigned char ch;

ch = 32;

while (ch) {

cout << ch;

ch++;

}

return 0;

}
Рассмотрим while-выражение из предыдущей программы. Возможно, вас удивило, что оно состоит всего лишь из одной переменной ch. Но «ларчик» здесь открывается просто. Поскольку переменная ch имеет здесь тип unsigned char, она может содержать значения от 0 до 255. Если ее значение равно 255, то после инкрементирования оно «сбрасывается» в нуль. Следовательно, факт равенства значения переменной ch нулю служит удобным способом завершить while-цикл.
Подобно циклу for, условное выражение проверяется при входе в цикл while, а это значит, что тело цикла (при ложном результате вычисления условного выражения) может не выполниться ни разу. Это свойство цикла устраняет необходимость отдельного тестирования до начала цикла. Следующая программа выводит строку, состоящую из точек. Количество отображаемых точек равно значению, которое вводит пользователь. Программа не позволяет «рисовать» строки, если их длина превышает 80 символов. Проверка на допустимость числа выводимых точек выполняется внутри условного выражения цикла, а не снаружи.

#include <iostream>

using namespace std;

int main ()

{

int len;

cout << «Введите длину строки (от 1 до 79): «;

cin >> len;

while (len>0 && len<80) {

cout << ‘.’;

len—;

}

return 0;

}
Тело while-цикла может вообще не содержать ни одной инструкции. Вот пример:

while (rand () != 100);
Этот цикл выполняется до тех пор, пока случайное число, генерируемое функцией rand (), не окажется равным числу 100.
Цикл do-while
Цикл do-while — это единственный цикл, который всегда делает итерацию хотя бы один раз.
В отличие от циклов for и while, в которых условие проверяется при входе, цикл do-while проверяет условие при выходе из цикла. Это значит, что цикл do-while всегда выполняется хотя бы один раз. Его общий формат имеет такой вид.
do {
инструкции;
}while (выражение);
Несмотря на то что фигурные скобки необязательны, если элемент инструкции состоит только из одной инструкции, они часто используются для улучшения читабельности конструкции do-while, не допуская тем самым путаницы с циклом while. Цикл do-while выполняется до тех пор, пока остается истинным элемент выражение, который представляет собой условное выражение.
В следующей программе цикл do-while выполняется до тех пор, пока пользователь не введет число 100.

#include <iostream>

using namespace std;

int main ()

{

int num;

do {

cout << «Введите число (100 — для выхода): «;

cin >> num;

}while (num != 100);

return 0;

}
Используя цикл do-while, мы можем еще более усовершенствовать программу «Угадай магическое число». На этот раз программа «не выпустит» вас из цикла угадывания, пока вы не угадаете это число.

// Программа «Угадай магическое число»:

// 3-е усовершенствование.

#include <iostream>

#include <cstdlib>

using namespace std;

int main ()

{

int magic; // магическое число

int guess; // вариант пользователя

magic = rand (); // Получаем случайное число.

do {

cout << «Введите свой вариант магического числа: «;

cin >> guess;

if (guess == magic) {

cout << «** Правильно ** „;

cout << magic <<“ и есть то самое магическое число.\n»;

}

else {

cout << «…Очень жаль, но вы ошиблись.»;

if (guess > magic)

cout <<» Ваш вариант превышает магическое число.\n»;

else cout <<» Ваш вариант меньше магического числа.\n»;

}

}while (guess != magic);

return 0;

}
Использование инструкции continue
Инструкция continue позволяет немедленно перейти к выполнению следующей итерации цикла.
В C++ существует средство «досрочного» выхода из текущей итерации цикла. Этим средством является инструкция continue. Она принудительно выполняет переход к следующей итерации, опуская выполнение оставшегося кода в текущей. Например, в следующей программе инструкция continue используется для «ускоренного» поиска чётных чисел в диапазоне от 0 до 100.

#include <iostream>

using namespace std;

int main ()

{

int x;

for (x=0; x<=100; x++) {

if (x%2) continue;

cout << x << ‘ ‘;

}

return 0;

}
Здесь выводятся только четные числа, поскольку при обнаружении нечётного числа происходит преждевременный переход к следующей итерации, и cout-инструкция опускается.
В циклах while и do-while инструкция continue передает управление непосредственно инструкции, проверяющей условное выражение, после чего циклический процесс продолжает «идти своим чередом». А в цикле for после выполнения инструкции continue сначала вычисляется инкрементное выражение, а затем— условное. И только после этого циклический процесс будет продолжен.
Использование инструкции break для выхода из цикла
Инструкция break позволяет немедленно выйти из цикла.
С помощью инструкции break можно организовать немедленный выход из цикла, опустив выполнение кода, оставшегося в его теле, и проверку условного выражения. При обнаружении внутри цикла инструкции break цикл завершается, а управление передается инструкции, следующей, после цикла. Рассмотрим простой пример.

#include <iostream>

using namespace std;

int main ()

{

int t;

// Цикл работает для значений t от 0 до 9, а не до 100!

for (t=0; t<100; t++) {

if (t==10) break;

cout << t <<‘ ‘;

}

return 0;

}
Эта программа выведет на экран числа от 0 до 9, а не до 100, поскольку инструкция break при значении t, равном 10, обеспечивает немедленный выход из цикла.
Инструкция break обычно используется циклах, в которых при создании особых условий необходимо обеспечить немедленное их завершение. Следующий фрагмент содержит пример ситуации, когда по нажатию клавиши выполнение цикла останавливается.

for (i=0; i<1000; i++) {

// Какие-то действия.

if (kbhit ()) break;

}
Инструкция break приводит к выходу из самого внутреннего цикла. Рассмотрим пример.

#include <iostream>

using namespace std;

int main ()

{

int t, count;

for (t=0; t<100; t++) {

count = 1;

for (;;) {

cout << count << ‘ ‘;

count++;

if (count==10) break;

}

cout << ‘\n’;

}

return 0;

}
Эта программа 100 раз выводит на экран числа от 0 до 9. При каждом выполнении инструкции break управление передается назад во внешний цикл for.
На заметку. Инструкция break, которая завершает выполнение инструкции switch, влияет только на инструкцию switch, а не на содержащий ее цикл.
На примере предыдущей программы вы убедились, что в C++ с помощью инструкция for можно создать бесконечный цикл. (Бесконечные циклы можно также создавать, используя инструкции while или do-while, но цикл for — это традиционное решение.) Для выхода из бесконечного цикла необходимо использовать инструкцию break. (Безусловно, инструкцию break можно использовать и для завершения небесконечного цикла.)
Вложенные циклы
Как было продемонстрировано на примере предыдущей программы, один цикл можно вложить в другой. В C++ разрешено использовать до 256 уровней вложения. Вложенные циклы используются для решения задач самого разного профиля. Например, в следующей программе вложенный цикл for позволяет найти простые числа в диапазоне от 2 до 1000.

/* Эта программа выводит простые числа, найденные в диапазоне от 2 до 1000.

*/

#include <iostream>

using namespace std;

int main ()

{

int i, j;

for (i=2; i<1000; i++) {

for (j=2; j<=(i/j); j++)

if (!(i%j)) break; // Если число имеет множитель, значит, оно не простое.

if (j > (i/j)) cout << i << « — простое число\n»;

}

return 0;

}
Эта программа определяет, является ли простым число, которое содержится в переменной i, путем последовательного его деления на значения, расположенные между числом 2 и результатом вычисления выражения i/j. (Остановить перебор множителей можно на значении выражения i/j, поскольку число, которое превышает i/j, уже не может быть множителем значения i.) Если остаток от деления i/j равен нулю, значит, число i не является простым. Но если внутренний цикл завершится полностью (без досрочного окончания по инструкции break), это означает, что текущее значение переменной i действительно является простым числом.
Инструкция goto
Инструкция goto — это С++-инструкция безусловного перехода.
Долгие годы эта инструкция находилась в немилости у программистов, поскольку способствовала, с их точки зрения, созданию «спагетти-кода». Однако инструкция goto по-прежнему используется, и иногда даже очень эффективно. В этой книге не делается попытка «реабилитации» законных прав этой инструкции в качестве одной из форм управления программой. Более того, необходимо отметить, что в любой ситуации (в области программирования) можно обойтись без инструкции goto, поскольку она не является элементом, обеспечивающим полноту описания языка программирования. Вместе с тем, в определенных ситуациях ее использование может быть очень полезным В этой книге было решено ограничить использование инструкции goto рамками этого раздела, так как, по мнению большинства программистов, она вносит в программу лишь беспорядок и делает ее практически нечитабельной. Но, поскольку использование инструкции goto в некоторых случаях может сделать намерение программиста яснее, ей стоит уделить некоторое внимание.
Инструкция goto требует наличия в программе метки. Метка — это действительный в C++ идентификатор, за которым поставлено двоеточие. При выполнении инструкции goto управление программой передается инструкции, указанной с помощью метки. Метка должна находиться в одной функции с инструкцией goto, которая ссылается на эту метку.
Метка — это идентификатор, за которым стоит двоеточие.
Например, с помощью инструкции goto и метки можно организовать следующий цикл на 100 итераций.

х = 1;

loop1:

х++;

if (х < 100) goto loop1;
Иногда инструкцию goto стоит использовать для выхода из глубоко вложенных инструкций цикла. Рассмотрим следующий фрагмент кода.

for (…) {

for (…) {

while (…) {

if (…) goto stop;

}

}

}

stop:

cout << «Ошибка в программе.\n»;
Чтобы заменить инструкцию goto, пришлось бы выполнить ряд дополнительных проверок. В данном случае инструкция goto существенно упрощает программный код. Простым применением инструкции break здесь не обошлось, поскольку она обеспечила бы выход лишь из самого внутреннего цикла.
Важно! Инструкцию goto следует применять с оглядкой (как сильнодействующее лекарство). Если без нее ваш код будет менее читабельным или для вас важна скорость выполнения программы, то в таких случаях использование инструкции goto показано.
Итак, подведем итоги…
Следующий пример представляет собой последнюю версию программы «Угадай магическое число». В ней использованы многие средства С++-программирования, представленные в этой главе, и, прежде чем переходить к следующей, убедитесь в том, что хорошо понимаете все рассмотренные здесь элементы языка C++. Этот вариант программы позволяет сгенерировать новое число, сыграть в игру и выйти из программы.

// Программа «Угадай магическое число»: последняя версия.

#include <iostream>

#include <cstdlib>

using namespace std;

void play (int m);

int main ()

{

int option;

int magic;

magic = rand ();

do {

cout << «1. Получить новое магическое число\n»;

cout << «2. Сыграть\n»;

cout << «3. Выйти из программы\n»;

do {

cout << «Введите свой вариант: «;

cin >> option;

}while (option<1 || option>3);

switch (option){

case 1:

magic = rand ();

break;

case 2:

play (magic);

break;

case 3:

cout << «До свидания !\n»;

break;

}

}while (option != 3);

return 0;

}

// Сыграем в игру.

void play (int m)

{

int t, x;

for (t=0; t<100; t++) {

cout << «Угадайте магическое число: «;

cin >> x;

if (x==m) {

cout << «** Правильно **\n»;

return;

}

else

if (x<m) cout << «Маловато.\n»;

else cout << «Многовато.\n»;

}

cout << «Вы использовали все шансы угадать число. » << «Попытайтесь снова.\n»;

}

Понравилась статья? Поделить с друзьями:
  • Цефтриаксон 500 мг инструкция по применению цена отзывы
  • Руководство управы ховрино
  • Сигнализация centurion x line инструкция скачать
  • Каким должен быть по вашему мнению стиль руководства
  • Номидез таблетки инструкция по применению для детей