Perl简易教程(安装——控制结构)
Ich_liebe_dich
2019-11-18 14:05:46
每有一门优秀的计算机语言被尘封,都是世界编程界的一大损失。——Ich_liebe_dich
~~这篇文章风格比较严肃,不喜勿喷。~~
Perl作为一种并不大众也并不小众的**解释性**语言,在洛谷的编译器里面处于几乎最底端的位置。
传说Perl的不成器主要是因为它的语法太过~~优美~~,这点我深表认同。但是,我毕竟是这门语言的使用者之一,我就有宣传它、美化它的义务。毕竟,Perl这个语言在某些程度上所达到的高度,还是很多其它语言完全无法比拟的。
(今天所讲全部内容仅限Perl5,Perl6与Perl5相比简直是全新的一门语言,再次不做介绍)
### 所以今天,我们来学习Perl。
Perl是一门解释性语言,编译器识别的就是源代码,简单来说就是全开源。
这是Perl的劣势之一,但Perl的开发者说过,只要知道你用哪种语言写的,你的代码从来都是开源的。
所以,接下来抛去这一点不谈,我们来下载Perl解释器。
解释器推荐使用[Active Perl](https://www.activestate.com/products/perl/downloads/)或者[Stawberry Perl](http://strawberryperl.com/)。这两个编译器实现了Perl规范里面大部分的功能,兼容性也不错,还是免费的。
**下载下来后,注意一下Perl的版本(在任何操作系统上对命令行输入perl -v即可)**
这里主要介绍Windows下的操作(因为我常用的就是Windows),至于Linux下的操作其实也差不多(指命令行上),如果使用过程中遇到麻烦,可以去相应官网查找你所需要的东西。
(每一个优秀的Perler都应该学会使用CPAN。但是,作为新手,里面的大部分东西实际上并不需要用,故此处先忽略。)
## 正题1:Perl的正确运行方式
运行Perl并不困难,在Windows下拥有文件名后缀.pl,在Linux下打开就有明显的头行Shebang(待会儿再讲)。
Windows下双击文件即可,默认启动方式是Perl.exe。如果不是,又不会调,再次安装又无法自动修改默认打开方式,没关系,还有第二种用法——命令行。
在命令行里面输入你要运行的Perl文件的相对/绝对路径即可。格式:
```
>perl file\x.pl
```
Linux下则是:
```
>perl file/x
```
差不多就是了,可以进行运行便足矣。
## 正题2:shebang行
这个行被作为Perl诞生在Unix系列操作系统的象征。这一行本来是作为文件类型识别的,但是由于文件名后缀的产生,逐渐失去了它应有的功能,现在主要是作为一个开启编译开关的功能而存在。
Shebang即#!。由于Perl的注释刚好也是#(单行注释),所以可以把Shebang看作是一种特殊的注释。
一个单纯的Shebang行长这样:
```
#!/usr/bin/perl
#!perl
#!/usr/perl
#!/bin/perl
#!/usr/bin/lib/perl
```
以上格式取决于你的Perl安装路径,默认取第一个。
在perl后面可以加上各种各样的开关,常见有三个:
```
#!/usr/bin/perl -w -s -d
#-w代表warning,开启警告的意思
#-s代表strict,是use strict的缩写
#-d代表DeBugger,是开启调试的意思(这个开关别乱用不然怎么死的都不知道)
```
这些开关可以像个别语言一样缩在一起:
```
#!/usr/bin/perl-swd
```
Shebang的简单介绍也到此为止了,毕竟它现在的存在有无也无所谓了。不信试一下洛谷的老爷机,带不带Shebang都能通过。
## 正题三:开始输出
众所周知,一门计算机语言的起步就是学会了输出“Hello world!”。这句话如同字面意思,代表了一门新语言的诞生。
Perl有多种输出方法,简单来说就三种(以下三种完全等价):
```
print "Hello world!\n";
say "Hello world!";#注意这种写法只有部分编译器能通过
printf "Hello world!\n";
```
可见Perl语句是以;作为分隔符,而非换行。所以,**Perl的引号能括住换行符**。这里还有一个要点,Perl的双引号和单引号都代表字符串,但意思不一样,比如(换行符用(lb)(line break)表示):
```
print 'hello';#hello
print "hello";#hello
print 'a\nb';#a\nb
print "a\nb";#a(lb)b
print 'a\n
b';#a\n(lb)b
print "a\n
b";#a(lb)(lb)b
```
单引号不带转义,只有单引号和反斜杠能被转义,其余都是原字符。双引号则相反,双引号带转义。至于Perl转义的规则十分复杂,有可能牵扯到变量问题。在此暂未对变量做介绍,故不停留。
## 正题四:变量
Perl的输入流并不简单,这里先讲解与输入数据息息相关的东西:变量。
Perl变量有很多种类型:标量,列表,散列,子例程,句柄,引用,符号表(使用难度从前到后),先介绍标量。
### Perl标量
标量是Perl运用最广泛的变量类型。Perl标量值表达含义十分丰富,可以是字符串,也可以是数字,可以是undef(一个特殊的量),也可以是类和引用(类与引用过于复杂先不做讨论)。使用时无定义即为全局变量,默认值为undef。
```
print $a;#print out nothing
$a=0;#undef->0
print $a;#0
```
变量起名规则参考C语言,也**尽量不要**(毕竟Perl的机制允许变量名重用)与Perl内置变量名重复,详情请参考文档perlvar
```
>perldoc perlvar
```
变量值中值得注意的是undef。没有人知道它的值用二进制怎么表示,因为它是个类。但是,它可以进行运算。这里有一张运算符表,可以简单概括一些Perl常见运算及优先级(优先级从高到底,中文名放后面):
```
( 左括号
. -> :: 对象/库操作符
++ -- 自增自减(仅数字)
** 乘方(快速幂)
! ~ \ $ @(取布尔反、取反、取引号、解引用) 一元+- (正负号)
=~ !~ 字符串匹配(带KMP)
* / % x 乘法除运算符
(最后一个是字符串重复,使用方法:$a x $b表示把$a字符串重复$b次)
+ - . 加减运算符
(前面两个用于数字加减,最后一个是字符串加减)
<< >> 位移(位运算里面的)
命名一元操作符(比如函数、文件测试什么的)
< > <= => lt gt le ge 大小比较操作符(字母那几个用于比较字符串)
== != <=> eq ne cmp 同上
(<=>和cmp的用法:<=>是数字,cmp是字符串,如果左边的数小于右边的数返回-1,如果相等返回0,如果左边的数大于右边的数返回1。)
& 位运算
| ^ 同上
&& 比较操作符
|| // 同上
(//的用法:如果左边是undef则返回右边,否则返回左边)
注意:Perl的比较操作符返回的是第一个结束匹配的值(比如短路||在匹配到正确后会直接原地返回而不会判断右边,则返回左边的值)。
.. 列表操作符
?: 熟悉的三目操作符
= += -= *= /= %= .=等等 赋值运算
, => 逗号,胖箭头(用法和逗号几乎一样)
) 左括号
not 优先级最低的取反
and 同上
or xor 同上
注意:Perl会自动转化数字与字符串,具体什么类型看操作符,所以操作符选取很重要
```
**这里有两个注意,请看完再下一步。**
### Perl列表
带@前缀的列表的默认存储方式是链表,所以尽量少用索引方式访问(1和-1除外)。
使用习惯如下:
```
@a=(1,2,3);#(1,2,3)
@a=qw(1 2 3);#同上,qw为忽略空白符的意思
@a=qw/1 2 3/;#同上
@a=reverse @a;#(3,2,1)
$a[0];#3
$a[1];#2
$a[-1];#1
$a[-2];#2
push @a,"0";#(3,2,1,0)
$x=pop @a;#$x=0,@a=(3,2,1)
$x=shift @a#$x=3,@a=(2,1)
unshift @a,3;#(3,2,1)
splice @a,0,3,(1,2,3);#(1,2,3)
splice @a,0,0,(1,2,3);#(1,2,3,1,2,3)
splice @a,0,1;#(2,3,1,2,3)
splice @a,3,2;#(2,3,1)
```
数组操作单一,但是有其它的stl用法,比较复杂,本章不做深入讨论,在此举例一些简单的例子,可以参考一下它们的用处:
```
@a=qw(1 2 3);
@a=grep $_<3,@a;#(1,2)
@a=map $_*2,@a;#(2,4)
@a=map{($_-1,$_);}@a;#(1,2,3,4)
use Util::List qw(sum);
sum @a;#10
```
### Perl散列
散列操作比较单一,实现算法是树堆。一般使用具体如下:
```
%a={'wo',2,'ho',4};
%a={
wo=>2,
ho=>4,
};#等效写法,胖箭头等于逗号
#Perl花括号最后的,和;一般情况下都可省
$a{'wo'};#2
$a{ho};#4
#Perl花括号里引号引起的不带运算符空白符的非句柄非函数字符串可以省略引号
$a{'+'}=4;#新元素
$a{+};#非法!
```
散列里面的数据在存进去后会全部打乱。输出或者操作时习惯使用sort操作符,在此先用,等下介绍用法。
```
%a=(
wo=>1,
ho=>2,
ich=>3,
liebe=>4,
dich=>5,
);
keys %a;#随机
values %a;#随机
```