Массивы могут быть многомерными. Мы рассмотрим случай двумерных массивов, которые используются, например, для представления матриц.
Предположим, что нужно храниить матрицу M размера nrows (число
строк) на ncols (число столбцов). Для определенности будем
считать, что элементами матрицы являются числа с плавающей
точкой типа double
. Существует два способа.
Одномерный массив. Элементы матрицы можно записывать в
одномерный массив размера nrows*ncols
. Обычно
элементы записывают по строчкам. Для получения (или изменения)
значения элемента матрицы с индексами i и j требуется вычислить
позицию этого элемента в одномерном массиве:
M[i * nrows + j]
Выделение и освобождение памяти производится обычным образом.
Второй способ хранения матрицы состоит в
использовании двумерного массива. Двумерный массив по
сути является массивом указателей на одномерные массивы и
объявляется как double **M;
.
Рассмотрим следующую программу.
int nrows, ncols;
int i, j;
double **M;
/* устанавливаем значения nrows и ncols */
/* выделяем память под массив указателей */
M = (double **)malloc(nrows * sizeof(double *));
/* выделяем память под каждую строчку матрицы */
for(int k = 0; k < nrows; ++k) {
M[k] = (double *)malloc(ncols * sizeof(double));
}
/* В качестве примера обнуляем значение с индексами i, j */
M[i][j] = 0;
/* Освобождаем память в обратном порядке */
for(int k = 0; k < nrows; ++k) {
free(M[k]);
}
free(M);
Выделение памяти производится nrows + 1 раз. Для каждой строки матрицы выделяется отдельный массив, адрес начала которого записывается в соответствующую ячейку массива M.
Получить значение элемента матрицы с индексами i и j можно с помощью двойных скобок. Первая скобка, ближняя к имени переменной, возвращает адрес массива, где записана строка матрицы. Вторая скобка дает смещение внутри этой строки.
Многомерные массивы получаются аналогично, как массивы массивов массивов.