Главная » Free Pascal » Статические и динамические массивы языка Free Pascal

0

Free Pascal так же, как и Object Pascal, поддерживает массивы двух категорий. Первую из них составляют традиционные массивы Паскаля, при объявлении кото- рых в явном или косвенном виде указываются конкретные границы изменения ка- ждого индекса:

const

k=5; q=6;

type

mat_q_k = array [1..q,1..k] of integer;

var

sa1: array [3..10] of byte;  // явное задание границ sa2: mat_q_k;               // косвенное задание границ

В ряде алгоритмических языков приняты соглашения о минимальном значении каждого индекса — в C и C++ индексы отсчитываются от 0, в Фортране — от 1, в Бейсике минимальной границей индекса можно управлять (оператор OPTION BASE). Паскаль допускает в качестве минимальных индексов любые значения порядковых данных. И ими могут быть не только числа, но и, например, символы:

var

ch: array [‘A’..’Z’] of integer; str: string;

begin

inc(ch[str[j]]);

Приведенный фрагмент наиболее простым способом позволяет подсчитать час- тоту появления тех или иных букв в обрабатываемом тексте.

Существует несколько вариантов для объявления многомерных массивов. На- пример, целочисленная матрица sa2, содержащая q строк и k столбцов, может быть включена в текст программы еще одним из следующих описаний:

var

sa2: array [1..q,1..k] of integer;

или

var

sa2: array [1..q][1..k] of integer;

или

var

sa2: array [1..q] of array [1..k] of integer;

В языке Free Pascal для обозначения традиционных массивов используется термин "статические массивы", хотя он не совсем точно описывает логику выде- ления памяти для их хранения. Дело в том, что традиционные массивы в зависимо- сти от места их определения делятся на глобальные и локальные. Глобальные мас- сивы описываются в одном из разделов объявлений головной программы. В отличие от них описания локальных массивов встречаются внутри функций или подпро- грамм. Для хранения глобальных массивов компилятор выделяет память перед на- чалом работы программы и чистит ее (числовые массивы заполняются нулями, а строковые — пустыми строками). Глобальные массивы хранятся в памяти до окон- чания работы программы и доступны в любой программной единице (функции или подпрограмме). В отличие от этого память для хранения локальных массивов вы- деляется во время работы программы в тот момент, когда вызывается та или иная программная единица. Эта память не чистится и доступна только в рамках той программной единицы, где она объявлена. При возврате из программной единицы память из-под локальных массивов освобождается. Поэтому локальные массивы появляются в оперативной памяти динамически, и термин "статический" в такой ситуации не очень удачен.

Вторую категорию составляют действительно динамические массивы, объявле- ние которых не содержат указания о границах изменения индексов:

var

da1: array of integer;          {одномерный массив} da2: array of array of integer; {двумерный массив}

Так как объявление динамического массива не сопровождается указанием о длине, то компилятор выделяет для каждого динамического массива (глобального или локального) по 4 байта. В них хранится указатель на начало значений элемен- тов динамического массива. В начальный момент значения всех таких указателей равны 0, что соответствует "пустым" динамическим массивам (ситуация напомина- ет стратегию распределения памяти под строки типа AnsiString).

Фактическое выделение памяти под динамические массивы производится только во время работы программы путем вызова процедуры SetLength (дослов- но — установить длину):

SetLength(da1,100);

Такое обращение эквивалентно "статическому" описанию вида:

da1: array [0..99] of integer;

Индексы динамических массивов всегда отсчитываются от 0, поэтому в об- ращении к процедуре SetLength кроме имени динамического массива задается ко- личество элементов. Память, впервые выделяемая динамическому массиву, всегда чистится.

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

Для выделения памяти под двумерный динамический массив к процедуре Set- Length обращаются с тремя параметрами, задавая количество строк и количество столбцов:

SetLength(da2,4,6);

Такое обращение эквивалентно "статическому" описанию вида:

da2: array [0..3, 0..5] of integer;

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

К дополнительным средствам досрочного возврата памяти, занятой элементами динамического массива, относятся следующие способы:

da1 := Nil;       {прямая засылка нуля в указатель}

da2 := Nil;

или

SetLength(da1,0); {косвенная засылка нуля в указатель}

SetLength(da2,0);

или

Finalize(da1);    {финальное освобождение ресурсов}

Finalize(da2);

Источник: Кетков, Ю. Л., Свободное программное обеспечение. FREE PASCAL для студентов и школьников, Ю. Л. Кетков, А. Ю. Кетков. — СПб.: БХВ-Петербург, 2011. — 384 с.: ил. + CD-ROM — (ИиИКТ)

По теме:

  • Комментарии