You are on page 1of 13

Міністерство Освіти і Науки України

Київський Національний Університет імені Тараса Шевченка

Факультет Інформаційних Технологій

Звіт з лабораторної роботи №5


з дисципліни Технології програмування

Вико
нав студент групи ІР-22
Музика Марк Сергійович
Викладач : к.ф.-м.н., ас. Пономарнеко Роман
Миколайович

Київ – 2021
ЗМІСТ
1. Постановка завдання 3
2. Аналітичні викладки 3
3. UML діаграма класу 4
4. Код програми 5
5. Тестування програми 13
6. Висновок 13
Лабораторна робота №5
Тема: Виняткові ситуації С++.
Мета: вивчити особливості генерації і обробки виняткових ситуацій в С ++.
Етапи виконання завдання:
Розробити покроковий алгоритм вирішення розрахункової частини завдання
і підзадач (при необхідності). Розробити UML діаграму класів. Виконати
програмну реалізацію завдання відповідно до варіанту. Прототипи класів
повинні містяться в окремому * .h- файлі. У програмі обов'язково передбачити
висновок інформації про виконавця роботи (ПІБ), номер варіанта, обраному
рівні складності і завданні. Передбачити можливість повторного запуску
програми (запит про бажання вийти з програми, або продовжити роботу).
Ключові моменти програми обов'язково повинні містити коментарі.
Завдання 1

Аналітичні викладки:
Виняткова ситуація – це незвичайні або несподівані обставини, що
виникають в роботі програми: збої апаратури, помилки введення-
виведення, програмні помилки. Виняткові ситуації призводять до переривання
програми, після чого слід необхідно виявити виняток і обробити його таким
чином, щоб виключити переривання при виконанні програми.
Для обробки виключень використовуються так звані блоки try-catch.
У разі, якщо «викидаються» нетипізовані дані(екземпляри класів, структур і
т.д.), краще «ловити» їх за посиланням. Якщо викидаються дані декількох
типів, то можна використовувати кілька блоків catch, що ловлять кожен
свій тип даних.
Коли порушується виняткова ситуація, програма переглядає стек функцій до
тих пір, поки не знайде відповідний catch. Якщо такий оператор не
знайдений, то виключення обробляється в стандартному обробнику, показуючи
незрозумілі повідомлення та аварійно завершуючипрограму.Блокиtry-
catchможутьміститивкладеніблокиtry-catch, та якщо не буде визначено
відповідного оператора catch на поточному рівні вкладення, виняток буде
спіймано на більш високому рівні. Оператори, що слідують за оператором
throw, ніколи не виконуються.
Будь-яке виключення, що виникло в процесі роботи програми, обов'язково
обробляється, якщо для нього є оператор catch(); якщо ж виняток не знаходить
відповідний catch(), то такий необроблений виняток передається по ланцюжку
виклику функції до тих пір, поки не залишиться нерозглянутих винятків. Якщо
catch() не буде знайдений, то виключення обробляється стандартними
функціями unexpected(), terminate(), abort().
Основне призначення unexpected() – підготувати програму до переривання,
далі викликається функція terminate(), що викликає abort() - ненормальне
завершення програми. Якщо необхідно обробити не специфіковане виключення
без використання стандартної unexpected(), що не допускає втручання, то
виконується перевизначення функцій unexpected() та terminate()за допомогою
функцій set_unexpected() та set_terminate().
UML діаграма класів:

Код програми:
Lab5.cpp:

#include "pch.h"
#include "Fraction.h"
#include "ExceptionHandler.h"
#include <iostream>
#include <string>
#include <ctime>

using namespace std;

void print_out(Fraction* fraction, char k)


{
int M, N;
char flag;

switch (k) {
case '+': cout << "Бажаєте додати число чи об'єкт типу Fraction: введiть n або f
вiдповiдно" << endl;
break;
case '-': cout << "Бажаєте вiдняти число чи об'єкт типу Fraction: введiть n або f
вiдповiдно" << endl;
break;
case '*': cout << "Бажаєте помножити на число чи на об'єкт типу Fraction: введiть n
або f вiдповiдно" << endl;
break;
case '/': cout << "Бажаєте подiлити на число чи на об'єкт типу Fraction: введiть n
або f вiдповiдно" << endl;
break;
}
cin >> flag;

if (flag == 'n')
{
cout << "Введiть число: ";
cin >> M;

switch (k) {
case '+': fraction = *fraction + M;
break;
case '-': fraction = *fraction - M;
break;
case '*': fraction = *fraction * M;
break;
case '/': fraction = *fraction / M;
break;
}
fraction->print();
}
else
{
cout << "Введiть чисельник: ";
cin >> M;

cout << "Введiть знаменник: ";


cin >> N;
Fraction* fraction_temp = new Fraction(M, N);

switch (k) {
case '+': fraction = *fraction + fraction_temp;
break;
case '-': fraction = *fraction - fraction_temp;
break;
case '*': fraction = *fraction * fraction_temp;
break;
case '/': fraction = *fraction / fraction_temp;
break;
}
fraction->print();
delete fraction_temp;
}
}

void repeat_try(Fraction* fraction, char k)


{
bool key_ex = true;
while (key_ex)
{
try {
try {
print_out(fraction, k);
}
catch (ExceptionHandler& ex) {
ex.print_ex();
throw ex;
}
key_ex = false;
}
catch (...) {
cout << "Повторiть спробу" << endl;
}
}
}

int main()
{
setlocale(0, "rus");

cout << "Варiант 11(Б)" << endl;


cout << "Музика Марк IP-22" << endl;

char p = 'y';
bool key_ex;
int N, M;
int temp_x, temp_y;
int array_size = 4;

while (p == 'y')
{
key_ex = true;

Fraction* fraction = new Fraction();


Fraction** fraction_array = new Fraction*[array_size];
while (key_ex)
{
try {
try {
cout << "Введiть чисельник: ";
cin >> M;
cout << "Введiть знаменник: ";
cin >> N;

fraction = new Fraction(M, N);


cout << "Введений дрiб:" << endl;
fraction->print();

for (int i = 0; i < array_size; i++)


fraction_array[i] = fraction;
}
catch (ExceptionHandler& ex) {
ex.print_ex();
throw ex;
}
key_ex = false;
}
catch (...) {
cout << "Повторiть спробу" << endl;
}
}

for (int i = 0; i < array_size; i = i + 4)


{
repeat_try(fraction_array[i], '+');
repeat_try(fraction_array[i + 1], '-');
repeat_try(fraction_array[i + 2], '*');
repeat_try(fraction_array[i + 3], '/');
}

cout << "Бажаєте продовжити використання, якщо так то введiть y, якщо нi то n:


";
cin >> p;

while ((p != 'y') && (p != 'n'))


{
cout << "Повторiть спробу: ";
cin >> p;
}

delete fraction;
delete[] fraction_array;
}

return 0;
}

Fraction.h:

#pragma once

class Fraction {
private:
int up; //in instruction it is m
int down; //in instruction it is n

int gcd(int M, int N); //greatest common divisor of fraction up and down
public:
Fraction(void);
Fraction(int M, int N);

Fraction* operator +(int X);


Fraction* operator +(Fraction* X);

Fraction* operator -(int X);


Fraction* operator -(Fraction* X);

Fraction* operator *(int X);


Fraction* operator *(Fraction* X);

Fraction* operator /(int X);


Fraction* operator /(Fraction* X);

void setUp(int X);


void setDown(int X);

int getUp(void) const;


int getDown(void) const;
void print(void) const;
};

Fraction.cpp:

#include "pch.h"
#include "Fraction.h"
#include "ExceptionHandler.h"
#include <iostream>

using namespace std;

Fraction::Fraction(void) : up(0), down(1)


{
}

Fraction::Fraction(int M, int N) : up(M), down(N)


{
if (N == 0)
throw ExceptionHandler(M, N, 'c', 'c');
else
{
int temp_gcd = gcd(up, down);
if (temp_gcd != 0)
{
up = up / temp_gcd;
down = down / temp_gcd;
}
else
{
up = 1;
down = 1;
}
}
}

Fraction* Fraction::operator+(int X)
{
Fraction* temp = new Fraction(this->up, this->down);
temp->up = temp->up + (temp->down * X);

int temp_gcd = gcd(temp->up, temp->down);


if (temp_gcd != 0)
{
temp->up = temp->up / temp_gcd;
temp->down = temp->down / temp_gcd;
}
else
{
temp->up = 1;
temp->down = 1;
}

return temp;
}

Fraction* Fraction::operator+(Fraction* X)
{
Fraction* temp = new Fraction(this->up, this->down);
temp->up = (temp->up * X->down) + (X->up * temp->down);
temp->down = temp->down * X->down;

int temp_gcd = gcd(temp->up, temp->down);


if (temp_gcd != 0)
{
temp->up = temp->up / temp_gcd;
temp->down = temp->down / temp_gcd;
}
else
{
temp->up = 1;
temp->down = 1;
}
return temp;
}

Fraction * Fraction::operator-(int X)
{
Fraction* temp = new Fraction(this->up, this->down);
temp->up = temp->up - (temp->down * X);

int temp_gcd = gcd(temp->up, temp->down);


if (temp_gcd != 0)
{
temp->up = temp->up / temp_gcd;
temp->down = temp->down / temp_gcd;
}
else
{
temp->up = 1;
temp->down = 1;
}

return temp;
}

Fraction * Fraction::operator-(Fraction* X)
{
Fraction* temp = new Fraction(this->up, this->down);
temp->up = (temp->up * X->down) - (X->up * temp->down);
temp->down = temp->down * X->down;

int temp_gcd = gcd(temp->up, temp->down);


if (temp_gcd != 0)
{
temp->up = temp->up / temp_gcd;
temp->down = temp->down / temp_gcd;
}
else
{
temp->up = 1;
temp->down = 1;
}

return temp;
}

Fraction * Fraction::operator*(int X)
{
Fraction* temp = new Fraction(this->up, this->down);
temp->up = temp->up * X;

int temp_gcd = gcd(temp->up, temp->down);


if (temp_gcd != 0)
{
temp->up = temp->up / temp_gcd;
temp->down = temp->down / temp_gcd;
}
else
{
temp->up = 1;
temp->down = 1;
}

return temp;
}

Fraction * Fraction::operator*(Fraction* X)
{
Fraction* temp = new Fraction(this->up, this->down);
temp->up = temp->up * X->up;
temp->down = temp->down * X->down;

int temp_gcd = gcd(temp->up, temp->down);


if (temp_gcd != 0)
{
temp->up = temp->up / temp_gcd;
temp->down = temp->down / temp_gcd;
}
else
{
temp->up = 1;
temp->down = 1;
}

return temp;
}

Fraction * Fraction::operator/(int X)
{
Fraction* temp = new Fraction(this->up, this->down);

if (X == 0)
throw ExceptionHandler(X, '/');
else
{
temp->down = temp->down * X;

int temp_gcd = gcd(temp->up, temp->down);


if (temp_gcd != 0)
{
temp->up = temp->up / temp_gcd;
temp->down = temp->down / temp_gcd;
}
else
{
temp->up = 1;
temp->down = 1;
}

return temp;
}
}

Fraction * Fraction::operator/(Fraction* X)
{
Fraction* temp = new Fraction(this->up, this->down);

if (X->up == 0)
throw ExceptionHandler(X->up, X->down, '/', 'f');
else
{
temp->up = temp->up * X->down;
temp->down = temp->down * X->up;

int temp_gcd = gcd(temp->up, temp->down);


if (temp_gcd != 0)
{
temp->up = temp->up / temp_gcd;
temp->down = temp->down / temp_gcd;
}
else
{
temp->up = 1;
temp->down = 1;
}
return temp;
}
}

int Fraction::gcd(int M, int N) {


if (N == 0)
return M;
else
return gcd(N, M % N);
}

void Fraction::setUp(int X)
{
up = X;
}

void Fraction::setDown(int X)
{
if (X == 0)
throw ExceptionHandler(up, X, 'c', 'c');
else
down = X;
}

int Fraction::getUp(void) const


{
return up;
}

int Fraction::getDown(void) const


{
return down;
}

void Fraction::print(void) const


{
cout << up << endl;
cout << "------" << endl;
cout << down << endl;
}

ExceptionHandler.h:

#pragma once

class ExceptionHandler {
private:
int up;
int down;
char symbol;
char type;

void print_ex_create() const;


void print_ex_number() const;
void print_ex_fraction() const;
public:
ExceptionHandler(int NUMBER, char SYMBOL);
ExceptionHandler(int UP, int DOWN, char SYMBOL, char TYPE);

void print_ex() const;


};

ExceptionHandler.cpp:

#include "pch.h"
#include "ExceptionHandler.h"
#include <iostream>
using namespace std;

ExceptionHandler::ExceptionHandler(int NUMBER, char SYMBOL) : up(NUMBER), down(1),


symbol(SYMBOL), type('n')
{
}

ExceptionHandler::ExceptionHandler(int UP, int DOWN, char SYMBOL, char TYPE) : up(UP),


down(DOWN), symbol(SYMBOL), type(TYPE)
{
}

void ExceptionHandler::print_ex() const


{
switch (type) {
case 'c': print_ex_create();
break;
case 'n': print_ex_number();
break;
case 'f': print_ex_fraction();
break;
}
}

void ExceptionHandler::print_ex_create() const


{
cout << "Error occured when you try to create a fraction: " << up << " / " << down <<
endl;
}

void ExceptionHandler::print_ex_number() const


{
cout << "Error occured when you try to " << symbol << " number: " << up << endl;
}

void ExceptionHandler::print_ex_fraction() const


{
cout << "Error occured when you try to " << symbol << " fraction: " << up << " / " <<
down << endl;
}
Тестування програми:

Висновок: вивчити особливості генерації і обробки виняткових ситуацій на


прикладі мови програмування високого рівня С++.

You might also like