Структурними називаються написані програми. Структурне програмування. Цілі та принципи структурного програмування

Структурне програмування- Це метод, що передбачає створення покращених програм. Він служить для організації проектування та кодування програм таким чином, щоб запобігти більшості логічних помилок та виявити ті, що допущені.

Використовуючи мову високого рівня (такі як Фортран) програмісти могли писати програми до кілька тисяч рядків завдовжки. Однак мова програмування, що легко розуміється в коротких програмах, коли справа стосується великих програм, стає нечитабельною (і некерованою). Позбавлення таких неструктурованих програм прийшло після створення в 1960 мов структурного програмування. До них відносяться мови Алгол, Паскаль та С.

Структурне програмування має на увазі точно позначені керуючі структури, програмні блоки, відсутність інструкцій GOTO, автономні підпрограми, в яких підтримується рекурсія та локальні змінні. Головним у структурному програмуванні є можливість розбиття програми на її елементи. Використовуючи структурне програмування, середній програміст може створювати та підтримувати програми понад 50 000 рядків завдовжки.

Структурне програмування тісно пов'язане такими поняттями як «низхідне проектування» та «модульне програмування».

Метод низхідного проектуванняпередбачає послідовне розкладання функції обробки даних на прості функціональні елементи ("зверху-вниз").

В результаті будується ієрархічна схема, що відображає склад і взаємопідпорядкованість окремих функцій, що зветься функціональна структура алгоритму(ФСА) програми.

Функціональна структура алгоритму програми розробляється в наступній послідовності:

1) визначаються цілі автоматизації предметної області та їх ієрархія;

2) встановлюється склад додатків (завдань обробки), що забезпечують реалізацію поставлених цілей;

3) уточнюється характер взаємозв'язку додатків та його основні характеристики (інформація на вирішення завдань, час і періодичність рішення та інших.);

4) визначаються необхідні вирішення завдань функції обробки данных;

5) виконується декомпозиція функцій обробки до необхідної структурної складності, що реалізується передбачуваним інструментарієм.

Подібна структура програми відображає найважливіше – склад та взаємозв'язок функцій обробки інформації для реалізації додатків, хоча й не розкриває логіку виконання кожної окремої функції, умови чи періодичність їх викликів.

Розкладання має носити суворо функціональнийхарактер, тобто. окремий елемент ФСА має описувати закінчену змістовну функціюобробки інформації, що передбачає певний спосіб реалізації на програмному рівні.


Модульне програмуваннязасноване на понятті модуля логічно взаємопов'язаної сукупності функціональних елементів, оформлених як окремих програмних модулів. Модульне програмування розглядається в розд 7.

Структурне програмуванняполягає у отриманні правильної програми з деяких простих логічних структур. Воно базується на суворо доведеній теоремі про структурування, яка стверджує, що будь-яку правильну програму (з одним входом, одним виходом, без зациклення та недосяжних команд) можна написати з використанням лише наступних основних логічних структур:

· Лінійної (слідування);

· Нелінійної (розвилка);

· Циклічною (цикл, або повторення).

Ця теорема була сформульована в 1966 Боймом і Якопіні (Corrado Bohm, Guiseppe Jacopini). Головна ідея теореми – перетворити кожну частину програми на одну з трьох основних структур або їх комбінацію так, щоб неструктурована частина програми зменшилася. Після достатньої кількості таких перетворень частина, що залишилася неструктурованою, або зникне, або стає непотрібною. У теоремі доводиться, що у результаті вийде програма, еквівалентна вихідної і використовує лише згадані основні структури.

Комбінації правильних програм, отримані з цих трьох основних структур, також є правильними програмами. Застосовуючи ітерацію та вкладення основних структур, можна отримати програму будь-якого розміру та складності. При використанні лише зазначених структур відпадає потреба у безумовних переходах та мітках. Тому іноді структурне кодування розуміють у вузькому значенні як програмування без GOTO.

В алгоритмічній мові С (С++) для реалізації структурного кодування використовуються наступні оператори:

· Складовий-оператор;

· Оператор-вираз;

· Оператор-вибору;

· Оператор-з-міткою;

· Оператор-переходу;

· Оператор-ітерації;

· Asm-оператор;

· Об'яви (тільки в С++).

Структура «слідування»(рис. 5.1, а) реалізується складовим оператором, оператором-виразом, asm-оператором та ін.

Складовий оператор, або блок, являє собою список (можливо, порожній) операторів, укладених у фігурні дужки {…} . Синтаксично блок розглядається як єдиний оператор, але він впливає на контекст ідентифікаторів, оголошених у ньому. Блоки можуть мати будь-яку глибину вкладеності.

Оператор-виразє виразом, за яким слідує точка з комою. Його формат наступний:

<выражение>;

Компілятор мови C++ виконує оператори-вирази, обчислюючи вирази. Усі побічні ефекти від цього обчислення завершуються на початок виконання наступного оператора. Більшість операторів-виразів є операторами привласнення або виклики функцій (наприклад, printf(), scanf()). Особливим випадком є ​​порожній оператор, що складається з однієї точки з комою ( ; ). Порожній оператор не виконує жодних дій. Однак він корисний у тих випадках, коли синтаксис C++ очікує на наявність деякого оператора, але за програмою він не потрібен (наприклад, нескінченний цикл for).

Asm-операторизабезпечують програмування лише на рівні асемблера (використання покажчиків, побітові операції, операції зсуву тощо.). Використовуючи асемблерну мову для обробки підпрограм критичних ситуацій, багаторазово повторюваних операцій, можна підвищити швидкість оптимізації без удосконалення мови високого рівня.

Структура «розвилка»(Рис. 5.1, б, в) реалізується операторами вибору. Оператори вибору , або оператори управління потоком, виконують вибір однієї з альтернативних гілок програми, перевіряючи для цього певні значення. Існує два типи операторів вибору: if...else та switch.

Базовий оператор if(рис. 5.1, б) має такий формат:

if(умовний_вираз)оператор_якщо_"істина" оператор_якщо_"брехня";

Мова C++ на відміну, наприклад, мови Паскаль немає спеціального булевого типу даних. В умовних перевірках роль такого типу може грати ціла чисельна змінна або покажчик на тип. Умовний_вираз повинен бути записаний у круглих дужках. Цей вираз обчислюється. Якщо воно є нульовим (або порожнім у разі типу покажчика), ми говоримо, що умовний_вираз хибно(false ) ; інакше воно істинно(True).

Якщо пропозиція else відсутня, а умовний_вираз дає значення "істина", то виконується оператор_якщо_"істина"; інакше він ігнорується.

Якщо задано пропозицію оператор_якщо_"брехня", а умовний_вираз дає значення "істина", то виконується оператор_якщо_"істина"; інакше виконується оператор_якщо "брехня".

Перетворення покажчиків виконуються таким чином, що значення покажчика завжди може бути коректно порівняно з виразом типу константи, що дає 0. Таким чином, порівняння для порожніх покажчиків може бути зроблено у вигляді:

if (!ptr) ... або if (ptr = = 0).

Оператор_якщо_"брехня" та оператор_якщо_"істина" самі можуть бути операторами if, що дозволяє організовувати будь-яку глибину вкладеності умовних перевірок. При використанні вкладених конструкцій if...else слід бути уважним та забезпечувати правильний вибірвиконуваних операторів. Будь-яка неоднозначність конструкції "else" дозволяється зіставленням else з останнім знайденим на рівні даного блоку if без else.

Наприклад, запис:

if (x == 1)

if (y == 1) puts("x=1 та y=1");

else puts("x! = 1");

дає неправильне рішення, оскільки else, незалежно від стилю запису, зіставляється не з першим, а з другим if. Тому правильний запис останнього рядка має бути таким:

else puts("x=1 та y!=1");

Однак за допомогою фігурних дужок можна реалізувати і першу конструкцію:

if (x = = 1)

if (y = = 1) puts("x = і y=1");

else puts("x! = 1"); // правильне рішення

Оператор switch(див. рис. 5.1, в) використовує наступний базовий формат:

switch(перемикає_вираз) case_оператор;

Він дозволяє передавати керування одному з кількох операторів з позначкою case залежно від значення перемикаючого вираження. Будь-який оператор у case_операторі (включно з порожнім оператором) може бути позначений однією (або більше) міткою варіанту:

caseконстантне_вираження_i : case_оператор_i;

де кожне константное_выражение_i повинно мати унікальне ціле значення (перетворюване до типу перемикаючого_вирази) в межах об'ємного оператора switch.

Допускається мати в одному операторі switch повторювані константи case.

Оператор може мати не більше однієї мітки default:

default: оператор_умовчання;

Після обчислення перемикаючого_виразу виконується зіставлення результату з одним із константних_виразів_i. Якщо знайдено відповідність, то управління передається case_оператору_i з позначкою, на яку знайдено відповідність. Якщо відповідності не знайдено і є мітка default, керування передається оператору_умовчання. Якщо відповідність не знайдена, а мітка default відсутня, жодні оператори не виконуються. Щоб зупинити виконання групи операторів для конкретного варіанту, слід використовувати оператор break.

КОНСПЕКТ ОГЛЯДНОЇ ЛЕКЦІЇ

Для студентів спеціальності
Т1002 "Програмне забезпечення інформаційних технологій"

(А.М.Кадан, к.т.н., доцент)

Запитання №34.
Характеристика основних методологій розробки програмного забезпечення

1. Методологія та технологія програмування.

2. Імперативне програмування.

2.1. Модульне програмування.

2.2. Структурне програмування.

3. Метод об'єктно-орієнтованого програмування.

Методологія та технологія програмування

Наведемо основні визначення.

Програма - завершений продукт, придатний для запуску своїм авторомна системі, де він був розроблений.

Програмний продукт - програма, яку будь-яка людина може запуститикати, тестувати, виправляти та розвивати. Така програма має бутинаписана в узагальненому стилі, ретельно відтестована та супроводженадетальною документацією. (З урахуванням модної в даний час концепції авторських прав тут необхідно уточнити - будь-яка людина,що має раз рішення працювати з вихідними текстами програм)

Програмний комплекс - набір взаємодіючих програм, узгоджених за функціями та форматами, точно визначеними інтерфейсами, і разомскладових повне засіб на вирішення великих завдань.

Життєвий цикл програмного забезпечення – це період його розробки та експлуатації, починаючи з виникнення задуму і до припинення її використання.

Методологія програмування – сукупність методів, що застосовуються у життєвому циклі програмного забезпечення та об'єднаних загальним філософським підходом.

З чотирьох широко відомих нині методологій програмування – імперативного, об'єктно-орієнтованого, логічного, функціонального – розглянемо те, чого вас вчили – методології імперативного та об'єктно-орієнтованого програмування.

Технологія програмування вивчає технологічні процеси та порядок їх проходження – стадії(з використанням знань, методів та засобів).

Технології зручно характеризувати у двох вимірах - вертикальному (що представляє процеси) і горизонтальному (що представляє стадії).

Процес - Сукупність взаємопов'язаних дій, що перетворюють деякі вхідні дані у вихідні. Процеси складаються з набору дій, а кожна дія з набору завдань. Вертикальний вимір відображає статичні аспекти процесів та оперує такими поняттями, як робочі процеси, дії, завдання, результати діяльності та виконавці.

Стадія - частина дій щодо створення програмного забезпечення, обмежена деякими часовими рамками і закінчується випуском конкретного продукту, що визначається заданими на цій стадії вимогами. Стадії складаються з етапів, які мають ітераційний характер. Іноді стадії об'єднують у більші часові рамки, які називаються фазами. Отже, горизонтальний вимір представляє час, відбиває динамічні аспекти процесів і оперує такими поняттями, як фази, стадії, етапи, ітерації та контрольні точки.

Технологічний підхід визначається специфікою комбінації стадій та процесів, орієнтованої на різні класи програмного забезпечення та на особливості колективу розробників.

Якщо знову звернутися до малюнку, то в даному випадку на кожній стадії виконується єдиний процес. Звичайно, при розробці та створенні великих програм така схема недостатньо коректна (та й просто нереалістична). Однак її можна взяти за основу для багатьох інших технологічних підходів до ведення життєвого циклу.

Імперативне програмування

Імперативне програмування – це історично перша методологія програмування, якою користувався кожен програміст, що програмує будь-якою з «масових» мов програмування – Basic, Pascal, C.

Вона орієнтована на класичну фон Неймановську модель, що тривалий час залишалася єдиною апаратною архітектурою. Методологія імперативного програмуванняхарактеризується принципом послідовної зміни стану обчислювача покроковим чином. При цьому керування змінами повністю визначене та повністю контрольоване.

Методи та концепції

· Метод зміни станів- полягає в послідовній зміні состаяння. Метод підтримується концепцією алгоритму.

· Метод управління потоком виконання- полягає у покроковому контроліуправління. Метод підтримується концепцією потоку виконання.

Обчислювальна модель. Якщо під обчислювачем розуміти сучасний комп'ютер, то його станом будуть значення всіх осередків пам'яті, стан процесора (у тому числі - покажчик поточної команди) та всіх сполучених пристроїв. Єдина структура даних – послідовність осередків (пар «адреса» – «значення») з лінійно впорядкованими адресами.

В якості математичної моделі Імперативне програмування використовує машину Тьюринга-Поста - абстрактний обчислювальний пристрій, запропонований на зорі комп'ютерної ери для опису алгоритмів.

Синтаксис та семантика. Мови, що підтримують цю обчислювальну модель, є засобом опису функції переходів між станами обчислювача. Основним їх синтаксичним поняттям є оператор. Перша група - прості оператори, які ніяка їх частина є самостійним оператором (наприклад, оператор присвоювання, оператор безумовного переходу, виклику процедури тощо.). Друга група - структурні оператори, що об'єднують інші оператори в новий, більший оператор (наприклад, складовий оператор, оператори вибору, циклу тощо).

Традиційне засіб структурування- підпрограма (процедура чи функція). Підпрограми мають параметри та локальні визначення та можуть бути викликані рекурсивно. Функції повертають значення, як результат своєї роботи.

Якщо в даній методології потрібно вирішити деяке завдання для того, щоб використовувати її результати при вирішенні наступного завдання, типовий підхід буде таким. Спочатку виконується алгоритм, який вирішує перше завдання. Результати його роботи зберігаються в спеціальному місці пам'яті, яке відоме наступному алгоритму, та використовуються ним.

Імперативні мови програмування. Імперативні мови програмуванняманіпулюють даними у покроковому режимі, використовуючи послідовні інструкції та застосовуючи їх до різноманітних даних. Вважається, що першою алгоритмічною мовою програмування була мова Plankalkuel (від plan calculus), розроблена у 1945-1946 роках Конрадом Цузе (Konrad Zuse).

Найбільш відомі та поширені імперативні мови програмування, більшість з яких було створено наприкінці 50-х – середині 70-х років XX століття, представлені на малюнку. Зверніть увагу на порожнє місце на малюнку, що відповідає 80-м та 90-м рокам минулого століття. Це період захоплення новими парадигмами, і імперативних мов у цей час мало з'являлося.

Клас задач.Імперативне програмування найбільш придатне на вирішення завдань, у яких послідовне виконання будь-яких команд є природним. Прикладом тут може бути управління сучасними апаратними засобами. Оскільки практично всі сучасні комп'ютери імперативні, ця методологія дозволяє породжувати досить ефективний код, що виконується. Зі зростанням складності завдання імперативні програми стають дедалі менш читаними.

Програмування та налагодження справді великих програм (наприклад, компіляторів), написаних винятково з урахуванням методології імперативного програмування, може затягтися довгі роки.

Рекомендації щодо літератури. Особливості імперативного програмування викладено у великій кількості книг. Найбільш систематично вони наведені у роботі "Універсальні мови програмування. Семантичний підхід" [Калінін, Мацкевич 1991].

Модульне програмування

Модульне програмування - це такий спосіб програмування, при якому вся програма розбивається на групу компонентівмодулями, причому кожен з них має свій контрольований розмір,е призначення і детально опрацьований інтерфейс із зовнішнім середовищем. Єдина альтернатива модульності - монолітна програма, яка,нічно, незручно. Таким чином, найцікавіше питання при вивченніні модульності - визначення критерію розбиття на модулі.

Концепція модульного програмування. В основі модульного програмування лежать три основні концепції:

Принцип приховування інформації Парнас. Кожен компонент приховує єдине проектне рішення, тобто модуль служить для приховування інформації. Підхід до розробки програм полягає в тому, що спочатку формується список проектних рішень, які особливо важко прийняти або які, швидше за все, змінюватимуться. Потім визначаються відслушні модулі, кожен з яких реалізує одне із зазначених решений.

Аксіома модульності Коуена. Модуль - незалежна програмна їжаниця, що служить для виконання певної певної функції програми та для зв'язку з рештою програми. Програмнаодиниця повинна задовольняти такі умови:

блоковість організації,тобто можливість викликати програмну єдиністьцю з блоків будь-якого ступеня вкладеності;

синтаксична відокремленість, тобто виділення модуля в тексті синтоксичними елементами;

семантична незалежність, тобто незалежність від місця, де програмна одиниця викликана;

спільність даних, тобто наявність власних даних, що зберігаютьсяпри кожному зверненні;

повнота визначення, тобто самостійність програмної одиниці.

Складальне програмування Цейтіна. Модулі - це програмні кір Пічі, з яких будується програма. Існують три основніпосилки до модульного програмування:

прагнення виділення незалежної одиниці програмного знання.В ідеальному випадку будь-яка ідея (алгоритм) має бути оформленау вигляді модуля;

потреба організаційного розчленування великих розробок;

можливість паралельного виконання модулів (у контексті параллельного програмування).

Визначення модуля та його приклади. Наведемо кілька додаткових визначень модуля.

  • Модуль- це сукупність команд, до яких можна звернутисяімені.

· Модуль -це сукупність операторів програми, що має граничні елементи та ідентифікатор (можливо агрегатний).

Функціональна специфікація модуля повинна включати:

  • синтаксичну специфікацію його входів, яка має дозволяти побудувати використовуваною мовою програмування синтаксичноправильне звернення щодо нього;

· опис семантики функцій, що виконуються модулем по кожному з йоговходів.

Різновиди модулів. Існують три основні різновиди модулів:

1) "Маленькі" (функціональні) модулі, що реалізують, як правило, однуякусь певну функцію. Основним і найпростішим модулем практично у всіх мовах програмування є процедура абофункція.

2) "Середні" (інформаційні) модулі, що реалізують, як правило, кількадо операцій або функцій над однією і тією ж структурою даних (інформаційним об'єктом), яка вважається невідомою поза цим модулем. Приклади "середніх" модулів у мовах програмування:

a)завдання у мові програмуванняAda;

b)кластер у мові програмування CLU;

c)класи в мовах програмування C++ та Java.

3) "Великі" (логічні) модулі, що поєднують набір "середніх" або"маленьких" модулів. Приклади "великих" модулів у мовах програмирування:

a)модуль у мові програмування Modula-2;

b)пакети у мовах програмуванняAdaі Java.

Набір характеристик модулязапропонований Майерсом [Майєрс 1980]. Він складається з наступногочих конструктивних характеристик:

1) розміру модуля;

У модулі має бути 7 (+/-2) конструкцій (наприклад, операторів дляфункцій чи функцій для пакета).Це число береться на основі уявлень психологів про середню операціюном буфері пам'яті людини. Символьні образи в людському мозку об'єднуються в "чанки" - набори фактів та зв'язків між ними, що запам'ятовуються і здобуті як єдине ціле. У кожний момент часу людина може обрабатувати не більше 7 чанків.

Модуль (функція) не повинен перевищувати 60 рядків. В результаті його можале помістити на одну сторінку друку або легко переглянути на екрані монітора.

2) міцності (зв'язності) модуля;

Існує гіпотеза про глобальні дані, що стверджує, що глобальнідані шкідливі та небезпечні. Ідея глобальних даних дискредитує себе так ж, як і ідея оператора безумовного переходуgoto. Локальність данихдає можливість легко читати та розуміти модулі, а також легко видаляти їхіз програми.

Зв'язність (міцність) модуля (cohesion ) - міра незалежності його елементів.Чим вище зв'язність модуля - тим краще, тим більше зв'язків щододо частини програми, що залишилася, він заховує в собі. Можна виділити типизв'язності, наведені нижче.

Функціональназв'язність. Модуль із функціональною зв'язністю реалі зує одну якусь певну функцію і не може бути розбитий на 2 модулі з тими ж типами зв'язків.

Послідовна зв'язність. Модуль з таким зв'язком може бути раз біт на послідовні частини, що виконують незалежні функції, алеспільно реалізують єдину функцію. Наприклад, один і той же модуль може бути використаний спочатку для оцінки, а потімроботи даних.

Інформаційна(комунікативна) зв'язність. Модуль з інформаційним ної зв'язністю - це модуль, який виконує кілька операційабо функцій над однією і тією ж структурою даних (інформаційним об'єктом), яка вважається невідомою поза цим модулем. Ця інформаціямаційна зв'язність застосовується для реалізації абстрактних типівданих.

Звернемо увагу на те, що засоби для завдання інформаційно міцнімодулів були відсутні в ранніх мовах програмування (наприклад, FORTRAN і навіть в оригінальній версії мови Pascal ). І лише пізніше, у мові програмвання Ada, з'явився пакет - засіб завдання інформаційно-міцного модуля.

3) зчеплення модуля з іншими модулями;

Зчеплення(coupling ) - міра відносної незалежності модуля від іншихмодулів. Незалежні модулі можуть бути модифіковані без переробки інших модулів. Що слабкіше зчеплення модуля, то краще. Розглянемо разособисті типи зчеплення.

Незалежнімодулі – це ідеальний випадок. Модулі нічого не знаютьодин про одного. Організувати взаємодію таких модулів можна, знаючи їхінтерфейс та відповідним чином перенаправивши вихідні дані одного модуля на вхід іншого.Досягти такого зчеплення складно, та й не потрібно, оскільки зчеплення за даними(Параметричне зчеплення) є досить хорошим.

Зчеплення за даними(параметричне) - це зчеплення, коли даніпередаються модулю як значення його параметрів або як результат йогозвернення до іншого модуля для обчислення певної функції. Цейвид зчеплення реалізується у мовах програмування при зверненнідо функцій (процедур). Два різновиди цього зчепленняняються характером даним.

· Зчеплення за простими елементами даних.

· Зчеплення структурою даних.В цьому випадку обидва модулі повиннізнати про внутрішню структуру даних.

4) рутинності (ідемопотентність, незалежність від попередніх оборотівній) модуля.

Рутинність- це незалежність модуля від попередніх звернень до нього(Від передісторії). Будемо називати модуль рутинним, якщо результат його ра боти залежить лише від кількості переданих параметрів (а не від кількості звернень).

Модуль повинен бути рутинним у більшості випадків, але є й випадки,коли модуль має зберігати історію. У виборі ступеня рутинності мо дуля користуються трьома рекомендаціями.

· У більшості випадків робимо модуль рутинним, тобто незалежним відпопередніх звернень.

· Залежні від передісторії модулі слід використовувати тільки в тихвипадках, коли це необхідно для зчеплення за даними.

· У специфікації модуля, що залежить від передісторії, повинна бути чіткосформульована ця залежність, щоб користувачі мали можливістьність прогнозувати поведінку такого модуля.

Структурне програмування.

Структурне програмування (СП) виникло як варіант вирішення проблеми зменшення складності розробки програмного забезпечення.

На початку ери програмування робота програміста нічим не регламентувалася. Завдання, що вирішувалися, не відрізнялися розмахом і масштабністю, використовувалися в основному машинно-орієнтовані мови і близькі до них мова типу Асемблера, програми, що розробляються, рідко досягали значних розмірів, не ставилися жорсткі обмеження на час їх розробки.

З розвитком програмування виникли завдання, на вирішення яких визначалися обмежені терміни дедалі складніших завдань із залученням груп програмістів. І як наслідок, розробники зіткнулися з тим, що методи, придатні для розробки невеликих завдань, не можуть бути використані при розробці великих проектів через складність останніх.

Таким чином, мета структурного програмування - підвищення надійностіпрограм, забезпечення супроводу та модифікації, полегшення та прискореннярозробки.

Методологія структурного імперативного програмування - підхід, за що ключається в завданні хорошої топології імперативних програм, у тому числі відмові від використання глобальних даних і оператора безумовного переходу, розробці модулів з сильною зв'язністю і забезпеченні їхвисимості з інших модулів.

Підхід базується на двох основних принципахпах:

  • Послідовна декомпозиція алгоритму розв'язання задачі зверху донизу.
  • Використання структурного кодування.

Нагадаємо, що дана методологія є найважливішим розвитком імпетивної методології.

Походження, історія та еволюція. Творцем структурного підходу вважається Едсгер Дейкстра. Йому такожналежить спроба (на жаль, абсолютно незастосовна длямасового програмування) поєднати структурне програмування з методами доказу правильності створюваних програм. У його розробці брали участь такі відомі вчені як Х. Мілс, Д.Е. Кнут, С. Хоор.

Методи та концепції, що лежать в основі структурного програмування. Їх три

Метод алгоритмічної декомпозиції зверху вниз -полягає в покроковійдеталізації постановки задачі, починаючи з найбільш загальної задачі. ДанийМетод забезпечує хорошу структурованість. Метод підтримуєтьсяконцепцією алгоритму.

Метод модульної організації частин програми- полягає у розбиттяпрограми на спеціальні компоненти, які називаються модулями. Методпідтримується концепцією модуля.

Метод структурного кодування -полягає у використанні при кодіванні трьох основних керуючих конструкцій. Мітки та оператор безумовного переходу є зв'язками, що важко відстежуються, без яких ми хочемо обійтись. Метод підтримується концепцією управління

Структурні мови програмування. Основна відмінність від класичної методології імперативного програмування полягає у відмові (точніше, тому чи іншому ступені відмови) від опе ратора безумовного переходу.

[Пратт Т., 1979] "Важливим для програміста властивістю синтаксису є можливість відобразити в структурі програми структуру алгоритму, що лежить в її основі . При використанні для побудови програми методу, відомого під назвою структурне програмування , програма конструюється ієрархічно - зверху донизу (від головної програмидо підпрограм найнижчого рівня), із застосуванням кожному рівні лише обмеженого набору управляючих структур: простих послідовностей інструкцій, циклів і деяких видів умовних розгалужень. При послідовному проведенні цього методу структуру результуючих алгоритмів легко розуміти, налагоджувати та модифікувати. В ідеалі ми маємо з'явитися можливість перевести побудовану таким чином схему програми прямо у відповідні програмні інструкції, що відображають структуру алгоритму."

Теорема про структурування (Бема-Джакопіні ( Boem - Jacopini )): Будь-яку правильну програму (тобто програму з одним входом та одним виходом без зациклювань та недосяжних гілок) можна записати з використанням наступних логічних структур – послідовність, вибору та повторення циклу

Наслідок 1: Будь-яку програму можна привести до форми без оператора goto.

Наслідок 2: Будь-який алгоритм можна реалізувати в мові, заснованому на трьох керуючих конструкціях - послідовність, цикл, повторення.

Наслідок 3: Складність структурованих програм обмежена, навіть у разі їхнього необмеженого розміру.

Структурне програмування - це самоціль. Його основне призначення-це отримання хорошої ("правильної") програми, проте навіть у найкращій програмі оператори переходуgotoіноді потрібні: наприклад - вихід із безлічі вкладених циклів.

Практично всіма мовами, що підтримують імперативну методологію,можна розробляти програми та з даної методології. У ряді мов введені спеціальні замінники оператора goto, що дозволяють полегшити керування циклами (наприклад, Break та Continue у мові C).

Клас задач.Клас задач для даної методології відповідає класу задач для імперіїтивної методології. Зауважимо, що при цьому вдається розробляти більшескладні програми, оскільки їх легко сприймати та аналізувати.

Рекомендації щодо літератури. Однією з найвідоміших робіт у цій галузі є стаття "Нотаткиз структурного програмування "[Дейкстра 1975].програмування докладно розглянуті у книзі "Теорія та практикаструктурного програмування" [Лінгер, Міллс, Уітт 1982]. Практикуструктурного програмування можна вивчати за книгою "Алгоритми +структури даних = програми" [Вірт 1985]. Філософія візуального структурногопрограмування докладно викладено у роботі [Паронджанов 1999].

Метод об'єктно-орієнтованого програмування.

Метод структурного програмування виявився ефективним під час написання програм «обмеженої складності». Однак зі зростанням складності програмних проектів, що реалізуються, і, відповідно, обсягу коду створюваних програм, можливості методу структурного програмування виявилися недостатніми.

Основною причиною проблем можна вважати те, що в програмі не відображалася безпосередньо структура явищ і понять реального світу і зв'язків між ними. При спробі аналізу та модифікації тексту програми програміст змушений був оперувати штучними категоріями.

Щоб писати більш складні програми, потрібен був новий підхід до програмування. У результаті розробили принципи Об'єктно-орієнтованого Програмування. OOP акумулює найкращі ідеї, втілені у структурному програмуванні, і поєднує їх із потужними новими концепціями, які дозволяють по-новому організовувати ваші програми.

Треба сказати, що теоретичні основи ООП було закладено ще 70-х роках минулого століття, але практичне їх втілення стало можливим лише в середині 80-х, з появою відповідних технічних засобів.

Методологія ООП використовує метод об'єктної декомпозиції, згідно з яким структура системи (статична складова) описується в термінах об'єктів та зв'язківміж ними, а поведінка системи (динамічна складова) – у термінах обміну повідомленнямиміж об'єктами. Повідомлення можуть бути як реакцією на події, викликані як зовнішніми чинниками, і породжувані самими об'єктами.

Об'єктно-орієнтовані програми називають «програмами, керованими від подій», на відміну традиційних програм, званих «програмами, керованими від даних».

Основні методи та концепції ООП

· Метод об'єктно-орієнтованої декомпозиції– полягає у виділенні об'єктів та зв'язків між ними. Метод підтримується концепціями інкапсуляції, успадкування та поліморфізму.

· Метод абстрактних типів даних- метод, що лежить в основі інкапсуляції. Підтримується абстрактних типів даних концепції.

· Метод пересилання повідомлень– полягає у описі поведінки системи термінах обміну повідомленнями між об'єктами. Підтримується поняттям повідомлення.

Обчислювальна модель чистого ООП підтримує лише одну операцію – надсилання повідомлення об'єкту. Повідомлення можуть мати параметри, які є об'єктами. Саме повідомлення також є об'єктом.

Об'єкт має набір обробників повідомлень (набір методів). Об'єкт має поля – персональні змінні даного об'єкта, значеннями яких є посилання на інші об'єкти. Про одне з полів об'єкта зберігається посилання об'єкт-предок, якому переадресовуються всі повідомлення, не оброблені цим об'єктом. Структури, що описують обробку та переадресацію повідомлень, зазвичай виділяються в окремий об'єкт, званий класом цього об'єкта. Сам об'єкт називається екземпляром зазначеного класу.

Синтаксис та семантика

У синтаксисі чистих об'єктно-орієнтованих мов все може бутизаписано у вигляді посилки повідомлень об'єктам. Клас в об'єктно-орієнтирванних мовах описує структуру та функціонування множиниоб'єктів з подібними характеристиками, атрибутами та поведінкою. Об'єкт належить до деякого класу і має своєвласним внутрішнім станом. Методи - функціональні властивостіякі можна активізувати.

В об'єктно-орієнтованому програмуванні визначають три основнівластивості:

Інкапсуляція. Це приховування інформації та комбінування даних тафункцій (методів) усередині об'єкта.

успадкування. Побудова ієрархії породжених об'єктів з можливістю ністю для кожного такого об'єкта-спадкоємця доступудо коду та даних всіх породжуючих об'єктів-предків.Побудова ієрархій є достатньоскладним справою, оскільки у своїй доводиться виконувати класифікування.

Більшість навколишніх об'єктів відноситься до категорій, розглянутих у книзі [Шлеєр, Меллор 1993]:

· Реальні об'єкти – абстракції предметів, що у фізичному світі;

· Ролі – абстракції мети чи призначення людини, частини устаткування чи організації;

· Інциденти – абстракції чогось того, що сталося або трапилося;

· Взаємодії – об'єкти, що виходять із відношення між іншими об'єктами.

Поліморфізм (поліморфізм включення) - привласнення дії од ного імені, яке потім поділяється вгору і вниз по ієрархії об'єктівтов, причому кожен об'єкт ієрархії виконує цю дію способом,відповідним саме йому.

Кожен об'єкт має посилання на клас, до якого він належить. Приприйомі повідомлення об'єкт звертається до класу для обробки даногоспілкування. Повідомлення може бути передане вгору по ієрархії спадковоня, якщо сам клас не має у своєму розпорядженні методу для його обробки. Якщо обра ботчик подій для повідомлення вибирається динамічно, то методи, реаліють обробників подій, прийнято називати віртуальними.

Природним засобом структурування у цій методології єкласи. Класи визначають, які поля та методи екземпляра доступні з поза, як обробляти окремі повідомлення і т. п. У чистих об'єктно-орієнтованих мовах ззовні доступні тільки методи, а доступ до даних об'єкта можливий лише за його методами.

Взаємодія завдань у цій методології здійснюється за допомогою обміну повідомленнями між об'єктами, що реалізують ці завдання.

Приклад опису в деякому абстрактному Pascal -подібною до об'єктно-орієнтованої мови класу «точка», що є спадкоємцем класу «координати» може виглядати так:

Type TCoordinates = class (TObject)

x, y: integer;
Constructor Init (_x, _y: integer);
Function GetX: integer;
Function GetY: integer;
Procedure SetX (_x: integer);
Procedure SetY (_y: integer);
Procedure Move (dx, dy: integer);
Destructor Done; virtual;

Constructor Init();
x:= _x; y:= _y
end;
Function GetX: integer;
begin
GetX := x
end;
. . . . . . . . . . . . .
End;

TPoint = class (TCoordinates)
Color: integer;
Constructor Init (_x, _y, _Color: integer);
Function SetColor (_Color: integer);
Function GetColor: integer;

Constructor Init(_x, _y, _Color: integer);
Inherited Init(_x, _y);
Color:= _Color
end;
. . . . . . . . . . . . .

End ;

Якщо ми надалі хочемо використати екземпляри класуTPoint, їх необхідно створити, викликавши метод-конструктор.

Var P1: Point;

P 1. Init (0 ,0 , 14); P 1. Move (+2, -2);

Для підтримки концепції ГТР були розроблені спеціальні об'єктно-орієнтовані мовипрограмування. Усі мови OOP можна розділити на три групи.

Чисті мови, що у найбільш класичному вигляді підтримують об'єктно-орієнтовану методологію. Такі мови містять невелику мовну частину та суттєву бібліотеку, а також набір засобів підтримки часу виконання.

Гібридні мови, які з'явилися в результаті впровадження об'єктно-орієнтованих конструкцій у популярні імперативні мови програмування.

Урізані мови, які з'явилися в результаті видалення з гібридних мов найбільш небезпечних та непотрібних з позицій ООП конструкцій.

Література

ISO/IEC 12207:1995 Information Technology – Software Life Cycle Processes.

[Вірт 1985] - Вірт Н. Алгоритми + структури даних = програми. - М: Мир, 1985

[Дейкстра 1975] - Дейкстра Е. Нотатки з структурного програмування // Дал У., Дейкстра Е., Хоар К. Структурне програмування. - М: Мир, 1975

[Калінін, Мацкевич 1991] - Калінін А.Г., Мацкевич І.В. Універсальні програми. Семантичний підхід - М.: Радіо і зв'язок, 1991

[Лінгер, Міллс, Вітт 1982] - Лінгер Р., Міллс Х., Вітт Б. Теорія і практика структурного програмування. - М.: Наука, 1990

[Майєрс 1980] - Майєрс Г. Надійність програмного забезпечення. - М: Мир, 1980

[Паронджанов 1999] - Параноджанов В.Д. Як покращити роботу розуму. - М.: Радіо і зв'язок, 1999

[Пратт Т., 1979] - Пратт Т. Мови програмування: розробка та реалізація. - М.: Світ , 1979

[Шлеєр, Меллор 1993] - Шлеєр С., Меллор С. Об'єктно-орієнтований аналіз: моделювання світу у станах. - Київ: Діалектика, 1993.

Структурне програмування– методологія програмування, спрямовану створення логічно простих і зрозумілих програм. Структурне програмування засноване на припущенні, що логічність та зрозумілість програми полегшує розробку, доказ правильності та подальший супровід програми, а також забезпечує її надійність.

Характерними принципами структурного програмування є:

· низхідне програмування –метод розробки програм, у якому програмування ведеться шляхом «згори-вниз», від загального до деталей;

· модульне програмування, При якому відносно незалежні підзадачі програмуються у вигляді окремих програмних модулів;

· Використання при програмуванні трьох структур управління (слідування, вибір, повторення). Структура слідування передбачає природну послідовність виконання операторів. Структура вибір задається схемою "якщо - то - інакше" ( умовний оператор if). Структурі повторення зіставлений оператор циклу;

· Відмова від безумовних передач управління та обмежене використання глобальних змінних.

В основі структурного програмування лежить теорема, що була суворо доведена в теорії програмування. Суть її в тому, що алгоритм для вирішення будь-якого логічного завдання можна скласти тільки із структур , розгалуження, цикл». Їх називають базовими алгоритмічними структурами. По суті, ми і раніше у всіх прикладах програм дотримувалися принципів структурного програмування.

Проходження – це лінійна послідовність дій (рис. 2.6):

Рис. 2.6. Слідування

Кожен блок може містити як просту команду, так і складну структуру, але обов'язково повинен мати один вхід і один вихід.

Розгалуження алгоритмічна альтернатива. Управління передається одному з двох блоків залежно від істинності чи хибності умови. Потім відбувається вихід загальне продовження (рис. 2.7):

Рис. 2.7. Розгалуження

Цикл повторення певної групи дій за умовою. Розрізняються два типи циклу. Перший цикл із передумовою (рис. 2.8):

Рис. 2.8. Цикл із передумовою

Поки що умова істинна, виконується серія, що утворює тіло циклу.

Другий тип циклічної структури цикл із постумовою (рис. 2.9):

Рис. 2.9. Цикл із постумовою

Тут тіло циклу передує умові циклу. Тіло циклу повторює своє виконання, якщо умова хибна. Повторення закінчується, коли умова стане справжньою.

Теоретично необхідним та достатнім є лише перший тип циклу цикл із передумовою. Будь-який циклічний алгоритмможна побудувати за його допомогою. Це загальний варіант циклу, ніж цикл-до. Справді, тіло циклу до хоча б один раз обов'язково виконається, тому що перевірка умови відбувається після завершення його виконання. А для циклу-поки можливий такий варіант, коли тіло циклу не виконається жодного разу. Тому в будь-якій мові програмування можна було б обмежитися лише циклом-поки. Однак у ряді випадків застосування циклу до виявляється більш зручним, і тому він використовується.

Іноді у літературі структурне програмування називають програмуванням без goto. Справді, за такого підходу немає місця безумовному переходу. Невиправдане використання у програмах оператора goto позбавляє її структурності, а отже, всіх пов'язаних із цим позитивних властивостей: прозорості та надійності алгоритму. Хоча у всіх процедурних мовах програмування цей оператор присутній, проте, дотримуючись структурного підходу, його слід уникати.

Складний алгоритм складається із з'єднаних між собою базових структур. Сполучатися ці структури можуть двома способами: послідовнимі вкладеним.Ця ситуація аналогічна тому, що ми спостерігаємо в електротехніці, де будь-яка як завгодно складна електричний ланцюгможе бути розкладена на послідовно та паралельно з'єднані ділянки.

Вкладені алгоритмічні структури є аналогом паралельно з'єднаних провідників. Тут більше підходить аналогія з матрьошками, поміщеними одна в одну. Якщо блок, що становить тіло циклу, сам є циклічною структурою, то, отже, мають місце вкладені цикли. У свою чергу, внутрішній цикл може мати в собі ще один цикл і т.д. У зв'язку з цим запроваджується уявлення про глибину вкладеності циклів. Так само і розгалуження можуть бути вкладеними один в одного.

Структурний підхід вимагає дотримання стандарту зображення блок-схем алгоритмів. Рисувати їх треба так, як це робилося у всіх наведених прикладах. Кожна базова структураповинна мати один вхід та один вихід. Нестандартно зображена блок-схема погано читається, втрачається наочність алгоритму.

Мови програмування Паскаль та Сі називають мовами структурного програмування. Вони є всі необхідні керуючі конструкції для структурної побудови програми. Наочність такої побудови надає структуризація зовнішнього виглядутекст програми. Основний прийом, що використовується для цього зрушення рядків, які повинні підпорядковуватися наступним правилам:

Конструкції одного рівня вкладеності записуються на одному вертикальному рівні (починаються з однієї позиції у рядку);

Вкладена конструкція записується зміщеною рядком на кілька позицій вправо щодо зовнішньої для неї конструкції.

Структурна методика алгоритмізації це не тільки форма опису алгоритму, але це ще й спосіб мислення програміста . Створюючи алгоритм, слід прагнути складати його з стандартних структур. Якщо використовувати будівельну аналогію, можна сказати, що структурна методика побудови алгоритму подібна до складання будівлі зі стандартних секцій на відміну від складання по цеглині.

Ще одним найважливішим технологічним прийомом структурного програмування є декомпозиція розв'язуваної задачі на підзавдання Найпростіші з погляду програмування частини вихідної задачі. Алгоритми вирішення таких підзавдань називаються допоміжними алгоритмами. У зв'язку з цим можливі два шляхи у побудові алгоритму:

«згори донизу»: спочатку будується основний алгоритм, потім допоміжні алгоритми;

«знизу нагору»: спочатку складаються допоміжні алгоритми, потім основний.

Перший підхід ще називають методом послідовної деталізації, другий складальним методом.

Складальний метод передбачає накопичення та використання бібліотек допоміжних алгоритмів, реалізованих у мовах програмування у вигляді підпрограм, процедур, функцій. При послідовної деталізації спочатку будується основний алгоритм, та був у нього вносяться звернення до допоміжним алгоритмам першого рівня. Після цього складаються допоміжні алгоритми першого рівня, в яких можуть бути звернення до допоміжних алгоритмів другого рівня, і т.д. Допоміжні алгоритми нижнього рівня складаються лише з простих команд.

Метод послідовної деталізації застосовується у будь-якому конструюванні складних об'єктів. Це природна логічна послідовність мислення конструктора: поступове заглиблення у деталі. У нашому випадку йдеться також про конструювання, але не технічних пристроїв, а алгоритмів. Досить складний алгоритм іншим способом збудувати практично неможливо.

У методі послідовної деталізації спочатку аналізується вихідне завдання. У ній виділяються підзавдання. Будується ієрархія таких підзавдань. Потім складаються алгоритми (або програми), починаючи з основного алгоритму (основної програми), далі – допоміжні алгоритми (підпрограми) з послідовним поглибленням рівня, доки отримаємо алгоритми, що з простих команд.

Перший крок деталізації. Спочатку намітимо всі необхідні підпрограми, вказавши їх заголовки (специфікації). На місці тіла підпрограм запишемо коментарі, що пояснюють (такий вид підпрограми називається «заглушкою»). Напишемо основну частину програми. А потім повернемося до детального програмування процедур та функцій. На першому етапі програмування замість тіла підпрограми опишемо її призначення у формі коментаря.

Структурне програмування - одне з найбільших досягнень у технології програмування. Хоча найзагальніше і досить невиразне уявлення про структурне програмування є майже у всіх, загальноприйнятого чіткого його визначення немає. Структурне програмування ставить за мету писати програми мінімальної складності, змусити програміста мислити ясно, полегшити сприйняття програми.

Текст програми має бути таким, щоб його можна було читати «зверху – вниз». Необмежене використання операторів безумовного переходу (GO TO ) порушує цю умову, тому структурне програмування часто називають програмуванням без GO ТО.

Можна навести приклади програм, які не містять GO TO, і акуратно розташовані драбинкою відповідно до рівня вкладеності операторів, але абсолютно незрозумілі і бувають інші програми, що містять GO TO і все ж таки зрозумілі. Так що наявність або відсутність GO TO – поганий показник якості програми (ілюстрації в Д. Кнут). І все ж таки: найбільш важко контрольованим і потенційно нестійким є оператор безумовного переходу - GO TO.

Структура тіла модулів і використовувані базові конструкції програмування повинні бути потенційно стійкими до апаратурних збоїв, спотворень вихідних даних та помилок у програмах.

Будь-яку програму можна синтезувати на основі елементарних базових конструкцій трьох типів:

1. Проста послідовність. 2. Умови (альтернативи).

3. Повторення (цикли, ітерації). Можливі один із двох або обидва види:

Робити «поки що» Робити «поки не»

4. Можна додати четверту конструкцію – вибір (перемикач).

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

Перелічені елементарні конструкції, наприклад, у мові Паскаль реалізовані так:

Умовний оператор IF лог. вир. THEN оператор 1 ELSE оператор2;

IF лог. вираз THEN оператор;

Повторення (цикли, ітерації)

а) Робити «поки що» WHILE умова продовження DO оператор;

б) Робити «поки що» REPEAT оператор UNTIL умова завершення;

в) Цикл з перебором FOR К: = В1 ТО В2 DO оператор;

FOR K:=B2 DOWNTO B1 DO оператор;

Вибір (перемикач) CASE умова OF

N1, ... Nk: оператор 1;

Ni , ... Nm : оператор п;

END;

У мові FoxBASE ці конструкції реалізовані у вигляді:

Умовний оператор IF лог. вираз

оператори1

[ ELSE

оператори2]

ENDIF

Цикл DO WHILE вираз

оператори

ENDDO

Вибір (перемикач) DO CASE

CASE лог. вираз 1

оператори

CASE лог. вираз2

Оператори

CASE лог. Вираз п

Оператори

ENDCASE

Кожна структура характеризується єдиною точкою передачі управління структуру (єдиний вхід) і єдиною точкою виходу з структури.

Ці конструкції мають систематизуюче та дисциплінуюче значення. Простота вихідних конструкцій структурного програмування запобігає появі складних інформаційних зв'язків та заляканих передач управління.

У разі підвищення структурованості модулів знижується складність програм, зростає їх наочність, що сприяє скорочення кількості помилок. Проте підвищення якості програм доводиться розплачуватися додаткової пам'яттю і часом реалізації на ЕОМ.

Структурність програми залежить від мови програмування, що використовується. Сучасні програмні засобирозробки програм є «найкращими» мовами структурного програмування. З поширених мов програмування найбільш підходящими вважаються Паскаль, Basic, FoxBASE. Структурне програмування, наприклад, мовою Ассемблер майже неможливе. Сам факт використання мови асемблера вказує на те, що програма написана в основному в термінах машинної мови.

Структурне програмування орієнтоване спілкування з людьми, а чи не з машиною, сприяє написанню програм, що становлять просте і ясне вирішення завдання.

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

Позиція щодо оператора GO TO має бути наступною: уникати використання GO TO усюди, де це можливо, але не ціною ясності програм. Часто виявляється доцільним використовувати GO TO для виходу з циклу або модуля, для переходу в конструкції ON (наприклад, мовою Basic) або щоб уникнути занадто великої глибини вкладеності розвилок, тим більше, що перехід здійснюється на наступні (розташовані нижче) оператори програми, і структурна програма продовжує залишатися легко читається зверху вниз. Найгіршим застосуванням оператора GO TO вважається передача управління на оператор, розташований вище (раніше) у тексті програми.

Крім того, щоб полегшити читання програми, її текст необхідно розбити фізично на частини, додаючи порожні рядки між розділами, підрозділами. Текст програми повинен бути написаний з правильними зрушеннями, тому розриви в послідовності виконання легко простежуються. Одноцільові пропозиції кожного модуля повинні вміщуватися на одній сторінці друкуючого пристрою.

Віруси