Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

osn_progr_final

.pdf
Скачиваний:
37
Добавлен:
12.02.2016
Размер:
3.27 Mб
Скачать

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

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

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

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

Згодом, трохи змінилася й сама ідеологія С++. Споконвічно автор відкидав можливість використання в мові засобів динамічного визначення типів (і деякі інші можливості), однак зараз такі засоби є. Частина змін, що вимагають перегляду самої ідеології мови, вносилися самим Брайном Страуструпом. Найбільше докладно історія змін і доповнень мови розглянуті в [16].

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

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

11

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

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

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

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

друга частина книги присвячена реалізації концепції ООП мовою С++;

доповнення містять важливу інформацію технічного плану по

організації вводу-виводу й керуванню виключеннями а також довідник функцій.

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

Даний посібник написаний на основі курсів лекцій, прочитаних в Міжнародному університеті "РЕП" імені академіка Степана Дем'янчука для студентів спеціальностей "Прикладна математика", "Інформатика" та на факультеті кібернетики Київського національного університету імені Тараса Шевченка.

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

Крім цього навчального посібника, автори можуть порекомендувати ознайомитися із дуже корисною працею “класика” Граді Буча “Об’єктно-орієнтований аналіз і проектування із прикладами додатків на С++”.

12

Авторський колектив висловлює подяку всім, хто прийняв участь в обговоренні матеріалу, опираючись на чиї думки був написаний цей посібник: Ю.А.Бєлову, А.Б.Ставровському, Е.В.Івохіну, М.Й.Шахрайчуку, П.С.Янчуку. Також хотілося б відзначити внесок рецензентів за їх правильні й своєчасні зауваження та рекомендації.

Особлива подяка – Міжнародному університету “РЕГІ” імені академіка Степана Дем'янчука та факультету кібернетики Київського національного університету імені Тараса Шевченка, за підтримки яких і було написано цей навчальний посібник.

13

1. ОСНОВИ ТЕХНОЛОГІЇ ПРОГРАМУВАННЯ.

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

Н.Вірт

Н. Вірт визначає поняття програмування в заголовку своєї книги1: Алгоритми + Дані = Програми. Іншими словами можна сказати, що програма - це інструментарій для виконання деяких дій над деякими даними. Що таке програмування? Це — наука чи мистецтво? Давно була запропонована правильна відповідь — "технологія". А головна ідея будь-якої технології - створення таких умов, коли реалізація процесу мінімально залежить від суб'єктивних факторів. Зокрема, це означає, що сучасні засоби програмування повинні забезпечувати максимальний захист від можливих помилок розробника.

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

У роботі [3] визначено: «Основними видами людської інтелектуальної діяльності, що вивчається в інформатиці, є:

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

алгоритмізація (реалізація причинно-наслідкових зв'язків і інших закономірностей у вигляді направленого процесу обробки інформації за формальними правилами);

програмування (реалізація алгоритму на ЕОМ);

виконання обчислювального експерименту (здобуття нового знання про явище, що вивчається, або об'єкт за допомогою обчислення на ЕОМ);

1Вирт Н. Алгоритмы+Структуры данных=Программа. - М.:Мир, 1989

2С.И. Ожегов. Словарь русского языка. - М.: Советская энциклопедия, 1975.

3Развитие определения «информатика» и «информационные технологии». - Препринт. АН СССР, Институт проблем информатизации; Под ред. И.А. Мизина. - М.: 1991.

14

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

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

Отже, програмування, як технологія в своєму розвитку пройшло наступні етапи.

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

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

Відбувається поступове розширення області застосування ком- п'ютерної техніки. Це ускладнює сам процес програмування. Ставиться і успішно розв'язується задача створення мов, які спрощують етап власне кодування алгоритмів. Процедурний підхід зажадав структуризації майбутньої програми, розділення її на окремі процедури. При розробці окремої процедури про інші процедури вимагалося знати лише їх призначення і спосіб виклику. Зростання складності програм приводить до появи технології структурного програмування. Робляться спроби формалізувати програмування як наукову дисципліну. Виходять роботи видатних учених Э. Дейкстри4, Ч. Хоара5, Э.

4Дейкстра Э. Дисциплина программирования. - М.: Мир, 1978.

5Хоар Ч. Программирование как инженерная профессия// Микропроцессорные средства и системы. 1984, 4. - С.

53-60.

15

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

У свою чергу, Е. Йодан розглядав структурне програмування, перш за все, з погляду всього процесу розробки, починаючи від проектування і завершуючи тестуванням і документуванням. Відзначимо, що структурні методи написання програм складають фундамент технології низхідного, поетапного програмування, тобто безпосередньо пов'язані з питаннями управління проектом в цілому.

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

Даний підхід можна охарактеризувати, як деревовидна технологія структурного програмування.

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

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

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

Існує також напрям, який, аналогічно, можна назвати висхідним

6 Йодан Э. Структурное проектирование и конструирование программ. - М.: Мир, 1979.

16

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

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

Основними правилами для успішного застосування даної технології є:

формалізований і строгий опис програмістом входів функцій і виходів всіх модулів програми і системи;

узгоджена розробка структур даних і алгоритмів;

обмеження на розмір підпрограм.

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

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

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

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

формальні системи теорії обчислюваності, загальні рекурсивні функції, системи Поста, алгоритми Маркова, лямбда числення Черча;

аналіз програм по низхідній схемі, декомпозиція, заснована на розбитті задач по рівнях 0, 1, ..., к.

17

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

функціональний блок (або конструкція проходження);

конструкція узагальненого циклу;

конструкція двійкового або дихотомічного розв’язання. Характерними рисами структурного програмування є:

простота і ясність (коментування);

використання лише базових конструкцій;

відсутність багатоцільових функціональних блоків;

відсутність невиправдано складних арифметичних і логічних конструкцій;

розташування в рядку програми не більше одного оператора мови програмування;

змістовність імен змінних.

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

Подальший розвиток структурного програмування привів до появи його різновиду – модульного програмування. Незалежні фрагменти задачі оформляються як модулі.

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

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

7 Bohm C., Jacopini G. Flow Diagrams Turing Machines, and Languages with Only Two Formulation Rules, Communicatins of the ASM, May, 1966.

18

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

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

Програмування пройшовши наївну і формальну фазу розвитку, (злегка переформулючи Гільберта) вступає у фазу практичну.

Має сенс навести цитату з книги Г. Майерса8 : «Низхідне функціональне проектування погано адаптується до розробки великих програмних систем. Низхідне проектування залишається корисною парадигмою для малих програм і індивідуальних алгоритмів..., але воно практично не масштабується на великі системи. Зміст не у тому, що Ви не можете розробляти систему зверху вниз: можете. Але, виторговуючи для себе короткочасову зручність за тривалу негнучкість, Ви некоректно нагромаджуєте одну функцію над іншою і (досить часто) функціональний інтерфейс над важливішими параметрами системи. Ви втрачаєте із виду аспект даних, і Ви жертвуєте можливістю багатократного використовування».

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

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

Як сказав Лейбніц: «Метод розв’язання хороший, якщо із самого початку ми можемо передбачати - і далі підтвердити це, - що, слідуючи цьому методу, ми досягнемо мети».

8 Г. Майерс. Надежность программного обеспечения. - М.: Мир, 1980.

19

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

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

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

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

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

20

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]