Learning Perl學(xué)習(xí)筆記(3)第四章:子程序

本章要點:
(1)在perl里,&fred和$fred雖然名字一樣馏艾,但是是兩種東西奴愉。一個是調(diào)用名為fred的子程序;一個是名為fred的標(biāo)量锭硼。
(2)用sub來定義子程序,并用{}來界定子程序的內(nèi)容轰异。
(3)如果你在一個腳本里定義了兩個名字相同的子程序,第二個將會覆蓋第一個搭独。
(4)調(diào)用子程序,使用&字符唉俗。比如:&marine配椭。但是這個符號是可以省略的,除非你的子程序名字與perl的內(nèi)置函數(shù)名字相同股缸,如果是這樣的情況,就必須用&來調(diào)用你的子程序寺酪。
(5)想要立即終止子程序替劈,使用return寄雀。
(6)使用my陨献,可以在子程序里設(shè)置變量,盡管每次調(diào)用子程序時急膀,必須再次定義它們龄捡。使用state,可以將私有變量的作用域限定在子程序中聘殖,但是Perl將在每次調(diào)用之間保留它們的值。
(7)defined:判斷一個值是否是undef而不是空字符串餐禁,使用defined函數(shù)突照,該函數(shù)對undef返回false,對其他所有值返回true:

$next_line = <STDIN>;
if ( defined($next_line) ) {
print "The input was $next_line";
} else {
print "No input available!\n";
}

(8)shift:去掉數(shù)組里的第一個元素。也就是卸載參數(shù)筑舅,當(dāng)你只需要一個參數(shù)時使用shift庄岖;讀取多個參數(shù)時使用列表賦值角骤。(參考:第五章 Perl函數(shù))。

參考文章:
1.Perl 變量
2.第五章 Perl函數(shù)

課后練習(xí):

第一題:

Write a subroutine, named total, which returns the total of a list of numbers.
Hint: the subroutine should not perform any I/O; it should simply process
its parameters and return a value to its caller. Try it out in this sample program,
which merely exercises the subroutine to see that it works. The first group of
numbers should add up to 25.

my @fred = qw{ 1 3 5 7 9 };
my $fred_total = total(@fred);
print "The total of \@fred is $fred_total.\n";
print "Enter some numbers on separate lines: ";
my $user_total = total(<STDIN>);
print "The total of those numbers is $user_total.\n";

Note that using <STDIN> in list context like that will wait for you to end input in
whatever way is appropriate for your system.

腳本:

#!/usr/bin/perl
use warnings;
use v5.24;

sub total {
        my $sum;
        foreach ( @_ ) {
                $sum += $_;
        }
        $sum;
}

my @fred = qw{ 1 3 5 7 9 };
my $fred_total = total(@fred);
print "The total of \@fred is $fred_total.\n";
print "Enter some numbers on separate lines:\n";
my $user_total = total(<STDIN>);
print "The total of those numbers is $user_total.\n";
$ ./practice.pl
The total of @fred is 25.
Enter some numbers on separate lines:
6
8
3
The total of those numbers is 17.

第二題

Using the subroutine from the previous problem, make a program to calculate
the sum of the numbers from 1 to 1,000.

腳本:

#!/usr/bin/perl
use warnings;
use v5.24;

sub total {
        my $sum;
        foreach ( @_ ) {
                $sum += $_;
        }
        $sum;
}

my @fred = (1..1000);
my $fred_total = total(@fred);
print "The total of 1 to 1000 is $fred_total.\n";

運行結(jié)果:

$ ./practice.pl
The total of 1 to 1000 is 500500.

第三題

Extra credit exercise: write a subroutine, called &above_average, which takes
a list of numbers and returns the ones above the average (mean). (Hint: make
another subroutine that calculates the average by dividing the total by the number
of items.) Try your subroutine in this test program:
my @fred = above_average(1..10);
print "@fred is @fred\n";
print "(Should be 6 7 8 9 10)\n";
my @barney = above_average(100, 1..10);
print "@barney is @barney\n";
print "(Should be just 100)\n";

腳本:

#!/usr/bin/perl
use warnings;
use v5.24;

sub total {
        my $sum;
        foreach (@_){
                $sum +=$_;
        }
        $sum;
}

sub average {
        my $count =@_; #數(shù)組賦值給標(biāo)量,返回數(shù)組元素個數(shù)
        my $sum =total(@_); #調(diào)用上一個子程序total蝉揍,這里省略了&符號
        $sum/$count;
}

sub above_average {
        my $average = average(@_); #調(diào)用上一個子程序average
        my @list;
        foreach my $number (@_){
                if ($number > $average){
                        push @list,$number; #push的意思是把元素添加到list的最后
                } 
        }
                @list; #返回添加完所有符合要求的元素的list
        }

my @fred = &above_average(1..10);
print "@fred is @fred\n";
print "(Should be 6 7 8 9 10)\n";
my @barney = &above_average(100, 1..10);
print "@barney is @barney\n";

運行:

$ ./practice.pl
6 7 8 9 10 is 6 7 8 9 10
(Should be 6 7 8 9 10)
100 is 100
(Should be just 100)

第四題

Write a subroutine named greet that welcomes the person you name by telling
them the name of the last person it greeted:
greet( "Fred" );
greet( "Barney" );
This sequence of statements should print:
Hi Fred! You are the first one here!
Hi Barney! Fred is also here!

腳本:

#!/usr/bin/perl
use warnings;
use v5.24;

sub greet {
        state $last_person; #state聲明變量又沾,使該變量為本子程序私有變量
        my $name = shift; #標(biāo)量name里只需要一個參數(shù),使用shift卸載參數(shù)
        print "Hi $name! ";
        if( defined $last_person ) {
                print "$last_person is also here!\n";
        }
        else {
                print "You are the first one here!\n";
        }
        $last_person = $name;
}
greet( 'Fred' ); #當(dāng)?shù)谝粋€參數(shù)賦值為Fred時杖刷,name標(biāo)量的undef被Fred取代,執(zhí)行打印“Hi Fred!”役听。而defined判斷l(xiāng)ast_person是空字符串表窘,所以if循環(huán)執(zhí)行else的命令。隨后乐严,name的參數(shù)傳遞給last_person。
greet( 'Barney' );#第二次調(diào)用子程序的時候昂验,name標(biāo)量被Barney取代,執(zhí)行操作打印“Hi Barney!”黍匾。這時if循環(huán)里呛梆,defined判斷l(xiāng)ast_person標(biāo)量里不是空字符串锐涯,而是之前name傳遞過來的Fred填物,所以執(zhí)行第一條命令打印“Fred is also here!”

運行結(jié)果:

$ ./practice1.pl
Hi Fred! You are the first one here!
Hi Barney! Fred is also here!

第五題

Modify the previous program to tell each new person the names of all the
people it has previously greeted:
greet( "Fred" );
greet( "Barney" );
greet( "Wilma" );
greet( "Betty" );
This sequence of statements should print:
Hi Fred! You are the first one here!
Hi Barney! I've seen: Fred
Hi Wilma! I've seen: Fred Barney
Hi Betty! I've seen: Fred Barney Wilma

腳本:

#!/usr/bin/perl
use warnings;
use strict;
use v5.24;

sub greet {
        state $last_person;
        state @name; #定義一個數(shù)組
        my $name;
        foreach my $name(@_){
                print "Hi $name! "; #打印出標(biāo)量
                if( defined $last_person ) {
                        print "I'v seen: @name\n"; #這里打印出數(shù)組里全部參數(shù),所以每調(diào)用一次升薯,打印的參數(shù)就會多一個
                }
                else {
                        print "You are the first one here!\n";
                }
                $last_person = $name;
                push @name, $name;#每運行一次,把參數(shù)添加到@name數(shù)組里
        }
}
greet( 'Fred' ); 
greet( 'Barney' );
greet( 'Wilama');
greet(' betty');

運行結(jié)果:

$ ./practice1.pl
Hi Fred! You are the first one here!
Hi Barney! I'v seen: Fred
Hi Wilama! I'v seen: Fred Barney
Hi betty! I'v seen: Fred Barney Wilama
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末广凸,一起剝皮案震驚了整個濱河市蛛枚,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蹦浦,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件侥袜,死亡現(xiàn)場離奇詭異溉贿,居然都是意外死亡,警方通過查閱死者的電腦和手機顽照,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進(jìn)店門代兵,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人植影,你說我怎么就攤上這事∷急遥” “怎么了?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵惶我,是天一觀的道長博投。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么捧挺? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任尿瞭,我火速辦了婚禮,結(jié)果婚禮上声搁,老公的妹妹穿的比我還像新娘。我一直安慰自己酥艳,他們只是感情好爬骤,可當(dāng)我...
    茶點故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布霞玄。 她就那樣靜靜地躺著骤铃,像睡著了一般坷剧。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上惫企,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天狞尔,我揣著相機與錄音,去河邊找鬼偏序。 笑死,一個胖子當(dāng)著我的面吹牛研儒,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播端朵,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼冲呢,長吁一口氣:“原來是場噩夢啊……” “哼舍败!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起瓢颅,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤弛说,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后木人,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡渔嚷,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年稠曼,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片霞幅。...
    茶點故事閱讀 37,997評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡司恳,死狀恐怖途乃,靈堂內(nèi)的尸體忽然破棺而出扔傅,到底是詐尸還是另有隱情,我是刑警寧澤猎塞,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布邢享,位于F島的核電站鹏往,受9級特大地震影響骇塘,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜款违,卻給世界環(huán)境...
    茶點故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望哄辣。 院中可真熱鬧,春花似錦力穗、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽元咙。三九已至,卻和暖如春庶香,著一層夾襖步出監(jiān)牢的瞬間简识,已是汗流浹背赶掖。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工倘零, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓疫鹊,卻偏偏與公主長得像,于是被迫代替她去往敵國和親拆吆。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,722評論 2 345