Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
1 (7).doc
Скачиваний:
23
Добавлен:
12.05.2015
Размер:
376.32 Кб
Скачать

Обробка масивів

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

Типовим способом доступу до елементів масиву у мовах програмування є звертання за індексами. РБНФ-нотація звертання до елемента масиву за індексом у С/С++ має вид:

елемент_масиву = ім’я”[“ індекс ”]” { ”[ “індекс”]”}.

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

arr[4], d[4] [5], а[і], m[і+5] [2].

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

int m[3], *p;

p = &m[0]; // або p = m.

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

Операції адресної арифметики:

  • Інкрементування / декрементування вказівників (“++“ / “--“). Значеннявказівника збільшується (зменшується) на кількість байт, що визначається типом, на який він вказує. Після виконання відповідної операції покажчик вказуєна наступний(попередній) елемент масиву.

  • Скорочене додавання / віднімання цілого числа (“+=“ / “-=“). Значеннявказівника збільшується (зменшується) на кількість байт, яка необхідна для розміщення заданого числа об’єктів, на які посилається покажчик. Після виконання відповідної операції покажчик зміщується вперед (назад) на задану кількість елементів масиву.

  • Додавання / віднімання цілого числа (“+“ / “-“). Задає логічне зміщення вперед (назад) на кількість байт, яка необхідна для розміщення заданого числа об’єктів, на які посилається покажчик.

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

Наприклад,

float m[7], n,*р1,*р2;

р1 = &m[0];

р2 = m;

р1 += 5; // зміщення вперед на 4 об’єкта (дійсних числа)

р1 --; // перехід до попереднього елемента масиву

р2 ++; // перехід до наступного елемента масиву

cout<<*(р2+3)<<“\n”; // покажчик-зміщення вперед на 5 об’єктів (дійсних чисел)

cout<<*(р1-2)<<“\n”; // покажчик-зміщення назад на 3 об’єкта (дійсних числа)

р1 -= 1; // зміщення назад на 1 об’єкт (дійсне число)

n = р1 - р2; // зміщення між елементами, на які вказують mPtr1 і mPtr2

Таким чином у С/С++ при роботі з елементами масиву мають місце дві інтерпретації покажчика, розрізнити які в тексті програми можна тільки в контексті використання покажчика:

  1. покажчик як посилання на окрему змінну(цій традиційній інтерпретації відповідає операція непрямого звернення за вказівником*p);

  2. покажчик на пам'ятьз відносною адресацією від поточного положення (підтримується операціями адресної арифметики).

Покажчик на масив можна індексувати точно так само, як і масив: при цьому компілятор перетворює індексацію в арифметику покажчиків. Наприклад, звернення до елемента масиву m[3] перетворюється в *(m +3). Тому будь-яке з присвоювань

*m = 2.4;

m [0] = 2.4;

*(m+0) = 2.4;

*р1 = 2.4;

p1[0] = 2.4;

*(р1+0) = 2.4;

виконує одну й ту ж дію: присвоює початковому елементу масива m значення 2.4.

Слід зазначити, що між ім'ям масиву і покажчиком на масив існує одна відмінність: покажчик - це змінна, тому можна написати рtr1 = m або рtr1++; але ім'я масиву не є змінною, і записи на зразок m = рtr1 або m ++ не допускаються.

Оскільки багатовимірні масиви в мові C/С++ - це масиви масивів, тобто масиви, елементами яких, у свою чергу, є масиви, то при оголошенні таких масивів в оперативній пам'яті створюється кілька різних об'єктів (виділяється пам'ять під них):

  • покажчик на двовимірний масив (його ім'я співпадає з іменем масиву);

  • масив покажчиків, кожен із яких містить адресу масиву-рядка вихідного двовимірного масиву;

  • двовимірний масив даних базового типу.

Наприклад, при виконанні оголошення двовимірного масиву int arr[4][3] в програмі створюється покажчик arr, який визначає в пам'яті місце розташування першого елемента масиву і, крім того, є покажчиком на масив з чотирьох покажчиків, кожен з яких містить адресу одновимірного масиву, що представляє собою рядок вихідного двовимірного масиву і складається з трьох елементів типу int (рис. 1).

arr

arr [0]

arr [0] [0]

arr [0] [1]

arr [0] [2]

arr [1]

arr [1] [0]

arr [1] [1]

arr [1] [2]

arr [2]

arr [2] [0]

arr [2] [1]

arr [2] [2]

arr [3]

arr [3] [0]

arr [3] [1]

arr [3] [2]

Рис. 1 Розподіл пам'яті для двовимірного масиву

Доступ до елементів масиву покажчиків здійснюється у формі arr[2] або *(arr+2), до елементів двовимірного масиву чисел типу int - у формі arr[1][2] або еквівалентних їй *(*(arr +1) +2) і (*(arr +1))[2] . Слід враховувати, що з точки зору синтаксису мови С/С++ покажчик arr і покажчики arr[0], arr[1], arr[2], arr[3] є константами і їх значення не можна змінювати під час виконання програми.

Розміщення тривимірного масиву відбувається аналогічно. Так, наприклад, оголошення float mas[3][4][5] породжує в програмі, окрім самого тривимірного масиву з 60 чисел типу float, масив з чотирьох покажчиків на тип float, масив з трьох покажчиків на масив покажчиків на float і покажчик на масив масивів покажчиків на float.

Оскільки елементи багатовимірних масивів розташовуються в пам'яті підряд по рядках, то такий порядок дає можливість звертатися до будь-якого елементу багатовимірного масиву, використовуючи адресу його початкового елемента і тільки один індексний вираз. Наприклад, звернення до елементу arr[1][2] можна здійснити за допомогою покажчика ptr, оголошеного у формі int *ptr = arr[0], як звернення ptr[5].

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]