Скачиваний:
154
Добавлен:
08.07.2017
Размер:
4 Мб
Скачать
☆

17. Контроль семантической корректности программ

Из ответов

Методика Флойда, затем развита Хорром и Виртом. Первонач ориент на процедур ЯП…

Рассм­ся спецификация программы вида: {P} S {Q}, P, Q ­ логические формулы, описывающие взаимосвязь нач и заключит состояния памяти пр­мы, S ­ программа,. Читается так: если P истинно до начала вып­ния S, то Q ­ истинно после ее завершения.

P ­ предисловие, Q ­ постусловие.

Методика док­ва: Для пр­мы формулируют P и Q. Считая P ­ истинным, пытаются доказать истинность Q , последовательно применяя правила вывода. Если доказано, то программа семантически корректна. ​Правила вывода​для осн алгор конструкций:

​

x​

x​

​​

​ ​

1.Для операций присваивания: {Pe } x:=e {P} ; {Pe } – выражение, полученное из Р

 

​

​

подстановкой е вместо всех свободных вхождений Х в Р; вхождение свободно, если оно не связ с кванторами всеобщности и сущ­ния.

2. Цикл repeat…until: {P}S{Q},

{P} repeat S until B {QΛB} //рис см внизу

Док­во семантич корректности вручную даже для простых пр­м нетривиально. Прогр­х ср­в полностью решающих задачу нет. Возм только поддержка процесса аналитич док­ва => данная методика прим лишь для новых алг­мов и критич важных фрагментов программы.

Опр​Инварианты объектов​– набор логич условий, одн­но хар­щих правильный объект данного класса. Для корректной работы с объектами инвариант д. сохр­ся. Предусловия и постусловия ​­ условия, которые д.б. выполнены до начала выполнения метода и справедливы после его окончания. Конструктор созд­т объект,в том числе вып­ся инвариант. При работе метода инвариант м. изм­ся, но по окончании восст­ся. Нарушение условий – ИС. Проверки целесообр на этапах отладки и тестир, затем д.б. отключены.

В С++ сущ­т ​механизм подтверждений​­ проверка условий на этапе отладки: void assent (int expr) из <assert.h> ­ проверяет заданное выражение, в случае нарушения выдает станд диагностику (Nфайла,Nстроки) и вызывает abort.

// Факториал отрицательного числа не считается

​assert​(n >= ​0​)​;

Сигналы​­ (signal.h) – Механизм для контроля асинхр событий, аппаратно зависим. Сигналы м.б. аппаратными, в т.ч. генерируемые микропроцессорами, и программными.

Для программной генерации: int raise(int sig). Для установки реакции на возбужденный сигнал исп­ся ф­ция signal(SIGABRT,my_abort)­связывает тип сигнала с его обработчиком void my_abort(int SIG)

18. Типы классов: конкретный, абстрактный, узловой, интерфейсный

ТИПЫ КЛАССОВ

 

●​Конкретный

­ определяет конкретное понятие из предметной

области системы.

 

Примеры– комплексные числа, символы нац алфавита, односвязный список, контейнеры STL, встроен типы в ЯП (квадрат).

Свойства:

▪Точно соответствует описываемому понятию ▪Обеспечивает эффективную реализацию

▪Минимально зависит от других классов и в этом смысле являются изолированным

▪Не предназначен для использования в качестве базового (нерекомендуется использовать в качестве родителя)

▪Как правило не имеет вирт. функций ▪Может порождать объекты.

Повторное их исп­ние обеспеч за счет агрегирования, а не наслед.

Недостатки наследования при реализации конкретных типов:

▪менее эф­ные методы при наслед (вызов вирт функции медленнее, чем обычной; вирт функции нельзя сделать inline)

▪Исп­ние динамич памяти. Прим вирт функции требует работы через указатели или ссылки и динамич памяти для хранения об­тов, т.к. их размер разный. В рез­те в программе резко сокращ число истинных локал перемнных.

▪Неудобство для прогр­та, т.к. увелич уровень косвенности.

▪При наслед отн­но снижается инкапсуляция.Вирт ф­ции м. замещать, а защищенными полями м. манипулировать из наследуемых классов.

●​Абстрактный ​­ абстракция группы родственных понятий (список, множество) // класс, в котором выделены свойства подкласов

Свойства:

▪Определяет понятие так чтобы были возможны несколько реализаций ▪Опр­т общий интерфейс ▪Как правило не имеет членов­данных, т.к. они ограничивают возможности послед реализации

▪Предназ для исп­ния в кач­ве базового ▪Имеет виртуальные функции ▪Не имеет конструкторов, т.к. нет полей ▪Есть виртуальный деструктор ▪Не для порождения объекты

Если класс содержит хотя бы одну чистую виртуальную функцию, то о нем говорят как об абстрактном классе (abstract class). Поскольку в абстрактном классе содержится, по крайней мере, одна функция, у которой отсутствует

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

●​Узловой​­ расширяет интерфейс абстрактного базового ( //интерфейс­­ виртуальные функции). Может порождать объекты и предназначен для исп­ния в кач­ве базового.

Например: Фигура <|­­­­ Четырехугольник <|­­­­ Квадрат, в этом случае Четырехугольк являеся узлом

Свойства:

▪Исп­т свои базовые классы для реализации части своих возможностей ▪Имеют большое число открытых методов ▪Имеет нетривиал конструкторы. 2 вида:

1.​Абстрактный узловой­ не может порождать объекты 2.​Конкретный узловой­ не предназначен для использования в качестве

базового.

пример для понимания​:

Типичный узловой класс не только предоставляет реализацию интерфейса, задаваемого его базовым классом (как это делает класс реализации по отношению к абстрактному типу), но и сам расширяет интерфейс, добавляя новые функции. Рассмотрим в качестве примера класс dialog_box, который представляет окно некоторого вида на экране. В этом окне появляются вопросы пользователю и в нем он задает свой ответ с помощью нажатия клавиши или "мыши":

​class​dialog_box : ​public​window { // ...

​public​:

dialog_box(​const​​char​* ...); // заканчивающийся

нулем список

// обозначений

клавиш

// ...

​virtual​​int​ask(); };

Здесь важную роль играет функция ask() и конструктор, с помощью которого программист указывает используемые клавиши и задает их числовые значения

●​Интерфейсный​­ используется для упорядочения интерфейса, устранение конфликта имён, реализуется без потери эффективности, может применяться для защиты потенц­но опасных классов.

class​​MyInterface​{ ​public​: ​// Empty virtual destructor for proper cleanup virtual​~​MyInterface​() {} ​virtual​​void​​Method1​() = ​0​; ​virtual​​void​​Method2​() = ​0​; }; //Интерфейс, в нем не определенны виртуальные функции

class​​MyAbstractClass​{ ​public​: ​virtual​~​MyAbstractClass​(); ​virtual​​void Method1​(); ​virtual​​void​​Method2​(); ​void​​Method3​(); ​virtual​​void​​Method4​() = 0​; ​// make MyAbstractClass not instantiable​}; //Абстрактный класс, в нем

определенны виртуальные функции

Множественные интерфейсы​– многократн исп­ние абстрактных типов в комб с конкретными для получения разл интерфейсов.

Насыщенные интерфейсы​­ объединение в базовом классе полезных функций потомков; возникают когда конкретные типы делаются производными от абстрактных. Плохое решение, если не все потомки поддерживают интерфейс. Характерны для языков с единичным наследованием..

Фабрики классов​­ класс с виртуальной функцией для создания объектов другого класса. Такая функция наз. "Виртуальный конструктор".

class X

{

public :

virtual X* clone() {return new X(*this)}; virtual X *newX() {return new X();}

}

http://stackoverflow.com/questions/12854778/abstract­class­vs­interface­in­c

Сериализация ­ процесс вывода полиморфных объектов (например, контейнер). Проблема с вводом – в С++ единств способ создать объект – вызвать его конструктор => где­то д.б. описан ​процесс перевода какой­либо

структуры данных​в последовательность ​битов​. Обратной к операции сериализации является операция ​десериализации​(структуризации) — восстановление начального состояния структуры данных из битовой последовательности.

Сериализация используется для передачи ​объектов​по сети и для сохранения их в ​файлы​.

Например, нужно создать распределённое ​приложение​, разные части которого должны

обмениваться данными со сложной структурой. В таком случае для типов данных, которые

предполагается передавать, пишется код, который осуществляет сериализацию и

десериализацию. Объект заполняется нужными ​данными​, затем вызывается код

сериализации, в результате получается, например, ​XML​­документ.

Многие объекты, в т.ч. и контейнеры, м. разделить на 2 части: дескриптор и представление.

Дескриптор​­ управляющая часть, которая контролирует доступ, распределяет память, управляет блокировкой и тд.

Представление​­ информационная часть, которая хранит состояние объекта. Для работы с такими объектами достаточно передавать дескр­р и работать с об­тами через него (т.е. это расширение понятия указателя). Если дескриптор поддерж­т все или почти все метода представления, то он наз­ся “заместитель” (или прокси).

При работе через дескрипторы возникает проблема определения момента представления в том случае если дескрипторов в программе несколько. Для ее решения исп­т обобщенный дескриптор. Следует считать случаи копирования дескриптора и удалять представления только когда будет удален последний дескриптор.

19. Библиотеки контейнерных классов

1.​Объектная библ­ка контейнеров (OBCL) Св­ва:

▪Все объекты, к­рые помещ в контейнеры, д.б. произв от общего абстракт класса object. Такие контейнеры – интрузивные (навязчивые)

▪В классе польз­ля д.б. переопр­ны чистые виртуал ф­ции: isA, nameof, isequal,printion. ▪От object производ­мы явл и сами контейнеры. В рез­те в контейнере м храниться др контейнеры. Контейнеры имеют 1 внешний итератор, к­рый прим ко всем объектам в контейнере рекурсивно + один внутр аппликатор foreach.

▪Класс object имеет вложенный класс TShouldDelete для управления статусом владения. По умолч все контейнеры обладают своими объектами, поэтому в них нельзя размещать локал статич объекты. С пом спец метода их можно лишить статуса владения.

2.​Биб­ка шаблонов контейнеров (BIDC) вкл­т шаблоны контейнеров и итераторов, исп­т наследование, контейнеры неинтрузивные. Св­ва:

1)​все контейнеры делятся на 2 группы:

▪низкого уровня (векторы, списки, дерево двоич поиска); ▪верхнего (массив, мн­во, очередь, стек, словарь); 2)​Контейнеры м.б.:

▪прямыми (они никогда не владеют своими объектами, хранят копии, не м.б. полиморфными);

▪косвенные (по умолч владеют объектами, классы насл­ся от TShouldDelete); 3)​по способу упр­ния порядком хранения объектов:

▪простые (не переразмещают объекты);

▪счетные (операция add добавл объект в 1ое свободное место, а после удаления контейнеры переупак­ся);

▪упорядоченные (после каждого add/delete сортируются); 4)​по способу упр­ния памятью:

▪с управлением (м. исп­ть аллокатор поль­ля ); ▪без упр­ния – исп­ся стандарт аллокатор.

Аллокатор­­ это объект, который управляет расположением элементов контейнера в памяти.

3.​Стандартная библ шаблонов (STL) содержит шаблоны контейнеров и итераторов, но ее нельзя отнести к ОО библиотекам. Контейнеры не имеют виртуал ф­ций и не предназнач для дальнейшего наследования. Сделано в целях эффективной реализации, но слабо годится для расширения.

2 способа расширения:

1)агрегирование станд контейнеров;

2)оборачивание контейнера с пом дескриптора с ОО св­вами и постр на этой основе своей иерархии классов.

3 категории контейнеров:

контейнеры последовательностей (vector, list, deque),

ассоциативные (set,multiset,map.multimap) //обращение к объектам по ключу (1­­Баканов)

и адаптеры контейнеров (stack, queue, priority_queue).

Алгоритмы работают с контейнерами через итераторы. Можно исп­ть функции объекты в алг­мах: предикаты, арифм операторы, связыватели,

http://samoychiteli.ru/document26299.html

Численный метод​. В эту библ­ку входит один контейнер – численный массив. С ним м. работать через срез. Фактически срез выделяет каждый Эл­т в массиве. 2ой способ работы – через маску. Маска наклад на массив значение 0 и 1: 1­эл­т массива попадает в рассм­ние, 0­нет. (// по маске выбираем элемнты массива: 1­­ выбираю, 0­­ не выбираю). Косвенный массив – хранит индексы эл­тов массива, с к­рым будет вып­ся работа.

Обобщенные численные алг­мы служат для накопления рез­тов под посл­тями эл­тов в массиве.

Интрузивный (навязчивый) контейнер ­ требует от объектов размещенных в контейнере, чтобы они обладали определенными свойствами (например, были наследниками заданного класса).

20. Численные методы еще можно почитать в 22 главе страуструпа

Обобщенные численные алгоритмы

Для использования численных алгоритмов требуется подключить заголовочный файл

<numeric>.​

Обобщенные численные алгоритмы

Алгоритм

Выполняемая функция

 

 

accumulate

Накопление

 

 

inner_product

Скалярное произведение

 

 

partial_sum

Расчет суммы с накоплением

 

 

adjacent_difference

Вычисление разности между смежными элементами

 

 

accumulate

Первая форма алгоритма ​accumulate​используется для накопления суммы элементов последовательности, заданной итераторами ​first​и ​last.​Начальное значение суммы (обычно это 0) задается третьим параметром. Тип этого параметра определяет тип результата (функция возвращает вычисленную сумму):

template <class In, class T>

T accumulate(In first, In last, T init)

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

template <class In, class T, class BinOp>

T accumulate(In first, In last, T init, BinOp binary_op)

В приведенном далее примере вычисляется сумма, произведение и сумма квадратов элементов массива:

#include <iostream> #include <numeric> #include <functional> using namespace std;

int sumkv( int s, int x){ return s+x*x;} int main(){

const int m=5;

int a[m]={3,2,5,1,6}, sum=0,mul=1,sum2=0; cout<< accumulate(a,a+m,sum)<<endl;

cout<< accumulate(a,a+m,mul,multiplies<int>())<<endl; cout<< accumulate(a,a+m,sum2,sumkv)<<endl;

return 0;

}

inner_product

Первая форма алгоритма ​inner_product​используется для вычисления скалярного произведения двух последовательностей (скалярным произведением

последовательностей ​а​и ​b​является выражение ​∑ai*bi)​. Начальное значение произведения задается четвертым параметром. Тип этого параметра определяет тип результата (функция возвращает вычисленное произведение):

template t<class Inl. class Iп2. class Т>

Т inner_product(Inl firstl, Inl lastl, In2 first2, T init);

Вторая форма алгоритма ​inner_product​используется для выполнения над двумя последовательностями действий, заданных с помощью двух функций или функциональных объектов. Первый используется вместо операции сложения, второй ­ вместо умножения:

template t<class In1, class In2, class T, class BinOp1, class BinOp2> T inner_product(In1 first1, In1 last1, In2 first2, T init, BinOp1

binary_op1, BinOp2 binary_op2);

Следующий вызов вычисляет произведение сумм соответствующих элементов последовательностей ​а​и ​b:​

cout<<inner__product(a, а + m, b, mul, multiplies<int>(), plus<int>());

partial_sum

Алгоритм ​partial_sumформирует последовательности из частичных сумм элементов. Например, для последовательности чисел 3 1 2 3 5 результатом будет 3 4 6 9 14, то есть каждый элемент результата равен предыдущему элементу, увеличенному на текущий элемент исходной последовательности.

Вместо суммы четвертым параметром можно задать другую операцию. Результат можно поместить и в исходную последовательность, для этого третьим параметром указывается итератор на ее начало. Функция возвращает итератор на элемент, следующий за концом результирующей последовательности.

template t<class In, class Out>

Out partial_sum(In first, In last, Out result); template t<class In. class Out. class BinOp>

Out partial_sum(In first, In last, Out result, BinOp binary_op);

adjacent_difference

Алгоритм ​adjacent_difference выполняет вычисление разности между смежными

элементами, то есть ​d​=a​–a​ . Вместо разности четвертым параметром можно задать i​i​ i­1​

другую операцию. Функция возвращает итератор на элемент, следующий за концом результирующей последовательности.

template t<class In, class Out>

Out partial_sum(In first, In last, Out result); template t<class In. class Out. class BinOp>

Out partial_sum(In first, In last, Out result, BinOp binary_op);

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