
- •Лекции по
- •(Те что я нашел)
- •Информация и данные.
- •Анализ программ, не содержащих ветвлений
- •Если p{ а }q и q{ b }r, то выполняется p{ a;b }r.
- •Проектирование цикла с помощью инварианта Задача 1. Найти сумму величин 1/iот 1 до тех пор, пока она не станет больше некоторого наперед заданного числаa.
- •Будем искать решение нашей задачи в виде цикла, имеющего следующий вид:
- •Линейные структуры данных.
- •Операции над линейной структурой данных
- •Виды линейных структур данных.
- •4)Стек на базе массива
- •Тема: Анализ создаваемых абстракций
- •Полнота
- •Аназиз типов данных
- •Операции egual, similar и copy
- •Функция абстракции
- •Функция абстракции есть
4)Стек на базе массива
size bodyTopInd
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 0sizeStask65535 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).
Функция инвариант представления:
1size65535divsizeof(T) & 0TopIndsize&PBody^[TopInd] - элемент в вершине стека.Pbodyуказывает на вектор памяти размеромsizesizeof(T)}
Procedure Create;
BEGIN
if sizeStasksizeof(T)>65536 then halt(1);
GetMem(S.Pbody,sizeStasksizeof(T));
S.TopInd: =0;
S.Size: =sizeStask;
END;
Procedure Push;
BEGIN
inc(S.TopInd);
S.Pbody^[S.TopInd]: =X;
END
СПЕЦИФИКАЦИИ
Существуют системы, в которых спецификации являются частью языка программирования.
Этапы создания программного обеспечения:
изучение
проектирование
кодирование
тестирование
отладка
использование
сопровождение
Спецификация содержит описание того общего, что содержится в программе (во множестве реализаций)
Спецификация - это текст, который обладает некоторыми свойствами.
Значение спецификации.
Главное назначение спецификации: отделение правильных реализаций от неправильных. Значениями спецификаций являются всевозможные правильные реализации
Программа
набор всех вычислений по этой программе;
конкретный вычислительный процесс по этой программе;
Спецификация
набор всех операций
конкретный вычислительный процесс
Создание спецификаций
Критерии, применяемые к спецификациям:
Ограниченность
Ошибки:
неполное задание ограничений в предложении requires
Неполный список исключительных ситуаций
Обобщенность
Стили написания спецификаций
Дефинитивный стиль
Операционный стиль
Дефиниционный стиль не задает программисту метод реализации абстракции, но описывает свойства.
Операционный указывает как достичь определенных свойств
Свойства спецификаций как текста
Полнота
Понимаемость
Факторы:
краткость
избыточность
структурированность
Нужно писать краткие, но полные спецификации.
Один, из главных эффектов спецификации - это более глубокое понимание смысла.
Этапы написания программы
Разработчику абстракции надо указать, что делать
Пользователю абстракции не на то, чем на спецификацию
При тестировании спецификации помогают генерировать тестовые данные, помогают создавать заглушки (приближенные модели программы)
На этапе компоновки позволяет сократить число проблем с интерфейсами за счет сокращения числа неявных предположений об этих интерфейсах
При отладке позволяет выявить местонахождение ошибок, позволяет избежать новых ошибок при исправлении.
В процессе сопровождения спецификации выступают как часть документации на программу и помагают различать вопросы что сделано в программе от того как это сделано.
Модификации программ
с изменением спецификации
без изменения спецификации
Кроме спецификаций иногда необходимо указывать принципы работы программы.
ИТЕРАТОРЫ
Итератор - абстракция, скрывающая подробности перебора элементов какой-то структуры данных.
Итератор осуществляет перебор компонентов множественного набора данных, удобным и эффективным способом и при этом не нарушает абстракцию через спецификацию.
Итератор выдает результаты не все целиком, а поочередно.
Итератор используется в следующих конструкциях:
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
Кроме понятия кванта памяти при работе с памятью используются такие понятия как :
Звено памяти -несколько подряд расположенных квантов, которые интерпре-
тируются по-разному.
Вектор памяти- несколько расположенных подряд квантов и интерпрети-
руются одинаково.
При распределении памяти возникает проблема: отыскивание очередной порции памяти, подходящей для размещения в ней звена (кванта памяти) называется Управлением памятью
Внутри программы формируется последовательность заявок выделение памяти. По каждой заявке служба памяти должна выделить память.
Служба памяти должна уметь:
Инициализировать себя.
Выделить память.
Освободить память.
Закончить работу.
Для различных структур данных необходима память различных размеров. Память распределяется и освобождается блоками.
Блок- участок памяти ,в котором существует служебные поля, которые
используются службой памяти.
блок
В зависимости от того, какого блок размера различают:
блоки фиксированной длины;
блоки переменной длины;
Компрессия- очень опасная операция. Заключается в том, что на освободившиеся области накладываются занятые области и все изменения записываются в файл.
Блоки переменной длины:
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;