Главная страница Случайная страница КАТЕГОРИИ: АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
Багатовимірні масиви
У мові 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, Тепер можемо перейти до сортування, що реалізовано в ПП6.19. (див. на СD). Кожен окремий елемент масиву v (ім’я формального параметра, що відповідає lineptr) є вказівником на символи, тому і temp має бути вказівником на символи, щоб їх можна було копіювати один в один.
|