Защо ни е това
Досега писахме програми направо в редактора. За малка задача става, но щом задачата порасне, кодът се обърква преди да си стигнал до средата. Затова процесът първо се рисува, а после се кодира.
Ключово
Изчислителният процес се описва графично с UML диаграма. Според това дали редът на операторите се променя, процесът е линеен, разклонен или цикличен.
Езикът UML
UML (Unified Modeling Language)
Унифициран език за моделиране — графичен език за специфициране и документиране на компонентите на софтуерна система. Създаден е през 1997 г. и се поддържа от Object Management Group (OMG), група от големи компании, разработващи софтуер.
Елементът, в който се извършва всяко моделиране, е диаграмата. Тя се рисува като правоъгълник, в който влизат всички елементи на модела. В горния ляв ъгъл има поле със „срязан“ долен десен ъгъл — там се записва името на моделирания обект или процес.
Езикът е много силно развит. В този урок ще вземем от него само това, което ни трябва, за да опишем изчислителен процес.
Бележка
В зората на програмирането за същото се е използвал блок-схемният език. Днес той е позагубил практическото си значение, но идеята е същата: графиката позволява разклоненията и зацикляннията да се проследят много по-лесно, отколкото в текст.
Блоковете на диаграмата
Съставните елементи на UML диаграмата са блокове и стрелки, свързващи блоковете според логиката на процеса. Всеки блок определя действие; когато действието е изпълнено, работата продължава с блока, до който води излизащата стрелка.
| Блок | Форма | Стрелки |
|---|---|---|
| Начало | Черен кръг | Не влизат стрелки, излиза точно една. Среща се еднократно в диаграмата. |
| Край | Черен кръг в окръжност | Може да влизат няколко, не излиза нито една. Може да има няколко такива блока, но поне един е задължителен. |
| Обработващ блок | Правоъгълник със заоблени краища | Произволен брой влизащи, точно една излизаща. Вътре се описват операции с данните — но не проверки. |
| Проверка на условие | Ромб | Произволен брой влизащи, точно две излизащи — надписани с ДА и НЕ. |
| Свързващ блок | Кръгче с номер | Идва по двойки с един и същ номер. Служи да се разкъса прекалено дълга стрелка или стрелка към блок на друга страница. |
Трите вида изчислителни процеси
Инструкциите на машинния език се делят на такива за извършване на операции (изпълняват се една след друга по реда, в който се срещат) и инструкции за преход (променят този ред). Същото разделение има и сред операторите на езика за програмиране. Оттам идват и трите вида процеси:
| Вид процес | Какво става с реда на операторите | Пример |
|---|---|---|
| Линеен | Не се променя — операторите се изпълняват отгоре надолу | Въведи страните, пресметни лицето, изведи го |
| Разклонен | Процесът се разлага на няколко самостоятелни клона според входните данни | Ако числото е отрицателно — едно, иначе — друго |
| Цикличен | Изпълнението се връща към вече изпълнени оператори — понякога милиони пъти | Сумиране на n числа |
Бележка
Всеки клон на разклонен процес може сам да се разклони на няколко независими клона, и така нататък. Тези три вида са градивните блокове, от които се сглобява всяка програма.
Как да не пишем един и същ код по два пъти
Големите количества код се пишат трудно, проверяват се трудно и се поддържат още по-трудно. Ако в програмата има еднотипни действия, които се срещат многократно, и най-малката промяна в тях налага да се намерят всички места в кода. Пропуснеш ли едно — кодът е неработоспособен.
- Цикъл — когато едно и също множество от оператори трябва да се изпълни многократно върху различни данни и между двете обработки не се налага да се изпълнява нищо друго.
- Подпрограма (процедура, модул) — когато между всеки две повторения трябва да се вършат и други действия. В C# обособените програмни части се наричат функции при процедурен стил и методи при обектно-ориентиран. Промяната се прави еднократно — в тялото на подпрограмата.
- Библиотека — колекция от готови стандартни подпрограми с близко предназначение. Включва се с оператора
usingв началото на програмата.
Методът Parse
Console.ReadLine() връща низ. За да смятаме с въведеното, низът трябва да се превърне в число. За целта всеки числов тип има метод Parse:
int i = int.Parse(Console.ReadLine());
long l = long.Parse(Console.ReadLine());
double x = double.Parse(Console.ReadLine());Сега вече програмата може да обработва всевъзможни данни, а не само тези, които сме записали в текста ѝ.
Внимание
Parse иска типът да пасне на въведеното. Ако подадеш abc на int.Parse, програмата спира с грешка. По-нататък ще видиш как това се хваща.
Класът Math
Класът Math предлага голям брой методи за пресмятане на математически функции. Аргументите могат да са константи или променливи. Ето най-често използваните:
| Метод | Какво връща | Пример |
|---|---|---|
Math.Abs(x) | Абсолютната стойност | Math.Abs(-7) е 7 |
Math.Ceiling(x) | Най-близката цяла стойност, по-голяма или равна на аргумента | Math.Ceiling(3.14) е 4 |
Math.Floor(x) | Най-близката цяла стойност, по-малка или равна на аргумента | Math.Floor(3.14) е 3 |
Math.Max(x, y) | По-голямата от двете стойности | Math.Max(4, 9) е 9 |
Math.Min(x, y) | По-малката от двете стойности | Math.Min(4, 9) е 4 |
Math.Sqrt(x) | Квадратния корен (аргументът е от тип double) | Math.Sqrt(16) е 4 |
Подходът отгоре надолу
При проектирането на програма програмистът има две възможности:
- Отдолу нагоре — започваш с най-елементарните части и постепенно ги свързваш в по-сложни, докато стигнеш крайната цел.
- Отгоре надолу — започваш с маркиране на крайните елементи на програмата, без те да са изградени напълно, и постепенно детайлизираш всеки от сложните елементи, представяйки го чрез по-прости.
И двата подхода са приложими, но често се предпочита отгоре надолу: при него програмата във всеки момент има някакви работоспособни части и може да бъде демонстрирана пред потенциални потребители.
На практика това значи, че първата диаграма е съвсем груба — четири блока: „Деклариране на променливи“, „Въвеждане на данните“, „Обработка на данните“, „Извеждане на резултати“. После всеки блок се детайлизира.
Упражнения
Задача 1. Въведи новата версия на програмата Types, компилирай я и я изпълни с различни данни, като се опиташ да предскажеш резултата според правилата за преобразуване на типове.
Задача 2. Напиши конзолно приложение, което по зададени на стандартния вход две цели стойности a и b намира и извежда периметъра и лицето на правоъгълник със страни a и b, като приложиш подхода отгоре надолу.
Задача 3. Напиши конзолно приложение, което по зададено лице S на квадрат намира и извежда периметъра му.
Какво трябва да запомниш
- В UML диаграмата обработващият блок има точно една излизаща стрелка, а блокът за проверка — точно две.
- Линейният процес не променя реда на операторите; разклоненият го разделя на клонове; цикличният връща изпълнението назад.
- Повторението на код се избягва с цикъл, с подпрограма или с готова библиотечна функция.
Console.ReadLine()дава низ — за смятане той се превръща в число сParse.- При подхода отгоре надолу програмата има работоспособни части във всеки момент от разработването.