Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Основы.doc
Скачиваний:
48
Добавлен:
07.03.2016
Размер:
3.6 Mб
Скачать

8.4. Багатовимірні масиви

Багатовимірні масиви задаються окремими вимірами в квадратних дужках, наприклад, оператор int matr [3][4]; задає опис двовимірного масиву з 3 рядків та 4 стовпців. У пам'яті такий масив розташовується послідовно по рядках. Тобто в пам’яті будь-який багатовимірний масив розташовується як одновимірний. Двовимірний масив представляє собою константну вказівку, яка збільшується на кількість елементів в кожному рядку масиву. Привласнимо двовимірний масив вказівці.

int matr [3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};

int (*mm)[4] = matr;

Тепер перший та другий рядок повністю еквівалентні, з тією відмінністю, що matr – константна вказівка, а mm – ні.

Запис int (*mm)[4] означає, що при арифметичних операціях з вказівкою, вона збільшується або зменшується на кількість байтів 4-х елементів типу даних int до першого розмикання. Після першого розмикання адреса збільшується на кількість байтів одного елементу int, як у разі звичайної вказівки.

Для доступу до елементу багатовимірного масиву вказують всі його індекси, наприклад, matr[i][j], або іншим способом: *(matr[i]+j) або *(*(matr+i)+j).

При ініціалізації багатовимірного масиву він представляється або як масив з масивів, при цьому кожен масив береться в свої фігурні дужки (в цьому випадку ліву розмірність при описі можна не вказувати), або задається загальний список елементів в тому порядку, в якому елементи розташовуються в пам'яті:

I-й варіант

II-й варіант

int aaa[3][2]=

{

{5,4},

{7,1},

{3,0}

};

int aaa[3][2]=

{5,4,7,1,3,0};

Як і у випадку роботи з одновимірним масивом, якщо ви ініціалізуєте один або більше елементів, інші – заповнюються нулями.

Приклад:

float ss[3][2]={0.0};

всі елементи масиву заповнюються нулями.

Наведемо приклад виведення певного елементу двовимірного масиву різними засобами з використанням вказівок.

#include <iostream>

using namespace std;

void main()

{

int ara[][2]={{100,200},{300,400},{500,600}};

int (*mm1)[2] = ara;

int *mm2 = (int*)ara;

cout << ara[1][1] <<"\t" <<*(*(ara+1)+1)<<"\n";

cout << mm1[1][1] <<"\t" <<*(*(mm1+1)+1)<<"\n";

cout << (*ara)[3] <<"\t" <<*(*ara+3)<<"\n";

cout << mm2[3] <<"\t" <<*(mm2+3)<<"\n";

}

Результат:

400 400

400 400

400 400

400 400

Змінні int ara[][2] та int (*mm1)[2] представляють собою вказівки, де запис у квадратних дужках показує на скільки елементів треба зміщуватись при арифметичних операціях. У нашому випадку це 2*sizeof(int). Після першого розмикання вказівка буде переміщуватись через 4 байти (sizeof(int)).

За допомогою рядку коду int *mm2 = (int*)ara; явно приводимо вказівку ara до типу (int*) після чого з двовимірним масивом можна працювати як з одновимірним.

Оператор for є гарним засобом організації доступу до кожного елемента двовимірної таблиці

for (row=0;row<2;row++)

for (col=0,col<3;col++)

cout <<row<" "<<col<<"\u";

Наведемо приклад виведення цін на дискети:

Комп’ютерна компанія продає дискети 3.5 і 5.25 дюйма. Кожна дискета буває однієї з 4-х ємностей: односторонніми, подвійної щільності, двосторонніми подвійної щільності, односторонніми підвищеної щільності, двосторонніми підвищеної щільності.

#include <iostream>

#include <iomanip>

using namespace std;

void main()

{

int row, col;

float disk[2][4] =

{{2.3f, 2.75f, 3.2f, 3.5f},

{1.75f, 2.1f, 2.6f, 2.95f}};

cout.setf(ios::fixed);

cout.setf(ios::showpoint);

cout << "\tSingle sided,\tDouble sided,"

<< "\tSingle sided,\tDouble sided,\n";

cout << "\tDouble density\tDouble density"

<< "\tHigh density \tHigh density \n";

for (row = 0; row < 2; row++)

{

if(row == 0)

cout << "3.5\" \t";

else

cout << "5.25\"\t";

for (col = 0; col < 4; col++)

cout << "$" << setprecision(2)

<< disk[row][col] << "\t\t";

cout << "\n";

}

}

Результат:

Single sided, Double density

Double sided, Double density

Single sided, High density

Double sided, High density

3.5

$2.30

$2.75

$3.20

$3.50

5.25

$1.75

$2.10

$2.60

$2.95

Наступний приклад представляє найбільший інтерес. У ньому продемонстровано як за рахунок приведення вказівок можна перетворити двовимірний масив в одновимірний і навпаки – одновимірний в двовимірний.

#include <iostream>

using namespace std;

void main()

{

int i,j;

//З 2-мірного в 1-й

int mas[3][3]=

{

{11,12,13},

{21,22,23},

{31,32,33}

};

int* aa = (int*)mas;

for(i=0;i<9;i++)

{

cout<<aa[i]<<" ";

}

cout<<"\n\n\n";

//З 1-мірного в 2-й

int а[9]= {1, 2, 3, 4, 5, 6, 7, 8, 9};

int (*b)[3];

b = (int(*)[3])а;

for(i=0;i<3;i++)

{

for(j=0;j<3;j++)

cout<<b[i][j]<<" ";

cout<<"\n";

}

}

Перетворення двовимірного масиву mas[3][3] в одновимірний здійснюється за допомогою рядка коду:

int* aa = (int*)mas;

Тобто вказівка int(*)[3] приводиться до вказівки int*.

Перетворення одновимірного масиву а[9] в двовимірний здійснюється за допомогою рядка коду:

b = (int(*)[3])а;

Тобто вказівка int* приводиться до вказівки int(*)[3]. При цьому вказівка b оголошується таким чином:

int (*b)[3];

Після виконання програми отримаємо наступний результат:

11 12 13 21 22 23 31 32 33

1 2 3

4 5 6

7 8 9

Знаючи особливості приведення вказівок при роботі з масивами можна маніпулювати їх вимірюваннями як завгодно. Тобто, перетворити масив з одного вимірювання в інше не представляє ніякої складності, оскільки в пам'яті всі елементи статичних масивів розташовуються послідовно без виділення додаткової пам'яті.

Можна працювати з багатовимірними масивами, виділяючи їм динамічну пам’ять з використанням оператору new. Для кожного вимірювання необхідно виділити додаткову пам’ять.

Приведемо приклад.

#include <iostream>

using namespace std;

void main()

{

//m, n - відповідно кількість рядків

// і стовпців масиву

int i, j, m, n;

cin>>m>>n;

//Ініціалізація масиву

int **mas = new int*[m];

for (i=0;i<m;i++)

mas[i]= new int[n];

//Введення даних

for(i=0;i<m;i++)

for(j=0;j<n;j++)

cin>>mas[i][j];

//Виведення даних

for(i=0;i<m;i++)

{

for(j=0;j<n;j++)

cout<<mas[i][j]<<" ";

cout<<"\n";

}

//Видалення масиву

for (i=0;i<m;i++)

delete[] mas[i];

delete [] mas;

}