Міністерство освіти і науки України
Національний університет "Львівська політехніка"
Кафедра "Інформаційні системи та мережі"
КУРСОВА РОБОТА
з дисципліни "Проблемно-орієнтовані мови програмування"
на тему:
Навчально - виховна програма
«Операцiї та вирази мови Сi»
студенту групи КН-17 Гудимі Т. А.
Тема: Навчально - виховна програма «Операцiї та вирази мови Сi»
Завдання: Навчально - виховна програма «Операцiї та вирази мови Сi»
ЗМIСТ ЗАВДАННЯ ТА КАЛЕНДАРНИЙ ПЛАН ЙОГО ВИКОНАННЯ
1.
Провести аналiтичний огляд лiтератури по заданій темi.
2.
Розробити алгоритм та графiчну схему програми розв'язування задачi
3.
Написати програму на мовах C /C++.
Вимоги до програми:
1) програма повинна мати меню для вибору режимів її роботи; у меню передбачити вибір типу та розміру даних, введення значень даних з клавіатури або файлу, виведення даних на екран, систему допомоги.
2) програма повинна мати інтерфейс у вигляді вікон та меню для вибору
режимів її роботи;
3) передбачити введення даних з клавіатури та з файлу та виведення
результатів на екран;
4) керування режимами роботи програми виконати за допомогою
клавіатури та миші.
4.
Пiдготувати вхiднi данi для контрольного прикладу.
5.
Реалiзувати та вiдлагодити програми на вказаних мовах програмування.
6.
Оформити записку до курсової роботи згiдно вимог Мiжнародних
стандартiв, дотримуючись такого змiсту:
28.05
-вступ;
-формулювання задачі;
-алгоритми розв'язування задачі;
-методи та засоби розв’язування задачі;
-опис програми на мові C/C++ ;
-технологія програмування, виконання та відлагодження програми;
-інструкція користувачу;
-контрольний приклад та аналіз результатів комп'ютерної реалізації
програми;
-висновки;
-література;
-додатки
ЗАВДАННЯ ПРИЙНЯТО ДО ВИКОНАННЯ: ____________
пiдпис студента
Керівник роботи: _______________ Кравець П.О.
Формулювання задачі.
Формулювання задачі: Програма може виконуватися на операційній системі DOS, Windows та її емуляцією під Linux. Для її виконання потрібні мінімальні характеристики комп’ютера, головне обладнання: клавіатура, миша та будь-який носій даних (з файловою системою FAT/FAT32 для операційної системи DOS). Керування програмою здійснюється за допомогою миші та клавіатури. Програма оформлена у вигляді вікон та меню для вибору режимів її роботи. Також в програмі є система розпізнавання математичних виразів.
Методи та засоби розв’язування задачі.
Для розв’язування задачі потрібно добре знати такі головні теми: робота з рядками символів, масивами, структурами, текстовими файлами.
Рядки. У мові програмування С не визначено спеціального типу для опрацювання рядків. Рядок символів розглядається як масив елементів типу char, який закінчується символом ‘\0’(нуль-символ), що є ознакою кінця рядка. Сталі типу рядок записуються у лапках. У сталих рядках нуль-символ записується автоматично.
Підчас оголошення символьного масиву необхідно до фактичної довжини рядка додати одиницю для нульового символа (не у всіх компіляторах). Якщо масив символів оголошують й ініціалізують одночасно, то довжину можна не зазначати, компілятор визначить її. Оскільки рядки є масивами символів, то назва рядка вказівником на його початок (на його перший елемент). Для опрацювання масивів символів у мові С є стандартні функції, які описуються у модулі string.h.
Масиви. Масив – впорядкований скінчений набір даних одного типу, які зберігаються в послідовно розташованих комірках оперативної пам’яті і мають спільну назву. Назву масиву дає користувач.
Масив складається з елементів. Кожен елемент має індекс, за яким його можна знайти у масиві. Кількість Індексів визначає розмірність масиву. Розрізняють одно та багатовимірні масиви. Двовимірний масив – це таблиця яка складається з декількох рядків і стовпців. У математиці поняттю масив відповідає поняття вектора та матриці.
Розмір – це кількість елементів масиву. Розмір масиву треба задати заздалегідь, оскільки компілятор має зарезервувати для нього необхідний обсяг пам’яті. Розміром може бути лише стала величина.
Звернутись до елементів масиву можна двома способами: за допомогою імені масиву та використовуючи вказівники. Нумерація елементів масиву починається від нуля.
Проініціалізувати масив можна одним із способів:
Використовуючи принцип замовчування;
Безпосередньо підчас його оголошення;
Застосовуючи команду присвоювання;
Підчас введення даних з клавіатури.
За замовчанням усім елементам масиву надається значення 0.
Підчас компіляції програмного коду для статичного оголошення масивів надається пам'ять. Для ефективного використання пам'яті призначене динамічне оголошення масивів. Динамічною змінною можна використовувати операції, визначені для даних відповідного базового типу.
Якщо елемент масиву має не один а декілька індексів, то такі масиви називаються багатовимірними. Прикладами багатовимірних масивів можуть бути різноманітні табличні дані. Двовимірному масиву у математиці відповідає поняття матриці.
Кількість індексів визначає вимірність масиву. Усі двовимірні масиви можна опрацьовавути як одновимірні.
Елементи двовимірного масиву визначаються іменем масиву та двома індексами. Перший індекс означає номер рядка а другий номер стовпця. Двовимірні масиви компілятор розглядає як послідовність одновимірних, тому до елементів можна звертатись і через вказівники. В такому випадку це вказівника на вказівник одновимірного масиву.
Структури. Структури дозволяють об'єднувати в єдиному об'єктi сукупнiсть значень, якi можуть мати рiзнi типи. Оголошення структури здiйснюється за допомогою ключового слова struct.
Синтаксис опису структури виглядає так :
struct [iм'я_структури]
{
тип1 елемент1;
тип2 елемент2;
........................
типN елементN;
} [список описiв];
З метою ознайомлення з цим типом даних розглянемо найпростiший приклад представлення поняття "дата", що складається з декiлькох частин: число (день, мiсяць, рiк), назва тижня та мiсяця:
struct date {
int day ;
int month ;
int year;
char day_name[15];
char mon_name[14];
} arr[100],*pd,data,new_data;
В даному прикладi оголошуються:
data, new_data - змiннi типу структури date;
pd - вказiвник на тип data
arr - масив iз 100 елементiв, кожний елемент якого має тип date.
Потрiбно вiдзначити, що на вiдмiну вiд описiв iнших типiв даних, опис структури не видiляє мiсця у пам'ятi пiд елементи структури. Її опис визначає лише так званий шаблон, що описує характеристики змiнних, що будуть розмiщуватися у конкретнiй структурi. Щоб ввести змiннi та зарезервувати для них пам'ять необхiдно або пiсля фiгурної дужки, що завершує опис структури, вказати список iдентифiкаторiв.
Як i звичайними масивами простих типiв, так само можна оперувати масивами структур, елементи якого мають структурований тип. Розглянемо наочний зразок, який iлюструє оголошення масиву структур:
typedef struct Date
{
int d; /* день */
int m; /* мiсяць */
int y; /* рiк */
} Date;
Date arr[100];
Вище було оголошено масив arr, що складається iз 100 елементiв, кожний з яких має тип Data. Кожний елемент масиву - це о крема змiнна типу Data, що складається iз трьох цiлих елементiв - d, m, y.
Доступ до полiв структури аналогiчний доступу до звичайних змiнних, плюс використання iндексу номеру елементу у квадратних дужках:
arr[25].d=24;
arr[12].m=12;
Проблеми старого підходу. В мові C основним способом організації даних були структури. Структура складається з набору полів, які ніяк не захищені. Якщо елементи структури мають змінну довжину, їх представляють у вигляді вказівників. Виділення і звільнення пам'яті під ці вказівники робляться вручну. Так, наприклад, одновимірний масив змінної довжини в мові C з перевіркою меж може представлятися таким чином:
struct Array {
double* val;
int len;
};
void FreeArray (const struct Array*);
void AllocArray (const struct Array*, int len);
double Elem (const struct Array*, int i);
void ChangeElem (const struct Array*, int i, double x);
Така реалізація небезпечна і неефективна з багатьох причин:
Необхідно викликати FreeArray і AllocArray. Програміст може забути викликати одну з цих функцій, або викликати її дуже рано/запізно, або двічі, або з вказівником на неправильний масив. Все це приводить до помилок, що важко виявити.
Функції Elem і ChangeElem повільні.
Немає ніякого способу перешкодити програмістам створювати і інші функції для роботи із структурою Array. Ці функції можуть робити з полями len і val будь-що.
Немає ніякого способу перешкодити програмістам безпосередньо міняти поля len і val.
Присвоєння об'єктів типу struct Array приведе до того, що їх поля val указуватимуть на одну і ту ж область пам'яті. Немає ніякого способу ні заборонити присвоєння, ні змінити таку поведінку.
Мова Сі++, використовуючи ООП, усуває всі ці проблеми.
Інкапсуляція. Основним способом організації інформації в Сі++ є класи. На відміну від типу структура (struct) мови Сі, що складається тільки з полів, клас (class) Сі++ складається з полів і функцій-членів або методів (англ. member functions). Поля бувають публічними (public), захищеними (protected) і приватними (private). У Сі++ тип структура аналогічний типу клас, відмінність в тому, що за умовчанням поля і функції-члени у структури публічні, а у класу - приватні.
З публічними полями можна робити зовні класу все, що завгодно. До захищених і приватних полів не можна звертатися ззовні класу, щоб не порушити цілісність даних класу. Спроба такого звернення викличе помилку компіляції. До таких полів можуть звертатися тільки функції-члени класу (а також так звані функції-друзі і функції-члени класів-друзів; про поняття друзів в C++ дивись нижче.) Поза тілом функцій-членів (а також друзів) захищені і власні поля недоступні навіть для читання. Такий захист полів називається інкапсуляциєю.
Використовуючи інкапсуляцію, автор класу може захистити свої дані від некоректного використання. Крім того, вона замислювалася для полегшення сумісної розробки класів. Малося на увазі, що зміна способу зберігання даних, якщо вони оголошені як захищені або приватні не вимагає відповідних змін в класах, які використовують змінений клас. Наприклад, якщо в старій версії класу дані зберігалися у вигляді лінійного списку, а в новій версії - у вигляді дерева, ті класи, які були написані до зміни формату зберігання даних, переписувати не буде потрібно, якщо дані були приватними або захищеними (у останньому випадку - якщо використовуючі класи не були класами-нащадками), оскільки жоден з них цих класів не міг би безпосередньо звертатися до даних, а тільки через стандартні функції, які в новій версії мають вже коректно працювати з новим форматом даних. Навіть оператор доступу operator [] може бути визначений як така стандартна функція.
Функції-члени, як і поля, можуть бути публічними, захищеними і приватними. Публічні функції може викликати будь-хто, а захищені і власні - тільки функції-члени і друзі.
Використовуючи інкапсуляцію, структуру Array з попереднього розділу можна переписати таким чином:
class Array {
public:
void Alloc(int new_len);
void Free();
inline double Elem(int i);
inline void ChangeElem(int i, double x);
protected:
int len;
double* val;
};
void Array::Alloc(int new_len)
{if (len>0) Free(); len=new_len; val=new double[new_len];}
void Array::Free() {delete [] val; len=0;}
inline double Array::Elem(int i)
{assert(i>=0 && i<len ); return val[i];}
inline void Array::ChangeElem(int i, double x)
{assert(i>=0 && i<len); val[i]=x;}
І далі
Array a;
a.Alloc(10);
a.ChangeElem(3, 2.78);
double b = a.Elem(3);
a.Free();
Тут масив а має 4 публічних функції-члена і 2 захищених поля. Описувач inline означає, що замість виклику функції її код підставляється в точку виклику, що вирішує проблему неефективності.
Алгоритм розв'язування задачі.
Написання програми я почав з підключення директив препроцесора. Після чого оголосив константи заголовків пунктів меню.
Оголосив глобальні змінні:
char *menu_strs[] – масив рядків для збереження заголовків пунктів головного меню;
char *s_menu_strs[] – масив рядків для заголовків пунктів меню налагоджень;
char *i_menu_strs[] – масив рядків для збереження заголовків пунктів меню введення;
char *hint_strs[] – масив рядків для збереження підказок до пунктів головного меню;
char *s_hint_strs[] – масив рядків для підказок до пунктів меню налагоджень;
char *i_hint_strs[] – масив рядків для збереження підказок до пунктів меню введення;
char *about_strs[] – масив рядків для збереження діалогу «Про програму»;
int c_val - для збереження вибраного користувачем пункту меню в діалозі;
int md=0 – для збереження поточного стану кнопок миші;
Розробив функцію для побудови вікон void window(char capt[80], int x1, int y1, int x2, int y2, int dbl), функцію void button(char capt[80], int x1, int y1, int x2, int y2, int dbl) для побудови кнопки, int make_menu(char capt[80],int u_m,int u_n,char *u_capt_strs[],char *u_hint_strs[]) для виведення і опрацювання меню, int BP() для визначення яка кнопка миші натиснена, void int mousein(int x1, int y1, int x2, int y2) – для перевірки наявності миші в прямокутнику. Оголосив прототипи функцій:
void inputs(); - введення виразу;
void calc(); - тест виразу;
void settings(); - меню налагоджень програми;
void help(); - вивід довідки;
double parser::process_stage_main( char * exp ); - обчислення виразу;
void parser::get_element(); - функцiя отримання елементу.
Згодом оголосив головну функцію void main(). В ній я забезпечив ініціалізацію текстового режиму й генератора випадкових чисел і виклик функції make_menu ().
Графічна схема програми:
Головна програма void main():
Функція int make_menu(char capt[80],int u_m,int u_n,char *u_capt_strs[],char *u_hint_strs[]):
Функція parser::parser():
Функція void parser::putback():
Функція void rand_inp(int what):
Функція void replacestr(char *st1, char *st2):
Функція void settings():
Функція void parser::process_stage_1( double & result ):
Функція void parser::process_stage_2( double & result ):
Функція void parser::process_stage_3( double & result ):
Функція void parser::process_stage_4( double & result ):
Функція void parser::process_stage_5( double & result ):
Функція void parser::process_stage_6( double & result ):
Функція double parser::process_stage_main( char * exp ):
Функція void window(char capt[80], int x1, int y1, int x2, int y2, int dbl):
Програма та її опис.
Назва програми:
KURS_GT.CPP;
Призначення програми:
Програма призначена для навчання операцій та виразів мови програмування Cі. Вона здійснює обрахунок введеного з клавіатури або згенерованого автоматично виразу.
Мови програмування на яких написана програма:
Сі — мінімалістична мова програмування. Серед її головних цілей: можливість прямолінійної реалізації компіляції, використовуючи відносно простий компілятор, забезпечити низькорівневий доступ до оперативної пам'яті, формувати лише декілька інструкцій машинної мови для кожного елементу мови, і не вимагати обширної динамічної підтримки. У результаті, код Сі придатний для більшості системного програмного забезпечення, котре традиційно писалося на аcемблері.
Незважаючи на її низькорівневі можливості, мова проектувалася для машинно-незалежного програмування. Сумісна зі стандартами та машинно-незалежно написана програма на Сі може легко компілюватися на великій кількості апаратних платформ та операційних систем з мінімальними змінами. Мова стала доступною для великої кількості платформ, від вбудованих мікроконтроллерів до суперкомп'ютерів.
Логічна структура програми:
Дії у програмі оформлені у вигляді окремих функцій. В головній функції викликається цикл while в якому, в залежності ві того, який пункт меню користувач вибрав, викликається відповідна функція. Також є функції для побудови кнопок і вікон, функція керування клавішам, визначення попадання курсора на клавішу, функція малювання та опрацюваня меню. В навчальній функції здійснюється читання даних з текстового файлу. В функції тестування забезпечено генерування виразу і читання відповіді з клавіатури або текстового файлу, в залежності від вибору користувача. При завершені введення відбудеться його обробка і обчислення й перевірка на спів падіння із введеною відповіддю.
Вхідні та вихідні дані:
В програмі всі дані зчитуються з клавіатури, миші та текстового файлу.
Програмні засоби:
Програма може виконуватися на операційній системі DOS, Windows та її емуляцією під Linux. Для запуску програми потрібен драйвер кирилиці UKR_DOS.com або UKRDOS.com.
Технічні засоби:
Програма буде працювати при мінімальних характеристиках комп’ютера з основними технічними засобами комп’ютера: монітор, клавіатура та постійний запам’ятовуючий пристрій.
Технологія програмування, виконання та
відлагодження програми.
При тестуванні програми на всіх етапах ніяких помилок не було виявлено. Тестування програми пройшло добре. Всі пункти меню працювали як було заплановано. Всі передбачені діалоги було виведено. При читанні з файлу помилок не виникало.
Інструкція користувачеві
Для запуску програми необхідно запустити файл RUN.BAT.
Меню.
Програма має зручне меню, в якому наявнi наступнi пункти:
Input> - вибiр способу введення даних
From keyboard - ввести вираз iз клавiатури
From file - зчитати вираз iз файлу
<Back - повернутись в головне меню програми
Test - перевiрка введеного виразу
Settings> - налаштування програми
Set min random value - ввести мiнiмальне число для генератора
випадкових чисел
Set max random value - ввести максимальне число для генератора
випадкових чисел
Text background color - вибрати колiр фону
Text color - вибрати колiр тексту
<Back - повернутись в головне меню програми
Help - виклик довiдки
About - перегляд iнформацiї про прораму
Exit - вийти з програми
Управлiння.
Вибiр потрiбного пункта меню - клавiшi управлiння курсором та мишею
Завершення введення даних - Enter
Закиття повідомлень - будь-яка клавiша або правий клiк мишею
Правила формуваня виразу.
Вираз формується згiдно з правилами мови Сi.
Пiдтримуються наступнi символи:
'0'..'9','.','-' - символи для запису цiлих та дробових чисел
'+','-','*','/' - знаки додавання, вiднiмання, множення, дiлення
'%' - цiлочисельне дiлення
'^' - пiднесення со степеня
'(',')' - дужки
'[',']' - абсолютне значення
'=' - знак "дорiвнює", використання необов'язкове.
Контрольний приклад та аналіз результатів комп’ютерної реалізації програми
Було проглянуто всі довідку програми. Виконано перевірку вкладених пунктів меню. Перевірено налагодження програми. Було здійснено завантаження виразу з файлу і згодом введення з клавіатури, з використанням генератора випадкових чисел і без. Згодом було запущено тест виразу: введено вручну обрахований розв’язок згенерованого програмою виразу і введену відповідь було порівняно із результатом обчислення програми. Було здійснено перехід до пункту меню «About» і в діалоговому вікні виведено інформацію про автора програми і завдання. Всі дії було виконано два рази з використанням миші і клавіатури.