Массив, в отличие от скалярного типа данных, представляющего
единственное значение, — это тип данных, предназначенный для
хранения и обработки нескольких скалярных данных, ссылаться
на которые можно с помощью индекса. Все массивы Perl одномерны
и их можно мыслить как некий линейный список скаляров. Для
извлечения какого-либо значения, хранимого в массиве, достаточно
одного индекса. В программе массив задается с помощью специальной
синтаксической конструкции языка Perl, называемой конструктором
массива. Он представляет собой список скалярных значений,
заключенный в круглые скобки. Элементы списка отделяются друг
от друга запятыми и представляют элементы массива:
(скаляр_1, скаляр_2, ... , скаляр_n)
Как и в других языках
программирования, массив Perl представляет набор однотипных
данных — скаляров, но скалярные данные могут быть как числовыми,
так и строковыми, поэтому, с точки зрения других языков программирования,
в массивах Perl хранятся смешанные данные — числа и строки.
В качестве скаляра в конструкторе массива может использоваться
числовой или строковый литерал или скалярная переменная, чье
значение и будет являться элементом массива:
(5, "умножить на", 4) # Используются только литералы.
($first, 'равно', $second) # Используются значения скалярных
переменных.
Массив может состоять из неограниченного
числа элементов, а может не иметь ни одного. В таком случае
его называют пустым массивом. Конструктор пустого массива
— круглые скобки без содержащегося в них списка ().
Как отмечалось в начале параграфа,
массив характеризуется тем, что к любому его элементу можно
обратиться при помощи индекса (целого литерала или скалярной
переменной, принимающей целое значение), который задается
в квадратных скобках непосредственно после конструктора массива.
Индексы массивов в языке Perl начинаются с о, а отрицательные
индексы позволяют обратиться к элементам в обратном их заданию
порядке:
(5, "умножить на", 4)[0] # Первый элемент массива:
5.
(5, "умножить на", 4)[2] # Последний элемент массива:
4.
(5, "умножить на", 4)[-1] f Последний элемент массива:
4.
(5, "умножить на", 4) [-3] # Первый элемент массива:
5.
При использовании отрицательных
индексов индекс -1 соответствует последнему элементу массива,
а индекс -п, где п — количество элементов массива, первому
элементу массива.
Нельзя использовать индекс
для извлечения элементов списка, возвращаемого некоторыми
функциями Perl. Индекс можно применять только к массивам или
их конструкторам, а для этого достаточно заключить список
в круглые скобки. Например, конструкция stat(@m) [0] вызовет
ошибку компиляции, если возвращаемым значением функции stat
является список, тогда как конструкция (stat (@m)) [0] приведет
к желаемому эффекту.
В качестве элемента списка
в конструкторе массива можно использовать конструктор массива,
но мы не получим в этом случае, как ожидает читатель, знакомый
с другими языками программирования, массив массивов, т. е.
многомерный массив, к элементам которого можно обратиться
с помощью нескольких индексов. Дело в том, что если в качестве
элемента списка в конструкторе массива используется конструктор
массива, то его элементы добавляются к элементам массива,
определяемого внешним конструктором, т. е. каждый его элемент
становится элементом внешнего массива, увеличивая количество
его элементов на количество элементов внутреннего массива.
Например, массив
(1, (2, 3), 4}
эквивалентен массиву
(1, 2, 3, 4)
В программе массивы
хранятся в специальных переменных, имена которых начинаются
с символа "@". Объявление переменной массива, или
просто массива, чаще всего осуществляется в операторе присваивания
(=), в правой части которого обычно задается конструктор массива:
Sarray = ($ml, '+', $m2, '=', $ml+$m2);
Задать или получить значения
элементов массива, хранящегося в переменной, можно и с помощью
индекса. Однако "операцию" индексирования нельзя
применять непосредственно к имени переменной массива, ее следует
применять к переменной, в которой первый символ заменен на
символ скалярной переменной $. Подобное "неудобство"
связано с последовательным проведением в Perl использования
первого символа переменной для указания ее типа: ведь элемент
массива является ничем иным как скаляром. Примеры использования
индекса с переменными массива представлены ниже:
$ml[0] = "Первый"; # Задает первый элемент массива
@ml.
$ml[l] = "Второй"; # Задает второй элемент массива
@ml.
@m2 = (1, 2, 3, 4, 5); # Задание массива @т2.
print @ml, "\n", $m2[0]; # Печать массива toil
и
# первого элемента массива @m2.
Массивы в Perl являются динамическими.
Добавление нового элемента в массив автоматически увеличивает
его размер. С помощью индекса можно добавить элемент, отстоящий
от последнего определенного элемента массива на любое число
элементов, и это действие не приведет к ошибке. Просто все
промежуточные элементы будут не определены (их значение будет
равно пустой строке ""). При такой реализации массивов
программисту не надо заботиться, как в других языках программирования,
что индекс выйдет за размеры массива. В случае обращения к
не существующему элементу массива Perl возвращает значение,
равное нулевой строке.
Замечание
Если для интерпретатора peri включен режим отображения предупреждающих
сообщений во время выполнения, то в случае обращения к не
определенному или не существующему элементу массива будет
отображаться сообщение, что значение элемента не определено.
В любой момент можно
определить число элементов массива. Для этого следует воспользоваться
синтаксической конструкцией
$ #имя_массива
При работе с массивами
самой "утомительной" процедурой может оказаться
процедура присваивания значений элементам массива. Хорошо,
если все необходимые данные для заполнения массива большой
размерности уже существуют в каком-либо текстовом файле. Тогда
можно присвоить значения элементам массива, воспользовавшись
операцией чтения из внешнего файла, но об этом в следующей
главе. А если необходимо в программе создать массив натуральных
чисел до 1000 включительно? Неужели надо писать 1000 операторов
присваивания, или организовывать цикл, в котором осуществлять
соответствующие присваивания, или создавать текстовый файл,
содержащий эти числа? К счастью, нет! В Perl для подобных
ситуаций предусмотрена операция диапазон, которую можно использовать
в конструкторе массива. Например, чтобы создать массив натуральных
чисел до 1000, достаточно одного оператора:
@naturalNumbers = (1..1000);
Общий синтаксис операции диапазон следующий:
первое_число..последнее_число
Она определяет набор чисел
(целых или вещественных), начинающихся с первое_число и не
превосходящих последнее_число, в котором последующее больше
предыдущего на единицу. Эта операция действительна не только
для чисел, но и для алфавитно-цифровых строк, но в этом случае
увеличение на единицу означает увеличение на единицу ASCII-кода
символа строки. Ниже показаны примеры использования операции
диапазон со строковыми данными:
"а".."с" i Соответствует: "а",
"b", "с"
"BCY".."BDB" # Соответствует: "BCY",
"BCZ", "BDA", "ВОВ"
Эта операция особенно удобна
для задания целых чисел, начинающихся с нуля, например, для
представления дня месяца в дате вида "01.02.2000":
@ day_ofjnonth = ("01".."31");
Переменные
массива и элемент массива можно подставлять в строки, ограниченные
двойными кавычками. Если интерпретатор встречает в строке
переменную массива, то он вставляет в нее значения элементов
массива, отделенные друг от друга пробелами. Результатом выполнения
следующих операторов
@т = (1. .3);
print "Числа@{т}являются целыми";
будет строка
Числа! 2 являются целыми
Все правила определения идентификатора
скалярной переменной при ее подстановке в строку переносятся
и на переменную массива.
В связи с возможностью подстановки
переменной массива можно указать быстрое решение проблемы
распечатки содержимого массива. Дело в том, что если в операторе
печати просто указать переменную массива, то его элементы
выводятся сплошной строкой без пробелов между ними, что является
неудобным при работе с числовыми данными. Если вставить переменную
массива в строку, то при ее печати между элементами массива
будут вставлены пробелы. Следующие два оператора печати
print @m, "\n"; print "@m\n";
отобразят массив @m предыдущего примера по-разному:
123
123
Подстановка в строку элемента
массива с помощью индексного выражения ничем не отличается
от подстановки скалярной переменной: элемент массива, полученный
с помощью индекса, является скалярной величиной. Однако здесь
может возникнуть одна интересная проблема, если в программе
определена скалярная переменная с таким же идентификатором,
что и у массива. Значение этой переменной или значение соответствующего
элемента массива будет вставлено в строку? Например, если
в программе определена скалярная переменная $var и массив
@var, то значение переменной или элемента массива будет вставлено
в строку "$var [0]".
Правильный ответ — значение
элемента, так как при синтаксическом анализе интерпретатор
будет рассматривать встретившуюся последовательность символов
как лексему $var[0], а не как имя переменной $var с последующим
символом "[". Если необходимо использовать значение
скалярной переменной $var в строке, то можно предложить три
способа решения этой проблемы:
"${var}[0.]" # Фигурные скобки ограничивают символы,
рассматриваемые
# интерпретатором как единое целое с символом $. "$var\[0]"
# Обратная дробная черта ограничивает идентификатор
# переменной. "$var" .• "[0]" # Конкатенация
строк (операция ".") позволяет однозначно
# интерпретировать переменную в первой строке.
Иногда для работы необходимо
выделить некоторое подмножество элементов массива, которое
мы будем называть фрагментом массива. Можно ее выполнить просто,
но не эффективно: присвоить элементам некоторого нового массива
значения соответствующих элементов старого, можно воспользоваться
специальной конструкцией Perl для выделения фрагмента массива.
Если после имени переменной массива в квадратных скобках задать
список индексов некоторых элементов массива, то такая конструкция
и будет определять фрагмент массива, причем индексы не обязательно
должны идти в каком-то определенном порядке — их можно задавать
произвольно. Для выделения фрагмента, состоящего из последовательно
идущих элементов массива, можно использовать знакомую нам
операцию диапазон. Фрагмент массива сам является массивом,
и поэтому его можно использовать в правой части оператора
присваивания. Несколько примеров создания фрагментов массива
приведено ниже:
@т = (10..19); # Исходный массив:
# (10, 11, 12, 13, 14, 15, 16, 17, 18, 19). @т[0, 2, 4, 6,
8];
# Фрагмент 1: (10, 12, 14, 16, 18). @т[6, 4, 5, 8, 6];
# Фрагмент 2: (16, 14, 15, 18, 16). @т[2..4];
# Фрагмент 3: (12, 13, 14). @т[8, 2..4, 0];
# Фрагмент 4: (18, 12, 13, 14, 10).
При выделении фрагмента массива
используется имя переменной массива, начинающейся с символа
"@", тогда как при ссылке на элемент массива префикс
имени переменной заменяется на символ "$". Здесь
опять прослеживается последовательное использование префикса
для задания типа переменной. Фрагмент массива является массивом,
а потому следует использовать символ "@".
|