Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Annotation 1 страница. Gt;текстовое поле с выравниванием значения вправо и добавлением пробелов слева@>>>>> ^>>> #числовое поле с выравниванием значения




Gt;текстовое поле с выравниванием значения вправо и добавлением пробелов слева@>>>>> ^>>> #числовое поле с выравниванием значения вправо с добавлением пробелов слева@#### ^### 0(вместо первого #) числовое поле с выравниванием значения вправо и добавлением нулей слева@0### ^0## .десятичная точка в числовом поле@.### @0##.## ...закончить текстовое поле многоточием, чтобы показать усечение значения@<<<<<... @*поле переменной ширины со значением, состоящим из нескольких строк@* ^*поле переменной ширины для следующих строк многострочного значения^* ~подавление вывода строки с пустыми значениями полей^* ~ ~~повторять строку, пока все значения полей не станут пустыми~~ ^* {}группировка списка значений, который располагается на нескольких строках аргументов{$one, $two, $three } #(первым символом в строке) строка комментария в описании формата (не может располагаться между строкой шаблонов и строкой аргументов)# это комментарий .(единственным символом на отдельной строке) конец форматаformat REPORT = описание формата. То, как применяются поледержатели при описании формата, можно увидеть из следующего примера:   format STDOUT = Учетная карточка пользователя N @0### $number --------------------------------------------------------- Фамилия @<<<<<<<<<<<<<< | Login @<<<<<<< $last_name, $login Имя @<<<<<<<<<<< | Группа @<<<<<<<<<<<<<<<<< $first_name, $group Отчество @<<<<<<<<<<<<<<<<<< | $middle_name E-mail @<<<<<<<<<<<<<<<<<< | Телефон @>>>>>>>>> $email, $phone Ограничение дискового пространства @####.## Мегабайт $quota --------------------------------------------------------- Дата регистрации @# @<<<<<<<<< @### года {$day, $month_name,$year}.   Из примера понятно, что формат отчета записывается в виде, максимально похожем на представление страницы отчета на экране или на бумаге. Каждому полю в строке шаблонов должно соответствовать скалярное значение в строке аргументов. Имена переменных в строке аргументов для наглядности часто располагаются под соответствующими поледержателями в предыдущей строке шаблонов, хотя это совсем не обязательно. Список переменных может находиться на нескольких строках аргументов (как это сделано в описании последней строки формата); в этом случае он должен заключаться в фигурные скобки. Имейте в виду, что скалярные переменные и массивы в строке аргументов разворачиваются в единый список скаляров, из которого по порядку берутся значения для заполнения полей.     Для форматированного вывода отчетов применяется функция write(), которая оформляет очередную порцию данных в соответствии с форматом отчета и выводит их в указанный выходной поток. Обращение к функции write() иногда называют вызовом формата. В качестве аргумента функции write() может передаваться файловый манипулятор выходного потока. Вызванная без аргументов, она направляет отчет в текущий выходной поток. Перед обращением к ней нужно заполнить новыми данными переменные, перечисленные в строках аргументов текущего формата. Обычно write() вызывается в цикле для вывода в отчет очередной строки. По историческим причинам для заполнения полей отчета часто используются глобальные переменные. Лексические переменные, объявленные с помощью my(), доступны в формате только тогда, когда формат и лексические переменные объявлены в одной области видимости. Подробно об областях видимости переменных будет рассказано в лекции 12. Если для выходного потока описан формат начала страницы отчета, то перед выводом строк отчета функцией write() в начале каждой страницы автоматически размещаются данные шапки страницы в соответствии с форматом начала страницы. Программа для вывода данных по формату, заданному в предыдущем примере, может выглядеть таким образом:   # данные в записи входного файла разделены запятыми open my $in, '<', 'users.txt' or die; while (my $line = <$in>) { local ($last_name, $first_name, $middle_name, $login, $group, $email, $phone, $quota, $number, $day, $month_name, $year) = split ',', $line; # данные для отчета помещены в переменные write STDOUT; # данные выводятся в STDOUT по формату } close $in or die; # здесь располагается описание формата...   В результате выполнения этой программы в поток STDOUT будет выведен отчет, состоящий вот из таких карточек:   Учетная карточка пользователя N 00001 --------------------------------------------------------- Фамилия Wall | Login larry Имя Larry | Группа root Отчество | E-mail [email protected] | Телефон +123456789 Ограничение дискового пространства 9876,54 Мегабайт --------------------------------------------------------- Дата регистрации 18 декабря 1987 года   В каждую из выводимых в отчет карточек помещаются данные из одной записи входного файла.     Без указания файлового манипулятора вывод отчета функцией write() и обычный вывод данных функцией print() происходит в выходной поток по умолчанию (STDOUT). С помощью функции select() можно назначить другой выходной поток по умолчанию. При вызове ей передается файловый манипулятор, и она переключается на новый поток, который становится текущим выходным потоком по умолчанию. Функция select() возвращает имя ранее выбранного манипулятора, и это значение используется для восстановления предыдущего выходного потока. Это происходит таким образом:   $old_handle = # сохранить файловый манипулятор select $new_handle; # переключиться на новый поток write; # вывести в новый поток select $old_handle; # восстановить предыдущий поток   При формировании сложного отчета может потребоваться возможность переключаться на разные форматы отчета. Установить для какого-либо потока определенный формат отчета можно путем присваивания имени формата переменной $~ ($FORMAT_NAME). Подобным же образом для конкретного потока устанавливается нужный формат заголовка страницы отчета: переменной $^ ($FORMAT_TOP_NAME) присваивается имя формата для шапки страницы. Это делается так:   $old_handle = select $out; # выбрать поток для отчета $^ = 'REPORT_TOP'; # назначить формат для шапки отчета $~ = 'REPORT'; # назначить формат для отчета write $out; # вывести в $out по формату REPORT select $old_handle; # вернуться к предыдущему потоку   Назначать для определенного потока формат отчета и заголовок страницы гораздо удобнее с помощью функций format_name() и format_top_name() из стандартного библиотечного модуля FileHandle. Это выглядит так:   use FileHandle; # подключить модуль работы с файлами # назначить для потока $report формат отчета REPORT format_name $report REPORT; # назначить для потока $report формат заголовка PAGE format_top_name $report PAGE; # используя назначенные форматы, write $report; # вывести строку отчета в $report   Обратите внимание, что при обращении к функциям format_name() и format_top_name() после файлового манипулятора не ставится запятая, так же как при вызове функции print().     Пока что в примерах использовались только обычные поля (regular fields), которые описываются поледержателями, начинающимися с символа @. Поледержатели, описание которых начинается с символа ^, представляют так называемые специальные поля (special fields), обладающие возможностью дополнительной обработки данных. Так, специальные числовые поля (например, ^###), содержащие неопределенное значение (undef), заполняются пробелами. Обычные числовые поля (например, @###) в этом случае выводят нули. Это демонстрирует следующий пример:   format STDOUT = обычное:'@##.##' специальное:'^####' undef, undef. write STDOUT; # вывод данных по формату в STDOUT # выведет: обычное:' 0.00' специальное:' '   Специальные текстовые поля (например, ^<<<) используются для вывода в отчет данных, располагающихся на нескольких строках.     Есть несколько способов описать в формате данные, занимающие в отчете несколько строк. Если нужно поместить на странице отчета многострочное текстовое значение, то можно воспользоваться поледержателем @*, который просто выведет значение полностью, сохраняя имеющиеся в нем все символы перевода строки, кроме последнего. Например, так делается в этой программе:   format STDOUT = Гамлет: @* $multi_line_text (У. Шекспир). $multi_line_text = "Быть\nИли не быть?\nВот в чем вопрос."; write STDOUT;   В результате ее выполнения будет выведено известное высказывание с сохранением его разбивки на несколько строк:   Гамлет: Быть Или не быть? Вот в чем вопрос. (У. Шекспир)   Поледержатель ^* описывает в формате текстовое поле, значение которого должно выводиться на несколько строк определенной ширины. В строке аргументов такому полю должно соответствовать имя переменной: скаляра, элемента массива или хэша. Когда значение этой переменной помещается в поле отчета, из переменной извлекается часть текстового значения до первого разделителя строк. Если переменная употребляется в формате несколько раз, то ее значение уменьшается на число извлеченных символов при каждом обращении к ней. Вот как это выглядит на примере:   # выводимое многострочное значение $text = "Что значит имя?\nРоза пахнет розой\n". "Хоть розой назови ее, хоть нет."; write STDOUT; # описание формата отчета format STDOUT = ^* $text ^* $text ^* ~ $text ^* ~ $text У.Шекспир, "Ромео и Джульетта".   Обратите внимание, что в формате для вывода значения переменной $text предусмотрены четыре строки. Причем первые две строки отчета (с шаблоном ^*) будут выводиться в любом случае: даже если $text содержит только одну строку текста, вторая строка будет заполнена пробелами. Чтобы не выводить пробельных строк, в описании третьей и четвертой строк указан шаблон подавления пустых строк (одна тильда, ~), который может располагаться в любом месте строки шаблона. После выполнения приведенной программы текст будет выведен в таком виде:   Что значит имя? Роза пахнет розой Хоть розой назови ее, хоть нет. У.Шекспир, "Ромео и Джульетта"   Если заранее неизвестно минимальное количество выводимых строк, можно применить шаблон повторения многострочного поля (две тильды подряд в любом месте строки, ~~). В этом случае строка шаблона будет применяться многократно, пока не будет исчерпано многострочное значение, при этом пустые строки выводиться не будут. Тильды в шаблоне подавления пустых строк и в шаблоне повторения строк при выводе отчета заменяются на пробелы. Таким образом, формат в последнем примере можно заменить на следующий:   format STDOUT = ^* ~~ $text У.Шекспир, "Ромео и Джульетта".   В результате будет выведен точно такой же отчет, как и с использованием предыдущего формата, но последний формат гораздо короче и выводит любое количество строк. Для описания в формате текстового значения, которое должно выводиться на несколько строк, применяется поледержатель следующего вида: ^<<<<<. Это специальное поле иногда называется "заполняемым полем". Оно предназначается для форматирования текстового значения, которое при выводе в отчет делится на строки, не превышающие ширину шаблона. Деление на строки производится по границам слов. Источником выводимого текста обязательно должна быть переменная со скалярным значением, из которой при каждом ее употреблении в формате извлекается столько слов, сколько поместится в соответствующем поле отчета. Заполнение шаблона текстом и вывод отчета в несколько строк иллюстрирует следующий пример:   my $shakespeare = 'Две равно уважаемых семьи '. 'В Вероне, где встречают нас событья, '. 'Ведут междоусобные бои '. 'И не хотят унять кровопролитья.'; my $text = $shakespeare; write STDOUT; # описание формата вывода format STDOUT = ~~ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< $text У.Шекспир, "Ромео и Джульетта".   В этом примере для организации неявного цикла вывода также применяется шаблон повторения строк, поскольку неизвестно, сколько строк будет заполнено выводимым текстом. При выполнении примера будет выведен текст в таком виде:   Две равно уважаемых семьи В Вероне, где встречают нас событья, Ведут междоусобные бои И не хотят унять кровопролитья. У.Шекспир, "Ромео и Джульетта"   Подобным образом в отчет выводятся блоки текстовой информации: примечания, описания, адрес и т. п.     Кроме переменных, в которых хранятся имена формата ($~) и заголовка страницы формата ($^), есть еще несколько специальных переменных для хранения информации о форматах. Номер текущей страницы выводимого отчета содержится в переменной $% ($FORMAT_PAGE_NUMBER), и ее часто включают в формат отчета. В переменной $= ($FORMAT_LINES_PER_PAGE) хранится число строк на странице: по умолчанию - 60, но его можно изменить на нужное значение перед выводом отчета. В переменной $- ($FORMAT_LINES_LEFT) содержится число оставшихся на странице строк. Переменная $^L ($FORMAT_FORMFEED) хранит символ перевода страницы (formfeed character), который используется в отчетах для прогона принтера до новой страницы. Специальная переменная $: ($FORMAT_LINE_BREAK_SEPARATOR) содержит набор символов разрыва строки, после которых строка может быть разделена при заполнении в формате специальных полей продолжения. Специальная переменная $^A ($ACCUMULATOR) является аккумулятором выводимых данных для функций formline() и write(), в котором накапливаются данные отчета перед их отправкой в выходной поток. При считывании данных для отчета из файла может пригодиться переменная $. ($INPUT_LINE_NUMBER), в которой хранится номер прочитанной из входного файла строки, что можно использовать для нумерации строк в отчете. Дополнительные сведения о форматах и отчетах в Perl можно узнать из стандартной документации, обратившись за помощью к утилите   perldoc perlform   В завершение лекции приведем пример законченной программы (с образцом исходных данных), выводящей отчет о книгах по языку Perl.   open my $report, '>', '/report.txt' or die; $old_handle = select $out; # выбрать поток для отчета select $report; $^ = 'HEAD'; $~ = 'REPORT'; # описание форматов для отчета while(<DATA>) { # чтение одной записи данных ($authors, $title, $year, $nick) = split ':'; write $report; # вывод одной строки отчета } close $report or die; # формат для заголовка страницы format HEAD = Классические книги по языку Perl издательства O'Reilly Лист @# $% ---------------+--------------------+----+------------ Авторы | Заглавие |Год | Прозвище ---------------+--------------------+----+------------. format REPORT = ^<<<<<<<<<<<<<<|^<<<<<<<<<<<<<<<<<<<|@###|@>>>>>>>>>>> $authors, $title, $year, $nick ^<<<<<<<<<<<<<<|^<<<<<<<<<<<<<<<<<<<| | ~~ $authors, $title ---------------+--------------------+----+------------. __DATA__ Cozens S.:Advanced Perl Programming,2nd ed.:2005:Panther Book Friedl J.E.F.:Mastering Regular Expressions:1997:Owls Book...   Результатом работы этой программы будет такой отчет, размещенный в файле report.txt:   Классические книги по языку Perl издательства O'Reilly Лист 1 ---------------+--------------------+----+------------ Авторы | Заглавие |Год | Прозвище ---------------+--------------------+----+------------ Cozens S. |Advanced Perl |2005|Panther Book |Programming,2nd ed. | | ---------------+--------------------+----+------------ Friedl J.E.F. |Mastering Regular |1997| Owls Book |Expressions | | ---------------+--------------------+----+------------ Schwartz R.L., |Learning Perl, 4th |2005| Llama Book Phoenix T., |ed. | | brian d foy | | | ---------------+--------------------+----+------------   Конечно, изученные в этой лекции средства отчетов не могут сравниться с современными специализированными построителями отчетов, но во многих случаях бывает достаточно форматирования выходных данных в виде простых отчетов, которое в Perl делается достаточно легко, просто и наглядно. Эта лекция была "лирическим отступлением" перед тем как начать углубленное изучение техники программирования на языке Perl.     Лекция 11. Ссылки   В этой лекции будут изучены ссылки и ссылочные структуры данных, которые играют очень важную роль в Perl, так как позволяют создавать многомерные массивы, массивы записей и различные динамические структуры данных произвольной сложности: очереди, списки, деревья, графы. Кроме того, умение работать со ссылками необходимо для понимания объектно-ориентированного программирования в Perl. Цель лекции: научиться обращаться со ссылками, объектами ссылок и структурами данных, основанными на ссылках, чтобы применять их при программировании задач со сложными структурами данных.   Ссылки явно или неявно применяются во всех языках программирования. Они позволяют гибко создавать динамические структуры данных неограниченной сложности. Ссылки являются одним из скалярных типов данных языка Perl, наряду с числами и строками. Ссылка (reference) - это информация о том, где при выполнении программы располагается в памяти объект определенного типа. Эту информацию можно использовать для доступа к объекту ссылки (referent). Ссылка - это возможность обратиться к какой-то информации не по имени, которое известно при компиляции, а по ее расположению в памяти при выполнении программы. В отличие от указателей в некоторых других языках, в Perl ссылки реализованы надежно и эффективно. Программист не должен заботиться о явном удалении из памяти объектов ссылок, поскольку занимаемая память автоматически освобождается встроенным сборщиком мусора, когда объекты ссылок перестают использоваться (то есть когда на них больше не указывает ни одна ссылка). Для создания ссылки на существующий программный объект предусмотрена операция взятия ссылки, обозначаемая обратной косой чертой (backslash), которая ставится перед объектом ссылки. В следующем примере показано, как можно получить ссылку на скалярную переменную и сохранить ее в другой переменной:   my $scalar = 'Скаляр'; # объект ссылки my $ref2scalar = \$scalar; # ссылка на скаляр   На рис. 11.1 показан результат сохранения ссылки на значение скалярной переменной в другой скалярной переменной.     Рис. 11.1. Ссылка на скалярное значение При помощи операции '\' можно брать ссылку на любые объекты, например, на литерал или на любое другое выражение, только при этом значение объекта ссылки нельзя будет изменить. В этом случае при выполнении программы выражение вычисляется, а результат сохраняется в анонимной области памяти, ссылка на которую и возвращается. Например:   my $ref2literal = \'Литерал'; # ссылка на литерал my $ref2expression = \($n1*$n2); # ссылка на выражение   Анонимные данные - это значения, не связанные ни с одной переменной, доступ к которым происходит только по ссылке. Ссылка всегда указывает на значение конкретного типа: скаляр, массив, хэш, подпрограмму (или элемент таблицы символов, о которых речи пока не было). На какой именно тип объекта указывает ссылка, можно узнать с помощью функции ref(), которая возвращает строку, описывающую тип значения объекта ссылки. Например:   print ref($ref2scalar); # выведет: 'SCALAR'   А что получится, если вывести значение самой ссылки? Ее значение будет преобразовано в строку, содержащую тип объекта ссылки и его адрес в виде шестнадцатиричного числа, например:   print $ref2scalar; # выведет, например: 'SCALAR(0x335b04)'   Обратно преобразовать в ссылку это строковое представление адреса не удастся.     Чтобы получить доступ к значению, на которое указывает ссылка, нужно выполнить разыменование ссылки (dereference). Для этого переменная, содержащая ссылку, заключается в фигурные скобки и перед ней ставится нужный разыменовывающий префикс: $ для скаляра, @ для массива, % для хэша, & для подпрограммы. (Другими словами, после разыменовывающего префикса, определяющего тип хранящегося в переменной значения, вместо имени переменной записывается содержащая ссылку переменная или выражение, возвращающее ссылку.) Если не возникает неоднозначности в интерпретации выражения, то переменную, хранящую ссылку, в фигурные скобки можно не заключать. Вот примеры разыменования ссылок на скалярные значения:   print "${$ref2scalar} "; # или: $$ref2scalar print "${$ref2literal} "; # или: $$ref2literal print "${$ref2expression} "; # или: $$ref2expression   Значение скалярной переменной при доступе по ссылке, естественно, может изменяться, но попытка с помощью ссылки изменить литерал вызовет ошибку при выполнении программы ("Modification of a read-only value attempted"):   ${$ref2scalar} = 'Новый скаляр'; # вполне законно ${$ref2literal} = 'Новый литерал'; # ОШИБКА!!!   Когда на какое-то значение ссылается несколько ссылочных переменных, то обращаться к этому значению можно с помощью любой из них. Значение доступно до тех пор, пока на него имеется хотя бы одна ссылка. Например:   my $ref2scalar = \$scalar; # ссылка на скаляр my $one_more_ref = $ref2scalar; # копия ссылки на скаляр # будет выведено одно и то же значение $scalar: print "${$ref2scalar} ${$one_more_ref}";   На рис. 11.2 показана ситуация, когда несколько ссылок указывают на одну скалярную переменную.     Рис. 11.2. Несколько ссылок на скаляр Если переменная $ref2scalar перестанет ссылаться на $scalar (например, после undef $ref2scalar), то значение $scalar все еще будет доступно через переменную $one_more_ref. Значением объекта ссылки также может быть ссылка (косвенная ссылка) на другой объект, возможно, тоже на ссылку. Ссылка даже может содержать ссылку на саму себя! Таким образом при необходимости можно построить цепочку ссылок любой длины. Например:   $value = 'Полезное значение'; $ref1 = \$value; # ссылка на значение $ref2 = \$ref1; # ссылка на ссылку на значение $ref3 = \$ref2; # ссылка на ссылку на ссылку на значение   Можно организовать многоуровневые косвенные ссылки без использования промежуточных переменных, несколько раз применяя операцию взятия ссылки на значение. Например, создадим такую цепочку ссылок:   $ref_chain = \\\$value; # цепочка из трех ссылок   Для доступа по такой цепочке ссылок к исходному значению правило разыменования применяется нужное число раз. Например, в цепочке из трех ссылок с помощью трех префиксов $ мы последовательно получаем доступ к ссылочным переменным, а еще один префикс нужен для доступа к полезному значению:   # выведем исходное значение через $ref3: print ${${${$ref3}}}; # или короче: print $$$$ref3; # или через $ref_chain: print $$$$ref_chain;   Если применить функцию ref() к переменной, содержащей ссылку на другой объект, то она вернет строку 'REF'. Если преобразовать в строку значение ссылки на ссылку, то будут выведено обозначение ссылочного типа и адрес объекта ссылки, например:   print ref($ref_chain); # выведет: 'REF' print $ref_chain; # выведет, например: 'REF(0x334e8c)'   Подобным же образом можно работать со ссылками на массивы. Ссылка на переменную типа "массив" также создается с помощью операции взятия ссылки:   my @array = ('Это', 'список', 'в', 'массиве'); my $ref2array = \@array; # ссылка на массив   Если обращение к массиву будет происходить только по ссылке, то можно обойтись без переменной типа "массив", а создать анонимный массив и присвоить ссылку на него в скалярную переменную. Ссылка на анонимный массив создается с помощью квадратных скобок, в которые заключается список начальных значений безымянного массива:   my $ref2anon = [ # ссылка на анонимный массив 'Это', 'анонимный', 'массив' ]; # конец присваивания ссылки my $ref2empty = []; # ссылка на пустой анонимный массив   Анонимные массивы удобно использовать для создания ссылки на копию массива. Для этого существующий массив помещается в квадратные скобки, и его значение будет скопировано в созданный анонимный массив:   my $ref2copy = [@array]; # ссылка на копию массива   Ссылка на именованный массив и ссылка на анонимный массив изображены на рис. 11.3.     Рис. 11.3. Ссылки на обычный и анонимный массивы Разыменование ссылки на массив производится аналогично разыменованию ссылки на скалярную переменную, только с использованием префикса массива @:   # будет выведено одно и то же значение @array: print "@{$ref2array} @$ref2array\n";   Естественно, что, обращаясь к массиву по ссылке, можно выполнять с ним любые действия, как и с именованным массивом, например:   my @array_copy = @{$ref2array}; # копия массива @{$ref2array}[0,1] = ('Новый', 'список'); # срез массива   Разыменование ссылки на элемент массива оформляется так: перед ссылочной переменной, которая может заключаться в фигурные скобки, указывается префикс скалярного значения $, а после ссылочной переменной указывается индекс элемента в квадратных скобках. Другими словами, для обращения к элементу массива по ссылке имя массива заменяется ссылочной переменной:   print ${$ref2array}[0]; # или: $$ref2array[0]   Обращение по ссылке к элементу массива более наглядно записывается с помощью инфиксной операции ->, слева от которой записывается имя переменной, содержащей ссылку на массив, а справа - индекс элемента массива в квадратных скобках. Операция "стрелка" наглядно представляет ссылку, символы -> в ней записываются без пробела между ними. Вот пример:   # доступ по ссылке к значению элемента массива: my $element_value = $ref2array->[0]; # изменение значения элемента массива: $ref2array->[0] = $new_value;   Как к обычным скалярным значениям можно обращаться по ссылке к отдельным элементам массива, например:   $ref2element = \$array[0]; # ссылка на элемент массива ${$ref2element} = $new_value; # изменение элемента массива   В элементах массива можно хранить ссылки на другие массивы: это позволяет создавать в Perl многомерные массивы или "массивы массивов", как это делается в языке Java. В этом случае доступ к элементам многомерного массива также обычно записывается с использованием операции "стрелка", которая употребляется нужное количество раз:   @{$ref2NxM->[$n]} # вложенный массив $ref2NxM->[$n]->[$m] # скалярный элемент двумерного массива $ref2NxMxP->[$n]->[$m]->[$p] # элемент 3-мерного массива   Для удобства чтения программы допускается не записывать операцию "стрелка" между парами индексов массива в квадратных скобках:   $ref2NxM->[$n][$m] # так гораздо симпатичнее! $ref2NxMxP->[$n][$m][$p] # а тем более так...   Для примера приведем программу создания двумерного массива из трех строк по пять элементов в каждой строке:   my $ref2RxC = []; # ссылка на анонимный массив массивов for (my $row = 0; $row < 3; $row++) { # цикл по строкам $ref2RxC->[$row] = []; # строка: вложенный массив for (my $col = 0; $col < 5; $col++) { # по колонкам $ref2RxC->[$row]->[$col] = ($row+1).'.'.($col+1); } }   Небольшие многомерные массивы удобно создавать, используя вложенные анонимные массивы. Это присваивание создаст такой же массив, что и в предыдущем примере:   $ref2RxC = [ # ссылка на двумерный анонимный массив [1.1, 1.2, 1.3, 1.4, 1.5], # 1-я "строка" [2.1, 2.2, 2.3, 2.4, 2.5], # 2-я "строка" [3.1, 3.2, 3.3, 3.4, 3.5] # 3-я "строка" ]; # конец присваивания ссылки   На рис. 11.4 изображен получившийся в результате "массив массивов" (Аrray of Аrrays, AoA), представляющий собой многомерный массив.     Рис. 11.4. Организация многомерного 'массива массивов' Для вывода значений многомерного массива обычно используется нужное число вложенных циклов for или других циклических конструкций:   # цикл по строкам (элементам массива верхнего уровня) for (my $row = 0; $row < @{$ref2RxC}; $row++) { # цикл по столбцам (элементам вложенных массивов) for (my $col = 0; $col < @{$ref2RxC->[$row]}; $col++) { print "$ref2RxC->[$row][$col] "; } print "\n"; }   В результате выполнения этой программы построчно будет выведено значение всех элементов из массива массивов:   1.1 1.2 1.3 1.4 1.5 2.1 2.2 2.3 2.4 2.5 3.1 3.2 3.3 3.4 3.5   В любой массив можно поместить список ссылок на другие программные объекты, например, таким образом:   @reference_list = (\$scalar, \@array, \%hash);   Можно записать то же самое более простым способом, поставив операцию взятия ссылки перед списком объектов в круглых скобках:   @reference_list = \($scalar, @array, %hash);   Списки ссылок на объекты могут, например, передаваться в подпрограмму для изменения перечисленных в списке объектов. Передача аргументов в подпрограммы по ссылке и по значению будет рассмотрена в следующей лекции.     Если попытаться разыменовать ссылку на несуществующий объект, то он автоматически будет создан. В этом случае работает удивительный механизм, называемый автосозданием объекта ссылки (буквально: "автооживление" - autovivification). Например, во время обращения по ссылке к элементу массива автоматически создается массив из пяти элементов, ссылка на него присваивается в переменную $array_ref, а пятый элемент получает начальное значение:   $array_ref->[4] = '5-й элемент'; # присваивание значения print ref($array_ref); # вызывает к жизни массив print scalar(@{$array_ref}); # из 5 элементов! print $$array_ref[4]; # печатаем значение




Поделиться с друзьями:


Дата добавления: 2014-11-25; Просмотров: 426; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.015 сек.