Главная страница Случайная страница КАТЕГОРИИ: АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
Ход работы. Диаграммы деятельности.Унифицированный язык моделирования (UML) является стандартным инструментом для создания «чертежей» программного обеспечения
Диаграммы деятельности. Унифицированный язык моделирования (UML) является стандартным инструментом для создания «чертежей» программного обеспечения. С помощью UML можно визуализировать, специфицировать, конструировать и документировать артефакты программных систем. UML пригоден для моделирования любых систем: от информационных систем масштаба предприятия до распределенных Web-приложений и даже встроенных систем реального времени. Это очень выразительный язык, позволяющий рассмотреть систему со всех точек зрения, имеющих отношение к ее разработке и последующему развертыванию. Несмотря на обилие выразительных возможностей, этот язык прост для понимания и использования. Диаграммы деятельности - это один из пяти видов диаграмм, применяемых в UML для моделирования динамических аспектов поведения системы. Диаграмма деятельности - это, по существу, блок-схема, которая показывает, как поток управления переходит от одной деятельности к другой, однако, по сравнению с последней, у ней есть явные преимущества: поддержка многопоточности и объектно-ориентированного проектирования. Диаграмма деятельности (Activity diagram) показывает поток переходов от одной деятельности к другой. Деятельность (Activity) - это продолжающийся во времени неатомарный шаг вычислений в автомате. Деятельности в конечном счете приводят к выполнению некоего действия (Action), составленного из выполняемых атомарных вычислений, каждое из которых либо изменяет состояние системы, либо возвращает какое-то значение. Действие может заключаться в вызове другой операции, посылке сигнала, создании или уничтожении объекта либо в простом вычислении - скажем, значения выражения. Графически диаграмма деятельности представляется в виде графа, имеющего вершины и ребра. Состояние действия и состояние деятельности. В потоке управления, моделируемом диаграммой деятельности, происходят различные события. Вы можете вычислить выражение, в результате чего изменяется значение некоторого атрибута или возвращается некоторое значение. Также, например, можно выполнить операцию над объектом, послать ему сигнал или даже создать его или уничтожить. Все эти выполняемые атомарные вычисления называются состояниями действия, поскольку каждое из них есть состояние системы, представляющее собой выполнение некоторого действия. Как показано на рис. 2.1, состояния действия изображаются прямоугольниками с закругленными краями. Внутри такого символа можно записывать произвольное выражение.
Рисунок 2.1 - Состояния действия и комментарий: а) простое действие; б) выражение; в) комментарий
Состояния действия не могут быть подвергнуты декомпозиции. Кроме того, они атомарны. Это значит, что внутри них могут происходить различные события, но выполняемая в состоянии действия работа не может быть прервана. Обычно предполагается, что длительность одного состояния действия занимает неощутимо малое время. В противоположность этому состояния деятельности могут быть подвергнуты дальнейшей декомпозиции, вследствие чего выполняемую деятельность можно представить с помощью других диаграмм деятельности. Состояния деятельности не являются атомарными, то есть могут быть прерваны. Предполагается, что для их завершения требуется заметное время. Можно считать, что состояние действия - это частный вид состояния деятельности, а конкретнее - такое состояние, которое не может быть подвергнуто дальнейшей декомпозиции. А состояние деятельности можно представлять себе как составное состояние, поток управления которого включает только другие состояния деятельности и действий. Переходы. Когда действие или деятельность в некотором состоянии завершается, поток управления сразу переходит в следующее состояние действия или деятельности. Для описания этого потока используются переходы, показывающие путь из одного состояния действия или деятельности в другое. В UML переход представляется простой линией со стрелкой, как показано на рис. 2.2.
Рисунок 2.2 - Нетриггерные переходы
Поток управления должен где-то начинаться и заканчиваться (разумеется, если это не бесконечный поток, у которого есть начало, но нет конца). Как показано на рисунке, вы можете задать как начальное состояние (закрашенный кружок), так и конечное (закрашенный кружок внутри окружности). Ветвление. Простые последовательные переходы встречаются наиболее часто, но их одних недостаточно для моделирования любого потока управления. Как и в блок-схеме, вы можете включить в модель ветвление, которое описывает различные пути выполнения в зависимости от значения некоторого булевского выражения. Как видно из рис. 2.3, точка ветвления представляется ромбом. В точку ветвления может входить ровно один переход, а выходить - два или более. Для каждого исходящего перехода задается булевское выражение, которое вычисляется только один раз при входе в точку ветвления. Ни для каких двух исходящих переходов эти сторожевые условия не должны одновременно принимать значение «истина», иначе поток управления окажется неоднозначным. Но эти условия должны покрывать все возможные варианты, иначе поток остановится. Для удобства разрешается использовать ключевое слово else для пометки того из исходящих переходов, который должен быть выбран в случае, если условия, заданные для всех остальных переходов, не выполнены. Реализовать итерацию можно, если ввести два состояния действия - в первом устанавливается значение счетчика, во втором оно увеличивается - и точку ветвления, вычисление в которой показывает, следует ли прекратить итерации.
Рисунок 2.3 - Ветвление
Алгоритм разветвляющейся структуры - это алгоритм, в котором вычислительный процесс осуществляется либо по одной, либо по другой ветви, в зависимости от выполнения некоторого условия. Программа разветвляющейся структуры реализует такой алгоритм. В программе разветвляющейся структуры имеется один или несколько условных операторов. Для программной реализации условия используется логическое выражение. В сложных структурах с большим числом ветвей применяют оператор выбора. Любое выражение, завершающееся точкой с занятой, рассматривается как оператор, выполнение которого заключается в вычислении выражения. Частным случаем выражения является пустой оператор; (он используется, когда но синтаксису оператор требуется, а по смыслу - нет). Примеры:
i++; // выполняется операция инкремента а* = b + с; // выполняется умножение с присваиванием fun(i, k); // выполняется вызов функции
Логическоевыражение - некоторое утверждение, относительно которого можно сказать: истинно оно или ложно. В языке C++ любое выражение, равное нулю считается ложным, тогда как любое выражение не равное нулю будет истинным. В Си++ используются шесть операторов отношения (табл. 2.1), позволяющих сравнивать между собой значения числовых переменных, а также значение переменной и константы. Условия, которые составлены с использованием одного оператора сравнения, называются простыми условиями. Общий вид:
< выражение> < оператор_сравнения> < выражение>
Из простых условий, которые являются выражениями логического типа можно строить составные условия. В этом случае простые условия необходимо связывать при помощи логических операций:! (не), & & (и), ||(или). Таблица 2.1 - Операторы отношения в языке C++
Операция логического И (& &). Логическая операция И используется в том случае, когда требуется одновременность выполнения двух условий, входящих в данную операцию. В языке C++ данное выражение может быть представлено следующим образом < условие 1> & & < условие 2> На практике эта логическая операция часто применяется для создания условия, что некоторая переменная принадлежит указанному промежутку. Например, составим условие, которое будет истинно тогда и только тогда, когда переменная х принадлежит промежутку от 10 до 20: 10 < x < 20. Это произойдёт только в том случае, когда х > 10 и x < 20. На языке C++ это записывается так:
x > 10 & & x < 20 Операция логического ИЛИ (||). Логическая операция ИЛИ используется только в том случае, когда требуется выполнение хотя бы одного из условий, входящих в данную операцию. В языке C++ данное выражение может быть представлено следующим образом:
< условие 1> || < условие 2>
На практике эта логическая операция часто применяется для создания условия, что некоторая переменная принимает одно из допустимых значений. Например, составим условие, которое истинно тогда и только тогда, когда x принимает фиксированные значения: 1, 2; 2, 3; 3, 4. Это произойдет только в том случае, когда x = 1, 2 или x = 2, 3 или x = 3, 4. На языке C++ это запишется как
x == 1.2 || x == 2.3 || x == 3.4 Операция логического НЕ (!). Операция НЕ принимает значение истина, если ее операнд принимает значение ложь, и наоборот, результатом операции НЕ будет ложь, если ее операнд принимает значение истина. В языке C++ данное выражение может быть представлено следующим образом:
! < условие>
На практике операция НЕ применяется для отрицания какого-либо факта. Все логические операции (за исключением операции логического НЕ) имеют приоритет ниже операций отношения, поэтому обрамлять скобками простые условия на основе операторов отношения не обязательно. Примеры:
if (a< 0) b = 1; // 1 if (a< b & & (a> d||a==0)) b++; else { b*=a; a=0; } // 2 if (a< b) { if (a< c) m = a; else m = c; } else { if (b< c) m = b; else m = c; } // 3 if (a++) b++; // 4 if (b> a) max = b; else max = a; // 5 В примере 1 отсутствует ветвь else. Подобная конструкция называется «пропуск оператора», поскольку присваивание либо выполняется, либо пропускается в зависимости от выполнения условия. Если требуется проверить несколько условий, их объединяют знаками логических операций. Например, выражение в примере 2 будет истинно в том случае, если выполнится одновременно условие a< b и одно из условий в скобках. Если опустить внутренние скобки, будет выполнено сначала логическое И, а потом - ИЛИ. Оператор в примере 3 вычисляет наименьшее значение из трех переменных. Фигурные скобки в данном случае не обязательны, так как компилятор относит часть else к ближайшему if. Пример 4 напоминает о том, что хотя в качестве выражений в операторе if чаще всего используются операции отношения, это не обязательно. Конструкции, подобные оператору в примере 5, проще и нагляднее записывать в виде условной операции (в данном случае: max=(b> a)? b: a;). Условный оператор. Условный оператор if используется для разветвления процесса вычислений на два направления. true false false
Рисунок 2.4 - Структурная схема условного оператора
Сначала вычисляется выражение, которое может иметь арифметический тип или тип указателя. Если оно не равно нулю (имеет значение true), выполняется первый оператор, иначе - второй. После этого управление передается на оператор, следующий за условным. Одна из ветвей может отсутствовать, логичнее опускать вторую ветвь вместе с ключевым словом else. Если в какой-либо ветви требуется выполнить несколько операторов, их необходимо заключить в блок, иначе компилятор не сможет понять, где заканчивается ветвление. Блок может содержать любые операторы, в том числе описания и другие условные операторы (но не может состоять из одних описаний). Необходимо учитывать, что переменная, описанная в блоке, вне блока не существует. Условный оператор в языке C++ имеет формат:
if(< Условие>) < Оператор>;
его действие можно описать с помощью фрагмента UML-диаграммы деятельности, изображенного на рис. 2.5 а:
Рисунок 2.5 - Фрагмент диаграммы деятельности UML, описывающей действия оператора if в языке C++: а) без альтернативной ветви else; б) с альтернативной ветвью else
Если помимо тех действий, которые требуется выполнить, когда заданное условие истинно, требуется исполнить и ряд действий, когда заданное условие ложно, то применяют следующую форму условного оператора:
if(< Условие>) < Оператор_1>; else < Оператор_2>;
его действие можно описать с помощью фрагмента блок-схемы алгоритма, изображенного на рис. 2.5 б. Иными словами, если «условие» принимает значение «истина», то выполняется «оператор1», и если «условие» принимает значение «ложь», то выполняется «оператор2». Например, для оператора if без альтернативной ветви else можно привести следующий фрагмент кода: // Условный оператор if(temperature > = 0) cout < < " Выше точки замерзания! \n"; // Действия, не относящиеся к условному оператору cout < < " Температура " < < temperature < < endl; тогда как для оператора if-else можно привести следующий пример:
// Условный оператор if(x < у) min = х; else min = у; // Действия, не относящиеся к условному оператору cout < < " min = " < < min;
Последний пример может быть прокомментирован следующим образом. Если условие x < у истинно, то переменной min будет присвоено значение х, если оно ложно, то min будет присвоено значение у. После выполнения инструкции if-else будет напечатано значение min. Оба оператора < Оператор_1> и < Оператор_2> могут представлять простые операторы (один оператор), в этом случае они не заключаются в фигурные скобки. Если же < Оператор_1> и/или < Оператор_2> представляют составной оператор (несколько операторов), то их нужно заключить в фигурные скобки. { Оператор_1; Оператор_2; ... Оператор_n; }
Каждый оператор внутри скобок должен заканчиваться точкой с запятой. Структура называется вложенной, если после < условия> или служебного слова else используются вновь условные операторы. Число вложений может быть произвольным. При этом справедливо следующее правило: служебное слово else всегда относится к ближайшему выше < условию>.
Пример 2.1. Составить UML-диаграмму деятельности и программу с использованием конструкции ветвления для вычисления значения функции:
Составим UML-диаграмму деятельности вычисления значения функции (рис. 2.6).
Рисунок 2.6 - UML-диаграмма деятельности для задачи расчета значения функции
По составленной диаграмме может быть написана программа вычисления значения функции.
|