Алгебра логіки - це розділ математики, що вивчає висловлення, розглянуті з точки зору їхніх логічних значень (істинності або хибності) і логічних операцій над ними.
Логічне висловлення - це будь-яка оповідальне речення, у відношенні якого можна однозначно сказати, істинне воно або хибне. Щоб звертатися до логічних висловлень, їм призначають імена.
Операції над логічними висловленнями:
НЕ Операція, що виражається словом "не", називається запереченням і позначається рискою над висловленням (або знаком). Висловлення істинне, коли A хибне, і хибне, коли A істинне.
І Операція, що виражається зв'язуванням "і", називається кон'юнкцією (лат. conjunctio - з'єднання) або логічним множенням і позначається точкою " " (може також позначатися знаками або &). Висловлення А·В істинно тоді і тільки тоді, коли обидва висловлення А и В істинні.
АБО Операція, що виражається зв'язуванням "або" (у невиключаючому сенсі) називається диз'юнкцією (лат. disjunctio - поділ) або логічним додаванням і позначається знаком v (або плюсом). Висловлення А v В помилкове тоді і тільки тоді, коли обидва висловлення А и В помилкові.
ЯКЩО-ТО Операція, що виражається зв'язуваннями "якщо., то", "з. випливає",". витікає.", називається імплікацією (лат. implico - тісно зв'язані) і позначається знаком. Висловлення помилкове тоді і тільки тоді, коли А істинно, а В хибне.
РІВНОСИЛЬНА Операція, що виражається зв'язуваннями "тоді і тільки тоді", "необхідно і досить",". рівносильно.", називається еквіваленцією або подвійною імплікацією і позначається знаком або ~. Висловлення істинне тоді і тільки тоді, коли значення А и В збігаються. За допомогою логічних змінних і символів логічних операцій будь-яке висловлення можна формалізувати, тобто замінити логічною формулою. В алгебрі логіки виконуються наступні основні закони, що дозволяють робити тотожні перетворення логічних виражень:
Рівносильні перетворення логічних формул мають те ж призначення, що і перетворення формул у звичайній алгебрі. Вони служать для спрощення формул або приведення їх до визначеного виду шляхом використання основних законів алгебри логіки. Під спрощенням формули, що не містить операцій імплікації і еквіваленції, розуміють рівносильне перетворення, що приводить до формули, що або містить у порівнянні з вихідною менше число операцій кон'юнкції і диз'юнкції і не містить заперечень неелементарних формул, або містить менше число входжень змінних.
Закон
Для АБО
Для І
Комутативний
Асоціативний
Дистрибутивний
Правила де Моргана
Тавтології
Поглинання
Склеювання
Операція над змінною з її інверсією
Правила операцій з константами
Закон подвійного заперечення
Приклади
1.
2.
3.
4.
5.
6.
7.
8.
9.
2. Перемикальні схеми
У комп'ютерах і інших автоматичних пристроях широко застосовуються електричні схеми, що містять сотні і тисячі перемикальних елементів: реле, вимикачів і т.п. Розробка таких схем досить трудомістка справа. Виявилося, що тут з успіхом може бути використаний апарат алгебри логіки.
Перемикальна схема - це схематичне зображення деякого пристрою, що складає з перемикачів і з'єднуючих провідників, а також із входів і виходів, на які подається і з яких знімається електричний сигнал.
Кожен перемикач має тільки два стани: замкнутий і розімкнутий. Перемикачеві Х поставимо у відповідність логічну перемінну х, що приймає значення 1 у тому і тільки в тому випадку, коли перемикач Х замкнути і схема проводить струм; якщо ж перемикач розімкнути, то х дорівнює нулеві.
Усій перемикальній схемі також можна поставити у відповідність логічну змінну, рівну одиниці, якщо схема проводить струм, і рівну нулеві - якщо не проводить. Ця змінна є функцією від змінних, відповідних усім перемикачам схеми, і називається функцією провідності.
Дві схеми називаються рівносильними, якщо через одну з них проходить струм тоді і тільки тоді, коли він проходить через іншу (при тому самому вхідному сигналі).
З двох рівносильних схем більш простою вважається та схема, функція провідності якої містить менше число логічних операцій або перемикачів.
При розгляді перемикальних схем виникають дві основні задачі: синтез і аналіз схеми.
СИНТЕЗ СХЕМИ по заданих умовах її роботи зводиться до наступних трьох етапів:
· складанню функції провідності по таблиці істинності, що відбиває ці умови;
· спрощенню цієї функції;
· побудові відповідної схеми.
АНАЛІЗ СХЕМИ зводиться до
· визначенню значень її функції провідності при всіх можливих наборах вхідних у цю функцію перемінних.
· одержанню спрощеної формули.
Приклади.
1. Побудуємо схему, що містить 4 перемикачі x, y, z і t, таку, щоб вона проводила струм тоді і тільки тоді, коли замкнути контакт перемикача t і який-небудь з інших трьох контактів.
Рішення. У цьому випадку можна обійтися без побудови таблиці істинності. Очевидно, що функція провідності має вигляд F (x, y, z, t) = t · (x v y v z), а схема виглядає так:
Приклад 2. Проаналізувати задану схему
Розв'язок
В даному випадку будувати таблицю істинності не потрібно.
Приклад 3
Розв'язок
Спрощена перемикальна схема
Таблиця істинності
z
t
F
0
0
0
0
1
1
1
0
1
1
1
1
3. Логічний елемент комп'ютера - це частина електронної логічної схеми, що реалізує елементарну логічну функцію.
Логічними елементами комп'ютерів є електронні схеми І, АБО, НЕ, І-НЕ, АБО-НЕ й інші (звані також вентилями), а також тригер.
За допомогою цих схем можна реалізувати будь-яку логічну функцію, що описує роботу пристроїв комп'ютера. Звичайно у вентилів буває від двох до восьми входів і один або два виходи.
Високий рівень звичайно відповідає значенню “істина" (“1”), а низький - значенню “неправда" (“0”).
Кожен логічний елемент має свою умовну позначку, що виражає його логічну функцію, але не вказує на те, яка саме електронна схема в ньому реалізована. Це спрощує запис і розуміння складних логічних схем.
Роботу логічних елементів описують за допомогою таблиць істинності.
Таблиця істинності - це табличне представлення логічної схеми (операції), у якому перераховані всі можливі сполучення значень істинності вхідних сигналів (операндів) разом зі значенням істинності вихідного сигналу (результату операції) для кожного з цих сполучень.
Схема І
Схема І реалізує кон'юнкцію двох або більше логічних значень.
Одиниця на виході схеми І буде тоді і тільки тоді, коли на усіх входах будуть одиниці. Коли хоча б на одному вході буде нуль, на виході також буде нуль.
Зв'язок між виходом z цієї схеми і входами x і y описується співвідношенням: z = x · y
(читається як "x і y"). Операція кон'юнкції на структурних схемах позначається знаком "&" (читається як "амперсенд"), що є скороченим записом англійського слова and.
Схема АБО
Схема АБО реалізує диз'юнкцію двох або більш логічних значень. Коли хоча б на одному вході схеми АБО буде одиниця, на її виході також буде одиниця.
Умовна позначка на структурних схемах схеми АБО з двома входами представлене на мал.5.2 Знак "1" на схемі - від застарілого позначення диз'юнкції як ">=1" (тобто значення диз'юнкції дорівнює одиниці, якщо сума значень операндів більше або дорівнює 1). Зв'язок між виходом z цієї схеми і входами x і y описується співвідношенням: z = x v y (читається як "x або y").
Схема НЕ
Схема НЕ (інвертор) реалізує операцію заперечення. Зв'язок між входом x цієї схеми і виходом z можна записати співвідношенням z =, x де читається як "не x" або "інверсія х".
Якщо на вході схеми 0, то на виході 1. Коли на вході 1, на виході 0.
Схема І-НЕ
Схема І-НЕ складається з елемента І и інвертора і здійснює заперечення результату схеми І. Зв'язок між виходом z і входами x і y схеми читається як "інверсія x і y".
Схема АБО-НЕ
Схема АБО-НЕ складається з елемента АБО й інвертора і здійснює заперечення результату схеми АБО. Зв'язок між виходом z і входами x і y схеми читається як "інверсія x або y".
2. Завданнядолабораторноїроботи
1. Спростити наступні вирази:
2. Проаналізувати наступні перемикальні схеми
3. Скласти перемикальні схеми функцій
4. Реалізувати функції з завдання 3 з допомогою логічних елементів.
Лабораторна робота №2
Синтезсхем
Теоретичнівідомості
1. Основні етапи побудови схеми
Цифрові електронні схеми на логічних елементах застосовуються в якості схем керування для різних задач контролю і регулювання технологічних об'єктів. Під синтезом схеми розуміють її проектування (розробку).
Перед початком синтезу схеми має бути чітко і однозначно сформульована задача, яку буде розв'язувати схема. У першу чергу призначаються вхідні і вихідні змінні і визначається, за яких умов вони приймають значення 1 і 0. На основі цього будується таблиця істинності. Таблиця істинності однозначно визначає, як буде працювати схема. Після побудови таблиці істинності підбирають логічні елементи, на яких її можна реалізувати. Схема має бути якомога простішою.
2. Нормальні форми запису
Нормальна диз'юнктивна форма (нормальна форма АБО) - форма запису рівнянь алгебри логіки, в якій повні кон'юнкції пов'язані між собою логічним додаванням.
Повна кон'юнкція-операція логічного множення, в якій беруть участь всі наявні вхідні змінні або їх інвертовані значення. Наприклад, якщо є змінні А і В, то одержуються 4 повні кон'юнкції:
Кожному 1-стану вихідного стовпця відповідає повна кон'юнкція. Якщо в таблиці істинності змінна приймає значення 0, у відповідній повній кон'юнкції вона інвертується.
Нормальна кон'юнктивна форма (нормальна форма І) - форма запису рівнянь алгебри логіки, в якій повні диз'юнкції пов'язані між собою логічним множенням.
Повна диз'юнкція-операція логічного додавання, в якій беруть участь всі наявні вхідні змінні або їх інвертовані значення.
Приклад:
Перевести нормальну форму І в нормальну форму АБО
За нормальною формою АБО можна синтезувати задану таблицю істинності.
Приклад
Спростити нормальну форму АБО
Спочатку спрощують кон'юнкції 1 і 2
Аналогічно спрощують 3 і 4
Тоді
Нормальна форма може бути переведена на елементи І-НЕ або АБО-НЕ. Для переведення на І-НЕ здійснюють подвійне заперечення, а потім використовують формули де Моргана.
Схема, що реалізує рівняння, представлена на рисунку:
3. Метод карт Карно.
Карти Карно служать для наочного представлення і спрощення нормальної форми АБО. Карти Карно можуть бути представлені у вигляді таблиць істинності для повних кон'юнкцій. Карти Карно завжди мають кількість полів рівну кількості можливих повних кон'юнкцій.1 в полі карти Карно означає наявність повної кон'юнкції.
Приклад
Занести в карту Карно нормальну форму АБО
Представлена на карті Карно нормальна форма АБО може бути спрощена за певних умов.
„Сусідні” повні кон'юнкції можна об'єднувати в групи.
У одній групі можуть бути об'єднані 2 чи 4 повні кон'юнкції. Вміст групи характеризується її координатами. Змінні, координати яких присутні і прямій, і інверсній формах, виключаються. При наявності декількох груп спрощене рівняння є результатом логічного додавання значень окремих груп.
Приклад
Максимально спростити за допомогою карти Карно нормальну форму АБО
Спочатку повні кон'юнкції заносяться в карту
Утворюються 2 групи по 2 поля. Спрощений вираз виглядає
Карта Карно для трьох змінних має форму циліндра, тому клітинки в протилежних кінцях одного рядка є сусідніми. У вигляді циліндра карту Карно малювати незручно, і тому зазвичай її представляють в наступному вигляді
В одній групі можуть бути об'єднані 2, 4 чи 8 повних кон'юнкцій.
Приклад
Записати і максимально спростити нормальну форму АБО, задану в карті Карно
Можуть бути утворені 2 групи з 4 клітинок. Спрощене рівняння
Карта Карно для 4 змінних:
Варіанти мінімізації:
Приклад
Скласти схему, що задовольняє заданій таблиці істинності
Карта Карно
Схема
Завдання до лабораторної роботи
1. Побудувати схему перемикача "2 з 3" на елементах АБО-НЕ
Перемикач "2 з 3" - на виході 1, коли 2 з 3 входів встановлені в 1.
2. Побудувати схему контролю парності
Схема контролю парності - 1 на виході тоді, коли парне число входів дорівнює 1.
Лабораторна робота № 3
АЛГОРИТМИЛІНІЙНОЇСТРУКТУРИ,РЕАЛІЗОВАНІНАС++
Теоретичначастина
У загальному мова програмування базується на двох основних поняттях - дані і алгоритми. Дані-це інформація, яку обробляє програма. Алгоритми - методи, які використовує програма. Мова С++ є процедурною, тобто основний акцент в ній робиться на алгоритмах. Це означає, що спочатку визначається послідовність дій, а потім ці дії реалізуються з допомогою мови програмування. Програма містить набір процедур, які комп'ютер повинен виконати для досягнення необхідного результату. Програмування на С++ є структурним. Програми проектуються за принципом "зверху вниз", ідея якого полягає у розбитті великої задачі на менші і такі, що легко розв'язуються.
Дані в С++ бувають прості і складені. Прості типи наведено в таблиці.
Типи даних:
Тип
Розмір, байт
Діапазон
Опис
char signed char
1
Від - 128 до 127
Символьний тип. Містить один символ або рядок символів. Кожен символ представляється одним байтом. Компілятор розрізняє як окремі наступні типи: char, signed char і unsigned char
unsigned char
1
Від
до 255
Символьний тип. Кожен символ представляється одним байтом (значення в діапазоні від 0 до 255)
short signed short
2
Від - 32768 до 32767
Цілий тип. Скорочене позначення типу short int. Довжина цього типу поза залежністю від використовуваного компілятора завжди більше або дорівнювати довжині значення типу char і менше або дорівнює довжині значення типу int
Unsigned short
2
Від 0 до 65535
Беззнаковий цілий тип
int signed int
42
Від - 2147483648 до 2147483647
Цілий тип. Довжина цього типу поза залежністю від використовуваного компілятора завжди більше або дорівнює довжині значення типу short int
unsigned int
4
Від 0 до 4294967259
Беззнаковий цілий тип
intn
n/8
Цілий тип, розмір у бітах якого визначається значенням п, і може бути рівним 8, 16, 32 або 64 бітам
long signed long
4
Від - 2147483648 до 2147483647
Цілий тип. Скорочене позначення типу long int
unsigned long
4
Від до 4294967259
Беззнаковий цілий тип
float
4
Від 3.4Е-38 до 3.4Е+38
Тип даних із плаваючою крапкою
До складених типів належать покажчики, масиви, перерахування, об'єднання, структури, класи. Більш детально вони будуть розглянуті в наступних лабораторних роботах.
Програмування включає в себе наступні етапи
1. Скориставшись текстовим редактором, написати текст програми і зберегти її в файлі. Цей файл буде вихідним кодом програми.
Допустимі розширення імен вихідного коду
2. Скомпілювати вихідний код. Це означає виконання програми, яка транслює вихідний файл у машинний код. Файл, що містить трансльований код, називається об'єктним кодом.
3. Зв'язати об'єктний код програми з об'єктними кодами функцій, використаних в програмі (додатковим кодом) і скомпонувати їх у єдину програму. Файл, який містить цю програму, називається виконуваним кодом.
Програми на С++ мають наступну структуру
1. Директиви препроцесора
#include
Змушує препроцесор включити у файл програми файли стандартних бібліотек або будь-який інший файл.
2. Блок опису вхідних змінних
3. Заголовок функції main () і її тіло у фігурних дужках{}. Тіло функції містить інструкції для комп'ютера. Кожна завершена функція називається оператором і завершується крапкою з комою. Слово, що стоїть перед назвою функції, називається типом функції (фактично, це тип результату, одержаного при виконанні функції). У круглих дужках після назви функціі мітиться список аргументів (параметрів) функції.
4. Оператор return, що завершує виконання функції main ()
Нижче наведено приклад програми, що здійснює перемноження двох чисел
#include <stdio. h> // підключення стандартної бібліотеки вводу/виводу
#include <math. h> // підключення стандартної бібліотеки математичних функцій
float x,y,z; // змінні типу „з плаваючою крапкою”
float main ()
{
printf ("Enter the number x: "); // вивід на екран тексту вимоги введення 1-го множника
scanf ("%f",&x); // зчитування введеного числа у форматі„з плаваючою крапкою”
printf ("Enter the number y: "); // вивід на екран тексту вимоги введення 2-го множника
scanf ("%f",&y); // зчитування введеного числа у форматі„з плаваючою крапкою”
z=x*y;
printf ("result\n%f\n",z); // виведення результату множення у форматі„з плаваючою крапкою”, \n-перехід на новий рядок
return (0);
}
Стандартні бібліотеки
Специфікація ANSI мов С и C++ визначає набір функцій стандартної бібліотеки. Незважаючи на те що стандартна бібліотека дуже велика, у ній можна виділити кілька великих функціональних груп.
Стандартні функції вводу/виводу. Їхні описи включені у файл заголовків stdio. h і віртуальний заголовок cstdio. У цю групу включають функції консольного вводу/виводу, такі як printf, scanf, gets, puts, getchar і putchar. Сюди також входять функції файлового вводу/виводу fopen (для відкриття файлів), fprintf, fscanf, fputs, fgets і ряд інших (для читання/ запису текстових файлів), fread і fwrite (для читання/ запису двійкових файлів). Також до цієї групи відносяться функції одержання поточної позиції у файлі й установки нової позиції у файлі (fseek, ftell, rewind), що дозволяють організувати довільний доступ до даних у файлі
Нижче приведені основні функції консольного вводу/виводу
· getchar () повертає черговий символ із клавіатури як ціле;
· gets (s) читає символи з клавіатури до появи символу нового рядка і поміщає їх у рядок s (сам символ нового рядка в рядок не включається);
· printf (fmt, par1, par2,.) виводить рядок параметрів par1, раг2 і т.д. у форматі, визначеному рядком fmt на стандартний пристрій виводу (звичайно монітор). Повертає число виведених символів (див. опис функції printf);
· putchar (ch) виводить символ ch на стандартний пристрій виводу. Якщо вивід успішний, повертається значення ch,;
· puts (s) виводить рядок s на стандартний пристрій виводу, додаючи наприкінці символ нового рядка. Повертає ненегативне значення при успіху або EOF - при помилці;
· scanf (fmt, par2, раг2,.) уводить рядок параметрів раr1, раг2 і т.д. у форматі, обумовленому рядком fmt зі стандартного пристрою вводу (із клавіатури), повертає число змінних, котрим привласнене значення
Для реалізації потокового вводу/виводу використовується функції. Описані в iostream. h
Функції роботи з рядками. Їхні описи включені у файл заголовків string. h і віртуальний заголовок cstring. У цю групу входять функції роботи з простими рядками типу char*: strlen повертає довжину рядка, strcpy копіює рядок в іншу і strcat додає рядок у кінець рядка. Функція stremp використовується для порівняння двох рядків на співпадіння. Інші важливі функції: strncat, strnemp, strncat і strstr. Є також ряд функцій типу strchr для пошуку необхідного символу. Функція strtok корисна для розбивки рядка на окремі елементи.
· strcat (s1fs2) додає s2 до s1;
· strcmp (s1, s2) порівнює рядки і повертає негативне (якщо s1 менше s2), нульове (якщо s1 дорівнює s2) або позитивне (якщо s1 більше s2) значення;
· strcpy (s1, s2) копіює s2 у s1;
· strlen (s) повертає довжину рядка (без врахування символу завершення рядка);
· strncat (s1, s2, n) додає s2 до s1, але не більш n символів;
· strncmp (s1, s2, n) аналогічна strcmp, але порівнює не більше n символів;
· strncpy (s1, s2, п) копіює s2 у s1, але не більш n символів;
· strchr (s,ch) повертає покажчик на перше входження символу ch у рядок s, якщо його немає, то повертається null;
· strcoll (s1,s2) аналог strcmp, але враховує установки локалізації
· strcspn (s1, s2) повертає значення індексу будь-якого з символів з s2 у рядку s1;
· strerror (n) повертає покажчик на рядок з описом помилки номер n;
· strpbrk (s1, s2) аналогічна strcspn, але повертає покажчик, а не індекс;
· strrchr (s, ch) аналогічна strchr, але пошук ведеться з кінця рядка;
strspn (s1, s2) повертає індекс першого символу в s1, відсутнього в s2;
Функції визначення типу символу. Їхні описи включені у файл заголовків ctype. h і віртуальний заголовок її type. Ці функції дозволяють визначити приналежність символу до визначеної категорії.
Математичні функції. Їхні описи включені у файл заголовків math. h і у віртуальний заголовок cmath. До цієї групи відносяться такі стандартні тригонометричні і гіперболічні функції, sin, cos, tan, asin, acos, atan, sinh, cosh і tanh. Також включаються функції pow для обчисленні ступеня числа, ехр для обчислення експонентної функції і логарифмічні функції log і log 10, а також функція для обчислення найближчого більшого цілого ceil, функції для обчислення найближчого меншого цілого floor, fabs, fmod, frexp, ldexp, modf і функції обчислення квадратного кореня sqrt. Необхідно відзначити, що такі математичні по своїй природі функції, як abs і rand, описані у файлі stdlib. h, а не в math. h.
Функції роботи з пам'яттю. Їхні описи включені у файл заголовків stdlib. h і у віртуальний заголовок cstdlib. В основному ці функції використовуються в бібліотеці для сумісності з мовою С. До них відносяться функції malloc, free, calloc і realloc. У мові С++ для тих же цілей переважно використовуються оператори new і delete.
Робота з програмою Microsoft Visual C++
Головне вікно програми має вигляд, зображений на рис.1
Щоб почати роботу, необхідно обрати FileNewFilesC++ Source File (рис.2).
Рис.1. Загальний вигляд головного вікна програми Microsoft Visual C++
Після завершення набору тексту програми натиснути кнопку (Build). Після виправлення помилок в разі їх виникнення, запустити програму на виконання, натиснувши кнопку Run
Рис.2. Вибір типу створюваного файлу.
Завдання до лабораторної роботи
1. Скласти програму, яка спочатку запитує ім'я особи, а потім з нею вітається.
2. Задано три точки. Визначити відстань від них до початку координат. Координати ввести з клавіатури.
3. Визначити дробову частину середнього арифметичного трьох чисел, що вводяться з клавіатури.
Навести повний текст програм з поясненнями.
Лабораторна робота № 4
РЕАЛІЗАЦІЯАЛГОРИТМІВЗРОЗГАЛУЖЕННЯМИВС++
Теоретичначастина
Базова структура „розгалуження" забезпечує вибір одного з альтернативних шляхів алгоритму в залежності від перевірки деякої умови. Кожен зі шляхів веде до загального виходу незалежно від того, який шлях було обрано. Структура розгалуження реалізується в наступних варіантах:
1. ЯКЩО - ТО
У С++ така структура реалізується з допомогою інструкції If
if (умова)
вираз або
if (умова) {. Вираз 1; вираз 2;
.
вираз n;)
БЛОК-СХЕМА:
2. ЯКЩО - ТО - ІНАКШЕ
If/else
if (умова)
вираз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 повинен виробляти значення того типу, якому належать усі мітки, серед яких не повинно бути однакових. Виконання оператора вибору починається з обчислення значення цього виразу. Потім знаходиться і виконується оператор з гілки, що містить отримане значення в якості однієї з міток.
БЛОК-СХЕМА
СинтаксиснаС++
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 from
the 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
АЛГОРИТМИ З ЦИКЛІЧНОЮ СТРУКТУРОЮ
Теоретичначастина
Циклічнакомпозиція пропонує повторне виконання деякого внутрішнього оператора доти, поки існують умови для цього. Внутрішній оператор називають також тіломциклу. Програмний текст, що складає тіло, визначає умову продовження або завершення виконання циклу. Усе разом складає операторциклу.
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.18
2. Задати масив з 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 50
void 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)
Синтаксис використання оператора new
int *p=new int
Вираз new int повідомляє програмі, що необхідна нова область для збереження даних типу int. Оператор new аналізує тип, щоб знати, скільки байт необхідно виділити. Потім він відшукує область пам'яті і повертає адресу. Далі адреса присвоюється змінній р, яка оголошується вказівником на тип int. Тепер р є адресою, а *р - значенням, що зберігається за цією адресою.
Звільнити зарезервований блок пам'яті можна з допомогою оператора delete
delete *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. Завданнядолабораторноїроботи
Створити клас трикутників, змінними якого є сторони трикутника, а методами-обчислення його площі і периметра. Створити два об'єкти, що належать до створеного класу, і для одного обчислити площу, а для другого - периметр.