- •Основы программирования на языке Паскаль
- •Часть 1. Основы языка Паскаль 2
- •Часть 2. Элементы профессионального программирования на Паскале 44
- •От автора
- •Часть 1. Основы языка Паскаль
- •1. Алгоритм и программа
- •1.1. Алгоритм
- •1.2. Свойства алгоритма
- •1.3. Формы записи алгоритма
- •1.4. Программа и программное обеспечение
- •1.5. Этапы разработки программы
- •2. Данные в языке Паскаль
- •2.1 Константы
- •2.2 Переменные и типы переменных
- •3. Арифметические выражения
- •4. Линейный вычислительный процесс
- •4.1 Оператор присваивания
- •4.2 Оператор ввода
- •4.3 Оператор вывода
- •4.4 Управление выводом данных
- •4.5 Вывод на печать
- •5. Структура простой программы на Паскале
- •6. Компилятор и оболочка Turbo Pascal
- •7. Разветвляющийся вычислительный процесс и условный оператор
- •7.4. Короткий условный оператор
- •If логическое_выражение then оператор1;
- •7.5. Полный условный оператор
- •If логическое_выражение then оператор1
- •7.7. Вложенные условные операторы
- •7.9. Примеры программ с условным оператором
- •8. Директивы компилятора и обработка ошибок ввода
- •9. Оператор цикла. Циклы с предусловием и постусловием
- •10. Цикл со счетчиком и досрочное завершение циклов
- •11. Типовые алгоритмы табулирования функций, вычисления количества, суммы и произведения
- •11.1 Алгоритм табулирования
- •11.2 Алгоритм организации счетчика
- •11.3 Алгоритмы накопления суммы и произведения
- •12. Типовые алгоритмы поиска максимума и минимума
- •13. Решение учебных задач на циклы
- •14. Одномерные массивы. Описание, ввод, вывод и обработка массивов на Паскале
- •15. Решение типовых задач на массивы
- •Часть 2. Элементы профессионального программирования на Паскале
- •16. Кратные циклы
- •16.1 Двойной цикл и типовые задачи на двойной цикл
- •16.2 Оператор безусловного перехода
- •17. Матрицы и типовые алгоритмы обработки матриц
- •18. Подпрограммы
- •18.1 Процедуры
- •18.2 Функции
- •18.3 Массивы в качестве параметров подпрограммы
- •18.4 Открытые массивы
- •19. Множества и перечислимые типы
- •20. Обработка символьных и строковых данных
- •20.1. Работа с символами
- •20.2 Работа со строками
- •21. Текстовые файлы
- •21.1 Общие операции
- •21.2 Примеры работы с файлами
- •21.3 Работа с параметрами командной строки
- •22. Записи. Бинарные файлы
- •23. Модули. Создание модулей
- •23.1. Назначение и структура модулей
- •23.2. Стандартные модули Паскаля
- •24. Модуль crt и создание простых интерфейсов
- •25. Модуль Graph и создание графики на Паскале
- •Приложение 1. Таблицы ascii-кодов символов для операционных систем dos и Windows
- •Приложение 2. Основные директивы компилятора Паскаля
- •Приложение 3. Основные сообщения об ошибках Паскаля
- •Приложение 4. Дополнительные листинги программ
- •Приложение 5. Расширенные коды клавиатуры
- •Ascii‑коды
- •Расширенные коды
- •Приложение 6. Правила хорошего кода
- •Приложение 7. Рекомендуемая литература
10. Цикл со счетчиком и досрочное завершение циклов
Прежде, чем перейти к примерам, обсудим еще ряд проблем, связанных с циклами. Как для while, так и для repeat, во-первых, нигде в явном виде не задается число шагов цикла (хотя его обычно можно вычислить), во-вторых, при использовании обоих циклов программист должен заботиться об изменении управляющей переменной. Между тем, весьма распространены задачи, где объем последовательно обрабатываемых данных известен заранее (а значит, известно и требуемое число шагов цикла), а управляющая переменная меняется с шагом, равным единице. Рассмотренный выше пример с двадцатью значениями x относится именно к таким задачам. Поэтому для обработки заранее известного объема данных с шагом по управляющей переменной, равным единице, вместо цикла while используется цикл со счетчиком (цикл for). Его общий вид следующий:
for счетчик := начальное_значение to конечное_значение do begin
{операторы тела цикла}
end;
Здесь счетчик – целочисленная переменная, начальное и конечное значения – целочисленные выражения или константы. Тело цикла образовано не менее, чем одним оператором, если этот оператор единственный, операторные скобки можно не писать. Работает цикл for следующим образом: счетчик автоматически меняется от начального значения до конечного включительно, для каждого значения счетчика выполняется тело цикла. После каждого шага цикла значение счетчика автоматически увеличивается на единицу. Если требуется, чтобы значение счетчика уменьшалось, а не увеличивалось, вместо ключевого слова to используется downto.
Подобно while, цикл for может не выполниться и ни разу – если начальное значение управляющей переменной сразу же больше конечного (при использовании to) или меньше (при использовании downto).
Запишем рассмотренный выше цикл по переменной x с помощью оператора for:
for x:=1 to 20 do begin
{операторы тела цикла}
end;
Удобства очевидны – границы изменения x заданы сразу же при входе в цикл, а выполнять шаг по x отдельным оператором не требуется. Понятны и ограничения – x должен быть описан с типом integer, а в случае изменения x с шагом, не равным единице, использовать for вместо while не удалось бы.
Вторая проблема связана с тем, что при выполнении программы довольно часто возникает необходимость завершить цикл досрочно – например, если искомое в нем значение уже найдено или возникла ошибка, из-за которой дальнейшие шаги становятся бессмысленными. Теоретически цикл можно было бы завершить, присвоив управляющей переменной значение, выходящее за пределы ее изменения:
x:=1;
while x<10 do begin
y:=ln(x);
if y>2 then x:=10; {При y>2 цикл нужно завершить}
x:=x+0.5;
end;
Однако, во избежание трудноуловимых ошибок, управляющую переменную не принято менять иначе, чем для выполнения шага цикла. Например, после оператора if y>2 then x:=10; в нашем листинге выполнение текущего шага продолжится, что чревато лишними или неправильными вычислениями. Кроме того, текст такой программы воспринимается нелегко.
Поэтому для досрочного выхода из цикла существует оператор break (от англ. "to break" - прервать), немедленно прекращающий его выполнение:
x:=1;
while x<10 do begin
y:=ln(x);
if y>2 then break; {При y>2 цикл нужно завершить}
x:=x+0.5;
end;
Break здесь передаст управление на оператор, следующий непосредственно за циклом. В отличие от предыдущего примера, здесь не будет выполняться часть тела цикла, следующая за break;.
Для немедленного продолжения цикла со следующего шага используется оператор continue (от англ. "to continue" – продолжить):
var n:integer;
begin
repeat
writeln ('Введите положительное число:');
read (n);
if n<1 then continue; {Если введено n<1, снова запросить число}
{Здесь расположены операторы обработки положительного числа}
break; {Выход из цикла обработки}
until false;
end.
В этом примере оператор continue использован для повторного перехода к вводу n, если введено n<1. Так как цикл обработки здесь – бесконечный, для выхода из него необходим break;. Кроме того, пример показывает одну из возможностей контроля правильности ввода данных. Указав директиву {$I-}, изученную в главе 8, мы могли бы защитить программу и от ввода пользователем нечисловых значений в качестве n.
В теме "Кратные циклы" второй части курса будет рассмотрен оператор goto, также способный решить проблему аварийного завершения циклов.