Массивы (Array) и работа с ними




Массив — это регулярная структура данных, объявляемая специальной конструкцией языка

Array [ диапазоны индексов ] of ТипКомпонентов

Наиболее часто массив используют для хранения значений векторов, например:

VAR

V: Array [ 1..3 ] of Real;

объявляя тем самым структуру из трех значений типа Real, проиндексированных заданным диапазоном целых чисел (V[1], V[2] и V[3]). Если индексация компонентов (элементов) массива задается числовым диапазоном, как в приведенном примере, то надо соблюдать лишь два требования: во-первых, диапазон не должен принадлежать типу LongInt, т.е. он обязан «уместиться» максимум в типе Word, a во-вторых, произведение количества компонентов массива, задаваемого диапазоном индексов, на размер компонента в байтах, не может превышать 65520 байт (почти 64K). Последнее требование является общим не только для всех массивов, но и для прочих структур данных. Таким образом, могут быть описаны массивы {132}

Array [9..99] of Char; { массив из 91 элемента }

Array [-10.. 10] of LongInt; { массив из 21 элемента }

Это очень удобно, так как позволяет не заботиться о приведении индексов к диапазону 1..N, как, например, приходится поступать при работе с Фортраном или некоторыми версиями Бейсика.

В общем случае ничто не обязывает объявлять диапазон индексов массива числами. В качестве индексов можно использовать любые перечислимые типы, как встроенные, так и вводимые. Индексы могут задаваться по-прежнему диапазоном, а если диапазон соответствует всему типу, то можно вместо него просто записать имя этого перечислимого типа:

TYPE

Monthtype = (January, February, March, April, May);

ComplectType = Array [ MonthType ] of Word;

SpringType = Array [ March..May ] of Word;

VAR

Complect: ComplectType; { пять элементов типа Word }

Spring: SpringType; { три элемента типа Word }

Alpha: Array [ 'A'..'z'] of Char;

Switch: Array [Boolean] of Byte; { два элемента }

Элементы массивов будут индексироваться значениями заданных перечислимых типов или их диапазонов: Complect [January] — первый, a Spring[May] — последний элементы в своих массивах; аналогичен смысл обращений Alpha [ 'А' ] и Switch [True].

Рассмотренные массивы — одномерные, т.е. такие, у которых компоненты — скаляры. Разрешено объявлять массивы массивов:

TYPE

VectorType = Array [ 1..3 ] of Real; { вектор }

MatrixType = Array [ 1..10] of VectorType; { матрица10x3 }

Описание типа двумерного массива MatrixType могло быть записано по-другому:

TYPE

MatrixType = Array [ 1..10] of Array [ 1..3 ] of Real;

или как

MatrixType = Array [ 1..10, 1..3 ] of Real;

Последний вариант наиболее наглядно представляет описание матрицы. Количество измерений формально не ограничено, но сумма размеров всех компонентов массива не должна превосходить 64K. {133} Каждое измерение совершенно не зависит от остальных, и можно объявлять массивы с разными индексами:

VAR

M: Array [ -10..0, 'A'..'C', Boolean ] of Byte;

Эквивалентная запись:

M: Array [-10..0] of

Array [ 'A'..'C' ] of

Array [Boolean] of Byte;

Интересно, что тип элемента массива M зависит от числа указанных при нем индексов. Так,

M[0] — массив-матрица типа Array['A'..'C',Boolean] of Byte,

М[0, 'B'] — вектор типа Array[Boolean] of Byte,

M[0, 'B', False] — значение типа Byte.

Если будут использоваться различные уровни «детализации» многомерных массивов, то надо будет позаботиться о совместимости по типу. Так, при приведенном выше описании массива M нельзя реально поставить подмассив M[0] в оператор присваивания, так как это не по правилам совместимости. Надо переписать объявление типа примерно так:

TYPE

ArrayBType = Array[Boolean] of Byte;

ArrayCType = Array ['A'..'C' ] of ArrayBType;

ArrayMType = Array [-10..0] of ArrayCType;

VAR

B: ArrayBType;

C: ArrayCType;

M: ArrayMType;

и лишь после этого будут разрешены присваивания вида

M[ -1 ]:= C;

B:= M[ -1, 'A' ];

Подобные вопросы совместимости можно обойти, используя приведение типов, а также специальную процедуру Move Турбо Паскаля, но это будет не повышением эффективности программы, а скорее свидетельством непродуманного объявления типов в ней.

Турбо Паскаль позволяет записывать индексы не через запятую, а как бы изолировано:

M[ -3, 'B', True ] эквивалентно M[ -3 ][ 'B' ][ True ] {134}

Компонентом массива может быть не только другой массив, но и запись, и указатель, и какой-либо другой тип. Если R — массив записей (RECORD), то доступ к полю каждой записи производится после указания индекса:

R[ i ].ПолеЗаписи

В памяти ПЭВМ массивы хранятся как сплошные последовательности компонентов, причем быстрее всего изменяется самый «дальний» индекс, если их несколько. В примере задания стартового значения многомерному массиву (см. разд. 5.2.2) порядок перечисления элементов (без учета скобок) соответствует порядку размещения значений в памяти. Адрес начала массива в памяти соответствует адресу его первого элемента (элемента с минимальными значениями индексов).

Турбо Паскаль имеет специальный режим компиляции, задаваемый ключом $R. Если вся программа или фрагмент ее компилировался в режиме {$R+}, то при обращении к элементам массивов будет проверяться принадлежность значения индекса объявленному диапазону, и в случае нарушения границ диапазона программа прервется с выдачей ошибки 201 (Range check Error). Напротив, в режиме {$R-} никаких проверок не производится, и некорректное значение индекса извлечет «как ни в чем не бывало» какое-нибудь значение — но, увы, не принадлежащее данному массиву. Обычно программу отлаживают в режимах $R+, а эксплуатируют при режиме $R-. Это несколько уменьшает размер ЕХЕ-файла и время его выполнения.

К двум совместимым массивам A и B применима только операция присваивания:

A:= B;

которая копирует поэлементно массив B в массив A.

Всевозможные математические действия над массивами (матрицами) необходимо реализовывать самим или использовать специальные библиотеки (например, Turbo Numeric Toolbox).

Для совместимости с другими версиями Паскаля Турбо Паскаль допускает использование составных символов (. и.) вместо квадратных скобок:

M[ 0 ] эквивалентно M(. 0.)

Кроме того, ключевое слово Array в описаниях массивов может предваряться зарезервированным словом PACKED (упакованный, сжатый): {135}

VAR

X: PACKED Array [ 1..100 ] of Real;

В Турбо Паскале данные и так хранятся максимально плотно, и слово PACKED практически игнорируется. Мы рекомендуем избегать его включения в тексты программ.

В завершение отметим одну особенность компилятора Турбо Паскаля. Для многих языков программирования справедливо правило: работа с элементом массива занимает больше времени, чем со скалярной переменной (надо вычислять местоположение элемента в памяти). Если индексы при обращении к элементу задаются переменными или выражениями, то это верно и для Турбо Паскаля. Но если индекс элемента задается константой, то скорость обращения к нему будет максимальной, потому что компилятор в этом случае вычислит расположение элемента еще на этапе компиляции программы.



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2022-11-01 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: