Новые книги

Кто из нас не знает, что такое LEGO? Но мало кому известно, какие изменения им пришлось пережить, чтобы достичь статуса самой популярной в мире компании по производству игрушек. Окунитесь в самое сердце LEGO, узнайте о причинах, приведших к кризису, и стратегиях, выведших ее на вершину.
Новое издание популярной книги с видеокурсом. Из чего состоит компьютер и как собрать его самостоятельно, как установить операционную систему и настроить ее для удобной работы, как следить за состоянием компьютера и как его модернизировать – теперь вы не только прочитаете об этом, но еще и увидите все собственными глазами. Такой «видеоподход» полностью исключает то, что вы чего-нибудь не поймете. Этот видеосамоучитель – настоящий обучающий курс для тех, кто желает собственными руками собирать, настраивать, обслуживать и модернизировать ПК.

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

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

   Статической переменной (статически размещенной) называется описан-

ная явным образом в программе переменная, обращение к ней осуществля-

ется по имени.  Место в памяти для размещения статических  переменных

определяется при компиляции программы.

   В отличие от таких статических переменных в программах, написанных

на языке ПАСКАЛЬ,  могут быть созданы динамические переменные. Основ-

ное свойство динамических переменных заключается в том,  что они соз-

даются и   память  для  них выделяется во время выполнения программы.

Размещаются динамические переменные  в  динамической  области  памяти

(heap - области).

   Динамическая переменная не указывается явно в описаниях переменных

и к   ней нельзя обратиться по имени.  Доступ к таким переменным осу-

ществляется с помощью указателей и ссылок.

   Работа с динамической областью памяти в TURBO PASCAL реализуется с

помощью процедур и функций 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:

 

                ЙННННН»          ЙННННН»

                є  *ДДєДДДДДДДДД>є     є

                ИНННННј          ИНННННј

                  p1               p1^

 

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

адрес которого будет записан в p2:

  

                ЙННННН»          ЙННННН»

                є  *ДДєДДДДДДДДД>є     є

                ИНННННј          ИНННННј

                  p2               p2^

 

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

   

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

   

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

ственно:

   

                ЙННННН»          ЙННННН»

                є  *ДДєДДДДДДДДД>є  2  є

                ИНННННј          ИНННННј

                  p1               p1^

 

                ЙННННН»          ЙННННН»

                є  *ДДєДДДДДДДДД>є  4  є

                ИНННННј          ИНННННј

                  p2               p2^

   

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

   

       p1^:=p2^;

 

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

значение 4:

   

   

                ЙННННН»          ЙННННН»

                є  *ДДєДДДДДДДДД>є  4  є

                ИНННННј          ИНННННј

                  p1               p1^

 

                ЙННННН»          ЙННННН»

                є  *ДДєДДДДДДДДД>є  4  є

                ИНННННј          ИНННННј

                  p2               p2^

 

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

   

      p2:=p1;

 

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

   

                ЙННННН»          ЙННННН»

                є  *ДДєДДДДДДДДД>є  4  є

                ИНННННј      ЪДД>ИНННННј

                  p1         і   p1^ p2^

                             і

                ЙННННН»      і

                є  *ДДєДДДДДДЩ

                ИНННННј

                  p2

                                                                   

   

   Переменные 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