Курсовая работа: Программирование действий над матрицами на языке С++
Возможно вы уже
сталкивались с такой проблемой, что массивы в с++ имеют ограниченный размер, а
мы точно не знаем количество элементов, необходимое в массиве. В таких случаях
необходимо использовать динамическое программирование. Т.е. выделять память под
элементы массива при необходимости добавить какой-либо элемент. В принципе, в
с++ это можно реализовать вручную, но зачем? если есть специальный класс -
vector. Он позволяет создавать нам массивы переменной длины в зависимости от
ситуации.
Для работы с вектором
необходимо подключить заголовочный файл:
#include
"vector"
Объявить рабочую
область:
После этого вектор
необходимо объявить, это можно сделать двумя способами.
vector<
int > vArray1; vector< int > vArray2(30);
В первом случае
указывается пустой вектор, а во втором начальный размер.
Можно получать
информацию о параметрах вектора:
·
size()
- сколько данных храниться
·
capacity()
- сколько может храниться до изменения размера
·
max_size()
- максимальный размер обычно равен наиболее большому доступному блоку памяти
1.6
Перегрузка операторов
Перегрузка операторов
— в программировании — один из способов реализации полиморфизма, заключающийся
в возможности одновременного существования в одной области видимости нескольких
различных вариантов применения оператора, имеющих одно и то же имя, но
различающихся типами параметров, к которым они применяются.
Реализация
Перегрузка
операций предполагает введение в язык двух взаимосвязанных особенностей:
возможности объявлять в одной области видимости несколько процедур или функций
с одинаковыми именами и возможности описывать собственные реализации операций
(то есть знаков операций, обычно записываемых в инфиксной нотации, между
операндами). Принципиально реализация их достаточно проста:
Перегрузка операций
предполагает введение в язык двух взаимосвязанных особенностей: возможности
объявлять в одной области видимости несколько процедур или функций с
одинаковыми именами и возможности описывать собственные реализации операций (то
есть знаков операций, обычно записываемых в инфиксной нотации, между
операндами).
Иногда возникает
потребность описывать и применять к созданным программистом типам данных
операции, по смыслу эквивалентные уже имеющимся в языке. Классический пример —
библиотека для работы с комплексными числами. Они, как и обычные числовые типы,
поддерживают арифметические операции, и естественным было бы создать для
данного типа операции «плюс», «минус», «умножить», «разделить», обозначив их
теми же самыми знаками операций, что и для других числовых типов. Запрет на
использование определённых в языке элементов вынуждает создавать множество
функций с именами вида ComplexPlusComplex, IntegerPlusComplex,
ComplexMinusFloat и так далее.
Когда одинаковые по
смыслу операции применяются к операндам различных типов, их вынужденно
приходится называть по-разному. Невозможность применять для разных типов
функции с одним именем приводит к необходимости выдумывать различные имена для
одного и того же, что создаёт путаницу, а может и приводить к ошибкам.
Например, в классическом языке Си существует два варианта стандартной
библиотечной функции нахождения модуля числа: abs() и fabs() — первый
предназначен для целого аргумента, второй — для вещественного. Такое положение,
в сочетании со слабым контролем типов Си, может привести к труднообнаруживаемой
ошибке: если программист напишет в вычислении abs(x), где x — вещественная
переменная, то некоторые компиляторы без предупреждений сгенерируют код,
который будет преобразовывать x к целому путём отбрасывания дробной части и
вычислять модуль от полученного целого числа!
Отчасти
проблема решается средствами объектного программирования — когда новые типы
данных объявляются как классы, операции над ними могут быть оформлены как
методы классов, в том числе и одноимённые (поскольку методы разных классов не
обязаны иметь различные имена), но, во-первых, оформление подобным образом
операций над значениями разных типов неудобно, а во-вторых, это не решает
проблему создания новых операторов.
Средства,
позволяющие расширять язык, дополнять его новыми операциями и синтаксическими
конструкциями (а перегрузка операций является одним из таких средств, наряду с
объектами, макрокомандами, функционалами, замыканиями) превращают его уже в метаязык
— средство описания языков, ориентированных на конкретные задачи. С его помощью
можно для каждой конкретной задачи построить языковое расширение, наиболее ей
соответствующее, которое позволит описывать её решение в наиболее естественной,
понятной и простой форме. Например, в приложении к перегрузке операций:
создание библиотеки сложных математических типов (векторы, матрицы) и описание
операций с ними в естественной, «математической» форме, создаёт «язык для
векторных операций», в котором сложность вычислений скрыта, и возможно описывать
решение задач в терминах векторных и матричных операций, концентрируясь на сути
задачи, а не на технике. Именно из этих соображений подобные средства были в
своё время включены в язык Алгол-68.
Чтобы разрешить
существование нескольких одноимённых операций, достаточно ввести в язык
правило, согласно которому операция (процедура, функция или оператор)
опознаются компилятором не только по имени (обозначению), но и по типам их
параметров. Таким образом, abs(i), где i объявлено как целое, и abs(x), где x
объявлено как вещественное — это две разные операции. Принципиально в
обеспечении именно такой трактовки нет никаких сложностей.
Чтобы дать возможность
определять и переопределять операции, необходимо ввести в язык соответствующие
синтаксические конструкции. Вариантов их может быть достаточно много, но по
сути они ничем друг от друга не отличаются, достаточно помнить, что запись вида
«<операнд1> <знакОперации> <операнд2>» принципиально
аналогична вызову функции
«<знакОперации>(<операнд1>,<операнд2>)». Достаточно разрешить
программисту описывать поведение операторов в виде функций — и проблема
описания решена.
2. Проектирование и этапы разработки
2.1
Постановка задачи
Задача
заключается в создании динамического класса для работы с матрицами.
Чтение
матриц происходит из файлов в котором они находятся, и после решений все
полученные результаты выводятся в другой файл.
Интерфейс.
Интерфейс представлен примитивным меню в котором
пользователь выбирает действие. При не открытии одного из файлов выводится
ошибка, при успешное выполнение выводится сообщение об успехе.
2.2
Средства разработки
В
качестве средства разработки выбран MS Visual Studio 2008 Express.
2.3
Описание процесса компиляции и запуска программы
Для
компиляции программы используется IDE MS Visual Studio. В папке с проектом должны присутствовать
файлы: file1.txt, file2.txt, file3.txt
Скомпиллированная
программа состоит из следующих файлов:
1) папка cnf
(конфигурационные файлы);
2)
matrix.exe (исполняемый файл);
3.
Реализация
3.1 Структура программы
Программа
содержит компоненты, отвечающие за:
1)
интерфейс,
2)
математическую логику,
3)
взаимодействие объектов класса,
4)
перегрузку операторов.
3.2 Структура класса

Заключение
В
ходе выполнения курсовой работы была получена работоспособная программа,
удовлетворяющая начальному заданию.
В
ходе разработке были проанализированы и использованы следующие технологии:
1)
Stl;
2)
потоков данных;
3)
перегрузка операторов;
В
качестве дальнейшего совершенствования программы представляется возможным
увеличение функциональности класса и интерфейса (с целью увеличения
информативности).
Литература
1.
Свободная энциклопедия http://ru.wikipedia.org/
2.
Книга У. Форд, У. Топп «Структура
данных в С++» ООО «Бином-Пресс»2006г.
3.
Беллман Р. Введение в теорию матриц. - М.: Мир, 1969.
4.
Курош А.Г.Курс высшей алгебры: Учебник для вузов 15-е изд.,
стереотип. - М.: Лань, 2006. - 432 с.
5.
Дж. Голуб, Ч. Ван Лоун Матричные
вычисления. - М.: Мир, 1999.
6.
Сайт «Знакомимся с вектором». http://www.cyberguru.ru/
7.
Б. Страуструп. «Язык
программирования C++. Специальное издание.», 2004 г.
Приложение. Исходный код программы. Заголовочные
файлы.
1.
matrix.h
#pragma once
#include <list>
#include <vector>
#include <iostream>
using std::vector;
using std::cout;
using std::istream;
using std::ostream;
class _matrix
{
private:
vector< vector<float> > vvf;
int stroka;
int stolbec;
public:
_matrix() {};
_matrix(int str, int stolb)
{
stroka = str;
stolbec = stolb;
vvf.resize(stroka, vector<float>(stolbec));
Страницы: 1, 2, 3 |