Книга: Язык Си - руководство для начинающих
УКАЗАТЕЛИ И МНОГОМЕРНЫЕ МАССИВЫ
Как создать указатели для многомерных массивов? Чтобы найти ответ на этот вопрос, рассмотрим несколько примеров.
Предположим, что у нас есть описания
int zippo[4][2]; /* массив типа int
из 4 строк и 2 столбцов */
int *pri; /* указатель на целый тип */
Тогда на что pri = zippo; указывает? На первый столбец первой строки:
zippo == &zippo[0][0]
А на что указывает pri + 1? На zippo[0][l], т.е. на 1-ю строку 2-го столбца? Или на zippo[l][0], элемент, находящийся во второй строке первого столбца? Чтобы ответить на поставленный вопрос, нужно знать, как располагается в памяти двумерный массив. Он размещается, подобно одномерным массивам, занимая последовательные ячейки памяти. Порядок элементов определяется тем, что самый правый индекс массива изменяется первым, т. е. элементы массива располагаются следующим образом:
zippo[0][0] zippo[0][1] zippo[1][0] zippo[1][1] zippo[2][0]
...
Сначала запоминается первая строка, за ней вторая, затем третья и т. д. Таким образом в нашем примере:
pri == &zippo[0][0] /* 1-я строка, 1 столбец */
pri + 1 == &zippo[0][1] /* 1-я строка, 2 столбец */
pri + 2 == &zippo[1][0] /* 2-я строка, 1 столбец */
pri + 3 == &zippo[1][1] /* 2-я строка, 2 столбец */
Получилось? Хорошо, а на что указывает pri + 5? Правильно, на zippo[2][l].
Мы описали двумерный массив как массив массивов. Если zippo является именем нашего двумерного массива, то каковы имена четырех строк, каждая из которых является массивом из двух элементов? Имя первой строки zippo[0], имя четвертой строки zippo[3]; вы можете заполнить пропущенные имена. Однако имя массива является также указателем на этот массив в том смысле, что оно ссылается на первый его элемент. Значит,
zippo[0] == &zippo[0][0]
zippo[1] == &zjppo[1][0]
zippo[2] == &zippo[2][0]
zippo[3] == &zippo[3][0]
Это свойство является более, чем новшеством. Оно позволяет использовать функцию, предназначенную для одномерного массива, для работы с двумерным массивом! Вот доказательство (хотя мы надеемся, что теперь вы бы поверили нам и так) использования двумерного массива в нашей программе нахождения среднего значения:
/* одномерная функция, двумерный массив */
main( )
{
static int junk[3][4] = {
{2, 4, 6, 8},
{100, 200, 300, 400},
{10, 40, 60, 90} };
int row;
for(row = 0; row < 3; row ++)
printf(" Среднее строки %d равно %d.n", row, mean(junk[row],4));
/* junk [row] - одномерный массив ИЗ четырех элементов */
}
/* находит среднее в одномерном массиве */
int mean(array,n)
int array[ ], n;
{
int index;
long sum;
if(n > 0) {
for(index = 0, sum = 0; index < n; index++)
sum += (long)array[index];
return((int)(sum/n)); }
else {
printf(" Нет массива. n");
return(0); }
}
Результат работы программы:
Cреднее строки 0 равно 5.
Cреднее строки 1 равно 250.
Cреднее строки 2 равно 50.