Опубликован: 07.03.2015 | Уровень: для всех | Доступ: свободно | ВУЗ: Компания ALT Linux
Лекция 6:

Статические и динамические матрицы

Аннотация: Данная глава посвящена обработке матриц в С++. На большом количестве примеров будут рассмотрены возможности языка для обработки статических и динамических матриц. В завершающем параграфе будет рассмотрено использование двойных указателей и функций на примере решения задач линейной алгебры.

6.1 Статические матрицы С(С++)

Матрица — это двумерный массив, каждый элемент которого имеет два индекса: номер строки — i, номер столбца —j.

Статический двумерный массив (матрицу) можно объявить так:

тип имя_переменной [n][m];

где тип определяет тип элементов массива, имя_переменной — имя матрицы, n — количество строк, m — количество столбцов в матрице. Строки нумеруются от 0 до n-1, столбцы — от 0 до m-1.

Например,

double x[20][35];

Описана матрица вещественных чисел x, состоящая из 20 строк и 35 столбцов (строки нумеруются от 0 до 19, столбцы от 0 до 34).

Как и любой другой переменной, матрице можно присвоить начальное значение, например int A[2][3]={{1,2,3}, {4,5,6}};

Для обращения к элементу матрицы необходимо указать её имя, и в квадратных скобках номер строки, а затем в квадратных скобках — номер столбца. Например, x[2][4] — элемент матрицы x, находящийся в третьей строке и пятом столбце1Напоминаем, что нумерация строк и столбцов идёт с 0..

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

6.2 Динамические матрицы

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

Блок-схема построчной обработки матрицы

Рис. 6.1. Блок-схема построчной обработки матрицы
Блок-схема обработки матрицы по столбцам

Рис. 6.2. Блок-схема обработки матрицы по столбцам

6.2.1 Использование указателей для работы с динамическими матрицами

При работе с динамическими матрицами можно использовать обычные указатели. После описания указателя необходимо будет выделить память для хранения N\times M элементов (N — число строк, M — число столбцов). Рассмотрим в качестве примера выделение памяти для хранения целочисленной матрицы размером N\times M.

int *A, N, M;
A=( int *) calloc (N*M, sizeof ( int ) );

Для выделения памяти можно использовать также и функцию malloc

A=( int *) malloc (N*M*sizeof ( int ) );

или операцию new

A=new int [N*M];

Память мы выделили, осталось найти способ обратиться к элементу матрицы. Все элементы матрицы хранятся в одномерном массиве размером N\times M элементов. Сначала в этом массиве расположена 0-я строка матрицы, затем 1-я и т.д. Поэтому для обращения к элементу A[i][j] необходимо по номеру строки i и номеру столбца j вычислить номер этого элемента k в динамическом массиве. Учитывая, что в массиве элементы нумеруются с нуля, k = iM + j. Обращение к элементу A[i][j] будет таким: *(A+i*M+j) или A[i*M+j].

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

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

int main ( )
{
int N,M;
float **a;
a=new float *[N ];
}

С помощью оператора new создан массив из n элементов2В данном случае массив указателей на float, в котором каждый элемент является адресом, где хранится указатель (фактически каждый указатель — адрес строки матрицы). Осталось определить значение элементов массива. Для этого организуем цикл (переменная цикла i изменяется от 0 до N-1), в котором будет выделяться память для хранения очередной строки матрицы. Адрес этой строки будет записываться в a[i].

for ( i =0; i<N; i++)
a [ i ]=new float [M];

После этого определён массив N указателей, каждый из которых адресует массив из M чисел (в данном случае вещественных типа float). Фактически создана динамическая матрица размера N\times M. Обращение к элементу динамической матрицы идёт так же, как и к элементу статической матрицы. Для того, чтобы обратиться к элементу a_{i,j} в программе на C++, необходимо указать его имя, и в квадратных скобках номер строки и столбца (a[i][j]).

Сергей Радыгин
Сергей Радыгин

Символы кириллицы выводит некорректно. Как сделать чтобы выводился читабельный текст на русском языке?

Тип приложения - не Qt,

Qt Creator 4.5.0 основан на Qt 5.10.0. Win7.

 

Юрий Герко
Юрий Герко

Кому удалось собрать пример из раздела 13.2 Компоновка (Layouts)? Если создавать проект по изложенному алгоритму, автоматически не создается  файл mainwindow.cpp. Если создавать этот файл вручную и добавлять в проект, сборка не получается - компилятор сообщает об отсутствии класса MainWindow. Как правильно выполнить пример?