【轉載】從C到Perl

來源:互聯網
上載者:User
文章目錄
  • 1.變數的類型由它前面的符號確定
  • 2.沒必要提前聲明一個變數
  • 3.沒有類型轉換
  • 4.沒有字元類型
  • 5./不是整除
  • 6.再談數組
  • 8.沒有struct和union
  • 9.沒有懸空的else
  • 10.不一般的do
  • 11.沒有記憶體流失
  • 12.函數參數
  • 13.函數原型
  • 14.沒有main函數
  • 15.不一樣的左值
  • 16.隱含變數/參數
  • 參考資料

    很多人並不是把Perl當做第一門程式設計語言來學習的,在學Perl之前往往已 經掌握了一兩門其它語言。雖然有爭議,但是我個人認為Perl確實不適合作為入門語言。這篇文章就是寫給那些熟悉C而且又想掌握Perl的程式員,介紹一 些技巧以及如何避免C程式員常犯的錯誤,帶你渡過危險的沼澤。在讀這篇文章之前,請先查看perltrap的手冊頁,裡面有很多有用的資訊,這裡不再重 複。歡迎來到Perl的魔法世界!

如果你喜歡C,那你也會愛上Perl。

    C語言的設計者Dennis Ritche說:“C語言詭異離奇,缺陷重重,卻獲得了巨大的成功。 ”這大概是因為C的抽象程度碰巧既滿足了程式員的要求, 又容易實現。鐘愛C的人都樂意寫一些稀奇古怪的C程式,並以此展示自己的才能。Perl在這方面更可謂是“有過之而無不及”。 Perl醜陋而又抽象,完全可以用來寫混亂代碼,但它又靈活實用,而且更接近自然語言,也可以用來寫詩。這本身就很有意思。在C擅長的底層領域,Perl 只能望塵莫及,畢竟它天生不是用來和硬體打交道的。但在文本處理領域,C只好俯首稱臣了,而Perl在這方面非常強大。據說,Perl也得到了很多生物學 家的青睞,在很大程度上協助了人類基因組計劃。謝謝Larry Wall!

給C程式員的提示

    Perl結合了多種程式設計語言的特性,C語言也在其中。Perl和C有以下相同之處:

  • 1.分號是每個簡單語句必需的,換行不能表示語句結束。
  • 2.數組下標也是從0開始,Perl中像substr這樣的字串函數也是從0開始計算位置的。
  • 3.逗號操作符的作用一樣。
  • 4.&&和||操作符作用一樣。 

    然而,Perl和C畢竟是兩種完全不同的程式設計語言,從C轉向Perl有很多值得注意的地方。我們在下面詳細討論。

 

1.變數的類型由它前面的符號確定

    這不是說Perl使用的是匈牙利標記法,而是Perl的特性。在Perl中,$說明變數是一個 scalar,@表明變數是一個array,而%說明後面的變數是一個hash。比如:@foo是一個數組,而$foo[0]是數組@foo中第一個元 素,@foo[0]是一個數組片段,當然也是數組,但這個片段只有一個元素$foo[0]。如果你陣列變數把賦給一個標量,比如:$bar=@foo;, 你將得到的是該數組中元素的個數。

2.沒必要提前聲明一個變數

    在C中你每引入一個變數,都要在前面聲明它的類型。在Perl中完全沒有必要,你可以在任何時候任意引 入新的變數。不過,問題就出來了,你可得當心。如果你不小心敲錯一個字母,Perl會把它當成你新引入的變數,並且自動初始化,有時不會給出任何錯誤提 示,而這顯然與你的最初目的不符!所以,最後在每個Perl程式的前面都加上use strict;,確保perl能對代碼進行更嚴格的檢查,就像你使用lint檢查C程式那樣。

3.沒有類型轉換

    Perl中的標量類型範圍很廣,可以是整數,可以是字串,也可以是浮點數。你可以很安全地把一個整數 默默地轉化成相應的字串。Perl解譯器能夠理解你的意思,不用擔心。但是,這並不是說任何時候你都可以高枕無憂,把字串“轉化”成整數時,你確實得 下一番功夫。我們在下面將會討論這個問題。

4.沒有字元類型

    Perl中沒有char這種類型。

$ch='c';

    上面的語句其實是給標量$ch賦了一個字串值,因為Perl中單引號也能括起字串(對比單引號和雙引號的不同留做練習)。正因如此,才使得把字串轉化成整數或者浮點數變得稍微麻煩了些。我們可以這樣這樣處理字元:

@array = split(//, $string);      # each element a single character@array = unpack("C*", $string);   # each element a code point (number)

    當然也可以使用Regex。Perl中也有類似atoi()的函數,叫作POSIX::strtod,在POSIX模組中,使用前應該先包含它。

 

5./不是整除

    由於Perl中沒有整數和浮點數類型的區分,所以當你想按照C的意思用/操作符表示整除時,它並非你想要的。實際上/在Perl中是浮點除法,下面的程式是危險的:

while($a/=2){push @tmp, $a % 2;}

    它會把$a精確地除到小得Perl無法表示它!如果你想表示整除,請將整個運算式放入int函數中。

 

6.再談數組

    當心:在Perl中只有hash是使用{}初始化的,普通數組array是使用 ()進行初始化的!使用{}給普通數組賦值解譯器會報錯。而且,Perl中的數組是可以任意伸縮的,不存在數組越界問題。不像C,Perl允許有匿名數組/散列/子函數,比如使用匿名數組交換兩個變數的值:

($var1, $var2) = ($var2, $var1);

    Perl數組脫離了底層特性,而且更加靈活方便。

 

7.沒有switch

    這實在是讓C程式員們吃驚,Perl居然沒有switch。的確,Perl並不需要switch ,因為switch完全可以用if/elsif/else(注意:是elsif而不是else if)或者?:來代替。Perl中的switch可以這樣來寫:

SWITCH: {if ($value == 1) { print "One" };if ($value == 2) { print "Two" };if ($value == 3) { print "Three" };if ($value > 3) { print "Unknown" };}#Or like this:SWITCH: {$value == 1 and print "One", last;$value == 2 and print "Two", last;$value == 3 and print "Three", last;print "Unknown";        #default}

    當然你也可以使用goto,畢竟TMTOWTDI(There's More Than One
Way To Do It.)。

  • //這裡有問題,因為7在5.8中實現,而且很強大.是用模組來實現的 

 

8.沒有struct和union

    如果你決定使用Perl編程,那麼你可以完全繞開struct這類東西。union 是更為底層的東西,更不應該出現在Perl中。如果你想用struct實現資料結構,比如單鏈表,那麼在Perl 中你可以選擇hash和reference。其實hash可以實現很多資料結構,更詳細的內容見《Mastering Algorithms with Perl》一書。如果你想用struct實現class,那麼你可以使用Perl中的object。最後,如果你說:“我不用struct完成不了這個程式”,那你怎麼不考慮用C而用Perl呢?

9.沒有懸空的else

    Perl中的條件和迴圈語句塊都需要用{}括起來,因此也就不存在懸空的else問題。記住:塊(block)本身就相當於一個只執行一次的迴圈,因此last對block也起作用。有點例外的情況是當條件判斷出現在一條語句的最後時,前面沒必要加花括弧。比如:

if $test print "yes";    #This one is WRONG!{print "yse"} if $test;  #WRONG again!print "yes" if $test;    #This one is right.

 

10.不一般的do

    do在Perl中被賦予三種不同的含義。當它後面是一個block時,它會把後面塊中的語句都執行一 遍,並且返回最後一個運算式的值;如果它和while或者until連用,Perl會通過測試條件來決定執行塊中的語句,但是,塊中的語句不會被計算在循 環之中。所以,使用last/next/redo來控制塊是沒用的。當它後面是一個檔案名稱時,它的作用是把名為此的檔案包含進來。當它後面是一個子函數 時,它是對後面子函數的調用,但這是一種不推薦使用的方式。

11.沒有記憶體流失

    你再也不用擔心free和malloc函數造成記憶體流失了,因為在Perl中沒有那種函數,也沒有指 針,你幾乎不用關心記憶體配置問題。Perl中類似指標的reference,沒有底層的那些特性。實際上,在Perl中造成記憶體流失是很罕見的。你再也不 用害怕字串空間不夠用,字串是否以'\0'結尾這種問題了,Perl中的字串像 C++中的String類一樣方便,就是沒有C++重載運算子帶來的串連和比較字串的實惠(Perl也可以重載運算子,在這裡不討論)。

12.函數參數

    Perl被設計成與自然語言很接近的電腦語言,這也就無怪乎用Perl也能寫出詩來了。函數參數不必都用圓括弧括起來。雖然加上圓括弧也沒什麼影響,但是你得知道,不加括弧可以讓你的程式更易讀,更優雅。試比較下面的語句: 

open (YOUREYES, $wide) or die ("$!");
open YOUREYES, $wide or die $!;

    這是Perl,放輕鬆點兒。更進一步,如果你不想轉遞給函數任何參數,不用帶多餘的圓括弧;但是如果你也想同樣處理你自己寫的子函數,你必須在使用之前就定義或者聲明那個函數。

    此外,Perl很好地支援可變參數,而且Perl傳遞函數參數實際上是引用傳遞,而不是像C那樣採用值傳遞!換句話說,你對@_中的元素進行修改,那麼相應的實參也會變化。Perl採用這種方法可以很容易地返回所需要的值。

13.函數原型

     Perl中的函數原型是調用環境中的自動模板,而不像C中的那樣。而且函數原型隻影響那些不帶&方式調用的函數。你必須十分注意函數原型是否將你 的子函數帶入了一個新的環境。因此,“最好在新函數中使用函數原型,但別在舊函數中使用函數原型。”如果你不小心,你可能因函數原型遇到很多麻煩。但如果 你非常謹慎,你可以用函數原型出色地完成任務。

14.沒有main函數

    C家族的語言都必須有一個main函數,而Perl不在其中。和Basic類似,Perl也沒有 main函數,自頂向下解釋執行。Perl中命令列介面的參數是通過@ARGV數組傳遞的,而且沒有$ARGC變數,因為把@ARGV賦給一個標量就能得 到參數個數。不過,Perl中的$ARGV[0]相當於C的argv[1],相當於argv[0] 的變數是$0。C中環境變數是通過main的參數char** env傳遞的,而Perl通過%ENV散列。

15.不一樣的左值

    Perl中所有可能是左值的東西都可以作為左值。比如,如果?:操作符的兩部分運算式都是左值,那麼整 個運算式也可以是左值。函數也可以是左值,若substr函數的第一個參數運算後是可修改的,它也可以用作左值。你也可以把自己的子函數定義成可以作為左 值使用的,是的,Perl允許你這麼做。就像這樣:

my $val;sub canuse : lvalue {        $val;        }canuse() = 9;

    它可以很安全地把右值賦給$var。

 

16.隱含變數/參數

    Perl的一大特點就是它有很多預定義好的變數,它們都有各自專門的用途,這和C大不相同。你必須熟悉 它們才能駕馭它們。$_可能是最常用的隱含變數了,它是輸入和模式比對中預設的變數/參數;@_是用於傳遞子函數參數的列表;$!儲存著最近一次系統調用 的錯誤資訊(相當於C中的errno)…… 還有很多其它。隱含變數雖然看起來有點古怪,但當你熟悉它後,它能給你節省很多時間,增加程式的可讀性。

    當然,Perl的魔力和魅力遠不止如此。Perl有著自己獨特的風格,散發著自己的光芒。你應該用心去尋找Perl中的pearl!願你也能用Perl創造更多的奇蹟,更多的藝術!

參考資料

1.《Programming Perl, Third Edition》

2.《Professional Perl Programming》

3.《Perl Debugged》

4.《The C programming Language, Second Edition》

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.