Опубликован: 03.09.2010 | Уровень: для всех | Доступ: свободно
Лекция 2:

Управляющие операторы языка

< Лекция 1 || Лекция 2: 123 || Лекция 3 >
Цикл с параметром for

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

for параметр := выражение_1 to выражение_2 do оператор
for параметр := выражение_2 downto выражение_1 do оператор

Выражения должны быть совместимы по присваиванию с переменной цикла (о правилах совместимости мы поговорим в конце третьей лекции), оператор — простым или составным. Циклы с параметром обычно применяются при работе с массивами.

Пример 1. Программа выводит на экран числа от 10 до 1 и подсчитывает их сумму:

var i, sum : integer;
begin
    sum := 0;
    for i := 10 downto 1 do begin 
        writeln(i); inc(sum, i) 
    end;
    writeln('Сумма чисел: ', sum);
end.

В этом цикле переменная i автоматически уменьшается на 1.

Пример 2. Программа выводит на экран символы от 'a' до 'z' :

var ch : char;
begin
    for ch := 'a' to 'z' do write(ch:2)
end.

Здесь счетчик цикла ch символьного типа поочередно принимает значение каждого символа от 'a' до 'z'.

ВНИМАНИЕ Если в теле цикла необходимо выполнить более одного оператора, необходимо заключить их в блок с помощью ключевых слов begin и end.

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

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

for i := 1 to 10 do begin inc(i,3); ... end;                           { плохо! }

Это может привести к зацикливанию программы.

Рекомендации по использованию циклов

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

Чтобы избежать ошибок, рекомендуется:

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

Процедуры передачи управления

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

  • break — завершает выполнение цикла, внутри которого записана;
  • continue — выполняет переход к следующей итерации цикла;
  • exit — выполняет выход из программы или подпрограммы, внутри которой записана;
  • halt — немедленно завершает выполнение программы.

Кроме того, для передачи управления используется оператор перехода goto.

Рассмотрим пример применения процедуры передачи управления.

Пример. Программа вычисления значения функции sin x (синус) с помощью бесконечного ряда Тейлора с точностью \varepsilon по формуле:

y = x - x3/3! + x5/5! - x7/7! +…

Этот ряд сходится при любых значениях аргумента. Точность достигается при |Rn| < ε, где Rn —остаточный член ряда, который для данного ряда можно заменить величиной Cn очередного члена ряда, прибавляемого к сумме.

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

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

Прямое вычисление члена ряда по приведенной выше общей формуле, когда х возводится в степень, вычисляется факториал, а затем числитель делится на знаменатель, имеет два недостатка, которые делают этот способ непригодным: большая погрешность вычислений и их низкая эффективность. При вычислении очередного члена ряда предыдущий уже известен, поэтому следует воспользоваться рекуррентной формулой получения последующего члена ряда через предыдущий Cn+1 = Cn *T, где T — некоторый множитель. Подставив в эту формулу Cn и Cn+1 , получим выражение для вычисления Т:

T=\frac{C_{n+1}}{C{n}}=\frac{x^2}{(2n+2)(2n+3)}

Текст программы с комментариями приведен в ( пример 2.4).

program ch;
const MaxIter = 500;              { максимальное количество итераций }
var x, eps : double;              { аргумент и точность }
    c, y   : double;              { член ряда и его сумма }
    n      : integer;             { номер члена ряда }
    done   : boolean;             { признак достижения точности }
begin
    writeln('Введите аргумент и точность:');
    readln(x, eps);
    done := true;
    c := x; y := c;                { первый член ряда и нач. значение суммы }
    n := 0;
    while abs(c) > eps do begin
        c :=- c * sqr(x) /(2 * n + 2)/(2 * n + 3);     { очередной член ряда } 
        y := y + c;                         { добавление члена ряда к сумме }
        inc(n);
        if n > MaxIter then begin                { аварийный выход из цикла }
            writeln('Ряд расходится!');
            done := false; break
        end
    end;
    if done then
        writeln('Для аргумента ', x, ' значение функции: ', y, #13#10,
                'вычислено с точностью', eps, ' за ',  n, ' итераций');
    readln;
end.
Листинг 2.4. Вычисление суммы бесконечного ряда

Оператор перехода goto

Этот оператор имеет простой синтаксис: в точке программы, из которой требуется организовать переход, после слова goto через пробел записывается имя метки, например goto 1 или goto error. При программировании на Паскале необходимость в применении оператора перехода возникает, как правило, в двух случаях:

  1. принудительный выход вниз по тексту программы из нескольких вложенных циклов или операторов выбора;
  2. переход из нескольких мест программы в одно (например, если перед выходом из программы необходимо всегда выполнять какие-либо действия).

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

< Лекция 1 || Лекция 2: 123 || Лекция 3 >
София Шишова
София Шишова

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

Юрий Макушин
Юрий Макушин
Россия, Москва, РЭА им. Плеханова, 2004