Содержание
Массивы
Теперь мы приступаем к изучению массива — наиболее широко используемого структурированного типа данных, предназначенного для хранения нескольких однотипных элементов.
Описание массива
Для того, чтобы задать массив, необходимо в разделе описания переменных (var) указать его размеры и тип его компонент.
Общий вид описания (одномерного) массива:
Чаще всего это трактуется так:
array[<левая_граница> .. <правая_граница>] of <тип_компонент>;
Например, одномерный (линейный) массив, состоящий не более, чем из 10 целых чисел, можно описать следующим образом:
Нумерация
Нумерация компонент массива не обязана начинаться с 1 или с 0 — вы можете описывать массив, пронумерованный любыми целыми числами. Необходимо лишь, чтобы номер последней компоненты был больше, чем номер первой:
Собственно говоря, нумеровать компоненты массива можно не только целыми числами. Любой порядковый тип данных (перечислимый, интервальный, символьный, логический, а также произвольный тип, созданный на их основе) имеет право выступать в роли нумератора. Таким образом, допустимы следующие описания массивов:
type Char2 = 'a', 'c' .. 'z'; { отсутствует символ «b» }
var a1 : array [Char] of Integer; { 256 компонент }
a2 : array [Char2] of Integer; { 25 целых компонент }
a3 : array [ShortInt] of Real; { 256 вещественных компонент }
Общий размер массива не должен превосходить 65 520 байт. Следовательно, попытка задать массив a4 : array[Integer] of Byte; не увенчается успехом, поскольку тип Integer покрывает 65 536 различных элементов. А про тип LongInt в данном случае лучше и вовсе не вспоминать.
Тип компонент массива может быть любым:
var a4 : array[10 .. 20] of Real; — массив из компонент простого типа
a5 : array[0 .. 100] of Record1; — массив из записей2
a6 : array[-10 .. 10] of ^String; — массив из указателей3 на строки
a7 : array[-1 .. 1] of Text; — массив из файловых переменных4
a8 : array[1 .. 100] of array[1 .. 100] of Char; — двумерный массив (массив векторов)
Для краткости и удобства многомерные массивы можно описывать и более простым способом:
var a9 : array[1 .. 10, 1 .. 20] of Real; — двумерный массив 10 х 20
a10 : array[Boolean, -1 .. 1, Char, -10 .. 10] of Word; — четырёхмерный массив 2 х 3 х 256 х 21
Общее ограничение на размер массива — не более 65 520 байт — сохраняется и для многомерных массивов. Количество компонент многомерного массива вычисляется как произведение всех его «измерений». Таким образом, в массиве а9 содержится 200 компонент, а в массиве а10 — 32 256 компонент.
Описание переменных размерностей
Если ваша программа должна обрабатывать матрицы5 переменных размерностей (скажем, N по горизонтали и М по вертикали), то вы столкнётесь с проблемой изначального задания массива, ведь в разделе type не допускается использование переменных. Следовательно, самый логичный, казалось бы, вариант
a : array[1 .. m, 1 .. n] of Real;
придётся отбросить.
Если на этапе написания программы ничего нельзя сказать о предполагаемом размере входных данных, то не остаётся ничего другого, как воспользоваться техникой динамически распределяемой памяти (см. лекцию 10).
Предположим, однако, что вам известны максимальные границы, в которые могут попасть индексы обрабатываемого массива. Скажем, N и М заведомо не могут превосходить 100. Тогда можно выделить место под наибольший возможный массив, а реально работать только с малой его частью:
var a : array[1 .. nmax, 1 .. nmax] of Real;
m, n : Integer;
Обращение к компонентам массива
Массивы относятся к структурам прямого доступа. Это означает, что возможно напрямую (не перебирая предварительно все предшествующие компоненты) обратиться к любой интересующей нас компоненте массива.
Доступ к компонентам линейного массива осуществляется так6:
<имя_массива>[<индекс_компоненты>]
а многомерного — так:
<имя_массива>[<индекс>, ... ,<индекс>]
Правила употребления индексов при обращении к компонентам массива таковы:
- Индекс компоненты может быть константой, переменной или выражением, куда входят операции и вызовы функций.
- Тип каждого индекса должен быть совместим с типом, объявленным в описании массива именно для соответствующего «измерения»; менять индексы местами нельзя.
- Количество индексов не должно превышать количество «измерений» массива. Попытка обратиться к линейному массиву как к многомерному обязательно вызовет ошибку. А вот обратная ситуация вполне возможна: например, если вы описали N-мерный массив, то его можно воспринимать как линейный массив, состоящий из (N-1)–мерных массивов.
Примеры использования компонент массива:
a3[-10] := 2.5;
a3[i + j] := a9[i, j];
a10[x > 0, Sgn(x), '!', Abs(k * 5)] := 0;
Задание массива константой
Для того чтобы не вводить массивы вручную во время отладки программы (особенно, если они имеют большую размерность), можно пользоваться не только файлами7. Существует и более простой способ, когда входные данные задаются прямо в тексте программы при помощи типизированных констант.
Если массив линейный (вектор), то начальные значения для компонент этого вектора задаются через запятую, а сам вектор заключается в круглые скобки.
Многомерный массив также можно рассматривать как линейный, предполагая, что его компонентами служат другие массивы. Таким образом, для системы вложенных векторов действует то же правило задания типизированной константы: каждый вектор ограничивается снаружи круглыми скобками.
Исключение составляют только массивы, компонентами которых являются величины типа Char. Такие массивы можно задавать проще: строкой8 символов.
Примеры задания массивов типизированными константами:
type mass = array[1 .. 3, 1 .. 2] of Byte;
const a : array[-1 .. 1] of Byte = (0, 0, 0); {линейный}
b : mass = ((1, 2), (3, 4), (5, 6)); {двумерный}
s: array[0 .. 9] of Char = '0123456789';
Замечание: Невозможно задать неименованную или нетипизированную константу, относящуюся к типу данных array.