- •2.1. Стандартные типы данных
- •2.2. Описание структур данных
- •2.3.1. Интервальные типы данных
- •2.4. Динамические структуры данных
- •2.5. Вариантные структуры данных
- •V: Variant; ; : rv.
- •I: Integer; ::::
- •V: Variant;
- •V: Variant;
- •V: Variant;
- •2.6. Выражения в Object Pascal
- •X, Rd: Double; I, Ri: Integer;
- •Var а, в, с: Boolean
- •X, y: Double;
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 реализована более удобная схема работы с динамическими массивами.