安徽理工大学 计算机科学与工程学院

99
安安安安安安 安安安安安安安安安安 Linux Linux 开开开开 开开开开 Development Foundation on Linux Development Foundation on Linux OS OS 开开 开开

Upload: sacha-hampton

Post on 02-Jan-2016

95 views

Category:

Documents


12 download

DESCRIPTION

Linux 开发基础 Development Foundation on Linux OS. 教师:赵宝. 安徽理工大学 计算机科学与工程学院. Outline. Shell programming on Linux OS GNU C/C++ programming CGI programming in C/C++ language Perl programming CGI programming in Perl language. Section 4 Perl programming. 4.1 编写第一个 Perl 程序. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: 安徽理工大学 计算机科学与工程学院

安徽理工大学 计算机科学与工程学院

LinuxLinux 开发基础开发基础Development Foundation on Linux OSDevelopment Foundation on Linux OS

教师:赵宝

Page 2: 安徽理工大学 计算机科学与工程学院

2

Outline

Shell programming on Linux OS

GNU C/C++ programming

CGI programming in C/C++ language

Perl programming

CGI programming in Perl language

Page 3: 安徽理工大学 计算机科学与工程学院

3

Section 4

Perl programming

Page 4: 安徽理工大学 计算机科学与工程学院

4

4.1 编写第一个 Perl 程序 第一步:选择一个自己喜欢的编译器,例如我们选择 vi

编辑器。 第二步:在编辑器中输入 Perl 程序: vi helloworld.pl 代码如下: helloworld.pl #! /usr/bin/perl print “Hello,word!\n”; 第三步:设置该文件为可执行文件: chmod +x helloworld.pl 第四步:运行程序即可: $./helloworld.pl

Page 5: 安徽理工大学 计算机科学与工程学院

5

4.1.1 提问并保留结果 在此基础上做稍微复杂一点的改变,我们使该程序按你的

名字打招呼。要做到这一点,需要一个变量来存放姓名。我们使用 $name 来保存姓名。

   #!/usr/bin/perl   printf " 请问您的姓名 ?";   $name=<STDIN>;   chop($name);   printf " 你好 , $name ,欢迎光临 !\n";

  这里第三行表示从终端获得行输入并赋值给 $name ,这里的 $name 的值有一个换行符,第四行 chop($name)表示去掉 $name 的最后一个字符 ( 即换行符 ) 。第五行显示输入。

Page 6: 安徽理工大学 计算机科学与工程学院

6

4.1.2 增加选择

  现在让我们为 admin 编写一个特殊的欢迎辞,而对其他人则采用普通欢迎辞。要达到这样的效果必须将输入的姓名与 admin 作比较,如果相同则执行特殊功能。

   #!/usr/bin/perl   printf " 请问您的姓名 ?";   $name=<STDIN>;   chop($name);   if ($name eq “admin"){   printf " 欢迎 admin 进入本系统 !\n";   } else {    printf " 你好 , $name ,欢迎光临 !\n";   }  这里第五行用 eq 操作符对两个字符串进行比较,相同则执行下一句,否则执行 else 下的语句 ( 是不是和 C 语言差不多?)。

Page 7: 安徽理工大学 计算机科学与工程学院

7

4.1.3 猜测密码 现在已经可以对 admin 发不同的欢迎辞,但如何加上密

码来控制权限呢?比如说,可以让除 admin 以外的人都必须输入密码直到正确为止:    #!/usr/bin/perl   $password="wsxy"; # 密码为 wsxy   printf " 请问您的姓名 ?";   $name=<STDIN>;   chop($name);   if ($name eq “admin"){   printf " 欢迎 admin 进入本系统 !\n";  

Page 8: 安徽理工大学 计算机科学与工程学院

8

} else {    printf " 你好 , $name!\n 请输入密码: ";   $guess=<STDIN>;   chop($guess);   while ($guess ne $password){   printf " 密码错误,请重新输入: ";   $guess=<STDIN>;   chop($guess);   }

Page 9: 安徽理工大学 计算机科学与工程学院

9

这里先将密码保存在标量变量 $password 中,然后当不是 zmd 登录后,先显示欢迎语句,然后要求输入密码,通过 ne 操作符将输入结果和 $password 相比较,密码相同则退出,不同则一直循环下去。

Page 10: 安徽理工大学 计算机科学与工程学院

10

当运行程序时, Perl 的内部编译器首先遍历整个源程序,把它转变为内部的字节码 ,它是程序的一种内部数据结构。Perl 的字节码引擎将运行这些字节码。

Page 11: 安徽理工大学 计算机科学与工程学院

11

4.2 标量数据 标量是 Perl 中最简单的数据类型。大多数的标量是数字

(如 255 或 3.25e20 )或者字符串 (如 hello◆ 或者盖茨堡地址) 。

标量数据可有操作符(如相加和串联),通常会产生一个新的标量数据。标量数据的值可以存放在标量变量中。标量可以从文件或设备读取,也可以写进去。

Page 12: 安徽理工大学 计算机科学与工程学院

12

4.2.1 所有数字内部的格式一致 整数 ( 如 255 , 2001 等 ) 和浮点数(有小数点的实数,

如 3.14159 , 1.35x1025 ),在 Perl 中 都当作双精度浮点数来处理。这就是说在 Perl 内部没有整数值。程序中的整数被当做等价的浮点数来处理。程序运行时,也许注意不到这种转换,不应当寻找只属于整数的操作符(不能被浮点数使用的),因为它们不存在 。

Page 13: 安徽理工大学 计算机科学与工程学院

13

4.2.2 浮点数 数字符号( literal )是 Perl 程序源代码中代替某个值的方法。数字符号不是计算或 I/O 操作的结果 ,它是直接写进代码中的数据。

有或没有小数点的数字都是允许的(包括 + 或 -号),也可带一个十进制的指数(符号为 E )

1.25 255.000 255.0 7.25e45 #7.25x10 的 45 次方 ( 一个大整数 ) -6.5e24 # -6.5x10 的 24 次方(一个大的负数) -12e-24 #- -12x10 的 -24 次方(很小的负数 ) -1.2E-23 #指数符号可以大写 (E)

Page 14: 安徽理工大学 计算机科学与工程学院

14

4.2.3 整数 0 2001 -40 255

Page 15: 安徽理工大学 计算机科学与工程学院

15

4.2.4 字符串 惯用 C 的程序员要注意,在 PERL 中,字符串的末尾并

不含有隐含的 NULL 字符, NULL 字符可以出现在串的任何位置。. 双引号内的字符串中支持简单变量替换,例如:$number = 11;$text = "This text contains the number $number.";则 $text 的内容为: "This text contains the number 11.“

双引号内的字符串中支持转义字符

Page 16: 安徽理工大学 计算机科学与工程学院

16

要在字符串中包含双引号或反斜线,则在其前加一个反斜线,反斜线还可以取消变量替换,如:$res = "A quote \" and A backslash \\";$result = 14;print ("The value of \$result is $result.\n") 的结果为:The value of $result is 14.

可用 \nnn(8 进制 ) 或 \xnn(16 进制 ) 来表示 ASCII 字符,如:$result = "\377"; # this is the character 255,or EOF$result = "\xff"; # this is also 255

Page 17: 安徽理工大学 计算机科学与工程学院

17

单引号字符串单引号字符串与双引号字符串有两个区别,一是没有变量替换功能,二是反斜线不支持转义字符,而只在包含单引号和反斜线时起作用。单引号另一个特性是可以跨多行,如:$text = 'This is two

lines of text ';

与下句等效:$text = "This is two\nlines of text\n";

Page 18: 安徽理工大学 计算机科学与工程学院

18

. 字符串和数值的互相转换例 1 :$string = "43";$number = 28;$result = $string + $number; # $result = 71若字符串中含有非数字的字符,则从左起至第一个非数字的字符,如:$result = "hello" * 5; # $result = 0$result = "12a34" +1; # $result = 13

Page 19: 安徽理工大学 计算机科学与工程学院

19

变量初始值在 PERL 中,所有的简单变量都有缺省初始值: "" ,即空字符。但是建议给所有变量赋初值,否则当程序变得大而复杂后,很容易出现不可预料且很难调试的错误。

Page 20: 安徽理工大学 计算机科学与工程学院

20

4.2.5 数字操作符 Perl 除了提供通常的操作符 加( + ),减( - ),乘( * ),除( / )等等之外: 2+3 5.1-2.4 3*12 14/2 10.2/0.3 10/3 # 通常是浮点除, 3.33333… …

Page 21: 安徽理工大学 计算机科学与工程学院

21

还提供了模数运算符( % )。 10%3 的值是 10 除以 3 的余数。两个操作数首先变成它们对应的整数值 ,如 10.5%3.2 转换为 10%3 后再计算 。

另外, Perl 中提供了和 FORTRAN 类似的指数操作符,C 和 Pascal 很希望有类似的能力。这个操作符由两个 *号表示,如 2**3 ,表示 2 的 3 次方,等于 8

Page 22: 安徽理工大学 计算机科学与工程学院

22

(1)乘幂的基数不能为负,如 (-5) ** 2.5 # error;(2)乘幂结果不能超出计算机表示的限制,如 10 ** 999999 # error(3) 取余的操作数如不是整数,四舍五入成整数后运算;运算符右侧不能为零(4) 单目负可用于变量: - $y ; # 等效于 $y * -1

Page 23: 安徽理工大学 计算机科学与工程学院

23

4.2.6 整数比较操作符 操作符 描述

< 小于> 大于== 等于<= 小于等于>= 大于等于!= 不等于<=> 比较,返回 1, 0, or -1

操作符 <=> 结果为:0 - 两个值相等1 - 第一个值大1 - 第二个值大

Page 24: 安徽理工大学 计算机科学与工程学院

24

4.2.7 字符串比较操作符 操作符 描述  

lt 小于  gt 大于  eq 等于  le 小于等于  ge 大于等于  ne 不等于  cmp 比较,返回 1, 0, or -1

Page 25: 安徽理工大学 计算机科学与工程学院

25

4.2.8 逻辑操作符 逻辑或: $a || $b 或 $a or $b逻辑与: $a && $b 或 $a and $b逻辑非: ! $a 或 not $a逻辑异或: $a xor $b

Page 26: 安徽理工大学 计算机科学与工程学院

26

4.2.9 位操作符 位与: &位或: |位非: ~位异或: ^左移: $x << 1右移: $x >> 2注:不要将 & 用于负整数,因为 PERL 将会把它们转化为无符号数。

Page 27: 安徽理工大学 计算机科学与工程学院

27

4.2.10 赋值操作符 = Assignment only

+= Addition and assignment-= Subtraction and assignment*= Multiplication and assignment/= Division and assignment%= Remainder and assignment**= Exponentiation and assignment&= Bitwise AND and assignment|= Bitwise OR and assignment^= Bitwise XOR and assignment

Page 28: 安徽理工大学 计算机科学与工程学院

28

$a = 1; none (basic assignment)$a -= 1; $a = $a - 1;$a *= 2; $a = $a * 2;$a /= 2; $a = $a / 2;$a %= 2; $a = $a % 2;$a **= 2; $a = $a ** 2;$a &= 2; $a = $a & 2;$a |= 2; $a = $a | 2;$a ^= 2; $a = $a ^ 2;

Page 29: 安徽理工大学 计算机科学与工程学院

29

.= 可在一个赋值语句中出现多次,如:$value1 = $value2 = "a string";.= 作为子表达式($a = $b) += 3;等价于$a = $b;$a += 3;但建议不要使用这种方式。

Page 30: 安徽理工大学 计算机科学与工程学院

30

4.2.11 自增自减操作符 : ++、 --( 与 C++ 中的用法相同 )

. 不要在变量两边都使用此种操作符: ++$var-- # error

. 不要在变量自增 /减后在同一表达式中再次使用: $var2 = $var1 + ++$var1; # error. 在 PERL 中 ++ 可用于字符串,但当结尾字符为 'z'、 'Z'、 '9' 时进位,如:$stringvar = "abc";$stringvar++; # $stringvar contains "abd" now

$stringvar = "aBC";$stringvar++; # $stringvar contains "aBD" now

Page 31: 安徽理工大学 计算机科学与工程学院

31

$stringvar = "abz";$stringvar++; # $stringvar now contains "aca"

$stringvar = "AGZZZ";$stringvar++; # $stringvar now contains "AHAAA"

$stringvar = "ab4";$stringvar++; # $stringvar now contains "ab5"

$stringvar = "bc999";$stringvar++; # $stringvar now contains "bd000". 不要使用 -- , PERL 将先将字符串转换为数字再进行自减$stringvar = "abc";$stringvar--; # $stringvar = -1 now

Page 32: 安徽理工大学 计算机科学与工程学院

32

果字符串中含有非字母且非数字的字符,或数字位于字母中,则经过 ++ 运算前值转换为数字零,因此结果为 1 ,如:$stringvar = "ab*c";$stringvar++;$stringvar = "ab5c";$stringvar++;

Page 33: 安徽理工大学 计算机科学与工程学院

33

4.2.12 字符串联结和重复操作符 联接 : .

重复: x联接且赋值 ( 类似 +=) : .=例:$newstring = "potato" . "head";$newstring = "t" x 5;$a = "be";$a .= "witched"; # $a is now "bewitched"

Page 34: 安徽理工大学 计算机科学与工程学院

34

4.2.13 逗号操作符 其前面的表达式先进行运算,如:

$var1 += 1, $var2 = $var1;等价于$var1 += 1;$var2 = $var1;使用此操作符的唯一理由是提高程序的可读性,将关系密切的两个表达式结合在一起,如:$val = 26;$result = (++$val, $val + 5); # $result = 32注意如果此处没有括号则意义不同:$val = 26;$result = ++$val, $val + 5; # $result = 27

Page 35: 安徽理工大学 计算机科学与工程学院

35

4.2.14 条件操作符 与 C 中类似,条件 ? 值 1: 值 2 ,当条件为真时取值 1 ,

为假时取值 2 ,如:$result = $var == 0 ? 14 : 7;$result = 43 + ($divisor == 0 ? 0 : $dividend / $divisor);PERL 5 中,还可以在赋值式左边使用条件操作符来选择被赋值的变量,如:$condvar == 43 ? $var1 : $var2 = 14;$condvar == 43 ? $var1 = 14 : $var2 = 14;

Page 36: 安徽理工大学 计算机科学与工程学院

36

4.2.14 转义字符

Page 37: 安徽理工大学 计算机科学与工程学院

37

Page 38: 安徽理工大学 计算机科学与工程学院

38

4.2.15 操作符的优先级 ++, -- 自增,自减

-, ~, ! 单目** 乘方=~, !~ 模式匹配*, /, %, x 乘,除,取余,重复+, -, . 加,减,联接<<, >> 移位-e, -r, etc. 文件状态<, <=, >, >=, lt, le, gt, ge 不等比较==, !=, <=>, eq, ne, cmp 相等比较& 位与

Page 39: 安徽理工大学 计算机科学与工程学院

39

|, ^ 位或,位异或&& 逻辑与|| 逻辑或.. 列表范围? and : 条件操作符=, +=, -=, *=, 赋值and so on  , 逗号操作符not Low-precedence logical NOTand Low-precedence logical ANDor, xor Low-precedence logical OR and XOR

Page 40: 安徽理工大学 计算机科学与工程学院

40

建议:1、当你不确定某操作符是否先执行时,一定要用括号明确之。2、用多行、空格等方式提高程序的可读性。

Page 41: 安徽理工大学 计算机科学与工程学院

41

4.3 数组 一、列表 列表是包含在括号里的一序列的值,可以为任何数值,也

可为空,如: (1, 5.3 , "hello" , 2) ,空列表: () 。注:只含有一个数值的列表 ( 如: (43.2) ) 与该数值本身( 即: 43.2 ) 是不同的,但它们可以互相转化或赋值。列表例:(17, $var, "a string")(17, 26 << 2)(17, $var1 + $var2)($value, "The answer is $value")

Page 42: 安徽理工大学 计算机科学与工程学院

42

二、数组 --列表的存贮列表存贮于数组变量中,与简单变量不同,数组变量以字符 "@" 打头,如:@array = (1, 2, 3);注:(1) 数组变量创建时初始值为空列表: () 。(2)因为 PERL 用 @ 和 $ 来区分数组变量和简单变量,所以同一个名字可以同时用于数组变量和简单变量,如:$var = 1;@var = (11, 27.1 , "a string");但这样很容易混淆,故不推荐。

Page 43: 安徽理工大学 计算机科学与工程学院

43

1、数组的存取. 对数组中的值通过下标存取,第一个元素下标为 0 。试图访问不存在的数组元素,则结果为 NULL ,但如果给超出数组大小的元素赋值,则数组自动增长,原来没有的元素值为 NULL 。如:@array = (1, 2, 3, 4);$scalar = $array[0];$array[3] = 5; # now @array is (1,2,3,5)$scalar = $array[4]; # now $scalar = null;$array[6] = 17; # now @array is (1,2,3,5,"","",17)

Page 44: 安徽理工大学 计算机科学与工程学院

44

数组间拷贝@result = @original;. 用数组给列表赋值@list1 = (2, 3, 4);@list2 = (1, @list1, 5); # @list2 = (1, 2, 3, 4, 5). 数组对简单变量的赋值(1) @array = (5, 7, 11);($var1, $var2) = @array; # $var1 = 5, $var2 = 7, 11 被忽略(2) @array = (5, 7);($var1, $var2, $var3) = @array; # $var1 = 5, $var2 = 7, $var3 ="" (null). 从标准输入 (STDIN) 给变量赋值$var = <STDIN>;@array = <STDIN>; # ^D 为结束输入的符号

Page 45: 安徽理工大学 计算机科学与工程学院

45

2 、字符串中的方括号和变量替换"$var[0]" 为数组@var 的第一个元素。"$var[0]" 将字符 "[" 转义,等价于 "$var". "[0]" , $var被变量替换, [0] 保持不变。"${var}[0]" 亦等价于 "$var" ."[0]" 。"${var}" 则取消了大括号的变量替换功能,包含文字: ${var}.

Page 46: 安徽理工大学 计算机科学与工程学院

46

3、列表范围:(1..10) = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)(2, 5..7, 11) = (2, 5, 6, 7, 11)(3..3) = (3). 用于实数(2.1..5.3) = (2.1, 3.1 ,4.1, 5.1)(4.5..1.6) = (). 用于字符串("aaa".."aad") = ("aaa","aab", "aac", "aad")@day_of_month = ("01".."31"). 可包含变量或表达式($var1..$var2+5)

Page 47: 安徽理工大学 计算机科学与工程学院

47

. 小技巧:$fred = "Fred";print (("Hello, " . $fred . "!n") x 2);其结果为:Hello, Fred!Hello, Fred!

Page 48: 安徽理工大学 计算机科学与工程学院

48

4、数组的输出:(1) @array = (1, 2, 3);print @array;结果为:123

Page 49: 安徽理工大学 计算机科学与工程学院

49

5、列表 /数组的长度当数组变量出现在预期简单变量出现的地方,则 PERL解释器取其长度。@array = (1, 2, 3);$scalar = @array; # $scalar = 3,即@array的长度($scalar) = @array; # $scalar = 1,即@array第一个元素的值注:以数组的长度为循环次数可如下编程:$count = 1;while ($count <= @array) {print ("element $count: $array[$count-1]n");$count++;}

Page 50: 安徽理工大学 计算机科学与工程学院

50

6 、子数组@array = (1, 2, 3, 4, 5);@subarray = @array[0,1]; # @subarray = (1, 2)@subarray2 = @array[1..3]; # @subarray2 = (2,3,4)@array[0,1] = ("string", 46); # @array =("string",46,3,4,5) now@array[0..3] = (11, 22, 33, 44); # @array = (11,22,33,44,5) now@array[1,2,3] = @array[3,2,4]; # @array = (11,44,33,5,5) now@array[0..2] = @array[3,4]; # @array = (5,5,"",5,5) now可以用子数组形式来交换元素:@array[1,2] = @array[2,1];

Page 51: 安徽理工大学 计算机科学与工程学院

51

7 、有关数组的库函数(1)sort-- 按字符顺序排序@array = ("this", "is", "a","test");@array2 = sort(@array); # @array2 = ("a","is", "test", "this")@array = (70, 100, 8);@array = sort(@array); # @array = (100, 70, 8) now

( 2)reverse-- 反转数组@array2 = reverse(@array);@array2 = reverse sort (@array);

Page 52: 安徽理工大学 计算机科学与工程学院

52

3)chop-- 数组去尾chop 的意义是去掉 STDIN (键盘)输入字符串时最后一个字符 --换行符。而如果它作用到数组上,则将数组中每一个元素都做如此处理。@list = ("rabbit", "12345","quartz");chop (@list); # @list = ("rabbi", "1234","quart") no

4)join/split-- 连接 / 拆分join 的第一个参数是连接所用的中间字符,其余则为待连接的字符数组。$string = join(" ", "this", "is","a", "string"); # 结果为 "this is a string"@list = ("words","and");$string = join("::", @list, "colons"); # 结果为 "words::and::colons"@array = split(/::/,$string); # @array = ("words","and", "colons") now

Page 53: 安徽理工大学 计算机科学与工程学院

53

5)push— 在列表右端添加元素@info = (“tom", “male",“25");

push(@info,”teacher”,”USA”); 6)pop— 在列表右端删除元素返回被删除的值 .@info = (“tom", “male",“25");Pop(@info);则返回值为 25.7)unshift: 在列表左端添加元素8)shift: 在列表左端删除元素,返回 被删除的值

Example: /home/xjfang/perl/arr1

Page 54: 安徽理工大学 计算机科学与工程学院

54

9)Splice 函数从列表中的任意部分删除元素某些元素,然后添加其它元素。@nums=(1,2,3,4,5);Splice(@num,3,1,(‘dog’,’cow’));则 @num 变为 (1,2,3,’dog’,’cow’,5)Splice(@num,3,0, (‘dog’,’cow’)); #insert则结果为 (1,2,3,’dog’,’cow’,4,5)Splice(@num,3,1, ()); # 删除列表中的一个元素则结果为 (1,2,3,5);Splice(@num,3,2); #get deleted element_list: (4,5)

Page 55: 安徽理工大学 计算机科学与工程学院

55

10)Split 函数 : 一个极佳的文本处理函数之一$sentence=“it is time for class”;@word=split(/ /,$sentence);则 @word=(‘it’,’is’,’time’,’for’,’class’);一个在系统用户数据库中查找用户的例子:/home/xjfang/perl/viewusers.pl

Page 56: 安徽理工大学 计算机科学与工程学院

56

4.4 Perl 的基本输入输出 从 STDIN 输入  从标准输入设备读取数据是很容易的,

我们已经从第一课上就使用 <STDIN> 操作符了。例如:    $name=<STDIN>;

  在数组环境中,可把所有剩余的行作为一列表返回。如:    @name=<STDIN>;

  此时,需要读入多行,然后再对各行分别处理。通常做法是:    while($_=<STDIN>){     chop($_);     # 处理 $_(每一行 )    }

Page 57: 安徽理工大学 计算机科学与工程学院

57

上述程序可简化为:    while(<STDIN>){     chop; # 等同于 chop($_)    处理 $_(每一行 )    }

  因为 $_ 是许多操作符的缺少变量。

Page 58: 安徽理工大学 计算机科学与工程学院

58

从 <> 输入  读取输入的另一种方法是使用 <> 。 <> 是从 Perl 程序命令行所指定的文件中读取数据。例如有个文件名为 pro1 的程序:    #!/usr/bin/perl;    while(<>){     print $_;    }

  在 UNIX 环境中运行:    pro1 file1,file2,file3example: /home/xjfang/perl/readfile.pl  此时,将依次读入文件 file1,file2,file3 中的每一行,然后显示输出。

Page 59: 安徽理工大学 计算机科学与工程学院

59

向 STDOUT 输出   Perl 用 print 和 printf向标准输出设备输出。   print 操作符使用字串列表作为参数,依次把每个字符串发送给标准输出,在发送时不插入或改变任何字符。如:

    print "网上学园 "." 欢迎您 !" # 打印 "网上学园欢迎您 !"    print 1+2," 你好 " # 打印 "3 你好 "

Page 60: 安徽理工大学 计算机科学与工程学院

60

printf 操作符用于格式化输出,在 C 语言中有相同的功能。它使用一个参数表,第一个参数是格式控制字符串,它定义了如何打印其余参数。例如:

    printf "%10s% 8d%8.2f\n",$a,$b,$c

  它的打印结果为: 10 个字符宽度的 $a ,空格, 8 个字符宽度的整数 $b , 8 个字符宽度且包含两位小数的浮点数 $c ,最后换行。

  注意:与前面操作符相类似, printf() 的括号可以省略。

Page 61: 安徽理工大学 计算机科学与工程学院

61

4.5 控制结构 1、选择结构 选择性控制结构

选择性控制结构包括 if 和 unless 语句,类似于 C 语言中的 if 。

首先介绍一下真和假的定义。在 Perl 中,这些规则有些难以理解。控制表达式的值为空串或 0 时,则表达式为假, 对于其它任何情况,表达式的值都为真。

注意: "00" 不是空串或 0 ,值为真。 "0.0" 也是如此。

Page 62: 安徽理工大学 计算机科学与工程学院

62

指令 : if 假如 语法一 : if(判别运算式 )

{ 表达式为真时的语句块 ; } 上个语法在 Perl 中也可以写成 : 表达式为真时的语句块 if (判别运算式 );

Page 63: 安徽理工大学 计算机科学与工程学院

63

范例 : print" 请输入您的分数 ?\n";

$scorre=<STDIN>; #<STDIN> 代表标准输入 , 会让使用者输入一字符串chop($score); # 将 $score 最后一个换行字符 \n删除掉if($score>=60){

print" 您的分数及格了 !\n"; } 也可以写成 : print " 您的分数及格了 !\n" if ($score>=6

0);

Page 64: 安徽理工大学 计算机科学与工程学院

64

语法二 : if(判别运算式一 ){ 判别式一为真时的语句块 ; }else{ 判别式一为假时的语句块 ; }

Page 65: 安徽理工大学 计算机科学与工程学院

65

范例 : print" 请输入您的分数 ?\n";

$scorre=<STDIN>;chop($score);if($score>=60){

print" 您的分数及格了 !\n"; }else{ print" 您的分数不及格 !\n"; }

Page 66: 安徽理工大学 计算机科学与工程学院

66

语法三 : if (判别运算式一 )

{ 判别式一为真时的语句块 ; }elsif(判别运算式二 ){ 判别式二为真时的语句块 ; }elsif(判别运算式三 ){ 判别式三为真时的语句块 ; }else{ 所有判别式为假时的语句块 ; }

Page 67: 安徽理工大学 计算机科学与工程学院

67

范例 : print" 请输入您的分数 ?\n";

$scorre=<STDIN>;chop($score);if($score>60){

print" 您的分数大于 60分 !\n"; }elsif ($score<60){ print" 您的分数小于 60分 !\n": }else{ print" 您的分数刚好是 60分 !\n"; }

Page 68: 安徽理工大学 计算机科学与工程学院

68

指令 : unless 假如非 unless 的含义就是说“如果判别式不为真,就执行 ...” 。 语法一 : unless(判别运算式 ) { 判别式为假时语句块 ; } 上个语法在 Perl 中也可以写成 :判别式为假时语句块 unl

ess (判别运算式 );

Page 69: 安徽理工大学 计算机科学与工程学院

69

范例 : print" 请输入您的分数 ?\n";

$scorre=<STDIN>;    #<STDIN> 代表标准输入 , 会让使用者输入一字符串chop($score); # 将 $score 最后一个换行字符 \n删除掉unless($score<60){

print" 您的分数及格了 !\n"; } 也可以写成 : print" 您的分数及格了 !\n"unless($score<

60);

Page 70: 安徽理工大学 计算机科学与工程学院

70

语法二 : unless(判别运算式 )

{ 判别式为假时语句块 ; }else{ 判别式为真时语句块 ; }

Page 71: 安徽理工大学 计算机科学与工程学院

71

范例 : print" 请输入您的分数 ?\n";

$scorre=<STDIN>;chop($score);unless($score<60){

print" 您的分数及格了 !\n"; }else{ print" 您的分数不及格 !\n"; }

Page 72: 安徽理工大学 计算机科学与工程学院

72

:&&,||及 ?: 作为控制结构 它们看上去像标点符号,或是表达式的一部分。但在 Perl

中可作为控制结构。 比如说:

  if (判别表达式 )   { 为真时语句块 };

也可以写为:

 为真时的语句块 if (判别表达式 )

Page 73: 安徽理工大学 计算机科学与工程学院

73

但更简单的方式是:判别式 && 为真时的语句块 && 为逻辑与操作符,其含义为:  若判别式为真,则表达式的值依赖于后面语句块的值。所以为真时的语句块被执行 ( 用来求值 ) 。  若判别式为假,则整个表达式为假,不用考虑后面语句块的值。所以为假时的语句块不被执行。同样道理, unless(this){that} 可替换为 this||that 。

?: 表达式举例 :exp1?exp2:exp3 表示:如果 exp1 为真则求 exp2 的值,否则求 exp3 的值。

Page 74: 安徽理工大学 计算机科学与工程学院

74

2. 循环性控制结构  任何一种语言没有循环就是不完整的。 Perl 也是如此,它可以用 while, do...while, for, until, foreach 来实现。

循环中还可以用 last , next , redo 等操作符进行控制。

Page 75: 安徽理工大学 计算机科学与工程学院

75

指令 : while 当 ..

语法 :

while(判别运算式 ) { 程序叙述区块 ; } 上个语法在 Perl 中也可以写成 : 程序叙述区块 while(判别运算式 );

Page 76: 安徽理工大学 计算机科学与工程学院

76

范例一 : while($<=10)

{ $sum+=$i;

$i++; } print"$sum\n"; # 此时 $sum =55;

Page 77: 安徽理工大学 计算机科学与工程学院

77

范例二 : $filename="/path/cgi.txt";

open(FILE,"$filename")||die "Cannot open $filename\n";# 可以把 <FILE>视为打开文件某一行的数据while($line=<FILE>){

print "$line"; } close(FILE);

Page 78: 安徽理工大学 计算机科学与工程学院

78

就会把 cgi.txt 这个文件的内容显示出来。 而这个范例可以把它改写成 : $filename="/path/cgi.txt";

open(FILE,"$filename")||die "Cannot open $ filename\n";print "$line"while($line=<FILE>);close (FILE);

Page 79: 安徽理工大学 计算机科学与工程学院

79

在这个范例中是把 $filename 文件内的数据一行一行的指派给 $line 这个纯量变量 ,再把 $line 显示出来 . 如果没有将 <FILE>指派给一个纯量变量的话 , 则会有一内定的输入变量 $_ 被 <FILE>所指派 .因为 $_ 是一个内定的变量 ,所以如果使用 print函数的时候没有加上要输出数据的话 ,就会把 $_ 的数据 print 出来 .所以这个范例也可以改写成 : $filename="/path/cgi.txt";open(FILE,"$filename") die"Cannot open $ filenameⅡ\n";while(<FILE>){

print; } close(FILE);

Page 80: 安徽理工大学 计算机科学与工程学院

80

指令 : do while 当 .. 语法 : do

{ 程序叙述区块 ; }while(判别运算式 ); 在 while 和 do while 循环中最大的不同是在 do while 循

环中 , 程序叙述区块至少会被执行一次。

Page 81: 安徽理工大学 计算机科学与工程学院

81

范例 : do{ $sum+=$i;

$i++; }while($i<=10);

print "$sum\n"; # 此时 $sum=55;

Page 82: 安徽理工大学 计算机科学与工程学院

82

指令 : until 直到 ...才 语法 : until(判别运算式 )

{ 程序叙述区块 ; } 上个语法在 Perl 中也可以写成 : 程序叙述区块 until (判别运算式 );

Page 83: 安徽理工大学 计算机科学与工程学院

83

范例 : until($i>10){ $sum+=$i;

$i++; } print "$sum\n"; # 此时 $Sum=55;

Page 84: 安徽理工大学 计算机科学与工程学院

84

指令 : do while 直到 ...才 语法 : do{ 程序叙述区块 ; }until (判别运算式 );

Page 85: 安徽理工大学 计算机科学与工程学院

85

范例 : do{ $sum+=$i;

$i++; }until($i>10); print "$sum\n"; # 此时 $sum=55;

Page 86: 安徽理工大学 计算机科学与工程学院

86

指令 : for 循环陈述 语法一 : for (初始化运算式 ;判别运算式 ; 循环过程运算式 )

{ 程序叙述区块 ; }

Page 87: 安徽理工大学 计算机科学与工程学院

87

范例一 : $sum=0;

for($i=1;$i<=10;$i++){

$sum+=$i; } print "$sum\n"; # 此时 $sum=55;

Page 88: 安徽理工大学 计算机科学与工程学院

88

范例二 : @array=(3,6,9);

$number=@array; # 把数组@array 的元素个数指派给$number# 此时 $number=3;for($i=0;$inumber;$i++){

$sum+=$array[$i]; # 把数组@array元素的值全部加起来

} print"$sum\n"; # 此时 $sum=18;

Page 89: 安徽理工大学 计算机科学与工程学院

89

语法二 : for $ variable(@array)

{ 程序叙述区块 ; } 在 Perl 语言中的 for 循环陈述还可以使用这个语法 ,各循

环陈述 foreach 的用法一样 . 如果把 $variable 变量省略的话 , 就会将数组@array 的元素一个一个指定给 $_ 这个变量 , 这是比较精简的写法 .

Page 90: 安徽理工大学 计算机科学与工程学院

90

@array=(3,6,9);for $int(@array){

$sum+=$int; } print"$sum\n"; # 此时 $sum=18;

Page 91: 安徽理工大学 计算机科学与工程学院

91

也可以写成 : @array=(3,6,9);

for (@array){

$sum+=$_; } print"$sum\n"; # 此时 $sum=18;

Page 92: 安徽理工大学 计算机科学与工程学院

92

指令 : foreach 循环陈述 语法 : foreach $ variable(@array)

{ 程序叙述区块 ; } 如果把 $variable 变量省略的话 , 就会将数组@array 的元素一一指定给 $_ 这个内定的输出变量 .

Page 93: 安徽理工大学 计算机科学与工程学院

93

范例一 : @array=(3,6,9);

foreach $int(@array){

$sum+=$int; } print "$sum\n"; # 此时 $sum=18;

Page 94: 安徽理工大学 计算机科学与工程学院

94

也可以定成 : @array=(3,6,9);

foreach(@array){

$sum+=$_; } print "$sum\n"; # 此时 $sum=18;

Page 95: 安徽理工大学 计算机科学与工程学院

95

范例二 : %FORM=("name","NCTU","value","TEM");

foreach $pair(sort keys%FORM){

print "$pair is $FORM{pair}\n"; }

Page 96: 安徽理工大学 计算机科学与工程学院

96

这个范例在 CGI 语言写作中常常会用到 . 先用 keys喧个函数来求出关联数组中全部的 key,再用 sort 这个函数把全部的 key由小到大排序 , 最后再把关联数组中的 key 和所对应的值 (value) 一一显示出来 . 而以上这个程序也可写成 :

%FORM=("name","NCTU","value","TEM");@array=(sort keys%FORM);foreach $pair(@array){

print "$pair is $FORM{pair}\n"; }

Page 97: 安徽理工大学 计算机科学与工程学院

97

指令 : last 退出循环陈述 语法 : last

Page 98: 安徽理工大学 计算机科学与工程学院

98

范例 : for($i=1;$i<=10;$i++)

{ last if ($i==5); # 如果 $i 等于 5 的话就退出 for 循环

print"$i\n"; } 会把 1 到 4之间的数值显示出来 .

Page 99: 安徽理工大学 计算机科学与工程学院

99

指令 :next 到循环的下一个陈述 语法 :next 范例 : for($i<=10;$i++)

{ # 如果是 2 的倍数的话 , 就到循环的下一个陈述

next if($i%2)==0) print"$i 是一个奇数 !\n"; } 会把 1 以 10之间的奇数显示出来。