|
| ||||||||||||||||||
Паскаль для новичков (часть 9)Оператор переходаАвтор: Владислав Демьянишин
В этот раз я продолжу рассмотрение темы “Операторы”.
Операторы (безусловного) перехода предназначены для передачи управления оператору, помеченному меткой (которому предшествует метка).
Авторская версия языка предполагает оформление метки в виде целого десятичного числа в диапазоне 1..9999. В качестве меток Turbo Pascal допускает использование идентификаторов. При использовании операторов перехода необходимо соблюдать следующие правила:
1) Все метки, находящиеся в блоке, должны быть описаны. При этом каждая метка может быть описана не более одного раза. Т.е. в пределах блока не может быть двух меток с одним и тем же именем.
2) Метка, указанная в операторе перехода, должна указывать на оператор (помечать его), находящийся в том же блоке, что и сам оператор перехода. Т.е. переходы вовне процедур (функций) или внутрь них не допускаются.
3) Попытка перехода (передачи управления) внутрь структурного оператора может вызвать непредсказуемые эффекты, хотя в данном случае компилятор может не выдать сообщения об ошибке.
Применение безусловного перехода в программе считается теоретически избыточным, так как может внести путаницу в цепочку логически размещенных операций программы, что может повлечь большие сложности при отладке и модификации такой программы. Применять операторы перехода рекомендуется, соблюдая следующие правила:
1) если кажется невозможным обойтись без операторов перехода, необходимо стремиться применять их для передачи управления только вниз по тексту программы (вперед); при возникновении необходимости передачи управления “назад” лучше использовать операторы цикла (см. далее);
2) для наглядности, расстояние между меткой и оператором перехода на нее не должно превышать одной страницы текста (или высоты экрана дисплея), иначе смысл такого безусловного перехода будет трудно уловить.
Метки определяются посредством описаний, которые начинаются со служебного слова label и содержат последовательность имен меток через запятую. Для передачи управления оператору, помеченному меткой, предусмотрен оператор безусловного перехода goto. Метка отделяется от следующего за ней оператора символом ‘:’ (двоеточие). Пример:
var j : integer;
{ объявляем две метки }
label Start, Finish;
begin
Start: writeln(‘Начало программы’);
…
goto Finish;
…
Finish: writeln(‘Конец программы’);
end.
Составной операторСамым простейшим структурным оператором является составной оператор. Данный оператор задает последовательность выполнения содержащихся в нем операторов. Составной оператор оформляется в виде списка операторов, отделенных друг от друга символом ‘;’ (точка с запятой) и заключенных между служебными словами begin и end.
Необходимость в составном операторе может возникать в тех случаях, когда синтаксис языка Pascal допускает использование только одного оператора в том месте программы, где необходим целый ряд действий (операторов, см. примеры далее). Приведу простой пример составного оператора:
begin
X := 10;
Y := 20;
Q := X*X – Y*Y;
end;
Условный операторСмысл условного оператора состоит в том, чтобы провести анализ некоторого логического условия, и в соответствии с тем, выполняется это условие или нет, передать управление соответствующему оператору. В качестве условия может быть выражение, возвращающее логическое значение булевского типа. Результатом анализа условия может быть значение true, т.е. условие выполняется и false, т.е. условие не выполняется.
Условный оператор выполняется следующим образом. Предварительно вычисляется выражение, указанное после служебного слова IF. Если условие выполняется, то управление передается оператору, указанному после служебного слова then, если нет, то выполняется оператор, указанный после служебного слова else. При этом часть условного оператора, начиная со слова else, может отсутствовать. Вот примеры условных операторов:
If Keypressed then writeln(‘Клавиша нажата’);
If A > B then Min := B
else Min := A;
if X1 > X2 then begin
T := X1;
X1 := X2;
X2 := T;
end;
Последний пример – это как раз тот случай, когда необходимо, чтобы по условию выполнялся ряд операторов, но в силу того, что за служебным словом then или else может следовать только один оператор, то есть возможность урегулировать ситуацию, используя составной оператор, содержащий как раз ряд тех необходимых операторов.
При составлении вложенных условных операторов следует учитывать, что ветвь else всегда принадлежит предшествующему ветвлению IF, у которого еще нет ветви else. Т.е. следующую конструкцию
if Условие1 then if Условие2 then Оператор1 else Оператор2;
для ясности, можно трактовать так
if Условие1 then begin
if Условие2 then Оператор1 else Оператор2;
end;
Необходимо соблюдать аккуратность при использовании вложенных условных операторов, чтобы в запале составления очередного условного оператора программы, не упустить из виду такую, на первый взгляд, мелкую деталь, которая может привести к совершенно иному выполнению условного ветвления.
Оператор вариантаДовольно часто возникает ситуация, когда цепочка условных операторов разрастается до огромных масштабов, например, следующий пример иллюстрирует скромное по своим размерам ветвление, но уже содержащее в себе сложность восприятия смысла, заложенного в нем:
type TWay = ( Up, Right, Down, Left );
var Way : TWay;
MapX, MapY : word;
begin
if Way = Up then MapY := MapY – 1
else if Way = Right then MapX := MapX + 1
else if Way = Down then MapY := MapY + 1
else MapX := MapX – 1;
end.
Последняя ветвь else не имеет оператора If, так как в случае невыполнения всех трех условий логично было бы, чтобы в действие вступал оператор, соответствующий четвертому и последнему варианту возможных значений типа TWay.
В данном случае нам еще повезло, что тип TWay имеет только четыре варианта принимаемых значений. Составление таких ветвлений превратилось бы в рутину, если бы вариантов было десять и более? А ведь в представленном ветвлении просматривается простая закономерность. Так можно ли его как-то упростить и сделать более эффективным и читабельным? Можно, и для этого в языке предусмотрен оператор варианта, конструкция которого может содержать произвольное число альтернатив для определенного выражения. Тогда последний пример можно переписать на новый лад:
case Way of
Up: MapY := MapY – 1;
Right: MapX := MapX + 1;
Down: MapY := MapY + 1;
Left: MapX := MapX – 1;
end;
Ну вот, совсем другое дело. Теперь рассмотрим порядок выполнения данного оператора. Предварительно вычисляется значение выражения, следующего за служебным словом case, но так как в данном случае стоит имя переменной Way, то производится чтение значения этой переменной. Полученное значение сравнивается поочередно с каждой альтернативой (константной, непосредственным значением), указанной после служебного слова of. В случае равенства значения выражения очередной константе, выполняется оператор-альтернатива, следующий за этой константой, отделенный от нее двоеточием. После завершения выполнения альтернативного оператора действие переходит к оператору, следующему за оператором варианта. При несовпадении значения Way ни с одной константой, данный оператор варианта не производит никаких действий.
А как же быть, если необходимо предусмотреть некоторую ветвь операторов, которая выполнялась бы в случае несовпадения значения выражения ни с одной константой? Для этого можно использовать альтернативу else, например:
case Way of
Up: MapY := MapY – 1;
Right: MapX := MapX + 1;
Down: MapY := MapY + 1;
else MapX := MapX – 1;
end;
Следовательно, конструкция, построенная с помощью оператора case полностью эквивалентна конструкции, построенной ранее с помощью оператора IF. К тому же она нагляднее и нет риска запутаться во многочисленных else.
Я еще раз хочу обратить ваше внимание на то, что константами в операторе варианта могут быть как непосредственные целые числа, так и имена нетипизированных констант, описанных ранее. Использование типизированных констант в альтернативах оператора варианта не допускается. При чем в каждом варианте можно указать целый список констант через запятую или диапазон значений, например:
case Way of
Up, Down : writeln(‘Двигаемся по вертикали’);
Right, Left : writeln(‘Двигаемся по горизонтали’);
end;
или
case X of
10,20,30 : writeln(‘десятки’);
1..9 : writeln(‘единицы’);
end;
В последней конструкции оператор writeln(‘единицы’) выполнится, если переменная X будет иметь одно из значений 1,2,3,..,8,9.
Как вы могли заметить, строки с константами я выровнял по двоеточиям, так как мне кажется, что такой вид нагляднее, хотя это дело вкуса, а как известно, на вкус и цвет товарища нет ;O)
Применять оператор варианта следует в соответствии со следующими правилами:
1) Допустимые значение выражения - “переключателя”, записанного после служебного слова case, должны удовлетворять дискретному типу: для целого типа они должны лежать в диапазоне –32768..32767.
2) Все указанные константы альтернатив должны иметь тип, совместимый с типом выражения.
3) Константы в альтернативах не должны повторяться в пределах оператора варианта, а диапазоны не должны пересекаться и не должны содержать констант, указанных в данной или других альтернативах.
И еще одно. Конструкция case предусматривает один оператор для каждой альтернативы. Если возникает необходимость выполнения нескольких операторов, следует сгруппировать их в составной оператор begin..end. Есть возможность указать пустой оператор для альтернативы, поставив символ ';' (точка с запятой) сразу после двоеточия, который ничего не будет выполнять. А синтаксис ветви else предусматривает указание последовательности операторов, разделенных символом ‘;’ (точка с запятой).
Оператор цикла с предусловиемДанный оператор обеспечивает циклическое (повторяющееся) выполнение указанного в нем одного оператора. Перед началом выполнения цикла и перед каждым очередным повторением тела цикла производится проверка значения булевского выражения, управляющего циклом (выражение указывается за служебным словом while). Если выражение возвращает значение true, то происходит очередное выполнение тела цикла (происходит итерация цикла), если же выражение возвращает false, то выполнение цикла прекращается и управление передается оператору, следующему за оператором цикла. Таким образом, если перед выполнением цикла выражение имеет значение false, то цикл не выполняется. Добавлю, что тело цикла может состоять только из одного оператора, и для преодоления этого ограничения следует использовать составной оператор begin..end. Тело цикла размещается после служебного слова do. Вот примеры оператора цикла с предусловием:
while not keypressed do writeln(‘Нажмите любую клавишу’);
while not keypressed do begin
GotoXY(1,1);
write(‘Нажмите любую клавишу’);
end;
Оператор цикла с постусловиемЭтот оператор делает то же, что и предыдущий, с точностью до наоборот. Т.е. сначала выполняется тело цикла, затем происходит проверка значения управляющего булевского выражения, и если выражение возвращает значение false, то цикл выполняет новую итерацию, а если значение выражения равно true, то цикл немедленно прекращает выполнение и передает управление оператору, следующему за оператором цикла.
Тело цикла размещается после служебного слова repeat, и может состоять из нескольких операторов. Завершается тело цикла служебным словом until, после которого указывается управляющее выражение. Вот примеры repeat-цикла:
repeat
GotoXY(1,1);
write(‘Нажмите любую клавишу’);
until keypressed;
или
Count := 10;
Sum := 0;
J := 0;
repeat
Sum := Sum + A[ J ];
inc( J );
until J > Count;
Продолжение следует…
© Владислав Демьянишин
Вы находитесь на официальном сайте Владислава Демьянишина - разработчика игры Dune IV (Dune 4). На нашем сайте Вы можете бесплатно скачать игры Dune IV (Dune 4), Battle City (Танчики с Dendy/Nintendo), читы к играм и многое другое. Также Вы можете скачать бесплатно программы и полезные утилиты. Все программы чистые, т.е. не содержат вирусов и иного вредоносного ПО.
Среди доступных программ есть мобильная читалка книг, менеджер переноса файлов с фото- и видеокамер на компьютер, текстовый редактор, WYSIWYG редактор, 3D аниматор, GIF аниматор, AVI аниматор, пакетный конвертор изображений, редактор электрических схем, программа для скриншотов, диспетчер тем рабочего стола и другие.
На нашем сайте можно не только бесплатно скачать игры, но и документацию и книги по программированию на MIDLetPascal, Turbo Pascal 6, Turbo Pascal 7, Borland Pascal, по программированию устройств Sound Blaster, Adlib, VESA BIOS, справочник Norton Guide и много другой полезной информации для программистов, включая примеры решения реальных задач по созданию резидентных программ.
Журнал > Программирование > Паскаль для новичков (Turbo Pascal, Assembler) > Паскаль для новичков (часть 9): Оператор перехода
| |||||||||||||||||||
|
|||||||||||||||||||