Будь умным!


У вас вопросы?
У нас ответы:) SamZan.net

тематического обеспечения ЕОМ ДНУ им

Работа добавлена на сайт samzan.net:


Отчет по лабораторной работе №2

с курса  

«Объектно-ориентированое программирование»

Студентки группы ПС-11-1

Кулинич Юлии Андреевны 

кафедра математического обеспечения ЕОМ, ДНУ им. О. Гончара

2012/2013 у.г.

Оглавление

1. Постановка задачи 3

2. Описание решения 3

Добавление класса в статическую библиотеку 4

Создание консольного приложения, ссылающегося на статическую библиотеку 5

Использование функциональных возможностей статической библиотеки в приложении 6

3. Исходный текст программы решения задачи 11

4. Описание интерфейса (руководство пользователя) 21

5. Описание тестовых примеров 22

6. Анализ ошибок 28


  1.  Постановка задачи

Розробити об’єктно-орієнтовану бібліотеку для роботи зі структурами даних за однією з нижченаведених тем у відповідності з нижченаведеними вимогами. Властивості та методи для класів розробити у відповідності з відомими визначеннями відповідних структур даних. Скласти тести для перевірки працездатності бібліотеки. Скласти програму, що демонструє можливості розробленої бібліотеки.

Загальні вимоги

В незалежності від індивідуального варіанта повинні бути реалізовані наступні можливості:

  1. Реалізація методів ініціалізації (конструктор по замовчуванню та конструктор з параметрами), копіювання (конструктор копіювання), індексації (перевантаження []), присвоювання (перевантаження =), візуалізації, збереження (на диск) та відновлення, діалогового керування, "розумного доступу" (перевантаження ->), а також псевдо змінних (забезпечення можливості виду: f(x)=const).
  2. Перевантаження (спільне використання) потокового введення/виведення. (введення з файл, виведення в файл)
  3. Створення та використання файла бібліотеки (*.LIB).
  4. Повторне використання класів без їх перекомпіляції (ReUse).
  5. Застосування вказаної структури даних для розв’язання типової задачі.

Результати виконання лабораторної роботи повинні бути викладені у вигляді звіту. Загальні вимоги до звіту – у файлі (lab_treb.doc)

В ході демонстрації роботи, програма дозволяє користувачеві в діалоговому режимі (за допомогою меню) виконувати операції над відповідними структурами даних.

Тема індивідуального завдання №12:

Багаточлени (додавання, множення, множення на константу, ділення, підвищення в степінь). Реалізація псевдозмінних: m(3,5)=9, де m – екземпляр класу багаточлен, тоді коефіцієнти з третьої по п’яту степінь заміняться на 9.

  1.  Описание решения
  2.  Создание проекта статической библиотеки
  3. В меню Файл выберите пункт Создать, а затем пункт Проект.
  4. В узле Visual C++ области Типы проектов выберите Win32.
  5. В области Шаблоны выберите Консольное приложение Win32.
  6. Выберите имя для проекта, например MathFuncsLib, и введите его в поле Имя. Выберите имя для решения, например StaticLibrary, и введите его в поле Имя решения.
  7. Для запуска мастера приложений Win32 нажмите кнопку ОК. На странице Общие сведения диалогового окна Мастер приложений Win32 нажмите кнопку Далее.
  8. На странице Параметры приложения диалогового окна Мастер приложений Win32 в поле Тип приложения выберите пункт Статическая библиотека.
  9. На странице Параметры приложения диалогового окна Мастер приложений Win32 в поле Дополнительные параметры снимите флажокПредкомпилированный заголовок.
  10. Чтобы создать проект, нажмите кнопку Готово.

Добавление класса в статическую библиотеку

  1. Чтобы создать файл заголовка для нового класса, в меню Проект выберите команду Добавить новый элемент. Откроется диалоговое окноДобавление нового элемента. В узле Visual C++ области Категории выберите пункт Код. В области Шаблоны выберите пункт Заголовочный файл (.h). Выберите имя для файла заголовка, например MathFuncsLib.h, и нажмите кнопку Добавить. Отобразится пустой файл.
  2. Добавьте класс с именем MyMathFuncs, осуществляющий обычные арифметические операции, такие как сложение, вычитание, умножение и деление.Для этого замените содержимое файла MathFuncsLib.h следующим кодом.
  3.  // MathFuncsLib.h
  4.  
  5.  namespace MathFuncs
  6.  {
  7.      class MyMathFuncs
  8.      {
  9.      public:
  10.          // Returns a + b
  11.          static double Add(double a, double b);
  12.  
  13.          // Returns a - b
  14.          static double Subtract(double a, double b);
  15.  
  16.          // Returns a * b
  17.          static double Multiply(double a, double b);
  18.  
  19.          // Returns a / b
  20.          // Throws DivideByZeroException if b is 0
  21.          static double Divide(double a, double b);
  22.      };
  23.  }

  1. Чтобы создать исходный файл для нового класса, в меню Проект выберите команду Добавить новый элемент. Откроется диалоговое окноДобавление нового элемента. В узле Visual C++ области Категории выберите пункт Код. В области Шаблоны выберите пункт Файл C++ (.cpp).Выберите имя для исходного файла, например MathFuncsLib.cpp, и нажмите кнопку Добавить. Отобразится пустой файл.
  2. Реализуйте функциональность класса MyMathFuncs в исходном файле. Для этого замените содержимое файла MathFuncsLib.cpp следующим кодом.
  3.  // MathFuncsLib.cpp
  4.  // compile with: /c /EHsc
  5.  // post-build command: lib MathFuncsLib.obj
  6.  
  7.  #include "MathFuncsLib.h"
  8.  
  9.  #include <stdexcept>
  10.  
  11.  using namespace std;
  12.  
  13.  namespace MathFuncs
  14.  {
  15.      double MyMathFuncs::Add(double a, double b)
  16.      {
  17.          return a + b;
  18.      }
  19.  
  20.      double MyMathFuncs::Subtract(double a, double b)
  21.      {
  22.          return a - b;
  23.      }
  24.  
  25.      double MyMathFuncs::Multiply(double a, double b)
  26.      {
  27.          return a * b;
  28.      }
  29.  
  30.      double MyMathFuncs::Divide(double a, double b)
  31.      {
  32.          if (b == 0)
  33.          {
  34.              throw new invalid_argument("b cannot be zero!");
  35.          }
  36.  
  37.          return a / b;
  38.      }
  39.  }
  40. Чтобы встроить проект в статистическую библиотеку, выберите в меню Проект пункт Свойства. В левой области в поле Свойства конфигурациивыберите Общие. В правой области в поле Тип конфигурации выберите Статическая библиотека (.lib). Нажмите кнопку ОК для сохранения изменений.
  41. Скомпилируйте статическую библиотеку, выбрав команду Построить решение в меню Построение. В результате будет создана статическая библиотека, которая может использоваться другими программами.

Создание консольного приложения, ссылающегося на статическую библиотеку

  1. Чтобы создать приложение, которое будет использовать созданную ранее статическую библиотеку и ссылаться на нее, в меню Файл выберите пунктСоздать, а затем пункт Проект.
  2. В узле Visual C++ области Типы проектов выберите Win32.
  3. В области Шаблоны выберите Консольное приложение Win32.
  4. Выберите имя для проекта, например MyExecRefsLib, и введите его в поле Имя. В раскрывающемся списке рядом с полем Решение выберите пунктДобавить в решение. После этого новый проект будет добавлен в то же решение, что и статическая библиотека.
  5. Для запуска мастера приложений Win32 нажмите кнопку ОК. На странице Общие сведения диалогового окна Мастер приложений Win32нажмите кнопку Далее.
  6. На странице Параметры приложения диалогового окна Мастер приложений Win32 в поле Тип приложения выберите пункт Консольное приложение.
  7. На странице Параметры приложения диалогового окна Мастер приложений Win32 в поле Дополнительные параметры снимите флажокПредкомпилированный заголовок.
  8. Чтобы создать проект, нажмите кнопку Готово.

Использование функциональных возможностей статической библиотеки в приложении

  1. После создания консольного приложения мастер создаст пустую программу. Имя исходного файла будет совпадать с именем, выбранным ранее для проекта. В этом примере он имеет имя MyExecRefsLib.cpp.
  2. Для использования математических процедур из статической библиотеки необходимо сослаться на эту библиотеку. Для этого в меню Проектвыберите пункт Ссылки. В диалоговом окне Страницы свойств библиотеки MyExecRefsLib разверните узел Общие свойства и выберите командуДобавить новую ссылку. Дополнительные сведения о диалоговом окне Ссылки см. в разделе Среда и ссылки, общие свойства и диалоговое окно "Страницы свойств: <Имя проекта>".
  3. Появится диалоговое окно Добавление ссылки. На вкладке Проекты перечисляются все проекты текущего решения и библиотеки, на которые можно создать ссылки. На вкладке Проекты выберите проект MathFuncsLib. Нажмите кнопку ОК.
  4. Для создания ссылки на файл заголовка MathFuncsLib.h необходимо изменить путь к каталогам включения. Для этого в диалоговом окне Окна свойств библиотеки MyExecRefsLib последовательно разверните узлы Свойства конфигурацииC/C++, а затем выберите Общие. В поле значения свойства Дополнительные каталоги включения введите путь к каталогу MathFuncsLib или найдите этот каталог.

Чтобы найти путь к каталогу, в раскрывающемся списке значений свойств щелкните Изменить. В текстовом поле диалогового окнаДополнительные каталоги включаемых файлов выберите пустую строку и нажмите кнопку с многоточием () в конце строки. В диалоговом окнеВыбор каталога выберите каталог MathFuncsLib и нажмите кнопку Выбор папки, чтобы сохранить выбранные значения и закрыть диалоговое окно.В диалоговом окне Дополнительные каталоги включаемых файлов нажмите кнопку ОК.

  1. Теперь класс MyMathFuncs можно использовать в приложении. Для этого замените содержимое файла MyExecRefsLib.cpp следующим кодом.
  2.  // MyExecRefsLib.cpp
  3.  // compile with: /EHsc /link MathFuncsLib.lib
  4.  
  5.  #include <iostream>
  6.  
  7.  #include "MathFuncsLib.h"
  8.  
  9.  using namespace std;
  10.  
  11.  int main()
  12.  {
  13.      double a = 7.4;
  14.      int b = 99;
  15.  
  16.      cout << "a + b = " <<
  17.          MathFuncs::MyMathFuncs::Add(a, b) << endl;
  18.      cout << "a - b = " <<
  19.          MathFuncs::MyMathFuncs::Subtract(a, b) << endl;
  20.      cout << "a * b = " <<
  21.          MathFuncs::MyMathFuncs::Multiply(a, b) << endl;
  22.      cout << "a / b = " <<
  23.          MathFuncs::MyMathFuncs::Divide(a, b) << endl;
  24.  
  25.      return 0;
  26.  }
  27. Постройте исполняемый файл, выбрав команду Построить решение в меню Построение.

Псевдопеременные - это термин, используемый для отображения определенных сведений в окне переменных или в диалоговом окне Быстрая проверка. Псевдопеременная вводится таким же способом, что и обычная переменная. Псевдопеременные не являются переменными, однако они не соответствуют именам переменных в программе.

Перегрузка ->

 Этот оператор -  доступ к объекту через указатель. Этот оператор помогат, когда в программе требуются так называемые "умные указатели" (smart pointers). Такие указатели внешне в конструкциях программы выглядят, как обычные (их можно инкрементировать и декрементировать, можно проверять значение на допустимость), но при этом их внутренняя начинка позволяет выполнять некую дополнительную работу - ту, которую в них заложил разработчик класса. Например, если у вас есть объект, содержащий массив текстовых строк, то умный указатель по оператору ++ может вместо перехода на следующую строку в массиве перейти на следующую в алфавитном порядке строку. Кстати, именно так - с помощью умных указателей - реализованы итераторы в стандартной библиотеке шаблонов. «Умные указатели» (  перегрузка   ->) обьекты, которые ведутсебя как указатели, и кроме того, выполняют некоторые действия, когда через них осуществляется доступ к обьекту.  

Неявная инициализация обеспечивается в языке C++ за счет использования

конструкторов. Конструктор—   это метод, который имеет то же самое имя, что и класс объекта. Хотя определение конструктора—   это часть определения класса, на самом деле конструктор задействуется в процесс се инициализации. В частности, метод-конструктор автоматически и неявно вызывается каждый раз, когда создается объект, принадлежащий к соответствующему классу. Можно задать несколько конструкторов. Какой конструктор будет вызван, зависит от аргументов, используемых при создании переменной. Объявление без аргументов приводит к вызову конструктора по умолчанию.

 Конструктор копирования - это конструктор, первым аргументом которого является ссылка на объект того типа, в котором этот конструктор объявлен.  Он используется, когда нужно сделать копию уже имеющегося обьекта класса.

Функция-операция содержит ключевое слово operator, за которым следует знак

переопределяемой операции:

тип operator операция ( список параметров) { тело функции }

Операция присваивания определена в любом классе по умолчанию как поэлементное

копирование. Эта операция вызывается каждый раз, когда одному существующему

объекту присваивается значение другого. Если класс содержит поля,

память под которые выделяется динамически, необходимо определить собственную

операцию присваивания. Чтобы сохранить семантику присваивания, операция-

функция должна возвращать ссылку на объект, для которого она вызвана,

и принимать в качестве параметра единственный аргумент — ссылку на присваиваемый

объект.

Операция индексирования [ ] обычно перегружается, когда тип класса представляет

множество значений, для которого индексирование имеет смысл. Операция

индексирования должна возвращать ссылку на элемент, содержащийся в множестве.

Для сохранения информации на диск будем использовать Файловые потоки. Использование файлов в программе предполагает следующие операции:

• создание потока;

• открытие потока и связывание его с файлом;

• обмен (ввод/вывод);

• уничтожение потока;

• закрытие файла.

Реализация перегрузки деления многочленов

В алгебре деление многочленов столбиком — алгоритм деления многочлена  на многочлен , степень которого меньше или равна степени многочлена . Алгоритм представляет собой обобщенную форму деления чисел столбиком, легко реализуемую вручную.

Для любых многочленов  и , , существуют единственные полиномы  и , такие что

,

причем  имеет более низкую степень, чем .

Целью алгоритма деления многочленов в столбик является нахождение частного  и остатка  для заданных делимого  и ненулевого делителя .[1]

Пример

Покажем, что

Частное и остаток от деления могут быть найдены в ходе выполнения следующих шагов:

1. Делим первый элемент делимого на старший элемент делителя, помещаем результат под чертой .

2. Умножаем делитель на полученный выше результат деления (на первый элемент частного). Записываем результат под первыми двумя элементами делимого .

3. Вычитаем полученный после умножения многочлен из делимого, записываем результат под чертой .

4. Повторяем предыдущие 3 шага, используя в качестве делимого многочлен, записанный под чертой.

5. Повторяем шаг 4.

6. Конец алгоритма.

Таким образом, многочлен  — частное деления, а  — остаток.

Реализуем этот алгоритм:

1. Повышаем степень многочлена-делителя до степени многочлена-делимого.
2. Умножаем многочлен-делитель на коэффициент при старшей степени многочлена-делимого и запоминаем этот множитель, он будет очередным коэффициентом многочлена-частного.
3. Отнимаем от многочлена-делимого полученный многочлен-делитель (таким образом, избавляемся от старшей степени многочлена-делимого, понижая его степень).
4. Если степень многочлена-делимого больше либо равна степени многочлена-делителя, перейти на пункт 1.

Разберём пример (многочлены из вики взяты):
Необходимо разделить x^3 - 12x^2 - 42 на x - 3. Имеем два массива коэффициентов:

1

2

3

| -42 | 0 | -12 | 1 |

и

| -3 | 1 |

Повышаем степень делителя. Имеем:

1

2

3

| -42 | 0 | -12 | 1 |

и

| 0 | 0 | -3 | 1 |

Умножаем полученный делитель на 1. Имеем:

1

2

3

| -42 | 0 | -12 | 1 |

и

| 0 | 0 | -3 | 1 |

Отнимаем делитель от делимого. Получаем:

1

2

3

| -42 | 0 | -9 | 0 |

и

| 0 | 0 | -3 | 1 |

Степень делимого понизилась на 1. Вернулись в начало алгоритма (степень исходного делителя всё ещё меньше делимого):

1

2

3

| -42 | 0 | -9 |

и

| -3 | 1 |

Повысили степень делителя:

1

2

3

| -42 | 0 | -9 |

и

| 0 | -3 | 1 |

Умножили делитель на -9:

1

2

3

| -42 | 0 | -9 |

и

| 0 | 27 | -9 |

Отняли делитель от делимого:

1

2

3

| -42 | -27 | 0 |

и

| 0 | 27 | -9 |

Степень исходного делителя меньше степени полученного делимого - переходим к началу:

Код Code

1

2

3

| -42 | -27 |

и

| -3 | 1 |

Повышаем степень делителя (поскольку степени равны, этот шаг оставит всё как есть):

1

2

3

| -42 | -27 |

и

| -3 | 1 |

Умножаем делитель на -27:

1

2

3

| -42 | -27 |

и

| 81 | -27 |

Отнимаем делитель от делимого:

1

2

3

| -123 | 0 |

и

| 81 | -27 |

Поскольку степень полученного многочлена (1) меньше степени исходного делителя (2) - выходим. Множители 1, -9, -27 являются коэффициентами частного в прямом порядке (частное: x^2 - 9x - 27).

  1.  Исходный текст программы решения задачи

“Lib_h.h”:

#include <iostream>

#include <fstream>

using namespace std;

class Polynom

{

 friend ostream& operator<< (ostream &output, const Polynom &p);

 friend istream& operator>> (istream &, Polynom &);

 

private:  // ptr[i] - коэф-энт, i - показатель степени

     float *ptr; //ptr to 1st element of array            

     int size; // Размер массива заданого указателем

  int counter;

 public:

  Polynom :: Polynom ();

  Polynom :: Polynom (int polynomSize);

  Polynom ::Polynom (const Polynom &polynomToCopy);

  Polynom ::~Polynom();

  int getSize() const;

  int getCounter() const;

  const Polynom &Polynom :: operator= (const Polynom &right);

  float &Polynom :: operator[] (int subscript);

  float Polynom :: operator[] (int subscript) const;

  Polynom *Polynom :: operator -> ();

  Polynom Polynom :: operator+(const Polynom &p2) const;

  Polynom Polynom :: operator-(const Polynom &p2) const;

  Polynom Polynom :: operator*(int c);

  Polynom Polynom :: operator*(const Polynom &p2);

  Polynom Polynom :: operator/(const Polynom &p2);

  Polynom Polynom :: operator()(int a, int b, int c);

  int Facktorial(int chislo);

     Polynom &Polynom :: Deg (int degree);

  void setSize(int newsize);

  void Polynom::writePolynom(char *filename);

  void Polynom::readPolynom(char *filename);

  

};

 

Lib_cpp.cpp”:

// Лабораторнаяработа№2.cpp: определяет точку входа для консольного приложения.

//

//#include <fstream>

#include "lib_h.h"

 using namespace std;

ostream& operator<< (ostream &output, const Polynom &p)

{

 cout << "f(x) = " ;

 p.counter;

 int k = 0;

 if (p.ptr[0] != 0)

 {

  cout << p.ptr[0];

  if (p.ptr[1] > 0) cout << " + ";

  else cout << " ";

 }

 if (p[1] != 0)

  {

   if (p.ptr[1] == 1)

   cout << "x";

   else cout << p.ptr[1] << "x";

   if (p.ptr[2] > 0) cout << " + ";

     }

 for (int i = 2; i < p.size; i++)

 {

  if (p.ptr[i] == 0) k++;

  if (p[i] != 0)  cout << p.ptr[i] << "x^" << i << " ";

  //if (p.ptr[i+1] > 0)  cout << "+";

  if ((i != (p.size-1)) && (p.ptr[i+1] !=0)) cout << "+";

   

 }

 if ((p.ptr[0]==0)&&(p.ptr[1]==0)&&(k == p.size-2)) cout << "0";

 return output;             // позволяет cout << p;

}

   istream& operator>> (istream &input, Polynom &p)

{

 cout << "__________________________________________" << endl

   <<"Введите коэффициэнты полинома в форме: " << endl

   << "f[степень x] = коэффициэнт" << endl;

 for (int i = 0; i < p.size; i++)

 {

  cout << "f[" << i << "] = ";

  input >> p.ptr[i];

 }

 cout << "Вы ввели полином: " << p << endl;

 cout << "__________________________________________"<< endl << endl;

 return input;              // позволяет cin >> p;

}

 // конструктор по умолчанию размера 10

Polynom :: Polynom ()

{

 counter = 0;

 //size = (polynomSize > 0 ? polynomSize : 10); //проверка polynomSize

 ptr = new float[10];

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

   ptr[i] = 0;

}

 //Конструктор

Polynom :: Polynom (int polynomSize)

{

 counter = 0;

 size = (polynomSize > 0 ? polynomSize : 10); //проверка polynomSize

 ptr = new float[size];

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

   ptr[i] = 0;

}

 //конструктор копии  использование : Polynom p2(p1);

Polynom ::Polynom (const Polynom &polynomToCopy) :size (polynomToCopy.size) //инициализатор элемента

{

 //++PolynomCount;                  // прибавление одного элемента

 //size = init.size;                // по умолчанию кол-во коэффициэнтов = 5

 ptr = new float [size];            // выделение пространства для массива

 //assert(ptr != 0);                // завершение, если память не выделена

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

  ptr[i] = polynomToCopy.ptr[i]; //копирование в объект

}

 //деструктор

Polynom ::~Polynom()

{

 //--PolynomCount; //уменьшение на 1 объект

 delete [] ptr;  //возвращение области памяти

}

  int Polynom :: getSize() const

{

 return size;

}

  int Polynom :: getCounter() const

  {

   return counter;

  }

 //Перегрузка =   - присваивание массивов

 const Polynom &Polynom :: operator= (const Polynom &right)

{

 if (&right != this) //проверка на самоприсваивание

 {

  if (size != right.size)

  {

   delete [] ptr;     //возвращение области памяти-адресанта

   size = right.size;   //изменение размера массива

   ptr = new float [size]; //выделение памяти для копии массива

  }

   //assert (ptr != 0);   //проверка успешного завершения new

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

    ptr[i] = right.ptr[i]; //copy

 }

 return *this;

}

 //операция индексации, перегрузка [] для неконстантных объектов p[5] = 5;

 float &Polynom :: operator[] (int subscript)  

{

 if (subscript < 0 || subscript >= size) //проверка на выход за границы диапозона

 {

  cerr << "Error! Subscript "<< subscript << "out of range!" << endl;

  exit(1);

 }

 return ptr[subscript];// ссылка на н-ный элемент массива

}

 //операция индексации, перегрузка [] для константных объектов, возвращает константную ссылку cout<<p[5];

 float Polynom :: operator[] (int subscript) const

{

 if (subscript < 0 || subscript >= size) //проверка на выход за границы диапозона

 {

  cerr << "Error! Subscript "<< subscript << "out of range!" << endl;

  exit(1);

 }

 return ptr[subscript];// возвращает копию элемента

}

Polynom *Polynom :: operator -> ()

{

 counter++;

 return this;

}

Polynom Polynom :: operator+(const Polynom &p2) const

{

 if (p2.size == size)

 {

  Polynom sum(p2);

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

  sum[i] += ptr[i];

  return sum;

 }

 else 

 {

  int sizeSum;

  if (p2.size > size) sizeSum = p2.size;

  if (size > p2.size) sizeSum = size;

  Polynom sum(sizeSum);

  for (int i = sizeSum; i < size;i++)

   sum[i] = ptr[i];

 if(p2.size > size)

  for (int i = sizeSum; i < p2.size;i++)

   sum[i] = p2[i];

 

 if (size > p2.size)

 {

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

   sum[i] = ptr[i];

  for (int i = 0; i < p2.size; i++)

   sum[i] += p2[i];

 }

 if (p2.size > size)

 {

     sum = p2;

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

   sum[i] += ptr[i];

     

 }

 return sum;

   }

 

}

Polynom Polynom :: operator-(const Polynom &p2) const

{

 if (p2.size == size)

 {

  Polynom razn(p2);

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

  razn[i] -= ptr[i];

  return razn;

 }

 else 

 {

  int sizeRazn;

  if (p2.size > size) sizeRazn = p2.size;

  if (size > p2.size) sizeRazn = size;

  Polynom razn(sizeRazn);

  for (int i = sizeRazn; i < size;i++)

   razn[i] = ptr[i];

 if(p2.size > size)

  for (int i = sizeRazn; i < p2.size;i++)

   razn[i] = p2[i];

 

 if (size > p2.size)

 {

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

   razn[i] = ptr[i];

  for (int i = 0; i < p2.size; i++)

   razn[i] -= p2[i];

 }

 if (p2.size > size)

 {

     razn = p2;

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

   razn[i] -= ptr[i];

     

 }

 return razn;

   }

 

}

   Polynom Polynom :: operator*(int c)

{   

 for (int i = 0; i < this->getSize(); i++)

             ptr[i] *= c;

 return *this;

}

Polynom Polynom :: operator*(const Polynom &p2)

{

 Polynom mult(size + p2.size);

 for (int i = 0; i < this->getSize(); i++)

 {

  for (int j = 0; j < p2.size; j++)

  {

      mult[i + j] = mult[i + j] + this->ptr[i]*p2[j];

  }

 }

 return mult;

}

 Polynom Polynom :: operator/(const Polynom &p2)

 {

 if (size < p2.size)

 {

  cerr << "Ошибка! Степень полинома-делителя больше, чем полинома-делимиго!";

  return p2;

 }

 Polynom P1(this->getSize());

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

  P1.ptr[i] = ptr[i];

 Polynom P2(p2);

 int sizeRes = 1 + size - P2.size;

 Polynom res(sizeRes);

 int tempSize = size;

 int tempP2Size = P2.size;

 int k = sizeRes - 1;

 float tempcoef = 1;

 while ((tempSize >= tempP2Size)||(k>=0))

 {

       float *temp = new float[tempSize];

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

     temp[i] = 0;

    //cout << "tempSize = "<< tempSize<<endl;

    //cout << "tempP2Size = " <<tempP2Size<<endl;

    if (tempSize > tempP2Size)    

    {

     for(int i = (tempP2Size - 1), j = (tempSize - 1); j > (tempSize - tempP2Size - 1); j--, i--)

      temp[j] = P2.ptr[i];

    }

    else for (int i = 0; i < tempP2Size; i++)

          temp[i] = P2.ptr[i];

    //for(int i = 0; i< tempSize; i++)

         //cout << ptr[i] << "    ";

    //cout << endl<<"temp: ";

  //for (int i = 0; i < tempSize; i++)

   //cout << temp[i] << "  ";

  //cout << "    "<< endl;

  tempcoef = P1.ptr[tempSize-1]/temp[tempSize-1]; //ptr

  // cout << "tempcoef = " << tempcoef<< endl;

  res.ptr[k] = tempcoef;

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

   temp[i] *= tempcoef;

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

   P1.ptr[i] = P1.ptr[i] - temp[i];  //ptr

  //for(int i = 0; i < tempSize; i++)

  //cout << ptr[i] << "   ";

  //cout << endl;

  delete []temp;

  tempSize--;

  k--;

  //cout <<endl << "next step: " << endl;

  //cout << "res : " <<res<<endl;

  if ( tempSize == 1) cout << "Остаток: "<< P1.ptr[0]<<endl;

 }

 //cout <<"res: "<< res << endl;

 return res;

 }

 

 int Polynom :: Facktorial(int chislo)

{

 if (chislo <= 1) return 1;

 else 

  {   int a = 1;

   for(int i = chislo; i > 0; i--)

    a = a*i;

   return a;

     }        

}

Polynom &Polynom :: Deg (int degree)

{

 if (this->getSize() >= 3)

 {

  cerr << "Ошибка! Данная функция возведит в степень многочлен только 1ой степени!"<<endl;

  return *this;

 }

 Polynom pd(degree + 1);

 Polynom coef(degree + 1);

 for (int k = 0; k <= degree; k++)

    coef[k] = coef.Facktorial(degree)/(coef.Facktorial(k) * coef.Facktorial(degree - k));

 for (int k = 0; k <= degree; k++)

 {

    int deg = degree - k;

    pd.ptr[k] = coef[k] * pow(ptr[0], deg) * pow (ptr[1], k);  

 }

 this->setSize(degree + 1);

 for (int i = 0; i < degree+1; i++)

   ptr[i] = pd[i];

 

    return *this;

}

 void Polynom ::setSize(int newsize)

{

 size = newsize;

}

 Polynom Polynom :: operator()(int a, int b, int c)

{

 if (a < 0 || a >= size) //проверка на выход за границы диапозона

 {

  cerr << "Ошибка!  "<< a << " выходит за границы диапозона!" << endl;

  return *this;

 }

 if (b < 0 || b >= size) //проверка на выход за границы диапозона

 {

  cerr << "Ошибка!  "<< b << " выходит за границы диапозона!" << endl;

  return *this;

 }

 if ( a > b)

 {

  cerr << "Вы ввели нелогичные данные: а > b!!! "<< endl;

  return *this;

 }

 for (int i = a; i < b+1;i++)

  ptr[i] = c; //no const

 //cout << "Измененный полином: " << *this << endl;

 return *this;

}

 void Polynom::writePolynom(char *filename)

{

 fstream f;

 f.open(filename, ios::out);

 if (f.fail())

 {

  cerr<<"Can't open file\n";

  system("PAUSE");

 }

 f << "f(x) = " ;

 if (ptr[0] != 0)

 {

  f << ptr[0];

  if (ptr[1] > 0) f << " + ";

  else f << " ";

 }

 if (ptr[1] != 0)

  {

   if (ptr[1] == 1)

       f << "x";

   else f << ptr[1] << "x";

   if (ptr[2] > 0) f << " + ";

     }

 for (int i = 2; i < size; i++)

 {

  if (ptr[i] != 0)  f << ptr[i] << "x^" << i << " ";

  if ((ptr[i+1] > 0) || (i != (size-1))) f << "+";

   

 }

 f <<endl;

 

}

 void Polynom::readPolynom(char *filename)

{

 fstream f;

 f.open(filename, ios::in);

 if (f.fail())

 {

  cerr<<"Can't open file\n";

  system("PAUSE");

 }

 f.seekg(0);

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

      f>>ptr[i];

}

“main.cpp”:

//#include "stdafx.h"

#include "lib_h.h"

#include <iostream>

using namespace std;

class f:public Polynom

{

public:

f(int chislo):Polynom(){}

 void ff()

{

 cout << "=)"<< endl;

 system("pause");

}

f();

private :

 int m;

};

int main()

{

 setlocale(LC_ALL, "Russian");

 cout << "Program by Kulinich Yulia PS-11-1" << endl

  << "Данная программа производит операции с полиномами" << endl;

 char cont;

 bool vv;

 f f1(4);

 f1.ff();

 cout << "Вводить значения с клавиатуры или из файла? Введите \n0 - с клавиатуры; \n1 - с файла"<<endl;

 cin >> vv;

 int count1, count2;

 if (vv == 0)

 {

     cout << "Введите степень вашего первого полинома"<< endl;

  cin >> count1;

  cout << "Введите степень второго полинома"<< endl;

  cin >> count2;

 }

 else 

 {

  count1 = 3;

  count2 = 3;

 }

     Polynom p1 (count1 + 1); //определение экземпляра

  Polynom p2 (count2 + 1); //определение экземпляра обьекта м класса Polynom

   do 

   {

 char choice;

 cout << "_______________________Meню______________________" << endl

   << "|                                               |" << endl

   << "|  1 - Сумма многочленов: P1 + P2               |" << endl

   << "|  2 - Произведение многочленов: P1*P2          |" << endl

   << "|  3 - Умножение на константу: P1*const         |" << endl

   << "|  4 - Деление многочленов: P1/P2               |" << endl

   << "|  5 - Возведение в степень: P1^const           |" << endl

   << "|  6 - Присваивание p1  p2: P1 = P2             |" << endl

   << "|  7 - Режим псевдопеременных                   |" << endl

   << "|  8 - Разность многочленов: P1 - P2            |" << endl

   << "|_______________________________________________|" << endl

   << "\nВаш выбор  ";

 cin >> choice;

 switch (choice)

{

    case '1':

  if (vv == true)

  {

   p1.readPolynom("lab1text.txt");

   p2.readPolynom("lab2text.txt");

  }

  else

  {

   cin >> p1;

   cin >> p2;

  }

  cout << p1->getSize() << endl;

  //cout << p1.getCounter()<<endl;

  cout << p1 + p2 << endl;

  (p1+p2).writePolynom("lab2.txt");

  cout << "Количество обращений к элементам многочлена p1 с использованием перегрузки -> :" << p1.getCounter()<<endl;

  cout << "Количество обращений к элементам многочлена p2 с использованием перегрузки -> :" << p2.getCounter()<<endl;

  break;

 case '2':    

  if (vv == true)

  {

   p1.readPolynom("lab1text.txt");

   p2.readPolynom("lab2text.txt");

  }

  else

  {

   cin >> p1;

   cin >> p2;

  }

  cout << p1 * p2 << endl;

  (p1*p2).writePolynom("lab2.txt");

  cout << "Количество обращений к элементам многочлена p1 с использованием перегрузки -> :" << p1.getCounter()<<endl;

  cout << "Количество обращений к элементам многочлена p2 с использованием перегрузки -> :" << p2.getCounter()<<endl;

  break;

 case '3':

  if (vv == true)  p1.readPolynom("lab1text.txt");

  else cin >> p1;

  int constt;

  cout << "input c = ";

  cin >> constt;

  cout << endl << p1*constt << endl;

  (p1*constt).writePolynom("lab2.txt");

  cout << "Количество обращений к элементам многочлена p1 с использованием перегрузки -> :" << p1.getCounter()<<endl;

  break;

 case '4':

  if (vv == true)

  {

   p1.readPolynom("lab1text.txt");

   p2.readPolynom("lab2text.txt");

  }

  else

  {

   cin >> p1;

   cin >> p2;

  }

  cout << p1/p2 << endl;

  (p1/p2).writePolynom("lab2.txt");

  cout << "Количество обращений к элементам многочлена p1 с использованием перегрузки -> :" << p1.getCounter()<<endl;

  cout << "Количество обращений к элементам многочлена p2 с использованием перегрузки -> :" << p2.getCounter()<<endl;

  break;

 case '5':

  if (vv == true)  p1.readPolynom("lab1text.txt");

  else cin >> p1; //==:  operator>> (cin, polynom_1);

  int degree;

  cout << "Введите степень, в которую хотите возвести полином - ";

  cin >> degree;

  cout << p1.Deg(degree) << endl;

  p1.setSize(count1);

  (p1.Deg(degree)).writePolynom("lab2.txt");

  p1.setSize(count1);

  cout << "Количество обращений к элементам многочлена p1 с использованием перегрузки -> :" << p1.getCounter()<<endl;

  break;

    case '6':

  if (vv == true)

  {

   p1.readPolynom("lab1text.txt");

   p2.readPolynom("lab2text.txt");

  }

  else

  {

   cin >> p1;

   cin >> p2;

  }

  p2 = p1;

  cout << p2 << endl;

  cout << "Количество обращений к элементам многочлена p1 с использованием перегрузки -> :" << p1.getCounter()<<endl;

  cout << "Количество обращений к элементам многочлена p2 с использованием перегрузки -> :" << p2.getCounter()<<endl;

  break;

 case '7':

  if (vv == true)  p1.readPolynom("lab1text.txt");

  else cin >> p1;

  int a, b, c;

 cout << "Режим задания псевдопеременной" << endl

      << "Реализация псевдопеременных: р(a,b)=c, где р – экземпляр класса многочлен,"

   << " тогда коэфициэнты с a по b степень заменятся на c" << endl

      <<"Введите значения псевдопеременных: \na = ";

 cin >> a;

 cout << "\nb = ";

 cin >> b;

 cout << "\nc = ";

 cin >> c;

 cout << p1(a, b, c) << endl;

 (p1(a, b, c)).writePolynom("lab2.txt");

 cout << "Количество обращений к элементам многочлена p1 с использованием перегрузки -> :" << p1.getCounter()<<endl;

  break;

 case '8':

  if (vv == true)

  {

   p1.readPolynom("lab1text.txt");

   p2.readPolynom("lab2text.txt");

  }

  else

  {

   cin >> p1;

   cin >> p2;

  }

  cout << p1 - p2 << endl;

  (p1-p2).writePolynom("lab2.txt");

  cout << "Количество обращений к элементам многочлена p1 с использованием перегрузки -> :" << p1.getCounter()<<endl;

  cout << "Количество обращений к элементам многочлена p2 с использованием перегрузки -> :" << p2.getCounter()<<endl;

  break;

 default:

  cout << "Вы ошиблись при вводе! Вводите числa только от 1 до 8!"<< endl;

 }

 

 cout << "\nВы хотите продолжать работу с программой? Введите Y(y)/N(n)" << endl;

 cin >> cont;

 if ((cont != 'Y')&&(cont != 'y')&&(cont != 'N')&&(cont != 'n'))

   {

  while ((cont != 'Y')&&(cont != 'y')&&(cont != 'N')&&(cont != 'n'))

   {

    cerr << "Вы ошиблись при вводе! Пожалуйста вводите только Y или y, если вы согласны продолжать работу и N или n, если хотите выйти из программы!" << endl;

    cin >> cont;

   }

   }

 }

 while ((cont == 'Y') || (cont == 'y'));

 system("PAUSE");

 return 0;

}

  1.  Описание интерфейса (руководство пользователя)

При запуске программы на консоль выводится приглашение ввести степень полиномов, с которыми будет производиться работа:

После ввода максимальных степеней полиномов выводится меню:

Далее от выбора пользователя зависит дальнейшая работа программы, к примеру пользователь выберет «1»:

На консоли появится приглашение ввести коэфициэнты полиномов, затем выведется введенный многочлен и результат. После этого выведется приглашение продолжить работу. В зависимости от выбора пользователя программа продолжает или завершает работу.

  1.  Описание тестовых примеров

1.)Если пользователь выбрал «1»:

Допустим степень многочленов разная, например, степень 1ого многочлена больше, чем степень 2ого:

Или, например, степень 2ого многочлена больше чем степень 1ого:

2.)Если пользователь выбрал «2»:

Если пользователь выбрал «3»:

4.) Если пользователь выбрал «4»:

5.)Если пользователь выбрал «5»:

Степень полинома больше чем 1:

Выводит ошибку, тогда перезапустим программу и введем многочлен 1ой степени:

6.)Если пользователь выбрал «6»:

7.)Если пользователь ввел «7»:

  1.  Анализ ошибок

Для начала проанализируем ошибки которые могут возникнуть при работе приложения:

  1.  Выход за границы массива:

Программа перехватывает данную ситуацию с помощью:

if (subscript < 0 || subscript >= size) //проверка на выход за границы диапозона

 {

  cerr << "Error! Subscript "<< subscript << "out of range!" << endl;

  exit(1);

 }

  1.  Ошибка при открытии файла:

Программа перехватывает данную ситуацию с помощью:

if (f.fail())

 {

  cerr<<"Can't open file\n";

  system("PAUSE");

 }

  1.  Запуск логически неверных операций, например деление многочлена на многочлен с большей степенью:

  1.  Ввод недопустимого значения, например  при запросе продолжать ли работу с программой ввод буквы X’:




1. вверх ногами партнершей бедный теолог вынужден был вальсировать глядя сквозь этот драгоценный обруч нах
2. ть напр. на воздействие и изменение психической реальности
3. тема отношений и общения с окружающими; способность к труду обучению к организации досуга и отдыха; изме
4. Операционно-технологическая карта на операцию- перепашка пара
5. ПРОЦЕССУАЛЬНОГО ПРИНУЖДЕНИЯ ^ 1 Понятие мер ^ производство по уголовному делу уголовнопроцессуа
6. Китай Ченде
7. для дам в России появились более 200 лет назад а не в 1990е как многие думают
8. Экологические основы природопользования
9.  Организационная часть 6
10. 40. 30 Спинномозговая жидкость её функции
11. социология и политология для студентов очной формы обучения РостовнаДону 2012
12. не бойтесь Я возвещаю вам великую радость которая есть для всех людей Лк 210
13. Становление новороссийской государственности
14. Реферат- Визначення ефективності та опрацювання напрямків поліпшення сітуації на підприємстві
15. РоссияВосток книга вторая
16. Предмет и основные концепции науки о человеке
17. Задание 1- К тексту стихотворения Сергея Есенина БЕРЕЗА добавьте- заголовок объект Wordrt автора
18. Вариант работы выбирается по последней цифре номера зачетной книжки
19. 9кл 11-1215-16 лет Подросток в одно и тоже время ~ и ребенок и взрослый а точнее сказать уже не ребенок но ещ
20. Информационная поддержка жизненного цикла изделия Понятие жизненного цикла изделия