
11. Ссылочные типы и указатели. Описание типа. Действия над ссылками.
статические объекты порождаются до выполнения программы и размер их значений известен заранее, то место в памяти выделяется еще на этапе компиляции. В программе ссылка на программные объекты осуществляется путем указания их имен, т.е. считается, что по имени осуществляется непосредственный доступ к объекту, а ссылка на объект осуществляется путем указания адреса объекта.
Программные объекты возникающие на этапе компиляции-статические, а объекты возникающие на этапе выполнения программы-динамические.
Для создания динамических объектов предусматривается ссылочный тип. Значением этого типа является ссылка на программный объект, по которой осуществляется доступ к этому объекту. Содержательно любой ссылочный тип определяет множество значений, которые являются указателями на значения некоторого определенного типа.p=nil – обнулить переменную. тип определяется либо путем непосредственного задания типа в описании переменных, либо в разделе описания типов.
Для описания используется символ "^" (признак ссылочного типа) и идентификатор типа/ не описание! только ссылки на имена типов!
Type
Massiv = array[1..100] of integer;
Dinamic = ^ Massiv;
Var
Mas : Dinamic; {массив указателей на тип integer}
p : ^ Integer; {указание места в памяти (адрес) этого объекта}
q :^ Char;
исключение. При описании записи возможна ссылка до описания записи типа.
Type
prec = ^rec; {объявление указателя на запись}
rec = record {объявление записи}
x, y : real;
ptr prec;
end;
const
st : rec = (x : 0; y : 0; ptr : nil) {инициализация записи}
Описание
Var
V : ^T;
адреса задаются совокупностью двух шестнадцатиразрядных слов, которые называются сегментом и смещением. Сегмент - это участок памяти, имеющий длину 65535 байт (64 К) и начинающийся с физического адреса, кратного 16 (0, 16, 32, 48 и т.д.). Смещение указывает, сколько байт от начала сегмента необходимо пропустить, чтобы обратиться к нужному адресу. абсолютный адрес образуется следующим образом: сегмент * 16 + смещение.
Для порождения самого динамического объекта служит процедура
New (P); где P – указатель. Процедура позволяет выделить область памяти такого размера, в которой может разместиться величина базового типа. Указатель принимает значение начального адреса выделенной области.
Dispose (P); где P – указатель. Процедура позволяет освободить область памяти, на которую указывает указатель Р, для последующего использования.
Действия над ссылками.
Чтобы получить значение элемента, с которым связан указатель, следует взять имя указателя и поставить после него знак "^".
Var P : ^Integer p^:= 58;
Type
NewReal = ^ Real;
Var
A : array[1..50] of NewReal;
A [1], A[k+5] – переменные ссылочного типа (ссылки);
A^ [1], A^[k+5] – переменные с указателем. Их значениями будут уже вещественные числа.
присваивания значений ссылочным переменным и переменным с указателем
p^:= 3; q^:= 58; p:= q; q:= nil;
(p:= q;) адрес, хранимый в р заменить на адрес, хранимый в q.
p^:= q^, то получим следующий результат:
Var
p, q : ^integer;
p := q^ (в левой части оператора присваивания стоит переменная ссылочного типа, а в правой части переменная с указателем типа integer).
p^:= 'a' (в левой части – динамическая переменная типа integer, а в правой – символьное значение).
p^:= nil (в левой части – динамическая переменная типа integer, а в правой – значение ссылочного типа).
Итак, использование динамических переменных имеет следующие отличия от использования статических переменных:
вместо описания самих динамических переменных в программе описываются только указатели на них – статические переменные ссылочного типа.
порождение динамических переменных производится с помощью процедуры New.
для ссылки на значение динамической переменной используется переменная с указателем.
Сравнение ссылок
две операции сравнения: равно или неравно. Эти операции проверяют, ссылаются ли два указателя на один и тот же адрес – знаками "=" и "< >". If p1 < > nil then …
Существует и другая возможность работать с динамической памятью – использовать процедуры GetMem и FreeMem.
GetMem (P, Size:word); где P переменная ссылочного типа; Size размер выделенной области в байтах. Процедура позволяет выделить в динамической области памяти область необходимого размера, при этом адрес выделенной области присваивается переменной Р.
FreeMem (P, Size: word); где P переменная ссылочного типа; Size размер выделенной области в байтах. Процедура освобождает занятую область памяти с адресом, задаваемым переменной Р и размером Size байт. Эта область свободна для повторного использования, а указатель Р становится неопределенным.
унарная операция получения адреса объекта - @. X:= @Y (переменная X будет содержать адрес параметра Y), Addr (Х) – функция получения адреса параметра.
стандартный ссылочный тип Pointer, который дает указатель, не связанный ни с каким конкретным базовым типом. что использование знака ^ после параметра типа Pointer дает параметр без типа.