2011年10月10日 星期一

控制敘述(Control Statements)

控制敘述(Control Statements)

控制敘述。有時我們為了讓程式在執行過程中,因為需求的不同,而進行不同的運算。

這個時候,我們就必須藉由控制敘述(Control Statements)進行程式中的流程控制。

先從perl基本的流程控制開始介紹吧!

首先我們先來介紹這三個:<STDIN> if else

<STDIN>是告訴你的程式,在這裡要停一下,等待使用者輸入一段文字或是數字。

if是讓你的程式能經過小括號( )內的判斷,再執行大擴號{ }內的運算,普遍的寫法是:

if(判斷條件)

{

# 符合判斷條件的話 就會在這裡執行運算

}

而在if之後通常是緊接else,

不過如果你不希望程式,去執行不符合的條件時,else可以捨去不寫。

else是當if判斷條件不成立的時候,則執行大擴號{}內的運算。

綜合以上的這三個控制敘述,我們來看個例子吧:

$number = <STDIN> ;# 程式等待使用者輸入 並把輸入的值存到變數

if ($number > 3)# 當變數大於3時 (記住 這裡沒有使用分號)

{

print "$number這個數大於3喔!\n";# 印出訊息以及換行

}

else # 這裡就不用寫判斷條件了

{

print "$number這個數等於或是小於3喔!\n";# 印出訊息以及換行

}

執行一次吧!你會發現程式真的停下來等你輸入呢!


因為開始使用到了大括號,就需要解釋什麼是程式區塊(Block)

在perl裡,程式區塊(Block)多半指的是大括號包起來的部分

之前我們定義變數都是直接設為$a = 0; 這樣的方式,

表示這個陣列、變數、雜湊可以作為全域(Global)使用,不受區塊限制

不過,如果前面多了一個my,就表示這個陣列、變數、雜湊,

就只能執行在這個特定的區塊裡面,一旦出了區塊,

這個變數或是陣列等,就不會存在。我們稱為區域化(local)

我們用簡單的例子來說明:

$a = 0; # 設$a為0

{

my $b = $a; # $a將$b取代 也就是$b跟$a目前同樣為0

print "$b\n"; # 印出$b以及換行一次

}

print "$b\n"; # 再次印出$b以及換行一次

理論上應該會看到兩次0被印出來,不過因為my的關係,

當你使用了-w這個除錯參數,你會看到印出這樣警告訊息:

Name "main::b" used only once: possible typo at test.pl line 11.

0

Use of uninitialized value $b in concatenation (.) or string at test.pl line 11.

第一行表示$b只被使用到了一次,

第二行可以看到$b順利被印了一次,也就是0這個值,

第三行則是表示$b不見了,uninitialized value表示$b沒有被定義,

而且也會看到清楚指出錯誤在第幾行。


了解區塊以後,我們回到if和else的部分。

有的時候我們希望不只一個判斷的時候,

if ($number == 1) {......} # 當變數等於1時

if ($number == 2) {......} # 當變數等於2時

if ($number == 3) {......} # 當變數等於3時

※注意,因為單等於(=)表示取代,所以做判斷的時候,是用雙等於(==)表示相等

一旦越來越多的判斷,這樣的寫法會因而降低你的程式易讀性,

所以更簡單的方法就是使用elsif,這是else if的合併寫法。

然而,什麼時候會使用到這麼多判斷呢?

不外乎就是用來判斷使用者有沒有亂輸入一些值了,

比方說在填寫表格的時候:

if ($MayDay eq '怪獸') {......} # 字串的判定用eq(equal相等)表示

elsif ($MayDay eq '阿信') {......} # 字串的判定用eq(equal相等)表示

elsif ($MayDay eq '石頭') {......} # 字串的判定用eq(equal相等)表示

elsif ($MayDay eq '瑪莎') {......} # 字串的判定用eq(equal相等)表示

elsif ($MayDay eq '冠佑') {......} # 字串的判定用eq(equal相等)表示

else {print "當然也有$MayDay";} # 以上都沒有符合 就執行這裡


接下來要談談,控制敘述中的重複執行吧!

重複執行讓你的程式,在還沒到達某一個門檻之前,反覆進行同一個運算流程。

舉例來說:假設我希望從1加到10(1+2+3...+10),那麼10就是門檻,而持續做加法就是反覆進行同一個的運算流程。

這裡先介紹兩種迴圈 while 以及 untail

while的用法是,當判斷句為真(true)時,會執行運算;也就表示,

一旦判斷句為假(false)時,會停止運算,結束這個迴圈。

一樣我們來看例子吧,假設我今天要從1加到10(1+2+3...+10):

$number = 1; # 設$number為1

$result = 0; # 設$result為0

while ($number <= 10) # 當$number小於等於10的時候都會執行 (即 當大10時停止運算)

{

$result = $result+$number; # 把$number的值 加上$result以後取代原本(左式)的$result

$number = $number+1; # 把$number的值+1以後 取代原本(左邊)的$number

# 而 $number = $number+1 可以縮寫為 $number++

}

print $result; # 寫在迴圈之後 表示走完迴圈才會印結果

來解釋上面這段程式流程吧!

當第一次進入while判斷句的時候,因為此時$number是1,符合執行條件,就會進入執行運算{}內

右式的$result+$number是 0+1,並且會把結果取代原本的$result,經過此行,$result被替換成1。

下一行,一樣又是$number+1是 1+1,所以經過此行,$number被替換成2。

大括號{}內的計算都完成以後,會跳回while的判斷句檢查,

(記住 是回判斷句 不是回到最上面的程式碼喔!)

因為$number此時為2,判斷句依舊成立,因此會繼續執行。

第二次的迴圈,$result被替換成3,$number被替換成2,繼續回到判斷句。

......

......

因此最後的執行結果$result會是55

untail的用法跟while用法一樣,

差別只在於判斷句,while(條件為真){執行}、untail(條件為假){執行}。


接下來介紹for以及foreach這兩個迴圈,

foreach是專門給陣列用的,在陣列(Array)那篇有介紹過。

在這裡我們就講for迴圈吧!

在perl敘述裡,for的使用上常常被簡化,我們還是從最傳統的方式來說明,

for的使用方法是:for(起始;條件;間隔){執行運算}

小括號裡面可以想像有一個變數正在當計數器使用。

來看看例子吧!

print "庭院";

for ($i=0;$i<3;$i=$i+1) # 而 $i = $i+1 可以縮寫為 $i++

{ # $i會先從0開始 每跑完一次就會累加1

print "深"; # 所以當$i為0、1、2都會執行(3就不符合小於條件)

}

print "幾許\n"; # 迴圈走完以後再print這行

執行結果就會是字串 庭院深深深幾許


接下來是我覺得很初學者很容易卡住的部分 - 雜湊(Hash)

沒有留言:

張貼留言