ВЕКТОР С УПРАВЛЯЕМОЙ ДЛИНОЙ.


Память под вектор с управляемой длиной отводится при создании строки и ее размер и размещение остаются неизменными все время существования строки. В дескрипторе такого вектора-строки может отсутствовать начальный индекс, так как он может быть зафиксирован раз навсегда установленными соглашениями, но появляется поле текущей длины строки. Размер строки, таким образом, может изменяться от 0 до значения максимального индекса вектора. "Лишняя" часть отводимой памяти может быть заполнена любыми кодами - она не принимается во внимание при оперировании со строкой. Поле конечного индекса может быть использовано для контроля превышения длиной строки объема отведенной памяти. Представление строк в виде вектора с управляемой длиной (при максимальной длине 10) показано на рис.4.6.

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

Рис.4.6. Представление строк вектором с управляемой длиной

В программном примере 4.4 приведен модуль, реализующий представление строк вектором с управляемой длиной и некоторые операции над такими строками. Для уменьшения объема в примере в секции Implementation определены не все процедуры/функции. Предоставляем читателю самостоятельно разработать прочие объявленные в секции Interface подпрограммы. Дескриптор строки описывается типом _strdescr, который в точности повторяет структуру, показанную на рис.4.6. Функция NewStr выделяет две области памяти: для дескриптора строки и для области данных строки. Адрес дескриптора строки, возвращаемый функцией NewStr - тип varstr - является той переменной, значение которой указывается пользователем модуля для идентификации конкретной строки при всех последующих операциях с нею. Область данных, указатель на которую заносится в дескрипторе строки - тип _dat_area - описана как массив символов максимального возможного объема - 64 Кбайт. Однако, объем памяти, выделяемый под область данных функцией NewStr, как правило, меньший - он задается параметром функции. Хотя индексы в массиве символов строки теоретически могут изменяться от 1 до 65535, значение индекса в каждой конкретной строке при ее обработке ограничивается полем maxlen дескриптора данной строки. Все процедуры/функции обработки строк работают с символами строки как с элементами вектора, обращаясь к ним по индексу. Адрес вектора процедуры получают из дескриптора строки. Обратите внимание на то, что в процедуре CopyStr длина результата ограничивается максимальной длиной целевой строки.

{==== Программный пример 4.4 ====}

{ Представление строк вектором с управляемой длиной }

Unit Vstr;

Interface

type _dat_area = array[1..65535] of char;

type _strdescr = record { дескриптор строки }

maxlen, curlen : word; { максимальная и текущая длины }

strdata : ^_dat_area; { указатель на данные строки }

end;

type varstr = ^_strdescr; { тип - СТРОКА ПЕРЕМЕННОЙ ДЛИНЫ }

Function NewStr(len : word) : varstr;

Procedure DispStr(s : varstr);

Function LenStr(s : varstr) : word;

Procedure CopyStr(s1, s2 : varstr);

Function CompStr(s1, s2 : varstr) : integer;

Function PosStr(s1, s2 : varstr) : word;

Procedure ConcatStr(var s1: varstr; s2 : varstr);

Procedure SubStr(var s1 : varstr; n, l : word);

Implementation

{** Создание строки; len - максимальная длина строки;

ф-ция возвращает указатель на дескриптор строки }

Function NewStr(len : word) : varstr;

var addr : varstr;

daddr : pointer;

begin

New(addr); { выделение памяти для дескриптора }

Getmem(daddr,len); { выделение памяти для данных }

{ занесение в дескриптор начальных значений }

addr^.strdata:=daddr; addr^.maxlen:=len; addr^.curlen:=0;

Newstr:=addr;

end; { Function NewStr }

Procedure DispStr(s : varstr); {** Уничтожение строки }

begin

FreeMem(s^.strdata,s^.maxlen); { уничтожение данных }

Dispose(s); { уничтожение дескриптора }

end; { Procedure DispStr }

{** Определение длины строки, длина выбирается из дескриптора }

Function LenStr(s : varstr) : word;

begin

LenStr:=s^.curlen;

end; { Function LenStr }

Procedure CopyStr(s1, s2 : varstr); { Присваивание строк s1:=s2}

var i, len : word;

begin

{ длина строки-результата м.б. ограничена ее макс. длиной }

if s1^.maxlen s2; -1 - если s1 < s2 }

Function CompStr(s1, s2 : varstr) : integer;

var i : integer;

begin i:=1; { индекс текущего символа }

{ цикл, пока не будет достигнут конец одной из строк }

while (i <= s1^.curlen) and (i <= s2^.curlen) do

{ если i-ые символы не равны, функция заканчивается }

begin if s1^.strdata^[i] > s2^.strdata^[i] then

begin CompStr:=1; Exit; end;

if s1^.strdata^[i] < s2^.strdata^[i] then

begin CompStr:=-1; Exit; end;

i:=i+1; { переход к следующему символу }

end;

{ если выполнение дошло до этой точки, то найден конец одной из строк, и все сравненные до сих пор символы были равны; строка меньшей длины считается меньшей }

if s1^.curlens2^.curlen then CompStr:=1

else CompStr:=0;

end; { Function CompStr }

.

.

END.



Дата добавления: 2016-07-22; просмотров: 1408;


Поиск по сайту:

Воспользовавшись поиском можно найти нужную информацию на сайте.

Поделитесь с друзьями:

Считаете данную информацию полезной, тогда расскажите друзьям в соц. сетях.
Poznayka.org - Познайка.Орг - 2016-2024 год. Материал предоставляется для ознакомительных и учебных целей.
Генерация страницы за: 0.01 сек.