Рейтинг@Mail.ru

Массивы Delphi XE7

Автор: Alex. Опубликовано в Программирование . просмотров: 27330

Рейтинг:  5 / 5

Звезда активнаЗвезда активнаЗвезда активнаЗвезда активнаЗвезда активна
 

Ни для кого не секрет, что Delphi XE7 получил улучшения в языке Object Pascal для работы с массивами. В этой статье мы разберёмся, что же появилось нового и пробежимся по уже имеющимся возможностям по работе с массивами.

Объявление и инициализация массива

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

program Project1;
 
{$APPTYPE CONSOLE}
 
{$R *.res}
 
uses
   System.SysUtils;
 
type
   TIntArray = array of integer;
 
var
   elem: integer;
   dynElem1: TIntArray;
   dynElem2: TArray<integer>;
   i, j: integer;
 
   //Статический массив.
   statArray1: array[0..3] of integer = (0, 1, 2, 3);
   //Статический двумерный массив.
   statArray2: array[0..1] of array[0..2] of integer = ((0, 1, 2), (10, 11, 12));
   //Динамический одномерный массив.
   dynArray1: array of integer = [0, 1, 2, 3];
   //Динамический одномерный массив (инициализация будет ниже).
   dynArray2: array of integer;
   //Динамический двумерный массив.
   dynArray3: array of TIntArray = [[0, 1, 2, 3], [10, 11, 12]];
   //Динамический двумерный массив.
   dynArray4: array of array of integer = [[0, 1, 2, 3], [10, 11, 12]];
   //Динамический одномерный массив.
   dynArray5: TArray<integer> = [0, 1, 2, 3];
   //Динамический двумерный массив.
   dynArray6: TArray<TArray<integer>> = [[0, 1, 2, 3], [10, 11, 12]];
 
begin
   try
      WriteLn('Одномерный статический массив statArray1:');
      for elem in statArray1 do
         WriteLn(elem);
      WriteLn('Двумерный статический массив statArray2:');
      for elem in statArray2 do
         Writeln(elem);
      WriteLn('Одномерный динамический массив dynArray1:');
      for elem in dynArray1 do
         Writeln(elem);
      WriteLn('Одномерный динамический массив dynArray2:');
      dynArray2 := [7, 8, 9]; //Инициализация динамического массива.
      for elem in dynArray2 do
         Writeln(elem);
      dynArray2 := []; //Удаляем все элементы массива.
      WriteLn('Массив dynArray2 после очистки:');
      for elem in dynArray2 do
         Writeln(elem);
      WriteLn('Двумерный динамический массив dynArray3:');
      for dynElem1 in dynArray3 do
         for elem in dynElem1 do
            Writeln(elem);
      WriteLn('Двумерный динамический массив dynArray4:');
      for i := 0 to Length(dynArray4) - 1 do
         for j := 0 to Length(dynArray4[i]) - 1 do
         Writeln(dynArray4[i][j]);
      WriteLn('Одномерный динамический массив dynArray5:');
      for elem in dynArray5 do
         Writeln(elem);
      WriteLn('Двумерный динамический массив dynArray6:');
      for dynElem2 in dynArray6 do
         for elem in dynElem2 do
            Writeln(elem);
      ReadLn;
   except
      on E: Exception do
         Writeln(E.ClassName, ': ', E.Message);
   end;
end.

Как видно из кода, при объявлении многомерного массива при помощи конструкций «array of T», позже возникают проблемы с чтением массива в цикле «for in do». Приходится либо ходить по массиву с помощью цикла «for to do» (см. массив dynArray3) либо объявлять тип дочернего массива (см. массив dynArray2). Гораздо удобнее объявлять тип массива с помощью шаблона «TArray<T>». При объявлении многомерного массива таким способом при чтении можно использовать циклы «for in do» и «for to do».

Что касается смешанных массивов, то такие массивы удалось инициализировать в одну строку только в случае, когда динамический массив находится внутри статического, но не наоборот:

var
   //Статический массив внутри динамического.
   //Инициализировать такой массив в одну строку не удаётся.
   multiArray1: array of array[0..1] of integer;
   //Динамический массив внутри статического.
   multiArray2: array[0..1] of array of integer = ([1, 2, 3], [10, 20, 30, 40]);

Конкатенация массивов, вставка и удаление элементов

Теперь с массивами можно работать так же, как и со строками, при условии, что массивы динамические и одного типа. Доступны функции Concat, Insert и Delete, а также оператор +.

Вот пример использования функции Concat:

var
   dynArray1: TArray<integer> = [0, 1, 2, 3];
   dynArray2: TArray<integer> = [4, 5, 6];
   dynArray3: array of integer = [0, 1, 2];
begin
   //Сложение двух массивов одного типа.
   dynArray1 := Concat(dynArray1, dynArray2); //Результат будет [0, 1, 2, 3, 4, 5, 6]
   //Добавление к массиву двух элементов.
   dynArray3 := Concat(dynArray3, [3, 4]); //Результат будет [0, 1, 2, 3, 4]. 
end;

Тоже самое можно записать с помощью оператора +:

var
   dynArray1: TArray<integer> = [0, 1, 2, 3];
   dynArray2: TArray<integer> = [4, 5, 6];
   dynArray3: array of integer = [0, 1, 2];
begin
   //Сложение двух массивов одного типа.
   dynArray1 := dynArray1 + dynArray2; //Результат будет [0, 1, 2, 3, 4, 5, 6]
   //Добавление к массиву двух элементов.
   dynArray3 := dynArray3 + [3, 4]; //Результат будет [0, 1, 2, 3, 4].
end;

А вот примеры использования функций Insert и Delete:

var
   dynArray1: TArray<integer> = [0, 1, 2, 3];
   dynArray2: TArray<integer> = [4, 5, 6];
   dynArray3: array of integer = [0, 1, 2];
   dynArray4: array of integer = [0, 1, 2, 4, 5];
begin
   //Вставляем элементы массива dynArray2 внутрь массива dynArray1.
   Insert(dynArray2, dynArray1, 2); //Результат будет [0, 1, 4, 5, 6, 2, 3]
   //Вставляем в массив dynArray3 два элемента.
   Insert([100, 200], dynArray3, 1); //Результат будет [0, 100, 200, 1, 2]
   //Вставляем один элемент в массив dynArray4.
   Insert(700, dynArray4, 3); //Результат будет [0, 1, 2, 700, 4, 5]
   //Удаляем два элемента из массива.
   Delete(dynArray4, 1, 2); //Результат будет [0, 700, 4, 5];
end;

Копирование массивов, изменение размера и другие возможности

Остальные замечательные функции для работы с массивами остались без изменений. Это Copy, Length, SetLength, Slice и функции для работы с многомерными массивами, такие как DynArrayBounds и DynArrayClear. Вот ещё несколько примеров по работе с массивами:

var
   bound: TBoundArray;
   dynArray1: TArray<integer> = [0, 1, 2, 3];
   dynArray2: TArray<integer>;
   dynArray3: TArray<TArray<integer>>;
begin
   //Копирование 2-х элементов массива.
   dynArray2 := Copy(dynArray1, 1, 2); //Результат будет [1, 2]
   //Копирование массива начиная с элемента с индексом 1 и до конца.
   dynArray2 := Copy(dynArray1, 1); //Результат будет [1, 2, 3]
   //Копирование массива целиком.
   dynArray2 := Copy(dynArray1); //Результат будет [0, 1, 2, 3]
   //Устанавливаем размер двумерного массива.
   SetLength(dynArray3, 10, 5);
   //Получение размерности двумерного массива.
   //Результат будет [9, 4] - максимальное значение для каждой размерности массива.
   bound := DynArrayBounds(Pointer(dynArray3), TypeInfo(TArray<TArray<integer>>));
end;

Результат нововведений в Object Pascal

О новых возможностях по работе с массивами в Delphi можно сказать следующее. Разработчики сделали отличное улучшение, работать с массивами теперь станет намного удобнее. Остаётся только пожелать, чтобы язык продолжил развиваться в лучшую сторону. Будем ждать очередных фишек.

Tags: Массивы Delphi Delphi Учебники по программированию

Комментарии   

Yoko
0 #1 Yoko 09.03.2021 16:49
Hello,
как создать и инициализировать массив битовых изображений *.bmp, *.jpg, затем вывести в TImage c помощью событий TTimer, В любом гиф-редакторе это делается на раз и два. В Делфи проблема!
Цитировать
Alex
0 #2 Alex 09.03.2021 19:11
Цитирую Yoko:
Hello,
как создать и инициализировать массив битовых изображений *.bmp, *.jpg, затем вывести в TImage c помощью событий TTimer, В любом гиф-редакторе это делается на раз и два. В Делфи проблема!

Для gif в Дельфи есть класс TGIFImage, но если прямо нужно засовывать картинки в массив, то можно использовать коллекцию TObjectList, в которой будут храниться ссылки на объекты TImage.
Цитировать

Добавить комментарий