- •1. Структура (состав) языка
- •2. Алфавит
- •3. Лексическая структура языка
- •4. Структура программной единицы
- •5. Стиль записи программ на языке Паскаль
- •6. Типы данных в Паскале
- •6.3 Классификация типов данных в Турбо Паскале
- •6.4 Порядковые типы
- •6.4.2 Булевский (логический) тип
- •Repeat тело_цикла until (логическое_выражение);
- •6.4.3 Целые типы Выделяют целые типы ------------- со знаком – shortint, integer, longint)
- •1 Группа функций:
- •2 Группа функций:
- •3 Группа функций:
- •6.4.4 Перечисляемый тип.
- •6.4.6 Символьный тип
- •6.5 Вещественные типы.
- •7. Выражения в языке Паскаль.
- •10. Вычисление по формулам.
- •10.1 Оператор присваивания .
- •10.2 Характер использования переменных в математике и в программах.
- •10.3 Бесконечности
- •10.4 Нестандартные операции
- •6.6 Строки
- •1) Операции присваивания и сравнения.
- •3) Заполнение строки одним символом
- •4) Стандартные функции и процедуры для работы со строками:
- •5) Подпрограммы преобразования из строкового представления в числовое и наоборот:
- •8. Совместимость и преобразование типов.
- •Совместимость типов
- •8.2 Тип результата арифметических выражений.
- •8.3 Преобразование (приведение) типов и значений.
- •8.3.1 Явное преобразование (приведение) типов.
- •8.3.2 Неявное преобразование или приведение типов.
- •9. Простейший ввод-вывод на Паскале
- •Стандартные файлы Input и Output
- •9.2 Процедуры ввода информации (с клавиатуры.
- •9.3 Процедуры вывода в тр.
- •10. Вычисление по формулам (продолжение)
- •10.6. Уточнение многоместных (n - арных) операций
- •11. Средства языка Паскаль для циклов с известным числом повторений.
- •12. Табулирование функций
- •13. Разветвляющиеся алгоритмы
- •13.1 Таблица ситуаций и команда выбора.
- •13.2 Средства языка Паскаль для программирования разветствляющихся алгоритмов
- •13.4 Описание ситуаций
- •13.5 Запись команды выбора (case) (уточнение таблицы ситуаций) с помощью набора команд ветвления
- •13.6 Запись последовательных команд ветвления в случае, когда соседние зависимые ситуации имеют общие признаки.
- •13.6.1 Восходящий подход
- •13.6.2 Нисходящий подход
- •14. Циклы с неизвестным числом повторений
- •15. Структурированные типы данных. Массивы
- •15.1 Классификация (особенности) структурированных типов данных
- •15. 2. Определение массива
- •15.3 Объявление массива на Турбо Паскале
- •15.4 Хранение элементов массива. Доступ к элементам и частям массива
- •15.5 Уточнение команд обработки массива
- •16. Правила разработки цикла
- •15. 6 Действия над массивами
- •17. Множества.
- •17.1 Множества в Паскале и в математике. Сходства и различия между ними.
- •17.2 Объявление множества на Паскале
- •17.3 Присваивание значений множествам. Конструктор множества
- •17.4 Операции над множествами.
- •17.5 Сравнение множеств.
- •17.6 Применение множеств.
- •18. Вспомогательные алгоритмы (подпрограммы).
- •18.1 Три способа записи повторяющихся команд
- •18.2 Понятие блока
- •18.3 Объекты подпрограммы (то, над чем выполняются действия).
- •18.4 Свойства локальных и глобальных объектов
- •Свойства глобальных объектов:
- •18.5 Выделение памяти под локальные и глобальные переменные
- •18.6 Передача параметров в подпрограммы.
- •Фактические параметры
- •18.7 Подпрограммы, возвращающие значение (функции)
- •18.8 Особенности использования процедур и функций в Турбо Паскале
- •18.9. Побочный эффект (side effect)
- •18.10 Опережающее определение процедур и функций.
- •18.11 Рекурсия и итерация.
- •18.12 Процедуры и функции как параметры.
- •18.13 Директивы подпрограмм
- •Директива forward
- •Директивы far и near
- •Директива external
- •Директива assembler
- •Директива inline
- •Директива interrupt
- •Отладка и тестирование программ, содержащих подпрограммы
- •18.14.1 Нисходящее тестирование и подпрограммы-заглушки
- •18.14.2 Восходящее тестирование и программы-тестеры
- •18.14.3 Рекомендации по отладке программ, содержащих подпрограммы
- •18.14.4 Использование отладчика для трассировки процедур
- •18.14.5 Область действия идентификаторов и переменные в окне Watch
- •18.15. Получение доступа а параметрам командной строки, запуск внешних программ.
- •19. Записи.
- •19.1 Понятие записи. Объявление записи в программе.
- •19.2 Доступ к полям записи.
- •19.3 Оператор with
- •19.4 Действия над записями
- •19.5 Записи с вариантами
- •Замечание1:Порядок частей – именно такой, как показано: фиксированная часть всегда первая (или единственная)
- •19.6 Типизированные константы - записи
- •20. Модули (Unit)
- •20.1 Что такое модуль?
- •20.2 Зачем нужны модули и какие есть средства, аналогтчные (в какой-то мере) модулям
- •Интерфейсная секция
- •Секция реализации
- •Секция инициализации
- •Подключение других модулей к данному (модулю)
- •20.4 Ссылки на описания модуля
- •Пример создания модуля
- •Использование модулей. Режимы Compile, Build и Make при компиляции модулей
- •Косвенные и перекрестные ссылки на модули
- •Пример модуля (стек)
- •Модули и большие программы
14. Циклы с неизвестным числом повторений
В тех циклах, которые мы рассматривали до этого, имелся т.н. параметр цикла, который выполнял следующие функции:
С его помощью задавалось нужное количество повторений тела цикла.
Выполнение цикла начиналось с нужной компоненты.
С его помощью выполнялся переход к нужным данным (следующей компоненте) на очередном повторении цикла.
В циклах с неизвестным числом повторений параметр цикла отсутствует. Для этих циклов необходимо "вручную" выполнить следующее:
Необходимо позаботиться, чтобы действия начались с нужной компоненты:
с нужного слагаемого при нахождении суммы;
с нужного элемента массива, при обработке массива.
Надо позаботиться, чтобы на следующем выполнении (повторении) тела цикла использовались новые данные (следующая компонента).
Надо позаботиться, чтобы цикл выполнялся нужное число раз.
Существует две разновидности циклов с неизвестным числом повторений на псевдокоде и Паскале:
Паскаль: while ситуация1 do
оператор |
Цикл с предусловием. Он может ни разу не выполниться, если ситуация1 не произошла. Эту ситуацию называют ситуацией продолжения.
повторить операторы ; пока не ситуация2; Паскаль: repeat операторы ; until ситуация2;
|
Цикл с постусловием. Он выполняется
всегда хотя бы 1 раз. Цикл с постусловием
будет выполняться до тех пор, пока
ситуация2 не наступит. Эту ситуацию
называют ситуацией завершения.
логическая переменная или лог. выражение
Тело цикла для цикла с предусловием может состоять только из одного оператора. Для цикла с постусловием тело может состоять из нескольких операторов.
В общем случае структура цикла с неизвестным числом повторений имеет следующий вид:
{подготовка цикла} Установить нач значение результата Встать на нужный (1-й) компонент нач пока продолжать повтор повторение
выполнить очередную итерацию кон перейти к следующей компоненте кц тело цикла
|
Цикл с постусловием: {подготовка цикла} Установить нач. значение результата Встать на нужный (1-й) компонент повторить выполнить очередную итерацию перейти к следующей компоненте
|
С помощью команды ветвления цикл с неизвестным числом повторений можно изобразить следующим образом:
< подготовка цикла> цикл: если продолжить то нц тело цикла идти к цикл кц всё |
цикл с постусловием: < подготовка цикла> цикл: тело цикла если закончить то идти к финиш иначе идти к цикл все финиш:
|
|
|
Общей чертой этих двух циклов является наличие проверки, по результатом которых делается вывод о необходимости завершения или продолжения цикла. Поэтому в обоих этих циклах в теле цикла должно содержаться действие, которое влияет на результат этой проверки. Либо в потоке обрабатываемых входных данных должно встретиться значение, завершающее цикл. Если это правило нарушить, то цикл или может ни разу не выполниться, или может выполняться бесконечно.
Циклы, которые не будут выполняться: Примеры простых бесконечных пустых циклов:
While (false) do; - ни разу while true do
Repeat while true; - только один раз. repeat until false;
Рассмотрим простые правильные примеры (шаблоны) использования циклов с неизвестным числом повторений:
1. Цикл, управляемый счетчиком (аналог цикла for, но с произвольным шагом счетчика)
{подготовка цикла}
Счетчик:=0; // инициализация счетчика
while
Счетчик <= Конечное_значение do
begin
... проверка счетчика
<Использование текущего значения счетчика>
Счетчик := Счетчик + Шаг; //модификация счетчика (увеличение или уменьшение)
end;
2. цикл, управляемый т.н. «сигнальной меткой»
Используется при обработке потока входных данных, количество которых заранее неизвестно (такие потоки входных данных называются последовательностями).
Последовательность имеет следующие черты:
- число элементов неизвестно;
- последним элементов должен быть признак конца последовательности;
- признак конца последовательности не должен совпадать ни с одним из значащих элементов последовательности;
- нельзя напрямую обратиться к нужному элементу (по имени, по номеру);
- не обязательно хранить в памяти всю последовательность (достаточно хранить только один - текущий для его обработки).
Сигнальная метка (признак конца последовательности) – уникальное значение во входном потоке, которое обозначает конец входного потока, но само это значение не является частью потока - не может использоваться (обрабатываться) как данные. Например, если вводится и обрабатывается поток целых положительных чисел, то в качестве такой сигнальной метки можно принять число = -1. Начинать обработку любой последовательности надо с выбора значения «сигнальной метки» (исходя из типа элементов последовательности).
{подготовка цикла} исходя из типа элементов последовательности
Сигнальная_метка
:= Выбранное_значение
Считать текущее значение из входного потока и присвоить его входной_переменной
while входная_переменная ≠ Сигнальная_метка do
begin
Обработать текущее значение входной_переменной
Считать текущее значение из входного потока и присвоить его входной_переменной
end;
3. цикл, управляемый событием (флагом)
Чтобы не было
зацикливания, следует делать следующее
(при отладке): -
считать число шагов (и прерывать цикл,
когда число шагов превышает некое
максимальное, заранее заданное); -
считать время (и прерывать цикл, когда
время превышает некое максимальное,
заранее заданное).
{подготовка
цикла} или Флаг = false
флаг
:= False; // инициализация
флага
while (Not флаг) do
begin непрерывно гоняя цикл
...
<пусто> если ожидаем наступление внешнего события
или по отношению к программе (процессу)
<выполнение действий, влияющих на флаг>
end;
Рассмотрим более сложный пример:
На интервале [x1, x2] находится корень уравнения. надо найти этот корень.
NB: Пусть нам известно, что на интервале [x1,x2] существует лишь один корень. Иначе мы найдем лишь один корень из нескольких имеющихся |
x1=A x0 x2=B
f(x0) = 0
Первую формулировку решения можно сразу записать следующим образом:
вычислить корень
При уточнении решения этой задачи возможны 2 ситуации: корень существует и корень не существует.
-
Ситуация
Действие
корень существует
найти корень
корень не существует
сообщить об ошибке и закончить
Искать
корень будем приближенным методом,
поэтому чтобы найти корень, придется
последовательно решить следующие
подзадачи:
найти 1-е приближение
найти 2-е приближение можно свернуть в цикл (число повт. неизвестно заранее)
найти 3-е приближение
...
В общем случае имеем большое количество однотипных действий. Такой линейный алгоритм желательно сворачивать в цикл. Число повторений заранее неизвестно. В данном методе для определения момента остановки задается достигнутая (на текущем шаге) точность поиска корня.
Структура цикла будет иметь вид:
{подготовка цикла} // подготовка нужна, так как в теле цикла используется рекурсия
установить начальное значение корня //найти 0-е приближение;
while
продолжать do текущая
левая граница
begin текущая правая граница
найти очередное приближение корня |
х1 - х2| >
end заданная точность
Ситуацию "продолжать" можно описать следующим образом: | х1 - х2| > . Для поиска корня будем использовать метод половинного деления. Суть этого метода поиска корня (метод деления пополам) заключается в следующем: на каждой итерации интервал определения корня делится пополам и определяется середина интервала, т.е. точка x = (х1+х2)/2 . Далее определяется, какую половину интервала выбрать в качестве нового интервала определения корня. На следующей итерации выбранный интервал вновь делиться пополам. При каждом делении интервала текущие значения х1 и х2 как бы приближаются друг к другу. При бесконечном числе повторений х1 и х2 сольются в одну точку (с точностью до ).
Команду "найти очередное приближение" можно разбить на две:
1) выбрать нужную половину интервала (изменить левую или правую границу)
2) вычислить новое значение корня.
Команду "установить начальные значения" можно уточнить таким образом :
Вычислить х:= (x1+x2)/2.
Команда "вычислить новое значение корня" уточняется таким же образом:
вычислить х:= (x1+x2)/2.
Чтобы уточнить задачу «выбрать нужную половину интервала» надо следовать следующим правилам корректировки: в качестве нового интервала выбирается та половина начального интервала., на границе которой функция имеет разные знаки (если функция имеет разные знаки на границах, то это значит, что она через "0" перейдет). В данном случае в качестве нового интервала примем правую половину интервала (функция на границах правой половины имеет разные знаки).
Возможны две ситуации при уточнении команды "скорректировать границы":
Ситуация |
Действие |
Знаки на интервале [х1; (х1+х2)/2] (левая половина) разные |
Принять х2 := (х1+х2)/2 |
Знаки на интервале [(х1+х2)/2; х2] (правая половина) разные |
Принять х1 := (х1+х2)/2 |
Эти ситуации взаимоисключающие, поэтому анализировать (проверять) будем только одну из них.
В итоге уточнения цикла while получим:
Проверка:
корень существует? ситуация «продолжать»
{подготовка цикла}
{установить начальное значение корня}
х:= (х1+х2)/2;
while
(abs(x1 + x2)> eps) do
begin
{определение новой половины интервала}
if (f(x1) * f((x1 - x2)/2) < 0)
then
{корень в левой половине}
x2:= (x1 + x2)/2
else
{корень в правой половине}
x1:= (x1 + x2)/2;
{определение текущего значения корня на новом интервале}
x:= (x1 + x2)/2;
end;

Псевдокод:
пока
ситуация1 повторить
оператор
Псевдокод:
Цикл
с предусловием:
нц
пока
не завершить;
цикл
с предусловием: