Динамические массивы
Наиболее удобным способом рационального
использования оперативной памяти для
хранения массивов данных, размеры
которых не определены или могут
варьироваться в широких диапазонах,
является применение динамических
массивов. При объявлении таких массивов
не указываются границы индексов. Объявив
тип
-
tmas=array
of Real;
можно использовать его для объявления
динамических массивов, например,
-
var
-
A,B,C:tmas;
размеры которых можно задавать и изменять
динамически (по мере необходимости), с
помощью стандартной процедуры SetLength.
Например, при выполненииSetLength(A,3)размер массиваAстанет
равным 3. В дальнейшем с помощью процедурыSetLengthможно увеличить или
уменьшить размер массива. В динамических
массивах для индексации используются
только целые значения и минимальное
значение индекса всегда 0. Минимальное
значение индекса массива определяется
стандартной функциейLow(всегда 0), максимальное значение индекса
— стандартной функциейHigh,
а длина (размер) – стандартной функциейLength(как для открытых
массивов в подпрограммах). При увеличении
размера прежние его элементы сохраняют
свои значения, а новые элементы со
значениями 0 добавляются в конец массива.
При уменьшении размера пропадают
элементы с наибольшими индексами, а
остальные сохраняют свои значения. При
задании нуля в качестве размера массива
занимаемая им память освобождается
полностью.
Объявив двумерные динамические массивы,
например,
-
type
tmatr=array of array of Real;
в подпрограмму можно будет передавать
матрицу (двумерный массив) с произвольным
количеством строк и столбцов. В общем
случае, динамический массив с любым
числом измерений и размерами может
использоваться в качестве фактического
параметра, соответствующего формальному
параметру «открытый массив», причем в
теле подпрограммы для любого его
измерения можно будет найти длину и
максимальное значение индекса (минимальное
всегда равно 0), используя имя формального
параметра и стандартные функции LengthиHigh(для статических
массивов при числе измерений, больше
2, для определения в подпрограмме
диапазонов младших индексов потребуется
использовать имена типов, что снижает
универсальность подпрограммы). Например,
для вычисления суммы элементов 3-мерного
динамического массиваX,
имеющего типtkmn
-
type
-
tmn=array
of array of Integer; -
tkmn=array
of tmn;
подпрограмму можно оформить так
-
procedure
Sum1(const a:array of tmn; out r:Integer); -
var
i,j,k:integer; -
begin
-
r:=0;
-
for
k:=Low(a) to High(a) do -
for
i:=Low(a[0]) to High(a[0]) do -
for
j:=Low(a[0,0]) to High(a[0,0]) do -
r:=r+a[k,i,j];
-
end;
Выделение памяти и указание пределов
изменения индексов по каждому измерению
динамического массива производится в
процессе выполнения программы путем
использования процедуры SetLength(a,n).
Нижняя граница индексов по любому
измерению динамического массива всегда
равна нулю. Наибольший индекс примет
тогда значениеn-1, гдеn-
количество элементов массива, задаваемое
при обращении к процедуреSetLength,
а первый параметр – имя массива. При
выделении памяти под матрицу можно
выполнить следующее обращениеSetLength(b,m,n)если
матрица имеет прямоугольную форму, т.е.
количество элементов во всех строках
одинаково и равноn(m– количество строк матрицы).
Использование динамических массивов
позволяет работать с матрицами, у которых
в каждой строке может быть разное
количество элементов. При выделении
памяти для многомерных массивов (в
частности, для хранения двумерных
матриц) сначала устанавливается длина
его первого измерения, затем второго,
третьего и т.д. Например, выделим память
для хранения элементов треугольной
матрицы.
-
.
. . . . -
var
-
a:array
of array of Real; -
n,l,j:Integer;
-
begin// РАЗДЕЛ ОПЕРАТОРОВ ПРОГРАММЫ
-
ReadLn(n);
-
SetLength(a,n);
-
for
i:=0 to n-1 do -
Setlength(a[i],i+1);
-
.
. . .
. -
end.
При изменении длины уже созданного
динамического массива сначала
резервируется память для размещения
нового массива, затем элементы старого
массива копируются в новый массив, после
чего освобождается память, выделенная
под первоначальный массив.
Для освобождения памяти,
помимо процедуры SetLength,
использовать процедуру Finalize или
идентификатору массива присвоить
значение nil.
Например, для освобождения памяти в
предыдущем примере можно записать
оператор a:=nil
или Finalize(a).
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
- #
- #
- #
- #
- #
- #
- #
- #
- #
- #
- #
ITishnik 9 / 9 / 1 Регистрация: 07.01.2013 Сообщений: 78 |
||||
1 |
||||
Как в динамическом массиве найти наибольшее значение?07.02.2013, 23:45. Показов 1979. Ответов 3 Метки нет (Все метки)
Как в динамическом массиве найти наибольшее значение?
0 |
Programming Эксперт 94731 / 64177 / 26122 Регистрация: 12.04.2006 Сообщений: 116,782 |
07.02.2013, 23:45 |
Ответы с готовыми решениями: как найти в массиве наибольшее , наименьшее , среднее значение Найти максимальное значение элемента на промежутке [a; b] в динамическом массиве. Классы С++ В динамическом массиве найти первый чётный элемент, написать его индекс и значение Как можно убрать последнее значение в динамическом массиве 3 |
Dekio Фрилансер 5845 / 1226 / 499 Регистрация: 23.11.2010 Сообщений: 3,375 Записей в блоге: 1 |
||||
08.02.2013, 00:10 |
2 |
|||
2 |
Заблокирован |
||||
08.02.2013, 11:45 |
3 |
|||
Как в динамическом массиве найти наибольшее значение?
http://codepad.org/VgjhODXT Output: Кликните здесь для просмотра всего текста Не по теме: *std::max_element(a, a + n);
0 |
go 3646 / 1378 / 243 Регистрация: 16.04.2009 Сообщений: 4,526 |
||||
08.02.2013, 14:07 |
4 |
|||
http://codepad.org/u7uuuHd9 Тогда так
http://liveworkspace.org/code/157k0P$0
1 |
Динамические массивы
Наиболее удобным способом рационального
использования оперативной памяти для
хранения массивов данных, размеры
которых не определены или могут
варьироваться в широких диапазонах,
является применение динамических
массивов. При объявлении таких массивов
не указываются границы индексов. Объявив
тип
-
tmas=array
of Real;
можно использовать его для объявления
динамических массивов, например,
-
var
-
A,B,C:tmas;
размеры которых можно задавать и изменять
динамически (по мере необходимости), с
помощью стандартной процедуры SetLength.
Например, при выполненииSetLength(A,3)размер массиваAстанет
равным 3. В дальнейшем с помощью процедурыSetLengthможно увеличить или
уменьшить размер массива. В динамических
массивах для индексации используются
только целые значения и минимальное
значение индекса всегда 0. Минимальное
значение индекса массива определяется
стандартной функциейLow(всегда 0), максимальное значение индекса
— стандартной функциейHigh,
а длина (размер) – стандартной функциейLength(как для открытых
массивов в подпрограммах). При увеличении
размера прежние его элементы сохраняют
свои значения, а новые элементы со
значениями 0 добавляются в конец массива.
При уменьшении размера пропадают
элементы с наибольшими индексами, а
остальные сохраняют свои значения. При
задании нуля в качестве размера массива
занимаемая им память освобождается
полностью.
Объявив двумерные динамические массивы,
например,
-
type
tmatr=array of array of Real;
в подпрограмму можно будет передавать
матрицу (двумерный массив) с произвольным
количеством строк и столбцов. В общем
случае, динамический массив с любым
числом измерений и размерами может
использоваться в качестве фактического
параметра, соответствующего формальному
параметру «открытый массив», причем в
теле подпрограммы для любого его
измерения можно будет найти длину и
максимальное значение индекса (минимальное
всегда равно 0), используя имя формального
параметра и стандартные функции LengthиHigh(для статических
массивов при числе измерений, больше
2, для определения в подпрограмме
диапазонов младших индексов потребуется
использовать имена типов, что снижает
универсальность подпрограммы). Например,
для вычисления суммы элементов 3-мерного
динамического массиваX,
имеющего типtkmn
-
type
-
tmn=array
of array of Integer; -
tkmn=array
of tmn;
подпрограмму можно оформить так
-
procedure
Sum1(const a:array of tmn; out r:Integer); -
var
i,j,k:integer; -
begin
-
r:=0;
-
for
k:=Low(a) to High(a) do -
for
i:=Low(a[0]) to High(a[0]) do -
for
j:=Low(a[0,0]) to High(a[0,0]) do -
r:=r+a[k,i,j];
-
end;
Выделение памяти и указание пределов
изменения индексов по каждому измерению
динамического массива производится в
процессе выполнения программы путем
использования процедуры SetLength(a,n).
Нижняя граница индексов по любому
измерению динамического массива всегда
равна нулю. Наибольший индекс примет
тогда значениеn-1, гдеn-
количество элементов массива, задаваемое
при обращении к процедуреSetLength,
а первый параметр – имя массива. При
выделении памяти под матрицу можно
выполнить следующее обращениеSetLength(b,m,n)если
матрица имеет прямоугольную форму, т.е.
количество элементов во всех строках
одинаково и равноn(m– количество строк матрицы).
Использование динамических массивов
позволяет работать с матрицами, у которых
в каждой строке может быть разное
количество элементов. При выделении
памяти для многомерных массивов (в
частности, для хранения двумерных
матриц) сначала устанавливается длина
его первого измерения, затем второго,
третьего и т.д. Например, выделим память
для хранения элементов треугольной
матрицы.
-
.
. . . . -
var
-
a:array
of array of Real; -
n,l,j:Integer;
-
begin// РАЗДЕЛ ОПЕРАТОРОВ ПРОГРАММЫ
-
ReadLn(n);
-
SetLength(a,n);
-
for
i:=0 to n-1 do -
Setlength(a[i],i+1);
-
.
. . .
. -
end.
При изменении длины уже созданного
динамического массива сначала
резервируется память для размещения
нового массива, затем элементы старого
массива копируются в новый массив, после
чего освобождается память, выделенная
под первоначальный массив.
Для освобождения памяти,
помимо процедуры SetLength,
использовать процедуру Finalize или
идентификатору массива присвоить
значение nil.
Например, для освобождения памяти в
предыдущем примере можно записать
оператор a:=nil
или Finalize(a).
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
- #
- #
- #
- #
- #
- #
- #
- #
- #
- #
- #
ITishnik 9 / 9 / 1 Регистрация: 07.01.2013 Сообщений: 78 |
||||
1 |
||||
Как в динамическом массиве найти наибольшее значение?07.02.2013, 23:45. Показов 1932. Ответов 3 Метки нет (Все метки)
Как в динамическом массиве найти наибольшее значение?
0 |
Programming Эксперт 94731 / 64177 / 26122 Регистрация: 12.04.2006 Сообщений: 116,782 |
07.02.2013, 23:45 |
Ответы с готовыми решениями: как найти в массиве наибольшее , наименьшее , среднее значение Найти максимальное значение элемента на промежутке [a; b] в динамическом массиве. Классы С++ В динамическом массиве найти первый чётный элемент, написать его индекс и значение Как можно убрать последнее значение в динамическом массиве 3 |
Dekio Фрилансер 5845 / 1226 / 499 Регистрация: 23.11.2010 Сообщений: 3,375 Записей в блоге: 1 |
||||
08.02.2013, 00:10 |
2 |
|||
2 |
Заблокирован |
||||
08.02.2013, 11:45 |
3 |
|||
Как в динамическом массиве найти наибольшее значение?
http://codepad.org/VgjhODXT Output: Кликните здесь для просмотра всего текста Не по теме: *std::max_element(a, a + n); 0 |
go 3646 / 1378 / 243 Регистрация: 16.04.2009 Сообщений: 4,526 |
||||
08.02.2013, 14:07 |
4 |
|||
http://codepad.org/u7uuuHd9 Тогда так
http://liveworkspace.org/code/157k0P$0 1 |
Редактировать
В PascalABC.NET рекомендуется использовать динамические массивы. В отличие от статических, они имеют огромное количество методов и операций, просты в создании, заполнении и выводе.
Описание и выделение памяти
Динамический массив описывается так:
begin
var a: array of integer;
end.
Память под динамический массив a выделяется в момент работы программы:
begin
var a: array of integer;
var n := ReadInteger;
a := new integer[n];
end.
Здесь — первое преимущество динамических массивов — в переменной a может храниться массив любого размера, память выделяется в процессе работы программы. Кроме того, выделенная память гарантированно автоматически заполняется нулевыми значениями.
Можно совместить описание и выделение памяти — тип динамического массива выводится автоматически:
begin
var n := ReadInteger;
var a := new integer[n];
end.
Обычно в PascalABC.NET совмещают описание динамического массива, выделение памяти и заполнение значениями. Самый простой способ — заполнить n нулями:
begin
var n := ReadInteger;
var a := |0| * n;
end.
Индексация в динамических массивах и использование статических массивов
Динамические массивы индексируются с нуля — это эффективно. В качестве индексов в динамических массивах могут выступать только целые.
Статические массивы тем не менее иногда удобно использовать — в задачах, где индексы либо символьные, либо по-существу начинаются не с нуля. Например, для подсчёта количества слов на каждую букву может использоваться стаический массив
var a := array ['a'..'z'] of integer;
Заполнение статических массивов — увы — производится в цикле. Кроме того, они не помнят свою длину и передача таких массивов в качестве параметров подпрограмм связана с техническими сложностями 40-летней давности, не нужными начинающим.
Простейшее заполнение
Важную роль играют функции заполнения динамических массивов. Перед заполнением они выделяют для массива память, поэтому в одной строке можно совмещать описание, выделение памяти и заполнение.
Простейшее заполнение — набором значений:
Заполнение диапазоном целых или символьных значений делается с использованием функции Arr:
var a := Arr(1..9);
var b := Arr('a'..'z');
Заполнение определённым значением осуществляется с помощью операции умножения массива на число:
begin
var n := ReadInteger;
var a := |0| * n; // массив из n нулей
end.
Для заполнения можно также использовать функцию ArrFill:
begin
var n := ReadInteger;
var a := ArrFill(n,0); // массив из n нулей
end.
Для заполнения массива случайными значениями следует использовать
begin
var n := ReadInteger;
var a := ArrRandomInteger(n); // по умолчанию значения от 0 до 100
var a1 := ArrRandomInteger(n,1,10); // случайные от 1 до 10
var r := ArrRandomReal(n); // по умолчанию значения от 0 до 10
var r1 := ArrRandomReal(n,2,5); // случайные вещественные от 2 до 5
end.
Не рекомендуется использовать алгоритм для заполнения массива случайными в каждой задаче:
begin
var n := ReadInteger;
var a := new integer[n];
for var i:=0 to n-1 do
a[i] := Random(0,100);
end.
Повторять этот текст в каждой задаче — странно. Для этого есть стандартные функции.
Ввод и вывод элементов массива
Для ввода элементов массива базовых типов используются функции
begin
var n := ReadInteger;
var a := ReadArrInteger(n);
var r := ReadArrReal(n);
var s := ReadArrString(n);
// ...
end.
Стандартная процедура вывода Write или Print выводит значения в массиве в квадратных скобках черезх запятую:
begin
var a := Arr(1..9);
Print(a); // [1,2,3,4,5,6,7,8,9]
end.
Однако лучше всего для вывода воспользоваться методом Print, выводящим все значения в массиве через пробел:
begin
var a := Arr(1..9);
a.Print; // 1 2 3 4 5 6 7 8 9
end.
Не рекомендуется вводить и выводить элементы массива в цикле
begin
var n := ReadInteger;
var a := new integer[n];
for var i:=0 to n-1 do
a[i] := ReadInteger;
end.
Повторять этот текст в каждой задаче — странно. Для этого есть стандартные функции.
Циклы по массиву
Для обработки элементов массива используются следующие циклы:
- Цикл for по индексам (если требуется менять элементв или нужна информация об индексах)
for var i:=0 to a.Length-1 do a[i] *= 2;
- Цикл foreach по элементам (если индексы не видны и мы не меняем массив)
var sum := 0; foreach var x in a do sum += x;
- Цикл foreach по индексам
foreach var i in a.Indices do a[i] += 2;
- Цикл foreach по диапазону индексов
var (K,L) := ReadInteger2; foreach var i in K..L do a[i] := 777;
Пример. Найти количество чётных элементов, стоящих на чётных местах
begin
var a := ArrRandomInteger(10);
a.Println;
var count := 0;
foreach var i in a.Indices do
if i.IsEven and a[i].IsEven then
count += 1;
Print(count);
end.
Методы массива
Массивы содержат большое количество стандартных методов:
a.Length - длина массива
a.Min - минимальный элемент в массиве
a.Max - максимальный элемент в массиве
a.IndexMin - индекс первого минимального элемента в массиве
a.IndexMax - индекс первого максимального элемента в массиве
a.Sum - сумма элементов в числовом массиве
a.Product - произведение элементов в числовом массиве
a.Average - среднее элементов в числовом массиве
a.First - первый элемент в массиве
a.Last - последний элемент в массиве
a.IndexOf(x) - индекс первого значения x или -1 если не найдено
a.Replace(x,y) - заменить в массиве все значения x на y
Кроме того, доступны процедуры
Sort(a) - сортировка элементов по возрастанию
SortDescending(a) - сортировка элементов по убыванию
Reverse(a) - инвертирование элементов массива
Методика. Обращаем внимание, что в методических целях естественно рассказывать, как эти алгоритмы устроены “внутри”.
Но потом следует пользоваться стандартными алгоритмами, а не заставлять учеников во всех задачах использовать рукописные сортировки или рукописный поиск минимума. Например, рекомендуется показать, как накопить сумму элементов массива:
begin
var a := ArrRandomInteger(10);
a.Println;
var sum := 0;
foreach var x in a do
sum += x;
Print(sum);
end.
Здесь следует обратить внимание, что этот алгоритм может быть легко модифицирован в алгоритм нахождения суммы элементов по условию: например, всех чётных элементов:
begin
var a := ArrRandomInteger(10);
a.Println;
var sum := 0;
foreach var x in a do
if x.IsEven then
sum += x;
Print(sum);
end.
Отметим, что заполнение случайными и вывод — это технические части программы, которые делаются в PascalABC.NET в одну строку, позволяя концентрироваться на алгоритме.
Если условие надо накладывать на индексы, то в этом случае (и только в этом случае) следует использовать цикл for по индексам:
begin
var a := ArrRandomInteger(10);
a.Println;
var sum := 0;
for var i:=0 to a.Length-1 do
if i.IsEven then
sum += a[i];
Print(sum);
end.
Для нахождения суммы без условия необходимо использовать стандартный метод a.Sum:
begin
var a := ArrRandomInteger(10);
a.Println;
Print(a.Sum);
end.
Отметим также, что для поиска суммы по условию также имеется короткая однострочная запись. Она требует использование стандартного метода Where с параметром, являющимся лямбда-выражением. Лямбда-выражения мы будем рассматривать далее:
begin
var a := ArrRandomInteger(10);
a.Println;
Print(a.Where(x -> x.IsEven).Sum);
end.
Методика. Поскольку данная запись использована здесь впервые, обращаем внимание на её высокую универсальность: алгоритмы фильтрации и поиска суммы не слиты в один алгоритм, а используются порознь один за другим, что позволяет:
- Лучше читать код (потому что он записан компактно и методами с понятными и очевидными названиями)
- Лучше модифицировать код
- Решать более сложные и более прикладные задачи за одно и то же время урока
Далее лямбда-выражения объясняются подробно и тщательно и используются повсеместно.
Операции с массивами
x in a - возвращает true если значение x содержится в a
a1 + a2 - возвращает массив, образованный слиянием массивов a1 и a2
a1 * n - возвращает массив, состоящий из n раз повторенных значений массива a
Изменение размера динамического массива
Если в процессе работы программы требуется чтобы динамический массив менял свой размер, то следует … пользоваться типом List!
Это — динамический массив с возможностью эффективного измненения размера и рядом дополнительных методов. Основным является методы Add — добавить в конец:
begin
var l := new List<integer>;
l.Add(1);
l.Add(3);
l.Add(5);
l.Print
end.
Для первоначального заполнения списков List используется короткая фунеция Lst:
begin
var l := Lst(1,3,5);
l.Print
end.
При необходимости список List можно преобразовать к динамическому массиву, вызвав метод .ToArray:
begin
var l := Lst(1,3,5);
var a := l.ToArray;
end.
Большинство методов, которые имеются в массивах, есть и в списках List. Поэтому выбор типа List или array of для контейнера при решении задач определяется тем, будет ли данный контейнер расширяться по ходу работы программы.
Вам надо знать размер массива.
Например, если вы создали динамически массив, как показано ниже.
#include <algorithm>
//...
size_t n = 10;
int *a = new int[n];
// заполнение значениями элементов массива
int *max = std::max_element( a, a + n );
if ( max != a + n )
{
std::cout << "The maximum element is equal to " << *max << std::endl;
}
Или итератор можете объявить, используя спецификатор auto
auto max = std::max_element( a, a + n );
В данном конкретном случае нет необходимости проверять, что максимальный элемент найден. Но в общем случае, когда вы априори не знаете, чему равно значение переменной n
, то такую проверку лучше делать.
Чтобы определить позицию найденного элемента, вы, в принципе, можете просто вычесть начало массива из найденного итератора, как, например,
auto pos = max - a;
Однако с точки зрения стиля программирования лучше воспользоваться стандартной функцией std::distance
, объявленной в заголовке <iterator>
, Например,
#include <iterator>
//...
auto = std::distance( a, max );
Это делает ваш код более гибким, так как массив вы можете заменить, например, каким-нибудь стандартным контейнером, который не имеет итераторов прямого доступа, и код все равно будет работать.
Массивы
Переменные можно объединять в массивы. Массив — это совокупность переменных одного типа.
Преимущества:
- Вместо нескольких однотипных переменных используется одна переменная.
- Можно применять групповую обработку элементов массива.
Каждый массив имеет имя — идентификатор. Переменные, входящие в массив, называются элементами массива. Любой элемент массива обозначается переменной с индексом, например, A(5). Другими словами отдельный элемент массива определяется своей позицией (индексом) в массиве. Можно сказать, что массив это именованная совокупность переменных одного типа, которые различаются значениями своих индексов.
С понятием массива связано понятие размерности. Чаще всего используются одномерные массивы (векторы или строки) и двумерные массива (матрицы). Максимальное количество измерений массива — 60.
Примеры массивов
Ежедневная утренняя и вечерняя температура воздуха в течение месяца представляется двумерным массивом из 31 строки и 2 столбцов, а эта же температура в течение года является уже трехмерным массивом 12x31x2.
Перечень десяти дисциплин по каждой из пяти специализаций представляется двумерным массивом из 5 строк и 10 столбцов.
Важно:
- Элементы массива имеют одинаковые характеристики (тип, размер и т.д.).
- Элементы массива могут использоваться во всех конструкциях языка, в которых допускается использование обычных переменных.
- Индекс элемента массива — это число (положительное, отрицательное или 0).
- Количество индексов элемента массива должно соответствовать количеству измерений массива: первый индекс соответствует первому измерению, второй индекс — второму и т.д.
- Для указания индекса можно использовать переменные или выражения. При этом значение выражения округляется до ближайшего целого числа.
- Значение каждого индекса имеет нижнюю и верхнюю границу. Если специально не указано другое значение, нижней границей индекса массива является 0.
- Инструкция Option Base 1, размещенная в области Declarations, устанавливает нижний индекс всех массивов в единицу.
Массив должен быть обязательно объявлен. Синтаксис объявления массива:
Dim varname(subscripts) As type
- varname — имя массива;
- subscripts — индексы измерений массива;
- type — тип элемента массива.
Для каждого индекса измерения ( subscripts ) можно указать нижнюю и верхнюю границы (граничная пара) в виде lower to upper, где обе границы суть целые числа или выражения, результат вычисления которых есть число. Нижняя граница может быть опущена, тогда она предполагается нулевой, если инструкция Option Base не указывает на другое. Индексы каждого измерения отделяются друг от друга запятой. Например, объявление Dim A (1 To 5, 2 To 17) определяет двумерный массив A из пяти строк с индексами от 1 до 5 и 16 столбцов с индексами от 2 до 17, всего 80 элементов. Запись A(3,10) указывает на девятый элемент третьей строки.
Рекомендуется:
- предусматривать такие значения индексов, которые соответствовали бы максимально возможному количеству элементов массива в каждом измерении.
Пример
Создать массив, значение каждого элемента которого равно индексу элемента.
Одномерный массив A имеет восемь элементов с индексами от 0 до 7.
Оператор присваивания значения и оператор распечатки значения записаны на одной строке через двоеточие.
Рис.
4.2.
Оператор присваивания значения и оператор распечатки значения
Динамические массивы
Если в момент объявления массива неизвестен его размер или же в процессе выполнения программы требуется изменить размеры массива, то массив изначально необходимо объявить как динамический. При объявлении динамического массива не указывается его размерность, например, Dim A(). Далее в программе должны быть установлены размеры массива при помощи оператора Redim.
Синтаксис:
ReDim [Preserve] varname (subscripts) [As type]
- Preserve — ключевое слово, позволяющее сохранить существующие элементы массива;
- varname — идентификатор массива;
- subscripts — индексы массива;
- type — тип элементов массива.
Внимание:
- Можно изменить только верхнюю границу индекса массива, Попытка изменения нижней границы индекса приведет к ошибке.
- При переопределении динамического массива без ключевого слова Preserve все ранее определенные элементы массива очищаются. Включение Preserve в оператор ReDim сохраняет существующие элементы массива, если размерность массива увеличивается. Если размерность массива уменьшается, то данные, находящиеся вне границ переопределенного массива теряются.
- Если массив многомерный, то при переопределении массива может быть изменена только верхняя граница последнего измерения.
- Ключевое слово Preserve не может использоваться для изменения количества измерений массива.
- Не используйте оператор Redim для изменения типа элементов массива.
Для определения границ динамического массива используются функции Lbound (индекс нижней границы) и Ubound (индекс верхней границы).
Синтаксис:
Lbound (arrayname [,dimension]) Ubound (arrayname [,dimension])
- arrayname — имя массива,
- dimension — номер измерения массива.
Для рассмотренной выше процедуры оператор Debug.Print Lbound(A,1) распечатает значение 0, а оператор Debug.Print Ubound(A,1) распечатает значение 7.
Пример
В процедуре запрашивается ввод целого числа. Создается массив из четного числа элементов, содержащих четные значения, меньшие или равные введенному числу.
Введенное число нацело делится на два. Результат — количество четных чисел, меньших или равных веденному числу. Если результат является четным числом, количество элементов в переопределяемом массиве равно этому числу; если нечетным числом, то на единицу меньше результата деления.
Введено число 125. Результат выполнения процедуры приведен ниже.
Рис.
4.3.
Создается массив из четного числа элементов, содержащих четные значения, меньшие или равные введенному числу
В процедуре используется условный оператор If, который определяет размер массива b в зависимости от четности результата деления нацело введенного числа. Функция Ubound используется для определения количества элементов созданного массива.
Пользовательский тип
Можно определить данные, состоящие из нескольких логически связанных между собой элементов — структура данных ( User-Defined Data Type ). Каждый пользовательский тип описывается с помощью инструкции Type в области Declarations. Завершение определения пользовательского типа данных — инструкция End Type. Например:
Type sqn sqn_zero As Integer sqn_unity As Integer End Type
Важно:
- Определяемые пользователем типы данных могут включать в себя один или несколько элементов любого типа данных, в том числе массивы и определенные пользователем типы данных.
- Не допускается номеров строк и меток строк в блоке Type…End Type.
- Можно создавать массивы типов данных, определяемых пользователем. При описании массива фиксированного размера с пользовательским типом данных нельзя использовать переменные для задания размерности массива.
- Структура пользовательского типа данных может быть многоуровневой. Обращение к элементу структуры осуществляется при помощи составного имени для исключения неоднозначности. Полное составное имя включает в себя имена структуры и всех подструктур, в которые входит определяемый элемент. Имена подструктур должны следовать в порядке иерархии, т.е. в том же порядке, в котором они определены в структуре.
- Для структур в целом применимы только операторы присваивания, элементы структур можно использовать в выражениях, соответствующих типу элемента.
How can I find out the minimum and maximum values of a certain dynamic array defined by array of Integer
?
ex:
Y: array of integer;
tswaehn
3871 silver badge11 bronze badges
asked Aug 27, 2013 at 12:31
Keaton PennellsKeaton Pennells
1892 gold badges4 silver badges15 bronze badges
The easiest way is to use the built-in functions that perform this service. They are called MinIntValue
and MaxIntValue
and can be found in the Math unit.
uses
Math;
....
TheMin := MinIntValue(TheArray);
TheMax := MaxIntValue(TheArray);
answered Aug 28, 2013 at 7:22
David HeffernanDavid Heffernan
602k42 gold badges1075 silver badges1491 bronze badges
4
There are overloaded functions for this in the unit Math:
function MinValue(const Data: array of Single): Single; overload;
function MinValue(const Data: array of Double): Double; overload;
function MinValue(const Data: array of Extended): Extended; overload;
function MinIntValue(const Data: array of Integer): Integer;
function MaxValue(const Data: array of Single): Single; overload;
function MaxValue(const Data: array of Double): Double; overload;
function MaxValue(const Data: array of Extended): Extended; overload;
function MaxIntValue(const Data: array of Integer): Integer;
since you are using integers you should use MinIntValue and MaxIntValue
answered Aug 28, 2013 at 7:44
1
You have to loop through the array, looking for the desired values, eg:
function TMyClass.GetMinValue: Integer;
var
Idx: Integer;
begin
Result := MyArray[Low(MyArray)];
for Idx := Low(MyArray)+1 to High(MyArray) do
begin
if MyArray[Idx] < Result then
Result := MyArray[Idx];
end;
end;
function TMyClass.GetMaxValue: Integer;
var
Idx: Integer;
begin
Result := MyArray[Low(MyArray)];
for Idx := Low(MyArray)+1 to High(MyArray) do
begin
if MyArray[Idx] > Result then
Result := MyArray[Idx];
end;
end;
answered Aug 27, 2013 at 16:54
Remy LebeauRemy Lebeau
556k31 gold badges460 silver badges774 bronze badges
2
It can be done in a single loop…
function ArrayValRange( somearray: array of integer; var minval: integer; var maxval: integer): boolean;
var
i: integer;
begin
result := false;
if length( somearray) < 1 then
exit;
result := true;
maxval = somearray[ Low(somearray)];
minval = maxval;
for i := Low(somearray)+1 to High(somearray) do
begin
if somearray[i] > maxval then
maxval := somearray[i];
if somearray[i] < minval then
minval := somearray[i];
end;
end;
then
if ArrayValRange( myarray, min, max) then
begin
//do your thing
end;
answered Aug 28, 2013 at 19:29
GrandmasterBGrandmasterB
3,3961 gold badge23 silver badges22 bronze badges
1
Одним из мощнейших средств языка Delphi являются динамические массивы.
Их основное отличие от обычных массивов заключается в том, что они хранятся
в динамической памяти. Этим и обусловлено их название. Чтобы понять,
зачем они нужны, рассмотрим пример:
var
N: Integer;
A: array[1..100] of Integer; // обычный массив
begin
Write(‘Введите количество элементов: ‘);
ReadLn(N);
…
end.
Задать размер массива A в зависимости от введенного пользователем значения
невозможно, поскольку в качестве границ массива необходимо указать константные
значения. А введенное пользователем значение никак не может претендовать
на роль константы. Иными словами, следующее объявление будет ошибочным:
var
N: Integer;
A: array[1..N] of Integer; // Ошибка!
begin
Write(‘Введите количество элементов: ‘);
ReadLn(N);
…
end.
На этапе написания программы невозможно предугадать, какие именно объемы
данных захочет обрабатывать пользователь. Тем не менее, Вам придется
ответить на два важных вопроса:
На какое количество элементов объявить массив?
Что делать, если пользователю все-таки понадобится большее количество
элементов?
Вы можете поступить следующим образом. В качестве верхней границы массива
установить максимально возможное (с вашей точки зрения) количество элементов,
а реально использовать только часть массива. Если пользователю потребуется
большее количество элементов, чем зарезервировано Вами, то ему можно
попросту вежливо отказать. Например:
const
MaxNumberOfElements = 100;
var
N: Integer;
A: array[1.. MaxNumberOfElements] of Integer;
begin
Write(‘Введите количество элементов (не более ‘, MaxNumberOfElements,
‘): ‘);
ReadLn(N);
if N > MaxNumberOfElements then
begin
Write(‘Извините, программа не может работать ‘);
Writeln(‘с количеством элементов больше , ‘ MaxNumberOfElements, ‘.’);
end
else
begin
… // Инициализируем массив необходимыми значениями и обрабатываем
его
end;
end.
Такое решение проблемы является неоптимальным. Если пользователю необходимо
всего 10 элементов, программа работает без проблем, но всегда использует
объем памяти, необходимый для хранения 100 элементов. Память, отведенная
под остальные 90 элементов, не будет использоваться ни Вашей программой,
ни другими программами (по принципу «сам не гам и другому не дам»).
А теперь представьте, что все программы поступают таким же образом.
Эффективность использования оперативной памяти резко снижается.
Динамические массивы позволяют решить рассмотренную проблему наилучшим
образом. Размер динамического массива можно изменять во время работы
программы.
Динамический массив объявляется без указания границ:
var
DynArray: array of Integer;
Переменная DynArray представляет собой ссылку на размещаемые в динамической
памяти элементы массива. Изначально память под массив не резервируется,
количество элементов в массиве равно нулю, а значение переменной DynArray
равно nil.
Работа с динамическими массивами напоминает работу с длинными строками.
В частности, создание динамического массива (выделение памяти для его
элементов) осуществляется той же процедурой, которой устанавливается
длина строк — SetLength.
SetLength(DynArray, 50); // Выделить память для 50 элементов
Изменение размера динамического массива производится этой же процедурой:
SetLength(DynArray, 100); // Теперь размер массива 100 элементов
При изменении размера массива значения всех его элементов сохраняются.
При этом последовательность действий такова: выделяется новый блок памяти,
значения элементов из старого блока копируются в новый, старый блок
памяти освобождается.
При уменьшении размера динамического массива лишние элементы теряютяся.
При увеличении размера динамического массива добавленные элементы не
инициализируются никаким значением и в общем случае их значения случайны.
Однако если динамический массив состоит из элементов, тип которых предполагает
автоматическую инициализацию пустым значением (string, Variant, динамический
массив, др.), то добавленная память инициализируется нулями.
Определение количества элементов производится с помощью функции Length:
N := Length(DynArray); // N получит значение 100
Элементы динамического массива всегда индексируются от нуля. Доступ
к ним ничем не отличается от доступа к элементам обычных статических
массивов:
DynArray[0] := 5; // Присвоить начальному элементу значение 5
DynArray[High(DynArray)] := 10; // присвоить конечному элементу значение
10
К динамическим массивам, как и к обычным массивам, применимы функции
Low и High, возвращающие минимальный и максимальный индексы массива
соответственно. Для динамических массивов функция Low всегда возвращает
0.
Освобождение памяти, выделенной для элементов динамического массива,
осуществляется установкой длины в значение 0 или присваиванием переменной-массиву
значения nil (оба варианта эквивалентны):
SetLength(DynArray, 0); // Эквивалентно: DynArray := nil;
Однако Вам вовсе необязательно по окончании использования динамического
массива освобождать выделенную память, поскольку она освобождается автоматически
при выходе из области действия переменной-массива (удобно, не правда
ли!). Данная возможность обеспечивается уже известным Вам механизмом
подсчета количества ссылок.
Также, как и при работе со строками, при присваивании одного динамического
массива другому, копия уже существующего массива не создается.
var
A, B: array of Integer;
begin
SetLength(A, 100); // Выделить память для 100 элементов
A[0] := 5;
B := A; // A и B указывают на одну и ту же область памяти!
B[1] := 7; // Теперь A[1] тоже равно 7!
B[0] := 3; // Теперь A[0] равно 3, а не 5!
end.
В приведенном примере, в переменную B заносится адрес динамической области
памяти, в которой хранятся элементы массива A (другими словами, ссылочной
переменной B присваивается значение ссылочной переменной A).
Как и в случае со строками, память освобождается, когда количество
ссылок становится равным нулю.
var
A, B: array of Integer;
begin
SetLength(A, 100); // Выделить память для 100 элементов
A[0] := 10;
B := A; // B указывает на те же элементы, что и A
A := nil; // Память еще не освобождается, поскольку на нее указывает
B
B[1] := 5; // Продолжаем работать с B, B[0] = 10, а B[1] = 5
B := nil; // Теперь ссылок на блок памяти нет. Память освобождается
end;
Для работы с динамическими массивами вы можете использовать знакомую
по строкам функцию Copy. Она возвращает часть массива в виде нового
динамического массива.
Не смотря на сильное сходство динамических массивов со строками, у
них имеется одно существенное отличие: отсутствие механизма копирования
при записи (copy-on-write).