Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Теория 9.doc
Скачиваний:
5
Добавлен:
05.05.2019
Размер:
349.7 Кб
Скачать

2.4. Динамические структуры данных

Для работы с динамическими структурами данных Turbo Pascal предла­гал два вида ссылочных типов — типизированные указатели и нетипизи-рованные.

Нетипизированный указатель представляет собой переменную, в которой хранится адрес некоторой области памяти некоторого размера, и пред­назначен для хранения произвольных данных. Типизированные ссылки указывают на место в памяти, где хранятся данные определенного типа.

В Delphi сохранены все возможности работы с указателями, а также до­бавлены новые структуры данных на их основе.

2.4.1. Нетипизированные указатели

Переменные -- нетипизированные указатели описываются с указанием типа Pointer, а выделение и освобождение памяти под них осуществ­ляется, соответсвенно, командами GetMem и FreeMem (см. листинг 2.6).

Листинг 2.6. Использование нетипизированных переменных-указателей

Program UsingPointers; Var

Point: Pointer;

Begin

GetMem(Point, 1024) ;

FreeMem(Point, 1024)

{Описание переменной-указателя, указан тип Pointer, то есть описывается нетипизированная ссылка!

{Выделение памяти под переменную-указатель размером 1024 байт} {Освобождение памяти, занятой под переменную-указатель}

End.

2.4.2. Типизированные указатели

Использование нетипизированных указателей ограничено стандартными функциями, принимающими такие переменные в качестве параметров, а также низкоуровневым программированием. Более интересными для рас­смотрения являются типизированные указатели.

Для описания типизированной ссылки не предусмотрен какой-либо спе­циальный тип данных, в отличие от нетипизированных указателей, име­ющих тип Pointer. Поскольку ссылочная переменная такого рода все­гда указывает на данные конкретного типа, то ее описание и строится на основе этого типа. Для указания на ссылочную природу переменных используется оператор «^», и описание выглядит следующим образом:

Var

<Переменная>:

^<названке типа>;

Или в разделе описания типов данных:

Туре

<Новый тип данных> = Л<Тип данных>;

После описания переменной-указателя под нее выделяется память толь­ко для хранения адреса, а под сами данные, на которые переменная ука­зывает, память не выделяется. Для инициализации переменной исполь­зуется процедура New, отличием которой от аналогичной процедуры GetMem, используемой для работы с нетипизированными указателями, является отсутствие второго параметра, определяющего размер выделяе­мой памяти. Это связано с тем, что типизированная ссылка указывает на данные известного типа, соответственно, размер эт^их данных также известен компилятору.

Итак, инициализация переменной выглядит следующим образом:

New(<Типизированный указатель>);

Соответственно, при освобождении памяти, занятой под типизированный

указатель, используется процедура Dispose — аналог процедуры FreeMem без второго параметра:

Dispose(<Типизированный указатель>);

Обращение к переменной-указателю происходит обычным образом — по ее имени, а для обращения к данным, на которые переменная указыва­ет, после имени переменной указывается оператор разыменовывания «л»:

<Название переменной>А

Рассмотрим пример работы с типизированной ссылкой, указывающей на переменную типа Double (см. листинг 2.7).

Begin

New(MyPDouble);

{Выде.-.е.-.-.^ переуе:-н;'.-: опреде~ =-■; ~ памятх з z .-

MyPDoubleA = 12. {Приев: е-" ссылает ; -.

Dispose(MyPDoubi

End.

котору:-: освобож

MyPDoub

2.4.3.

В Delphi добавлена ин зания размерностей и.

Var

IntArray: Array

Такие массивы являю длину. Установка разм ния программы произ ций SetLength и Lenc меруются от нуля.

Program UsingDyna Var

А, В: Array of

Листинг 2.7. Пример работы с типизированной ссылкой

Program UsingTypedPointers; Type

pDouble = "Double;

Var

MyPDouble: pDouble;

{Описание типа данных — указателя на переменную типа Double}

(Описание переменной — типизированного указателя на переменную типа Double}

Begin

New(MyPDouble) ;

{Выделение места в динамической памяти под одну переменную типа Double (размер необходимой памяти определяется автоматически) , адрес выделенной памяти заносится в переменную MyPDouble}

MyPDoubleA = 12.8;

{Присвоение переменной, на которую ссылается переменная-указатель значения 12.8}

Dispose(MyPDouble);

{Освобождение памяти, занятой под переменную, на которую указывает переменная MyPDouble. Адрес освобожденной памяти остается в переменной MyPDouble, но его использование недопустимо} End.

2.4.3. Динамические массивы

В Delphi добавлена интересная возможность описания массивов без ука­зания размерностей и, соответственно, пределов изменения индексов:

Var

IntArray: Array Of Integer;

Такие массивы являются динамическими6 и изначально имеют нулевую длину. Установка размера массива и определение его во время выполне­ния программы производится так же как и для строк, с помощью функ­ций SetLength и Length, соответственно. Элементы в данном случае ну­меруются от нуля.

Program UsingDynamicArraysl; Var

А, В: Array of Integer;

{Описание двух переменных — динамических массивов целочисленных элементов}

Begin

SetLength(A, 5)

А[0] := 1;

End.

{Установка размера массива А (5 элементов)}

{Присвоение значения I элементу массива А с номером 0}

Заметим, что в Turbo Pascal также существовала возможность использования динамических массивов через типизированные указатели, под которые память выделяется процедурой FreeMem, а не New. Однако о безопасности использования таких структур должен был заботиться программист. Также неудобства доставляла необходимость указания размерностей таких массивов и ограничение максимального числа элементов. В Object Pascal реализована более удобная схема работы с динамическими массивами.