Меню сайта
Форма входа
Категории раздела
Учебник по Паскалю [13] Практика [23]
примеры программ
Главная » Статьи » Pascal » Учебник по Паскалю

Динамические переменные (использование указателей)

Указатели

Операционная система MS – DOS все адресуемое пространство делит на сегменты. Сегмент – это участок памяти размером 64 кбайт. Для задания адреса необходимо определить адрес начала сегмента и смещение относительно начала сегмента.

В Турбо Паскале определен адресный тип Pointer указатель

Переменные типа Pointer

var p: Pointer;

содержат адрес какого-либо элемента программы и занимают 4 байта, при этом адрес хранится как два слова, одно из них определяет сегмент, второе – смещение.

Переменную типа указатель можно описать другим способом.

type NameType= ^T;
var p: NameType;

Здесь p – переменная типа указатель, связанная с типом Т с помощью имени типа NameType. Описать переменную типа указатель можно непосредственно в разделе описания переменных:

var p: ^T;

Необходимо различать переменную типа указатель и переменную, на которую этот указатель ссылается. Например, если p – ссылка на переменную типа Т, то p^ – обозначение этой самой переменной.

Для переменных типа указатель введено стандартное значение NIL, которое означает, что указатель не ссылается ни к какому объекту. Константа NIL используется для любых указателей.

Над указателями не определено никаких операций, кроме проверки на равенство и неравенство.

Переменные типа указатель могут быть записаны в левой части оператора присваивания, при этом в правой части может находиться либо функция определения адреса Addr(X), либо выражение @ X, где @ – унарная операция взятия адреса, X – имя переменной любого типа, в том числе процедурного.

Переменные типа указатель не могут быть элементами списка ввода-вывода.

ДИНАМИЧЕСКИЕ ПЕРЕМЕННЫЕ

Статической  переменной (статически как бы размещенной) именуется, как мы выражаемся, описанная явным образом в програмке переменная, обращение к которой осуществляется по имени. Место в памяти для размещения статических переменных определяется при компиляции программы.

В отличие от таковых статических переменных в програмках, написанных на языке Паскаль, могут быть сделаны динамические переменные. Основное свойство динамических, как люди привыкли выражаться, переменных также заключается в том, что они создаются и память для их, стало быть, выделяется во время выполнения программы. Располагаются динамические переменные в динамической области памяти (heap – области).

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

Работа с динамической областью памяти в Турбо Паскале реализуется с помощью процедур и функций New, Dispose, GetMem, FreeMem, Mark, Release, MaxAvail, MemAvail, SizeOf.

Процедура New (var p: Pointer) выделяет место в динамической области памяти для размещения динамической переменной p^ и ее адрес присваивает указателю p.

Процедура Dispose (var p: Pointer) освобождает участок памяти, выделенный для размещения динамической переменной процедурой New, и значение указателя p становится неопределенным.

Процедура GetMem (var p: Pointer; size: Word) выделяет участок памяти в heap-области, присваивает адрес его начала указателю p, размер участка в байтах задается параметром size.

Процедура FreeMem (var p: Pointer; size: Word) освобождает участок памяти, адрес начала которого определен указателем p, а размер параметром size. Значение указателя p становится неопределенным.

Процедура Mark (var p: Pointer) записывает в указатель p адрес начала участка свободной динамической памяти на момент ее вызова.

Процедура Release (var p: Pointer) освобождает участок динамической памяти, начиная с адреса, записанного в указатель p процедурой Mark, то есть, очищает ту динамическую память, которая была занята после вызова процедуры Mark.

Функция MaxAvail: Longint возвращает длину в байтах самого длинного свободного участка динамической памяти.

Функция MemAvail: Longint полный объем свободной динамической памяти в байтах.

Вспомогательная функция SizeOf (X): Word возвращает объем в байтах, занимаемый X, причем X может быть либо именем переменной любого типа, либо именем типа.

Рассмотрим некоторые примеры работы с указателями.

var
   p1, p2: ^Integer;

Здесь p1 и p2 – указатели или переменные ссылочного типа.

p1:=NIL; p2:=NIL;

После выполнения этих операторов присваивания указатели p1 и p2 не будут ссылаться ни на какой конкретный объект.

New(p1); New(p2);

Процедура New(p1) выполняет следующие действия:

– в памяти ЭВМ выделяется участок для размещения величины целого типа;
– адрес этого участка присваивается переменной p1:

Аналогично, процедура New(p2) обеспечит выделение участка памяти, адрес которого будет записан в p2:

После выполнения операторов присваивания

p1^:=2; p2^:=4;

в выделенные участки памяти будут записаны значения 2 и 4 соответственно:

В результате выполнения оператора присваивания

p1^:=p2^;

в участок памяти, на который ссылается указатель p1, будет записано значение 4:

После выполнения оператора присваивания

p2:=p1;

оба указателя будут содержать адрес первого участка памяти:

Переменные p1^, p2^ являются динамическими, так как память для них выделяется в процессе выполнения программы с помощью процедуры New.

Динамические переменные могут входить в состав выражений, например:

p1^:=p1^+8; Write('p1^=',p1^:3);

Пример. В результате выполнения программы:

Program DemoPointer;
Var p1,p2,p3:^Integer;
Begin
p1:=NIL; p2:=NIL; p3:=NIL;
New(p1); New(p2); New(p3);
p1^:=2; p2^:=4;
p3^:=p1^+Sqr(p2^);
writeln('p1^=',p1^:3,' p2^=',p2^:3,' p3^=',p3^:3);
p1:=p2;
writeln('p1^=',p1^:3,' p2^=',p2^:3)
End.

на экран дисплея будут выведены результаты:

p1^= 2 p2^= 4 p3^= 18
p1^= 4 p2^= 4

Категория: Учебник по Паскалю | Добавил: nazgull (26.12.2010)
Просмотров: 9316 | Теги: динамическая память паскаль, Урок, пример, динамические переменные | Рейтинг: 0.0/0
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Ссылки