
- •Алфавит и лексемы
- •Константы
- •Имена, ключевые слова и знаки операций
- •Ввод с клавиатуры
- •Вывод на экран
- •Условный оператор if
- •Оператор варианта case
- •Цикл с предусловием while
- •Цикл с постусловием repeat
- •Цикл с параметром for
- •Рекомендации по использованию циклов
- •Оператор перехода goto
- •Перечисляемый тип данных
- •Интервальный тип данных
- •Двумерные массивы
- •Операции
- •Процедуры и функции для работы со строками
- •Множества
- •Операции над множествами
- •Подпрограммы для работы со всеми типами файлов Процедуры
- •Функции
- •Текстовые файлы
- •Бестиповые файлы
- •Компонентные файлы
- •Прямой доступ
- •Процедуры
- •Функции
- •Глобальные и локальные переменные
- •Параметры-значения
- •Параметры-переменные
- •Параметры-константы
- •Нетипизированные параметры
- •Открытые массивы и строки
- •Рекурсивные подпрограммы
- •Описание модулей
- •Использование модулей
- •Модуль System
- •Модуль Crt
- •Работа с экраном
- •Работа с клавиатурой
- •Модули Dos и WinDos
- •Модуль Graph
- •Структура графической программы
- •Модуль Strings
Цикл с параметром for
Этот оператор применяется, если требуется выполнить тело цикла заранее заданное количество раз. Параметр порядкового типа на каждом проходе цикла автоматически либо увеличивается, либо уменьшается на единицу:
for параметр := выражение_1 to выражение_2 do оператор
for параметр := выражение_2 downto выражение_1 do оператор
Выражения должны быть того же типа, что и переменная цикла, оператор - простым или составным.
Пример #3. |
|
|
Программа выводит на экран в столбик числа от 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.
|
ВНИМАНИЕ Если в теле цикла необходимо выполнить более одного оператора, необходимо заключить их в блок с помощью begin и end.
Выражения, определяющие начальное и конечное значения счетчика, вычисляются один раз до входа в цикл. Цикл for реализован в Паскале как цикл с предусловием, то есть его можно представить в виде эквивалентного оператора while. После нормального завершения цикла значение счетчика не определено.
Рекомендации по использованию циклов
Часто встречающимися ошибками при программировании циклов являются использование в теле цикла переменных, которым не были присвоены начальные значения, а также неверная запись условия продолжения цикла. Нужно помнить и о том, что в операторе while истинным должно являться условие повторения вычислений, а в операторе repeat - условие их окончания.
Чтобы избежать ошибок, рекомендуется:
не забывать о том, что если в теле циклов while и for требуется выполнить более одного оператора, нужно заключать их в блок;
убедиться, что всем переменным, встречающимся в правой части операторов присваивания в теле цикла, до этого присвоены значения, а также возможно ли выполнение других операторов;
проверить, изменяется ли в теле цикла хотя бы одна переменная, входящая в условие продолжения цикла;
предусматривать аварийный выход из итеративного цикла по достижению некоторого предельно допустимого количества итераций.
Лекция 7
Процедуры передачи управления
В Паскале есть несколько стандартных процедур, изменяющих последовательность выполнения операторов:
break - завершает выполнение цикла, внутри которого записана;
continue - выполняет переход к следующей итерации цикла;
exit - выходит из программы или подпрограммы, внутри которой записана;
halt - немедленно завершает выполнение программы.
Кроме того, для передачи управления используется оператор перехода goto.
Рассмотрим пример применения процедур передачи управления.
Пример #1. |
|||
|
Программа вычисления значения функции Сh x(гиперболический косинус) с помощью бесконечного ряда Тейлора с точностью по формуле:
|
||
Этот ряд сходится при любых значениях аргумента. При увеличении номера n модуль члена ряда Cn стремится к нулю. При некотором n неравенство |Cn| >= eps перестает выполняться, и вычисления прекращаются. Общий алгоритм прост: задать начальное значение суммы ряда, а затем многократно вычислять очередной член ряда и добавлять его к ранее найденной сумме, пока абсолютная величина очередного члена ряда не станет меньше заданной точности. До выполнения программы предсказать, сколько членов ряда потребуется просуммировать, невозможно. В цикле такого рода есть опасность, что он никогда не завершится - как из-за возможных ошибок в вычислениях, так и из-за ограниченной области сходимости ряда. Кроме того, в данном случае при увеличении абсолютной величины аргумента значения функции сильно возрастают и могут переполнить разрядную сетку. Поэтому для надежности программы необходимо предусмотреть аварийный выход из цикла с печатью предупреждающего сообщения по достижении некоторого максимально допустимого количества итераций. Прямое вычисление члена ряда по приведенной выше общей формуле, когда х возводится в степень, вычисляется факториал, а затем числитель делится на знаменатель, имеет два недостатка, которые делают этот способ непригодным. Первый недостаток - большая погрешность вычислений. Второй недостаток связан с эффективностью вычислений: как легко заметить, при вычислении очередного члена ряда нам уже известен предыдущий, поэтому вычислять каждый член ряда "от печки" нерационально. Для уменьшения количества выполняемых действий следует воспользоваться рекуррентной формулой получения последующего члена ряда через предыдущий Cn+1 = Cn * T, где T - некоторый множитель. Подставив в эту формулу Cn и Cn+1, получим выражение для вычисления Т:
Ниже приведен текст программы с комментариями. program ch; const MaxIter = 500; { максимальное количество итераций } var x, eps : double; { аргумент и точность } c, y : double; { член ряда и его сумма } n : integer; { номер члена ряда } done : boolean; { признак достижения точности } begin writeln('Введите аргумент и точность:'); readln(x, eps); done := true; c := 1; y := c; { первый член ряда и нач. значение суммы } n := 0; while abs(c) > eps do begin c := c * sqr(x) /(2 * n + 1)/(2 * n + 2); { очередной член ряда } 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.
|