/b>Теоретична частинаБазова структура „розгалуження" забезпечує вибір одного з альтернативних шляхів алгоритму в залежності від перевірки деякої умови. Кожен зі шляхів веде до загального виходу незалежно від того, який шлях було обрано. Структура розгалуження реалізується в наступних варіантах:1. ЯКЩО - ТОУ С++ така структура реалізується з допомогою інструкції Ifif (умова)вираз абоif (умова) {. Вираз 1; вираз 2;.вираз n;)БЛОК-СХЕМА:2. ЯКЩО - ТО - ІНАКШЕIf/elseif (умова)вираз1; elseвираз2;вкладені конструкціїif (умова1) <if (умова2)вираз2;>elseвираз1;При позитивному результаті перевірки вибирається для виконання оператор, що безпосередньо йде за умовою, при негативному - оператор, що йде за символом else. Тобто, якщо перевірка умови дає результат true, то виконується вираз 1, в іншому випадку-вираз 2.БЛОК-СХЕМА:У програмах нерідко трапляється, що вибір дії залежить від результату декількох наступних перевірок - до першої, що завершилася успішно.Приклад:char ZNAC;int x,y,z;if (ZNAC == '-') x = y - z;else if (ZNAC == '+') x = y + z;else if (ZNAC == '*') x = y * z;else if (ZNAC == '/') x = y / z;3. ВИБІРДеякі спільні риси з умовними операторами мають оператори вибору (по мітці). Передбачається, що виконання програми розгалужується відповідно до однієї з декількох заздалегідь відомих ситуацій, позначених іменами у вигляді цілочисельних значень, рядків або ідентифікаторів.< оператор вибору>:: =case <вираз> ofпослідовність гілок>endcase<послідовність гілок >:: = <гілка>| <послідовність гілок >; < гілка >< гілка >:: = <мітка>: <оператор> [<мітка>: < гілка ><мітка>:: = <позначення значення>Вираз між case і of повинен виробляти значення того типу, якому належать усі мітки, серед яких не повинно бути однакових. Виконання оператора вибору починається з обчислення значення цього виразу. Потім знаходиться і виконується оператор з гілки, що містить отримане значення в якості однієї з міток.БЛОК-СХЕМАСинтаксис на С++switch (цілочисельний вираз) {case константа1:вираз 1;break;саsе константа2:вираз 2;break;case константа-n:вираз n;break;default:дія за замовчуванням; }Приклад#include <stdio. h>#include <string. h>#include <math. h>int main (void){char ch;float x,y;x=0.5;printf ("1 ");printf ("2 ");printf ("3 ");printf (" Enter your choice: ");do {ch = getchar (); /* read the selection fromthe keyboard */switch (ch) {case '1':y=sin (x);printf ("%f",y);break;case '2':y=cos (x);printf ("%f",y);break;case '3':y=sin (x) /cos (x);printf ("%f",y);break;}Завдання до лабораторної роботи:1. Скласти програму для знаходження розв'язку квадратного рівняння.2. Визначити номер квадранта, в якому знаходиться точка з заданими координатами х, у.3. Визначити, чи є задане число двозначним і парним.4. Ввести з клавіатури два рядки і порівняти їх за кількістю символів.Вимоги до оформлення звіту:Звіт повинен містити блок схеми алгоритмів і тексти програм до всіх завданьЛабораторна робота № 5АЛГОРИТМИ З ЦИКЛІЧНОЮ СТРУКТУРОЮТеоретична частинаЦиклічна композиція пропонує повторне виконання деякого внутрішнього оператора доти, поки існують умови для цього. Внутрішній оператор називають також тілом циклу. Програмний текст, що складає тіло, визначає умову продовження або завершення виконання циклу. Усе разом складає оператор циклу.Існує кілька видів циклів.<цикл із попередньою перевіркою>:: =while <логічний вираз> do<оператор>end doБЛОК-СХЕМАСинтаксис в С++· whilewhile (умова) {вираз1;вираз2;;вираз-n; }<цикл із перевіркою в кінці>:: =repeat<оператор>until < логічний вираз >БЛОК-СХЕМАdo{ вираз1;вираз2;вираз-n; }while (умова);<цикл із параметром>:: =for <параметр> - <початкове значення>step <крок>to < граничне значення >do <оператор>enddo<параметр>:: = <ідентифікатор>БЛОК-СХЕМАСинтаксис в С++:for(ініціалізуючий вираз; умовний вираз; модифікуючий вираз) {вираз1;вираз2;вираз-n; }Приклади програм1. Обчислити таблицю значень функції y=2x/ (1+sin (x/3)), якщо х змінюється в інтервалі від 1.5 до 6.5 з кроком 0.5#include <math. h>#include <stdio. h>double F (double x);int main (void){double xmax=6.5,dx=0.5; xmin=1.5;while (xmin<xmax){printf (“%d\n%d”, xmin,F (xmin));xmin+=dx;}return 0;}double F (double x){return 2*x/ (1+sin (x/3));}2. Задати масив з 4 елементів і знайти його найменший елемент#include <stdio. h>int main (void){double X [4];double min;int i;printf (“Enter the elements”);for (i=0; i<=4; i++)scanf ("%d\n", &X [i]);min=X [0];for (i=1; i<=4; i++){if (X [i] <min)min=X [i];}printf (“Minimal is %d”,min)return 0;}Завдання до лабораторної роботи1. Обчислити таблицю значень функції y=0,5/ (1/x+lnx), якщо х змінюється в інтервалі від 10 до 25 з кроком 1.5 Вивести на екран значення, що знаходяться в межах 0.16-0.182. Задати масив з 5 елементів і знайти суму додатних елементів і добуток від'ємних3. Задати слово і порахувати, скільки разів в нього входить літера А.Вимоги до оформлення звіту:Звіт повинен містити блок схеми алгоритмів і тексти програм до всіх завданьЛабораторна робота №6Робота з вказівниками1. Теоретична частинаВказівник - це змінна, в якій зберігається адреса іншого об'єкта. Якщо змінна містить адресу іншої змінної, прийнято говорити, що вона посилається на неї.Змінна, що зберігає адресу комірки пам'яті, має бути оголошена як вказівник. Оголошення вказівника складається з імені базового типу, символу * і імені змінної. Загальна форма виглядає наступним чином:int *p;Базовий тип вказівника визначається базовим типом змінної, на яку він посилається.Існує два спеціальні оператори роботи з вказівниками - це оператор розіменування вказівника * і оператор взяття адреси &. Оператор & є унарним і повертає адресу свого операнда. Наприклад, оператор присвоєнняА=&cзаписує у вказівник адресу змінної с. Ця адреса відноситься до комірки пам'яті, яку займає с. Адреса і значення змінної в жоден спосіб не пов'язані.Оператор розіменування вказівника є протилежністю оператора &. Цей унарний оператор повертає значення, що зберігається за вказаною адресою.Пріоритет операцій * і & вищий за пріоритет всіх арифметичних операцій, за винятком унарного мінуса.Якщо адреса займає декілька комірок пам'яті, її адресою вважається адреса першої комірки.Необхідно слідкувати за тим, що вказівник посилається на змінну правильного типу. Розглянемо приклад (в результат виконання програми змінній у мало бути присвоєно значення змінної х)#include <stdio. h>int main (void){double x = 100.1, y;int *p;p = (int *) &x; /* Вказівник цілого типу р посилається на змінну подвійної точностіy = *p; /Оператор працює не так, як вимагалосяprintf ("%f", y);. Число 100.1 не виводитьсяreturn 0;}Вказівник можна присвоїти іншому вказівнику.Приклад#include <stdio. h>int main (void){int x;int *p1, *p2;p1 = &x;p2 = p1;printf (" %p", p2); /* Виводить адресу змінної х, не її значення */return 0;}У прикладі на змінну х посилаються обидва вказівника р1 і р2.До вказівників можна застосовувати лише дві арифметичні дії - віднімання і додавання Віднімання дозволяє визначити кількість елементів базового типу, розташованих між двома вказівниками.До вказівників можна застосовувати операції порівняння. Як правило, це робиться тоді, коли вказівними посилаються на той самий об'єкт, наприклад, масив. Розглянемо в якості прикладу пару функцій для роботи зі стеками, в які записують і з яких зчитують цілі числа. Стек-це список, доступ до елементів якого здійснюється за принципом „першим увійшов-останнім вийшов”. Стеки використовуються в компіляторах, інтерпретаторах, програмах обробки електронних таблиць. Щоб створити стек, необхідні дві функції push () і pop ().Функція push () заносить числа в стек, а функція рор () видобуває їх звідтам. У наведеній нижче програмі вони керуються функцією. При вводі числа з клавіатури програма заносить його в стек. Якщо користувач ввів 0, значення видобувається зі стеку. Програма припинить роботу при введенні - 1.#include <stdio. h>#include <stdlib. h>#define SIZE 50void push (int i);int pop (void);int *tos, *p1, stack [SIZE];int main (void){int value;tos = stack; /* tos вказує на вершину стеку */p1 = stack; /* Ініціалізація p1 */do {printf ("Enter value: ");scanf ("%d", &value);if (value! =0) push (value);else printf ("value on top is %d\n", pop ());} while (value! =-1);return 0;}void push (int i){p1++;if (p1== (tos+SIZE)) {printf ("Stack Overflow. \n");exit (1);}*p1 = i;}int pop (void){if (p1==tos) {printf ("Stack Underflow. \n");exit (1);}p1--;return * (p1+1);}Як бачимо, стек реалізовано у вигляді масиву stack. Спочатку вказівними pi і tos посилаються на перший елемент стека. Потім вказівник рі починає переміщуватись по стеку, а tos зберігає значення вершини. Це дозволяє запобігти переповненню стека і звертанню до порожнього стека. Функції push () і pop () можна застосовувати відразу після ініціалізації стека. У кожній з них виконується перевірка, чи не вийшов вказівник за межі допустимого діапазону значень.Вказівники і масиви тісно пов язані між собою. Розглянемо приклад:char str [80], *p1;p1 = str;Тут вказівнику р1 присвоєна адреса першого елементу масиву. Щоб отримати доступ до 5-го елементу масиву, треба виконати один з двох операторівstr [4] або* (p1+4)Як і звичайні змінні, вказівники можна розміщати в масивах. Оголошення масиву, що складається з 10 змінних, виглядає наступним чиномint *x [10];Щоб присвоїти адресу цілочисельної змінної var третьому елементу масиву вказівників, виконуємо операторx [2] =&var;Щоб видобути значення змінної використовуючи вказівник розіменування*x [2]Масив вказівників передається у функцію в звичайний спосіб-достатньо вказати його ім'я в якості аргументу.Прикладvoid display_array (int *q [])int t;for (t=0; t<10; t++)printf ("%d", *q [t]);Іноді вказівник може посилатись на інший вказівник, який в свою чергу містить адресу змінної. Така адресація називається непрямою. Змінна, що являє собою вказівник на вказівник, записується з додатковою *.Приклад#include <stdio. h>int main (void) {int x, *p, **q;x = 10;P = &x;q = &p;printf ("%d", **q) // вивід числа хНезважаючи на те, що функція не є змінною, вона також розташовується в пам'яті, і як наслідок, її адресу можна присвоювати вказівнику. Ця адреса вважається точкою входу в функцію. Саме вона використовується при її виклику. Це дозволяє також передавати функції в якості аргументів іншим функціям.Будь-яка змінна є іменованою областю пам'яті, яка резервується під час компіляції, а вказівники служать лише псевдонімами для областей пам'яті, до яких в разі потреби можна звернутись просто по імені. Справжня цінність вказівників виявляється тоді, коли для зберігання даних в процесі виконання програми виділяється неіменована область пам'яті. У цьому випадку вказівники є єдиним засобом доступу до цієї пам'яті. У С++ є два способи виділити пам'ять: з допомогою бібліотечної функції malloc або з допомогою оператора newПрототип функції виглядає наступним чиномvoid *malloc (size_t кількість байтів)Наприкладchar *p;р= malloc (lOOO); /*виділити 1000 байт *абоint *p;*p= (int*) malloc (50*sizeof (int));. виділити память під 50 цілих чиселФункція free є протилежністю malloc - вона звільняє раніше зайняту динамічну область пам'яті. Прототип функції виглядає наступним чиномvoid free (void *p)Синтаксис використання оператора newint *p=new intВираз new int повідомляє програмі, що необхідна нова область для збереження даних типу int. Оператор new аналізує тип, щоб знати, скільки байт необхідно виділити. Потім він відшукує область пам'яті і повертає адресу. Далі адреса присвоюється змінній р, яка оголошується вказівником на тип int. Тепер р є адресою, а *р - значенням, що зберігається за цією адресою.Звільнити зарезервований блок пам'яті можна з допомогою оператора deletedelete *p;Цим очищується область пам'яті, але сам вказівник не знищується і його можна використовувати повторно, наприклад, для вказування на іншу область пам'яті.2. Завдання до лабораторної роботи1. Вести символьний масив. Знайти адреси першого і останнього його елементів і визначити його розмір в байтах.2. Скласти програму, що здійсню переписування рядка символів в зворотному порядку.3. Визначити адреси елементів масиву чисел розмірністю 4 на 4, що знаходяться на головній діагоналі.Лабораторна робота №7 Основні поняття об'єктно-орієнтованого програмування 1. Теоретична частина Об'єкт - це абстрактна сутність, наділена характеристиками об'єктів навколишнього реального світу. Створення об'єктів і маніпулювання ними - це зовсім не привілей мови C++, а скоріше результат методології програмування, що втілює в кодових конструкціях опис об'єктів і операції над ними. Кожен об'єкт програми, як і будь-який реальний об'єкт, відрізняється власними атрибутами і характерною поведінкою. Об'єкти можна класифікувати по різних категоріях. Кожен клас займає визначене місце в ієрархії класів. Таким чином, будь-який клас визначає деяку категорію об'єктів, а всякий об'єкт є екземпляр деякого класу. Об'єктно-орієнтоване програмування (ООП) - це методика, що концентрує основну увагу програміста на зв'язках між об'єктами, а не на деталях їхньої реалізації. Основні принципи ООП: · інкапсуляція; · спадкування; · поліморфізм; · створення класів і об'єктів) Інкапсуляція є об'єднання в єдиному об'єкті даних і кодів, що оперують з цими даними. У термінології ООП дані називаються членами даних (data members) об'єкта, а коди - об'єктними методами або функціями-членами (methods, member functions). Інкапсуляція дозволяє в максимальному ступені ізолювати об'єкт від зовнішнього оточення. Вона істотно підвищує надійність розроблюваних програм, тому що локалізовані в об'єкті функції обмінюються з програмою порівняно невеликими обсягами даних, причому кількість і тип цих даних звичайно ретельно контролюються. У результаті заміна або модифікація функцій і даних, інкапсульованих в об'єкт, як правило, не спричиняє негативних наслідків для програми в цілому (з метою підвищення захищеності програм в ООП майже не використовуються глобальні змінні). Іншим достатньо важливим наслідком інкапсуляції є легкість обміну об'єктами, переносу їх з однієї програми в іншу. Запозичена в природи ідея спадкування вирішує проблему модифікації поведінки об'єктів і додає ООП виняткову силу і гнучкість. Спадкування дозволяє, практично без обмежень, послідовно будувати і розширювати класи, створені розробниками. Починаючи з найпростіших класів, можна створювати похідні класи по зростаючій складності, що не тільки легкі в налагодженні, але і прості за внутрішньою структурою. Послідовне проведення в життя принципу спадкування, особливо при розробці великих програмних проектів, добре погоджується з технікою спадного структурного програмування (від загального до частки), і багато в чому стимулює такий підхід. При цьому складність коду програми в цілому істотно скорочується. Похідний клас (нащадок) успадковує усі властивості, методи і події свого базового класу („батька”) і всіх його попередників в ієрархії класів. При спадкуванні базовий клас обростає новими атрибутами й операціями. У похідному класі звичайно з'являються нові члени даних, властивості і методи. При роботі з об'єктами програміст звичайно підбирає найбільш підходящий клас для рішення конкретної задачі і створює одного або декількох нащадків від нього, що здобувають здатність робити не тільки те, що закладено в „батьку”. Дружні функції дозволяють похідному класові одержати доступ до всіх членів даних зовнішніх класів. Крім того, похідний клас може перевантажувати (overload) наслідувані методи в тому випадку, коли їхня робота в базовому класі не пасує нащадкові. Використання перевантаження в ООП усіляко заохочується, хоча в прямому розумінні значення цього слова перевантажень звичайно уникають. Говорять, що метод перевантажений, якщо він асоціюється з більш ніж одною однойменною функцією. Поліморфізм - це властивість родинних об'єктів (тобто об'єктів, класи яких є похідними від одного „батька”) поводитися по-різному в залежності від ситуації, що виникає в момент виконання програми. У рамках ООП програміст може впливати на поведінку об'єкта тільки побічно, змінюючи вхідні в нього методи і додаючи „нащадкам" відсутні в „батька" специфічні властивості. Для зміни методу необхідно перевантажити його в „нащадку”, тобто оголосити в „нащадку” однойменний метод і реалізувати в ньому потрібні дії. У результаті в об'єкті-батьку й об'єкті-нащадку будуть діяти два однойменних методи, що мають різну кодову реалізацію і, отже, що додають об'єктам різне поведінку. Наприклад, в ієрархії родинних класів геометричних фігур (точка, пряма лінія, квадрат, прямокутник, окружність, еліпс і т.д.) кожен клас має метод Draw, що відповідає за належний відгук на подію з вимогою намалювати цю фігуру. Завдяки поліморфізмові, „нащадки” можуть перевантажувати загальні методи "батька" для того, щоб реагувати специфічним образом на ту саму подію. Класи в C++ Перед тим як працювати з класом, програма повинна його оголосити. Розглянемо синтаксис оголошення класу на прикладі класу circle: class Circle { public: Circle (); void SetRadius (void); void GetRadius (void); ~Circle (); private: void CalculateArea (void); int radius; int color; }; Ключове слово class показує компілятору, що все, що знаходиться у фігурних дужках ({}) належить оголошенню класу. (Не забувайте ставити крапку з комою наприкінці оголошення.) Оголошення класу містить оголошення елементів даних (наприклад, int radius) і прототипи функцій-елементів класу. В оголошенні класу circle містяться наступні елементи даних: int radius; int color; Оголошення також містить п'ять прототипів функцій-елементів: Circle (); // конструктор void SetRadius (void); void GetRadius (void); ~Circle (); // деструктор void CalculateArea (void); Прототипи функцій і оголошення елементів даних включаються в оголошенні класу в розділи public (відкритий) або private (закритий). Ключові слова public і private говорять компілятору про приступність елементів-функцій і даних. Наприклад, функція SetRadius () визначена в розділі public, і це означає, що будь-яка функція програми може викликати функцію SetRadius (). Функція CalculateArea () визначена в розділі private, і цю функцію можна викликати тільки в коді функцій-елементів класу Circle. Аналогічно, оскільки елемент даних radius оголошений у розділі private, прямий доступ до нього (для установки або читання його значення) можливий тільки в коді функцій-елементів класу Circle. Якби ви оголосили елемент даних radius у розділі public, то будь-яка функція програми мала би доступ (для читання і присвоювання) до елемента даних radius. Приклад: Заповнення і вивід платіжної відомості include <iostream> #include <cstring> using namespace std; class employee { char name [80]; // private by default public: void putname (char *n); // these are public void getname (char *n); private: double wage; // now, private again public: void putwage (double w); // back to public double getwage (); }; void employee:: putname (char *n) { strcpy (name, n); } void employee:: getname (char *n) { strcpy (n, name); } void employee:: putwage (double w) { wage = w; } double employee:: getwage () { return wage; } int main () { employee ted; char name [80]; ted. putname ("Ted Jones"); ted. putwage (75000); ted. getname (name); cout << name << " makes $"; cout << ted. getwage () << " per year. "; return 0; } 2. Завдання до лабораторної роботи Створити клас трикутників, змінними якого є сторони трикутника, а методами-обчислення його площі і периметра. Створити два об'єкти, що належать до створеного класу, і для одного обчислити площу, а для другого - периметр.
Страницы: 1, 2, 3
|