Разработка программ в C++ Builder

Лабораторная работа № 7.

Разработка программы "Умножение матриц" в C++ Builder

Цель работы

Написать программу перемножения двух матриц размерностью 4х4.

Пример умножения двух матриц:

Умножить

на .

Решение.

В ходе вычислений были выполнены следующие действия

Умножаем 1 строку на 1 столбец 1 • (-1) + (-2) • 23 + 3 • 4.4 + 1 • (-4.4) = -38.2

Умножаем 1 строку на 2 столбец 1 • 2 + (-2) • (-23) + 3 • 12 + 1 • 12 = 96

Умножаем 1 строку на 3 столбец 1 • 3 + (-2) • 1 + 3 • 1 + 1 • (-1) = 3

Умножаем 2 строку на 1 столбец 23 • (-1) + (-23) • 23 + 1 • 4.4 + 2 • (-4.4) = -556.4

Умножаем 2 строку на 2 столбец 23 • 2 + (-23) • (-23) + 1 • 12 + 2 • 12 = 611

Умножаем 2 строку на 3 столбец 23 • 3 + (-23) • 1 + 1 • 1 + 2 • (-1) = 45

Умножаем 3 строку на 1 столбец (-44) • (-1) + 12 • 23 + 0 • 4.4 + 1 • (-4.4) = 315.6

Умножаем 3 строку на 2 столбец (-44) • 2 + 12 • (-23) + 0 • 12 + 1 • 12 = -352

Умножаем 3 строку на 3 столбец (-44) • 3 + 12 • 1 + 0 • 1 + 1 • (-1) = -121

Пример компоновки формы

Спецификация программы:

1) Для работы с матрицами (ввод и вывод матриц) должен быть использован компонент StringGrid.

2) Перемножаемые матрицы должны вводиться пользователем. То есть таблица StringGrid1 и StringGrid2 должны быть редактируемые.

3) Таблица с результатом StringGrid3должна быть закрыта для редактирования пользователем.

Справка по работе с компонентом StringGrid.

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

Компонент StringGrid находится на вкладке Additional панели компонентов.

Таблица StringGrid состоит из выделенных серым FixedCols и FixedRows - зафиксированных ячеек-заголовков, и обычных, белых ячеек. Содержимое Fixed ячеек недоступно для редактирования, и меняется только программно. Для установки количества фиксированных ячеек можно изменить значение свойств FixedCols и FixedRows в окне свойств Object Inspector. Или поменять количество фиксированных строк и столбцов программно, написав в коде программы команды

StringGrid1-> FixedCols=1; // устанавливает 1 фиксированный столбец

StringGrid1-> FixedRows=1; // устанавливает 1 фиксированную строку

Общее количество строк и столбцов в таблице можно установить вручную в окне Object Inspector, отредактировав свойства RowCount и ColCount, а можно изменить программно в ходе выполнения программного кода, написав следующие команды:

StringGrid1->RowCount=5 //устанавливаем общее кол-во строк равное 5

StringGrid1->ColCount=7 //устанавливаем общее кол-во столбцов равное 7

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

За многие свойства компонента StringGrid отвечает свойство Options. В Инспекторе Объектов Options - это раскрывающийся список, представляющий собой элементы данного множества. Если значение элемента равно True, то он присутствует в множестве, если False - то нет.

Как следует из таблицы, за возможность редактировать содержимое ячеек с клавиатуры отвечает элемент goEditing свойства-множества Options. В Инспекторе Объектов установите его значение в True. Чтобы управлять этой возможностью программно, нужно включить или исключить из множества данный элемент:

StringGrid1->Options<<goEditing; //Включаем редактирование, другие

//элементы не трогаем

StringGrid1->Options>>goEditing; //Выключаем редактирование, другие

//элементы не трогаем

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

Содержимое ячейки (i, j), где где i - номер столбца, j - номер строки, имеет вид:

StringGrid1->Cells[i][j]

и доступно как для чтения, так и для записи. Например:

StringGrid1->Cells[i][j]=”Hello”; - записывает слово в ячейку с координатами I и j.

A=StringGrid1->Cells[i][j]; - считывает содержимое ячейки с координатами I и j в переменную A.

Номера столбцов (i) и строк (j) отсчитываются от 0.

Выделенная ячейка таблицы имеет:

номер столбца: StringGrid1->Col

номер строки: StringGrid1->Row

поэтому содержимое выделенной ячейки будет адресоваться так:

S=StringGrid1->Cells[StringGrid1->Col][StringGrid1->Row];

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

StringGrid1->LeftCol Номер столбца, видимого самым левым

StringGrid1->TopRow Номер строки, видимой самой верхней

StringGrid1->VisibleColCount Количество столбцов, видимых в рамках таблицы

StringGrid1->VisibleRowCount Количество строк, видимых в рамках таблицы

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

DefaultRowHeight - высота строк по умолчанию

DefaultColWidth - ширина столбцов по умолчанию

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

RowHeights[i] - массив, содержащий высоты строк с номером i

ColWidths[i] - массив, содержащий ширины столбцов с номером i

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

Так как таблица StringGrid, в отличие от, например, компонента ListBox, не имеет метода для очистки содержимого сразу всех ячеек, то для удаления внесённых в таблицу ранее данных приходится очищать каждую ячейку отдельно. Делается это двумя вложенными циклами for, пробегающими по столбцам и строкам:

int i, j;

{

for (i=1;i<StringGrid1->RowCount;i++) //Заголовки строк не трогаем

for (j=1;j<StringGrid1->ColCount;j++) //Заголовки столбцов не трогаем

StringGrid1->Cells[j][i]='';

}

Хотя, есть метод для очищения содержимого целого столбца или строки:

StringGrid1->Cols[i]->Clear(); //Очищается столбец с номером i

StringGrid1->Rows[i]->Clear(); //Очищается строка с номером i

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

int i, j;

{

for (i=1;i<StringGrid1->RowCount;i++) //Заголовки столбцов не трогаем

//цикл от 1

{

StringGrid1->Rows[i]->Clear();

StringGrid1->Cells[0][i]="Заголовок строки i";

}

}