Партнерка на США и Канаду по недвижимости, выплаты в крипто

  • 30% recurring commission
  • Выплаты в USDT
  • Вывод каждую неделю
  • Комиссия до 5 лет за каждого referral

На следующем цикле чтения в массив Tek^ будет заноситься очередное текущее слово.

Время выполнения программы, приведенной в данном примере, существенно уменьшается по сравнению с аналогичной программой, использующей только автоматические переменные, за счет отсутствия физической пересылки массивов.

Пояснения к программе, приведенной в данном примере, схематически представляют рисунки 6.6 – 6.9.

Рисунок 6.6 – Результат выполнения
оператора New (Rez)

Рисунок 6.7 – Результат выполнения
оператора Vspom := Rez

Рисунок 6.8 – Результат выполнения
оператора Rez := Tek


Рисунок 6.9 – Результат выполнения
оператора Tek := Vspom


6.2.2. Процедуры Getmem и Freemem

Использование процедур Getmem и Freemem – это второй метод работы с динамическими переменными.

Вызов процедуры Getmem имеет следующий формат:

Getmem (P, Size);

Здесь P - указатель любого типа, Size – выражение типа Word.

Процедура Getmem выделяет из Heap-области (хип-область, область кучи, область динамической памяти) блок памяти заданного размера Size (порождает динамическую переменную размера Size) и адрес этого блока присваивает ссылочной переменной P. Максимальный размер блока – 65521байт (64К байта – $F (смещение)).

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

Freemem (P, Size)

Здесь P – указатель произвольного типа, которому предварительно было присвоено значение процедурой Getmem или оператором присваивания; значение Size должно точно соответствовать размеру переменной, размещенной до этого процедурой Getmem.

НЕ нашли? Не то? Что вы ищете?

Процедура Freemem уничтожает динамическую переменную P^, занимаемая ею память считается свободной, значение P становится неопределенным.

Таким образом, действие процедур Getmem/Freemem аналогично действию процедур New/Dispose – порождается и уничтожается динамическая переменная.

Пример 6.8.

Эквивалентные фрагменты программ, использующие процедуры Getmem/Freemem и New/Dispose.

Type

       T = <Тип>;

Var

       P: ^T;

Begin

В общем случае процедуры Getmem/Freemem дают большую свободу действий по сравнению с процедурами New/Dispose, так как позволяют работать без привязки к конкретному типу переменных.

Пример 6.9.

Использование процедур Getmem/Freemem. Различная интерпретация выделенной области памяти.

Type

         Zap =        Record

                                 X, Y: Integer;

                 End;

         St = String [20];

Var

       P: Pointer;

Begin

         Getmem (P, 100); {Выделение блока памяти размером 100 байт, адрес этого блока присвоен ссылочной переменной Р}

         Zap(P^).X := 124; {Интерпретация выделенной области как записи – блоку памяти, связанному с указателем Р, присваивается тип Zap}

         Zap(P^).Y := 47; {Интерпретация выделенной области как записи}

       …

         Real(P^) := 0.213; {Интерпретация выделенной области как Real}

         St(P^) := ’ПРОГРАММИРОВАНИЕ’; {Интерпретация выделенной области как строки}

       Freemem (P, 100); {Освобождение блока памяти размером 100 байт}

6.2.3. Процедуры Mark и Release

Процедуры Mark (пометить) и Release (освободить) позволяют повысить эффективность работы с динамической памятью.

Обращение к процедуре Mark имеет следующий вид:

Mark (P1);

Здесь P1 – переменная типа указатель, ссылающаяся на переменную какого угодно типа.

Процедура Mark присваивает своему параметру P1 адрес начала свободной области динамической памяти.

Помеченная область с помощью процедур New или Getmem используется для размещения отдельных динамических переменных.

Когда данные динамические переменные окажутся ненужными, занимаемую ими память можно освободить. Для этого используется процедура Release с тем же параметром, что и в предыдущем обращении к процедуре Mark:

Release (P1);

Процедура Release освобождает память, начиная с адреса, полученного в результате выполнения последней процедуры Mark. Значение указателя P1 после выполнения процедуры Release равно Nil.

Схематически представление работы с динамической памятью без и с использованием процедур Mark/Release иллюстрирует рисунок 6.10.

Рисунок 6.10 – Схематическое представление
работы с динамической памятью
без и с использованием процедур Mark/Release

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

Возможна вложенность процедур Mark. Тогда каждой процедуре Mark соответствует своя процедура Release.

Пример 6.10.

Использование вложенных процедур Mark/Release.

В одной и той же программе не рекомендуется использовать одновременно процедуры Dispose или Freemem и Mark/Release, так как это может привести к непредсказуемым результатам (механизмы управления свободной памятью для процедур Dispose, Freemem и Mark/Release существенно различаются).

В общем случае вместо любой автоматической переменной в программе можно использовать динамическую переменную.

Основное достоинство использования динамических переменных – экономия памяти компьютера.

Недостатки использования динамических переменных по сравнению с автоматическими:

    удлиняется текст программы за счет использования процедур New/Dispose, Mark/Release, Getmem/Freemem; снижается наглядность программы за счет использования переменной с указателем (динамической переменной); снижается быстродействие программы за счет необходимости во время ее выполнения размещать порожденную динамическую переменную в памяти машины, за счет формирования значения соответствующего указателя и за счет усложнения доступа к значению динамической переменной.

Раздел 7. Динамические структуры данных

7.1. Динамические цепочки

7.1.1. Структура динамической цепочки

Динамические цепочки являются аналогами строк текущей длины.

В строке каждый следующий элемент занимает ячейку памяти со следующим по порядку адресом.

Элементы строки можно размещать в памяти произвольно, если каждый элемент снабдить явным указанием места, где находится следующий за ним элемент. В этом случае каждый элемент строки должен состоять из двух полей: в одном поле (Element) – символ сроки, в другом (Adrcled) – ссылка на следующий элемент строки (адрес следующего элемента).

Каждая такая пара называется звеном. Ссылки сцепляют звенья в одну цепочку.

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

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

Пример 7.1.

Объявление звена цепочки.

Type

       Adr = ^Zveno;

       Zveno =        Record

               Element: Char;

               Adrcled: Adr

       End;

В примере 7.1 тип Adr представляет собой ссылки на программные элементы типа Zveno.

В данном примере имя типа Zveno используется до его описания при описании типа Adr (ссылочного типа). Ссылочный тип – единственный тип, где можно использовать имя до его описания. Обратную последовательность объявлений (вначале описать тип Zveno, а потом – тип Adr) в примере 7.1 использовать было бы нельзя (так как в типе Zveno используется неописанный тип Adr, а Zveno не является ссылочным типом).

Последнее звено цепочки должно быть снабжено ссылкой Nil (это признак конца цепочки).

Для работы с цепочкой необходимо использовать два указателя: ссылку на ее первое звено (Adr1) и ссылку на текущее звено (Adrzv). Ссылки должны иметь тип Adr. Например,

Var Adr1, Adrzv: Adr;

Схематично цепочка может быть представлена так, как изображает рисунок 7.1.

Рисунок 7.1 – Схематическое представление цепочки

Для удобства работы с цепочкой в нее обычно включается заглавное «нулевое» звено (хотя это и не обязательно). В поле Adrcled данного звена содержится ссылка на первое звено цепочки (его адрес). Поле Element может быть использовано для хранения какой-либо информации о строке.

7.1.2. Формирование цепочки

Пусть имеется объявление звена цепочки, соответствующее примеру 7.1.

Алгоритм формирования цепочки:

Отвести область памяти для очередного звена. Его адрес занести в поле Adrcled текущего звена. Новое звено сделать текущим (занести его адрес в указатель текущего звена Adrzv). В поле Element текущего звена занести очередной символ. В поле Adrcled текущего звена занести Nil. Прочитать следующий символ исходного текста. Повторить этапы алгоритма, начиная с первого этапа.

Предварительно перед выполнением этапов 1 – 6 алгоритма необходимо сформировать заглавное звено.

Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33