Примеры операторов CASE.




Проектирование последовательного потока управления.

 

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

 

Операторы CASE, FOR и REPEAT рассмотренные в этой главе позволяют программисту выражать свои намерения точно и более естественно, чем использую набор CF Pascal. Когда оператор IF выбирает один из двух вариантов, оператор CASE позволяет выбирать одну из нескольких альтернатив. Как и оператор WHILE, FOR и REPEAT управляют итерациями. Оператор FOR управляется подсчетом итераций, таким образом, использование операторов FOR естественно для ситуаций, когда необходимо выполнить определенное количество повторяющихся действий. Наоборот, оператор WHILE подходит для ситуаций, когда количество итераций неизвестно, но известно условие завершения цикла. В WHILE цикл может быть бесконечным, а в FOR – не может. Оператор REPEAT также управляет неограниченным циклом, но тогда как проверка WHILE на завершение происходит перед каждой итерацией и выражается в форме условия, которое должно удовлетворяться для продолжения, REPEAT выполняет проверку после каждой итерации и это происходит в форме условия, которое должно удовлетворяться для завершения.

 

Оператор CASE.

 

Мы использовали вложенные IF для выбора одного оператора из нескольких. Оператор CASE может часто заменять вложенные IF с выигрышем в наглядности и эффективности.

 

Оператор CASE строится из выражения порядкового типа для выбора и списка операторов, каждый из которых отмечен одной или более константами того же порядкового типа. Например, в

 

CASE A > B OF

TRUE: Max:= A;

FALSE: Max:= B;

END

 

выражение для выбора будет A > B типа BOOLEAN, а метками будут константы того же типа TRUE и FALSE. Выражение для выбора вычисляется и оператор, помеченный соответствующей меткой, выбирается для выполнения. После того как выбранный оператор завершает выполнение, управление передается оператору, следующему за оператором CASE. Константные метки не могут повторяться, поэтому выполнено будет не более одного оператора. Если не существует оператора с меткой имеющей значение выражения для выбора, результат выполнения оператора CASE неопределен.

Оператор CASE может быть симулирован вложенными операторами IF. Рассмотрим оператор CASE:

 

CASE Exp OF

L1a, L1b: S1;

L2: S2;

...;

LN: SN

END

 

оператор IF

 

IF (Exp = L1a) OR (Exp = L1b)

THEN

S1

ELSE

IF Exp = L2

THEN

S2

ELSE

...

ELSE

IF Exp = LN

THEN

SN

 

Выполняет те же действия, когда значение Exp является одним из L1a, L1b, L2,..., LN. Однако когда значение Exp не входит в набор вариантов, оператор IF работает как пустой оператор, а оператор CASE неопределен. Большинство Паскаль-машин реализуют оператор CASE некорректно, и он в случае отсутствия варианта работает аналогично соответствующему оператору IF.

Использование оператора CASE сокращает глубину вложенности операторов и необходимость в логических операторах, повышая читаемость программы. Также оператор CASE более эффективен, чем IF, поскольку весь весь оператор CASE вычисляется один раз, а для вложенных IF выполняется множество сравнений.

 

Примеры операторов CASE.

 

Операторы CASE особенно полезны с перечислимыми типами. Процедура WriteMonth записывает строковое хначение, соотвествующее значению перечислимого типа Month.

 

PROCEDURE WriteMonth(VAR Fout: TEXT; Mo: Month);

{Fout.3=W and Mo<>NoMonth -->

записываем три символа соответствущих значению Mo в Fout.1}

BEGIN {WriteMonth}

CASE Mo OF

Jan: WRITE(Fout, ‘Jan’);

Feb: WRITE(Fout, ‘Feb’);

Mar: WRITE(Fout, ‘Mar’);

Apr: WRITE(Fout, ‘Apr’);

May: WRITE(Fout, ‘May’);

Jun: WRITE(Fout, ‘Jun’);

Jul: WRITE(Fout, ‘Jul’);

Aug: WRITE(Fout, ‘Aug’);

Sep: WRITE(Fout, ‘Sep’);

Oct: WRITE(Fout, ‘Oct’);

Nov: WRITE(Fout, ‘Nov’);

Dec: WRITE(Fout, ‘Dec’);

END;

END; {WriteMonth}

 

WriteMonth пердполагает, что Mo было присвоено одно из константных значений типа Month и явно исключает из своей области определения NoMonth. Более robust версия WriteMonth может проверять, что Mo имеет одно из двенадцати значений типа Month перед выполнением оператора CASE.

 

IF Mo IN [Jan.. Dec]

THEN

CASE Mo OF

Jan: WRITE(Fout, ‘Jan’);

Feb: WRITE(Fout, ‘Feb’);

Mar: WRITE(Fout, ‘Mar’);

Apr: WRITE(Fout, ‘Apr’);

May: WRITE(Fout, ‘May’);

Jun: WRITE(Fout, ‘Jun’);

Jul: WRITE(Fout, ‘Jul’);

Aug: WRITE(Fout, ‘Aug’);

Sep: WRITE(Fout, ‘Sep’);

Oct: WRITE(Fout, ‘Oct’);

Nov: WRITE(Fout, ‘Nov’);

Dec: WRITE(Fout, ‘Dec’);

END;

 

Защищая оператор CASE таким способом, программист может быть уверен, что он всегда (на всех Паскаль-машинах) будет выполняться корректно.

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

 

WHILE NOT EOF

DO

BEGIN

READ(Ch);

IF Ch IN [‘+’, ‘-‘, ‘*’, ‘/’]

THEN

CASE Ch OF

‘+’, ‘-‘:

BEGIN

WRITELN(‘Обнаружен аддитивный оператор’);

CASE Ch OF

‘+’: NumPlus:= NumPlus + 1;

‘-‘: NumMinus:= NumMinus + 1

END

END;

‘*’, ‘/‘: WRITELN(‘Обнаружен мультипликативный оператор’);

END

ELSE

NumOther:= NumOther + 1;

END

 

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

 

IF AnswerCount <= 1

THEN

CASE AnswerCount OF

0: WRITE(‘There are none.’);

1: WRITE(‘There is 1.’);

END

ELSE

WRITE(‘There are ’, AnswerCount:3)

 



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2016-04-12 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: