Глава 2В этой главе:
Скалярные операции Скалярные переменные Скалярные операции и функции <STDIN> как скалярное значение Упражнения Скалярные данныеЧто такое скалярные данные Скаляр ≈ это простейший вид данных, которыми манипулирует Perl. Скаляр ≈ это либо число (допустим, 4 или 3.25е20), либо строка символов (например, hello или Gettysburg Address). Хотя в общем-то числа и строки ≈ это совершенно разные вещи, в Perl они используются практически как взаимозаменяемые понятия, поэтому мы опишем их в одной главе.Над скалярной величиной можно производить операции (например, суммирование или конкатенацию), полученный результат, как правило, также является скаляром. Скалярную величину можно сохранять в скалярной переменной. Скаляры можно читать из файлов и с устройств, а также записывать в файлы и на устройства. Числа Хотя скаляр ≈ это либо число, либо строка*, в данный момент нам будет полезно рассмотреть их отдельно. Итак, сначала числа, а через минуту ≈ строки.В Perl для всех чисел используется один и тот же внутренний форматКак станет ясно из нескольких следующих абзацев, можно задавать и целые (чисто числовые значения, например 17 или 342), и числа с плавающей запятой (действительные числа, например 3,14 или 1,35, умноженное на 1025). При этом
* Или ссылка, но это более сложная тема.во внутренних вычислениях Perl использует только значения с плавающей запятой двойной точности*. Это значит, что внутренних целых величин в Perl нет; целочисленная константа в программе рассматривается как эквивалентное значение с плавающей запятой**. Вы, вероятно, не заметите этого преобразования (или попросту проигнорируете его), но в любом случае не нужно искать целочисленные операции (как дополнение к операциям с плавающей запятой), ибо их попросту нет.Литералы с плавающей запятой Литерал ≈ это способ представления величины в тексте Perl-программы. В своей программе вы можете называть литерал константой, но мы будем пользоваться термином литерал. Литералы ≈ это способ представления данных в исходном тексте вашей программы как входной информации для компилятора Perl. (Данные, которые читаются из файлов или записываются в файлы, трактуются похоже, но не совсем так.)Perl принимает полный набор литералов с плавающей запятой, которыми пользуются программисты, работающие на С. Допускаются числа с десятичными запятыми и без них (включая необязательный префикс "плюс" или "минус"). Кроме того, можно использовать показатель степени числа десять (экспоненциальное представление) с буквой Е. Например:1.25 # около единицы с четвертью 7.25е45 # 7,25, умноженное на 10 в 45-й степени (большое число)-6.5е24 # минус 6,5, умноженное на 10 в 24-й степени# ("большое" отрицательное число) -12е-24 # минус 12, умноженное на 10 в минус 24-й степени# (очень маленькое отрицательное число) -1.2Е-23 # еще одна форма записи этого числа Целочисленные литералы Целочисленные литералы также весьма просты, например: 12 15 -2004 3485 Не начинайте целое число с нуля, потому что Perl поддерживает восьмеричные и шестнадцатеричные литералы. Восьмеричные числа начинаются с нуля, а шестнадцатеричные ≈ с Ох или ох***. Шестнадцатеричные цифры- Значение с плавающей запятой двойной точности ≈ это то, что компилятор С, который компилировал Perl, использовал для объявления double.-* Если только вы не используете "целочисленный режим", но по умолчанию он не включен.-** "Начальный нуль" работает только в литералах, но не действует при автоматическом преобразовании строк в числа. Строку данных, выглядящую как восьмеричное или шест-надцатеричное значение, можно преобразовать в число с помощью функций oct или hex.от А до F (в любом регистре) обозначают обычные цифровые значения от 10 до 15. Например:0377 t восьмеричное 377, то же самое, что десятичное 255-Oxff # Строки Строки ≈ это последовательности символов (например, hello). Каждый символ представляет собой 8-битовое значение из 256-символьного набора (при этом символ NUL ничего особенного, как в некоторых языках, собой не представляет).Самая короткая из возможных строк не содержит ни одного символа. Самая длинная строка заполняет всю наличную память (но сделать с ней что-либо вы вряд ли сможете). Это соответствует принципу "отсутствия встроенных ограничений", которому Perl следует при каждой возможности. Обычно строки представляют собой последовательности букв, цифр и знаков препинания, коды которых лежат в диапазоне ASCII 32 ≈ 126. Однако возможность наличия в строке любого символа с кодом от 0 до 255 означает, что вы можете создавать, просматривать необработанные двоичные данные и манипулировать ими как строками ≈ то, что вызвало бы серьезные трудности в большинстве других языков. (Например, можно "залатать" свою операционную систему, прочитав нужный фрагмент кода как Perl-строку, внеся изменение и записав результат обратно на диск.)Как и числа, строки могут иметь литеральное представление (способ представления строкового значения в Perl-программе). Литеральные строки бывают двух видов: в одинарных кавычках и в двойных кавычках*. Есть еще одна похожая форма: строка в обратных кавычках ('вот такая'). Это не столько литеральная строка, сколько способ выполнения внешних команд и получения их результатов. Более подробно этот вопрос рассматривается в главе 14.Строки в одинарных кавычках Строка в одинарных кавычках представляет собой последовательность символов, заключенную в одинарные кавычки. Одинарные кавычки частью самой строки не являются, они служат лишь для того, чтобы Perl мог определить начало и окончание строки. Все символы, стоящие между кавычками (в том числе символы новой строки, если строка разбивается на несколько экранных строк), действительны внутри строки. Два исключения:чтобы вставить одинарную кавычку в строку, уже заключенную в одинарные кавычки, поставьте перед ней обратную косую черту. Для того чтобы вставить * Есть также here -строки, похожие на here-локу менты shell. Они рассматриваются в главе 19, Программирование CGI. См. также главу 2 книги Programming РеНи man-страницу pcrldata( I).в строку в одинарных кавычках обратную косую, поставьте перед ней еще одну обратную косую черту. Примеры: 'hello' # пять символов: h, e, 1, 1, о'don\'t' # пять символов: d, о, п, одинарная кавычка, t'' # пустая строка (без символов)'silly\\me' # silly, обратная косая, те'hello\n' # hello, обратная косая, п'hello there' # hello, новая строка, there (всего 11 символов)Отметим, что пара символов \п внутри строки в одинарных кавычках интерпретируется не как символ новой строки, а как два символа: обратная косая и п. (Обратная косая имеет специальное значение только в том случае, если за ней следует еще одна обратная косая или одинарная кавычка.)Строки в двойных кавычках Строка в двойных кавычках действует почти так же, как С-строка. Это тоже последовательность символов, но на этот раз ≈ заключенная в двойные кавычки. Теперь, однако, обратная косая приобретает полную силу и может задавать определенные управляющие символы и вообще любой символ в восьмеричном и шестнадцатеричном форматах. Вот некоторые строки в двойных кавычках:"hello world\n" # hello world и новая строка"new \177" # new, пробел и символ удаления (восьмеричное 177)"coke\tsprite" # coke, знак табуляции, spriteШироко используются сочетания обратной косой черты с различными символами (так называемая управляющая последовательность с обратной косой). Полный перечень управляющих последовательностей, которые применяются в строках в двойных кавычках, приведен в табл. 2.1.Таблица 2.1. Управляющие последовательности
Еще одна особенность строк в двойных кавычках состоит в том, что в них производится интерполяция переменных, т.е. при использовании строки все скалярные переменные и переменные-массивы в ней заменяются их текущими значениями. Мы, однако, формально еще не знакомы с тем, что такое переменная (за исключением краткого обзора, данного в главе 1), поэтому мы вернемся к этому вопросу позднее.Скалярные операции Оператор обозначает проведение определенной операции, благодаря которой создается новое значение (результат) из одного или нескольких других значений (операндов). Например, символ + обозначает операцию, потому что при его использовании берутся два числа (операнда, например, 5 и 6) и создается новое значение (11, результат).Вообще говоря, операции и выражения Perl представляют собой надмножество операций и выражений, имеющихся в большинстве других АЛГОЛ-и Паскаль-подобных языков программирования (вроде С или Java). При выполнении операции предполагается наличие или числовых, или строковых операндов (либо сочетания операндов этих типов). Если вы введете строковый операнд там, где должно быть число, или наоборот. Perl автоматически преобразует этот операнд, используя весьма нечетко сформулированные правила, которые мы подробно рассмотрим ниже в разделе "Преобразование чисел в строки и обратно".Операции над числами В Perl применяются обычные операции сложения, вычитания, умножения, деления и т.д. Например:2+3 #2 плюс 3, или 5 5.1-2.4 #5,1 минус 2,4, или приблизительно 2,7 3 * 12 #3 умножить на 12 = 36 14/2 #14 делить на 2, или 7 10.2/0.3 # 10,2 делить на 0,3, или приблизительно 34 10/3 # всегда означает деление чисел с плавающей запятой, # поэтому результат приблизительно равен 3,3333333...Кроме того, в Perl используется ФОРТРАН-подобная операция возведения в степень, по которой многие тоскуют в Паскале и С. Эта операция обозначается двумя звездочками, например 2**3 равно двум в степени три, или восьми. (Если этот результат "не помещается" в число с плавающей запятой двойной точности, например, отрицательное число возводится в нецелую степень или большое число возводится в большую степень, выдается сообщение об ошибке ≈ fatal error)Perl поддерживает также операцию деления с остатком. Значение выражения 10 % 3 ≈ остаток от деления 10 на 3, или 1. Оба значения сначала сокращаются до целых, т.е. 10.5 % 3.2 вычисляется как 10 % 3.Операции логического сравнения следующие: <, <=, ===, >==, >, !=. Эти операции сравнивают два значения в числовом формате и возвращают значение "истина" (true) или "ложь" (false). Например, операция 3 > 2 возвращает значение "истина", потому что три больше, чем два, тогда как операция 5 != 5 возвращает "ложь", потому что утверждение, что пять не равно пяти ≈ неправда. Определение значений "истина" и "ложь" рассматривается позже, а пока можно считать, что "истина" ≈ это единица, а "ложь" ≈ нуль. (Вы еще увидите эти операции в табл. 2.2.)Вас, вероятно, удивило слово "приблизительно" в комментариях к примерам, которые мы привели в начале этого раздела. Разве при вычитании 2, 4 из 5,1 не получается точно 2, 7? На уроке математики, может быть, и получается, но в компьютерах, как правило, ≈ нет. В вычислительной технике получается приближенное значение, которое точно лишь до определенного числа десятичных разрядов. Числа в компьютерах хранятся не так, как их представляет себе математик. Впрочем, если вы не делаете чего-нибудь сверхсложного, то, как правило, увидите именно те результаты, которых ожидаете.Сравнивая приведенные ниже операторы, вы увидите, что в действительности компьютер получил в результате вышеупомянутого вычитания (функция print f описывается в главе б):printf ("%.51\n", 5.1 - 2.4) # 2.699999999999999733546474089962430298328399658203125 print(5.1 - 2.4, "\n") ; # 2.7 Не обращайте на это особого внимания: стандартный формат функции print для вывода на экран чисел с плавающей запятой обычно скрывает такие незначительные неточности представления. Если это создает какую-то проблему, следует воспользоваться объектными модулями Math::BigInt и Math::BigFloat ≈ в них реализована арифметика с бесконечной точностью для целых и чисел с плавающей запятой, только выполняются эти операции несколько медленнее. Подробности вы найдете в главе 7 книги Programming Perl и в интерактивной (сетевой) документации на эти модули.Операции над строками Строковые значения можно конкатенировать операцией ".". (Да, это именно одна точка.) Данная операция изменяет строки-операнды не более, чем операция 2+з изменяет 2 или 3. Строку-результат (более длинную) можно использовать в дальнейших вычислениях или сохранить в переменной."hello" . "world" # то же самое, что "helloworld" ∙hello world' . "\n" # то же самое, что "hello world\n" "fred" . " " . "barney" # то же самое, что "fred barney"Отметим, что конкатенацию нужно задавать явно при помощи знака ".", а не просто располагать два значения рядом друг с другом.Еще одна группа операций над строками -≈ операции сравнения. Эти операции похожи на соответствующие операции ФОРТРАНа, например it (меньше чем) и т.д. Операции сравнения строк сравнивают ASCII-значения символов строк обычным способом. Полный набор операций сравнения (как для чисел, так и для строк) приведен в таблице 2.2.Таблица 2.2. Операции сравнения чисел и строк
Вы, возможно, спросите, почему предусмотрены отдельные операции для чисел и строк, если числа можно автоматически преобразовывать в строки и наоборот. Давайте рассмотрим два значения, 7 и 30. Если их сравнить как числа, то 7, очевидно, меньше 30. Если же сравнить их как строки, то строка "30" идет перед строкой "7" (ведь ASCII-значение цифры 3 меньше ASCII-значения цифры 7), поэтому 30 меньше 7. Perl всегда требует указывать тип сравнения, то есть конкретизировать, какое именно сравнение, числовое или строковое, будет проводиться.Если вы уже имеете опыт программирования на shell в среде UNIX, вы, возможно, заметили, что эти числовые и строковые операции сравнения приблизительно противоположны тому, что подразумевается под ними в UNIX-команде test. В частности, для числового сравнения используется eq, а для строкового применяется знак =.Есть еще одна строковая операция ≈ операция повторения строки, знак которой ≈ строчная буква х. В результате выполнения этой операции возвращается столько конкатенированных копий левого операнда (строки), сколько указано в правом операнде (числе). Например:"fred" х 3 # "fredfredfred" "barney" х (4+1) # "barney" x 5, или# "barneybarneybarneybarneybarney" (3+2) х 4 #5х4, или "5" х 4, т.е. "5555"Последний пример стоит объяснить подробнее. Круглые скобки указывают на то, что эту часть выражения нужно вычислить первой. (Круглые скобки здесь работают так же, как в обычной математике.) Однако в операции повторения строки левый операнд должен быть строкой, поэтому число 5 преобразуется в односимвольную строку "5" (правила этого преобразования мы рассмотрим позднее). Эта строка копируется четыре раза, что в итоге дает четырехсимвольную строку 5555. Если бы мы поменяли операнды местами, то у нас было бы пять копий строки 4, т.е. 44444. Это показывает, что повторение строки ≈ некоммутативная операция.При необходимости число копий (правый операнд) сначала усекается до целого значения (4, 8 превращается в 4). Если указать число копий, меньшее единицы, в результате выполнения операции получится пустая строка (строка нулевой длины).Приоритет и ассоциативность операций Разным операциям присваивается разный приоритет Это позволяет избежать неоднозначности такого рода, когда две операции пытаются манипулировать тремя операндами. Например, что выполнять в первую очередь в выражении 2+3*4 ≈ сложение или умножение? Если сначала выполнить сложение, мы получим 5*4, или 20. Если же сначала выполнить умножение (как нас учили на уроках математики), то мы получим 2+12, или 14. К счастью, в Perl выбран стандартный математический вариант, т.е. умножение выполняется первым. Поэтому мы говорим, что умножение имеет более высокий приоритет, чем сложение.Порядок выполнения операций, определяемый приоритетом, можно изменить с помощью круглых скобок. Выражение, заключенное в скобки, вычисляется в первую очередь, и лишь затем выполняется операция, стоящая за скобками (так, как нас учили на уроках математики). Следовательно, если бы нам захотелось выполнить сложение до умножения, необходимо было бы записать (2+3)*4, что дало бы в результате 20. Если вы хотите напомнить, что умножение выполняется перед сложением, можете добавить "декоративные", функционально бесполезные круглые скобки: 2+ (3*4).При выполнении операций сложения и умножения* очередность их выполнения определяется достаточно просто, но, скажем, при конкатенации строк в сочетании с возведением в степень могут возникнуть проблемы. Единственно верный путь разрешить их ≈- обратиться к официальной, не предполагающей никаких исключений, таблице приоритетов Perl-операций. (Это табл. 2.3. Отметим, что некоторые из операций нами еще не описаны;более того, они могут так и не появиться на страницах этой книги. Пусть, однако, этот факт не отпугнет вас.) Операции, аналогичные операциям С, имеют тот же приоритет, что и в этом языке. Таблица 2.3. Ассоциативность и приоритет операций: от высокого к низкому
* Вы хорошо помните алгебру? Если нет, то в повсеместном использовании круглых скобок ничего предосудительного нет.В этой таблице каждая операция имеет более высокий приоритет, чем перечисленные за ней, и более низкий приоритет, чем перечисленные перед ней. Операции одного уровня приоритетов разрешаются в соответствии с правилами ассоциативности. Как и приоритет, ассоциативность определяет порядок выполнения операций, если две операции с одинаковым приоритетом пытаются манипулировать тремя операндами: 2 ** з ** 4 # 2 ** (3 ** 4) , или 2 ** 81, или около 2.41е24 72/12/3 # (72 / 12) / 3, или 6/3, или 2 30 / 6 * 3 # (30/6) *3, или 15В первом случае операция ** имеет ассоциативность справа, поэтому круглые скобки подразумеваются справа. Операции * и / имеют ассоциативность слева, поэтому круглые скобки подразумеваются слева.Преобразование чисел в строки и обратно Если строковое значение используется как операнд в операции с числами (например, в операции сложения), Perl автоматически преобразует эту строку в эквивалентное числовое значение, как если бы оно было введено в виде десятичного числа с плавающей запятой*. Нечисловые окончания и начальные пробельные символы игнорируются, поэтому " 123. 4 5 f red" (с начальным пробелом) без какого-либо предупреждения преобразуется в 123. 45**. Самый крайний из подобных случаев ≈ когда нечто, не являющееся числом, вообще без предупреждения преобразуется в нуль (как строка fred, которую мы использовали здесь как число).Если же, наоборот, там, где должно быть строковое значение, вводится числовое (например, в операции конкатенации строк), это числовое значение конвертируется в строку, которая была бы выведена на экран вместо него. Например, если вы хотите конкатенировать строку х с результатом умножения 4 на 5, это можно записать как"X" .(4*5) f то же самое, что "X" . 20, или "Х20"(Помните, что круглые скобки заставляют сначала выполнить 4*5, а затем выполнять операцию конкатенации.)Другими словами, вам не нужно (в большинстве случаев) беспокоиться о том, что указано в качестве операнда ≈ строка или число, поскольку Perl выполняет все необходимые преобразования самостоятельно.* Шестнадцатеричные и восьмеричные значения этому автоматическому преобразованию не подлежат. Для интерпретации таких значений следует использовать функции hex и oct.** Если в командной строке не указана опция -w. В целях обеспечения безопасности всегда задавайте эту опцию.Скалярные переменные Имя переменной ≈ это имя контейнера, который содержит одно или более значений. Имя переменной остается постоянным на протяжении всей программы, но значение (или значения), содержащееся в этой переменной, как правило, в ходе выполнения программы непрерывно изменяется.Скалярная переменная содержит одно скалярное значение (представляющее собой число, строку или ссылку). Имена скалярных переменных состоят из знака доллара и буквы, за которой могут следовать еще несколько букв, цифр и знаков подчеркивания*. Строчные и прописные буквы различаются: переменная $А и переменная $а ≈ разные. Все буквы, цифры и знаки подчеркивания в имени переменной имеют значение. Так, переменная$a_very_long_variable_that_ends_in_l отличается от переменной $a_very_long_variable_that_ends_in_2 Имена переменных следует, как правило, подбирать так, чтобы они имели какой-то смысл в связи со значением переменной. Например, имя $xyzl23, вероятно, не очень описательно, в отличие от $line_length.Скалярные операции и функции Самая распространенная операция, выполняемая над скалярной переменной ≈ присваивание, которое представляет собой способ задания значения этой переменной. Операция присваивания в Perl обозначается знаком равенства (почти как в С и ФОРТРАНе). С левой стороны ставится имя переменной, с правой ≈ присваиваемое ей значение или выражение, при помощи которого это значение вычисляется, например:$а =17; # присвоить переменной $а значение 17$b = $а + 3; # присвоить $Ь текущее значение $а плюс 3 (20)$b == $b * 2; # присвоить $b значение $b, умноженное на 2 (40)Обратите внимание: в последней строке переменная $Ь используется дважды: один раз для получения значения (в правой части), а второй ≈ для указания, куда поместить вычисленное выражение (в левой части). Это допустимый, надежный и довольно распространенный прием. Распространен он настолько, что через минуту мы увидим, как все это можно записать в сокращенном виде.Возможно, вы заметили, что скалярные переменные всегда предваряются знаком $. В shell знак $ используют для получения значения, а при присваивании нового значения его не указывают. В Java и С этот символ* Их количество ограничено числом 255. Надеемся, этого достаточно. 2. Скалярные данныеВ этой таблице каждая операция имеет более высокий приоритет, чем перечисленные за ней, и более низкий приоритет, чем перечисленные перед ней. Операции одного уровня приоритетов разрешаются в соответствии с правилами ассоциативности. Как и приоритет, ассоциативность определяет порядок выполнения операций, если две операции с одинаковым приоритетом пытаются манипулировать тремя операндами: 2 ** 3 ** 4 # 2 ** (3 ** 4) , или 2 ** 81, или около 2.41е24 72/12/3 # (72 / 12) / 3, или 6/3, или 2 30 / 6 * 3 # (30/6)*3, или 15В первом случае операция ** имеет ассоциативность справа, поэтому круглые скобки подразумеваются справа. Операции * и / имеют ассоциативность слева, поэтому круглые скобки подразумеваются слева.Преобразование чисел в строки и обратно Если строковое значение используется как операнд в операции с числами (например, в операции сложения), Perl автоматически преобразует эту строку в эквивалентное числовое значение, как если бы оно было введено в виде десятичного числа с плавающей запятой*. Нечисловые окончания и начальные пробельные символы игнорируются, поэтому<< 12 3.4 5 f red" (с начальным пробелом) без какого-либо предупреждения преобразуется в 123. 45**. Самый крайний из подобных случаев ≈ когда нечто, не являющееся числом, вообще без предупреждения преобразуется в нуль (как строка fred, которую мы использовали здесь как число).Если же, наоборот, там, где должно быть строковое значение, вводится числовое (например, в операции конкатенации строк), это числовое значение конвертируется в строку, которая была бы выведена на экран вместо него. Например, если вы хотите конкатенировать строку х с результатом умножения 4 на 5, это можно записать как"X" .(4*5) # то же самое, что "X" . 20, или "Х20"(Помните, что круглые скобки заставляют сначала выполнить 4*5, а затем выполнять операцию конкатенации.)Другими словами, вам не нужно (в большинстве случаев) беспокоиться о том, что указано в качестве операнда ≈ строка или число, поскольку Perl выполняет все необходимые преобразования самостоятельно.* Шестнадцатеричные и восьмеричные значения этому автоматическому преобразованию не подлежат. Для интерпретации таких значений следует использовать функции hex и oct.** Если в командной строке не указана опция -w. В целях обеспечения безопасности всегда задавайте эту опцию.Скалярные переменные Имя переменной ≈ это имя контейнера, который содержит одно или более значений. Имя переменной остается постоянным на протяжении всей программы, но значение (или значения), содержащееся в этой переменной, как правило, в ходе выполнения программы непрерывно изменяется.Скалярная переменная содержит одно скалярное значение (представляющее собой число, строку или ссылку). Имена скалярных переменных состоят из знака доллара и буквы, за которой могут следовать еще несколько букв, цифр и знаков подчеркивания*. Строчные и прописные буквы различаются: переменная $А и переменная $а ≈ разные. Все буквы, цифры и знаки подчеркивания в имени переменной имеют значение. Так, переменная$a_very_long_variable_that__end.s__in__l отличается от переменной $a_very_long_variable_that__ends_in_2 Имена переменных следует, как правило, подбирать так, чтобы они имели какой-то смысл в связи со значением переменной. Например, имя $xyzl23, вероятно, не очень описательно, в отличие от $line_length.Скалярные операции и функции Самая распространенная операция, выполняемая над скалярной переменной ≈ присваивание, которое представляет собой способ задания значения этой переменной. Операция присваивания в Perl обозначается знаком равенства (почти как в С и ФОРТРАНе). С левой стороны ставится имя переменной, с правой ≈ присваиваемое ей значение или выражение, при помощи которого это значение вычисляется, например:$а =17; # присвоить переменной $а значение 17$b = $а + 3; # присвоить $Ь текущее значение $а плюс 3 (20)$b = $b * 2; # присвоить $b значение $b, умноженное на 2 (40)Обратите внимание: в последней строке переменная $Ь используется дважды: один раз для получения значения (в правой части), а второй ≈ для указания, куда поместить вычисленное выражение (в левой части). Это допустимый, надежный и довольно распространенный прием. Распространен он настолько, что через минуту мы увидим, как все это можно записать в сокращенном виде.Возможно, вы заметили, что скалярные переменные всегда предваряются знаком $. В shell знак $ используют для получения значения, а при присваивании нового значения его не указывают. В Java и С этот символ* Их количество ограничено числом 255. Надеемся, этого достаточно.вообще опускается. Если вы постоянно присваиваете одной или нескольким переменным новые значения, то неминуемо будете делать ошибки. (Наше решение заключалось в том, чтобы прекратить писать программы на shell, awk и С, но для вас этот путь может быть неприемлем.)Скалярное присваивание не только является операцией, его можно использовать и в качестве значения, аналогично тому как это делается в С. Другими словами, выражение $а=3 имеет значение, аналогично тому как имеет некоторое значение выражение $а+3. Значением является та величина, которая присваивается, т.е. $а=3 имеет значение 3. Хотя на первый взгляд это может показаться несуразным, использование присваивания как значения полезно, если вы хотите присвоить переменной промежуточное значение в выражении или просто скопировать одно значение в несколько переменных. Например:$Ь = 4 + ($а =3); # присвоить 3 переменной $а, затем прибавить к 4,# в результате чего $Ь получит значение 7 $d = ($с = 5); # скопировать 5 в $с, а затем и в $d $d = $с = 5; # то же самое, но без круглых скобокПоследнее выражение работает, потому что присваивание имеет ассоциативность справа. Операции присваивания с вычислением Выражения типа $ а == $а + 5 (где переменная стоит по обе стороны от оператора присваивания) встречаются довольно часто, поэтому в Perl применяется сокращенный метод записи операции изменения переменной ≈ операция присваивания с вычислением. Почти все двоичные операции, с помощью которых вычисляются значения, имеют соответствующую форму с добавленным знаком равенства. Например, следующие две строки эквивалентны:$а = $а + 5; # без операции присваивания с вычислением $а += 5; # с операцией присваивания с вычислениемЭквивалентны и эти строки: $Ь = $Ь * 3;$b *= 3; В каждом из вышеприведенных случаев данная операция вызывает изменение существующего значения переменной определенным способом, а не просто замену этого значения результатом вычисления какого-то нового выражения. Другой распространенной операцией присваивания является операция конкатенации строк: $str = $str . " "; # добавить пробел к $str $str .= " "; # то же самое, но с операцией присваиванияПочти все двоичные операции, записанные таким образом, допустимы. Например, операция возведения в степень записывается как * * =. Так, $ а * * = 3 означает "возвести число, содержащееся в переменной $а, в третью степень и поместить результат обратно в $а".Как и простая операция присваивания, эти операции также могут быть использованы в качестве значения, которым является новое значение переменной. Например: $а = 3;$b = ($а += 4); # $а и $b теперь равны 7Автоинкремент и автодекремент Казалось бы, для прибавления единицы к $а можно просто записать $а += 1, но Perl идет на шаг дальше и сокращает даже эту запись. Операция ++ (автоинкремент) прибавляет к своему операнду единицу и возвращает ин-крементированное значение, например:$а += 1; # с операцией присваивания ++$а; # с префиксным автоинкрементом $d = 17;$е = ++$d; # и $е, и $d теперь равны 18Здесь операция ++ используется как префиксная, т.е. знак операции стоит слева от операнда. Автоинкремент можно записывать и в суффиксной форме (справа от операнда). В этом случае результатом выражения является старое значение переменной, которое она имела до инкрементирования. Например:$с = 17;$d = $с++; # $d равно 17, а $с равно 18Поскольку значение операнда изменяется, операнд должен быть скалярной переменной, а не просто выражением. Не стоит рассчитывать, что ++16 получит значение 17, и нельзя сделать так, чтобы ++($а+$Ь) каким-то образом стало больше, чем сумма $а и $Ь.Операция автодекремента (") похожа на операцию автоинкремента, но здесь не прибавляется единица, а вычитается. Как и операция автоинкремента, операция автодекремента имеет две формы ≈ префиксную и суф-фиксную. Например:$х = 12;--$х; # $х теперь равно 11$у = $х"; # $у равно 11, а $х - 10Операции автоинкремента и автодекремента выполняются и над значениями с плавающей запятой. Автоинкрементирование переменной со значением 4,2 дает, как и следовало ожидать, 5,2*.* Операция автоинкрементирования выполняется даже над строками. См. по данному вопросу книгу Programming Perl или man-страницу perlop(\).Функции chop и chompВесьма полезной иногда бывает встроенная функция chop. Эта функция принимает один аргумент, указываемый в круглых скобках ≈ имя скалярной переменной ≈ и удаляет из строкового значения этой переменной последний символ. Например:$х = "hello world";chop($x); # $x теперь имеет значение "hello worl"Обратите внимание: значение аргумента здесь меняется, отсюда и требование к наличию скалярной переменной, а не просто скалярного значения. Писать chop (' suey'), чтобы превратить аргумент в 'sue', не имеет смысла, потому что места для хранения этого значения нет. Кроме того, можно ведь и просто написать: ' sue '.Возвращаемое значение для этой функции ≈ отброшенный символ (в приведенном выше примере с "hello world" это буква d). Следующий код, очевидно, неверен:$х == chop($x); # НЕВЕРНО: заменяет $х ее последним символом chop($x); # ВЕРНО: как и выше, удаляет последний символЕсли в функции chop задать пустую строку, то она ничего не сделает и ничего не возвратит, не выдавая сообщения об ошибке и вообще никак не реагируя*. Большинство операций в Perl имеют разумные граничные условия; другими словами, вы можете использовать их в пределах накладываемых ограничений и за ними, причем часто без какой-либо реакции с их стороны. Некоторые утверждают, что это один из фундаментальных недостатков Perl, а другие пишут первоклассные программы, нисколько не утруждая себя заботой о соблюдении этих ограничений. Вам решать, к какому лагерю присоединяться.При усечении уже усеченной строки отбрасывается еще один символ. Например: $а = "hello world\n";chop $a; # теперь $а имеет значение "hello world" chop $a; # оп-ля! теперь $а имеет значение "hello worl"Если вы не уверены в том, есть ли в конце переменной символ новой строки, можете использовать несколько более безопасную операцию chomp, которая удаляет только символ новой строки**, например:$а == "hello world\n";chomp ($a); # теперь $а имеет значение "hello world" chomp ($a); # ага! никаких изменений в $а не произошло* Если вы не используете соответствующий здравому смыслу ключ -w.** Или иное значение, которое задано переменной $ \ в качестве разделителя входных записей.Интерполяция скаляров в строках Если строковый литерал взят в двойные кавычки, в нем необходимо выполнить интерполяцию переменных (помимо проверки на наличие управляющих последовательностей с обратной косой). Это значит, что строка просматривается на предмет наличия имен скалярных переменных* ≈ а именно комбинаций знака доллара с буквами, цифрами и знаками подчеркивания. Если ссылка на переменную имеется, она заменяется текущим значением этой переменной (или пустой строкой, если значение переменной еще не присвоено). Например:$а = "fred";$b = "some text $a"; # $b имеет значение "some text fred" $c = "no such variable $what"; # $c имеет значение "no such variable "Текст, который заменяет переменную, не просматривается, т.е. даже при наличии в нем знаков доллара никакие дальнейшие замены не производятся: $х = *$fred'; # буквально знак доллара и слово "fred" $у = "hey $х"; # значение ≈ 'hey $fred'; двойной подстановки нетЕсли необходимо предотвратить подстановку значения вместо имени переменной, необходимо либо изменить эту часть строки так, чтобы она стояла в одинарных кавычках, либо поставить перед знаком доллара обратную косую, которая отменяет его специальное значение: $fred = 'hi'; $barney = "a test of " . '$fred'; # буквально: 'a test of $fred' $barney2= "a test of \$fred"; # то же самоеВ качестве имени переменной будет взято самое длинное из возможных имен, имеющих смысл в этой части строки. Это может вызвать проблему, если вы хотите сразу же после заменяемого значения дать какой-то постоянный текст, который начинается с буквы, цифры или знака подчеркивания. Проверяя строку на предмет наличия имен переменных, Perl посчитал бы эти символы дополнительными символами имени ≈ а как раз этого вам и не нужно. В Perl имеется разделитель имени переменной. Просто заключите имя переменной в фигурные скобки. Другой вариант ≈ завершить эту часть строки и начать другую часть строки знаком операции конкатенации:$fred = "pay"; $fredday = "wrong!"; $barney = "It's $fredday"; # не день зарплаты payday, a "It's wrong!" $barney = "It's ${fred}day"; # теперь $barney получает значение "It's payday" $barney2 = "It's $fred"."day"; # еще один способ $barney3 = "It's " . $fred . "day"; # и еще один* И переменных-массивов, но этот вопрос мы будем рассматривать в главе 3 Массивы и списочные данные.Для изменения регистра букв, задействованных в интерполяции переменных, можно использовать специально предназначенные для этого строковые управляющие последовательности*. Например: $bigfred = "\Ufred"; # $bigfred имеет значение "FRED"$fred = "fred"; $bigfred = "\U$fred"; # то же самое$capfred = "\u$fred"; # $capfred имеет значение "Fred"$barney = "\LBARNEY"; # $barney теперь имеет значение "barney"$capbarney = "\u\LBARNEY"; # $capbarney теперь имеет значение "Barney"$bigbarney = "BARNEY"; $capbarney = "\u\L$bigbarney"; # то же самоеКак видите, изменяющие регистр строковые управляющие последовательности хранятся до тех пор, пока не окажут свое воздействие, поэтому, несмотря на то, что первая буква слова barney не стоит непосредственно за символами \и, она становится прописной благодаря воздействию \и.Термин "интерполяция переменных" иногда заменяют термином "интерполяция двойных кавычек", потому что интерполяция выполняется в строках, заключенных в двойные кавычки. (А также в строках, заключенных в обратные кавычки, которые мы рассмотрим в главе 14.)<STDIN> как скалярное значениеЕсли вы ≈ типичный хакер, то, вероятно, давно уже задаетесь вопросом:а как же ввести в Perl-программу какое-либо значение? Вот самый простой способ. Каждый раз, когда там, где требуется скалярное значение, вы используете дескриптор <STDIN>, Perl читает следующую полную строку текста со стандартного ввода (до первого символа новой строки) и использует ее в качестве значения этого дескриптора. Термином "стандартный ввод" может обозначаться многое, но если вы не делаете в своей программе ничего необычного, это означает терминал пользователя, вызвавшего вашу программу (вероятнее всего, ваш собственный терминал). Если строки, которую можно было бы прочитать, еще нет (типичный случай, если только вы заранее не набрали полную строку), Perl-программа останавливается и ждет, пока вы не введете какие-нибудь символы и вслед за ними символ перехода на новую строку.В конце строкового значения дескриптора <STDIN> обычно стоит символ новой строки. Чаще всего от этого символа нужно избавляться сразу же (ведь между hello Hhello\n ≈ большая разница). Здесь и приходит на помощь знакомая нам функция chomp. Типичная последовательность ввода выглядит примерно так:$а = <STDIN>; # читаем текст chomp($a); # избавляемся от надоедливого символа новой строки* Вы, возможно, придете к выводу, что легче воспользоваться функциями uc, ucfirst, lc И Icfirst.Общепринятое сокращение этих двух строк выглядит так: chomp($a = <STDIN>) ; Присваивание внутри круглых скобок продолжает относиться к $а даже после того, как этой переменной уже присвоено значение. Таким образом, функция chomp оперирует с переменной $а. (Это вообще справедливо для операции присваивания; присваиваемое выражение можно использовать везде, где необходима переменная, а действия относятся к переменной, стоящей слева от знака равенства.)Вывод с помощью функции printИтак, мы вводим значения с помощью дескриптора <stdin>. А как их вывести из программы? С помощью функции print. Эта функция принимает значения, стоящие в скобках, и выдает их без всяких украшений на стандартный вывод. Стандартный вывод ≈ это опять-таки ваш терминал (если вы не делаете в программе ничего необычного). Например:print("hello world\n"); # выводится hello world с символом новой строки print "hello world\n"; # то же самоеОбратите внимание на второй пример, где показана форма функции print без круглых скобок. Использовать скобки или нет ≈ это, главным образом, вопрос стиля и быстроты набора, но есть несколько случаев, где скобки обязательны во избежание двусмысленности.Мы увидим, что для функции print можно задавать список значений, но поскольку про списки мы еще не говорили, отложим этот вопрос до главы 6.Значение undefЧто будет, если использовать скалярную переменную до того, как ей присвоено значение? Ничего серьезного, в общем-то, не произойдет. До присваивания значения переменные имеют значение undef. При использовании в качестве числа это значение выглядит как нуль, а при использовании в качестве строки ≈- как пустая строка нулевой длины. Впрочем, при работе с ключом -w вы получите предупреждение ≈ это хороший способ вылавливания ошибок программирования.Многие операции возвращают undef, когда их аргументы выходят за пределы диапазона или не имеют смысла. Если вы не делаете ничего особенного, вы получите в подобном случае нуль или пустую строку без серьезных последствий. На практике это едва ли представляет собой проблему.Одна из уже знакомых нам операций, которая в определенных обстоятельствах возвращает undef ≈ это операция <stdin>. Обычно она возвращает следующую из прочитанных строк; если же строк для чтения больше нет (например, когда вы нажали на терминале клавиши [Ctri+D] или когда в файле больше нет данных), то <stdin> возвращает значение undef. В главе 6 мы посмотрим, как осуществить проверку в данной ситуации и выполнить специальные действия, если данных для чтения больше нет.Упражнения Ответы к упражнениям приведены в приложении А. 1. Напишите программу, которая вычисляет длину окружности с радиусом 12, 5. Длина окружности равна 2я (около 2 * 3,141592654) радиусам.2. Модифицируйте программу из предыдущего упражнения так, чтобы она запрашивала и принимала значение радиуса окружности у пользователя.3. Напишите программу, которая запрашивает и считывает два числа, после чего выводит на экран результат перемножения этих чисел.4. Напишите программу, которая считывает строку и число и выводит на экран строку столько раз, сколько задано числом, причем каждый раз с новой строки. (Совет: используйте оператор х.) |
HIVE: All information for read only. Please respect copyright! |