setlength в паскале что это
Динамические массивы в Паскале
Как создать одномерный динамический массив в Паскале?
Динамические массивы в Pascal
Динамические массивы в Паскале не имеют заранее определенного размера.
Размер динамических массивов может изменяться.
Динамические массивы в Паскале пример
Пример создания динамического массива в Паскале:
здесь создан новый тип TIntMassiv, это динамический массив, его размер не известен, и переменная данного типа intMassiv.
Размер динамического массива неизвестен, но для работы с таким массивом размер надо установить. Устанавливают размер динамического массива в Паскаль с помощью функции SetLength
здесь установлен размер два для массива intMassiv.
Отсчет индексов динамического массива в Паскале всегда ведут с нуля.
Присвоим значение первому элементу массива intMassiv, а индекс первого элемента динамического массива всегда равен нулю:
Присвоим значение второму элементу массива intMassiv, а индекс второго элемента динамического массива всегда равен 1:
Изменим длину динамического массива в сторону увеличения:
здесь мы увеличили размер массива на один элемент, он добавился в конец существующего массива.
Присвоим значение новому третьему элементу массива intMassiv, а индекс третьего элемента динамического массива всегда равен 2:
Изменим длину динамического массива в сторону уменьшения:
здесь мы уменьшили размер массива на два элемента, при этом последние два элемента существующего массива удалились.
После окончания работы с динамическим массивом освобождаем память, выделенную для него:
Динамический или статический?
Традиционно в языке Паскаль используются статические массивы вида
Границы массива обязательно задаются константами, и изменить размер массива в ходе работы программы нельзя. Зато можно сделать индекс не только целого, но и, скажем, символьного или перечислимого типа. Например, для подсчета встречаемости каждой буквы можно использовать массив
и работать с ним в свое удовольствие:
Недостатки таких массивов известны: если заранее неизвестно, сколько элементов потребуется использовать, то под массив отводится память максимального размера. В итоге в большинстве случаев мы «запасаемся впрок», а иногда и этого «запаса» оказывается недостаточно. Именно поэтому такие массивы называются статическими: их размер статичен и должен быть задан на этапе компиляции программы.
В Delphi Object Pascal появились динамические массивы, размер которых можно не только задавать, но и менять по ходу работы программы. Именно об этих массивах и о преимуществах их использования пойдет речь далее.
Описываются они предельно просто:
Чтобы задать размер такого массива, следует вызвать процедуру SetLength:
Как мы видим, размер такого массива может быть задан переменной, которая вычисляется по ходу работы програмы (в данном случае ее значение вводится).
Чтобы определить размер динамического массива, следует вызвать функцию Length: Length(a) возвращает размер динамического массива.
Динамические массивы представляются в памяти ссылками. Это означает, что любая переменная типа «динамический массив» является указателем на непрерывный участок динамической памяти. Первоначально этот указатель хранит nil, а вызов SetLength(a) выделяет под данные массива блок динамической памяти и записывает в a адрес этого блока памяти.
Во-вторых, при присваивании динамических массивов обе пременные b1 и b2 указывают на один участок динамической памяти, поэтому изменение элемента в массиве b1 приводит и к изменению массива b2:
Еще в Delphi имеются так называемые открытые массивы. К сожалению, они по внешнему виду очень похожи на динамические:
Смысл в том, что при вызове на место открытого массива можно подставлять статический массив любого размера. Но запись array of integer используется в совершенно другом смысле! Поэтому мы полностью отказались от открытых массивов в PascalABC.NET. Пользуйтесь динамическими массивами!
Посмотрим теперь, что нового появилось в динамических массивах в PascalABC.NET.
1. Динамические массивы можно инициализировать при описании:
2. Выделять память под динамическе массивовы можно с помощью операции new:
3. Как мы упомянули, динамический массив в PascalABC.NET является классом, а значит, он имеет методы и свойства:
5. Ввиду структурной эквивалентности типов для динамических массивов их можно передавать в подпрограмму следующим образом:
Напомним, что открытые массивы в PascalABC.NET отсутствуют!
6. Для динамических массивов (в отличие от статических) можно использовать цикл foreach (при условии, что мы осуществляем доступ к элементам только на чтение):
И, наконец, скажем несколько слов про двумерные динамические массивы. Они моделируются как массивы массивов.
Следующий код иллюстрирует создание двумерного динамического массива размера m на n:
Динамические массивы
Описание динамического массива
Тип динамического массива конструируется следующим образом:
array of тип элементов (одномерный массив)
array [,] of тип элементов (двумерный массив)
и т.д.
Переменная типа динамический массив представляет собой ссылку. Поэтому динамический массив нуждается в инициализации (выделении памяти под элементы).
Выделение памяти под динамический массив
Для выделения памяти под динамический массив используется два способа. Первый способ использует операцию new в стиле вызова конструктора класса:
Данный способ хорош тем, что позволяет совместить описание массива и выделение под него памяти:
Второй способ выделения памяти под динамический массив использует стандартную процедуру SetLength :
Элементы массива при этом заполняются значениями по умолчанию.
Процедура SetLength обладает тем преимуществом, что при ее повторном вызове старое содержимое массива сохраняется.
Инициализация динамического массива
Можно инициализировать динамический массив при выделении под него память операцией new:
Инициализацию динамического массива в момент описания можно проводить в сокращенной форме:
При этом происходит выделение памяти под указанное справа количество элементов.
Инициализация одномерного массива проще всего осуществляется стандартными функциями Seq. которые выделяют память нужного размера и заполняют массив указанными значениями:
var a := Arr(1,3,5,7,8); // array of integer
var s := Arr(‘Иванов’,’Петров’,’Сидоров’); // array of string
var b := ArrFill(777,5); // b = [777,777,777,777,777]
var r := ArrRandom(10); // заполнение 10 случайными целыми в диапазоне от 0 до 99
В таком же стиле можно инициализировать массивы массивов:
var a := Arr(Arr(1,3,5),Arr(7,8),Arr(5,6)); // array of array of integer
Длина динамического массива
Динамический массив помнит свою длину (n-мерный динамический массив помнит длину по каждой размерности). Длина массива (количество элементов в нем) возвращается стандартной функцией Length или свойством Length :
Для многомерных массивов длина по каждой размерности возвращается стандартной функцией Length с двумя параметрами или методом GetLength(i) :
Ввод динамического массива
После выделения памяти ввод динамического массива можно осуществлять традиционно в цикле:
for var i:=0 to a.Length-1 do
read(a[i]);
Ввод динамического массива можно осуществлять с помощью стандартной функции ReadSeqInteger:
var a := ReadSeqInteger(10);
При этом под динамический массив выделяется память нужного размера.
Вывод динамического массива
Процедура write выводит динамический массив, заключая элементы в квадратные скобки и разделяя их запятыми:
var a := Arr(1,3,5,7,9);
writeln(a); // [1,3,5,7,9]
n-мерный динамический массив выводится так, что каждая размерность заключается в квадратные скобки:.
var m := new integer[3,3] ((1,2,3),(4,5,6),(7,8,9));
writeln(m); // [[1,2,3],[4,5,6],[7,8,9]]
Динамический массив можно выводить также методом расширения Print или Println:
При этом элементы по умолчанию разделяются пробелами, но можно это изменить, задав параметр Print, являющийся разделителем элементов. Например:
выводит каждый элемент на отдельной строке.
Массивы массивов
Если объявлен массив массивов
то его инициализацию можно провести только с помощью SetLength :
Для инициализации такого массива с помощью new следует ввести имя типа для array of integer :
type IntArray = array of integer;
var с: array of IntArray;
.
c := new IntArray[5];
for i := 0 to 4 do
c[i] := new integer[3];
Инициализацию массива массивов можно также проводить в сокращенной форме:
Присваивание динамических массивов
Динамические массивы одного типа можно присваивать друг другу, при этом обе переменные-ссылки будут указывать на одну память:
Следует обратить внимание, что для динамических массивов принята структурная эквивалентность типов: можно присваивать друг другу и передавать в качестве параметров подпрограмм динамические массивы, совпадающие по структуре.
Чтобы одному динамическому массиву присвоить копию другого массива, следует воспользоваться стандартной функцией Copy :
Передача динамического массива в подпрограмму
Динамический массив обычно передается в подпрограмму по значению, т.к. сама переменная уже является ссылкой:
procedure Squares(a: array of integer);
begin
for var i:=0 to a.Length-1 do
a[i] := Sqr(a[i]);
end;
begin
var a := Arr(1,3,5,7,9);
Squares(a);
end.
Динамический массив передается по ссылке только в одном случае: если он создается или пересоздается внутри подпрограммы. В частности, это необходимо делать если для динамического масива внутри подпрограммы вызывается SetLength:
procedure Add(var a: array of integer; x: integer);
begin
SetLength(a,a.Length+1);
a[a.Length-1] := x;
end;
begin
var a := Arr(1,3,5,7,9);
Add(a,666);
writeln(a);
end.
Клуб программистов
Delphi programming
Подписаться на рассылку:
SetLength
Изменяет размер строки или размер динамического массива
Описание:
Процедура SetLength изменяет размер строки, одномерного динамического массива или многомерного динамического массива
При изменении размера строки StringToChange, новый размер NewLength может быть меньше, такой же или больше, чем у существующей строки. Во всех случаях размер задается в символах и в любом случае создается новая строка.
Динамический массив объявляется без задания фиксированной длины. Такое объявление создает лишь указатель. Даже многомерный динамический массив создается в виде одного неинициализированного указателя.
Dim1Length указывает на левое (внешнее) измерение массива.
Пример кода:
var
myString : string;
onPos : Integer;
begin
// Set up my string to hold a well known phrase
myString := ‘The cat sat on the mat’;
// Display this string
ShowMessage(‘»‘+myString+'»‘);
// Now make the string longer
SetLength(myString, 25);
// Display this string again
// Note that the string is prematurely terminated
// This is because the extra characters are not initialised
ShowMessage(‘»‘+myString+'»‘);
// Display this string again
// Now the string is fully initialised
ShowMessage(‘»‘+myString+'»‘);
end;
Результат выполнения:
Описание:
var
singleArray : array of string;
multiArray : array of array of Word;
i, j : Integer;
begin
// Set the length of a single dimension array
SetLength(singleArray, 4);
// Now fill it up : note that dynamic arrays start at 0
ShowMessage(‘Single dimensional array :’);
for i := 0 to 3 do
begin
singleArray[i] := ‘String ‘+IntToStr(i);
ShowMessage(‘Element ‘+IntToStr(i)+’ = ‘+singleArray[i]);
end;
// Set the length of a multi dimensional array
SetLength(multiArray, 2, 3);
// Now fill it up
ShowMessage(‘Multi-dimensional array :’);
for i := 0 to 1 do
for j := 0 to 2 do
begin
multiArray[i,j] := i + j;
ShowMessage(‘Element ‘+IntToStr(i)+’,’+IntToStr(j)+’ = ‘+
IntToStr(multiArray[i,j]));
end;
end;
Учебный модуль для работы с массивами
Почему? По ряду причин.
Со времени последней статьи о массивах в PascalABC.NET произошел ряд изменений. Во-первых, появились двумерные динамические массивы, которые описываются следующим образом:
Инициализируются такие массивы либо с помощью операции new:
Цикл по такому массиву осуществляется следующим образом:
Заметим, что модуль лишь облегчает выполнение часто встречающихся операций, но не содержит подпрограмм решения учебных задач типа вставки, удаления, сдвига элементов и пр.
Рассмотрим несколько примеров его использования.
Пример 1. Создание случайного одномерного массива и его сортировка.
Здесь функция CreateRandomIntegerArray выделяет память из 10 элементов под динамический массив и заполняет его случайными значениями в диапазоне от 0 до 99, процедура WritelnArray выводит массив на экран, разделяя данные пробелами и процедура Sort сортирует массив по возрастанию.
Приведем этот же пример с небольшими вариациями.
Пример 1a.
Здесь используется автоопределение типа при инициализирующем присваивании, массив заполняется случайными числами в диапазоне от 1 до 9, затем его элементы выводятся, разделяясь запятыми, затем он сортируется по убыванию.
Пример 1б.
Наконец, рассмотрим пример заполнения и вывода двумерного динамического массива. Чтобы были понятны типы, опишем его явно.
Пример 2.
Здесь создается матрица 4 на 5, заполняется случайными вещественным значениями (по умолчанию от 0 до 10) и выводится на экран, при этом количество знаков после десятичной точки равно 2.
Это практически все возможности небольшого модуля Arrays, облегчающего выполнение рутинных операций с динамическими массивами.