Інформатика
Масиви та покажчики : Оголошення та звертання до багатовимірних масивів
 

Оголошення та звертання до багатовимірних масивів

     Багатомірний масив у мові С розглядається як сукупність масивів меншої розмірності. Наприклад, двовимірний масив - це сукупність одновимірних масивів (його рядків), тривимірний масив - це сукупність матриць, матриці - сукупності рядків, а рядок - сукупність елементів одновимірного масиву.
     Елементи масивів розташовуються в ОП таким чином, що швидше змінюються самі праві індекси, тобто елементи одновимірного масиву розташовуються підряд, двовимірного - по рядках, тривимірного - по матрицях.
     Для звертання до елементів багатомірного масиву можна використовувати нуль і більш індексів (індексних виразів):
ім'я-масиву [вираз1][вираз2] ...
Наприклад, для звертання:
- до одновимірного масиву можна використовувати одно-індексний вираз (індекс);
- до двовимірного - 1 або 2 індексний вираз;
- до тривимірного - 1, 2 або 3 індексний вираз і т.д.
     При звертанні до багатомірних масивів одержання значення елемента масиву можливо тільки після визначення адреси елемента масиву, тобто при повній кількості індексів. При цьому обчислюються індексні вирази зліва на право, і доступ до значення виконується після обчислення останнього індексного виразу.
     Приклад оголошення двовимірного масиву значень типу int.
int а[m][n] ;
     Цей масив складається з m одновимірних масивів (рядків), у кожному з яких утримується n елементів (стовпців). При роботі з цим двовимірним масивом можна використовувати одно або 2 індексних виразів. Наприклад:
- а[i][j] містить 2 індекси; використовується для звертання до елемента i-рядка, j-стовпця масиву; обчислюються індексні вирази, визначається адреса елемента масиву і вилучається його значення;
- a[i] містить 1 індекс; визначає адресу одновимірного масиву: адреса початку i-рядка масиву;
- а не містить індексу і визначає адресу масиву, його нульового елемента.
     Таким чином, звертання до двовимірних масивів за допомогою імені і тільки одного індексу визначає покажчик на початок відповідного рядка масиву (адреса його нульового елемента). Наприклад:
а[0] == &a[0][0] == a+0*n*sizeof(int);
а[1] == &а[1][0] == a+1*n*sizeof(int);
a[i] == &a[i][0] == a+i*n*sizeof(int).
     Приклад оголошення тривимірного масиву:
int а[k][m][n] ;
де k- кількість матриць з m рядками і n стовпцями;
m - кількість рядків (одновимірних масивів) у матриці;
n - кількість стовпців (елементів у рядку) матриці.
     Цей масив складається з k матриць, кожна з яких складається з m одновимірних масивів (рядків) по n елементів (стовпців). При звертанні до цього масиву можна використовувати імена:
- a[l][i][j] містить 3 індекси; використовується для звертання до елемента l-матриці, i-рядка. j-стовпця масиву; обчислюються індексні вирази, визначається адреса елемента масиву і вилучається його значення;
- a[k][i] визначає одновимірний масив - адреса початку i-рядка; k - матриці;
- a[k] визначає двовимірний масив - адреса початку k - матриці, тобто нульового елемента його нульового рядка;
- а - адреса початку масиву, нульового елемента нульового рядка нульової матриці.
Наприклад:
int b[3][4][5];
int i, *ip, *ipp;
i = b[0][0][1];
ip = b[2][0];
ipp = b[2];
де: ip, ipp - покажчики на значення типу int.
Після ip = b[2][0]; ip є покажчиком на елемент 0-рядка 0-го стовпця 2-й матриці масиву, тобто b[2][0][0].
Після ipp = b[2]; ipp адресує 0-й рядок 2-ї матриці масиву, тобто містить адреса b[2][0][0].
     Звертання до елементів багатомірного масиву більш детально розглянемо на прикладі двовимірного масиву. Наприклад:
int а[3][4];      /* а - покажчик-константа */
int *р = а;      /* р - покажчик-змінна */
     Після цього покажчик р можна використовувати замість покажчика а для звертання до рядків або елементів масиву а у вигляді: ім'я покажчика і зсув елемента щодо адреси початку масиву а.
     В оперативній пам'яті елементи масиву а розташовуються таким чином, що швидше всіх змінюється самий правий індекс, тобто в послідовності:
а[0][0] а[0][1] а[0][2] а[0][3] а[1][0] ... а[2][2] а[2][3].
При цьому для звертання до масиву а можна використовувати імена:
&a == а == &а[0][0] == *а - адреса а[0][0] - елемента 0-ого рядка 0-ого стовпця масиву а;
**а == *(&а[0][0]) == а[0][0] - значення елемента нульового рядка нульового стовпця масиву а;
a[i] == (а + i) == *(а + i) == &а[i][0] - адреса елемента i-рядка 0-стовпця;
*a[i] == **(а + i) == *(&а[i]) == a[i][0] - значення 0-го елемента i-рядка;
a[i][j] == *(*(а + i) + j) == *(a[i] + j) == a[i][j] - значення елемента i-рядка j-стовпця масиву а;
де:
(а + i) == *(а + i) == a[i] - адреса 0-го елемента i-рядка == &a[i][0];
(*(а + i) + j)- адреса j-елемента i-рядка = &a[i][j];
*(*(а + i) + j)- значення j-елемента i-рядка = a[i][j].
     Значення адреси початку i-рядка (адреси 0-елемента i-рядка) на машинному рівні формується у виді:
a[i] = а + i == (a+i*n*sizeof(int)), де n - кількість значень в одному рядку.
     Таким чином, адреса (i+1)-рядка відстоїть від i-рядка на (n*sizeof(int)) байтів, тобто на відстань одного рядка масиву.
     Вираз a[i][j] компілятор С++ переводить в еквівалентний вираз:
*(*а + i) + j). Зрозуміло, запис a[i][j] більш традиційний у математиці і більш зрозумілий.
     До елементів двовимірного масиву можна звернутися і за допомогою скалярного покажчика на масив. Наприклад, після оголошення:
int а[m][n], *р = а;
*(p+i*n+j) - значення j - елемента i-рядка ;
де: n - кількість елементів у рядку;
i*n + j - змішання а[i][j]- елемента відносно початку масиву а.

 
© 2008 ХНУРЭ, Інформатики, Сінельнікова Т.Ф., informatika@kture.Kharkov.ua
Розроблено за допомогою LERSUS