Введение

Тип структуры данных
структура организации байтов в памяти

В информатике массив — это структура данных, состоящая из набора элементов (значений или переменных) одинакового размера памяти, каждый из которых идентифицируется как минимум одним индексом или ключом массива. Массив хранится таким образом, что положение каждого элемента может быть вычислено из его индексного кортежа с помощью математической формулы. Самый простой тип структуры данных — линейный массив, также называемый одномерным массивом. Например, массив из десяти 32-битных (4 байта) целочисленных переменных с индексами от 0 до 9 может быть сохранен как десять слов по адресам памяти 2000, 2004, 2008, …, 2036 (в шестнадцатеричном виде: 0x7D0, 0x7D4, 0x7D8, …, 0x7F4), так что элемент с индексом i имеет адрес 2000 + (i × 4). Адрес памяти первого элемента массива называется начальным адресом, базовым адресом или адресом основания. Поскольку математическая концепция матрицы может быть представлена как двумерная сетка, двумерные массивы также иногда называют «матрицами». В некоторых случаях термин «вектор» используется в вычислительной технике для обозначения массива, хотя более математически корректным эквивалентом являются кортежи, а не векторы. Таблицы часто реализуются в виде массивов, особенно таблицы поиска; слово «таблица» иногда используется как синоним массива. Массивы — одни из старейших и важнейших структур данных, и используются практически в каждой программе. Они также используются для реализации многих других структур данных, таких как списки и строки. Они эффективно используют логику адресации компьютеров. В большинстве современных компьютеров и многих внешних устройствах хранения память представляет собой одномерный массив слов, индексы которых являются их адресами. Процессоры, особенно векторные, часто оптимизированы для операций с массивами. Массивы полезны главным образом потому, что индексы элементов могут быть вычислены во время выполнения. Среди прочего, эта особенность позволяет одному итеративному оператору обрабатывать произвольное количество элементов массива. По этой причине элементы структуры данных массива должны иметь одинаковый размер и использовать одинаковое представление данных. Набор допустимых индексных кортежей и адреса элементов (и, следовательно, формула адресации элементов) обычно, но не всегда, Индексация массива первоначально выполнялась с помощью самомодифицирующегося кода, а затем с использованием индексных регистров и косвенной адресации. Некоторые мэйнфреймы, разработанные в 1960-х годах, такие как Burroughs B5000 и его преемники, использовали сегментацию памяти для проверки границ индексов аппаратно. Языки ассемблера обычно не имеют специальной поддержки массивов, кроме той, которую предоставляет сама машина. Самые ранние языки программирования высокого уровня, включая FORTRAN (1957), Lisp (1958), COBOL (1960) и ALGOL 60 (1960), поддерживали многомерные массивы, как и C (1972). В C++ (1983) существуют шаблоны классов для многомерных массивов, размерность которых фиксируется во время выполнения. 1 (индексация, начинающаяся с единицы). Первый элемент массива индексируется под номером 1. n (индексация, начинающаяся с n). Базовый индекс массива может быть выбран произвольно. Обычно языки программирования, допускающие индексацию, начинающуюся с n, также допускают отрицательные значения индексов, а в качестве индексов массива могут использоваться другие типы скалярных данных, такие как перечисления или символы. Использование индексации, начинающейся с нуля, является дизайнерским решением многих влиятельных языков программирования, включая C, Java и Lisp. Это приводит к более простой реализации, где индекс относится к смещению от начальной позиции массива, поэтому первый элемент имеет смещение, равное нулю. Массивы могут иметь несколько измерений, поэтому часто для доступа к массиву используется несколько индексов. Например, к элементу во 2-й строке и 4-м столбце двумерного массива A с тремя строками и четырьмя столбцами можно получить доступ с помощью выражения A[1][3] в системе индексации, начинающейся с нуля. Таким образом, для двумерного массива используются два индекса, для трехмерного — три, а для n-мерного — n. Количество индексов, необходимых для указания элемента, называется размерностью, размерностью или рангом массива. В стандартных массивах каждый индекс ограничен определенным диапазоном последовательных целых чисел (или последовательных значений какого-либо перечисляемого типа), а адрес элемента вычисляется по «линейной» формуле на основе индексов.

Одномерные массивы

Одномерный массив (или массив с одним измерением) — это тип линейного массива. Доступ к его элементам осуществляется с помощью одного индекса, который может представлять собой индекс строки или столбца. В качестве примера рассмотрим объявление в C: `int anArrayName[10];`, которое объявляет одномерный массив из десяти целых чисел. Этот массив может хранить десять элементов типа `int`. Индексы этого массива начинаются с нуля и заканчиваются девятью. Например, выражения `anArrayName[0]` и `anArrayName[9]` соответствуют первому и последнему элементам соответственно. Для вектора с линейной адресацией элемент с индексом `i` находится по адресу `B + c · i`, где `B` — фиксированный базовый адрес, а `c` — фиксированная константа, иногда называемая приращением адреса или шагом. Если допустимые индексы элементов начинаются с 0, то константа `B` просто является адресом первого элемента массива. По этой причине язык программирования C определяет, что индексы массива всегда начинаются с 0, и многие программисты называют этот элемент "нулевым", а не "первым". Однако индекс первого элемента можно выбрать, соответствующим образом выбрав базовый адрес `B`. Например, если массив содержит пять элементов, индексированных от 1 до 5, и базовый адрес `B` заменен на `B + 30c`, то индексы тех же элементов будут от 31 до 35. Если нумерация не начинается с 0, то константа `B` может не соответствовать адресу какого-либо элемента.

Векторы допинга

Формула адресации полностью определяется размерностью d, базовым адресом B и инкрементами c1, c2, …, ck. Часто полезно упаковать эти параметры в запись, называемую дескриптором массива, вектором шага или вектором допа. В то время как динамически расширяемые массивы требуют линейного (Θ(n)) времени для вставки или удаления элементов в произвольной позиции. Связные списки позволяют удалять и вставлять элементы в середине за постоянное время, но требуют линейного времени для доступа по индексу. Их использование памяти обычно хуже, чем у массивов, но все равно линейное. Вектор Илиффа является альтернативой многомерной структуре массива. Он использует одномерный массив ссылок на массивы на одно измерение меньше. Для двух измерений, в частности, эта альтернативная структура будет вектором указателей на векторы, по одному для каждой строки (указатель на c или c++). Таким образом, к элементу в строке i и столбце j массива A можно получить доступ с помощью двойной индексации (A[i][j] в типичном обозначении). Эта альтернативная структура позволяет создавать "рваные" массивы, где каждая строка может иметь разный размер — или, в общем случае, где допустимый диапазон каждого индекса зависит от значений всех предшествующих индексов. Она также позволяет избежать одного умножения (на инкремент адреса столбца), заменяя его битовым сдвигом (для индексации вектора указателей строк) и одним дополнительным обращением к памяти (для получения адреса строки), что может быть выгодно в некоторых архитектурах.

Размер

Размерность массива — это количество индексов, необходимых для выбора элемента. Таким образом, если рассматривать массив как функцию на множестве возможных комбинаций индексов, то это размерность пространства, область определения которого является дискретным подмножеством. Следовательно, одномерный массив — это список данных, двухмерный массив — прямоугольная таблица данных, трехмерный массив — блок данных и так далее. Это не следует путать с размерностью множества всех матриц с заданной областью определения, то есть с числом элементов в массиве. Например, массив с 5 строками и 4 столбцами является двумерным, но множество таких матриц образует 20-мерное пространство. Аналогично, трехмерный вектор можно представить в виде одномерного массива размера три.