Главная Случайная страница


Полезное:

Как сделать разговор полезным и приятным Как сделать объемную звезду своими руками Как сделать то, что делать не хочется? Как сделать погремушку Как сделать так чтобы женщины сами знакомились с вами Как сделать идею коммерческой Как сделать хорошую растяжку ног? Как сделать наш разум здоровым? Как сделать, чтобы люди обманывали меньше Вопрос 4. Как сделать так, чтобы вас уважали и ценили? Как сделать лучше себе и другим людям Как сделать свидание интересным?


Категории:

АрхитектураАстрономияБиологияГеографияГеологияИнформатикаИскусствоИсторияКулинарияКультураМаркетингМатематикаМедицинаМенеджментОхрана трудаПравоПроизводствоПсихологияРелигияСоциологияСпортТехникаФизикаФилософияХимияЭкологияЭкономикаЭлектроника






Динамические переменные





Переменные, которые описываются в разделе var какого-либо блока про- граммы или подпрограммы, называются статическими. Транслятор после анализа этого раздела, т.е. до выполнения программы, отводит каждой переменной в зависимости от ее типа соответствующее число ячеек памяти определенной длины и закрепляет их за данной переменной на все время работы блока. Они не могут использоваться под другие нужды, даже если в процессе работы про- граммы эта переменная становится ненужной. Статические переменные размещаются в непрерывной области памяти, имеющей небольшой объем, большая часть оперативной памяти при этом остается неиспользованной.

Динамическое распределение памяти широко используется для экономии компьютерных ресурсов при обработке данных большого объема, которые могут не уместиться в памяти, отводимой для статических переменных. При этом те переменные или объекты, которые становятся ненужными, уничтожаются, а освобожденное место используется для новых переменных или объектов. Это особенно эффективно в задачах, в которых число необходимых объектов зависит от обрабатываемых данных или от действий пользователя в процессе выполнения программы, т.е. заранее неизвестно. Для динамического распределения выделяется специальная область оперативной памяти – heap (куча). Динамическая память (куча) – это свободная часть оперативной памяти, которая доступна для использования в процессе работы программы. Как правило, она значительно больше памяти, отводимой для статических переменных. Динамическое размещение данных происходит непосредственно при выполнении про- граммы. При динамическом размещении заранее неизвестны ни количество, ни тип данных. К ним нельзя обращаться по именам, как к статическим переменным. Для работы с объектами в динамически распределяемой области памяти используются указатели. При этом сами указатели должны описываться в разделе var, т.е. являются статическими переменными.

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

Динамическое распределение памяти в куче может производиться двумя способами: 1) с помощью процедур new и dispose

2) с помощью процедур getmem и freemem.

При первом способе выделение памяти для динамической переменной производится процедурой: procedure new (имя указателя);

где имя указателя – имя переменной, являющейся типизированным указателем. Этой переменной передается адрес начала выделенной области памяти. Размер выделяемой области определяется размером памяти, необходимым для размещения того типа данных, который указан при объявлении указателя.

Например:

var p:^real;

… new(p);

Здесь описывается переменная p, являющаяся указателем на действительное значение. Процедура new выделяет память для переменной типа real, и переменная - указатель p будет содержать адрес первого байта памяти, выделенной для этой переменной. После того, как указатель приобрел некоторое значение, отличное от nil, то есть стал указывать на конкретный байт памяти, в выделенный участок памяти может быть помещено значение соответствующего типа. Чтобы получить доступ к данным, на которые указывает типизированный указатель, надо записать:

имя переменной -указателя ^

Символ ^ после имени указателя означает, что речь идет не о значении переменной-указателя, а о значении того динамического объекта, на который указывает эта переменная. Имя ссылочной переменной с последующим символом ^ называют динамической переменной (переменной с указателем).

Например:

var i: ^integer; a: ^real;

Begin

new(i); new(a); i^:=10; a^:=5.3/i^;

End.

Здесь a^ - число 0,53

a – адрес числа 0,53

Нельзя смешивать указатели и данные:

a:=sqr(a^)-i^; {неверно}

a^:=sqr(a); {неверно}

После того, как динамическая переменная стала ненужной, ее можно уничтожить, а освободившиеся байты вернуть в кучу. Освобождение памяти, динамически выделенной процедурой new, осуществляется процедурой dispose:

procedure dispose (имя указателя);

Применение процедуры dispose освобождает память, но не изменяет значение указателя, не делает его равным nil, хотя теперь указатель не указывает ни на что конкретное. Например, если р – указатель на динамическую переменную, память для которой выдела процедурой new(p), то процедура dispose(р) освобождает занимаемую динамической переменной память (байты, содержавшие p^, будут считаться свободными). При этом значение указателя р не изменяется, однако его использование приведет к порче значений других динамических переменных. Поэтому рекомендуется освободившемуся указателю присваивать значение nil: dispose(р); р:= nil;


Пример:

var p1, p2, p3:^integer;{указатели на переменные типа integer}

Begin

//выделяется память для динамических переменных типа integer new(p1); new(p2); new(p3);

//динамические переменные p1^, p2^ и p3^ получают значения p1^:=5; p2^:=3; p3^:=p1^+p2^;

writeln(‘сумма чисел равна ‘,p3^);

//освобождается память, занимаемая динамическими переменными dispose(p1); dispose(p2); dispose(p3);

End.

Второй способ динамического выделения памяти связан с применением процедуры Getmem для выделения памяти и Freemem для ее освобождения:

procedure Getmem(имя указателя, объем памяти в байтах);

procedure Freemem(имя указателя, объем памяти в байтах);

В этих процедурах могут использоваться не только типизированные, но и нетипизированные указатели.

Например: var a:pointer;

begin Getmem(a,4); … Freemem(a,4); end.

Если используется типизированный указатель, то объем необходимой памяти лучше всего определить функцией sizeof, так как размеры памяти, отводимой под тот или иной тип данных, могут изменяться в различных версиях компилятора. Функция sizeof(х) вычисляет длину в байтах для х.

Getmem(p,sizeof(real)); Freemem(p,sizeof(real));

Чтобы получить доступ к данным, на которые указывает нетипизированный указатель pointer, нельзя писать: имя переменной-указателя ^. Надо сначала привести его к другому типу указателя. Явное приведение типа переменной можно проводить для любых типов, имеющих одинаковый размер, с помощью конструкции: идентификатор типа (выражение).

Например:

type Pint=^integer;

var p1,p2:Pint; p:pointer; i:integer;

выражение Pint(p) приведет тип указателя p к объявленному выше типу Pint, после чего его можно записать:

Pint(p):=p1; i:=Pint(p)^+p2^;

Пример:

type pint = ^integer;

var p1,p2:pint;p:pointer;

Begin

new(p1); new(p2); getmem(p,sizeof(integer));

p1^:=5; p2^:=10; {можно записать p:=p1;p^ уже нельзя} pint(p)^:=p1^;

writeln(pint(p)^+p2^); {результат 15} dispose(p1); dispose(p2); freemem(p,sizeof(integer));

End.

Динамическая память используется для организации динамических структур данных. Простейшими динамическими структурами являются стеки, очереди и списки. Элементы этих структур программируются в виде величин типа запись, причем одно из полей является указателем на следующий (предыдущий) элемент структуры. Это позволяет размещать данные в памяти независимо друг от друга, так что удаление элемента из структуры или добавление нового элемента не приводит к необходимости перемещать в памяти другие элементы, как это происходит, например, при использовании массивов.

 







Date: 2016-07-18; view: 478; Нарушение авторских прав



mydocx.ru - 2015-2024 year. (0.008 sec.) Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав - Пожаловаться на публикацию