Министерство науки и образования Украины

НТУУ «КПИ» Славутичская филия

Курсовая работа

по

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

«КАЛЬКУЛЯТОР МАТРИЦ»

Выполнил:

студенты группы ИСС-71

Проверил:

Славутич 2009 г.

Введение........................................................................................................................................

ГЛАВА 1........................................................................................................................................

Теоретические основы ООП........................................................................................................

ГЛАВА 2........................................................................................................................................

Техническое задание.......................................................................................................

2.1.Описание предметной области..........................................................................................

2.1.1 Матрицы.........................................................................................................................

2.1.2 Определители..............................................................................................................

2.2.Технология обработки информации................................................................................

2.2.1. Функциональные требования...................................................................................

НЕ нашли? Не то? Что вы ищете?

2.2.2. Требования к интерфейсу..........................................................................................

ГЛАВА 3......................................................................................................................................

РАБОЧИЙ ПРОЕКТ...................................................................................................................

3.1.Общие сведения (среда функционирования (ОС), способ загрузки, способ инсталляции, требования к ПО, требования к ТО).............................................................................................................

3.2. Укрупненный алгоритм..................................................................................................

3.2.1.КЛАССЫ.....................................................................................................................

3.2.2.МОДУЛИ.....................................................................................................................

3.2.3.СХЕМА АЛГОРИТМА..............................................................................................

3.2.4.ОБРАБОТКА ИСКЛЮЧЕНИЙ.................................................................................

3.2.Руководство пользователя................................................................................................


Введение

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

Целью данного курсового проекта является создание именно такой программы, которая могла бы выполнять основные операции над матрицами.

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

Значит предполагаемый проект должен обладать рядом качеств, которые бы выделили его среди остальных программ с той же функцией.

Во-первых, функциональность, то есть программа должна включать основной и дополнительный набор операций с матрицами.

Во-вторых, простота интерфейса, рассчитанного практически на любого пользователя, имеющего хотя бы первоначальное понятие о матрицах.

В-третьих удобство в использовании программы.

Основное назначение данного курсового проекта – увеличение показателя производительности работников, чья работа связана с вычислениями каких-то величин размерностью матриц, из-за использования нового программного продукта на производстве.

ГЛАВА 1

Теоретические основы ООП

История становления программирования богата какими-либо нововведениями, которые коренным образом меняют всю предшествующую систему. Одним из первых и наиболее ярких таких открытий можно считать выход в свет книги «Программирование без GOTO». Следующим наиболее важным шагом по праву считают переход к процедурно-функциональному программированию, когда программы разбивались на ряд независимых блоков, и в итоге просто грамотно соединялись в единое целое. Ну и третьим, наверное, самым большим открытием можно считать появление объектно-ориентированного программирования. ООП объединило в себе одновременно процедурные методы, для чего создавались самостоятельные модули, структурное проектирование и стимулировало творческий подход к созданию программ.

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

Неформально можно сказать, что объектно-ориентированное программирование стоит на трёх китах, таких как инкапсуляция, полиморфизм и наследование. Что же это такое?

Инкапсуляция – это процесс отделения друг от друга элементов объекта, определяющих его устройство и поведение; инкапсуляция служит для того, чтобы изолировать обязательства абстракции от их реализации.

Наследование означает такое отношение между классами (отношение родитель - потомок), когда один класс заимствует структурную или функциональную часть одного или нескольких других классов (соответственно, одиночное и множественное наследование).

Полиморфизм: одно и то же имя может означать объекты разных типов, но, имея общего предка, все они имеют и общее подмножество операций, которые можно над ними выполнять.

Главным звеном программы в ООП является объект (например класс).Главным в понятии объекта является объединение идей абстракции данных и алгоритмов. Объекты обладают целостностью, которая не может быть нарушена. Свойства, которые характеризуют объект и его поведение, остаются неизменными.

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

Для ООП очень важное значение имеет понятие абстрагирования.

Абстракция выделяет существенные характеристики некоторого объекта, отличающие его от всех других видов объектов и, таким образом, четко определяет его концептуальные границы с точки зрения наблюдателя.

Абстрагирование концентрирует внимание на внешних особенностях объекта и позволяет отделить самые существенные особенности поведения от несущественных.

Класс делится на две части: интерфейс и реализацию.

Интерфейс отражает внешнее поведение объекта, описывая абстракцию поведения всех объектов данного класса.

Внутренняя реализация описывает представление этой абстракции и механизмы достижения желаемого поведения объекта.

Для удобного представления программы используются модульность и иерархия. Модульность – это разделение программы на фрагменты, которые компилируются по отдельности, но могут устанавливать связи с другими модулями. Иерархия – это упорядочение абстракций, разложение их по уровням.

Сохраняемость – способность объекта существовать во времени, переживая породивший его процесс, и (или) в пространстве, перемещаясь из своего первоначального адресного пространства. Говоря другими словами, сохраняемость – это способность классов использоваться не только в одной программе или части программы.

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

1)  все объекты имеют свой специализированный тип - класс;

2)  каждый класс должен иметь различные виды полей данных, в зависимости от степени доступа: закрытые, открытые, наследованные;

3)  классы могут наследовать часть полей данных и методов у других классов;

4)  методы представляются в виде именованных операций, что придает программе читабельность.

С++ - это попытка решения разработчиками языка С задач объектно-ориентированного программирования. С++ был разработан сотрудником исследовательской лаборатории компании AT&T Бьерном Страуструпом (Bjarn Stroustrup) в 1980 году. В своих исторических замечаниях Страуструп поясняет, почему в качестве базового языка был выбран С:

- многоцелевой, лаконичный и относительно низкого уровня;
- отвечает большинству задач системного программирования;
- "идет везде и на всем";
- пригоден в среде программирования UNIX.

Первоначальное название "С с классами" в 1983 году, по предложению Рика Масситти(Rick Mascitti), было изменено на С++. В этом же году С++ был впервые применен за пределами исследовательской группы. С 1980 года С++ претерпел два существенных изменения: в 1985 и 1990 годах. Первый рабочий проект языка С++ стандарта ANSI (American National Standarts Institute) был представлен в январе 1994 года.

ГЛАВА 2

Техническое задание.

2.1.Описание предметной области.

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

2.1.1 Матрицы

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

Чаще всего элементы матрицы обозначаются одной буквой с двумя индексами, указывающими "адрес" элемента - первый индекс дает номер строки, содержащий элемент, второй - номер столбца. Если матрица имеет m строк и n столбцов, то говорят, что матрица имеет размеры . Принято обозначать матрицы заглавными латинскими буквами, часто - полужирными, а ее элементы - такими же буквами, но строчными. Таким образом, матрица (размеров ) записывается в виде

.

Для краткости допускается обозначение матрицы размеров в виде , где индекс i пробегает все значения от 1 до m, а j - от 1 до n. При обозначении матриц используются скобки - круглые и квадратные.

Матрицы, имеющие одно и то же число n строк и столбцов, называют квадратными; это число n называют порядком квадратной матрицы.
Важную роль играют так называемые диагональные матрицы. Под этим подразумеваются квадратные матрицы, имеющие все элементы равные нулю, кроме элементов главной диагонали, т. е. элементов в позициях (1,1), (2,2), ..., (n, n). Диагональная матрица D с диагональными элементами d1, d2, ..., dn обозначается diag(d1, d2, ..., dn). Диагональная матрица diag(1, 1, ..., 1) называется единичной и обозначается E (или En) или же I (или In). Матрица, состоящая из одних нулей, называется нулевой.

Матрица, состоящая из одной строки, часто называется вектором (строкой, вектор-строкой, строчной матрицей), а из одного столбца - вектор-столбцом (столбцом, столбцовой матрицей).

Две матрицы считаются равными, если они одного размера и у них совпадают элементы, стоящие на одинаковых местах.

Матрицу A={ai j} можно транспонировать, т. е. заменить строки столбцами, в результате чего получится транспонированная матрица AT={aj i}.

Две матрицы A={ai j} и B={bi j} одного и того же размера можно складывать, их суммой будет матрица того же размера C={ci j}, , т. е. чтобы получить сумму двух матрицы достаточно сложить соответствующие элементы этих матриц, находящихся на одних и тех же позициях. Поскольку мы рассматриваем здесь матрицы с элементами из поля P действительных чисел, то очевидна ассоциативность операции сложения матриц, вытекающая из ассоциативности сложения элементов поля P. Аналогично имеет место коммутативность сложения. Таким образом, справедливы действия:

(A+B)+C=A+(B+C); [Ассоциативность] A+B=B+A; [Коммутативность] Матрица 0, состоящая из нулей, играет роль нуля: A+0=A при любой A.

Определим произведение элемента c из поля P на матрицу A={ai j}: cA={cai j}, т. е. чтобы умножить матрицу на число необходимо каждый элемент матрицы умножить на это число.

Для любой матрицы A существует противоположная матрица - A такая, что A+(-A)=0. 
В качестве матрицы - A, очевидно, следует взять матрицу (-1)A, элементы которой отличаются от элементов A знаком. . . . .

Все перечисленные свойства матриц непосредственно следуют из определений и свойств действий в поле чисел.

Рассмотрим матрицу A={ai j} размером и матрицу B={bi j} размером . Число столбцов первой матрицы (стоящей слева в произведении) равно числу строк второй матрицы (стоящей справа в произведении). Для матриц, обладающих таким свойством и только для таких матриц, можно ввести действие умножения матрицы на матрицу, в результате чего получается матрица C={ci j} размером , где . Правило умножения легко запомнить в словесной форме: 
"чтобы получить элемент произведения ci j двух матриц нужно элементы i-ой строки первой матрицы умножить на соответствующие элементы j-го столбца второй матрицы и все произведения сложить". Это правило называют "правилом строка на столбец".

Пример:

Пусть A={ai j} размером и B={bi j} размером , а также введем векторы , и . Рассмотрим линейные подстановки с этими матрицами:


(!: во вторую строчку вкралась ошибка, найдите ее)

и

.

Эти подстановки, используя определение умножения матриц, можно записать в матричном виде: Y=AX, X=BT.

Покажем, что если эти две подстановки сделать одну за другой, т. е. выразить переменные y1, ..., ym через t1, ..., tk, то матрица коэффициентов окажется равной AB.

Действительно, пусть

.

Тогда коэффициент ci j есть коэффициент при tj в yi. Выпишем все необходимое для вычисления этого коэффициента:

.

При подстановке x1, x2, ..., xk в yi, получим

.

Таким образом, , так что матрица коэффициентов в выражениях y1, ..., ym через t1, ..., tk действительно равна AB. 
Итак, последовательному произведению ("суперпозиции") двух линейных подстановок соответствует произведение их матриц. В матричной форме суперпозицию этих подстановок можно записать в виде Y=A(BT). Вместе с тем матрица суперпозиции равна AB, и этот факт записывается так: Y=(AB)T. Таким образом, верно следующее соотношение ассоциативности:

A(BT)=(AB)T, где T - столбец.

Рассмотрим теперь свойства действия умножения матриц:

(cA)B=A(cB)=cAB; (A1+A2)B=A1B+A2B; A(B1+B2)=AB1+AB2.

Эти свойства непосредственно вытекают из того, что элементы произведения выражаются как через элементы A, так и через элементы B в виде линейных однородных многочленов. Это можно проверить, используя правило умножения и сложения матриц, группируя необходимые слагаемые).

(AB)C=A(BC) [ассоциативность умножения].

Это свойство трактуется таким образом, что если одна из частей равенства имеет смысл, то имеет смысл и другая, и они равны. Это равенство можно доказать, воспользовавшись следующим простым замечанием. Пусть P и Q - две матрицы такие, что PQ имеет смысл. Пусть Q1, Q2, ..., Qk - столбцы матрицы Q. Тогда столбцами матрицы PQ являются PQ1, PQ2, ..., PQk, что непосредственно следует из определения. Это обстоятельство можно записать в виде P(Q1, Q2, ..., Qk) = (PQ1, PQ2, ..., PQk).

Обозначим через C1, C2, ..., Cl столбцы матрицы C. Тогда (AB)C = ((AB)C1, (AB)C2, ..., (AB)Cl). Далее, BC = (BC1, BC2, ..., BCl) и A(BC) = (A(BC1), A(BC2), ..., A(BCl)). Но как было установлено выше, (AB)C1 = A(BC1), (AB)C2 = A(BC2), ..., ибо C1, C2, ... - столбцы. Таким образом, (AB)C = A(BC).

Особую роль при умножении матриц играют единичные матрицы En (если нужно буквой n указать порядок) или просто E. Из правила умножения матриц непосредственно следует, что AE=A и EA=A, если эти произведения определены.

(AB)T=BTAT.
Об этом свойстве произведения матриц говорят так: "при транспонировании произведения матриц порядок сомножителей меняется".

Докажем это. 

Пусть ,

Положим , , так что ,

Пусть, далее, ,

Тогда ,

Итак, при всех i = 1, 2, ..., m и j = 1, 2, ..., n, а это и означает, что G=FT, т. е. , что и требовалось доказать.

Подведем итоги

Матрицы можно складывать, умножать их на число, а также умножать матрицы друг на друга. Эти действия обладают свойствами:

(A+B)+C=A+(B+C); A+B=B+A; Существует 0: A + 0 = 0 + A = A; Для A существует - A: A + (-A)=0; . . . .

Если для некоторых объектов (в нашем случае, это матрицы) выполняются эти восемь свойств, то говорят, что эти объекты  образуют векторное пространство, так что матрицы фиксированных размеров образуют векторное пространство.

(AB)C=A(BC). (cA)B=A(cB)=cAB. (A1+A2)B=A1B+A2B. A(B1+B2)=AB1+AB2. Существуют единичные матрицы (единицы), а именно, если A размером , то EmA = AEn = A. (AT)T = A. (A + B)T = AT + BT. (cA)T = cAT. (AB)T = BTAT.

Для квадратных матриц фиксированного порядка n действия сложения и умножения определены всегда, и их результатами являются квадратные матрицы того же порядка. Об этом обстоятельстве говорят таким образом: квадратные матрицы фиксированного порядка образуют кольцо. Кольцо, наделенное структурой векторного пространства, т. е. система объектов, обладающих свойствами 1-12, называется алгеброй над основным полем. Таким образом, квадратные матрицы с элементами из поля K составляют алгебру над этим полем.

2.1.2 Определители.

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

Утверждение 1. Число всех перестановок n элементов равно.

Доказательство. Действительно, общий вид перестановки из n символов есть i1, i2, ..., in, где каждое is есть одно из чисел 1, 2, ..., n, причем ни одно из этих чисел не встречается дважды. В качестве i1 можно взять любое из чисел 1, 2, ..., n; это дает n различных возможностей. Если, однако, i1 уже выбрано, то в качестве i2 можно взять лишь одно из оставшихся n-1 чисел, т. е. число различных способов выбрать символы i1 и i2 равно произведению n(n-1) и т. д.

Таким образом, число перестановок из n символов при n=2 равно 2!=2 (перестановки 12 и 21; в примерах, где n  9, мы не будем разделять переставляемые символы запятыми); при n=3 это число равно 3!=6. С ростом n число перестановок чрезвычайно быстро возрастает; так, при n=10 оно равно 3628800.

Теперь разобьем все n! перестановок n элементов на два класса по признаку, кажущемуся довольно искусственным, но именно это разбиение будет нужно для разумного правила расстановки знаков в определителе.

Пусть ( 1,  2, ...,  n) - некоторая перестановка чисел 1, 2, ..., n. Говорят, что пара элементов ( i,  j), i < j, образует инверсию, если  i >  j. Число всех пар элементов перестановки, образующих инверсию, называется числом инверсий в перестановке и обозначается inv( 1,  2, ...,  n). Так, inv()=7 (инверсии образуют пары 31, 32, 51, 54, 52, 42, 87).

Перестановки, содержащие четное число инверсий, называются четными, содержащие нечетное число инверсий - нечетными.

Если в некоторой перестановке мы поменяем местами какие-либо два символа (не обязательно стоящие рядом), а все остальные символы оставим на месте, то получим, очевидно, новую перестановку. Это преобразование перестановки называется транспозицией.

Утверждение 2. От любой перестановки из n символов можно перейти к любой другой перестановки посредством нескольких транспозиций.

Доказательство. Применим индукцию. Это утверждение справедливо при n = 2; если требуется начинать с перестановки 12, то вторая (а их всего две) 21 получается из первой в результате одной транспозиции. Предположим, что наше утверждение уже доказано для n-1, и докажем его для n. 
Пусть ( 1,  2, ...,  n) и ( 1,  2, ...,  n) - две данные перестановки. 
Если  1=  1, то ( 2, ...,  n) и ( 2, ...,  n) отличаются только порядком и, в силу предположения об индукции, посредством нескольких транспозиций можно перейти от ( 2, ...,  n) к ( 2, ...,  n) и, следовательно, от ( 1,  2, ...,  n) к ( 1,  2, ...,  n). Пусть теперь  1  1. Тогда  1=  i при некотором i  1. Сделав в ( 1,  2, ...,  n) транспозицию ( 1,  i), мы придем к новой перестановке, у которой на первом месте находится  i = 1. В силу доказанного выше свойства, эта перестановка превращается в ( 1,  2, ...,  n) посредством нескольких транспозиций. Следовательно, от ( 1,  2, ...,  n) к ( 1,  2, ...,  n) можно перейти посредством нескольких транспозиций, что и требовалось доказать.

Заметим, что переход от одной перестановки к другой посредством транспозиций неоднозначен.

Утверждение 3. Всякая транспозиция меняет четность перестановки.

Доказательство. Рассмотрим сначала случай, когда транспонируемые символы i и j стоят рядом, т. е. перестановка имеет вид..., i, j, ..., где многоточия заменяют те символы, которые не затрагиваются транспозицией. Транспозиция превращает нашу перестановку в перестановку..., j, i, ..., причем, понятно, в обеих перестановках каждый из символов i, j составляет одни и те же инверсии с символами, остающимися на месте. Если символы i и j раньше не составляли инверсии, то в новой перестановке появляется одна новая инверсия, т. е. число инверсий увеличивается на единицу; если же они раньше составляли инверсию, то теперь она пропадает, т. е. число инверсий на единицу уменьшается. В обоих случаях четность перестановки меняется.

Пусть теперь между транспонируемыми символами i и j расположены s символов, s > 0, т. е. перестановка имеет вид..., i, k1, k2, ..., ks, j,

Транспозицию символов i и j можно получить в результате последовательного выполнения 2s+1 транспозиций соседних элементов. А именно это будут транспозиции, переставляющие символы i и k1, затем i (уже стоящие на месте символа k1) и k2 и т. д., пока i не займет место символа ks. За этими s транспозициями следует транспозиция, перемещающая символы i и j, а затем s транспозиций символа j со всеми k, после чего j занимает место символа i, а символы k возвращаются на свои старые места. Таким образом, мы нечетное число раз меняли четность перестановки, а поэтому перестановки (1) и..., j, k1, k2, ..., ks, i, ... имеют противоположные четности.

Утверждение 4. Число четных перестановок n элементов равно числу нечетных перестановок.

Доказательство. Пусть число четных перестановок равно a, число нечетных равно b. Рассмотрим множество всех четных перестановок. Сделаем в них одну и ту же транспозицию, например, (1,2). Мы получим нечетные перестановки, попарно различные, в количестве a штук. Так как число всех нечетных перестановок равно b, то заключаем, что a  b. Теперь рассмотрим множество всех нечетных перестановок и сделаем в них транспозицию (1,2). Мы получим b четных перестановок и, следовательно, b  a. Из установленных неравенств следует, что a = b, что и требовалось доказать.

Попутно мы получили, что если во всех четных перестановках сделать одну и ту же транспозицию, что мы получим все нечетные перестановки.

Определим теперь еще одно понятие, а именно понятие подстановки. 
Подстановкой
n-й степени на множестве {1, 2, ..., n} называется взаимно однозначное отображение множества на себя. Удобно задавать подстановку прямым указанием замен для каждого элемента, посредством записи образа под прообразом. Так, запись задает подстановку, которая заменяет элементы 1, 2, 3, 4, 5, соответственно, на 5, 1, 3, 2, 4; порядок расположения ее столбцов безразличен. В такой записи в "числителе" и в "знаменателе" оказываются перестановки. Удобно в "числителе" записывать элементы в натуральном расположении. От одной записи подстановки к другой можно перейти при помощи нескольких транспозиций столбиков. В частности, всякая подстановка на множестве {1, 2, ..., n} может быть записана в виде

(2)

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

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

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

Утвержденние 5. Либо при всех записях подстановки четности верхней и нижней строк совпадают, либо же при всех записях они противоположны.

В первом случае подстановка будет называться четной, во втором - нечетной.

Если подстановка записана в виде (2), т. е. в верхней строке стоит четная перестановка 1, 2, ..., n, то четность подстановки будет определяться четностью перестановки  1,  2, ...,  n, стоящей в нижней строке. Отсюда следует

Утверждение 6. Число четных подстановок n-й степени равно числу нечетных, т. е. равно .

2.2.Технология обработки информации

Любая матрица представляется в виде двухмерного массива целых десятичных чисел типа int. Кроме того, каждой таблице соответствует еще 2 положительных целых числа типа unsigned char хранящие размеры матрицы.

2.2.1. Функциональные требования

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

o  Представление матрицы в формате, описанном выше. Для этого должен использоваться отдельный класс – класс матриц.

o  Операции изменения размеров матриц.

o  Операции преобразования матриц (транспонирование).

o  Операции инициализации матриц (инициализация единичной, нулевой, случайной, одночисельнной матрицы).

o  Операции сложения, и умножения матриц.

o  Операции умножения матрицы на скаляр и возведение в скалярную степень.

o  Удобная память калькулятора (буфер).

2.2.2. Требования к интерфейсу

Интерфейс должен обеспечивать пользователю возможность:

1)  удобного ввода данных с клавиатуры;

2)  изменять размер вычисляемых матриц и контролировать текущие размеры рабочих матриц и результирующей;

3)  Производить все операции, перечисленные в «Функциональных требованиях» интуитивно понятным и удобным способом;

4)  Визуально контролировать содержимое буферной памяти калькулятора;

5)  Не допускать обработки исходных данных, противоречащих логике работы программы путем вывода сообщений об ошибке;

Внешний вид программы:


ГЛАВА 3

РАБОЧИЙ ПРОЕКТ

3.1.Общие сведения (среда функционирования (ОС), способ загрузки, способ инсталляции, требования к ПО, требования к ТО)

Среда функционирования:

Borland C++ Builder – это среда быстрой разработки, в которой в качестве языка программирования используется язык C++ Builder (C++ Builder Language). Можно сказать, что язык C++ Builder – это расширенный С++. Например, в С++ Builder есть строковый

(AnsiString) и логический (Bool) типы, которых нет в классическом С++. К тому же несомненным преимуществом языка C++ Builder является встроенная RAD (rapid application development) которая обеспечивает быструю разработку приложений.

Запуск программы:

Стандартный, т. е. двойной клик на иконке программы.

Способ инсталляции:

Копирование исполняемого файла программы на нужный носитель.

Требования к ПО и к ТО:

Ø  операционная система Windows 9x/ME/2000/XP/2003

Ø  16 Мб оперативной памяти

Ø  1 Мб свободного пространства на жестком диске

Ø  Pentium 133 MHz

3.2. Укрупненный алгоритм

3.2.1.КЛАССЫ

В данной программе реализованы 4 класса:

class TMatrix {...}

класс матриц;

class TForm1 : public TForm {...}

главная форма

class TAboutBox1 : public TForm {...}

форма окна About;

class TErrorBox1 : public TForm {...}

форма окна ошибок;

Класс TMatrix:

Переменные:

Квадратный массив целых чисел **_mat;

Беззнаковые целые _NNUM1 и _NNUM2 определяющие размеры массива _mat;

Методы:

Изменение размера:

1) void DeleteOldMatrix()

Удаляет старую матрицу;

2) void InitNewMatrix1()

Выделяет память под новую матрицу размером 3x3;

3) void InitNewMatrix1(int M, int N)

Выделяет память под новую матрицу размером MxN;

Инициализация:

1) void InitRandom()

Заполняет матрицу случайными числами;

2) void InitZero()

Заполняет матрицу нулями;

3) void InitE()

Если матрица квадратная, то инициализирует единичную матрицу;

Действия с одним элементом:

1) void InitElem(int i, int j, int NewInt)

Присваивает элементу с индексом [i][j] значение NewInt;

2) int GetElem(int, int)

Возвращает значение элемента с индексом [i][j];

Операции с двумя матрицами:

1) void MSumm(TMatrix &A, TMatrix &B)

Возвращает значение суммы матриц A и B;

2) void MDiff(TMatrix &A, TMatrix &B)

Возвращает значение разности матриц A и B;

3) void MMult(TMatrix &A, TMatrix &B)

Возвращает значение произведения матриц A и B;

Операции с одной матрицей:

1) void MScalMult(int ScalInt)

Возвращает значение умножения матрицы на скаляр ScalInt;

2) void MNegative()

Возвращает значение умножения матрицы на -1;

3) void MTrans()

Возвращает значение транспонированной матрицы;

Класс TForm1:

Переменные:

Элементы интерфейса программы в форме указателей на объект;

Четыре переменные матрицы типа TMatrix:

- _Mat1, _Mat2 – Матрицы привязанные к таблицам строк StringGrid 1 и 2 соответственно;

- _Res - Матрица привязанная к таблице StringGrid3 (хранит результат выполнения операций);

- _Mem – Матрица являющаяся памятью калькулятора;

Четыре переменные целого типа, хранящие размеры таблиц строк StringGrid1 и 2: _SG1_R, _SG1_C, _SG2_R, _SG2_C;

Указатель типа TStringGrid *_SGFocus, определяющий какая таблица строк StringGrid активна в данный момент;

Указатель типа TMatrix *_MatFocus, определяющий какая матрица соответствует активной таблице строк StringGrid;

Переменная целого типа _Edit1Num хранящая значение поля Edit1(поля для значения какого-то целого скаляра);

Переменная целого типа _SGFocusInt определяющая номер активной таблицы StringGrid;

Переменная целого типа _Memory определяющая, используется ли память калькулятора;

Методы:

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

__fastcall TForm1(TComponent* Owner);

Функции чтения формы:

1) ReadMemory()

Заносит значения из активной StringGrid в матрицу памяти;

2) ReadForm()

Заполняет матрицы _Mat1 и _Mat2 значениями из соответствующих StringGrid;

3) ReadMatrix();

Заполняет соответствующую матрицу значениями из активной StringGrid;

Функции вывода значений в интерфейс:

1) Print(int Index)

Заполняет соответствующую параметру Index StringGrid из соответствующей матрицы;

2) WriteMemory()

Выводит значение памяти калькулятора в активную StringGrid;

3) WriteForm()

Заполняет StringGrid3 значениями из матрицы _Res (выводит результат);

4) WriteMatrix()

Заполняет активную StringGrid значениями из активной матрицы;

1) SGRight(int SGNUM)

Проверяет допустимость значений каждой строки соответствующей параметру SGNUM StringGrid;

2) ExceptCatch(int ErrCode)

Хранит инструкции по обработке каждого исключения;

Класс TAboutBox1:

Переменные:

Элементы интерфейса формы в форме указателей на объекты;

Методы:

Конструктор: _fastcall TForm1(TComponent* Owner);

Класс TErrorBox1:

Переменные:

Переменные типа *TLabel, используемые для вывода в форму сообщений об ошибке;

Остальные элементы интерфейса формы в форме указателей на объекты;

Методы:

Конструктор: _fastcall TForm1(TComponent* Owner);

3.2.2.МОДУЛИ

Исходный текст программы размещается в четырех модулях (восьми файлах) и двух дополнительных файлах:

1)  Unit1.h используется для хранения класса TForm1;

2)  Unit2.h используется для хранения класса TMatrix;

3)  Unit3.h используется для хранения класса TAboutBox;

4)  Unit4.h используется для хранения класса TErrorBox;

5)  Unit1.cpp используется для хранения методов класса TForm1 с формой доступа published;

6)  File1.cpp используется для хранения методов класса TForm1 с формой доступа public(описанные программистом);

7)  Unit2.cpp используется для хранения методов класса TMatrix;

8)  Unit3.cpp используется для хранения методов класса TAboutBox;

9)  Unit4.cpp используется для хранения методов класса TErrorBox;

10)  File2.h используется для хранения глобальных констант;

3.2.3.СХЕМА АЛГОРИТМА

Любая функция нажатия функциональной кнопки главного окна использует одну из функций чтения формы и/или одну из функций вывода в форму описанных в файле File1.cpp

Сначала происходит чтение одной или двух таблиц строк StringGrid с занесением значений из них в соответствующие матрицы.

Затем с помощью методов класса TMatrix данные обрабатываются и выводятся по необходимости в результирующую или одну из рабочих StringGrid.

Рассмотрим на примере функции нажатия кнопки сложения.

1)  Чтение обеих StringGrid с помощью метода ReadForm() с занесением результата в _Mat1 и _Mat2.

2)  Присвоение матрице _Res значения суммы матриц _Mat1 и _Mat2 с помощью метода класса TMatrix MSumm(TMatrix, TMatrix).

3)  Вывод матрицы _Res в форму с помощью функции WriteForm().

3.2.4.ОБРАБОТКА ИСКЛЮЧЕНИЙ

В программе генерируются исключения с кодом целого типа.

Все они делятся на 6 групп:

Код 1: Несоответствующий выбранной операции размер матрицы (матрица должна быть квадратной).

Код 2: Несоответствующие выбранной операции размеры матриц (матрицы должны иметь одинаковый размер).

Код 3: Недопустимые данные (элементами матриц могут быть только числа).

Код 4: Недопустимые данные (независимое поле Edit должно содержать только числа).

Код 5: Несоответствующие выбранной операции размеры матриц (высота первой матрицы должна соответствовать ширине второй).

Код 10: Внутренняя ошибка класса TMatrix (неправильные индексы). От пользователя не зависит.

При поимке любого исключения вызывается функция ExceptCatch(int ErrorCode), которая выводит соответствующее сообщение об ошибке в форму TErrorBox1 и показывает саму форму.

3.2.Руководство пользователя

Интерфейс любой программы должен отличаться легкой восприимчивостью пользователем.

Если пользователь сможет разобраться в программе без руководства, то работа программиста будет считаться выполненной великолепно. В этой работе тоже были приложены усилия для создания простого, понятного и удобного интерфейса.(рис. 1)

рис. 1

В левой части окна(одна над другой) находятся три основные панели.

Каждая из двух верхних представляют собой панель, включающую рабочую таблицу строк (рис. 2а) и два объекта (рис. 2б, в) изменения размера таблицы.

Каждый объект представляет собой числовое поле и две кнопки «+» и «-». Верхний объект изменения размера таблицы (рис2.б) служит для изменения высоты таблицы, нижний (рис. 2в) – ширины.

б

 

в

 

а

 

рис. 2

Каждая такая панель представляет собой матрицу.

Для ввода данных необходимо:

1.  Выбрать нужный размер

2.  Выделяя курсором необходимую ячейку ввести значение данной ячейки.

б

 

в

 

а

 

рис. 3

В левом нижнем углу окна находится результирующая панель.

Она представляет собой панель, включающую результирующую таблицу (рис. 2а) и две кнопки (рис. 3в) для переноса данных из результирующей таблицы в одну из рабочих.

Верхняя кнопка «ТО 1» служит для переноса данных в первую матрицу, нижняя – во вторую.

В правом верхнем углу отображается информация о размерах матрицы (рис. 3б): высоте и ширине.

Панель основных операций.

Над матрицами можно выполнять операции сложение, вычитание, умножение с помощью нажатия соответствующей кнопки на панели основных операций (рис. 4).

«*» - умножение матриц(рис. 4а);

«+» - сложение матриц(рис. 4б);

«-» - вычитание матриц(рис. 4в);

«Модуль» - подсчет определителя матрицы(рис. 4г);

г

 

в

 

б

 

а

 

рис. 4

Операции преобразования матрицы.

Во время работы матрицу можно преобразовать с помощью нажатия соответствующей кнопки на панели дополнительных операций (рис. 5).

«Е» - инициализация единичной матрицы(рис. 5а);

«0» - инициализация нулевой матрицы(рис. 5д);

«Rand» - инициализация случайной матрицы(рис. 5е);

«Integer» - инициализация матрицы целым из поля «Число» (рис. 5б)

«- Х» - умножение матрицы на –1(рис. 5з);

«Х * С» - умножение матрицы на скаляр(рис. 5в);

«Х ^ C» - возведение матрицы в скалярную степень(последовательное умножение на себя)(рис. 5ж);

«Т» - транспонирование матрицы(рис. 5г);

з

 

ж

 

е

 

д

 

г

 

в

 

б

 

а

 

рис. 5

Все эти операции производятся над активной матрицей.

Чтобы сделать матрицу активной необходимо сначала выделить соответствующую ей таблицу, а затем нажать соответствующую операции кнопку.

Для операций умножения на скаляр и возведения в скалярную степень используется целое число.

Это число вводится в числовое поле (рис. 6) находящееся в верхней правой части окна.

рис. 6

Для очистки всей формы (обнуления всех матриц формы) используется кнопка «С»(рис. 7), находящаяся в правом нижнем углу окна.

рис. 7

Использование памяти.

В данном калькуляторе можно использовать память для хранения одной матрицы.

Все операции с памятью производятся с помощью кнопок на панели памяти (рис. 8)

Чтобы занести в память матрицу нужно выделить матрицу кликом мыши и нажать кнопку «М». На панели появится индикатор «М».

Чтобы вынести результат из памяти нужно выделить матрицу кликом мыши и нажать кнопку «МR».

Чтобы очистить память необходимо нажать «МС». Индикатор «М» исчезнет.

рис. 8

Для получения информации о программе нажмите кнопку «О программе», находящуюся в правом верхнем углу окна.

рис. 9

ПРИЛОЖЕНИЯ

ИСХОДНЫЙ ТЕКСТ ПРОГРАММЫ

Project1.cpp

//

#include <vcl. h>

#pragma hdrstop

//

USEFORM("Unit1.cpp", Form1);

USEFORM("Unit3.cpp", AboutBox);

USEFORM("Unit4.cpp", AboutBox1);

//

WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)

{

try

{

Application->Initialize();

Application->CreateForm(__classid(TForm1), &Form1);

Application->CreateForm(__classid(TAboutBox), &AboutBox);

Application->CreateForm(__classid(TAboutBox1), &AboutBox1);

Application->Run();

}

catch (Exception &exception)

{

Application->ShowException(&exception);

}

catch (...)

{

try

{

throw Exception("");

}

catch (Exception &exception)

{

Application->ShowException(&exception);

}

}

return 0;

}

//

Unit1.h

//

#ifndef Unit1H

#define Unit1H

#ifndef File1H

#define File1H

//

#include <Classes. hpp>

#include <Controls. hpp>

#include <StdCtrls. hpp>

#include <Forms. hpp>

#include "CSPIN. h"

#include <ExtCtrls. hpp>

#include <Grids. hpp>

#include "Unit2.h"

class TMatrix;

//

class NSquare {};

class InsideError {};

class NRightSize {};

//

class TForm1 : public TForm

{

__published: // IDE-managed Components

TPanel *Panel1;

TStringGrid *StringGrid1;

TPanel *Panel2;

TStringGrid *StringGrid2;

TPanel *Panel3;

TStringGrid *StringGrid3;

TPanel *Panel11;

TButton *Button0;

TGroupBox *GroupBox12;

TEdit *Edit1;

TPanel *Panel13;

TButton *ButtonC;

TGroupBox *GroupBox14;

TButton *Button2;

TButton *Button3;

TLabel *Label3;

TPanel *Panel15;

TButton *Button7;

TButton *Button6;

TButton *Button5;

TPanel *Panel16;

TButton *Button17;

TButton *Button15;

TButton *Button16;

TButton *Button11;

TButton *Button12;

TEdit *Edit1_1;

TButton *Button1_1P;

TButton *Button1_1M;

TButton *Button1_2P;

TButton *Button1_2M;

TEdit *Edit1_2;

TButton *Button2_1P;

TButton *Button2_1M;

TEdit *Edit2_1;

TButton *Button2_2P;

TButton *Button2_2M;

TEdit *Edit2_2;

TButton *Button3_2;

TButton *Button3_1;

TLabel *Label3_1;

TLabel *Label3_2;

TButton *Button10;

TButton *Button18;

TLabel *Label1;

TLabel *Label2;

TButton *Button8;

TButton *Button1;

TLabel *Label4;

TLabel *Label5;

TLabel *Label6;

TLabel *Label7;

TLabel *Label8;

TLabel *Label9;

void __fastcall Button6Click(TObject *Sender);

void __fastcall Button5Click(TObject *Sender);

void __fastcall Button7Click(TObject *Sender);

void __fastcall Button3_1Click(TObject *Sender);

void __fastcall Button3_2Click(TObject *Sender);

void __fastcall ButtonCClick(TObject *Sender);

void __fastcall Button15Click(TObject *Sender);

void __fastcall Button1_1PClick(TObject *Sender);

void __fastcall Button1_1MClick(TObject *Sender);

void __fastcall Button1_2PClick(TObject *Sender);

void __fastcall Button1_2MClick(TObject *Sender);

void __fastcall Button2_1PClick(TObject *Sender);

void __fastcall Button2_1MClick(TObject *Sender);

void __fastcall Button2_2PClick(TObject *Sender);

void __fastcall Button2_2MClick(TObject *Sender);

void __fastcall StringGrid1Click(TObject *Sender);

void __fastcall StringGrid2Click(TObject *Sender);

void __fastcall Button16Click(TObject *Sender);

void __fastcall Button12Click(TObject *Sender);

void __fastcall Button11Click(TObject *Sender);

void __fastcall StringGrid1Exit(TObject *Sender);

void __fastcall StringGrid2Exit(TObject *Sender);

void __fastcall Button10Click(TObject *Sender);

void __fastcall Button17Click(TObject *Sender);

void __fastcall Button3Click(TObject *Sender);

void __fastcall Button8Click(TObject *Sender);

void __fastcall Button2Click(TObject *Sender);

void __fastcall Button1Click(TObject *Sender);

void __fastcall Button0Click(TObject *Sender);

private:

// User declaration

TMatrix _Mat1,

_Mat2,

_Res,

_Mem;

int _Memory;

int _SG1_R,

_SG1_C,

_SG2_R,

_SG2_C;

int _Edit1Num;

int _SGFocusInt;

TStringGrid *_SGFocus;

TMatrix *_MatFocus;

public:

// User declarations

__fastcall TForm1(TComponent* Owner);

TForm1 :: ReadMemory();

TForm1 :: WriteMemory();

TForm1 :: ReadForm();

TForm1 :: ReadMatrix();

TForm1 :: WriteForm();

TForm1 :: WriteMatrix();

TForm1 :: StringRight(AnsiString *String);

TForm1 :: Print(int Index);

TForm1 :: SGRight(int SGNUM);

TForm1 :: ExceptCatch(int ErrCode);

};

//

extern PACKAGE TForm1 *Form1;

//

#endif

#endif

Unit1.cpp

//

#include <vcl. h>

#pragma hdrstop

#include "Unit1.h"

#include "Unit2.h"

#include "Unit3.h"

#include "Unit4.h"

#include "File2.h"

//

#pragma package(smart_init)

#pragma link "CSPIN"

#pragma resource "*.dfm"

TForm1 *Form1;

//

__fastcall TForm1::TForm1(TComponent* Owner)

: TForm(Owner)

{

_Mat1.InitZero();

_Mat2.InitZero();

_SG1_R = 3;

_SG1_C = 3;

_SG2_R = 3;

_SG2_C = 3;

_SGFocus = StringGrid1;

_MatFocus = &_Mat1;

_Memory = 0;

_SGFocusInt = 1;

for (int i = 1; i <= SGMAX; i++)

{

StringGrid1->Cells[i][0] = IntToStr(i);

StringGrid2->Cells[i][0] = IntToStr(i);

StringGrid3->Cells[i][0] = IntToStr(i);

}

for (int i = 1; i <= SGMAX; i++)

{

StringGrid1->Cells[0][i] = IntToStr(i);

StringGrid2->Cells[0][i] = IntToStr(i);

StringGrid3->Cells[0][i] = IntToStr(i);

}

for (int i = 1; i < SGMAX ; i++)

for (int j = 1; j < SGMAX; j++)

{

StringGrid1->Cells[j][i] = "0";

StringGrid2->Cells[j][i] = "0";

StringGrid3->Cells[j][i] = "0";

}

}

//

//

//

void __fastcall TForm1::Button6Click(TObject *Sender)

{

try

{

ReadForm();

_Res. MSumm(_Mat1, _Mat2);

WriteForm();

}

catch (int ExceptCode)

{

ExceptCatch(ExceptCode);

}

}

//

void __fastcall TForm1::Button5Click(TObject *Sender)

{

try

{

ReadForm();

_Res. MMult(_Mat1, _Mat2);

WriteForm();

}

catch (int ErrCode)

{

ExceptCatch(ErrCode);

}

}

//

void __fastcall TForm1::Button7Click(TObject *Sender)

{

try

{

ReadForm();

_Res. MDiff(_Mat1, _Mat2);

WriteForm();

}

catch (int ErrCode)

{

ExceptCatch(ErrCode);

}

}

//

void __fastcall TForm1::Button3_1Click(TObject *Sender)

{

StringGrid1->RowCount = StringGrid3->RowCount;

StringGrid1->ColCount = StringGrid3->ColCount;

Edit1_1->Text = IntToStr(_SG1_R = StringGrid1->RowCount - 1);

Edit1_2->Text = IntToStr(_SG1_C = StringGrid1->ColCount - 1);

_Mat1 = _Res;

Print(1);

}

............................................

И т. д.

File1.cpp

#include "Unit1.h"

#include "Unit2.h"

#include "Unit4.h"

//

TForm1::ReadForm()

{

SGRight(1);

SGRight(2);

_Mat1.InitNewMatrix1(_SG1_R, _SG1_C);

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

for (int j = 0; j < _SG1_C; j++)

_Mat1.InitElem(i, j, StrToInt(StringGrid1->Cells[j + 1][i + 1]));

_Mat2.InitNewMatrix1(_SG2_R, _SG2_C);

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

for (int j = 0; j < _SG2_C; j++)

_Mat2.InitElem(i, j, StrToInt(StringGrid2->Cells[j + 1][i + 1]));

}

//

TForm1::WriteForm()

{

StringGrid3->RowCount = _Res._NNUM1 + 1;

StringGrid3->ColCount = _Res._NNUM2 + 1;

Label3_1->Caption = IntToStr(_Res._NNUM1);

Label3_2->Caption = IntToStr(_Res._NNUM2);

for (int i = 0; i < _Res._NNUM1; i++)

for (int j = 0; j < _Res._NNUM2; j++)

StringGrid3->Cells[j+1][i+1] = IntToStr(_Res. GetElem(i, j));

}

//

TForm1 :: Print(int Index)

{

if (Index == 1)

{

for (int i = 0; i < _Mat1._NNUM1; i++)

for (int j = 0; j < _Mat1._NNUM2; j++)

StringGrid1->Cells[j+1][i+1] = IntToStr(_Mat1.GetElem(i, j));

}

if (Index == 2)

{

for (int i = 0; i < _Mat2._NNUM1; i++)

for (int j = 0; j < _Mat2._NNUM2; j++)

StringGrid2->Cells[j+1][i+1] = IntToStr(_Mat2.GetElem(i, j));

}

}

//

TForm1 :: ReadMatrix()

{

SGRight(_SGFocusInt);

int N1 = _SGFocus->RowCount - 1;

int N2 = _SGFocus->ColCount - 1;

_MatFocus->InitNewMatrix1(N1, N2);

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

for (int j = 0; j < N2; j++)

_MatFocus->InitElem(i, j, StrToInt(_SGFocus->Cells[j + 1][i + 1]));

}

//

TForm1 :: WriteMatrix()

{

for (int i = 0; i < _MatFocus->_NNUM1; i++)

for (int j = 0; j < _MatFocus->_NNUM2; j++)

_SGFocus->Cells[j + 1][i + 1] = IntToStr(_MatFocus->GetElem(i, j));

}

//

TForm1 :: ReadMemory()

{

SGRight(_SGFocusInt);

int N1 = _SGFocus->RowCount - 1;

int N2 = _SGFocus->ColCount - 1;

_Mem. InitNewMatrix1(N1, N2);

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

for (int j = 0; j < N2; j++)

_Mem. InitElem(i, j, StrToInt(_SGFocus->Cells[j + 1][i + 1]));

}

//

TForm1 :: WriteMemory()

{

_SGFocus->RowCount = _Mem._NNUM1 + 1;

_SGFocus->ColCount = _Mem._NNUM2 + 1;

for (int i = 0; i < _MatFocus->_NNUM1; i++)

for (int j = 0; j < _MatFocus->_NNUM2; j++)

_SGFocus->Cells[j + 1][i + 1] = IntToStr(_Mem. GetElem(i, j));

}

//

TForm1 :: ExceptCatch(int ErrCode)

{

switch (ErrCode)

{

case 1:

{

AboutBox1->Label1->Caption = "WRONG SIZE";

AboutBox1->Label2->Caption = "The matrix must be square";

}

break;

case 2:

{

AboutBox1->Label1->Caption = "WRONG SIZE";

AboutBox1->Label2->Caption = "Both matrixes must have same size";

}

break;

case 3:

{

AboutBox1->Label1->Caption = "WRONG DATA";

AboutBox1->Label2->Caption = "The matrix must have only integers";

}

break;

case 4:

{

AboutBox1->Label1->Caption = "WRONG DATA";

AboutBox1->Label2->Caption = "The edit area must have an integer";

}

break;

case 5:

{

AboutBox1->Label1->Caption = "WRONG SIZE";

AboutBox1->Label2->Caption = "Bad size of second matrix";

}

break;

case 10:

{

AboutBox1->Label1->Caption = "INSIDE ERROR";

AboutBox1->Label2->Caption = "Bad index";

}

break;

default:

{

AboutBox1->Label1->Caption = "NEW ERROR";

AboutBox1->Label2->Caption = "";

}

break;

}

AboutBox1->ShowModal();

}

//

TForm1 :: SGRight(int SGNUM)

{

TStringGrid *SG;

AnsiString buf;

if (SGNUM == 1) SG = StringGrid1;

if (SGNUM == 2) SG = StringGrid2;

for (int i = 1; i < SG->RowCount; i++)

for (int j = 1; j < SG->RowCount; j++)

{

if (SG->Cells[i][j] == "")

{

SG->Cells[i][j] = "0";

throw 3;

}

for (int k = 1; k < SG->Cells[i][j].Length(); k++)

{

if (((SG->Cells[i][j])[k] > 57) || ((SG->Cells[i][j])[k] < 48))

if ((SG->Cells[i][j])[k] != 45)

{

SG->Cells[i][j] = "0";

throw 3;

}

}

}

}

//

Unit2.h

//

#ifndef Unit2H

#define Unit2H

#include<conio. h>

#include<stdio. h>

#include<stdlib. h>

//*****

//******* CLASS TMATRIX *******

//*****

class TMatrix

{

private:

//------ ??????????

int **_mat;

public:

unsigned char _NNUM1, _NNUM2;

//------ Constructors

TMatrix();

TMatrix(int);

//------ Metods

// Init operations

void InitRandom();

void InitZero();

void InitE();

// One element operations

void InitElem(int, int, int);

int GetElem(int, int);

// Matrix operations

void MScalMult(int);

void MSumm(TMatrix &, TMatrix &);

void MDiff(TMatrix &, TMatrix &);

void MMult(TMatrix &, TMatrix &);

void MNegative();

void MTrans();

void MMod();

void MMin();

// Size operations

void DeleteOldMatrix();

void InitNewMatrix1();

void InitNewMatrix1(int, int);

};

//

#endif

Unit2.cpp

//

#pragma hdrstop

#include "Unit2.h"

#include "Unit1.h"

//*****

//***** Constructors **

//*****

TMatrix :: TMatrix(void)

{

_NNUM1 = 3;

_NNUM2 = 3;

_mat = new int *[_NNUM1];

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

_mat[i] = new int[_NNUM2];

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

for (int j = 0; j < _NNUM2; j++)

_mat[i][j] = 0;

}

//*****

TMatrix :: TMatrix(int InitNum)

{

_NNUM1 = 3;

_NNUM2 = 3;

_mat = new int *[_NNUM1];

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

_mat[i] = new int[_NNUM2];

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

for (int j = 0; j < _NNUM2; j++)

_mat[i][j] = InitNum;

}

//***

//***** CLASS FUNCTIONS

//***

//***** INITNEWMATRIX

void TMatrix :: InitNewMatrix1(int m, int n)

{

_NNUM1 = m;

_NNUM2 = n;

_mat = new int *[_NNUM1];

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

_mat[i] = new int[_NNUM2];

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

for (int j = 0; j < _NNUM2; j++)

_mat[i][j] = rand()%100-50;

}

//***** DELETEOLDMATRIX

void TMatrix :: DeleteOldMatrix()

{

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

delete _mat[i];

_NNUM1 = 0;

_NNUM2 = 0;

}

//***** INITRANDOM

void TMatrix :: InitRandom()

{

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

for (int j = 0; j < _NNUM2; j++)

_mat[i][j] = rand()%100-50;

}

//***** INITE

void TMatrix :: InitE()

{

if (_NNUM1 != _NNUM2)

throw 1;

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

for (int j = 0; j < _NNUM2; j++)

if (i == j)

_mat[i][j] = 1;

else

_mat[i][j] = 0;

}

//***** MSCALMULT

void TMatrix :: MScalMult(int Scal)

{

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

for (int j = 0; j < _NNUM2; j++)

_mat[i][j] *= Scal;

}

//***** MSUMM

void TMatrix :: MSumm(TMatrix & A, TMatrix & B)

{

if ((A._NNUM1 != B._NNUM1) || (A._NNUM2 != B._NNUM2))

throw 2;

InitNewMatrix1(A._NNUM1, A._NNUM2);

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

for (int j = 0; j < _NNUM2; j++)

_mat[i][j] = A._mat[i][j] + B._mat[i][j];

}

//***** MDIFF

void TMatrix :: MDiff(TMatrix & A, TMatrix & B)

{

if ((A._NNUM1 != B._NNUM1) || (A._NNUM2 != B._NNUM2))

throw 2;

InitNewMatrix1(A._NNUM1, A._NNUM2);

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

for (int j = 0; j < _NNUM2; j++)

_mat[i][j] = A._mat[i][j] - B._mat[i][j];

}

//***** MMULT

void TMatrix :: MMult(TMatrix & A, TMatrix & B)

{

if (A._NNUM2 != B._NNUM1)

throw 5;

InitNewMatrix1(A._NNUM1, B._NNUM2);

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

for (int j = 0; j < _NNUM2; j++)

{

_mat[i][j] = 0;

for (int k = 0; k < A._NNUM2; k++)

_mat[i][j] += A._mat[i][k] * B._mat[k][j];

}

}

//***** MTRANS

void TMatrix :: MTrans()

{

if (_NNUM1 != _NNUM2)

throw 1;

int buf;

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

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

{

buf = _mat[i][j];

_mat[i][j] = _mat[j][i];

_mat[j][i] = buf;

}

}

//***** MNEGATIVE

void TMatrix :: MNegative()

{

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

for (int j = 0; j < _NNUM2; j++)

_mat[i][j] = -_mat[i][j];

}

//

#pragma package(smart_init)

File2.h

//*****

// GLOBALS ****

//*****

const int SGMAX = 11;

const int SGMIN = 1;