Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
40
Добавлен:
23.03.2015
Размер:
1.05 Mб
Скачать

4)Стек на базе массива

size body

TopInd

rep

size

TopIndвершина

2

1

type

T=<описание типаТ>

stack_T=record

size:word

TopInd:word

Pbody:^body;

end;

Body=array[1..65536 div sizeof(T)] of T;

{stack_T=data type is Create,Push,Pop,IsEmpty,Done}

Описание: Stack_T- это изменяемые стеки элементов типа Т.ОперацииPushиPopизменяют состояние стека.

Procedure Create(Var S:Stack_T; size_stask:word);

requires 0sizeStask65535 div sizeof(T)

effectsсоздают пустой стек элементов типа Т с размером вsizeStaskэлементов типа Т

Procedure Push(Var S:Stask_T;X:T);

requiresS- содержит меньше элементов,чемS.size

modifies S

effects вталкивает элемент Xв стекS

Proceddure Pop(Var S:Stask_T);

requires S- непустой

modifies S

effectsвыталкивает элемент из вершины стека

Function Top (S:Stask_T):T;

requires S- непустой

effects возвращает элемент , находящийся в вершине стека.

Function IsEmpty(S:Stask_T):boolean;

effects IsEmpty=S=пустой стек

Proceddure Done(Var S:Stask_T);

effects освобождает память, занимаемую телом стека,и приводит дескриптор в нерабочее состояние.

IMPLEMENTATION

{ Функция абстракции:

Типичный стек есть последовательность элементов e1,e2,…,en,гдеn- вуршина стека (т.е. стек растет в строку старших индексов массиваpBody).

Функция инвариант представления:

1size65535divsizeof(T) & 0TopIndsize&PBody^[TopInd] - элемент в вершине стека.Pbodyуказывает на вектор памяти размеромsizesizeof(T)}

Procedure Create;

BEGIN

if sizeStasksizeof(T)>65536 then halt(1);

GetMem(S.Pbody,sizeStasksizeof(T));

S.TopInd: =0;

S.Size: =sizeStask;

END;

Procedure Push;

BEGIN

inc(S.TopInd);

S.Pbody^[S.TopInd]: =X;

END

СПЕЦИФИКАЦИИ

Существуют системы, в которых спецификации являются частью языка программирования.

Этапы создания программного обеспечения:

  • изучение

  • проектирование

  • кодирование

  • тестирование

  • отладка

  • использование

  • сопровождение

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

Спецификация - это текст, который обладает некоторыми свойствами.

Значение спецификации.

Главное назначение спецификации: отделение правильных реализаций от неправильных. Значениями спецификаций являются всевозможные правильные реализации

  • Программа

набор всех вычислений по этой программе;

конкретный вычислительный процесс по этой программе;

  • Спецификация

набор всех операций

конкретный вычислительный процесс

Создание спецификаций

Критерии, применяемые к спецификациям:

  1. Ограниченность

Ошибки:

неполное задание ограничений в предложении requires

  1. Неполный список исключительных ситуаций

  2. Обобщенность

Стили написания спецификаций

  1. Дефинитивный стиль

  2. Операционный стиль

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

Операционный указывает как достичь определенных свойств

Свойства спецификаций как текста

  • Полнота

  • Понимаемость

Факторы:

  • краткость

  • избыточность

  • структурированность

Нужно писать краткие, но полные спецификации.

Один, из главных эффектов спецификации - это более глубокое понимание смысла.

Этапы написания программы

Разработчику абстракции надо указать, что делать

Пользователю абстракции не на то, чем на спецификацию

При тестировании спецификации помогают генерировать тестовые данные, помогают создавать заглушки (приближенные модели программы)

На этапе компоновки позволяет сократить число проблем с интерфейсами за счет сокращения числа неявных предположений об этих интерфейсах

При отладке позволяет выявить местонахождение ошибок, позволяет избежать новых ошибок при исправлении.

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

Модификации программ

  • с изменением спецификации

  • без изменения спецификации

Кроме спецификаций иногда необходимо указывать принципы работы программы.

ИТЕРАТОРЫ

Итератор - абстракция, скрывающая подробности перебора элементов какой-то структуры данных.

Итератор осуществляет перебор компонентов множественного набора данных, удобным и эффективным способом и при этом не нарушает абстракцию через спецификацию.

Итератор выдает результаты не все целиком, а поочередно.

Итератор используется в следующих конструкциях:

for each <для элемента i, возвращаемого итератором А>

do <<выполнить над i некоторое действие D>>

Итератор позволяет разделить действия использования элемента. Он позволяет решить проблемы экономии памяти и времени.

Спецификация итератора:

iname=iter (<аргументы>) gields (<результаты>)

signals (<результаты, возвращаемые по исключительной ситуации>)

Пример. Вычислить сумму элементов множества целых чисел S (на базе массива неповторяющихся элементов)

elements=iter (S:intset) gields(int)

requires S не модифицируется в теле цикла

effects выдает элементы S в некотором произвольном порядке, причем каждый элемент

только один раэ

rep=array[int]

elements=iter(S:int) gields (int)

i:int=rep $ low(s) - нижняя граница индекса массива

while true do

gield(S[i])

except when bounds:returns end

i:=i+1

end

end elements

setsum=proc (S:intset) returns(int)

Sum:int:=0

for el:int in intset $ elements(S)do

Sum:=Sum+el

end for

return (Sum)

end SetSum

intset=cluster is ... elements...

Итераторов для одного типа может быть несколько. Итераторы могут использоваться как фильтры.

Встроенные итераторы языка CLU

from to=iter(x,y:int) gields(int)

effects выдает целые числа между x и y включительно в порядке следования.

filter=iter(S:intset) gields (int)

predicate:proctype(int) returns(bool)

for el:int in elements(S) do

if predicate(el) then

gield(el)

end if

end for

end filter

filter(S, intset $ elements, odd) -выдает только нечетные элементы

****************************************************************************************************

Служба управления памятью.

Свойство ОП (оперативная память):Вся динамически распределенная память может рассматриваться как сплошной массив, состоящий из байтов и назы-ваемый кучей (НЕАР-областью). К элементам которого можно добраться по адресу (прямой доступ ) НЕАР- область размещается в памяти компьютера следом за памятью, которое занимает тело программы.

Квант памяти: несколько ячеек , распо-

ложенных рядом на которые

накладывается определенная

Дос интерпритация.

640К

Несколько квантов памяти образуют совокуп-

ность квантов

Куча

Программа

DOS 1

0

Куча

Б4 Б4

Б3

Б2 Б2

Б1

Кроме понятия кванта памяти при работе с памятью используются такие понятия как :

Звено памяти -несколько подряд расположенных квантов, которые интерпре-

тируются по-разному.

Вектор памяти- несколько расположенных подряд квантов и интерпрети-

руются одинаково.

При распределении памяти возникает проблема: отыскивание очередной порции памяти, подходящей для размещения в ней звена (кванта памяти) называется Управлением памятью

Внутри программы формируется последовательность заявок выделение памяти. По каждой заявке служба памяти должна выделить память.

Служба памяти должна уметь:

  1. Инициализировать себя.

  2. Выделить память.

  3. Освободить память.

  4. Закончить работу.

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

Блок- участок памяти ,в котором существует служебные поля, которые

используются службой памяти.

блок

В зависимости от того, какого блок размера различают:

  • блоки фиксированной длины;

  • блоки переменной длины;

Компрессия- очень опасная операция. Заключается в том, что на освободившиеся области накладываются занятые области и все изменения записываются в файл.

Блоки переменной длины:

l1 L-l1

L L-l1 L-l1-l2 lkFree -список свободных блоков

Free

При выделении памяти возникает проблема - как выделять? (Блок подходящего размера)

Для выбора блока существует 3 стратегии:

  • Первый подходящий (first) удовлетворяющий размеры;

  • Наиболее подходящий (max) наименьший из удовлетворяющих:

  • Наименее подходящий (min)

Подготовка памяти для повторного использования:

а) простое восстановление памяти.

б) сложное восстановление памяти.

а) При простом восстановлении два блока так и

остаются,а при сложном они объединяются

б)

Кроме этих двух востановлений используются системы с самовостановления. К таким системам относятся:

-алгоритм близнецов;

-алгоритм фибоначчиевых близнецов.

Рассмотрим алгоритм близнецов.

К maxsize

1,2,4,8,16,...2, ...2 -объекты памяти.

Обозначим через А адрес блока.

к

Близнецами порядка к называются 2 блока размером 2 , расположенных рядом с

к

адресами 2 кратности.

Следствие : Адреса близнецов порядка К имеют специальную структуру:

А=старшие разряды х 00...0

к+1 разряд младшие к разрядов

адрес близ-

нецов.

Х: 0-младший близнец

1-старший близнец

Формула, по которой определяется адрес близнеца:

к

близнец к а=2 ХОR а

Служба памяти по методу близнецов

H1

голова списков

Body rep

sizebody

head

0

1 size

. =2

.

size

Рассмотрим программную реализацию этой системы.

Unit TWIN;

interfase

const

Null=32768;

maxsize=15;

sizekvant=2;

type

index=0..32768;

HeapBodyType=array[0 ..maxsize]of index;

BodyPtr=^HeapBodyType;

Heap=object

size:byte;

Head:array[0..maxsize]of index;

Body:Body Ptr

End;

Procedure Init(sizeheap:byte);

function Get_Mem(k:byte):Index;

procedure Free_Mem(a:index,k:byte);

procedure Done;

Implementation;

Procedure Init(sizeheap:byte);

var

bodysize:word;

i:byte;

begin

bodysize=(1shl sizeheap)*sizekvant;

Get_Mem(Body,Bodysize);

size:=sizeheap;

For i:=0 to size-1 do

heap[i]:=null;

heap^[size]:=0;

body^[0]:=null;

end;

Function Bliznuk(a:index;k:byte):index;

begin

Bliznuk:=(1 shl k)XOR a;

end;

Function Heap.Get_Mem;

var

z:index;

вegin

if Head[k]<>Null then

begin

z:=Head[k];

Head[k]:=Body^[z];

Get_Mem:=z;

end

else if k=size then

Get_mem:=Null

else

begin

z:=Get_Mem(k+1);

if z;Null then Get_Mem:=Null

else

Body^[z]:=Head[k];

Head[k]:=z;

Get_Mem:=Bliznuk(z,k);

end;

end;

end;

Procedure Free_Mem;

var

p:index;

G: index;

Q: index;

begin

if k=size then

begin

Head[size]:=0;

Body[0]:=Null;

end

else

begin

p:=Head[k];

g:=Bliznuk{a,k);

Body^[a]:=p;

Head[k]:=a;

q:=a;

while(p<>Null)and(p<>g) do

begin

q:=p;

p:=Body^[p];

end;

if p<=g then

begin

Body^[a]:=Body^[p];

Head[k]:=Body[a];

if a>g then

Free_Mem(g,k+1)

else

Free_Mem(a,k+1);

end;

end;

end;

end;

Соседние файлы в папке POSIBNIK