Язык программирования Перфолента.Net - Официальный сайт

 Язык программирования Перфолента.Net - Официальный сайт.

Поиск   
Главная :: О проекте :: Контакты :: Обратная связь :: Благодарности :: ВходГость

   >   >   >   > 

Если выделить небольшой кусочек текста, то воспроизведение начнется с этого места.


Многомерные массивы и массивы массивов

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


Визуализация двумерного массива

В предыдущей статье мы подробно разобрали работу с одномерными массивами. Однако в реальных задачах часто возникает необходимость хранить данные в виде таблиц, матриц или более сложных структур. Для этих целей в языке Перфолента.Net предусмотрены многомерные массивы и массивы массивов. В этой статье мы рассмотрим, как объявлять, инициализировать, изменять и эффективно использовать такие структуры данных.

В языке Перфолента.Net поддерживаются:

  • многомерный массив — это один массив, содержащий данные нескольких измерений. Объявляются как ТипЭлементов[, … ,], например, Целое[,] или Целое[,,].
  • массив массивов — это несколько вложенных друг в друга одномерных или многомерных массивов, где каждый массив содержит данные одного или нескольких измерений. Объявляются как ТипЭлементов[]…[], например, Целое[][] или Целое[][][];
  • а также их произвольные комбинации, например, Целое[][,][].


Умнику на заметку: Существуют понятия нумерация и индексация. Нумерация начинается с единицы, а индексация начинается с нуля. Индекс элемента на единицу меньше, чем его номер. Для обращения к элементам массивов используются индексы!

 

Многомерные массивы

 

Что такое многомерный массив?

Многомерный массив — это массив, состоящий из нескольких измерений, для доступа к элементам которого необходимо указать несколько индексов, по одному для каждого измерения. Наиболее часто используются двумерные массивы, которые можно представить в виде прямоугольной таблицы со строками и столбцами или матрицы. Трёхмерный массив можно визуализировать как куб или массив таблиц. Четырёхмерный как массив кубов, и так далее.

 

Объявление многомерных массивов

Для создания типа многомерного массива в квадратных скобках указывается соответствующее количество запятых, отделяющих измерения массива. Количество запятых на единицу меньше размерности (количества измерений) массива.

Для объявления многомерного массива (как и одномерного) в языке программирования Перфолента существует оператор Массив (странно, если бы он назывался иначе). Выглядит это так:

// Объявление пустого двумерного массива целых чисел
Массив А[2,3] тип Целое

В этом примере мы создали таблицу данных 3 × 4 (а не 2 × 3) элементов типа Целое, т.к. существует элемент с индексом 0, к которому мы можем обратиться так А[0]. Это значит, что при создании массива мы указываем для каждого измерения верхний индекс, а не количество элементов, как в некоторых других языках программирования. Если вы случайно укажете количество элементов, то ничего страшного не произойдет, у вас просто будет одно лишнее место в измерении массива.

Умнику на заметку: Как и при объявлении переменной, к моменту объявления имя массива не должно быть занято.

В одном операторе мы можем создать несколько массивов с элементами одного типа:

// Объявление двумерного и трёхмерного массивов с элементами одного типа
Массив МатрицаСлов[999,999], КубСлов[99,99,99] тип Строка

Мы так же можем задать элементам массива начальное значение, указав его после знака равно:

Массив А[4,9] тип Целое = 1

В результате в массиве будет 5 × 10 = 50 единиц.

Внимание! Выражение задающее начальное значение будет вычислено столько раз, сколько элементов в массиве! Это позволяет последовательно заполнять элементы разными значениями, например:

ин = 1
// Элементы этих массивов будут заполнены последовательностью
// чисел от 1 до 21 (9+4*3)
Массив аа[8], бб[3,2] = ин++
ин = 1
// Элементами массива тт будут три объекта типа СуперСтрока,
// содержащих фразы Индекс=1, Индекс=2 и Индекс=3  
Массив тт[2] = Новый СуперСтрока("Индекс="+ин++)
// Двумерный массив, в каждой ячейке которого лежат индексы ячейки
ин1=0
ин2=0
Массив м[2,3] = ""+?(ин2%4=3, ин1++, ин1)%3+","+ин2++%4

 

Умнику на заметку: т.к. существуют значения структурного и ссылочного типов, то надо помнить об этом при инициализации массивов. Понятно, что все элементы массива структурного типа будут содержать собственные копии значения. А вот элементы массива ссылочного типа могут содержать ссылки на один и тот же объект или на разные, в зависимости от инициализирующего выражения. Надо просто помнить, что инициализирующее выражение вычисляется столько раз, сколько элементов в создаваемом массиве. Подробнее о структурных и ссылочных типах можно прочитать здесь: Переменные. Объявление переменных, инициализация и их использование..

 

Ещё примеры:

// Создание пустого двумерного массива без элементов
Массив мцп4[,] тип Целое
// Или так
Массив мцп5[-1,-1] тип Целое
// Двумерный массив 3×3 (индексы от 0 до 2 по каждому измерению)
Массив МИ[2,2] тип Строка
// Трёхмерный массив по два элемента на измерение
Массив МАС3М[1,1,1] тип Вещ

 

Вместо создания массивов оператором Массив, можно создавать переменные имеющие тип массива и присваивать им массив, созданный ранее оператором Массив, или создавая массив на лету оператором Новый.

// Объявление переменной двумерного массива целых чисел
// не содержащей массива (даже пустого)
Перем мп0 тип Целое[,] = Неопределено
// Объявление переменной двумерного массива целых чисел
// и присвоение ей ссылки на существующий массив
Перем мп1 тип Целое[,] = мцп4
// Создание пустого двумерного массива без элементов
Перем мп2 тип Целое[,] = Новый Целое[,]
// Или с явным указанием индексов без элементов
Перем мп3 тип Целое[,] = Новый Целое[-1,-1]
// Создание двумерного массива из 11×21 элементов
Перем мп4 тип Целое[,] = Новый Целое[10,20]

 

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

// Объявление переменной двумерного массива целых чисел
// и присвоение ей ссылки на существующий массив
мп10 = мцп4
// Создание пустого двумерного массива без элементов
мп20 = Новый Целое[,]
// Или с явным указанием индексов без элементов
мп30 = Новый Целое[-1,-1]
// Создание двумерного массива из 11×21 элементов
мп40 = Новый Целое[10,20]

Умнику на заметку: Неявное объявление переменных и массивов возможно только в том случае, если в программе отсутствует директива препроцессора #ТребоватьОбъявлениеПеременных.

 

Доступ к элементам многомерного массива

Для доступа к элементам многомерного массива, как и при его создании, используются индексы, разделённые запятыми:

// Создаём двумерный массив строк
Массив МИ[2,2] тип Строка
// Устанавливаем значение элемента
МИ[1,1] = "58с"+33333
ВыводСтроки "МИ[1,1] = "+МИ[1,1]
// Заполняем массив значениями
Для Инд1 = 0 По 2
    Для Инд2 = 0 По 2
        МИ[Инд1, Инд2] = ""+Инд1+","+Инд2
        ВыводСтроки "МИ["+Инд1+","+Инд2+"] = "+МИ[Инд1,Инд2]
    КонецЦикла;
КонецЦикла;

 

Инициализация многомерных массивов

 

Инициализация при объявлении

Многомерные массивы можно инициализировать непосредственно при создании с помощью вложенных инициализаторов:

// Двумерный массив целых чисел
масИниЦел2М = {{0, 1},{0, 2}}
ВыводСтроки "масИниЦел2М[1,1]="+масИниЦел2М[1,1]

 

Инициализация с помощью оператора «Новый»

Как и в предыдущем случае, при создании многомерного массива оператором Новый можно инициализировать массив с помощью вложенных инициализаторов:

// Двумерный массив вещественных чисел 3×3
Перем МАС2М = Новый Вещ[2,2]{
    {0.0, 0.1, 0.2},
    {1.0, 1.1, 1.2},
    {2.0, 2.1, 2.2}
};
// Трёхмерный массив
Перем МАС3М = Новый Вещ[1,1,1]{
    {{0.00, 0.01}, {0.10, 0.11}},
    {{1.00, 1.01}, {1.10, 1.11}}
};

 

Инициализация существующего массива

Уже существующий многомерный массив так же можно инициализировать с помощью вложенных инициализаторов:

// Инициализируем существующий массив набором значений
МАС3М{
    {{0.00, 0.01}, {0.10, 0.11}},
    {{1.00, 1.01}, {1.10, 1.11}}
};

 

Операции с многомерными массивами

 

Изменение размера

Для изменения размера массива используется оператор МассивИзменить:

// Изменение размера двумерного массива
МассивИзменить мЧ25[5,10]
// Разрешается писать с пробелом
Массив Изменить мЧ25[5,10]

Важно: при изменении размера многомерного массива можно изменять только последнюю размерность! Попытка изменить другие размерности приведёт к ошибке:

Попытка
    // Тут будет ошибка, т.к. изменять можно только последнюю размерность массива
    МассивИзменить мЧ25[10,20]
Исключение Ош
    ВыводСтроки "Ошибка при МассивИзменить мЧ25[10,20] - "+Ош.ОписаниеОшибки()
КонецПопытки

 

Производительность при изменении размера

При работе с массивами важно учитывать производительность. Приведём тест, сравнивающий ручное изменение размера массива с использованием оператора МассивИзменить:

// Ручное изменение размера
т0 = ТекущаяУниверсальнаяДатаВМиллисекундах()
мЫ1 = Новый Целое[3]{1,2,3,4}
Для Инд1 = 1 По 20000
    мЫ2 = Новый Целое[Инд1]
    Для Инд2 = 0 По Инд1-1
        мЫ2[Инд2] = мЫ1[Инд2]
    КонецЦикла
    мЫ1 = мЫ2
КонецЦикла
т1 = ТекущаяУниверсальнаяДатаВМиллисекундах()
ВыводСтроки("~"+ Цел(т1-т0) )

// С использованием оператора МассивИзменить
т2 = ТекущаяУниверсальнаяДатаВМиллисекундах()
мЫ1 = Новый Целое[3]{1,2,3,4}
Для Инд1 = 0 По 20000
    // Работает от 4 до 10 раз быстрее, чем то же самое вручную
    МассивИзменить мЫ1[Инд1]
КонецЦикла
т3 = ТекущаяУниверсальнаяДатаВМиллисекундах()
ВыводСтроки("~"+ Цел(т3-т2) )
ВыводСтроки "Соотношение: "+(Вещ(т1-т0)/(т3-т2))+" раз."

 

Очистка массива

Оператор МассивОчистить устанавливает всем элементам значения по умолчанию для заданного типа:

// Очистка нескольких массивов сразу
МассивОчистить мСтр, масИниЦел2М
// Разрешается писать с пробелом
Массив Очистить мСтр, масИниЦел2М
ВыводСтроки "мСтр[0]="+ЕслиНеопределено(мСтр[0],"Элементы очистились...")

 

Удаление массива

Оператор МассивУдалить присваивает переменной массива значение Неопределено.
Если на массив не осталось других ссылок, то он будет удален из памяти при сборке мусора:

// Удаление нескольких массивов сразу
МассивУдалить мСтр, масИниЦел2М
// Разрешается писать с пробелом
Массив Удалить мСтр, масИниЦел2М
ВыводСтроки "мСтр="+?(мСтр Это Неопределено,"Массив НЕ определен!!!","Массив определен!!!")

 

Сравнение многомерных массивов

Массивы в языке Перфолента.Net сравниваются как объекты ИПеречисляемый (IEnumerable), что на практике означает последовательное сравнение друг с другом всех элементов двух массивов:

ма1 = {2,4}
ма2 = {2,4}
ВыводСтроки "ма1=ма2 "+(ма1=ма2)
ВыводСтроки "ма1<>ма2 "+(ма1<>ма2)

 

 

Массивы массивов

 

Помимо многомерных массивов, в языке Перфолента.Net поддерживаются массивы массивов. Их принципиальное отличие: каждый вложенный массив может иметь свой собственный размер. Такая структура удобна, когда данные «рваные» — например, строки таблицы имеют разное количество столбцов.

 

Простой массив массивов

Объявляется через последовательность пустых квадратных скобок в описании типа: Целое[][] — массив, каждый элемент которого является массивом целых чисел. Создаётся такой массив так же, как и обычный, с указанием размеров на каждом уровне:

// Создаём массив из 2 элементов, каждый из которых — массив из 5 целых
Перем МММ2 тип Целое[][] = Новый Целое[1][4]

// Проверим типы на каждом уровне
Для Инд1 = 0 По 1
    ВыводСтроки ""+ТипЗнч(МММ2[Инд1])+" "+Инд1
    Для Инд4 = 0 По 4
        ВыводСтроки ""+ТипЗнч(МММ2[Инд1][Инд4])+" "+Инд1+" "+Инд4
    КонецЦикла
КонецЦикла

// Доступ к элементам — двойные квадратные скобки
МММ2[0][0] = 33
МММ2[1][4] = 55
ВыводСтроки "МММ2[0][0]="+МММ2[0][0]
ВыводСтроки "МММ2[1][4]="+МММ2[1][4]

// Инициализатор: каждый вложенный массив создаётся явно
МММ2{
    Новый Целое[4]{4,5,6,7,8},
    Новый Целое[4]{41,52,63,74,85}
}
Для Инд1 = 0 По 1
    Для Инд4 = 0 По 4
        ВыводСтроки ""+МММ2[Инд1][Инд4]+" "+Инд1+" "+Инд4
    КонецЦикла
КонецЦикла

Обратите внимание: при инициализации каждый вложенный массив задаётся явно через Новый Целое[4]{...}. Вложенные фигурные скобки без оператора Новый для массивов массивов не работают — это принципиальное отличие от инициализации обычных многомерных массивов.

 

Комбинированные массивы массивов: Целое[][,][]

Самое интересное — комбинировать разные типы вложенности. Рассмотрим объявление:

Перем МММ3 тип Целое[][,][] = Новый Целое[1][2,3][4]

Читается это справа налево и означает трёхуровневую структуру:

  1. Целое[][,][] — внешний массив из элементов типа Целое[,][];
  2. Целое[,][] — прямоугольный двумерный массив, каждый элемент которого — Целое[];
  3. Целое[] — обычный одномерный массив целых.

Создание Новый Целое[1][2,3][4] означает: внешний массив из 2 элементов; каждый — двумерный массив размером 3×4; каждый элемент внутри — одномерный массив из 5 целых.

Доступ к элементам идёт через чередование обычных и «многомерных» индексаторов:

// Проверим типы на каждом уровне вложенности
Для Инд1 = 0 По 1
    ВыводСтроки ""+ТипЗнч(МММ3[Инд1])+" "+Инд1
    Для Инд2 = 0 По 2
        Для Инд3 = 0 По 3
            ВыводСтроки ""+ТипЗнч(МММ3[Инд1][Инд2,Инд3])
            +" "+Инд1+" "+Инд2+" "+Инд3
            Для Инд4 = 0 По 4
                ВыводСтроки ""+ТипЗнч(МММ3[Инд1][Инд2,Инд3][Инд4])
                +" "+Инд1+" "+Инд2+" "+Инд3+" "+Инд4
            КонецЦикла
        КонецЦикла
    КонецЦикла
КонецЦикла

// Запись значений
МММ3[0][0,0][0] = 33
МММ3[1][2,3][4] = 55
ВыводСтроки "МММ3[0][0,0][0]="+МММ3[0][0,0][0]
ВыводСтроки "МММ3[1][2,3][4]="+МММ3[1][2,3][4]

Инициализатор такого «трёхуровневого» массива выглядит громоздко, но вполне логично: каждый промежуточный уровень описывается своим оператором Новый с явными размерами и вложенными фигурными скобками:

МММ3{
    Новый Целое[2,3][4]{
        {Новый Целое[4]{14,15,16,17,18},
         Новый Целое[4]{24,25,26,27,28},
         Новый Целое[4]{34,35,36,37,38},
         Новый Целое[4]{44,45,46,47,48}
        },
        {Новый Целое[4]{54,55,56,57,58},
         Новый Целое[4]{64,65,66,67,68},
         Новый Целое[4]{74,75,76,77,78},
         Новый Целое[4]{84,85,86,87,88}
        },
        {Новый Целое[4]{94,95,96,97,98},
         Новый Целое[4]{114,115,116,117,118},
         Новый Целое[4]{224,225,226,227,228},
         Новый Целое[4]{334,335,336,337,338}
        }
    },
    Новый Целое[2,3][4]{
        {Новый Целое[4]{444,445,446,447,448},
         Новый Целое[4]{554,555,556,557,558},
         Новый Целое[4]{664,665,666,667,668},
         Новый Целое[4]{774,775,776,777,778}
        },
        {Новый Целое[4]{884,885,886,887,888},
         Новый Целое[4]{994,995,996,997,998},
         Новый Целое[4]{1114,1115,1116,1117,1118},
         Новый Целое[4]{2224,2225,2226,2227,2228}
        },
        {Новый Целое[4]{3334,3335,3336,3337,3338},
         Новый Целое[4]{4444,4445,4446,4447,4448},
         Новый Целое[4]{5554,5555,5556,5557,5558},
         Новый Целое[4]{6664,6665,6666,6667,6668}
        }
    }
}

// Обход всех четырёх измерений
Для Инд1 = 0 По 1
    Для Инд2 = 0 По 2
        Для Инд3 = 0 По 3
            Для Инд4 = 0 По 4
                ВыводСтроки ""+МММ3[Инд1][Инд2,Инд3][Инд4]
                +" "+Инд1+" "+Инд2+" "+Инд3+" "+Инд4
            КонецЦикла
        КонецЦикла
    КонецЦикла
КонецЦикла

 

Как читать описание типа массива массивов

Описание типа многоуровневого массива в Перфолента.Net читается справа налево. Пустые скобки [] — это одномерный массив; [,] — прямоугольный двумерный; [,,] — трёхмерный и т. д.

Тип

Что означает

Целое[]

одномерный массив целых

Целое[,]

двумерный массив целых

Целое[][]

массив массивов целых

Целое[][,]

массив двумерных массивов целых

Целое[][,][]

массив двумерных массивов, элементы которых — одномерные массивы целых

Практическое правило: при создании через Новый сначала указывается размер первого уровня, затем в квадратных скобках — размеры вложенного многомерного уровня, затем — размеры следующего и так до самого нижнего. Например, Новый Целое[1][2,3][4] создаёт 2 внешних элемента, каждый — матрицу 3×4, каждый её элемент — массив из 5 целых.

 

 

Заключение

Многомерные массивы и массивы массивов в языке Перфолента.Net предоставляют мощные возможности для работы с табличными и многомерными данными. Язык поддерживает как обычные многомерные массивы, так и массивы массивов произвольной вложенности, включая комбинированные типы вида Целое[][,][].

Основные возможности включают:

  • Объявление массивов любой размерности и вложенности;
  • Инициализацию при создании и заполнение существующих массивов;
  • Изменение размера (с ограничением на последнюю размерность);
  • Очистку и удаление массивов.

При работе с массивами массивов помните: каждый вложенный массив — это отдельный объект, который нужно создать явно, а описание типа вида Целое[][,][] читается справа налево.




К началу статьи


Предыдущая статья:
Индексаторы объектов. Срезы массивов и строк.

Вернуться в раздел:
Синтаксис языка Перфолента
  Поддержи проект!

Вы можете поддержать разработку Перфоленты, перечислив любую удобную сумму, которая пойдет на развитие языка и поддержку инфраструктуры сайта.

  Новости:
      27.09.2026 Добавлена статья про многомерные массивы и массивы массивов
      23.06.2026 В редакторе блок-схем ДРАКОН появилась поддержка языка программирования Перфолента.Net
      21.01.2026 На сайт добавлена статья "Конструируем класс. События"
      20.01.2026 Опубликован новый релиз 0.4.18.0_NY языка программирования Перфолента.Net
      29.12.2025 Анонс: Новая возможность - разрабатываем веб-сайты, веб-приложения и веб-API на Перфоленте!
      07.06.2025 Небольшие дополнения к документации на сайте - описание атрибута поля &Атомарное
      09.05.2025 На сайте опубликован релиз 0.4.16.0_SE дистрибутива языка программирования Перфолента.Net
      27.04.2025 Дополнена статья про циклы
      04.01.2025 Опубликован новый релиз дистрибутива языка программирования Перфолента.Net версии 0.4.15.0_CE
      23.09.2024 Опубликована новая статья: "Конструируем класс. Делегаты."
      30.08.2024 Опубликован новый релиз дистрибутива языка программирования Перфолента.Net версии 0.4.14.0
       Все новости