Студопедия

Главная страница Случайная страница

КАТЕГОРИИ:

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






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






У мові C++ передбачено багатовимірні масиви. Розглянемо завдання перетворення дня місяця в день року і навпаки. Наприклад, перше березня є 60-м днем не високосного року та 61-м днем високосного року. Введемо дві функції для виконання цих перетворень: Day_of_year перетворить місяць і день у точно призначений день року, а Month_day – день року на місяць і день. Остання функція повертає два значення, тому аргументи місяця і дня повинні бути вказівниками:

Month_day(1977, 60, & m, & d)

надає m значення 3 і d значення 1 (1 березня).

Обидві ці функції потребують інформаційну таблицю, яка вказує кількість днів у кожному місяці. Кількості днів у місяці високосного і не високосного років розрізняються, тому простіше подати їх у вигляді двох рядків двовимірного масиву, ніж намагатися простежувати під час обчислень, що саме відбувається в лютому. Такий масив і функції, які виконують ці перетворення, визначено в ПП6.15. (див. на СD). Двовимірний масив day_tab повинен бути зовнішнім для Day_of_year і Month_day, оскільки він використовується обома цими функціями.

За визначенням у мові C++ двовимірний масив є одновимірним масивом кожен елемент якого є масивом. Тому індекси записуються як day_tab [ i ][ j ], а не day_tab [ i, j ], як у більшості мов. Використовувати двовимірні масиви можна так само, як і в інших мовах. Елементи зберігаються по рядках, тобто в разі звернення до елементів у порядку їх розміщення в пам’яті найшвидше змінюється найбільш правий індекс.

Масив ініціалізується за допомогою списку початкових значень, розташованих у фігурних дужках {}, де кожен рядок двовимірного масиву ініціалізується відповідним підсписком. Так у початок масиву day_tab поміщено стовпчик із нулями для того, щоб номери місяців змінювалися від 1 до 12, а не від 0 до 11.

Якщо двовимірний масив передається функції, то опис відповідного аргументу функції повинен містити кількість стовпчик. Кількість рядків несуттєва, оскільки фактично передається вказівник. У розглядуваному випадку це вказівник об’єктів, що є масивами з 13 чисел типу int. Отже, для передачі масиву day_tab функції F опис у F мав би вигляд:

F(day_tab)

int day_tab[2][13];

{...}

Кількість рядків несуттєва, тому опис аргументу в F міг би бути таким: int day_tab [][13]; або int (* day_tab)[13];. Це означає, що аргумент є вказівником масиву з 13 цілих значень. Круглі дужки тут потрібні, оскільки квадратні дужки [] мають вищий рівень старшинства, ніж операція *; Без круглих дужок () int *day_tab [13]; є описом масиву з 13 вказівників на цілі.

6.8. Масиви вказівників (вказівники на вказівники)

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

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

Процес сортування містить три кроки: читання всіх рядків уведення, їх сортування та виведення у правильній послідовності.

Розділимо програму на кілька функцій і виділимо провідну фун­кцію, яка керує роботою всієї програми. Спочатку розглянемо струк­туру даних і їх введення або виведення. Функція, яка здійснює введення, повинна одержувати символи кожного рядка, запам’ятовувати їх і будувати масив вказівників рядків. Вона також має підраховувати кількість введених рядків, потрібну для сортування і виведення, за умови кінцевої кількості рядків. У разі надто великої їх кількості можна повертати деяку кількість рядків, відмінну від можливої, наприклад – функція виведення (див. ПП6.16 на СD) повинна друкувати рядки в тому порядку, в якому вони з’являються в масиві вказівників. Символ нового рядка наприкінці кожного рядка видаляється, тому він не буде впливати на порядок сортування рядків (ПП6.17 див. на СD).

Опис char *lineptr [ lines ]; повідомляє, що lineptr є масивом з lines елементів, кожен з яких – вказівник на змінні типу char. Це означає, що lineptr [ i ] – вказівник на символи, а * lineptr [ i ] зчитує символ. Сам lineptr є масивом, який передається функції WriteLines,
і ним можна оперувати як вказівником. Тоді функція WriteLines матиме вигляд, як у ПП6.18. (див. на СD). Спочатку * lineptr вказує на перший рядок, кожне збільшення пересуває вказівник на наступний рядок, у той час, як nlines спадає до нуля.

Тепер можемо перейти до сортування, що реалізовано в ПП6.19. (див. на СD). Кожен окремий елемент масиву v (ім’я формального параметра, що відповідає lineptr) є вказівником на символи, тому і temp має бути вказівником на символи, щоб їх можна було копіювати один в один.


Поделиться с друзьями:

mylektsii.su - Мои Лекции - 2015-2024 год. (0.007 сек.)Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав Пожаловаться на материал