- •Принципы модульного программирования
- •1. Процедуры
- •1.1.Пример программы с процедурой
- •1.2. Расположение процедур в программе
- •2. Функции
- •2.1. Пример программы с функцией
- •3. Внешние процедуры и функции
- •3.1. Модули пользователей
- •Сложные типы данных, применяемые в Паскале
- •1. Множества
- •1.1. Примеры программ с использованием множеств
- •2. Записи
- •2.1.Пример программы обработки записей
- •Файлы и наборы данных
- •1.Текстовые файлы
- •1.1. Создание текстового файла
- •1.2. Работа с существующим текстовым файлом
- •2. Последовательные файлы
- •2.1.Примеры программ с файлами, содержащими данные простого типа
- •2.2.Работа с файлами, содержащими данные сложного типа
- •2.2.1. Создание последовательного файла
- •2.2.2. Работа с файлом filan
- •3. Файлы с произвольным (прямым) доступом
- •3.1. Создание файла с прямым доступом
- •3.2. Работа с файлом: поиск и коррекция записей
- •3.3. Упорядочение записей в файле
- •3.4. Удаление записей из файла
- •3.5. Вставка записей в файл
- •Динамическое распределение памяти. Указатели и списки
- •1. Использование указателей. Списки
- •2. Очереди
- •2.1. Очередь типа Lifo
- •2.2. Очередь Fifo
- •Стандартные модули Турбо Паскаля
- •Модуль Crt
- •Модуль dos
- •Модуль Graph
- •1. Инициирование графического режима
- •2. Вывод текста (надписей) в графическом режиме
- •3. Вывод точек на экран
- •4. Построение графических изображений
- •5. Запоминание и вывод изображений
- •Библиографический список
- •Содержание
- •Процедуры 3
- •2. Функции 12
3.5. Вставка записей в файл
Эта операция предполагает увеличение размеров набора данных и передвижение признака end of file. Она осуществляется так же, как слияние файлов – с использованием временного набора. Последовательность действий такая:
1. Ввод номера (Num) вставляемой записи;
2. Перепись из исходного файла f начальных записей (от 0 до номера, меньшего Num) во временный файл;
3. Передача вставляемой записи (с номером Num) во временный файл.
4. Пока нет конца файла f переписывать из него во временый файл оставшиеся записи ("хвост").
Перепись временного файла на место исходного файла f.
Динамическое распределение памяти. Указатели и списки
Все рассмотренные ранее типы данных - статические. Компилятор выделяет для них память до выполнения программы, после анализа ее текста. При этом достаточно проверить раздел Var текста программы и выделить для переменных соответствующие объемы памяти, которые помечаются именами переменных.
Существуют задачи, в которых заранее не известно количество объектов, обрабатываемых программой (слабо заполненные таблицы, строки, слова, очереди, списки и т.д.). Для таких задач целесообразно выделять память объектам в процессе выполнения программы, т.е. динамически.
Динамические переменные - это переменные, которым выделяется память и присваиваются значения непосредственно при выполнении программы.
Для динамического размещения необходимо задавать адреса данных особым собразом, т.к. в разделе Var нельзя описать динамические переменные непосредственно. Это делается с помощью указателей (ссылок, Pointer).
Указатель описывается обычно в разделе Type в виде:
Type
имя = ^ тип_объекта;
Пример.
Type
p = ^ Char;
q = ^ Integer;
Здесь p и q – указатели для символа и целого числа соотвественно. Используя эти типы, можно описать, например, следующие переменные:
Var
pt,r: q; { Ссылки на динамические данные типа Integer}.
Данные типа "указатель" (адреса) нельзя вывести на экран или печать с помощью Write. Например, не допустим оператор Write(pt);
Данное, связанное с указателем, имеет имя вида:
имя_указателя^
Пример.
pt^, r^ – данные типа Integer, адреса которых определяются указателями pt и r.
Для них допустимы операторы Read и Write.
Пример.
Read (pt^ );
Существует особое значение указателя: Nil ("ничего"). Это значение не указывает ни на какую переменную.
При работе с динамическими переменными используются специальные процедуры:
1) New (указатель); выделяет в памяти место для переменной, адрес которой задается указателем. При этом значение переменной не задается.
Пример.
New (pt); – выделено место для одной переменной целого типа.
Для задания значения динамической переменной используются пара операторов вида:
New (ук);
Read (ук^ );
Их работу иллюстрируют рисунками вида рис.7.
Рис.7. Запись в память значения динамической переменной,
которое вводится с клавиатуры.
Другой способ задания значения динамической переменной - с помощью оператора присваивания. Он иллюстрируется рис.8.
New (ук);
ук^ := выражение;
Рис.8. Запись в память значения динамической переменной,
которое вычисляется в операторе присваивания
2) Dispose (указатель): – освобождает место в памяти, занятое переменной, адрес которой задан указателем.
Пример.
Dispose (r);
Процедура выполняется, если указатель определен (r <> Nil).
Освобождение места в памяти с помощью процедуры Dispose выполняется, если переменные обработаны и нужно использовать это место для размещения других данных. Такой "мусор" периодически удаляют, чтобы он не мешал (не занимал напрасно динамическую память).
Program Pointers;
Type
point =^ integer;
Var
i,j:Integer;
p,q:point;
Begin
New(p); { Выделение памяти для р }
New(q); { Выделение памяти для q }
i:=5; { Запись 5 на место i }
p^:=7; { Запись 7 на место p }
q^:=p^ -i; { Запись 7-5=2 на место, }
{ адрес которого хранится в q }
q:=p; { Ссылки q и p стали одинаковыми }
{ Объект, адрес которого хранился в q, потерян,
{ стал "мусором" }
End.
При работе с указателями и списками необходимо следить, чтобы связи не терялись и не оставалась "куча мусора". В последнем случае вместо выполнения оператора: q:=p; надо было сделать так:
Dispose(q);
q:=p;
