Учебный курс. Микро Паскаль. Условия и циклы.

AVR
Статья №4
Наверное самыми востребованными операторами на любых языках программирования являются циклы и условия. Их то мы и разберем. Все циклы и условия относиться к структурным операторам.
Структурные операторы строятся из специальных зарезервированных слов, логических выражений и других операторов. Каждый такой оператор явно или не явно содержит одну или несколько логических проверок.

И еще одно понятие, которое часто встречается в циклах и условиях – составной оператор.
Составной оператор – это оператор вида:

Begin
  line_1;
  line_2;
  line_n;
 End;

где операторы line_x, в свою очередь, могут быть простыми или составными операторами.
Составной оператор трактуется как один оператор. Такая конструкция используется в ситуациях, когда, согласно формальным правилам языка, разрешается использование лишь одного оператора, а в действительности требуется несколько операторов.

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

Цикл с предусловием.
Данный оператор имеет вид

while условие do действие;

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

while counter < 100 do
   inc (counter);

Цикл с постусловием
Данный цикл имеет вид

repeat действие until условие;

Здесь в начале выполняется «действие», затем вычисляется логическое значение «условия». Процесс повторяется, пока «условие» равно «ложь». Так же можно в сегменте действие применить составной оператор, но можно его и не применять. Паскаль допускает использование нескольких простых операторов. Следующие два примера эквивалентны.

repeat
  line_1;
  line_2;
  line_3;
until false;

repeat
 begin
   line_1;
   line_2;
   line_3;
 end;
until false;

В этом цикле, в отличие от цикла while проверка условия проверяется в последнюю очередь и тело цикла выполняется хотя бы один раз при любом «условии».

Цикл со счетчиком
Здесь два варианта циклов

for…to...do и for…downto…do

В этом цикле участвует любая, обвяленная ранее скалярная переменная, называемая управляющей переменной цикла.
Рассмотрим подробнее цикл

for I := z1 to z2 do

I – Любая переменная. z1,z2 – начальная и конечная точки счетчика цикла. Здесь правильное условие z1<z2. При z1=z2 цикл выполнится один раз, а при z1>z2 — не выполнится ни разу. Эти значения остаются неизменными в ходе выполнения всего цикла. Управляющая переменная последовательно увеличиваясь, пробегает все значения от z1 до z2.

И на оборот, для второго вида цикла.

for I := z1 downto z2 do

Здесь правильное условие z1>z2. При z1=z2 цикл выполнится один раз, а при z1<z2 — не выполнится ни разу. Управляющая переменная последовательно уменьшаясь, пробегает все значения от z1 до z2.
Пример цикла:


 for I := 1 to 10 do
   begin
     line_1 := I;
     line_n;
   end;

Значение управляющей переменной (I) можно использовать для каких либо вычислений внутри цикла, но изменять ее нельзя.
В теле любого цикла можно применить оператор break, который безусловно завершает цикл. Или оператор continue, который завершает текший шаг цикла и переходит к следующей итерации цикла. Рассмотрим более конкретный пример:

1	for i := 1 to 5 do
2	  begin
3	    if i = 3 then continue;
4	    nop;
5	    if i = 4 then break;
6	    nop;
7	  end;
8	

Если значение I будет равно 3, то после третьего шаге цикла, будет выполняться не четвертая, а вторая строка. А если значение I будет равно 4, то после пятого шага цикл вовсе завершиться. Управление перейдет на шаг восемь. Иногда это удобно. Например когда мы явно видим, что очередной проход цикля явная лажа, мы его бросаем и переходим к следующей итерации цикла. Или когда искомое значение найдено, нет нужды проходить весь цикл полностью. Мы его просто бросаем.

Условные операторы.
Оператор вида if … then … Называют условным оператором. общий вид таков:
if условие then действие

Выражение «условие» является логическим. Если выражение «условие» принимает значение истина, то выполняется оператор «действие». В противном случае будет выполняться оператор, следующий за оператором «действие».

По формальным правилам языка, в условном операторе «действие» допускается применение лишь одного оператора. Однако на практике обычно нужно больше операторов. Приходиться применять составной оператор.
Операторы if…then можно вкладывать друг в друга. Вот так:

if условие1 then 
 if условие2 then
  действие;

Пример оператора:

if x > 10 then x := 0;

Существует еще и полная версия оператора, которая имеет вид:

if условие then действие1 else действие2;

Выполняется следующим образом: Если «условие» равно истина, то выполняется «действие1», иначе выполняется «действие2». Следует отметить, что между оператором «действие1» и else точка с запятой не ставиться. Это приведет ошибке компиляции программы.
Выражение «условие» также может быть составным. В этом случае каждая единица составного условия пишется в круглых скобках () и отделяется друг от друга булевыми операторами. Например

if (x>0) and (x < 10) then
 x := x+1;

Читаться так: Если икс больше нуля И икс меньше десяти, то …

Или такой пример:

if (x<10) or (x > 20) then
 x := 15;

Читаться так: Если икс меньше десяти, ИЛИ икс больше двадцати, то …

Еще одна разновидность условного оператора case…of…end.
Это оператор выбора. Он имеет следующий вид:

case выражение of 
 значение_1: действие_1;
 значение_2: действие_2;
 …
 значение_Х: действие_Х;
 else: действие_Else;
end;

«выражение», возможно, принимает одно из «значений», находящихся слева от двоеточий, затем выполняется соответствующее действие. Ветвь else, отвечающая всем не перечисленным «значениям» и не обязательна. В «выражении» оператора case допустимо применять переменные целого типа. В нутрии оператора case … end допустимо применение составных операторов. А теперь более конкретный пример. Допустим переменная x принимает значение от 1 до 4 тогда:

case x of
 1: begin x:=2; break; end;
 2: begin x:=3; break; end;
 3: begin x:=4; break; end;
 4: x:= 1;
end;

Здесь используются как простые операторы, так и составные. Ветвь else вовсе не используется.

  • +3
  • 20 марта 2011, 20:11
  • Rom

Комментарии (9)

RSS свернуть / развернуть
Здесь обязательное условие z1<z2.
Строго говоря, не обязательное. Просто при z1=z2 цикл выполнится один раз, а при z1>z2 — не выполнится ни разу. С константными z1 и z2 смысла в этом нету, а вот если хотя бы одно из них переменная…
Стоит также указать, что начальное и конечное условия цикла for вычисляются один раз, перед циклом.
Следует отметить, что между оператором «действие1» и else точка с запятой не ставиться. Это приведет к логической ошибке выполнения программы.
На самом деле ошибка синтаксическая. Компилятор возмущенно заорет ";" is not allowed before «else». А вот в С все гораздо смешнее.
В нутрии оператора case … end допустимо применение составных операторов, а так же операторов break и continue.
Нифига подобного. Их можно вызывать только внутри циклов, к которым case не относится. Если case находится внутри цикла — тогда можно, но влиять они разумеется будут именно на цикл, в котором case крутится.

Еще забавная особенность микропаскаля — в нем можно использовать переменные в качестве меток case'а.
0
  • avatar
  • Vga
  • 20 марта 2011, 21:03
Начальное условие, действительно, вычисляется один раз перед циклом, но конечное условие вычисляется перед каждым проходом цикла.
0
В паскале — оба вычисляются только раз. В Delphi — тоже. Насчет mP не знаю, надо проверять. Но вариант с вычислением каждый цикл — накладен, собственно, основной профит с for — это именно оптимизация за счет однократного вычисления границ (и кстати, если компилятор считает что это не повлияет — например, если не использовать счетчик внутри цикла — то цикл будет идти вниз до нуля, даже если использовано to, а не downto.
0
Проверил документацию. Вычисляет каждый раз. Черт. Значит типичное для дельфи for i:=0 to List.Count-1 применять нельзя.
0
Да, хорошая возможность «выстрелить себе в ногу», изменяя конечное условие в теле цикла. Кстати, в C тоже вычисляется каждый раз.
0
Ну в С и цикла со счетчиком нету. Тамошний for — универсальный цикл.
0
Здесь обязательное условие z1<z2.
Строго говоря, не обязательное. Просто при z1=z2 цикл выполнится один раз, а при z1>z2 — не выполнится ни разу. С константными z1 и z2 смысла в этом нету, а вот если хотя бы одно из них переменная…
Стоит также указать, что начальное и конечное условия цикла for вычисляются один раз, перед циклом.
Да согласен. Не правильно выразил свою мысль.

Следует отметить, что между оператором «действие1» и else точка с запятой не ставиться. Это приведет к логической ошибке выполнения программы.
На самом деле ошибка синтаксическая. Компилятор возмущенно заорет ";" is not allowed before «else». А вот в С все гораздо смешнее.

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

В нутрии оператора case … end допустимо применение составных операторов, а так же операторов break и continue.
Нифига подобного. Их можно вызывать только внутри циклов, к которым case не относится. Если case находится внутри цикла — тогда можно, но влиять они разумеется будут именно на цикл, в котором case крутится.

Да, верно. Погорячился я не много.
0
Что — то с памятью моей стало. Точно помню, где то, возможно в турбо Паскале ни какой ошибки не выскакивало, а в Микро Паскале да синтаксическая ошибка.
Маловероятно. Дельфи тоже ругается, а он до сих пор обратно совместим с турбопаскалем. Да и Вирт не тот человек, чтобы оставлять в своем языке такие сюрпризы. Это же не С. Напротив, он разрабатывает языки так, чтобы минимизировать ошибки. Оберон, например, не позволяет даже вызывать функцию как процедуру (т.е. игнорировать возвращаемое значение).
0
В принципе, ошибка могла не выскакивать в микропаскале. Он довольно косенький и старые версии могли обрабатывать эту конструкцию неправильно. Обновление версии с 2009 года на 2011 разом полечило большую часть непонятных багов в моей программе :)
0
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.