Програмування С, С++теорія та практика (частина 1)
1.9.3 Оголошення та звертання до багатовимірних масивів
У даному розділі розглянемо оголошення і зв'язок покажчиків і елементів багатомірних масивів - що мають 2 та більше вимірів.
Багатомірний масив у мові Сі розглядається як сукупність масивів меншої розмірності. Наприклад, двовимірний масив - це сукупність одновимірних масивів (його рядків), тривимірний масив - це сукупність матриць, матриці - сукупності рядків, а рядок - сукупність елементів одновимірного масиву.
Елементи масивів розташовуються в ОП таким чином, що швидше змінюються самі праві індекси, тобто елементи одновимірного масиву розташовуються підряд, двовимірного - по рядках, тривимірного - по матрицях, а матриці - по рядках.
Для звертання до елементів багатомірного масиву можна використовувати нуль і більш індексів (індексних виразів):
ім'я-масиву [вираз1][вираз2] ...
Наприклад, для звертання:
• до одновимірного масиву можна використовувати одно- індексний вираз (індекс);
• до двовимірного - 1 або 2 індексний вираз;
• до тривимірного - 1, 2 або 3 індексний вираз і т.д.
При звертанні до багатомірних масивів одержання значення елемента масиву можливо тільки після визначення адреси елемента масиву, тобто при повній кількості індексів. При цьому обчислюються індексні вираз зліва на право, і доступу до значення виконується після обчислення останнього індексного виразу.
Приклад оголошення двовимірного масиву значень типу іпґ.
іпї а[т][п] ;
Цей масив складається з т одновимірних масивів (рядків), у кожному з яких утримується п елементів (стовпців). При роботі з цим двовимірним масивом можна використовувати одно або 2 індексний вираз. Наприклад:
а[і]Ц]- містить 2 індекси; використовується для звертання до елемента і-рядка, ] -стовпця масиву; обчислюються індексні вирази, визначається адреса елемента масиву і вилучається його значення;
а[і] - містить 1 індекс; визначає адресу одновимірного масиву: адреса початку і-рядка масиву;
а - не містить індексу і визначає адресу масиву, його нульового елемента.
Таким чином, звертання до двовимірних масивів за допомогою імені і тільки одного індексу визначає покажчик на початок відповідного рядка масиву (адреса його нульового елемента). Наприклад:
а[0] == &а[0] [0] == а+0*п*зігео£(іп'Ь) ;
а[1] == &а[1][0] == а+1*п*зігео£(іп^);
а[і] == &а[і][0] == а+і*п*зігео£(іп^);
Приклад оголошення тривимірного масиву:
іпї а[к][т][п] ;
де:
- к- кількість матриць з т рядками і п стовпцями;
- т - кількість рядків (одновимірних масивів) у матриці;
- п - кількість стовпців (елементів у рядку) матриці.
Цей масив складається з к матриць, кожна з яких складається з т одновимірних масивів (рядків) по п елементів (стовпців). При звертанні до цього масиву можна використовувати імена:
а[1][і][|] - містить 3 індекси; використовується для звертання до елемента 1-матриці, і-рядка. ] -стовпця масиву; обчислюються індексні вирази, визначається адреса елемента масиву і вилучається його значення;
а[к] [і] - визначає одновимірний масив - адреса початку і-рядка; к - матриці;
а[к] - визначає двовимірний масив - адреса початку к - матриці, тобто нульового елемента його нульового рядка;
а - адреса початку масиву, нульового елемента нульового рядка нульової матриці.
Наприклад: іп£ Ь[3][4][5]; іп£ і, *ір, *ірр; і = Ь[0][0] [1]; ір = Ь[2] [0] ; ірр = Ь[2] ;
де: ір, ірр - покажчики на значення типу іпі.
Після ір = Ь[2][0]; ір є покажчиком на елемент 0-рядка 0-го стовпця 2-й матриці масиву, тобто Ь[2][0][0].
Після ірр = Ь[2]; ірр адресує 0-й рядок 2-ї матриці масиву, тобто містить адреса Ь[2] [0] [0].
Звертання до елементів багатомірного масиву більш детально розглянемо на прикладі двовимірного масиву. Наприклад:
іп£ а[3][4]; /* а - покажчик-константа */
іп£ *р = а; /* р - покажчик-змінна */
Після цього покажчик р можна використовувати замість покажчика а для звертання до рядків або елементів масиву а у вигляді: ім'я покажчика і зсув елемента щодо адреси початку масиву а.
В ОП елементи масиву а розташовуються таким чином, що швидше всіх змінюється самий правий індекс, тобто в послідовності: а[0][0] а[0] [1] а[0] [2] а[0][3] а[1][0] ... а[2][2] а[2][3].
При цьому для звертання до масиву а можна використовувати імена:
&а == а == &а[0][0] == *а
адреса а[0] [0] - елемента 0-ого рядка 0-ого стовпця масиву а;
**а == * (&а [0] [0]) == а [0] [0]
значення елемента нульового рядка нульового стовпця масиву а; а[і] == (а + і) == *(а + і) == &а[і][0] адреса елемента і-рядка 0-стовпця;
*а[і] == **(а + і) == *(&а[і]) == а[і][0] значення 0-го елемента і-рядка; а[і][]] == *(*(а + і) + і) == *(а[і] + і) == а[і][]] значення елемента і-рядка \ -стовпця масиву а;
де:
(а + і) == *(а + і) == а[і]
адреса 0-го елемента і-рядка == &а[і][0];
(* (а + і) + і)
адреса ,)-елемента і-рядка = &а[і][)];
*(*(а + і) + з)
значення _]-елемента і-рядка = а[і][]].
Значення адреси початку і-рядка (адреси 0-елемента і-рядка) на машинному рівні формується у виді:
а[і] = а + і == (а+і*п*зі2ео£(іп£)) , де п - кількість
значень в одному рядку.
Таким чином, адреса (і+1)-рядка відстоїть від і-рядка на (п*8І2ЄОҐ(іпІ)} байтів, тобто на відстань одного рядка масиву.
Вираз а[і][]] компілятор Сі переводить в еквівалентний вираз:
*(*а + і) + ,)). Зрозуміло, запис а[і][]] більш традиційний у математиці і більш наочний.
До елементів двовимірного масиву можна звернутися і за допомогою скалярного покажчика на масив. Наприклад, після оголошення:
іп£ а[т][п], *р = а;
* (р+і*п+і) - значення ) - елемента і-рядка ; де: п - кількість елементів у рядку;
і*п + ) - змішання а[і][)]- елемента відносно початку масиву а.
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
