Що таке масив? Операції над масивами

Масив - це складний (складовий, структурований) тип даних, що характеризується таким:

· Елементи масиву мають однаковий тип на відміну від структур, тому кожен елемент масиву займає однаковий обсяг пам'яті;

· Масив розташовується в оперативній пам'яті, а не на зовнішньому пристрої, як файли (2-й семестр);

· Елементи масиву займають поспіль осередки, що йдуть, на відміну, наприклад, від списків (2-й семестр).

Доступ до елементів масиву в мові З здійснюється двома способами.

Перший, за допомогою порядкового номера масиву, який називається індексом , характерний для багатьох мов програмування і у першому семестрі. Він більш простий і звичний для тих, хто вивчав мову Pascal.Як індекс можна використовувати вираз цілого або сумісного з ним типу, у тому числі константу або змінну. Як індекс не можна використовувати вираз речового типу.

Крім того, в мові С є можливість обробляти масиви, використовуючи покажчики (адреси) , оскільки у С++ існує зв'язок між масивами та покажчиками. Незважаючи на те, що в першому способі в програмі відсутній спеціальний тип для роботи з адресами, покажчики все одно використовуються.

Масиви можуть мати одну або кілька розмірів. У цьому параграфі розглядається одновимірний масив, який іноді називають вектором , маючи на увазі вектор в n-мірному просторі. Робота з двовимірними масивами ( матрицями) розглядається в гол. 5. Три і більше розмірностей практично використовують рідко, оскільки такі масиви займають великий обсяг оперативної пам'яті.

Скрізь надалі під словом "масив" розумітимемо одномірний масив.

З погляду часу (етапу), коли розподіляється пам'ять під масив, існують два види. Пам'ять для динамічного масиву виділяється під час виконання програми, і якщо масив не потрібен, пам'ять йому можна звільнити. Такі масиви розглядаються у другому семестрі.

Одновимірний масив з фіксованою розмірністю (назвемо його статичний ) оголошується у загальному вигляді так:

тип ім'я [N];

Тут тип- Тип елементів масиву. Спочатку будемо розглядати прості типи (int, float, char), але можна використовувати і складні, наприклад, структури. Ім'язаписується за правилами ідентифікаторів. Кожен елемент масиву має те саме ім'я, змінюється лише індекс чи номер елемента. N- Розмірність (або розмір) масиву у вигляді цілісної константи або константного виразу. Ця величина визначає кількість осередків оперативної пам'яті, зарезервованої для масиву. Наприклад:

float A;або const n=10; float A[n];

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

На відміну від динамічного масиву для статичного на етапі компіляції резервується пам'ять для розміщення Nчисел зазначеного типу (10 дійсних чисел). Для масиву потрібна пам'ять об'ємом k*Nбайт (4*10 ), де k- необхідна кількість байт для розміщення одного елемента вказаного типу (одного числа типу float). Ця пам'ять зберігається на весь час виконання програми, а точніше функції або блоку, де описаний масив. Програмно необхідний обсяг пам'яті визначається за допомогою операції sizeofнаступним чином:

M=sizeof (тип)*N; або M = sizeof (ім'я); або M= sizeof ім'я;

де M- Змінна цілого типу, що визначає розмір масиву в байтах. Тип обов'язково записується у дужках, а ім'я може бути без дужок. Наступна програма двічі виведе число 40.

float A; int M1, M2;

M1=sizeof(float)*10; //але M1=sizeof float *10;-помилка!

M2=sizeof(A); //або M2=sizeof A;

cout<

У багатьох сучасних системах програмування, у тому числі і в С++, нумерація елементів масиву починається з 0. A- Останній елемент масиву. Це з використанням покажчиків під час роботи з масивами (див. 2-й семестр). Тому в прикладі індекс змінюється від 0 до 9 включно, тобто індекс останнього елемента масиву на одиницю менший за його розмірність. Оголошені 10 елементів масиву позначаються так: A, A, A, ..., A. У С++ відсутня перевірка меж масивів. Можна вийти за його кордон і записати значення в певну змінну або навіть код програми. Про такий контроль має подбати програміст.

При використанні статичних масивів виникають проблеми, якщо розмір масиву заздалегідь ми знаємо. У такому разі оголошуємо масив максимальної розмірності, яка, як правило, відома. Реальну розмірність вводимо і використовуємо далі, наприклад, у циклах та інших цілей:

const nmax = 100; float X;

int n; cout<<”Input the size of array ”; cin>>n;

/* Дальше працюємо з n(а не з nmax) елементами масиву, наприклад, вводимо їх. /

for (int i=0; i

{ // Цей рядок можна опустити разом із фігурними дужками.

cout<<”X[“<

cin>>X[i];

Такий спосіб простіше, але неефективний з погляду розподілу пам'яті, оскільки "замовляємо" більше пам'яті, ніж реально використовуємо. У разі професійно використовуються ефективніші динамічні масиви (див. 2-й семестр).

Масив- це набір елементів (компонентів), що мають однаковий . Причому цей тип даних може бути як простим, і складним.

Елементи масиву в пам'яті комп'ютера розташовані один за одним. Отримати доступ до окремого елемента масиву можна за індексом цього елемента.

Будь-який масив має фіксований розмір. Таким чином, розмірність масиву- це кількість індексів, необхідне однозначного доступу до елемента масиву.

Масив може бути як одновимірним, і багатовимірним. Наприклад, таблиця – це двомірний масив (рядки таблиці – це одна розмірність масиву, стовпці таблиці – друга). Зрозуміло, таблицю можна як два одномірних масиву. Але легше працювати з одним масивом, ніж із двома.

Найчастіше використовуються одномірні та двомірні масиви. Рідше – тривимірні. Масиви з більшою розмірністю я використовувати не рекомендую (особливо новачкам), так як це загрожує великою кількістю помилок, що важко знайти.

Як індекс масиву може використовуватися змінна. Ця змінна повинна обов'язково мати.

Деякі мови програмування та засоби розробки мають у своєму арсеналі динамічні масиви, тобто масиви не з фіксованою, а з невизначеною розмірністю.

Навіщо потрібні масиви? Відповідь проста – для зручності (як, втім, і всі мовні конструкції). У багатьох випадках працювати з масивом даних зручніше, ніж з окремими змінними.

Синтаксис масиву в Паскалі:

var Ім'яМассива: array of ТипДаних;

Тут Ім'яМассива- це ім'я змінної, що з цим масивом. Тип даних- Це тип даних елементів масиву. Приклад:

var M1: array of byte;

Тут ми оголосили масив із ім'ям М1, який містить 16 елементів типу byteз індексами від 0 до 15. перший елемент масиву має індекс 0, другий індекс 1 і так далі.

Працювати з окремим елементом масиву можна так:

var m: byte;
M1: = 100;
m:= M1;

Тут ми спочатку у перший елемент масиву записуємо значення 100, а потім у змінну mзаписуємо значення першого елемента масиву. Здогадайтеся, яке значення буде у змінній mпісля цього))).

Але зрозуміти всю красу використання масивів ви зможете тільки тоді, коли спробуєте обробити всі елементи масиву в . Наприклад, так:

for i:= 0 to 15 do M1[i] := i;
for i:= 0 to 15 do Write(M1[i], " ");

Сподіваюся, не треба пояснювати, що робить цей код. А тепер уявіть, скільки б рядків коду вам довелося написати, якби те саме ви робили за допомогою звичайних змінних.

Двовимірний масив оголошується так:

M2: array of byte;

Це буде матриця (або таблиця) 4х2. Тобто такий масив має кілька рядків (у прикладі 4) і кілька стовпців (у прикладі 2). Того ж результату можна досягти, якщо оголосити масив масивів:

M2e: array of array of byte;

Тут новачкам зазвичай важко збагнути, що з усім цим "багатомірством" робити. Ну нічого, звикайте. Перший масив – це рядки таблиці. Другий – це стовпці. Тобто кожен елемент першого масиву містить масив array. Таблиця (матриця), представлена ​​нашим прикладом, має такий вигляд:


Таким чином,

М2 - це осередок 1.1 (перший рядок, перший стовпець)
М2 - це осередок 1.2 (перший рядок, другий стовпець)
М2 - це осередок 2.1 (другий рядок, перший стовпець)

Якщо ви спробуєте використати, наприклад, М2, компілятор видасть попередження, так як стовпця 3 в нашому масиві не існує. Однак будьте обережні! У деяких засобах розробки програма буде створена (залежить від налаштувань середовища)! І ви можете отримати помилку, яку буде важко виявити.

А тепер приклад використання нашого двомірного масиву:

//Заповнюємо масив for i: = 1 to 4 do for j: = 1 to 2 do M2 = i * 10 + j; //Виводимо масив на екран for i: = 1 to 4 do for j: = 1 to 2 do Write (M2, "");

Як бачите, тут ми використовуємо ДВІіндексних змінних ( iі j) та вкладені . Як працюють вкладені цикли – спробуйте здогадатися самі. Якщо не вийде - поставте питання в розділі. Цей розділ я намагаюся перевіряти хоча б щодня.

Сподіваюся, із цим кодом ви розібралися. Або хоча б запустили його і подивилися, що він робить. А він виводить двовимірний масив на екран. Але висновок виконується в один рядок. І це не дуже зручно для двомірного масиву. Адже зазвичай у таких масивах представлені матриці (таблиці). Тобто зручніше сприймати інформацію, якщо вона виводитиметься у вигляді таблиці. У нашому випадку хотілося б отримати 4 рядки та 2 стовпці.

Спробуйте вирішити це завдання самостійно. А якщо у вас не вийде, то ось один із варіантів рішення:

For i:= 1 to 4 do for j:= 1 to 2 do case j of 1: Write(M2, " "); 2: WriteLn(M2, " "); end;

Це рішення не є універсальним, тому що його складно застосувати до масивів з іншою розмірністю (з іншою кількістю стовпців). Зате воно просте. І у багатьох випадках його можна використати.

Const k = 8; //Кількість стовпців var i, j: byte; M2f: array of array of byte; // Заповнюємо масив for i: = 1 to 4 do for j: = 1 to k do M2f: = i * 10 + j; //Виводимо таблицю for i: = 1 to 4 do for j: = 1 to k do case j of k: WriteLn (M2f, ""); else Write(M2f, " "); end;

Вивчіть уважно цей приклад і знайдіть усі ділянки коду, де використовується константа k. Далі, сподіваюся, ви розберетеся із цим кодом самостійно.

Ну і насамкінець додам, що для визначення індексів масиву можна використовувати вже відомі нам стандартні функції Lowі High. Наприклад, так:

WriteLn("Індекс першого елемента М1:", Low(M1));
WriteLn("Індекс останнього елемента М1:", High(M1));

Стаття вийшла більше, ніж я очікував. Але сподіваюся, у вас вистачило терпіння дочитати її до кінця...

При вирішенні завдань з великою кількістю даних однакового типу використання змінних з різними іменами, які не впорядковані за адресами пам'яті, ускладнює програмування. У таких випадках у мові Сі використовують об'єкти, які називаються масивами.

- Це безперервна ділянка пам'яті, що містить послідовність об'єктів однакового типу, що позначається одним ім'ям.

Масив характеризується такими основними поняттями:

Елемент масиву (значення елемента масиву)– значення, що зберігається у певній комірці пам'яті, розташованої в межах масиву, а також адресу цієї комірки пам'яті.
Кожен елемент масиву характеризується трьома величинами:

  • адресою елемента - адресою початкової комірки пам'яті, в якій розташований цей елемент;
  • індексом елемента (порядковим номером елемента у масиві);
  • значенням елемента.

Адреса масиву – адреса початкового елемента масиву.

Ім'я масиву – ідентифікатор, який використовується для звернення до елементів масиву.

Розмір масиву – кількість елементів масиву

Розмір елемента – кількість байт, які займає один елемент масиву.

Графічно розташування масиву в пам'яті комп'ютера можна у вигляді безперервної стрічки адрес.

Представлений малюнку масив містить q елементів з індексами від 0 до q-1 . Кожен елемент займає пам'яті комп'ютера k байт, причому розташування елементів у пам'яті послідовне.

Адреси i-го елемента масиву має значення

Адреса масиву є адресою початкового (нульового) елемента масиву. Для звернення елементів масиву використовується порядковий номер (індекс) елемента, початкове значення якого дорівнює 0 . Так, якщо масив містить елементів q, то індекси елементів масиву змінюються в межах від 0 до q-1 .

Довжина масиву – кількість байт, що відводиться пам'яті для зберігання всіх елементів масиву.

Довжина Масиву = Розмір Елементу * Кількість Елементів

Для визначення розміру елемента масиву може використовуватись функція

int sizeof (тип);

Наприклад,

sizeof (char) = 1;
sizeof(int) = 4;
sizeof (float) = 4;
sizeof (double) = 8;

Оголошення та ініціалізація масивів

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

тип ім'я [розмірність] = (ініціалізація);

Ініціалізація є набір початкових значень елементів масиву, зазначених у фігурних дужках, і розділених комами.

int a = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9); // масив a з 10 цілих чисел

Якщо кількість ініціалізуючих значень, зазначених у фігурних дужках, менша, ніж кількість елементів масиву, вказана в квадратних дужках, то всі елементи, що залишилися в масиві (для яких не вистачило ініціалізуючих значень) дорівнюватимуть нулю. Цю властивість зручно використовувати для завдання нульових значень усім елементам масиву.

int b = (0); // масив b з 10 елементів, ініціалізованих 0


Якщо масив проініціалізований при оголошенні, то константні початкові значення його елементів вказуються через ком у фігурних дужках. У цьому випадку кількість елементів у квадратних дужках може бути опущена.

int a = (1, 2, 3, 4, 5, 6, 7, 8, 9);

При зверненні до елементів масиву індекс необхідного елемента вказується у квадратних дужках.

Приклад на Сі

1
2
3
4
5
6
7
8

#include
int main()
{
int a = (5, 4, 3, 2, 1); // масив a містить 5 елементів
printf("%d%d%d%d\n", a, a, a, a, a);
getchar();
return 0;
}

Результат виконання програми:

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

int a;

Для завдання початкових значень елементів масиву часто-густо використовується параметричний цикл:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18


#include
int main()
{
int a;
int i;
// Введення елементів масиву
for (i = 0; i<5; i++)
{
printf("a[%d] = ", i);
scanf("%d", &a[i]);
}
// Виведення елементів масиву
for (i = 0; i<5; i++)
printf("%d", a[i]); // Пробіл у форматі друку обов'язковий
getchar(); getchar();
return 0;
}

Результат виконання програми

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

У мові Сі можуть бути оголошені багатовимірні масиви. Відмінність багатовимірного масиву від одномірного у тому, що у одномірному масиві становище елемента визначається одним індексом, а багатомірному - декількома. Прикладом багатовимірного масиву є матриця.

Загальна форма оголошення багатовимірного масиву

тип ім'я[розмірність1][розмірність2]...[розмірністьm];

Елементи багатовимірного масиву розташовуються в послідовних осередках оперативної пам'яті зростання адрес. У пам'яті комп'ютера елементи багатовимірного масиву розташовуються поспіль, наприклад масив, що має 2 рядки і 3 стовпці,

int a;


буде розташований у пам'яті наступним чином

Загальна кількість елементів у наведеному двовимірному масиві визначиться як

Кількість Рядок * Кількість Стовпців = 2 * 3 = 6.

Кількість байт пам'яті, необхідних розміщення масиву, визначиться як

Кількість елементів * Розмір елемента = 6 * 4 = 24 байти.

Ініціалізація багатовимірних масивів

Значення елементів багатовимірного масиву, як і в одновимірному випадку, можуть бути задані константними значеннями при оголошенні, укладеними у фігурні дужки (). Однак у цьому випадку зазначення кількості елементів у рядках та стовпцях має бути обов'язково вказано у квадратних дужках.

Приклад на Сі

1
2
3
4
5
6
7
8
9

#include
int main()
{
int a = (1, 2, 3, 4, 5, 6);
printf("%d%d%d\n", a, a, a);
getchar();
return 0;
}



Однак частіше потрібно вводити значення елементів багатовимірного масиву у процесі виконання програми. З цією метою зручно використовувати вкладений параметричний цикл.

Приклад на Сі

1
2
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

#define _CRT_SECURE_NO_WARNINGS
#include
int main()
{
int a; // масив з 2 рядків та 3 стовпців
int i, j;
// Введення елементів масиву
for (i = 0; i<2; i++) // цикл по рядках
{
for (j = 0; j<3; j++) // цикл по стовпцях
{
printf("a[%d][%d] = ", i, j);
scanf("%d", &a[i][j]);
}
}
// Виведення елементів масиву
for (i = 0; i<2; i++) // цикл по рядках
{
for (j = 0; j<3; j++) // цикл по стовпцях
{
printf("%d", a[i][j]);
}
printf("\n"); // Переведення на новий рядок
}
getchar(); getchar();
return 0;
}



Передача масиву у функцію

Обробку масивів зручно організовувати за допомогою спеціальних функцій. Для обробки масиву як аргументи функції необхідно передати

  • адреса масиву,
  • розмір масиву.

Виняток становлять функції обробки рядків, які достатньо передати лише адресу.

При передачі змінні як аргументи функції дані передаються як копії. Це означає, що якщо всередині функції відбудеться зміна значення параметра, це ніяк не вплине на його значення всередині функції, що викликає.

Якщо в функцію передається адреса змінної (або адреса масиву), то всі операції, що виконуються в функції з даними, що знаходяться в межах видимості зазначеної адреси, проводяться над оригіналом даних, тому вихідний масив (або значення змінної) може бути змінено функцією, що викликається.

Приклад на Сі Дан масив із 10 елементів. Поміняти місцями максимальний і вихідний елементи масиву. Для пошуку максимального елемента та обміну використовувати функцію.

1
2
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

#define _CRT_SECURE_NO_WARNINGS
#include
// Функція обміну
void change(int * x, int n)
{
// x - покажчик на масив (адреса масиву)
// n - розмір масиву
int i;
int max, index;
max = x;
index = 0;
// Пошук максимального елемента
for (i = 1; i {
if (x[i]>max)
{
max = x [i];
index = i;
}
}
// Обмін
x = x;
x = max;
}
// Головна функція
int main()
{
int a;
int i;
for (i = 0; i<10; i++)
{
printf("a[%d] = ", i);
scanf("%d", &a[i]);
}
change(a, 10); // виклик функції обміну
// Виведення елементів масиву
for (i = 0; i<10; i++)
printf("%d", a[i]);
getchar();
getchar();
return
p = p * x [i];
}
return p;
}
// Головна функція
int main()
{
int a; // оголошено масив a з 5 елементів
int i;
int pr;
// Введення елементів масиву
for (i = 0; i<5; i++)
{
printf("a[%d] = ", i);
scanf("%d", &a[i]); // &a[i] - адреса i-го елемента масиву
}
pr = func(a, 5); // Обчислення твору
printf("\n pr = %d", pr); // Висновок твору парних елементів
getchar(); getchar();
return 0;
}



Опис масиву дозволяє використовувати у програмі будь-який із його елементів. Для позначення елементів масиву Сі використовують індексовані змінні.

Індексована змінна (індексний вираз)– позначення осередку для зберігання елемента масиву. Іменується вказівкою ідентифікатора масиву та індексу (індексів) елемента.

ü Увага! Особливість позначення елементів масиву Сі - нумерація індексів від 0, а чи не від 1. Тому індекси Си на одиницю менше заданих математично. Ця обставина має враховуватися у програмі, особливо у формуванні умови повторення (виходу) циклу.

Схема розподілу пам'яті для зберігання одновимірного масиву така:

Довжина осередку для зберігання кожного елемента визначається типом масиву:

· символьний - 1 байт;

· Цілочисленний - 2 байти;

· Речовий - 4 байти;

· Подвійний точності - 8 байт.

Структура позначення індексованої змінної одновимірного масиву:

ім'я[індекс]

Де ім'я – ідентифікатор масиву;

індекс - операнд цілого типу, що визначає номер елемента в ряді інших складових масив;

- Обмежувачі індексу.

Наприклад, описаному раніше масиві D(16) перший елемент позначається індексним виразом d, другий – d, поточний – d[i], передостанній – d і останній – d.

При необхідності індекс може задаватися арифметичним виразом. Наприклад, d або d. У будь-якому випадку на момент використання змінної індекс повинен бути визначений (розрахований) і отримане значення має укладатися в заданий описником діапазон.

Розглянутий приклад ідентифікації елементів масиву D застосовується до будь-якого з описаних одновимірних масивів.

Індексовані змінні дозволяють здійснити програмну реалізацію алгоритмів із використанням елементів масивів. При цьому для одномірного масиву індексована змінна дозволяє визначити конкретну адресу кожного елемента.

Адреса будь-якої змінної визначається операцією &. Отже, елемент d адресу – &d, у d[i] – &d[i], тобто. всі елементи масиву розміщуються в оперативній пам'яті лінійно, починаючи з адреси &d.



У мові Сі ідентифікатор одновимірного масиву однозначно визначає адресу першого елемента. Наприклад, c º &c, d º &d.

Адреса кожного елемента одномірного масиву виражається залежністю ім'я+індекс (індекс визначає зсув елемента щодо першого на вказану кількість елементів). Наприклад, &c[i] (адреса i-го елемента масиву З) обчислюється як c+i.

Таким чином, індексний вираз повністю визначає конкретну комірку зберігання відповідного елемента.

Масив

Розмірністьмасиву - кількість індексів, необхідне однозначного доступу до елемента масиву .

Формаабо структура масиву- Кількість розмірностей і розмір (протяжність) масиву для кожної розмірності може бути представлений одномірним масивом.

У ряді мов програмування, наприклад, Лісп, JavaScript, PHP, Ruby застосовуються також асоціативні масиви (або хеш-масиви), в яких елементи не обов'язково є однотипними, а доступ до них не обов'язково здійснюється за індексом.

Загальний опис

Масив - упорядкований набір даних для зберігання даних одного типу, що ідентифікуються за допомогою одного або декількох індексів. У найпростішому випадку масив має постійну довжину і зберігає одиниці даних того самого типу.

Кількість індексів масиву, що використовуються, може бути різним. Масиви з одним індексом називають одновимірними, з двома - двовимірнимиі т. д. Одновимірний масив нестрого відповідає вектору в математиці, двовимірний - матриці. Найчастіше застосовуються масиви з одним або двома індексами, рідше – з трьома, ще більше індексів зустрічається вкрай рідко.

Приклад статичного масиву Паскаль

(Одномірний масив цілих чисел. Нумерація елементів від 1 до 15) a: array [1..15] of Integer; (Двовимірний масив символів. Нумерація по стовпцям типу Byte (від 0 до 255) по рядках від 1 до 5) multiArray: array [Byte, 1 .. 5] of Char; (Одномірний масив із рядків. Нумерація за типом word (від 0 до 65536)) rangeArray: array [Word] of String;

Приклад статичного масиву С/С++

Int Array [10]; // Одновимірний масив цілих чисел розміру 10 // Нумерація елементів від 0 до 9 double Array [12] [15]; // Двовимірний масив дійсних чисел подвійної точності// Розміру 12 на 15. // Нумерація по стовпцях від 0 до 11, по рядках від 0 до 14

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

У мовах програмування, що допускають оголошення програмістом власних типів, зазвичай існує можливість створення типу «масив». У визначенні такого типу може вказуватись розмір, тип елемента, діапазон значень та типи індексів. Надалі можливе визначення змінних створеного типу. Усі такі змінні-масиви мають одну структуру. Деякі мови підтримують для змінних масивів операції присвоєння (коли однією операцією всім елементам масиву присвоюються значення відповідних елементів іншого масиву).

Оголошення типу «масив» у мові Паскаль

Type TArrayType = array [0..9] of Integer; (* Оголошення типу "масив" *) var arr1, arr2, arr3: TArrayType; (* Оголошення трьох змінних-масивів одного типу *)

Специфічні типи масивів

Динамічні масиви

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

Приклад динамічного масиву на Delphi

ByteArray: Array of Byte; // Одновимірний масив multiArray : Array of Array of string ; // Багатовимірний масив

Приклад динамічного масиву на Сі

Float * array1; // Одновимірний масив int** array2; // Двовимірний масив array1 = (float *) malloc (10 * sizeof (float)); // виділення 10 блоків за sizeof(float) байт кожен array2 = (int **) malloc (16 * sizeof (int *)); // Виділення 16 блоків по sizeof(int*) байт кожен. Сюди будуть записані покажчики на одновимірні масиви-рядки for (i = 0; i< 16 ; i++ ) array2[ i] = (int * ) malloc (8 * sizeof (int ) ) ; // Виділення 8 блоків по sizeof(int) байт кожен. Це одномірні масиви – рядки матриці. // Звернення до масиву array1 [i] = 5.0; * (array1 + i) = 5.0; array2 [i] [j] = 6; // Записи еквівалентні. Перша з використанням індексу,* (* (array2 + i) + j) = 6; // Друга з операцією розіменування.

Приклад динамічного масиву С++

Float * array1; // Одновимірний масив int** array2; // Багатовимірний масив array1 = new float [10]; // Виділення 10 блоків розміром типу float array2 = new int * [16]; // Виділення 16 блоків розміром типу покажчика на int for (int i = 0; i< 16 ; i++ ) { array2[ i] = new int [ 8 ] ; }

Гетерогенні масиви

Гетерогеннимназивається масив, різні елементи якого можуть бути безпосередньо записані значення, що відносяться до різних типів даних . Масив, що зберігає покажчики на значення різних типів, не є гетерогенним, оскільки дані, що власне зберігаються в масиві, відносяться до єдиного типу - типу «покажчик». Гетерогенні масиви зручні як універсальна структура зберігання наборів даних довільних типів. Відсутність їх підтримки у мові програмування призводить до необхідності реалізації складніших схем зберігання даних. З іншого боку, реалізація гетерогенності потребує ускладнення механізму підтримки масивів у мовному трансляторі. Гетерогенний масив як вбудований тип даних присутній у мовах PHP та 1С.

Реалізація

Одним із способом реалізації статичних масивів з одним типом елементів є наступний (у Фортрані порядок індексів протилежний такому в Сі):

  1. Під масив виділяється безперервний блок пам'яті об'ємом S*m 1 *m 2 *m 3 …m n , де S – розмір одного елемента, а m 1 …m n – розміри діапазонів індексів (тобто кількість значень, які може набувати відповідного індексу).
  2. При зверненні до елемента масиву A адреса відповідного елемента обчислюється як B+S*((…(i 1p *m 1 +i 2p)*m 2 +…+i (n-1)p)*m n-1 +i np ), де B - база (адреса початку блоку пам'яті масиву), i kp - значення k-го індексу, приведене до цілого з нульовим початковим зсувом.

Таким чином, адреса елемента із заданим набором індексів обчислюється так, що час доступу до всіх елементів масиву однаково.

Перший елемент масиву, залежно від мови програмування може мати різний індекс. Розрізняють три основні різновиди масивів: з відліком від нуля (zero-based), з відліком від одиниці (one-based) та з відліком від специфічного значення заданого програмістом (n-based). Відлік індексу елемента масивів з нуля більш характерний для низькорівневих мов програмування, проте цей метод був використаний у мовах вищого рівня мовою програмування Сі.

Більш складні типи масивів – динамічні та гетерогенні – реалізуються складніше.

Переваги

  • легкість обчислення адреси елемента за його індексом (оскільки елементи масиву розташовуються один за одним)
  • однаковий час доступу до всіх елементів
  • малий розмір елементів: вони складаються лише з інформаційного поля

Недоліки

  • для статичного масиву - відсутність динаміки, неможливість видалення чи додавання елемента без зсуву інших
  • для динамічного та/або гетерогенного масиву - нижча (порівняно зі звичайним статичним) швидкодія та додаткові накладні витрати на підтримку динамічних властивостей та/або гетерогенності.
  • при роботі з масивом у стилі C (з покажчиками) та за відсутності додаткових засобів контролю - загроза виходу за межі масиву та пошкодження даних

Див. також

Література

  • Вірт Н.Алгоритми та структури даних = Algoritms and data structure. – М.: Світ, 1989. – 360 с. - ISBN 5-03-001045-9
  • Хювен Е., Сеппянен Й.Мир Ліспа. Введення в мову ЛІСП та функціональне програмування. У 2-х т. = Lisp-maailma: Johdatus kieleen ja ohjelmointiin/Пер. з Фінськ. – М.: Світ, 1990. – ISBN 5-03-001935-9
  • Магаріу Н. А.Мова програмування АПЛ. – М.: «Радіо та зв'язок», 1983. – 96 с.
  • Бартеньєв О. В.Сучасні Фортран. - 3-тє вид., Дод. і перероб. - М.: ДІАЛОГ-МІФІ, 2000. - 449 с.

Примітки