日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

perl教程(2)

發(fā)布時間:2023/12/20 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 perl教程(2) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

第六節(jié):

一、數(shù)組變量的限制
在前面講的數(shù)組變量中,可以通過下標(biāo)訪問其中的元素。例如,下列語句訪問數(shù)組@array的第三個元素:
$scalar = $array[2];
雖然數(shù)組很有用,但它們有一個顯著缺陷,即很難記住哪個元素存貯的什么內(nèi)容。假如我們來寫一個程序計算某文件中首字母大寫的單詞出現(xiàn)的次數(shù),用數(shù)組來實現(xiàn)就比較困難,程序代碼如下:

1 : #!/usr/local/bin/perl
2 :
3 : while ($inputline = <STDIN>) {
4 : while ($inputline =~ /b[A-Z]S+/g) {
5 : $word = $&;
6 : $word =~ s/[;.,:-]$//; # remove punctuation
7 : for ($count = 1; $count <= @wordlist;
8 : $count++) {
9 : $found = 0;
10: if ($wordlist[$count-1] eq $word) {
11: $found = 1;
12: $wordcount[$count-1] += 1;
13: last;
14: }
15: }
16: if ($found == 0) {
17: $oldlength = @wordlist;
18: $wordlist[$oldlength] = $word;
19: $wordcount[$oldlength] = 1;
20: }
21: }
22: }
23: print ("Capitalized words and number of occurrences:n");
24: for ($count = 1; $count <= @wordlist; $count++) {
25: print ("$wordlist[$count-1]: $wordcount[$count-1]n");
26: }

運行結(jié)果如下:


Here is a line of Input.
This Input contains some Capitalized words.
^D
Capitalized words and number of occurrences:
Here: 1
Input: 2
This: 1
Capitalized: 1

這個程序每次從標(biāo)準(zhǔn)輸入文件讀一行文字,第四行起的循環(huán)匹配每行中首字母大寫的單詞,每找到一個循環(huán)一次,賦給簡單變量$word。在第六行中去掉標(biāo)點后,查看該單詞是否曾出現(xiàn)過,7~15行中在@wordlist中挨個元素做此檢查,如果某個元素與$word相等,@wordcount中相應(yīng)的元素就增加一個數(shù)。如果沒有出現(xiàn)過,即@wordlist中沒有元素與$word相等,16~20行給@wordlist和@wordcount增加一個新元素。
二、定義
正如你所看到的,使用數(shù)組元素產(chǎn)生了一些問題。首先,@wordlist中哪個元素對應(yīng)著哪個單詞并不明顯;更糟的是,每讀進(jìn)一個新單詞,程序必須檢查整個列表才能知道該單詞是否曾經(jīng)出現(xiàn)過,當(dāng)列表變得較大時,這是很耗費時間的。
這些問題產(chǎn)生的原因是數(shù)組元素通過數(shù)字下標(biāo)訪問,為了解決這類問題,Perl定義了另一種數(shù)組,可以用任意簡單變量值來訪問其元素,這種數(shù)組叫做關(guān)聯(lián)數(shù)組,也叫哈希表。
為了區(qū)分關(guān)聯(lián)數(shù)組變量與普通的數(shù)組變量,Perl使用%作為其首字符,而數(shù)組變量以@打頭。與其它變量名一樣,%后的第一個字符必須為字母,后續(xù)字符可以為字母、數(shù)字或下劃線。
三、訪問關(guān)聯(lián)數(shù)組的元素
關(guān)聯(lián)數(shù)組的下標(biāo)可以為任何簡單/標(biāo)量值,訪問單個元素時以$符號打頭,下標(biāo)用大括號圍起來。例如:

$fruit{"bananas"}
$number{3.14159}
$integer{-7}

簡單變量也可作為下標(biāo),如:
$fruit{$my_fruit}
四、增加元素
創(chuàng)建一個關(guān)聯(lián)數(shù)組元素最簡單的方法是賦值,如語句$fruit{"bananas"} = 1; 把1賦給關(guān)聯(lián)數(shù)組%fruit下標(biāo)為bananas的元素,如果該元素不存在,則被創(chuàng)建,如果數(shù)組%fruit從未使用過,也被創(chuàng)建。
這一特性使得關(guān)聯(lián)數(shù)組很容易用于計數(shù)。下面我們用關(guān)聯(lián)數(shù)組改寫上面的程序,注意實現(xiàn)同樣的功能此程序簡化了許多。


1 : #!/usr/local/bin/perl
2 :
3 : while ($inputline = ) {
4 : while ($inputline =~ /b[A-Z]S+/g) {
5 : $word = $&;
6 : $word =~ s/[;.,:-]$//; # remove punctuation
7 : $wordlist{$word} += 1;
8 : }
9 : }
10: print ("Capitalized words and number of occurrences:n");
11: foreach $capword (keys(%wordlist)) {
12: print ("$capword: $wordlist{$capword}n");
13: }

運行結(jié)果如下:


Here is a line of Input.
This Input contains some Capitalized words.
^D
Capitalized words and number of occurrences:
This: 1
Input: 2
Here: 1
Capitalized: 1

你可以看到,這次程序簡單多了,讀取輸入并存貯各單詞數(shù)目從20行減少到了7行。
本程序用關(guān)聯(lián)數(shù)組%wordlist跟蹤首字母大寫的單詞,下標(biāo)就用單詞本身,元素值為該單詞出現(xiàn)的次數(shù)。第11行使用了內(nèi)嵌函數(shù)keys()。這個函數(shù)返回關(guān)聯(lián)數(shù)組的下標(biāo)列表,foreach語句就用此列表循環(huán)。
注:關(guān)聯(lián)數(shù)組總是隨機(jī)存貯的,因此當(dāng)你用keys()訪問其所有元素時,不保證元素以任何順序出現(xiàn),特別值得一提的是,它們不會以被創(chuàng)建的順序出現(xiàn)。
要想控制關(guān)聯(lián)數(shù)組元素出現(xiàn)的次序,可以用sort()函數(shù)對keys()返回值進(jìn)行排列,如:

foreach $capword (sort keys(%wordlist)) {
print ("$capword: $wordlist{$capword}n");
}

 

五、創(chuàng)建關(guān)聯(lián)數(shù)組
可以用單個賦值語句創(chuàng)建關(guān)聯(lián)數(shù)組,如:
%fruit = ("apples",17,"bananas",9,"oranges","none");
此語句創(chuàng)建的關(guān)聯(lián)數(shù)組含有下面三個元素:

下標(biāo)為apples的元素,值為17
下標(biāo)為bananas的元素,值為9
下標(biāo)為oranges的元素,值為none
注:用列表給關(guān)聯(lián)數(shù)組賦值時,Perl5允許使用"=>"或","來分隔下標(biāo)與值,用"=>"可讀性更好些,上面語句等效于:
%fruit = ("apples"=>17,"bananas"=>9,"oranges"=>"none");
六、從數(shù)組變量復(fù)制到關(guān)聯(lián)數(shù)組
與列表一樣,也可以通過數(shù)組變量創(chuàng)建關(guān)聯(lián)數(shù)組,當(dāng)然,其元素數(shù)目應(yīng)該為偶數(shù),如:
@fruit = ("apples",17,"bananas",9,"oranges","none");
%fruit = @fruit;
反之,可以把關(guān)聯(lián)數(shù)組賦給數(shù)組變量,如:
%fruit = ("grapes",11,"lemons",27);
@fruit = %fruit;
注意,此語句中元素次序未定義,那么數(shù)組變量@fruit可能為("grapes",11,"lemons",27)或("lemons",27,"grapes",11)。
關(guān)聯(lián)數(shù)組變量之間可以直接賦值,如:%fruit2 = %fruit1; 還可以把數(shù)組變量同時賦給一些簡單變量和一個關(guān)聯(lián)數(shù)組變量,如:
($var1, $var2, %myarray) = @list;
此語句把@list的第一個元素賦給$var1,第二個賦給$var2,其余的賦給%myarray。
最后,關(guān)聯(lián)數(shù)組可以通過返回值為列表的內(nèi)嵌函數(shù)或用戶定義的子程序來創(chuàng)建,下例中把split()函數(shù)的返回值--一個列表--賦給一個關(guān)聯(lián)數(shù)組變量。

1: #!/usr/local/bin/perl
2:
3: $inputline = <STDIN>;
4: $inputline =~ s/^s+|s+n$//g;
5: %fruit = split(/s+/, $inputline);
6: print ("Number of bananas: $fruit{"bananas"}n");

運行結(jié)果如下:

oranges 5 apples 7 bananas 11 cherries 6
Number of bananas: 11

 

七、元素的增刪
增加元素已經(jīng)講過,可以通過給一個未出現(xiàn)過的元素賦值來向關(guān)聯(lián)數(shù)組中增加新元素,如$fruit{"lime"} = 1;創(chuàng)建下標(biāo)為lime、值為1的新元素。
刪除元素的方法是用內(nèi)嵌函數(shù)delete,如欲刪除上述元素,則:
delete ($fruit{"lime"});
注意:

1、一定要使用delete函數(shù)來刪除關(guān)聯(lián)數(shù)組的元素,這是唯一的方法。
2、一定不要對關(guān)聯(lián)數(shù)組使用內(nèi)嵌函數(shù)push、pop、shift及splice,因為其元素位置是隨機(jī)的。

 

八、列出數(shù)組的索引和值
上面已經(jīng)提到,keys()函數(shù)返回關(guān)聯(lián)數(shù)組下標(biāo)的列表,如:


%fruit = ("apples", 9,
"bananas", 23,
"cherries", 11);
@fruitsubs = keys(%fruits);
這里,@fruitsubs被賦給apples、bananas、cherries構(gòu)成的列表,再次提請注意,此列表沒有次序,若想按字母順序排列,可使用sort()函數(shù)。
@fruitindexes = sort keys(%fruits);
這樣結(jié)果為("apples","bananas","cherries")。類似的,內(nèi)嵌函數(shù)values()返回關(guān)聯(lián)數(shù)組值的列表,如:


%fruit = ("apples", 9,
"bananas", 23,
"cherries", 11);
@fruitvalues = values(%fruits);
這里,@fruitvalues可能的結(jié)果為(9,23.11),次序可能不同。
九、用關(guān)聯(lián)數(shù)組循環(huán)
前面已經(jīng)出現(xiàn)過利用keys()函數(shù)的foreach循環(huán)語句,這種循環(huán)效率比較低,因為每返回一個下標(biāo),還得再去尋找其值,如:


foreach $holder (keys(%records)){
$record = $records{$holder};
}

Perl提供一種更有效的循環(huán)方式,使用內(nèi)嵌函數(shù)each(),如:


%records = ("Maris", 61, "Aaron", 755, "Young", 511);
while (($holder, $record) = each(%records)) {
# stuff goes here
}

each()函數(shù)每次返回一個雙元素的列表,其第一個元素為下標(biāo),第二個元素為相應(yīng)的值,最后返回一個空列表。
注意:千萬不要在each()循環(huán)中添加或刪除元素,否則會產(chǎn)生不可預(yù)料的后果。
十、用關(guān)聯(lián)數(shù)組創(chuàng)建數(shù)據(jù)結(jié)構(gòu)
用關(guān)聯(lián)數(shù)組可以模擬在其它高級語言中常見的多種數(shù)據(jù)結(jié)構(gòu),本節(jié)講述如何用之實現(xiàn):鏈表、結(jié)構(gòu)和樹。
1、(單)鏈表
鏈表是一種比較簡單的數(shù)據(jù)結(jié)構(gòu),可以按一定的次序存貯值。每個元素含有兩個域,一個是值,一個是引用(或稱指針),指向鏈表中下一個元素。一個特殊的頭指針指向鏈表的第一個元素。
在Perl中,鏈表很容易用關(guān)聯(lián)數(shù)組實現(xiàn),因為一個元素的值可以作為下一個元素的索引。下例為按字母順序排列的單詞鏈表:


%words = ("abel", "baker",
"baker", "charlie",
"charlie", "delta",
"delta", "");
$header = "abel";
上例中,簡單變量$header含有鏈表中第一個單詞,它同時也是關(guān)聯(lián)數(shù)組第一個元素的下標(biāo),其值baker又是下一個元素的下標(biāo),依此類推。
下標(biāo)為delta的最后一個元素的值為空串,表示鏈表的結(jié)束。
在將要處理的數(shù)據(jù)個數(shù)未知或其隨程序運行而增長的情況下,鏈表十分有用。下例用鏈表按字母次序輸出一個文件中的單詞。


1 : #!/usr/local/bin/perl
2 :
3 : # initialize list to empty
4 : $header = "";
5 : while ($line = <STDIN>) {
6 : # remove leading and trailing spaces
7 : $line =~ s/^s+|s+$//g;
8 : @words = split(/s+/, $line);
9 : foreach $word (@words) {
10: # remove closing punctuation, if any
11: $word =~ s/[.,;:-]$//;
12: # convert all words to lower case
13: $word =~ tr/A-Z/a-z/;
14: &add_word_to_list($word);
15: }
16: }
17: &print_list;
18:
19: sub add_word_to_list {
20: local($word) = @_;
21: local($pointer);
22:
23: # if list is empty, add first item
24: if ($header eq "") {
25: $header = $word;
26: $wordlist{$word} = "";
27: return;
28: }
29: # if word identical to first element in list,
30: # do nothing
31: return if ($header eq $word);
32: # see whether word should be the new
33: # first word in the list
34: if ($header gt $word) {
35: $wordlist{$word} = $header;
36: $header = $word;
37: return;
38: }
39: # find place where word belongs
40: $pointer = $header;
41: while ($wordlist{$pointer} ne "" &&
42: $wordlist{$pointer} lt $word) {
43: $pointer = $wordlist{$pointer};
44: }
45: # if word already seen, do nothing
46: return if ($word eq $wordlist{$pointer});
47: $wordlist{$word} = $wordlist{$pointer};
48: $wordlist{$pointer} = $word;
49: }
50:
51: sub print_list {
52: local ($pointer);
53: print ("Words in this file:n");
54: $pointer = $header;
55: while ($pointer ne "") {
56: print ("$pointern");
57: $pointer = $wordlist{$pointer};
58: }
59: }

運行結(jié)果如下:


Here are some words.
Here are more words.
Here are still more words.
^D
Words in this file:
are
here
more
some
still
words

此程序分為三個部分:


主程序:讀取輸入并轉(zhuǎn)換到相應(yīng)的格式。
子程序:add_word_to_list,建立排序單詞鏈表。
子程序:print_list,輸出單詞鏈表
第3~17行為主程序,第4行初始化鏈表,將表頭變量$header設(shè)為空串,第5行起的循環(huán)每次讀取一行輸入,第7行去掉頭、尾的空格,第8行將句子分割成單詞。9~15行的內(nèi)循環(huán)每次處理一個單詞,如果該單詞的最后一個字符是標(biāo)點符號,就去掉。第13行把單詞轉(zhuǎn)換成全小寫形式,第14行傳遞給子程序 add_word_to_list。
子程序add_word_to_list先在第24行處檢查鏈表是否為空。如果是,第25行將單詞賦給$header,26行創(chuàng)建鏈表第一個元素,存貯在關(guān)聯(lián)數(shù)組%wordlist中。如果鏈表非空,37行檢查第一個元素是否與該單詞相同,如果相同,就立刻返回。下一步檢查這一新單詞是否應(yīng)該為鏈表第一個元素,即其按字母順序先于$header。如果是這樣,則:
1、創(chuàng)建一個新元素,下標(biāo)為該新單詞,其值為原第一個單詞。
2、該新單詞賦給$header。
如果該新單詞不該為第一個元素,則40~44行利用局域變量$pointer尋找其合適的有效位置,41~44行循環(huán)到$wordlist{$ pointer}大于或等于$word為止。接下來46行查看該單詞是否已在鏈表中,如果在就返回,否則47~48行將其添加到鏈表中。首先47行創(chuàng)建新元素$wordlist{$word},其值為$wordlist{$pointer},這時$wordlist{$word}和$wordlist{$ pointer}指向同一個單詞。然后,48行將$wordlist{$pointer}的值賦為$word,即將$wordlist{$ pointer}指向剛創(chuàng)建的新元素$wordlist{$word}。
最后當(dāng)處理完畢后,子程序print_list()依次輸出鏈表,局域變量$pointer含有正在輸出的值,$wordlist{$pointer}為下一個要輸出的值。
注:一般不需要用鏈表來做這些工作,用sort()和keys()在關(guān)聯(lián)數(shù)組中循環(huán)就足夠了,如:


foreach $word (sort keys(%wordlist)) {
# print the sorted list, or whatever }

但是,這里涉及的指針的概念在其它數(shù)據(jù)結(jié)構(gòu)中很有意義。
2、結(jié)構(gòu)
許多編程語言可以定義結(jié)構(gòu)(structure),即一組數(shù)據(jù)的集合。結(jié)構(gòu)中的每個元素有其自己的名字,并通過該名字來訪問。
Perl不直接提供結(jié)構(gòu)這種數(shù)據(jù)結(jié)構(gòu),但可以用關(guān)聯(lián)數(shù)組來模擬。例如模擬C語言中如下的結(jié)構(gòu):


struce{
int field1;
int field2;
int field3; }mystructvar;

我們要做的是定義一個含有三個元素的關(guān)聯(lián)數(shù)組,下標(biāo)分別為field1、field2、field3,如:


%mystructvar = ("field1" , "" ,
"field2" , "" ,
"field3" , "" ,);

像上面C語言的定義一樣,這個關(guān)聯(lián)數(shù)組%mystrctvar有三個元素,下標(biāo)分別為field1、field2、field3,各元素初始值均為空串。對各元素的訪問和賦值通過指定下標(biāo)來進(jìn)行,如:
$mystructvar{"field1"} = 17;
3、樹
另一個經(jīng)常使用的數(shù)據(jù)結(jié)構(gòu)是樹。樹與鏈表類似,但每個節(jié)點指向的元素多于一個。最簡單的樹是二叉樹,每個節(jié)點指向另外兩個元素,稱為左子節(jié)點和右子節(jié)點(或稱孩子),每個子節(jié)點又指向兩個孫子節(jié)點,依此類推。
注:此處所說的樹像上述鏈表一樣是單向的,每個節(jié)點指向其子節(jié)點,但子節(jié)點并不指向父節(jié)點。
樹的概念可以如下描述:


因為每個子節(jié)點均為一個樹,所以左/右子節(jié)點也稱為左/右子樹。(有時稱左/右分支)
第一個節(jié)點(不是任何節(jié)點的子節(jié)點的節(jié)點)稱為樹的根。
沒有孩子(子節(jié)點)的節(jié)點稱為葉節(jié)點。
有多種使用關(guān)聯(lián)數(shù)組實現(xiàn)樹結(jié)構(gòu)的方法,最好的一種應(yīng)該是:給子節(jié)點分別加上left和right以訪問之。例如,alphaleft和alpharight指向alpha的左右子節(jié)點。下面是用此方法創(chuàng)建二叉樹并遍歷的例程:


1 : #!/usr/local/bin/perl
2 :
3 : $rootname = "parent";
4 : %tree = ("parentleft", "child1",
5 : "parentright", "child2",
6 : "child1left", "grandchild1",
7 : "child1right", "grandchild2",
8 : "child2left", "grandchild3",
9 : "child2right", "grandchild4");
10: # traverse tree, printing its elements
11: &print_tree($rootname);
12:
13: sub print_tree {
14: local ($nodename) = @_;
15: local ($leftchildname, $rightchildname);
16:
17: $leftchildname = $nodename . "left";
18: $rightchildname = $nodename . "right";
19: if ($tree{$leftchildname} ne "") {
20: &print_tree($tree{$leftchildname});
21: }
22: print ("$nodenamen");
23: if ($tree{$rightchildname} ne "") {
24: &print_tree($tree{$rightchildname});
25: }
26: }

結(jié)果輸出如下:


grandchild1
child1
grandchild2
parent
grandchild3
child2
grandchild4

第七節(jié):

一、引用簡介
二、使用引用
三、使用反斜線()操作符
四、引用和數(shù)組
五、多維數(shù)組
六、子程序的引用
子程序模板
七、數(shù)組與子程序
八、文件句柄的引用

一、引用簡介
引用就是指針,可以指向變量、數(shù)組、哈希表(也叫關(guān)聯(lián)數(shù)組)甚至子程序。Pascal或C程序員應(yīng)該對引用(即指針)的概念很熟悉,引用就是某值的地址,對其的使用則取決于程序員和語言的規(guī)定。在Perl中,可以把引用稱為指針,二者是通用的,無差別的。引用在創(chuàng)建復(fù)雜數(shù)據(jù)方面十分有用。
Perl5中的兩種引用類型為硬引用和符號引用。符號引用含有變量的名字,它對運行時創(chuàng)建變量名并定位很有用,基本上,符號引用就象文件名或UNIX系統(tǒng)中的軟鏈接。而硬引用則象文件系統(tǒng)中的硬鏈接。
Perl4只允許符號引用,給使用造成一些困難。例如,只允許通過名字對包的符號名哈希表(名為_main{})建立索引。Perl5則允許數(shù)據(jù)的硬引用,方便多了。
硬引用跟蹤引用的計數(shù),當(dāng)其數(shù)為零時,Perl自動將被引用的項目釋放,如果該項目是對象,則析構(gòu)釋放到內(nèi)存池中。Perl本身就是個面向?qū)ο蟮恼Z言,因為Perl中的任何東西都是對象,包和模塊使得對象更易于使用。
簡單變量的硬引用很簡單,對于非簡單變量的引用,你必須顯式地解除引用并告訴其應(yīng)如何做,詳見《第 章Perl中的面向?qū)ο缶幊獭贰?br />二、使用引用
本章中,簡單變量指像$pointer這樣的變量,$pointer僅含一個數(shù)據(jù)項,其可以為數(shù)字、字符串或地址。
任何簡單變量均可保存硬引用。因為數(shù)組和哈希表含有多個簡單變量,所以可以建立多種組合而成的復(fù)雜的數(shù)據(jù)結(jié)構(gòu),如數(shù)組的數(shù)組、哈希表的數(shù)組、子程序的哈希表等等。只要你理解其實只是在用簡單變量在工作,就應(yīng)該可以正確的在最復(fù)雜的結(jié)構(gòu)中正確地解除引用。
首先來看一些基本要點。
如果$pointer的值為一個數(shù)組的指針,則通過形式@$pointer來訪問數(shù)組中的元素。形式@$pointer的意義為“取出$pointer中的地址值當(dāng)作數(shù)組使用”。類似的,%$pointer為指向哈希表中第一個元素的引用。
有多種構(gòu)建引用的方法,幾乎可以對任何數(shù)據(jù)建立引用,如數(shù)組、簡單變量、子程序、文件句柄,以及--C程序員會感興趣的--引用。Perl使你有能力寫出把自己都搞糊涂的極其復(fù)雜的代碼。:)
下面看看Perl中創(chuàng)建和使用引用的方法。
三、使用反斜線()操作符
反斜線操作符與C語言中傳遞地址的操作符&功能類似。一般是用創(chuàng)建變量又一個新的引用。下面為創(chuàng)建簡單變量的引用的例子:
$variavle = 22;
$pointer = $variable;
$ice = "jello";
$iceprt = $ice;
引用$pointer指向存有$variable值的位置,引用$iceptr指向"jello"。即使最初的引用$variable銷毀了,仍然可以通過$pointer訪問該值,這是一個硬引用,所以必須同時銷毀$pointer和$variable以便該空間釋放到內(nèi)存池中。
在上面的例子中,引用變量$pointer存的是$variable的地址,而不是值本身,要獲得值,形式為兩個$符號,如下:


#!/usr/bin/perl
$value = 10;
$pointer = $value;
printf "n Pointer Address $pointer of $value n";
printf "n What Pointer *($pointer) points to $$pointern";

結(jié)果輸出如下:


Pointer Address SCALAR(0x806c520) of 10
What Pointer *(SCALAR(0x806c520)) points to 10

每次運行,輸出結(jié)果中的地址會有所改變,但可以看到$pointer給出地址,而$$pointer給出$variable的值。
看一下地址的顯示,SCALAR后面一串十六進(jìn)制,SCALAR說明該地址指向簡單變量(即標(biāo)量),后面的數(shù)字是實際存貯值的地址。
注意:指針就是地址,通過指針可以訪問該地址處存貯的數(shù)據(jù)。如果指針指向了無效的地址,就會得到不正確的數(shù)據(jù)。通常情況下,Perl會返回NULL值,但不該依賴于此,一定要在程序中把所有的指針正確地初始化,指向有效的數(shù)據(jù)項。
四、引用和數(shù)組
關(guān)于Perl語言應(yīng)該記住的最重要的一點可能是:Perl中的數(shù)組和哈希表始終是一維的。因此,數(shù)組和哈希表只保存標(biāo)量值,不直接存貯數(shù)組或其它的復(fù)雜數(shù)據(jù)結(jié)構(gòu)。數(shù)組的成員要么是數(shù)(或字符串)要么是引用。
對數(shù)組和哈希表可以象對簡單變量一樣使用反斜線操作符,數(shù)組的引用如下:


1 #!/usr/bin/perl
2 #
3 # Using Array references
4 #
5 $pointer = @ARGV;
6 printf "n Pointer Address of ARGV = $pointern";
7 $i = scalar(@$pointer);
8 printf "n Number of arguments : $i n";
9 $i = 0;
10 foreach (@$pointer) {
11 printf "$i : $$pointer[$i++]; n";
12 }

運行結(jié)果如下:


$ test 1 2 3 4
Pointer Address of ARGV = ARRAY(0x806c378)
Number of arguments : 4
0 : 1;
1 : 2;
2 : 3;
3 : 4;

第5行將引用$pointer指向數(shù)組@ARGV,第6行輸出ARGV的地址。$pointer返回數(shù)組第一個元素的地址,這與C語言中的數(shù)組指針是類似的。第7行調(diào)用函數(shù)scalar()獲得數(shù)組的元素個數(shù),該參數(shù)亦可為@ARGV,但用指針則必須用@$pointer的形式指定其類型為數(shù)組,$ pointer給出地址,@符號說明傳遞的地址為數(shù)組的第一個元素的地址。第10行與第7行類似,第11行用形式$$pointer[$i]列出所有元素。
對關(guān)聯(lián)數(shù)組使用反斜線操作符的方法是一樣的--把所有關(guān)聯(lián)數(shù)組名換成引用$poniter。注意數(shù)組和簡單變量(標(biāo)量)的引用顯示時均帶有類型--ARRAY和SCALAR,哈希表(關(guān)聯(lián)數(shù)組)和函數(shù)也一樣,分別為HASH和CODE。下面是哈希表的引用的例子。


#!/usr/bin/perl
1 #
2 # Using Associative Array references
3 #
4 %month = (
5 '01', 'Jan',
6 '02', 'Feb',
7 '03', 'Mar',
8 '04', 'Apr',
9 '05', 'May',
10 '06', 'Jun',
11 '07', 'Jul',
12 '08', 'Aug',
13 '09', 'Sep',
14 '10', 'Oct',
15 '11', 'Nov',
16 '12', 'Dec',
17 );
18
19 $pointer = %month;
20
21 printf "n Address of hash = $pointern ";
22
23 #
24 # The following lines would be used to print out the
25 # contents of the associative array if %month was used.
26 #
27 # foreach $i (sort keys %month) {
28 # printf "n $i $$pointer{$i} ";
29 # }
30
31 #
32 # The reference to the associative array via $pointer
33 #
34 foreach $i (sort keys %$pointer) {
35 printf "$i is $$pointer{$i} n";
36 }

結(jié)果輸出如下:


$ mth
Address of hash = HASH(0x806c52c)
01 is Jan
02 is Feb
03 is Mar
04 is Apr
05 is May
06 is Jun
07 is Jul
08 is Aug
09 is Sep
10 is Oct
11 is Nov
12 is Dec

與數(shù)組類似,通過引用訪問哈希表的元素形式為$$pointer{$index},當(dāng)然,$index是哈希表的鍵值,而不僅是數(shù)字。還有幾種訪問形式,此外,構(gòu)建哈希表還可以用=>操作符,可讀性更好些。下面再看一個例子:


1 #!/usr/bin/perl
2 #
3 # Using Array references
4 #
5 %weekday = (
6 '01' => 'Mon',
7 '02' => 'Tue',
8 '03' => 'Wed',
9 '04' => 'Thu',
10 '05' => 'Fri',
11 '06' => 'Sat',
12 '07' => 'Sun',
13 );
14 $pointer = %weekday;
15 $i = '05';
16 printf "n ================== start test ================= n";
17 #
18 # These next two lines should show an output
19 #
20 printf '$$pointer{$i} is ';
21 printf "$$pointer{$i} n";
22 printf '${$pointer}{$i} is ';
23 printf "${$pointer}{$i} n";
24 printf '$pointer->{$i} is ';
25
26 printf "$pointer->{$i}n";
27 #
28 # These next two lines should not show anything 29 #
30 printf '${$pointer{$i}} is ';
31 printf "${$pointer{$i}} n";
32 printf '${$pointer->{$i}} is ';
33 printf "${$pointer->{$i}}";
34 printf "n ================== end of test ================= n";
35

結(jié)果輸出如下:


================== start test =================
$$pointer{$i} is Fri
${$pointer}{$i} is Fri
$pointer->{$i} is Fri
${$pointer{$i}} is
${$pointer->{$i}} is
================== end of test =================

可以看到,前三種形式的輸出顯示了預(yù)期的結(jié)果,而后兩種則沒有。當(dāng)你不清楚是否正確時,就輸出結(jié)果看看。在Perl中,有不明確的代碼就用print語句輸出來實驗一下,這能使你清楚Perl是怎樣解釋你的代碼的。
五、多維數(shù)組
語句@array = list;可以創(chuàng)建數(shù)組的引用,中括號可以創(chuàng)建匿名數(shù)組的引用。下面語句為用于畫圖的三維數(shù)組的例子:
$line = ['solid' , 'black' , ['1','2','3'] , ['4','5','6']];
此語句建立了一個含四個元素的三維數(shù)組,變量$line指向該數(shù)組。前兩個元素是標(biāo)量,存貯線條的類型和顏色,后兩個元素是匿名數(shù)組的引用,存貯線條的起點和終點。訪問其元素語法如下:


$arrayReference->[$index] single-dimensional array
$arrayReference->[$index1][$index2] two-dimensional array
$arrayReference->[$index1][$index2][$index3] three-dimensional array

可以創(chuàng)建在你的智力、設(shè)計經(jīng)驗和計算機(jī)的內(nèi)存允許的情況下極盡復(fù)雜的結(jié)構(gòu),但最好對可能讀到或管理你的代碼的人友好一些--盡量使代碼簡單些。另一方面,如果你想向別人炫耀你的編程能力,Perl給你足夠的機(jī)會和能力編寫連自己都難免糊涂的代碼。:)
建議:當(dāng)你想使用多于三維的數(shù)組時,最好考慮使用其它數(shù)據(jù)結(jié)構(gòu)來簡化代碼。
下面為創(chuàng)建和使用二維數(shù)組的例子:


1 #!/usr/bin/perl
2 #
3 # Using Multi-dimensional Array references
4 #
5 $line = ['solid', 'black', ['1','2','3'] , ['4', '5', '6']];
6 print "$line->[0] = $line->[0] n";
7 print "$line->[1] = $line->[1] n";
8 print "$line->[2][0] = $line->[2][0] n";
9 print "$line->[2][1] = $line->[2][1] n";
10 print "$line->[2][2] = $line->[2][2] n";
11 print "$line->[3][0] = $line->[3][0] n";
12 print "$line->[3][1] = $line->[3][1] n";
13 print "$line->[3][2] = $line->[3][2] n";
14 print "n"; # The obligatory output beautifier.

結(jié)果輸出如下:


$line->[0] = solid
$line->[1] = black
$line->[2][0] = 1
$line->[2][1] = 2
$line->[2][2] = 3
$line->[3][0] = 4
$line->[3][1] = 5
$line->[3][2] = 6

那么三維數(shù)組又如何呢?下面是上例略為改動的版本。


1 #!/usr/bin/perl
2 #
3 # Using Multi-dimensional Array references again
4 #
5 $line = ['solid', 'black', ['1','2','3', ['4', '5', '6']]];
6 print "$line->[0] = $line->[0] n";
7 print "$line->[1] = $line->[1] n";
8 print "$line->[2][0] = $line->[2][0] n";
9 print "$line->[2][1] = $line->[2][1] n";
10 print "$line->[2][2] = $line->[2][2] n";
11 print "$line->[2][3][0] = $line->[2][3][0] n";
12 print "$line->[2][3][1] = $line->[2][3][1] n";
13 print "$line->[2][3][2] = $line->[2][3][2] n";
14 print "n";

結(jié)果輸出如下:


$line->[0] = solid
$line->[1] = black
$line->[2][0] = 1
$line->[2][1] = 2
$line->[2][2] = 3
$line->[2][3][0] = 4
$line->[2][3][1] = 5
$line->[2][3][2] = 6

訪問第三層元素的方式形如$line->[2][3][0],類似于C語言中的Array_pointer[2][3][0]。本例中,下標(biāo)均為數(shù)字,當(dāng)然亦可用變量代替。用這種方法可以把數(shù)組和哈希表結(jié)合起來構(gòu)成復(fù)雜的結(jié)構(gòu),如下:


1 #!/usr/bin/perl
2 #
3 # Using Multi-dimensional Array and Hash references
4 #
5 %cube = (
6 '0', ['0', '0', '0'],
7 '1', ['0', '0', '1'],
8 '2', ['0', '1', '0'],
9 '3', ['0', '1', '1'],
10 '4', ['1', '0', '0'],
11 '5', ['1', '0', '1'],
12 '6', ['1', '1', '0'],
13 '7', ['1', '1', '1']
14 );
15 $pointer = %cube;
16 print "n Da Cube n";
17 foreach $i (sort keys %$pointer) {
18 $list = $$pointer{$i};
19 $x = $list->[0];
20 $y = $list->[1];
21 $z = $list->[2];
22 printf " Point $i = $x,$y,$z n";
23 }

結(jié)果輸出如下:


Da Cube
Point 0 = 0,0,0
Point 1 = 0,0,1
Point 2 = 0,1,0
Point 3 = 0,1,1
Point 4 = 1,0,0
Point 5 = 1,0,1
Point 6 = 1,1,0
Point 7 = 1,1,1

這是一個定義立方體的例子。%cube中保存的是點號和坐標(biāo),坐標(biāo)是個含三個數(shù)字的數(shù)組。變量$list獲取坐標(biāo)數(shù)組的引用:$list = $$ pointer{$i}; 然后訪問各坐標(biāo)值:$x = $list->[0]; ... 也可用如下方法給$x、$y和$z賦值:($x,$y,$z) = @$list;
使用哈希表和數(shù)組時,用$和用->是類似的,對數(shù)組而言下面兩個語句等效:
$$names[0] = "kamran";
$names->[0] = "kamran";
對哈希表而言下面兩個語句等效:
$$lastnames{"kamran"} = "Husain";
$lastnames->{"kamran"} = "Husain";
Perl中的數(shù)組可以在運行中創(chuàng)建和擴(kuò)展。當(dāng)數(shù)組的引用第一次在等式左邊出現(xiàn)時,該數(shù)組自動被創(chuàng)建,簡單變量和多維數(shù)組也是一樣。如下句,如果數(shù)組contours不存在,則被創(chuàng)建:
$contours[$x][$y][$z] = &xlate($mouseX, $mouseY);

轉(zhuǎn)載于:https://www.cnblogs.com/shineshqw/articles/1978140.html

總結(jié)

以上是生活随笔為你收集整理的perl教程(2)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。