then
BEGIN
...
end
else { ПодУсловие не выполняется }
BEGIN
...
end
ELSE { Условие не выполняется }
BEGIN
...
end;
- 96 -
Еще раз обращаем внимание на отсутствие точки с запятой между ключевыми словами до самого внешнего слова END.
При вложениях условных операторов самое главное — не запутаться в вариантах сочетаний условий (отчасти этому может помочь ступенчатая форма записи операторов). Всегда действует правило: альтернатива ELSE считается принадлежащей ближайшему условному оператору IF, не имеющему ветви ELSE. Именно это правило заложено в компилятор, и, как следствие этого, есть риск создать неправильно понимаемые условия. Например:
IF Условие1
THEN
if Условие2
then ОператорА
ELSE
ОператорБ;
По записи похоже, что ОператорБ будет выполняться только при невыполнении Условия1. Но в действительности он будет отнесен к Условию2 и выполнится лишь при выполнении Условия1 и невыполнении Условия2. Попытка закрыть вложенный условный оператор установкой «;» после ОператораА лишь ухудшит положение. Выход здесь таков: нужно представить вложенное условие как составной оператор
IF Условие1
THEN
BEGIN
if Условие2
then ОператорА
end
ELSE
ОператорБ;
и для ветви ELSE ближайшим «незакрытым» оператором IF окажется оператор с Условием1.
В условии оператора IF может стоять достаточно сложное логическое выражение. В нем придется учитывать приоритет различных логических и математических операций, а также текущую схему компиляции логических выражений в Турбо Паскале. (Подробнее об этом см. разд. 9.3 «Логические вычисления и операции отношения».)
6.3. Оператор варианта (CASE)
Оператор варианта необходим в тех случаях, когда в зависимости от значений какой-либо переменной надо выполнить те или иные
- 97 -
операторы (простые или составные). Если вариантов всего два, то можно обойтись и оператором IF. Но если их, например, десять? В этом случае оптимален оператор варианта CASE. Структура оператора CASE имеет вид
CASE УправляющаяПеременнаяИлиВыражение OF
НаборЗначений1 : Оператор1;
НаборЗначений2 : Оператор2;
НаборЗначенийЗ : ОператорЗ;
...
НаборЗначенийN : ОператорN
ELSE
АльтернативныйВсемНаборамОператор
END;
Между служебными словами CASE и OF должна стоять переменная или выражение (оно вычислится при исполнении оператора CASE). Тип переменной (или значения выражения) может быть только перечислимым (включая типы Char и Boolean), диапазоном или целочисленным одного из типов Byte, ShortInt, Integer или Word. Все прочие типы не будут пропущены компилятором Турбо Паскаля. Набор значений — это конкретные значения управляющей переменной или выражения, при которых необходимо выполнить соответствующий оператор, игнорируя остальные варианты. Если в наборе несколько значений, то они разделяются между собой запятыми. Можно указывать диапазоны значений. Между набором значений и соответствующим ему оператором обязательно должно ставиться двоеточие «:».
Оператор в конкретном варианте может быть как простым, так и составным. Конец варианта обязательно обозначается точкой с запятой. Турбо Паскаль допускает необязательную часть ELSE. Если значение переменной (выражения) не совпало ни с одним из значений в вариантах, то будет выполнен оператор, стоящий в части ELSE.
Завершает оператор CASE слово END. По-прежнему перед ELSE и END необязательна точка с запятой. Рассмотрим пример оператора варианта (в нем Err — переменная типа Word):
| CASE Err OF
| 0 : WriteLn( 'Нормальное завершение программы' );
| 2, 4, 6 : begin
| WriteLn('Ошибка при работе с файлом');
| WriteLn('Повторите действия снова.')
| end;
- 98 -
| 7..99 : WriteLn( 'Ошибка с кодом ', Err )
| ELSE {case}
| WriteLn( 'Код ошибки=,Err,' См. описание')
| END; {case}
Здесь в зависимости от значения переменной Err выводится на экран операторами WriteLn текст соответствующего сообщения. Наличие варианта ELSE (Err не равна 0, 2, 4, 6 и не входит в диапазон 7..99) гарантирует выдачу сообщения в любом случае.
Значения в каждом наборе должны быть уникальными, т.е. они могут появиться только в одном варианте. Пересечение наборов значений для разных вариантов является ошибкой, и она будет замечена компилятором.
Оператор варианта CASE очень удобен и, как правило, более эффективен, чем несколько операторов IF того же назначения. Эффективность его в смысле скорости будет максимальной, если размещать наиболее вероятные значения (или их наборы) первыми в порядке следования.
6.4. Оператор цикла с предусловием (WHILE)
В практике программирования циклы — повторяющиеся выполнения одних и тех же простых или составных операторов — играют очень важную роль. Существует три стандартных способа организации циклических вычислений.
Рассмотрим оператор цикла с предусловием, записываемый как
WHILE Условие DO Оператор;
Конструкция WHILE...DO переводится как «пока...делать». Оператор (простой или составной), стоящий после служебного слова DO и называемый телом цикла, будет выполняться циклически, пока выполняется логическое условие, т.е. пока значение «Условия» равно True. Само условие цикла может быть логической константой, переменной или выражением с логическим результатом.
Условие выполнения тела цикла WHILE проверяется до начала выполнения каждой итерации. Поэтому, если условие сразу не выполняется, то тело цикла игнорируется и будет выполняться оператор, стоящий сразу за телом цикла.
При написании циклов с предусловием следует помнить о двух вещах. Во-первых, чтобы цикл имел шанс когда-нибудь завершиться, содержимое его тела должно обязательно влиять на условие цикла. Во-вторых, условие должно состоять из корректных
- 99 -
выражений и значений, определенных еще до первого выполнения тела цикла. Поясним сказанное примером, вычисляющим значение факториала 10! (рис. 6.1).
| VAR
| Factorial, N : Integer;
| BEGIN
| Factorial := 1; { стартовое значение факториала = 0! }
| N:=1; {стартовое значение для условия цикла}
| WHILE N<=10 DO
| begin { начало тела цикла WHILE }
| Factoriaclass="underline" =Factorial*N; { вычисление факториала N! }
| N := N + 1 { N должно меняться в цикле }
| end; { конец тела цикла WHILE }
| WriteLn( Factorial ); { вывод результата расчета }
| END.
Рис. 6.1