Масиви в параметрах процедур і функцій

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

Функція Average приймає як параметр масив відомої розмірності. Вимога фіксованого розміру для масиву-параметра часто є надмірно стримуючим фактором. Процедура для знаходження середнього значення повинна бути здатна працювати з масивами довільної довжини. Для цієї мети в мову Delphi введені відкриті масиви-параметри. Такі масиви були запозичені розробниками мови Delphi з мови Modula-2.

1. Відкритий масив-параметр описується за допомогою словосполучення array of, при цьому межі масиву опускаються:

2. Усередині підпрограми Average нижня межа відкритого масиву A дорівнює нулю (Low (A) = 0), а ось значення верхньої межі (High (A)) невідомо і з'ясовується тільки на етапі виконання програми.

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

Ось приклад використання функції Average:

4. У другому операторі відкритий масив конструюється в момент виклику функції Average. Конструктор відкритого масиву представляє собою укладений у квадратні дужки список виразів. У виразах можуть використовуватися константи, змінні і функції. Тип виразів повинен бути сумісний з типом елементів масиву. Конструювання відкритого масиву рівносильно створенню і ініціалізації тимчасової змінної.

5. Відкриті масиви можуть бути передані в підпрограми тільки за значенням або як параметри-константи.

6. Деякі бібліотечні підпрограми мови Delphi приймають параметри типу array of const - відкриті масиви констант. Масив, переданий в якості такого параметра, обов'язково конструюється в момент виклику підпрограми і може складатися з елементів різних типів (!). Фізично він складається із записів типу TVarRec, що кодують тип і значення елементів масиву (записи розглядаються нижче). Відкритий масив констант дозволяє емулювати підпрограми зі змінним кількістю різнотипних параметрів і використовується, наприклад, в функції Format для форматування рядка.

Передача параметрів за значенням

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

procedure Test (s: string);

При виклику зазначеної процедури буде створена копія передається їй як параметр рядка s, з якої і буде працювати процедура Test. При цьому всі внесені в рядок зміни жодним чином не позначаться на вихідної змінної s.

Однак це не відноситься до об'єктів. Наприклад, якщо в функцію передається змінна (а точніше екземпляр об'єкта) TStringList, то в даному випадку відбудеться передача за посиланням (навіть якщо це не зазначено явно).

Одномірні і двовимірні статичні масиви. Опис і звернення до елементів. Передача масивів як параметрів в підпрограми. Приклади.

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

де кожен indexType - це порядковий тип, розмірність якого не перевищує 2GB. Для цього можна скористатися ідентифікатором деякого типу (наприклад, boolean або ansichar), однак на практиці зазвичай явно задається поддиапазон цілих чисел. Число елементів масиву в кожному вимірі задається відповідним порядковим типом. Кількість елементів масиву дорівнює добутку кількостей елементів у всіх вимірах.

Словосполучення array of є зарезевірованним. Квадратні дужки після слова array є вимогою синтаксису, а після слова of - тип елементів масиву.

Найпростіший випадок - це одновимірний масив:

Після опису типу можна переходити до визначення змінних і типізованих констант:

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

3. Масив може бути визначений і без опису типу:

4. Щоб отримати доступ до окремого елементу масиву, потрібно в квадратних дужках вказати його індекс, наприклад

5. Оголошені вище масиви є одновимірними, так як мають тільки один індекс. Одномірні масиви зазвичай використовуються для подання лінійної послідовності елементів. Якщо при описі масиву задано два індексу, масив називається двовимірним, якщо n індексів - n-мірним. Двовимірні масиви використовуються для подання таблиці, а n-мірні - для подання просторів. Ось приклад оголошення таблиці, що складається з 5 колонок і 20 рядків:

Те ж саме можна записати в більш компактному вигляді:

Щоб отримати доступ до окремого елементу багатовимірного масиву, потрібно вказати значення кожного індексу, наприклад

або в більш компактній записи

Ці два способи індексації еквівалентні.

Одномірні і двовимірні динамічні масиви. Опис і звернення до елементів. Процедура SetLength, функції Length, Low, High. Приклади.

Одним з найпотужніших засобів мови Delphi є динамічні масиви. Їх основна відмінність від звичайних масивів полягає в тому, що вони зберігаються в динамічної пам'яті. Цим і обумовлено їх назва. Щоб зрозуміти, навіщо вони потрібні, розглянемо приклад:

Задати розмір масиву A в залежності від введеного користувачем значення неможливо, оскільки в якості меж масиву необхідно вказати константні значення. А введене користувачем значення ніяк не може претендувати на роль константи. Іншими словами, таке оголошення буде помилковим:

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

  • На яку кількість елементів оголосити масив?
  • Що робити, якщо користувачеві все-таки знадобиться більшу кількість елементів?

Можна поступити наступним чином. В якості верхньої межі масиву встановити максимально можливе (?) Кількість елементів, а реально використовувати тільки частина масиву. Якщо користувачеві буде потрібно більшу кількість елементів, ніж зарезервовано, то йому можна просто ввічливо відмовити. наприклад:

Таке рішення проблеми є неоптимальним. Якщо користувачеві необхідно всього 10 елементів, програма працює без проблем, але завжди використовує обсяг пам'яті, необхідний для зберігання 100 елементів. Пам'ять, відведена під інші 90 елементів, не використовуватиметься ні Вашою програмою, ні іншими. А тепер уявіть, що всі програми надходять таким же чином. Ефективність використання оперативної пам'яті різко знижується.

Динамічні масиви дозволяють вирішити розглянуту проблему найкращим чином. Розмір динамічного масиву можна змінювати під час роботи програми.

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

array of baseType

Робота з динамічними масивами:

1. Змінна DynArray є посилання на розміщувані в динамічної пам'яті елементи масиву.

2. Спочатку пам'ять під масив НЕ резервується, кількість елементів в масиві дорівнює нулю, а значення змінної DynArray одно nil.

3. Створення динамічного масиву (виділення пам'яті для його елементів) здійснюється процедурою SetLength.

4. Зміна розміру динамічного масиву виробляється цією ж процедурою:

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

При зменшенні розміру динамічного масиву зайві елементи теряютяся.

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

5. Визначення кількості елементів проводиться за допомогою функції Length:

6. Елементи динамічного масиву завжди індексуються від нуля.

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

8. До динамічних масивів, як і до звичайних масивам, застосовні функції Low і High, які повертають мінімальний і максимальний індекси масиву відповідно. Для динамічних масивів функція Low завжди повертає 0.

9. Звільнення пам'яті, виділеної для елементів динамічного масиву, здійснюється установкою довжини в значення 0 або привласненням змінної-масиву значення nil (обидва варіанти еквівалентні):

Однак Вам зовсім необов'язково по закінченні використання динамічного масиву звільняти виділену пам'ять, оскільки вона звільняється автоматично при виході з області дії змінної-масиву (зручно, чи не так!). Дана можливість забезпечується механізмом підрахунку кількості посилань.

10. При присвоєнні одного динамічного масиву іншому, копія вже існуючого масиву не створюється.

У наведеному прикладі, в змінну B заноситься адреса динамічної області пам'яті, в якій зберігаються елементи масиву A (іншими словами, посилальної змінної B присвоюється значення посилальної змінної A).

Як і в випадку з рядками, пам'ять звільняється, коли кількість посилань стає рівним нулю.

11. Для роботи з динамічними масивами ви можете використовувати знайому по рядках функцію Copy. Вона повертає частину масиву у вигляді нового динамічного масиву.

12. Для багатовимірних динамічних масивів:

Тобто пам'ять виділяється для кожної розмірності.

12. Сила-силенна. Опис, завдання, операції над множинами. Приклади.

Безліч - це складовою тип даних для подання набору деяких елементів як єдиного цілого. Область значень цього типу - набір всіляких підмножин, складених з його елементів, включаючи і порожня множина. Всі елементи безлічі належать до деякого порядкового типу, який називається базовим типом множини. Базовий тип не може мати більше, ніж 256 можливих значень. Тому, в якості базового типу вибирають або однобайтові порядкові типи (AnsiChar, Byte, ShortInt, Boolean, WordBool), або їх деяку підмножину.

Для опису множинного типу використовується словосполучення set of, після якого записується базовий тип множини.

Тепер можна оголосити змінну множинного типу:

Можна оголосити безліч і без попереднього опису типу:

· У виразах значення елементів множини вказуються в квадратних дужках: [2, 3, 5, 7], [1..9], [ 'A', 'B', 'C'].

· Якщо безліч не має елементів, воно називається порожнім і позначається як [].

· Приклад ініціалізації множин:

Операції над множинами

При роботі з множинами допускається використання операцій відносини (=, <>,> =, <=), объединения, пересечения, разности множеств и операции in.

Операції порівняння (=, <>). Два безлічі вважаються рівними, якщо вони складаються з одних і тих же елементів. Порядок проходження елементів в порівнюваних множинах значення не має. Два безлічі A і B вважаються нерівними, якщо вони відрізняються по потужності або за значенням хоча б одного елемента.