Матрица — это некоторая прямоугольная область (таблица), состоящая из строк и столбцов. Пересечения строк и столбцов образуют ячейки. Изобразим на рисунке прямоугольную матрицу a(n×m), состоящую из n строк и m столбцов:
Пусть
n=3
и
m=4.
Строки
и столбцы пронумеруем, начиная с 0. Заведём вспомогательные
переменные:
i — текущее значение строки;
j — текущее значение столбца.
Прежде чем начать работу с матрицей, необходимо дать её описание. Но не всё так просто. У матрицы два измерения, а в языках С/С++ имеются только одномерные массивы и нет двумерных, трёхмерных и т.д. массивов, т.е. нет многомерных массивов, а есть только одномерные. Как же тогда работать с матрицами? Решение элементарное. Считаем матрицу одномерным массивом, состоящим из n строк, где каждая строка — это тоже массив, но из m элементов, т.е. рассматриваем матрицу как массив массивов. Формально это можно записать таким образом:
Тип_элементов Имя_матрицы[число_строк][число_столбцов];
Для нашей матрицы a описание будет выглядеть так (пусть элементы матрицы — действительные числа):
const int n = 3; // число строк
const int m = 4; // число столбцов
double a[n][m]; // выделяем память под матрицу
И теперь можно приступать к работе с матрицей. Например, присвоить значение какому-нибудь элементу матрицы:
a[1][2] = 2.5;
Так мы присвоили значение элементу, расположенному в первой строке и во втором столбце (именно он отмечен на рисунке).
Индексы для матриц задаются так же, как и для одномерных массивов. И так же нежелательно выходить за пределы матрицы (по строкам или по столбцам — всё равно).
Разберём на простом примере некоторые приёмы работы с матрицами.
Пример. Дана прямоугольная матрица действительных чисел размером n×m. Пронормировать эту матрицу, т.е. поделить значение всех элементов матрицы на максимальный по модулю элемент.
Возможный текст программы:
#include <iostream>
using namespace std;
#include <cmath>
int main()
{
const int n = 3; // число строк
const int m = 4; // число столбцов
double a[n][m]; // выделяем память под матрицу
int i, j;
double max;
// Ввод матрицы с клавиатуры
cout << "Matriza A("<< n << "*" << m << "):" << endl;
for(i = 0; i < n; i++)
for(j = 0; j < m; j++)
cin >> a[i][j];
// Поиск в матрице максимального по модулю значения
max = fabs(a[0][0]);
for(i = 0; i < n; i++)
for(j = 0; j < m; j++)
if(fabs(a[i][j]) > max)
max = fabs(a[i][j]);
cout << "max=" << max << endl;
// Нормируем матрицу
for(i = 0; i < n; i++)
for(j = 0; j < m; j++)
a[i][j] /= max;
// Вывод матрицы в виде таблицы на экран монитора
for(i = 0; i < n; i++)
{
for(j = 0; j < m; j++)
cout << a[i][j] << "\t ";
cout << endl;
}
return 0;
}
Как видно из текста программы, для работы с матрицей почти всегда требуются двойные циклы. Обратите на то, как напечатать матрицу в виде таблицы.
Матрицы, как и одномерные массивы, можно инициализировать на этапе выделения памяти. Сделать это несложно. Зададим возможные начальные значения для матрицы из рассмотренного выше примера:
const int n = 3; // число строк
const int m = 4; // число столбцов
// выделяем память под матрицу с одновременной
// инициализацией элементов
double a[n][m] =
{
{3, -3.1, 4.6, 5.5},
{2, 1.2, -10, -2.5},
{7.6, 3.1, 1.6, 0.5}
};