free pascal динамические массивы

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

Как создать одномерный динамический массив в Паскале?

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

Динамические массивы в Паскале не имеют заранее определенного размера.

Размер динамических массивов может изменяться.

Динамические массивы в Паскале пример

Пример создания динамического массива в Паскале:

здесь создан новый тип TIntMassiv, это динамический массив, его размер не известен, и переменная данного типа intMassiv.

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

здесь установлен размер два для массива intMassiv.

Отсчет индексов динамического массива в Паскале всегда ведут с нуля.

Присвоим значение первому элементу массива intMassiv, а индекс первого элемента динамического массива всегда равен нулю:

Присвоим значение второму элементу массива intMassiv, а индекс второго элемента динамического массива всегда равен 1:

Изменим длину динамического массива в сторону увеличения:

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

Присвоим значение новому третьему элементу массива intMassiv, а индекс третьего элемента динамического массива всегда равен 2:

Изменим длину динамического массива в сторону уменьшения:

здесь мы уменьшили размер массива на два элемента, при этом последние два элемента существующего массива удалились.

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

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

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

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

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

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

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

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

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

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

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

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

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

da1: array of integer; <одномерный массив>da2: array of array of integer;

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

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

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

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

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

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

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

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

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

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

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

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

A dynamic array is an array whose dimensions are not known at compile-time. The dynamic array type is not the only type providing variable-length arrays, but as of 2018 it is the only one FPC supports.

Contents

usage

concept

A dynamic array’s definition will only allocate space for a pointer. During runtime various routines will ensure convenient usage, but most importantly the syntax how to access array’s elements by placing indices in square brackets, is supported by the compiler (implemented as automatic de-referencing the pointer).

Dynamic arrays’ indices are always non-negative integers starting at zero for the first element. It is not possible to use an enumerative type, any other ordinal type as index, or to change the first element being specified by an index of 1 .

definition

A one-dimensional dynamic array is defined like this:

Note, how no dimensions’ size is specified.

In order to define a multidimensional array, an array itself is specified as the base type.

sizing

The compiler procedure setLength will change a dynamic array’s length, provided there is enough memory.

The procedure allocates memory for as many records of the base type as specified, plus some management data. It then copies all elements of the old incarnation to the new one. New fields, that d > default intrinsic.

Mult > setLength , too.

Val > samples ‘ first dimension are in 0 .. 11 , while val > 0 .. 63 .

One quite useful fact is, the limitation all dimensions have to be of the same size does not apply to dynamic arrays.

initializing

Since FPC 3.0.0 dynamic array types that are not anonymous are automatically equipped with a “constructor” as it might be familiar from object-oriented programming. This lets you unite setLength calls and a series of assignments in one statement:

Of course you can nest arrays as well:

handling

Keep in mind dynamic arrays are pointers. Assigning dynamic array variables to each other does not copy any payload, but just the address. This differs from static arrays’ behavior.

If you want to duplicate data you have to use system . copy .

Only by using copy both arrays can be modified independently.

As stated above, setLength copies data. The highlighted line in the example above is (semantically) equivalent to setLength ( bar , length ( bar )) .

Dynamic arrays are reference counted. Calling setLength ( myDynamicArrayVariable , 0 ) virtually does myDynamicArrayVariable := nil and decreases the reference count. Only when the reference count hits zero, the memory block is released.

Nonetheless, dynamic arrays are finalized automatically. It is not necessary to manually setLength ( … , 0 ) on all your references when the program comes to end, or when leaving a scope in general.

Remember, sizeOf of a dynamic array evaluates to the size of a pointer.

Оцените статью