10 · Массивы
Индексирование массивов
Одного имени массива недостаточно, когда нужно прочитать конкретное значение или изменить часть таблицы: для этого служит индексирование — запись имени с индексами в квадратных скобках. Полная запись содержит индекс на каждое измерение, неполная выбирает область; сохранение её в переменную создаёт независимую копию.
Формы записи
Формы различаются числом индексов и тем, задан ли индекс одним значением или диапазоном TO. Одиночный индекс выбирает координату, диапазон сохраняет измерение с выбранными границами.
<массив>[<индекс>]<массив>[<индекс 1>, <индекс 2>]<массив>[<фиксированный индекс>]<массив>[<фиксированный индекс>, <начало> TO <конец>]<массив>[<начало 1> TO <конец 1>, <начало 2> TO <конец 2>]Массив является переменной или выражением массивного типа. Каждый индекс и каждая граница диапазона задаются числовым выражением, а положение аргумента соответствует номеру измерения. Начало и конец диапазона включаются в результат. Значение обязано быть целым и помещаться в INTEGER; ненулевая дробная часть вызывает MB3007.
Результат: элемент или представление
Индекс должен быть целым числом. Значение DOUBLE или DECIMAL допустимо, только если его дробная часть равна нулю; иначе возникает MB3007. В диапазоне TO нижняя граница не должна быть больше верхней: обратный диапазон вызывает MB3002, а не пустой результат.
Если все измерения заданы одиночными индексами, результат имеет тип элемента. При оставшихся измерениях результат является массивным представлением: фиксированный индекс убирает одно измерение, диапазон TO сохраняет его с выбранными границами, а неуказанные конечные измерения входят в представление полностью. Представление сохраняет логические границы выбранных измерений, то есть индексы не перенумеровываются. Для доступа нужен выделенный массив.
Для присваивания отдельному элементу указывают все индексы. Сохранение области в массивной переменной создаёт независимую копию. Для изменения исходной области передают срез непосредственно в ARRAYFILL или обходят его через FOR EACH BYREF.
Полный и частичный доступ
Следующая программа читает один элемент, затем получает строку таблицы и работает с ней как с отдельным массивом:
DIM board[1 TO 2, 2 TO 4] AS INTEGER
board[2, 3] = 20
DIM rowPart[] AS INTEGER
rowPart[] = board[2]
PRINT rowPart[3]
rowPart[3] = 99
PRINT board[2, 3]Программа выводит:
20
20Фиксированный индекс 2 убрал первое измерение, поэтому в rowPart[] осталось только измерение столбцов. Его границы не изменились: элемент, записанный как board[2, 3], читается как rowPart[3], а не как rowPart[1]. Вторая запись изменила копию; исходный элемент остался равен 20.
Диагностика
Несовместимый тип элемента или индекса даёт MB2003, неверное число индексов — MB2004. Индекс или диапазон, вышедший за границы при индексировании, сообщается кодом MB3002; невыделенный массив и недопустимая пара границ — кодом MB3005. Запрещённая нижняя граница -2147483648 вызывает MB3007, выход числового значения за диапазон INTEGER — MB3008.
Число аргументов чтения должно быть от 1 до ранга. Для записи отдельному элементу требуется ровно столько индексов, каков ранг массива.
См. также
Срезы и представления · Литерал массива · Двумерные массивы · Диагностика
Массив целиком
<массив>[]Пустые квадратные скобки после массивного имени или поля обозначают этот массив целиком при любом числе измерений. Скобки не означают, что массив пуст, не выделяют память, не создают представление или копию и не читают отдельный элемент. Имя массива без [] недопустимо: в ARRAYLENGTH(board[]) суффикс нужен и у многомерного массива. Запись board[,] задаёт ранг в объявлении, но не обозначает массив целиком в выражении.
DIM fruits[] AS STRING = SPLIT("яблоко,банан", ",")
DIM basket[] = fruits[]
basket[2] = "груша"
PRINT fruits[2]
PRINT ARRAYLENGTH(basket[])Вывод:
банан
2Переменная basket содержит независимую копию массива fruits. Запись с индексом fruits[2] выбирает элемент, а fruits[] обозначает весь массив. Присваивание, возврат из функции и передача BYVAL копируют вложенные данные; явная передача BYREF сохраняет связь с переменной. Для массивного поля суффикс также обязателен: bag.fruits[]. Вызов функции MakeFruits() уже является массивным выражением, если функция возвращает массив. Его элемент выбирается записью MakeFruits()[2]; дополнительный пустой суффикс после вызова не требуется.