Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Динамические массивы

Необходимость работы с большими по числу элементов массивами явилась главной причиной для разработки методов работы с дополнительной динамической памятью. Одним из ее основных результатов явился тип данных "указатель", который в двух словах (по два байта каждое) содержит адрес одиночной величины или массива. Этот тип рассмотрен в Главе 3. Указатель на адрес величины a получается путем использования префикса ^ перед ней: ^ a. Для засылки в указатель адреса уже существующей переменной применяют операцию получения адреса переменной (префикс @ перед ее именем или обращение к функции addr()), для обращения к значению переменной, адрес которой хранится в указателе, к нему примеряется операция разыменования, обозначаемая при помощи суффикса ^.

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

В отличие от статических, динамическими называют массивы, размер которых может изменяться во время исполнения программы. С одной стороны, это дает возможность работать с массивами, не ограничивая заранее их размер предельными объёмами. С другой стороны, более рационально используется память вычислительного устройства за счет выделения массивам реально необходимых ее объёмов. Динамические массивы появились в более поздних версиях Паскаля, с появлением Delphi 4. В отличие от статического случая, переменная динамического массива не содержит все элементы массива, а является указателем на область в памяти, где лежат данные элементы, т.е. на первый элемент массива. Использование динамических массивов освобождает от непосредственного использования указателей в простейших случаях работы с динамической памятью.

Для поддержки работы с динамическими массивами в языке программирования должны быть соответствующие операторы, встроенные функции, добавлены новые возможности прежним операторам.

Как и для обычных массивов, описание динамического массива можно задать при помощи предварительного описания типа (указывается имя динамического массива и тип элементов – один из базовых типов), можно без него - непосредственно при описании переменной. Оба вида описания динамического массива подобны описанию статического с той разницей, что не указывается размерность. Для многомерных массивов также допускается вложенность.

Пример 1. Описания динамических массивов:

type
T1DByteArray: Array of Byte;
{Предварительное описание одномерного динамического массива байтовых величин} T1DIntArray = array of integer; {Предварительное описание одномерного динамического массива целых величин} T2DStringArray: Array of Array of string; {Предварительное вложенное описание двумерного динамического массива строковых величин} var
B: T1DByteArray;
{Присвоение переменной B типа одномерного динамического массива байтовых величин T1DByteArray } StringMas: T2DStringArray; {Присвоение переменной StringMas типа двумерного динамического массива строковых величин T2DStringArray } Ar_Int:array of integer; {Непосредственное описание переменной Ar_Int как одномерного динамического массива целых величин}

При объявлении динамического массива место под него не отводится. Переменная динамического массива представляет собой обычный указатель (4 байта) на начало массива. Если массив еще не объявлен либо количество элементов в нем равно 0 (массив пуст), то переменная равна nil.

Если динамический массив не пуст, то его действительный размер всегда на 8 байт больше того пространства памяти, которое занимают его элементы за счет двух дополнительных 4-байтовых величины. Сразу перед данными (по отрицательному смещению -4) в памяти помещается индикатор количества элементов в массиве. Перед ним (по смещению -8) находится счетчик ссылок на массив. Этот счетчик ссылок позволяет иметь несколько переменных, ссылающихся на одни и те же данные в массиве и не заботиться об управлении памятью. Компилятор самостоятельно следит за доступом к данным и при уменьшении счетчика ссылок до 0 освобождает всю память массива. Нумерация элементов в динамических массивах, в отличие от статических, начинается с 0 (как в языке С).

Присваивание динамических массивов вида Array_A:= Array_B по аналогии со статическими возможно, когда:

1) оба массива описаны как динамические и имеют одинаковый тип элементов,

2) размер массива Array_A не превышает (больше либо равен) размеру Array_B, либо Array_A=nil.

При выполнении присваивания динамических массивов они имеют общую память и изменения значений элементов в одном массиве приводят к таким же изменениям и во втором. Если затем над одним из массивов выполняются преобразования, меняющие его структуру, то такая общность значений элементов теряется и связь значений элементов массивов утрачивается. Присвоение динамического массива статическому компилятор запрещает, для этого необходимо использовать поэлементную запись из динамического в статический массив.

Удалить динамический массив можно несколькими способами: применением функции Finalize или установкой нулевой длины массива.

Помимо возможности описания массивов без указания их размерности, в Паскале введены следующие основные функции для работы с динамическими массивами:

1) SetLength (mas, number) - устанавливает новый размер массива mas равным number (число элементов);

2) Length (mas) - возвращает количество элементов в массиве mas;

3) Low (mas) _- возвращает индекс первого элемента в массиве mas (всегда 0 для динамических массивов);

4) High (mas) - возвращает индекс последнего элемента в массиве mas;

5) Copy(mas, start_imdex, number) - возвращает подмножество из number элементов массива mas, начиная с номера start_imdex;

6) Slice - используется при передаче динамического массива в процедуры в качестве открытого массива (open arrays).

Сразу после объявления динамический массив пуст. Для работы с ним необходимо задать число элементов в нем с использованием функции SetLength. При повторном применении SetLength кмассиву его размер изменится. Если новое значение размера больше предыдущего, то а нем сохраняются все прежние значения и в конце добавляются новые нулевые элементы. Если новый размер меньше предыдущего, то массив обрезается до нового размера.

Пример 2. Задание длины массива Ar_Int из примера 1:

SetLength(Ar_Int,10);

В результате в массиве будет задано 10 элементов - от Ar_Int [0] до Ar_Int [9].

Обращение к первому элементу динамического массива Dyn_Ar имеет вид Dyn_Ar[0] или Dyn_Ar[Low (Dyn_Ar)].

Пример 3. Обнуление всех элементов динамического массива Dyn_Ar типа integer: FillChar(Dyn_Ar [0],Length(Dyn_Ar)*sizeof(integer)); При работе с динамическими, как и статическими массивами необходимо следить, чтобы номера элементов в массивах не выходили за текущие их границы. Иначе компилятор прекращает выполнение программы с выдачей сообщения об ошибке.

Пример 4 с использованием динамических массивов А,В и статического С:

var A,B: array of integer;

C: array[0..10] of integer;

Len, i: Integer;

<== предыдущая лекция | следующая лекция ==>
Вопросы для проверки знаний. Работа с двухмерными массивами (матрицами) | Вопросы для проверки знаний. Len:=4; SetLength (A,Len);//Создание дин
Поделиться с друзьями:


Дата добавления: 2014-01-06; Просмотров: 648; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.01 сек.