Perl语言入门读书笔记 | 四. 子程序

2024-04-11 11:38

本文主要是介绍Perl语言入门读书笔记 | 四. 子程序,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

其实就是所谓的函数。

1. 子程序基础

  1. 子程序中可以使用任何全局变量;
  2. 子程序最后一次运算的结果,会被自动当成子程序的返回值。当然,也可以使用return关键字。
sub max{if($_[0] > $_[1]){ $_[0] }else{ $_[1] }
}print &max(3, 5);

$_[0]和$_[1]、@_ 都是函数的私有变量,不会受外界影响。默认情况下,Perl里面的所有变量都是全局变量,哪怕是在函数里创建的。这是一件很危险的事。如果不小心又创建了一个之前出现过的同名变量的话,很容易在无意间就改变了之前出现过的这个变量的值。通过my关键字,可以创建私有变量,和全局变量两不相犯,从而避免了这种情况。

sub max{if(@_ != 2){        # 判断参数个数print "Error\n"}my($m, $n) = @_;    # 创建新的私有变量,并将参数赋值给变量if($m > $n){ $m }else{ $n }
}print &max(3, 5);

一个改进的、可以接受任意个参数的max函数如下,这个算法的名字很有意思。“高水线(high-watermark)”:大水过后,在最后一波浪消退时,高水线会标示出所见过的最高水位。

sub max{my($max_so_far) = shift @_;        # 数组中的第一个值,暂时当它最大foreach (@_){if($_ > $max_so_far){$max_so_far = $_;}}$max_so_far;
}print &max(3, 5, 10, 4, 6);

2. my关键字

my关键字不会更改变量赋值时的上下文:

my ($num) = @_;	# 列表上下文,和($num) = @_; 相同, $num被设为数组的第一个数
my $num = @_;	# 标量上下文,和 $num = @_;  相同, $sum被设为数组的大小

在日常编程中,最好将每个新变量都使用my声明,让它保持在自己所在的词法作用域内。

foreach my $rock (qw{a b c}){print $rock;
}

use strict关键字:编译器会强制使用一些严格的、良好的编程风格。比如,变量要先声明(用my关键字),后使用:

use strict;
my $vivi = 3;
$vivi += 1;

以上代码没有加my的话,就会报错:

Global symbol “$vivi” requires explicit package name (did you forget to declare “my $vivi”?)

3. 省略函数调用的$号

在不加$号也不会产生歧义的情况下,函数调用时函数名前的$号是可以省略的。如下面这种情况,函数shift不仅可以省略$号,连参数列表两边的括号都可以省略:

use strict;
my @array = qw(a b c);
my @dealed = shift @array;

如果自己定义的子程序与Perl内置函数同名的话,为了调用自己定义的子程序,就必须加$号。所以更一般的情况是,调用自建函数时务必使用$号,除非你很确定Perl所有的内置函数名没有与你的自建函数同名。

4. state关键字

sub marine{$n += 1;print "$n\n"
}&marine;
&marine;

这段代码输出1和2,$n是全局变量。但是加上use strict;后,这段代码将出错,因为$n没有被定义。但是如果将$n定义为my,每次函数执行完成后,$n的内容会被清空,输出结果就会变成1和1。为了保留函数结果,我们使用state关键字来声明持久性私有变量。

use strict;
use feature 'state';
sub marine{state $n = 0;$n += 1;print "$n\n";
}&marine;
&marine;

第一次调用这个子程序时,Perl声明并初始化变量$n,而在接下来的调用中,这个声明表达式将被Perl忽略。每次子程序返回后,$n的当前值都会被保留下来,以备下次调用时再用。

state关键字的用法和my基本相似,但是不能在列表上下文中初始化数组类型的state变量。

use strict;
use feature 'state';
my @array = qw(a b c);  # 正确
state @array = qw(a b c);   # 错误

课后习题

(1)

use strict;
use feature 'state';sub total{my($sum) = 0;foreach (@_){$sum += $_;} $sum;
}my @fred = qw{1 3 5 7 9};
print &total(@fred);

(2)

use strict;
use feature 'state';sub total{my($sum) = 0;foreach (@_){$sum += $_;} $sum;
}my @fred = 1..1000;
print &total(@fred);

(3)

use strict;
use feature 'state';sub average{my $n = @_;my($sum) = 0;foreach (@_){$sum += $_;} $sum / $n;
}sub above_average{my $avg = &average(@_);foreach (@_){if($_ > $avg){print "$_\t";}}
}my @fred = 1..10;
print &above_average(@fred);

(4)

use strict;
use feature 'state';sub greet{my ($guest) = @_;state $last;if($last eq undef){print "Hi $guest! You are the first one here!\n";}else{print "Hi $guest! $last is also here!\n";}$last = $guest;
}&greet("Fred");
&greet("Barney");

(5)

use strict;
use feature 'state';sub greet{my ($guest) = @_;state @last;if(@last == 0){print "Hi $guest! You are the first one here!\n";}else{print "Hi $guest! I've seen: "."@last\t"."\n";}push @last, $guest;
}&greet("Fred");
&greet("Barney");
&greet("Wilma");
&greet("Betty");

参考文献

  1. Perl语言入门 第六版中文清晰PDF

这篇关于Perl语言入门读书笔记 | 四. 子程序的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/893971

相关文章

C语言中位操作的实际应用举例

《C语言中位操作的实际应用举例》:本文主要介绍C语言中位操作的实际应用,总结了位操作的使用场景,并指出了需要注意的问题,如可读性、平台依赖性和溢出风险,文中通过代码介绍的非常详细,需要的朋友可以参... 目录1. 嵌入式系统与硬件寄存器操作2. 网络协议解析3. 图像处理与颜色编码4. 高效处理布尔标志集合

Go语言开发实现查询IP信息的MCP服务器

《Go语言开发实现查询IP信息的MCP服务器》随着MCP的快速普及和广泛应用,MCP服务器也层出不穷,本文将详细介绍如何在Go语言中使用go-mcp库来开发一个查询IP信息的MCP... 目录前言mcp-ip-geo 服务器目录结构说明查询 IP 信息功能实现工具实现工具管理查询单个 IP 信息工具的实现服

C 语言中enum枚举的定义和使用小结

《C语言中enum枚举的定义和使用小结》在C语言里,enum(枚举)是一种用户自定义的数据类型,它能够让你创建一组具名的整数常量,下面我会从定义、使用、特性等方面详细介绍enum,感兴趣的朋友一起看... 目录1、引言2、基本定义3、定义枚举变量4、自定义枚举常量的值5、枚举与switch语句结合使用6、枚

Go 语言中的select语句详解及工作原理

《Go语言中的select语句详解及工作原理》在Go语言中,select语句是用于处理多个通道(channel)操作的一种控制结构,它类似于switch语句,本文给大家介绍Go语言中的select语... 目录Go 语言中的 select 是做什么的基本功能语法工作原理示例示例 1:监听多个通道示例 2:带

C语言函数递归实际应用举例详解

《C语言函数递归实际应用举例详解》程序调用自身的编程技巧称为递归,递归做为一种算法在程序设计语言中广泛应用,:本文主要介绍C语言函数递归实际应用举例的相关资料,文中通过代码介绍的非常详细,需要的朋... 目录前言一、递归的概念与思想二、递归的限制条件 三、递归的实际应用举例(一)求 n 的阶乘(二)顺序打印

Spring Boot + MyBatis Plus 高效开发实战从入门到进阶优化(推荐)

《SpringBoot+MyBatisPlus高效开发实战从入门到进阶优化(推荐)》本文将详细介绍SpringBoot+MyBatisPlus的完整开发流程,并深入剖析分页查询、批量操作、动... 目录Spring Boot + MyBATis Plus 高效开发实战:从入门到进阶优化1. MyBatis

C语言中的数据类型强制转换

《C语言中的数据类型强制转换》:本文主要介绍C语言中的数据类型强制转换方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C语言数据类型强制转换自动转换强制转换类型总结C语言数据类型强制转换强制类型转换:是通过类型转换运算来实现的,主要的数据类型转换分为自动转换

利用Go语言开发文件操作工具轻松处理所有文件

《利用Go语言开发文件操作工具轻松处理所有文件》在后端开发中,文件操作是一个非常常见但又容易出错的场景,本文小编要向大家介绍一个强大的Go语言文件操作工具库,它能帮你轻松处理各种文件操作场景... 目录为什么需要这个工具?核心功能详解1. 文件/目录存javascript在性检查2. 批量创建目录3. 文件

C语言实现两个变量值交换的三种方式

《C语言实现两个变量值交换的三种方式》两个变量值的交换是编程中最常见的问题之一,以下将介绍三种变量的交换方式,其中第一种方式是最常用也是最实用的,后两种方式一般只在特殊限制下使用,需要的朋友可以参考下... 目录1.使用临时变量(推荐)2.相加和相减的方式(值较大时可能丢失数据)3.按位异或运算1.使用临时

使用C语言实现交换整数的奇数位和偶数位

《使用C语言实现交换整数的奇数位和偶数位》在C语言中,要交换一个整数的二进制位中的奇数位和偶数位,重点需要理解位操作,当我们谈论二进制位的奇数位和偶数位时,我们是指从右到左数的位置,本文给大家介绍了使... 目录一、问题描述二、解决思路三、函数实现四、宏实现五、总结一、问题描述使用C语言代码实现:将一个整