
Указатели и динамические структуры
Данные в TP могут быть:
1. Статистические. Память под статистические переменные выделяется во время компиляции и сохраняется в течение всей работы программы (статическая память).
2. Динамические. Память под динамические величины отводится во время выполнения программы (динамическая память). И если потребность в каких-либо данных отпала до окончания программы, то занятую ими память можно освободить для другой информации.
Использование динамической памяти позволяет:
Увеличить объем обрабатываемых данных.
Создавать структуры данных переменного размера.
Для работы с динамическими величинами используется ссылочный тип. Величины, имеющие ссылочный тип, называются указателями.
Описание указателя:
var <имя> : <ссылочный тип>;
var <имя>: <^тип>; - если тип известен
: ^pointer; - если тип неизвестен
Например:
var p1:^integer;
var p2:^char;
Указатель – это переменная, значением которой является адрес в памяти. Для переменных, объявленных с помощью указателя, память выделяется в динамической области, размер которой намного (4-5 раза) превосходит размер сегмента, где размещаются обычные переменные. Такой способ объявления может использоваться при большом количестве массивов большой размерности.
Указатель располагается в статистической памяти и требует описания, сами динамические величины не требуют описания, т.к. во время компиляции память под них не выделяется.
Как происходит выделение памяти под динамическую величину? – в результате выполнения процедуры
New(<указатель>);
Например.
New(p1); New(p2);
После этого выделяется память под динамические величины
p1^, p2^. Им можно присваивать значения:
p1^:=10; p2^:=’B’;
Запись вида uk^ определяет содержимое по адресу, на который ссылается указатель uk.
Nil – это пустая ссылка, т.е. которая никуда не указывает.
Ввод и вывод указателей не допускается.
Значения указателей можно сравнивать (= и <>), для работы с ними используют следующие стандартные процедуры и функции:
new (указатель); -процедура, по которой указатель получает в качестве значения адрес в динамической памяти и по этому адресу выделяется в соответствии с типом нужное количество байт;
dispose (указатель); - процедура, по которой память, выделенная new, освобождается;
getmem (указатель, <кол-во байт>); - процедура, по которой указатель получает значение, и по этому адресу выделяется не одна область памяти (как new), а n областей;
freemem (указатель, <кол-во байт>) – процедура, освобождающая n областей памяти;
addr (переменная) – функция, которая указателю присвоит адрес переменной (аналогичное действие выполнит и операция @переменная);
maxavail – функция, возвращающий максимальный непрерывный свободный участок в heape памяти (тип longint);
memavail – функция, возвращающая всю свободную динамическую память (тип longint).
Пример: Даны a и b. Найти с=a+b с использованием указателей.
var ua, ub, uc: ^integer;
begin
new (ua); new(ub); new(uc); {выделяем память}
read (ua^, ub^);
uc^:=ua^+ub^;
writeln (uc^:10);
end.
Замечание. При достижении end. память освобождается, поэтому dispose(ua), dispose(ub), dispose(uc), можно не записывать.