Розробка програм мовою С++
Розробка програм мовою С++
ЗМІСТ - ВСТУП
- РОЗДІЛ 1 Функції
- 1.1 Модульна структура програм і способи інформаційного зв'язку модулів
- 1.2 Визначення, оголошення та виклик функції
- 1.3 Організація та активація функцій з іеформаційним зв'язком через аргументи і параметри. Передача значень функції
- 1.4 Використання вказівників при роботі з функцією, з даними аргумента і параметрами. Передача вказівників
- 1.5 Передача за посиланням
- 1.6 Організація та активація функцій з інформаційним зв'язком через зовнішні змінні
- 1.7 Рекурсивні функції
- 1.8 Вбудовані функції
- 1.9 Перевантажені функції
- РОЗДІЛ 2 Програмні модулі
- 2.1 Завдання 1 Структури
- 2.1.1 Постановка завдання
- 2.1.2 Програма та програмна реалізація
- 2.1.3 Тестування завдання
- 2.2 Завдання 2 Фукція
- 2.2.1 Постановка завдання
- 2.2.2 Програма та програмна реалізація
- 2.2.3 Тестування завдання
- 2.3 Завдання 3 Масиви
- 2.3.1 Постановка завдання
- 2.3.2 Програма та програмна реалізація
- 2.3.3 Тестування завдання
- 2.4 Завдання 4 Операції над лінійним списком
- 2.4.1 Постановка завдання
- 2.4.2 Програма та програмна реалізація
- 2.4.3 Тестування завдання
- 2.5 Програма-монітор
- 2.5.1 Постановка завдання
- 2.5.2 Програма та програмна реалізація
- 2.5.3 Тестування завдання
- ВИСНОВКИ
- ПЕРЕЛІК ПОСИЛАНЬ
- ДОДАТКИ
ВСТУПС++ - це універсальна мова програмування середнього рівня, яка підтримує більшість сучасних концепцій програування, характеризується достатньою потужністю, доброю структурованістю, високою ефективністю, можливістю безпосереднього доступу до дних, компактністю. В даному курсовому проекті наведені приклади реалізації програм таких розділів прогамування як файли, адреси даних та вказівники, цикли, масиви, графічний режим.В теоретичній роботі розглядається організація функцій у прграмах і реалізація звернень до них.РОЗДІЛ 1. ФУНКЦІЇ1.1 Модульна структура програм і способи інформаційного зв'язку модулів Програмне забезпечення автоматизованих комплексів задач має, як правило, модульну структуру, тобто складається з послідовності окремих модулів, упорядкованих за певною системою. У різних інструментальних системах програмування модуль постає у вигляді певної структурної одиниці: блоку, підпрограми, функції. У мові С++ модулем є функція. Проектування програмного забезпечення здійснюється за заздалегідь вибраною проектувальником стратегією. Найчастіше використовується стратегія низхідного структурного проектування, під час якого розробка починається з визначення загальної функції, або ж мети, яка повинна бути реалізована ком-плексом загалом, а потім реалізовується покрокова деталізація цієї функції доти, доки весь комплекс не буде описаний достатньою мірою докладно. На кожному кроці одну чи кілька окремих підцілей функцій представляють або за допомогою окремих модулів, або груп модулів. При цьому з'являється необхідність у деталізуванні нових функцій і т. д. Зрештою, загальна функція програмного комплексу виражається за допомогою еквівалентної структури відповідним чином сполучених підфункцій. Кожна з таких підфункцій вирішує лише частину задачі, однак вона є простішою від початкової функції і часто допускає подальше розбиття, об'єднання та пере-вірку. Описаний процес не повинен бути чисто формальним. Якщо отримана на якомусь кроці функція достатньо проста, то її не слід штучно ускладнювати шляхом подальшого розбиття. Після того, як визначена функціональна структура програмного комплексу, з'ясовується технологія обробки даних, тобто здійснюється вибір пакетної або діалогової технології. У теперішній час найчастіше використовується діалогова технологія, при якій доступ користувача до процесу обробки даних різко розширюється, тобто користувач отримує можливість звертатися послідовно до модулів, що обробляють кожен крок. Інтерфейс користувача, тобто його зв'язок з процесом обробки даних, у цьому варіанті доцільно реалізувати на основі системи меню різного рівня ієрархії. Програмний комплекс мовою С++ являє собою множину функцій, між якими реалізуються визначені інформаційні зв'язки і які активізуються в наперед визначеній та ієрархічно упорядкованій послідовності. Після визначення модульної структури програмного комплексу програміст вирішує питання про структуру вхідних та вихідних даних, які мають бути строго уніфіковані в межах задач, про склад робочих змінних та класи використовуваної пам'яті. Для вибору класу пам'яті для кожної конкретної змінної аналізуються можливості передавання її значення в інші модулі, вимоги до збереження її значення в мо-мент завершення певного модуля. Область дії змінних вибирається в межах викорис-товуваного програмістом класу пам'яті, визначає вид інформаційного зв'язку між окремими модулями. Якщо програма використовує автоматичні чи реєстрові змінні, то міжмодульний зв'язок повинен бути організований через аргументи і параметри, які без-посередньо вказуються у процесі звертання до функції і в заголовковій її частині. У цьому разі йдеться про використання функції з параметрами. При використанні вказаних вище видів змінних може виникнути ситуація, коли необхідно активізувати функцію без передавання аргументів, тобто між модулями не існує інформаційного зв'язку. В цьому випадку функція оформлюється як функція без параметрів і в момент її активізації список аргументів не описується. Якщо програміст використовує зовнішні змінні, то інформаційний зв'язок між модулями здійснюється на їх основі без передавання аргументів та параметрів. У цьому разі говорять про використання функції без параметрів. 1.2 Визначення, оголошення та виклик функції Функція -- це логічно самостійна частина програми, котрою можуть передаватися параметри і яка може повертати значення. Кожна функція повинна мати ім'я для виклику функції. Ім'я одної з функцій -- main( ) -- має бути присутнім у кожній програмі, і воно зарезервоване. При роботі з локальними змінними інформаційний зв'язок є єдиним видом міжмодульного зв'язку. З використанням функцій у мові С++ пов'язані три поняття: визначення функції; оголошення функції; виклик. Визначенням функції називається код, який описує те, що робить функція. Визначення функції потрібно проводити за такою схемою: <тип вертаного значення> <ім'я функції> (<список параметрів>) { <тип> <внутрішні змінні>; <оператори; [return(вираз);] } Перед першою фігурною дужкою стоїть заголовок визначення функції, між фігурними дужками міститься тіло визначення функції. Тіло функції -- це складовий оператор, що містить операто-ри, які визначають дії функції. Синтаксис мови С++ забороняє всередині визначення функції поміщати визначення ще однієї функції. Тексти всіх функцій повинні бути записані послідовно, один за іншим. void fun (int х, float у) // заголовок функції { // початок тіла функції ... } // кінець тіла функції Тип вертаного функцією значення вказує тип даних результату, що повертається із функції оператору її виклику. В С, якщо тип значення, що повертається функцією, не заданий, то функція за замовчуванням повертає значення int. В С++ необхідно явно оголошувати тип значення, що повертається функціями. Якщо функція не вертає значення, то її тип повинен бути вказаний як void. Ім'я функції формується за правилами написання ідентифікатора. Потрібно пам'ятати, що синтаксис мови С++ чутливий до регістра символів, тому int Fun( ) int fun( ) int FUN( ) відносяться до заголовків трьох різних функцій. Список параметрів -- інакше його називають списком формальних параметрів -- розділений комами список змінних, які приймають значення в момент активізації функції під час її виклику. Як об'єкти списку можуть використовуватися прості змінні, масиви, вказівники, а також типи, що визначаються користувачем. Список параметрів може бути відсутнім, тоді список параметрів задається як void. Список параметрів береться в круглі дужки, після яких точка з комою не ставиться. С++ відрізняється від С способом завдання порожнього списку параметрів. У С порожній список параметрів означає, що перевірка аргументів відсутня, при виклику функції може бути переданий будь-який аргумент. У С++ це означає відсутність аргументів, наступні два оголошення еквівалентні. Наприклад, int fun ( ); int fun (void); Усі об'єкти списку мають бути описані відповідними типами безпосередньо в списку параметрів перед відповідним елементом списку. float Sum (float v, int d) Потім записується складний оператор, у якому описуються змінні, що беруть участь у розрахунках усередині функції і за необхідності оператор повернення значення return. Оператор return може повертати в точку виклику функції лише одне значення, яке може бути виразом, змінною, константою чи вказівником. Крім передачі значень оператор return завершує виконання функції і передає керування наступному оператору викличної функції, навіть у тому разі, якщо він не є останнім. Коли функція не повертає ніякого значення, то вираз в операторі відсутній, у цьому випадку оператор return можна опустити. Звертання до функції має бути реалізоване з іншої функції, в якій обов'язково повинен міститися опис типів вертаного функцією значення і бути вказане ім'я функції зі списком аргументів (або ж фактичних аргументів чи фактичних параметрів) у потрібному місці будьякого виразу. <ім'я функції> (<список аргументів>); Аргументи повинні бути попередньо описані. У списку аргументів вони знаходяться у тій самій послідовності, що й у списку параметрів функції. Аргументи передаються з викличної функції в функцію, що викликається, за значенням, тобто обчислюється значення кожного виразу, що представляє аргумент, і це значення використовується в тілі функції замість відповідного формального параметра. Аргументи можуть бути константами, простими змінними, масивами, вказівниками. Безпосередньо в момент активізації функції відбувається формування стека передаваних у функцію значень, в якому довжина кожного значення визначається типом аргументу, що передається. Виняток становлять вказівники, при їх використанні відбувається не передавання значень, а переад-ресація параметрів функції за конкретними адресами пам'яті. Оголошення функції -- це оператор, що включає в себе тип вертаного значення, ім'я функції та її параметри. Цей оператор закінчується крапкою з комою. Мова С++ вимагає, щоб оголошення функції передувало її визначенню або першому використанню в програмі. Таке оголошення називається прототипом функції. Прототип функції вказує компілятору тип даних, що повертаються функцією, кількість параметрів, яку чекає функція, тип параметрів і очікуваний порядок їх слідування. Компілятор використовує прототип функції для перевірки правильності викликів функції. Прототип функції має вигляд: <тип вертаного значення> <ім'я функції> (<список аргументів>); Наприклад, int sum (int, int, int); Цей прототип вказує, що sum має три аргументи типу int і повертає результат типу int. Прототип розміщується у викличній програмі до заголовку main( ). При наявності прототипу передбачається перетворення аргументів до активізації функції в тип, завданий для відповідно-сті параметрів у прототипі. Наприклад, int f(float а, float b) main ( ) { float a1, int b1; t = f(a1, b1); . . . } Невідповідність типів аргументів та параметрів може призвести до неправильної інтерпретації передаваних значень у момент активізації функції, коли формується стек значень, передаваних у функцію. Прототип функції, розміщений поза описом якоїсь функції, відноситься до всіх викликів даної функції, які виникають після цього прототипу в даному файлі. Прототип функції, розміщений всередині опису певної функції, відноситься лише до викликів усередині цієї функції. Другим способом оголошення функції перед використанням є поміщення прототипів функцій у заголовний файл (файл з роз-ширенням .h), який підключається директивою #include до тексту програми. Списки аргументів і параметрів можуть містити невизначену кількість об'єктів. У цьому разі у списку параметрів після останнього ставляться крапки. Якщо у списку параметрів вказані тільки крапки, то список може бути порожнім. Прототип функції, заголовок функції і виклик функції повинні бути узгоджені між собою за кількістю, типом, порядком сліду-вання аргументів і параметрів та за типом вертаних значень. Наприклад, визначена користувачем функція sum( ) використовується для розрахунку суми ряду. Ця сума вертається з допо-могою оператора return у функцію main( ) і виводиться на друк. // Підрахунок суми ряду #include<iostream.h> int sum(int, int, int); // прототип функції main() { int nach, kon, shag; cout << "\n Введіть початкове значення члена ряду: "; cin >> nach; cout << "\n Введіть кінцеве значення члена ряду: "; cin >> kon; cout << "\n Введіть крок зміни члена ряду: "; cin >> shag; cout << "\n Сума ряду дорівнює " << sum (nach, kon, shag); return 0; } // Визначення функції sum int sum (int nachr, int konr, int shagr) { int i, sumr = 0; for(i = nachr; i< = konr; i+ = shagr) sumr+ = i; return (sumr); } 1.3 Організація та активація функцій з іеформаційним зв'язком через аргументи і параметри. Передача значень функції В С++ є три способи передачі аргументів у функцію: передача за значенням, передача за посиланням з аргументами-вказівниками і передача за посиланням з аргументами-посиланнями. Коли аргументи передаються в функцію за значенням, то відбувається створення копій аргументів, передача їх у функцію і присвоєння параметрам. Викликана функція працює з копією аргументів, тому жодні зміни значень параметрів не відіб'ються на зміні аргументів. Якщо за значенням передається більше, ніж один аргумент, то копії кожної з них присвоюються відповідним параметрам функції, яку викликають. У попередньому прикладі функція sum( ) передає копії змінних nach, kon, shagr, які використовуються функцією як значення для параметрів nachr, konr, shagr. Виклик функції за значенням застосовується в тих випадках, коли обсяг аргументів, що передаються в функцію, невеликий і функція не повертає великого об'єму даних. 1.4 Використання вказівників при роботі з функцією, з даними аргумента і параметрами. Передача вказівників Щоб мати можливість безпосередньо змінювати значення змінних викличної програми, необхідно використати передачу за посиланням з аргументами-вказівниками. Це, звичайно, необхідне в разі, коли в викличну програму потрібно передавати більше одного значення і повернути більше за одне значення. При цьому передаються не копії змінних, а копії адрес змінних. Функція, використовуючи вказівник, здійснює доступ до потрібних елементів пам'яті, і можна змінювати значення об'єкта, розташовані за цією адресою. Дана передача дозволяє передавати в викличну функцію масиви як аргументи. Якщо масив використовується як аргумент функції, передається тільки адреса масиву, а не копії всіх елементів. При виклику функції з ім'ям масиву в функцію передається вказівник на перший елемент масиву. Існує кілька способів оголошення параметра, призначеного для отримання вказівника на масив. Перший варіант полягає в тому, щоб використати як аргумент функції ім'я масиву. При передачі масиву в функцію передається також розмірність, щоб функція могла обробляти задане число елементів у масиві. Наявність розмірності індексів в оголошенні параметра повідомляє функцію, як розташовані елементи в масиві. Якщо ми передаємо одновимірний масив як аргумент функції, в списку параметрів функції розмірність може бути опущена, тобто квадратні дужки будуть порожніми. Розмірність першого індексу багатомірного масиву також можна не вказувати, але вся інша розмірність індексів повинна бути зазначена. Другий спосіб полягає в тому, щоб використати як аргумент функції вказівник на масив. 1.5 Передача за посиланням В С++ можна здійснювати передачу за посиланням з аргументами-посиланнями. Посилання є неявним вказівником і використовується як інше ім'я вже існуючого об'єкта. Формат визначення посилання є таким: <тип>& <ім'я посилання> = <вираз; або <тип>& <ім'я посилання> (<вираз>); Як вираз, що ініціалізується, має бути ім'я певного об'єкта, що має місце в пам'яті. Значенням посилання після визначення з ініціалізацією стає адреса цього об'єкта. Наприклад, int х = 7; //Визначена й ініціалізована змінна х int& ref= х;//Визначене посилання, значенням її є адреса змінної х Для доступу до вмісту ділянки пам'яті, на який вказує посилання, не треба виконувати розіменування, що є обов'язковим при зверненні до значення змінної через вказівник. Кожна операція над посиланням є операцією над тим об'єктом, з яким вона пов'язана. Можна змінити значення х, записавши х = 35; або ref = 35;. Існують обмеження при визначенні і використанні посилань: Не можна взяти адресу змінної типу посилань; Не можна створити масив посилань; Не можна створити вказівник на посилання; Не допускаються посилання на бітові поля. При використанні посилання як параметра забезпечується доступ із тіла функції до відповідного аргументу, тобто ділянки пам'яті, виділеної для аргументу, тобто початкова змінна може бути змінена за допомогою викличної функції. Щоб указати, що параметр функції передається за посиланням, після типу параметра в прототипі функції записується символ &. У виклику функції змінна вказується на ім'я, але вона буде передана за посиланням. 1.6 Організація та активація функцій з інформаційним зв'язком через зовнішні змінні Областю дії зовнішніх змінних є всі функції програмного комплексу, якщо ці змінні описані перед якою-небудь функцією, або як extern усередині функції. Це означає, що працювати з зовнішніми змінними можна в межах комплексу і значення, що формуються при цьому, доступні для всіх функцій. У цьому разі немає необхідності здійснювати міжмодульний зв'язок через аргументи і параметри, а достатньо лише активізувати необхідну функцію і продовжити виконання дії з зовнішніми змінними, які були розпочаті в інших функціях. Імена змінних в усіх функціях для позначення відповідних об'єктів повинні обов'язково бути однаковими. 1.7 Рекурсивні функції Функція називається рекурсивною, якщо вона викликає сама себе. Розрізняють пряму та непряму рекурсії. Функція називається непрямою рекурсивною в тому разі, якщо вона містить звернення до іншої функції, що містить прямий або непрямий виклик першої функції. Якщо в тілі функції явно використовується виклик цієї функції, то має місце пряма рекурсія. Класичним прикладом рекурсії є обчислення факторіала. Факторіал невід'ємного цілого числа n дорівнює n х (n-1) х (n-2) х. .. х 3 х 2 х 1, причому за визначенням факторіал 1! і 0! дорівнює 1. Факторіал числа дорівнює добутку попередніх щодо нього послідовностей чисел, тобто n! = nx(n-1)!. Якщо обчислення факторіала оформити у виді рекурсивної функції, то програма може бути подана в ось якому вигляді: // Обчислення факторіала #include <iostream.h> unsigned long factorial (unsigned int); void main( ) { int i; unsigned int n; cout << endl << "Введіть ціле додатне число"; cin >> n; for (i = 0; i< = n; i++) cout << endl << " Факторіал " << i << "!=" << factorial(i); return; } unsigned long factorial (unsigned int num); {if (n = = 1 ¦¦ n = = 0) return 1; else return (num*factorial(num-1)); } Рекурсивні функції обробляються повільно й займають більше стекової пам'яті, ніж їхні нерекурсивні еквіваленти. Надто велика кількість рекурсивних викликів функції може призвести до переповнення стека. Оскільки місцем зберігання параметрів і локальних змінних функції є стек, і кожен новий виклик створює нову копію змінних, простір стека може бути вичерпаний, це викличе помилку переповнення і призведе до аварійної зупинки програми. 1.8 Вбудовані функції Вбудовані функції (inline) -- це функції, чиє тіло підставляється в кожну точку виклику, замість того, щоб генерувати код виклику. Модифікатор inline перед вказівкою типу результату в оголошенні функції загадує компілятору згенерувати копію коду функції у відповідному місці, щоб уникнути виклику цієї функції. У результаті виходить множина копій коду функцій, вставлених у програму, замість єдиної копії, якою передається керування при кожному виклику функції. Модифікатор inline необхідно застосовувати для невеликих і часто використовуваних функцій. Наприклад, #include <iostream.h> inline int min (int x1, int y1) { if (x1 < y1) return (x1); else return (y1); } void main( ) { int х, у, z; { cout << endl << "Введіть два цілих числа "; cin >> х >> у; z = min(х, у); cout << endl << " Мінімальним з " << х << " і " << у << " є " << z; } Компілятор може ігнорувати модифікатор inline, якщо вбудований код надто великий, компілятор згенерує звичайний виклик функції. 1.9 Перевантажені функції С++ дозволяє визначати функції з однаковими іменами, але унікальними типами аргументів. У цьому разі про функції кажуть, що вони перевантажені. Перевантаження функції використовується звичайно для створення кількох функцій з однаковим ім'ям, призначених для виконання схожих задач, але з різними типами даних. Наприклад, #include <iostream.h> int fun (int х, int у) { return (х*х+у*у);} float fun (float х, float у) { return (х*х+у*у); } main( ) { int x1 = 10, y2 = 3; float x2 = 13.75, y2 = 11.25 cout << endl <<"Сума квадратів чисел " << x1<< " і " << y1 << "дорівнює " << fun(x1, y1) << endl <<"Сума квадратів чисел " << x2<< " і " << y2 << "дорівнює " << fun(x2, y2) return 0; } Перевантажені функції розрізняються за допомогою сигнатури -- комбінації імені функції і типів її параметрів. Компілятор кодує ідентифікатор кожної функції за числом і типом її параметрів, це називається декорируванням імені, щоб мати можливість здійснювати надійне зв'язування типів. Надійне зв'язування типів гарантує, що викликається належна функція і що аргументи узгоджуються з параметрами. Компілятор виявляє помилки зв'язування і видає повідомлення про них. Кожне декороване ім'я починається з символу @, який передує імені функції. Закодований список параметрів починається з символів $g. Типи значень функцій, що повертаються, не відбиваються в декорованих іменах. Перевантажені функції можуть мати різні або однакові типи значень, що повертаються, і обов'язково повинні мати різні списки параметрів. Дві функції, відмінні лише за типами значень, що повертаються, викличуть помилку компіляції. РОЗДІЛ 2. Програмні модулі2.1 Завдання 1 Структури 2.1.1 Постановка завдання У файлі оперативної систекми «Task.in» зберігається в текстовій формі відмість з відомостями про продукти. Кожен рядок цього файлу містить відо-мості про один вид продукту, представлені у такому форматі: 1…2 - порядковий номер продукту; позиція 3 - пробільних літера; позиції 4…15 - назва продукту довжиною не більше 11 имволів, в довільному місці поля; позиція 16 - пробільних літера; позиції 17…19 - вміст білка в 100 грамах продукту (ціле). Кількість продуктів у відомості дорівнює 16. Приклад зазначеного файлу: 01 щука 20 02 сом 16 Написати: 1) визначення масиву структур для зберігання зазначеної відомості і фрагмент програми, який заповнить відомість даними, вводяться з файлу операційної системи «Task.in» (введення даних повинно здійснюватися в текстовому режимі); 2) фрагмент програми для знаходження і друку (у файл «Task.out») інформацію про продукт з найбільшим вмістом білка. 2.1.2 Програма та програмна реалізація Дане завдання реалізоване у модулі TASK1.CPP (TASK1.EXE) Для опису даної програми була введена структура (struct Tbook) та заданий масив (char name[20]) для зберігання даних даного типу. Реалізація програми здійснюється за допомогою файлів “Task_in” та “Task_out”. Зчитування проводиться стандартною функцією scanf згідно визначеного формату даних вхідного файлу «Task_in». Під час роботи програма визначає продукт з найбільшим вмістом білка. Результатом виконання є вивід інформації про продукт та її запис у вихідний файл «Task_out». Тіло програми повністю побудоване згідно алгоритму(додаток 7). Розглянемо програму: // Програма Task1.cpp #include <conio.h> #include <process.h> #include <fstream.h> #include <stdio.h> #include <dos.h> #include <math.h> struct Tbook { char name[20]; int index; float price; }; Tbook shelf[15]; FILE *taskin, *taskout; void TASK1() { clrscr(); printf("Chytania fajlu 'task.in'\n\n"); if((taskin = fopen("task.in", "rt")) == NULL) { perror("ERROR\n"); getch(); exit(errno); }; int i = 0; sqrt; while(i < 16) { if(fscanf(taskin,"%2i %11s %f\n", &shelf[i].index, shelf[i].name, &shelf[i].price ) == EOF) break; printf("%2i %11s %2.0f\n", shelf[i].index, shelf[i].name, shelf[i].price); i++; }; fclose(taskin); printf("\n...zavershene!"); float max=shelf[0].price; int ind=0; for(i = 0; i < 16; i++) { if (shelf[i].price>=max){max=shelf[i].price; ind=i;} }; printf("\n\nMaksymalnyj vmist bilka mae \"%s\" - %2.0f\n",shelf[ind].name,shelf[ind].price); printf("\n\nZapys u fajl 'task.out'"); taskout = fopen("task.out", "w+"); fprintf(taskout, "%2i %11s %2.0f", shelf[ind].index, shelf[ind].name, shelf[ind].price); fclose(taskout); printf("...zavershenyj!"); getch(); }; 2.1.3 Тестування завдання Для проведення тестування потрібно першочергово заповнити файл Task_in (з операційної системи). Даний файл було заповннено наступними значеннями(рис. 2.131). Після цього програму потрібно запустити. Результат виконання, а саме інформацію про продукт з найбільшим вмістом білка можна записаний у вихідному файлі Task_out(рис. 2.132). Рис. 2.131 Task_in Рис. 2.132 Task_out 2.2 Завдання 2 Фукція 2.2.1 Постановка завдання Знайти величину і номер першого негативного і останнього позитивного елементів у масиві дійсного типу заданого розміру. 2.2.2 Програма та програмна реалізація Дане завдання реалізоване у модулі TASK2.CPP (TASK2.EXE) У підпрограмі оголошено масив(float a[100]), змінна n-відповідає кількості елементів у масиві, також є дві функції (int pos, int neg) - одана шукає намер першого негативного елементу масиву, інша номер останнього позитивного елементу масиву. Тіло програми повністю побудоване згідно алгоритму(додаток 8). Розглянемо програму: // Task2.cpp #include <iostream.h> #include <conio.h> //-------------------- int pos(float *a, int n) { int i=n-1; while (a[i]<0) i--; return i; } //---------------------- int neg(float *a, int n) { int i=0; for (i=0; i<=n; i++) if (a[i]<0) break; return i; } //------------------------- void TASK2() { clrscr(); int i,n; int k1; int k2; float a[100]; cout<<"Vvedit velychynu masyvu:"; cin>>n; if (n>1) { for (i=0; i<=n-1; i++ ) { cout<<"Vvedit znachenia Masyv["<<i<<"]:"; cin>>a[i]; k1=pos(a,n); k2=neg(a,n); } } cout<<"\n\n"; cout<<"Pershyj negatyvnyj element maje nomer "<<k2+1<<",a jogo vmist: "<<a[k2]<<endl; cout<<"Ostannij pozytyvnyj element maje nomer "<<k1+1<<",a jogo vmist: "<<a[k1]; getch(); } 2.2.3 Тестування завдання Для перевірки даної підпрограми мною були введені дані про кількість елементів у масиві та власне сам масив. В результаті був отриманий результат - номер та власне саме значення першого негативного та останнього позитивного елементів у масиві(рис. 2.321).
Рис. 2.321 Тестовий приклад Task2.срр 2.3 Завдання 3 Масиви 2.3.1 Постановка завдання Елемент матриці називають локальним мінімумом, якщо його значення строго менше значень всіх наявних сусідів. Підрахувти кількість локальних мінімумів заданої матриці і надрукува інформацію про кожного з них. 2.3.2 Програма та програмна реалізація Дане завдання реалізоване у модулі TASK3.CPP (TASK3.EXE) На початку програми оголошений масив р[10][10]. Оголошений лічильник k - який підраховує кількість локальних мінімумві у матрицці. Під час запуску підпрограма запитує користувача розмірності матриці n. Після цього вона заповняється елементами. Наступним етапом є опрацювання матриці оператором for. Після опрацювання виводиться повідомлення про кількість локальних мінімумів k та інфориація про кожного з них. Програма побудована згідно алгоритму: void TASK3()
Розглянемо програму: //Task3.cpp #include <iostream.h> #include <conio.h> void TASK3(){ clrscr(); int i,j,n,k,k1; k=0; int p[10][10]; cout<<"Vvedit znachenia n:"<<"\n"; cin>>n; for (i=0; i<=n-1; i++ ){ for (j=0; j<=n-1; j++){ cout<<"Vvedit znachenia p["<<i<<"]["<<j<<"]: "; cin>>p[i][j];} } for (i=0; i<=n-1; i++ ) for (j=0; j<=n-1; j++){ k1=0; if ((i==0) || (p[i-1][j]>p[i][j])) k1++; if ((i==n-1) || (p[i+1][j]>p[i][j])) k1++; if ((j==0) || (p[i][j-1]>p[i][j])) k1++; if ((i==n-1) || (p[i][j+1]>p[i][j])) k1++; if (k1==4){k++; cout<<"Inform pro lokalnuy minimymiv"<<endl; cout<<"p["<<i<<"]["<<j<<"]="<<p[i][j]<<endl; } cout<<endl;} cout<<"Kilkist lokalnux minimymiv\n"<<k; getch(); } 2.3.3 Тестування завдання Для тесту були введені наступні значення(рис. 2.331). В результаті був отриманий наступний результат:
Рис. 3.31 Тестовий приклад Task3.cpp
2.4 Завдання 4 Операції над лінійним списком. Робота з динамічною пам'яттю 2.4.1 Постановка завдання Визначено наступний покажчик на початок лінійного списку: struct Node // NODE: вузол лінійного списку { Node *pLink; // Pointer LINK: // Покажчик на черговий вузол float Info // INFOrmation: інформація } *Start; Написати прототип, визначення і приклад виклику функції для видалення зі списку k останніх елементів із звільненням зайнятої ними пам'яті. В окркмому випадку, перед викликом цієї функції лінійний список може бути порожній або може містити будь-яку кількість елементів. Усі вихідні дані (покажчик на корінь лінійного списку, кількість що видаляються елементів) і результати виконання функції (покажчик на початок лінійного списку) повинні передаватися через список параметрів. 2.4.2 Програма та програмна реалізація Дане завдання реалізоване у модулі TASK4.CPP (TASK4.EXE) Опишемо алгоритм роботи даної програми: Створено список (Node *pLink;),у якому оголошено наступні функції: void func(Node *Start); // Відповідає за видалення елементів зі списку void vvid(); // Вводимо елементи списку (кінцевий елемент - 0) void vuvid(Node *Start); // Виводить результат, без останніх k- елементів void clear(Node *Start); // Звільняє займану ними пам'ять Розглянемо програму: // Task4.cpp #include <iostream.h> #include <conio.h> struct Node { Node *pLink; float Info; } *Start, *Cur, *New, *Prev; int n=0; void func(Node *Start); void vvid(); void vuvid(Node *Start); void clear(Node *Start); char Empty; void TASK4() { clrscr(); vvid(); vuvid(Start); func(Start); vuvid(Start); clear(Start); getch(); } void vvid() { cout << "Vvedit elementu spusky (kintsevuj element - 0):\n"; Cur = new Node; Start = Cur; do { Prev = Cur; cin >> Cur->Info; Cur->pLink = new Node; Cur = Cur->pLink; n++; } while(Prev->Info != 0); Prev->pLink = NULL; delete Cur; n--; Cur = Start; while(Cur->pLink != NULL) { Prev=Cur; Cur=Cur->pLink; } if(Start==Cur) Start = NULL; else { Prev->pLink=NULL; delete Cur; } } void vuvid(Node *Start) { if(Start != NULL) { cout << "\n\nVvedenuj spusok:\n"; Cur = Start; while(Cur != NULL) { cout << Cur->Info << " "; Cur = Cur->pLink; } cout << "\n\n"; } Else { cout << "\nVu ne vvelu spusok"; Empty ='y'; } } void func(Node *Start) { if(Start != NULL) { int k; Cur=Start; cout << "Vvedit kilkist elementiv do vudalennja: "; cin >> k; if(k<n) { for(int i=0; i<(n-k); i++) { Prev=Cur; Cur=Cur->pLink; } Prev->pLink=NULL; while(Cur!=NULL) { Prev=Cur; Cur=Cur->pLink; delete Prev; } } else cout << "Vu vvelu kilkist bilshy abo rivny kilkosti elementiv y Zpusky"; } } void clear(Node *Start) { if(Start != NULL) { Cur = Start; while(Cur != NULL) { Prev = Cur; Cur = Cur->pLink; delete Prev; } delete Cur; } }
2.4.3 Тестування завдання При запуску програми з'являється повідомлення з проханням ввести елементи списку (кінцевий елемент списку - 0). Вводимо елементи списку. Натискаємо клавышу enter і появляється перелік всіх введених елементів списку. Після цього слід ввести кількість k - останніх елементів для видалення з кінця списку із звільненням займаної ними пам'яті. Кінцевим результатом є вивід на екран списку без k останніх елементів і звільнення займаної ними пам'яті(рис. 3.41).
Рис. 3.41 Приклад видалення k останніх елементів зі списку із звільненням пам'яті 2.5 Програма-монітор 2.5.1 Постановка завдання Написати програму-монітор,яка б об'єднувала всі модулі, додати інформацію про автора і протестувати роботу проекту 2.5.2 Програма та програмна реалізація Дане завдання реалізоване у модулі MAIN.CPP (MAIN.EXE) Даний проект складається з 6 модулів та основного модуля, в якому міститься головна функція main() проекту. Додаткові модулі не зв'язані один з одним, а лише з головним модулем. Загальна схема проекту із способами взаємодії між модулями наведена на рисунку 2.521 Рис. 2.521 Схема проекту Розбиття програми на різні процедури визначається логічною структурою програми. Використання додаткових модулів дозволило спростити реалізацію проекту та більш наочно показати взаємодію одних частин проекту з іншими та значно зменшити час на відлагодження та компіляцію цілого проекту. MAIN.CPP (додаток 1) - основний файл проекту, в ньому знаходиться послідовність дій програми, тобто в даному модулі програма викликає інші підмодулі які виконуюсь певну функцію. Програма спочатку запускає електронну титульну сторінку курсової роботи і для продовження просить натиснути будь яку клавішу, після цього виводить головне меню, в якому запитує виконання наступної дії. Після кожної виконаної дії програма виводить головне меню. Всі ці дії безпосередньо виконуються лише запуском відповідних функцій з додаткових модулів. Крім того, функція GRAPH() ініціалізує графічний режим, підключаючи BGI драйвер EGAVGA.BGI. Програма-монітор побудована згідно алгоритму(додатку 5). Опишу словесно алгоритм роботи основного модулю проекту. Цей модуль є основним меню програми, в якому надається змога вибрати любе завдання. Він містить наступні функції: void TYTUL() - виводить титульну сторінку проекту, void GRAPH() - ініціалізує графічний режим, підключаючи BGI драйвер EGAVGA.BGI, void TASK1() - запускає перше завдання на виконання, void TASK2() - запускає друге завдання на виконання, void TASK3() - запускає третє завдання на виконання, void TASK4() - запускає четверте завдання на виконання, void AVTOR() - виводить повідомлення про автора проекту. До нього підключаються усі інші модулі програми і саме з нього вони починають своє виконання. При запуску програми цей модуль починає виконання TYTUL, тобто він ініціалізовує графічний режим і виводить титульну сторінку на екран. Після цього необхідно натиснути будь-яку клавішу, щоб повернутися в головне меню. Кожному пункту меню відповідає відповідна цифра, після вводу якої запускаються інші функції (наприклад підкючення графічного режиму за допомогою функції GRAPH() і виконання підпрогами виводу повідомлення про автора - AVTOR(), це ввід цифри 6). Підпрограма AVTOR(додаток 3). Спочатку встановлюється колір фону, після цього встановлюється колір тексту, що містить іформацію про автора. Після цього виконується затримка цього зображення на екрані монітора за допомогою функції getch() і після натискання будь-якої клавіші виконується очистка екрану за допомогою функції clrscr() і пвернення до основного меню. Підпрограма TYTUL(додаток 2) містить лише іншу текстову інформацію. Після натискання клавіші enter підпрограма повертається у головне меню функції main().
2.5.3 Тестування завдання Для запуску програми потрібно запустити на виконання файл MAIN.EXE. Для вірної роботи програми у тій же папці має бути файл-драйвер EGAVGA.bgi. Дана програма може працювати під управлінням операційної системи сімейства Windows, починаючи від версії 95 та під управлінням ОС MS-DOS. Мінімальні системні вимоги для коректної роботи програми: - операційна система Windows 95, Windows 98 або MS-DOS; - процесор - не менше 80386; - оперативної пам'яті - 512 Кб; - відеокарта - 16 біт; - вільного місця на жорсткому диску - 1Мб. Після запуску програми спочатку бачимо зображення електронної титульної сторінки (рис. 2.531). Рисунок 2.531 - Зображення електронної титульної сторінки Програма чекає, поки буде натиснута довільна клавiша. Після натискання з'являється меню програми, з варіантами виконуваних операцій (рисунок 2.532) Рис. 2.532 - Меню програми з варіантами дій Для того щоб запустити перший модуль необхідно ввести 2 і натиснути клавішу вводу. Після цього ми побачимо зображення подібне до рисунка 2.533 (зображення залежить від вхідних даних). Рис.2.533 - Завдання 1 Програма зберігає вихідні дані у файл TASK.OUT і чекає поки ми натиснемо будь-яку клавішу і потрапимо у головне меню. Якщо вводимо 3 і натискаєм клавішу вводу, то запуститься підпрограма знаходження значення величини і номеру першого негативного і останнього позитивноо елементів у масиві( рис. 2.534). Рис.2.534 - Завдання 2 Якщо введемо 4 і натискаєм клавішу вводу, то запуститься підпрограма знаходження кількості локальних мінімумів (рис. 2.535). Рис.2.535 - Завдання 3 Якщо введемо 5 і натискаємо клавішу вводу, то запуститься підпрограма видалення зі списку k останніх елементів із звільненням зайнятої ними памяті (рис. 2.536) Рис. 2.536 - Завдання 4 Якщо 6 і натискаємо клавішу вводу, появитьяс інформація про автора проекту(рис. 2.537). Рис.2.537 - Вивід повідомлення про автора програми Після натискання будь-якої клавіші ми потрапляєм у головне меню програми. Після вводу 7 і натисканні клавіші вводу, ми можем побачити, що програма припиняє своє виконання. ВИСНОВКИ Під час виконання даної курсової роботи я удосконалив свої знання в мові програмування С++ та навчився писати програми в середовищі Borland C++. Під час виконання даної роботи були опрацьовані всі розділи мови програмування С++. Детальніше зосереджена була увага на таких розділах як масиви (їх оголошення та ініціалізація), стрічки, функції, файли (а саме зчитування даних з файлу, виведення даних у файл), структури та їх оголошення, вказівники. Створення титульної сторнки та головного меню спонукало до більш детальнішого опрацювання графічного режиму та функцій для графічних побудов. ПЕРЕЛІК ПОСИЛАНЬ 1. Глинський Я.М., Анохін В.Є., Ряжська В.А. С++ і С++ Builder. Навч. посібн. 3-тє вид. - Львів: СПД Глинський, 2006. - 192с. 2. Пахомов Б.И. С/С++ и Borland C++ Builder для студента. - Спб.: БХВ-Петербург, 2006. - 448 с. 3. С/С++. Программирование на языке высокого уровня / Т.А. Павловская. СПб.: Питер, 2002. - 464 с 4. С для «чайников», 2-е издание.: Пер. с англ. - М.:ООО «И.Д.Вильямс», 2006. - 352с. 5. Сабуров С. Языки программирования C++. - М.: Бук_пресс, 2006. - 647 с. 6. http://soft.munic.msk.su/ Додаток 1 MAIN.CPP #include <graphics.h> #include <stdlib.h> #include <stdio.h> #include <iostream.h> #include <conio.h> #include <math.h> //Pidkljuchenia dod. fajliv #include "TYTUL.cpp" #include "GRAPH.cpp" #include "AVTOR.cpp" #include "TASK1.cpp" #include "TASK2.cpp" #include "TASK3.cpp" #include "TASK4.cpp" void main() { //Pochatkovyj vyvid tytulky GRAPH(); TYTUL(); closegraph(); int z=0; while (z!=6) { GRAPH(); int xmax=getmaxx(),ymax=getmaxy(); setcolor(BLACK); bar(0,0,xmax,ymax); settextstyle(0,0,1); setcolor(1); outtextxy(150,30,"MENU"); setcolor(0); outtextxy(50,40,"________________________________"); setcolor(4); outtextxy(50,50,"1 - TYTULKA"); setcolor(2); outtextxy(50,65,"2 - TASK1"); outtextxy(50,80,"3 - TASK2"); outtextxy(50,95,"4 - TASK3"); outtextxy(50,110,"5 - TASK4"); setcolor(13); outtextxy(50,125,"6 - PRO AVTORA"); setcolor(4); outtextxy(50,140,"7 - EXIT"); setcolor(0); outtextxy(50,146,"________________________________"); setcolor(0); outtextxy(50,450,"Vvedit nomer punktu z yakogo pochaty"); cin>>z; switch (z) { case 1: closegraph(); GRAPH(); TYTUL(); break; case 2: closegraph(); TASK1(); break; case 3: closegraph(); TASK2(); break; case 4: closegraph(); TASK3(); break; case 5: closegraph(); TASK4(); break; case 6: closegraph(); GRAPH(); AVTOR(); break; case 7: exit(1); break; } } closegraph(); } Додаток 2 TYTUL.CPP #include <graphics.h> #include <stdlib.h> #include <stdio.h> #include <iostream.h> #include <conio.h> #include <math.h> #include <dos.h> void TYTUL() { setcolor(2); rectangle(10,5,630,470); setcolor(6); setbkcolor(15); outtextxy(170,10,"MINISTERSTO OSVITY I NAUKY UKRAINY"); outtextxy(150,25,"LUCKUY NACIONALNY TECHNICHNY UNIVERSYTET"); setcolor(4); outtextxy(380,100,"Kafedra kompyuternoi ingenerii"); outtextxy(240,210,"Kursova robota"); outtextxy(250,230,"z predmety"); setcolor(GREEN); outtextxy(240,245,"\"Programuvannia\""); outtextxy(270,260,"na temy:"); outtextxy(200,275,"\"Rozrobka program movoju C++\""); setcolor(1); settextstyle (1,0,3); outtextxy (380,320,"Vykonav st.gr.KSM-12"); outtextxy (380,335,"Misyuk V.V."); outtextxy (380,350,"Pereviryla "); outtextxy (380,365,"Zavisha V.V."); setfillstyle(1,2); outtextxy (280,440,"Lutsk 2010"); setcolor(4); while (!kbhit()) { outtextxy(200,455,"Natysnit' bud' jaku klavishu..."); delay(1000); setcolor(15); outtextxy(200,455,"Natysnit' bud' jaku klavishu..."); delay(1000); setcolor(4); } clrscr(); } Додаток 3 AVTOR.CPP #include <graphics.h> #include <stdlib.h> #include <stdio.h> #include <iostream.h> #include <conio.h> #include <math.h> void AVTOR() { setbkcolor(15); setcolor(GREEN); outtextxy(240,210,"Vykonav st.gr. KSM-12"); setcolor(4); outtextxy(275,230,"Misyuk V.V/"); setcolor(GREEN); outtextxy(280,245,"Lutsk 2010"); outtextxy(200,getmaxy()-12,"Natysnit' bud jaku klavishu..."); getch(); clrscr(); }
Додаток 4
GRAPH.CPP #include <iostream.h> #include <graphics.h> #include <conio.h> #include <stdlib.h> void GRAPH(){ int gdriver = DETECT, gmode, errorcode; initgraph(&gdriver, &gmode, " "); errorcode = graphresult(); if (errorcode != grOk) { cout << "Pomylka:"<< grapherrormsg(errorcode); cout<< "\n Dlia vyhodu natysnit' bud' jaky klavishu"; getch(); exit(1); } } Додаток 5 Блок-схема алгоритму void main() Додаток 6 void AVTOR() Додаток 7 Блок-схема алгоритму void TASK1()
|