Наиболее быстро изменяется последний индекс элементов массива, поскольку многомерные массивы в языке Си размещаются в памяти компьютера построчно друг за другом (см. следующую тему «Адресная функция»).
Рассмотрим особенности работы с многомерными массивами на конкретном примере двухмерного массива.
Например, пусть приведена следующая декларация двухмерного массива:
int m[3][4];
Идентификатор двухмерного массива – это указатель на массив указателей (переменная типа указатель на указатель: int **m;).
Поэтому двухмерный массив m[3][4]; компилятор рассматривает как массив трех указателей, каждый из которых указывает на начало массива со значениями размером по четыре элемента каждый. В ОП данный массив будет расположен следующим образом:
Указа-тели
m [0]
®
m[0][0]
m[0][1]
m[0][2]
m[0][3]
m [1]
m[1][0]
m[1][1]
m[1][2]
m[1][3]
m [2]
m[2][0]
m[2][1]
m[2][2]
m[2][3]
(А) (В)
Рис. 10.1. Схема размещения элементов массива m размером 3×4
Причем в данном случае указатель m[1] будет иметь адрес m[0]+4*sizeof(int), т.е. каждый первый элемент следующей строки располагается за последним элементом предыдущей строки.
Приведем пример программы конструирования массива массивов:
#include <stdio.h>
void main()
{
int x0[4] = { 1, 2, 3,4}; // Декларация и инициализация
int x1[4] = {11,12,13,14}; // одномерных массивов
int x2[4] = {21,22,23,24};
int *m[3] = {x0, x1, x2,}; // Создание массива указателей
int i,j;
for (i=0; i<3; i++) {
printf("\n Cтрока %d) ", i+1);
for (j=0; j<4; j++)
printf("%3d", m[ i ] [ j ]);
}
}
Результаты работы программы:
Cтрока 1) 1 2 3 4
Cтрока 2) 11 12 13 14
Cтрока 3) 21 22 23 24
Такие же результаты будут получены и в следующей программе:
В последней программе массив указателей на соответствующие массивы элементов создается компилятором автоматически, т.е. данные массива располагаются в памяти последовательно по строкам, что является основанием для декларации массива m в виде
Замена скобочного выражения m[3][4] на m[12] здесь не допускается, так как массив указателей не будет создан.
Таким образом, использование многомерных массивов в языке Си связано с расходами памяти на создание массивов указателей.
Очевидна и схема размещения такого массива в памяти – последовательное (друг за другом) размещение «строк» – одномерных массивов со значениями (векторная организация памяти).
Обращению к элементам массива при помощи операции индексации m[i][j] соответствует эквивалентное выражение, использующее адресную арифметику – *(*(m+i)+j).
Аналогичным образом можно установить соответствие между указателями и массивами с произвольным числом измерений.