- •Ю.П. Чернов, о.П. Шафеева программирование для начинающих
- •1. Среда программирования turbo pascal 7.0
- •1.1. Структура меню среды
- •1.2. Правила оформления программ
- •1.3. Команды редактора тп
- •Команды удаления и вставки
- •1.4. Компиляция и исправление синтаксических ошибок
- •2. Элементы языка pascal
- •2.1. Алфавит языка
- •2.2. Константы. Идентификаторы
- •2.3. Операторы
- •2.3.1. Оператор присваивания
- •2.3.2. Оператор безусловного перехода
- •Стандартные функции
- •2.3.3. Условный оператор if
- •2.3.4. Опеpатоp варианта case
- •2.3.5. Составной и пустой операторы
- •2.3.6. Операторы цикла
- •2.4. Процедуры прерываний
- •2.5. Типизированные константы
- •2.6. Структура программы
- •2.7. Подпрограммы
- •2.7.1. Определение процедур и функций
- •2.7.2. Вложенные подпрограммы
- •2.7.3. Вызов подпрограмм
- •2.7.4. Процедуры
- •2.7.5. Функции
- •2.7.6. Передача в подпрограмму параметров-массивов и параметров-строк
- •2.7.7. Рекурсия
- •2.8. Типы в Турбо Паскале
- •2.8.1. Целые типы
- •Классификация целых типов
- •Встроенные процедуры и функции для целых типов
- •2.8.2. Логический тип
- •2.8.3. Символьный тип
- •Служебные символы
- •2.8.4. Строковый тип
- •Встроенные функции и процедуры для обработки строк
- •Процедуры преобразования
- •2.8.5. Перечислимый тип
- •2.8.6. Ограниченный тип (диапазон)
- •2.8.7. Вещественные типы
- •Вещественные типы
- •Встроенные функции
- •2.8.8. Структурированные типы данных. Массивы
- •2.8.9. Множества
- •2.8.10. Записи
- •2.9. Изменение типа выражения
- •2.10. Процедурные типы
- •2.11. Файлы
- •Общие процедуры и функции для работы с файлами
- •2.11.1. Текстовые файлы
- •2.11.2. Типизированные файлы
- •2.11.3. Нетипизированные файлы
- •2.12. Указатели и динамическая память
- •2.13. Модули
- •2.14. Библиотека Турбо Паскаля
- •2.14.1. Модуль crt
- •2.14.2. Модуль graph
- •Var driver, Mode: integer переменные драйвера и режима.
- •Управление графическим режимом
- •Управление экраном, окном, страницей
- •Управление цветом и палитрой
- •Работа с точками
- •Работа с линиями
- •Построение фигур из линий
- •Построение криволинейных фигур
- •Работа с текстом
- •Обмен с памятью
- •2.15. Динамические структуры данных
- •2.15.1. Связанные динамические данные. Списки
- •Чтобы сослаться на двунаправленный кольцевой список как на единый программный объект, используется указатель, значением которого является ссылка на заглавное звено списка.
- •2.15.2 Очередь
- •2.15.3. Стек
- •3. Практическое программирование Этапы подготовки и решения задач на компьютере
- •Порядок выполнения лабораторных работ
- •Лабораторная работа 1 Основы программирования в среде Турбо Паскаля.
- •Приоритет операций в выражении
- •Задание 1 (программа 1_1)
- •Лабораторная работа 2 Программирование разветвленных алгоритмов. Операторы передачи управления
- •Лабораторная работа 3 Программирование циклических алгоритмов с заданным числом повторений
- •Лабораторная работа 4 Программирование циклических алгоритмов с предусловием
- •Лабораторная работа 5 Программирование циклических алгоритмов с постусловием
- •Модифицировать программу 3_2 для вычисления функций f1(X) и f2 (X) с применением оператора цикла с постусловием. Выполнить ее и сравнить результаты с полученными ранее.
- •Лабораторная работа 6 Программирование алгоритмов обработки одномерных массивов
- •Задание 1
- •Лабораторная работа 7
- •Лабораторная работа 8 Программирование с использованием функций
- •Лабораторная работа 9 Программирование с использованием процедур
- •Лабораторная работа 10 Обработка символьных и строковых данных
- •Лабораторная работа 11 Файлы
- •Лабораторная работа 12 Записи
- •Лабораторная работа 13 Решение нелинейных уравнений
- •Задание (программа_13)
- •Лабораторная работа 14 Вычисление приближенного значения определенного интеграла
- •Лабораторная работа 15 Модульное программирование
- •Лабораторная работа 16 Графика
- •Библиографический список
- •Обозначения графические в схемах алгоритмов (гост 19.701-90)
- •Зарезервированные слова Turbo Pascal 7.0
- •Приложение в
- •Кодировка символов в соответствии с кодами ascii
- •Приложение г
- •Альтернативная кодировка госТа для кодов 128...255
- •Клавиши с кодами из двух частей
- •Содержание
2.12. Указатели и динамическая память
Динамическая память - оперативная память персонального компьютера, предоставляемая программе при ее работе, за вычетом сегмента данных (64 Кб), стека (16 Кбайт) и собственно тела программы. Ее применение является фактически единственной возможностью обработки данных большой размерности. По умолчанию размер динамической памяти составляет не менее 200..300 Кб (вся доступная память ПК), однако может изменяться настройкой среды Турбо Паскаля.
Для управления динамической памятью используются указатели. Указатель это переменная, которая в качестве своего значения содержит адрес байта памяти (или номер ячейки оперативной памяти, состоящий из сегмента и смещения).
Указатели делятся на типизированные и нетипизированные. Они описываются они в разделе VAR как
<имя переменной>: <тип_указателя>;
Для объявления типизированного указателя используется символ ^, который помещается перед соответствующим типом, например:
Var
p1,u: ^integer; {типизир.указатель на целое}
p2: ^real; {типизир.указатель на вещ.}
Нетипизированный помечается стандартным типом pointer, например:
Var
p: pointer; {объявляется переменная, значением которой является адрес}
Поскольку нетипизированные указатели не связаны с конкретным типом, с их помощью удобно размещать данные, тип которых меняются в процессе работы программы. Нетипизированный указатель не может быть явно выведен на экран или печать.
Вся динамическая память в Турбо Паскале рассматривается как сплошной массив байтов, который называется кучей. Физически куча размещается в старших адресах сразу за областью памяти, которую занимает тело программы.
Память в куче под любую динамически размещаемую переменную выделяется процедурой
NEW (<типизированный_указатель>;
В результате обращения к ней указатель приобретает значение, соответствующее динамическому адресу, начиная с которого можно разместить данные. Например:
BEGIN
new(p1); {выделяется 2 байта памяти, указатель смещается на 2 байта}
new(p2); {выделяется в памяти 6 байт, указатель смещается на 6 байт (тип READ)}
После того, как определен физический байт памяти, по указанному адресу можно разместить любое значение соответствующего типа, например:
p1^:=20; {в область памяти p1 помещено значение 20}
p2^:=2*Pi; {в область памяти p2 - значение 6.28}
Для адресного типа разрешены операции присваивания между указателями одного типа. Например:
new(u); {выделяется 2 байта памяти под u}
u:=p1; {запрещены присваивания u:=p2 , p2:=u}
Для нетипизированных указателей же можно записать: p:=p1; и p2:=p;
Указатели можно сравнивать на равенство и неравенство.
В ТП можно передавать значения только между указателями, связанными с одним и тем же типом данных, например:
u^ := sqr(p1^) + u^ - 27 ;
Не допустимо в выражениях смешивать адреса (указатели) и значения (данные).
Для освобождения динамической памяти (возврата динамической памяти в кучу) используется процедура
DISPOSE (<типизированный указатель>);
Данная процедура возвращает в кучу освобожденную память, например:
DISPOSE(u); DISPOSE(p1); DISPOSE(p); {3 оператора вернут 10 байт}.
Повторное применение процедуры DISPOSE к свободному указателю приведет к возникновению ошибки периода исполнения. Поэтому для пометки освободившегося указателя обычно используется зарезервированное слово NIL (пустой).
Пример фрагмента программы, в которой для объявления указателя использована типизированная константа с начальным значением, равным NIL:
Const i: ^integer = NIL; {объявление константы-указатель}
...
if i = NIL then {проверка указателя: "свободный?"}
NEW(i); {резервирование памяти}
... { обработка данных}
DISPOSE(i); {освобождение памяти}
i = NIL; {пометка свободным}
Все операции с кучей выполняются под управлением особой программы, которая называется администратором кучи. Она ведет учет всех свободных фрагментов в куче. При очередном обращении к процедуре NEW администратор отыскивает в куче наименьший свободный фрагмент, в котором может разместиться требуемая переменная. Адрес начала найденного фрагмента возвращается в указателе, а сам фрагмент или его часть нужной длины помечается как занятая часть кучи.
Для работы с нетипизированными указателями используют процедуры:
GETMEM(<нетип.указатель>, SIZE); для резервирования памяти, FREEMEM(<нетип.указатель>, SIZE); для освобождения памяти.
SIZE размер в байтах требуемой или освобождаемой части кучи.
За одно обращение к куче процедурой GETMEM можно зарезервировать до 65521 байта динамической памяти.
При работе с динамической памятью необходимо соблюдать правило: освобождаться столько памяти, сколько ее было зарезервировано, и именно с того адреса, с которого она была зарезервирована. Например:
Var p: pointer;
Begin
Getmem(p,8);
...
FreeMEM(p,8);
End.