- Perl語言IC設計實踐
- 滕家海編著
- 2718字
- 2022-02-08 17:37:59
1.2 初識命令行參數
Perl語言和大部分編程語言一樣,有變量、控制結構、函數和模塊。我們將在下面介紹這些基礎內容。
大部分有意義的程序都需要先與外部交換數據—取得輸入,再經過一番運算以后,反饋相應的輸出。程序與外界最常見的接口就是命令行參數。
下面各節內容將從無到有,逐步完善一個處理命令行參數的程序。
最常見的Perl程序的運行方式是參數在命令行(command line,也就是terminal)中執行,類似ls -a /home。我們約定:ls稱為命令或者程序,-a和/home都稱為參數(argument),同時-a也可稱為選項(option),/home也可稱為參數值(parameter)。
我們先看一個簡短的Perl程序,它會輸出所有的輸入參數(每行一個)。圍繞這個程序,我們將一起學習基本的數據類型(標量和數組)和控制結構(for)等內容。行首的數字不是程序的內容,而是行號,以方便后文指定說明。
代碼1-1 ch01/read_argument_v1.pl
1 #!/usr/local/bin/perl 2 3 print "Command is: $0\n"; 4 5 for my $arg ( @ARGV ) { 6 print $arg, "\n"; 7 } 8 9 exit 0;
運行該程序:
./read_argument_v1.pl -a first -b second
程序將輸出:
Command is: ./read_argument_v1.pl -a first -b second
如果你運行此程序時沒有得到預期的輸出,請參照1.1節檢查Perl環境。
第1行,該行代碼將我們的Perl位置告訴shell,你的Perl位置可能與我的不同,請運行which perl確認其路徑。有了這一行代碼后,就可以直接運行可執行文件(read_argument_v1.pl)。如果沒有這一行代碼,則只能以如下方式運行程序:
perl read_argument_v1.pl
第2、4、8行,是空行。只是為了代碼更美觀,不影響代碼的功能。
第3行,print是一個函數,它把后面的內容,都依次輸出到命令行(窗口的標準輸出)中。$0(美元符號后面緊跟一個數字零)是Perl內建的一個變量,它的值是被執行的程序本身,一般是第一個字符串(即./read_argument_v1.pl)。
如果我們按如下代碼執行:
perl read_argument_v1.pl
那么$0是:
read_argument_v1.pl
本行末尾的"\n"是一個換行符。
第5~7行,是一個循環(for)結構,循環遍歷數組@ARGV的內容。每次循環,按照次序把@ARGV的某個值,賦值到$arg。然后print函數把$arg輸出到命令行,并緊跟一個換行符。@ARGV是Perl內建的一個數組,它包含命令行的全部輸入參數(包括選項和參數值,不包括$0)。my是一個聲明變量的函數,我們在for循環中,常常需要一個臨時變量來存儲每次循環獲取的變量值,我們通常會在for語句中夾帶一個my聲明,這樣的好處是:使得$arg的作用域僅限于此for循環結構,在此for結構之外,$arg是未定義的。這是一個在軟件工程領域被證明過的、有效的代碼實踐—避免使用全局變量,盡量縮小變量的作用范圍。
第9行,exit 0,表示整個程序的結尾、邏輯上的結尾。在它之后還可以編寫其他代碼,比如子例程等,我們之后就會介紹這些內容。我們一般以0(零)表示整個程序正常結束,其他非零值表示異常結束。exit的返回值對該程序本身的意義不大,其返回值主要用于調用該程序的其他程序。
下面我們詳細介紹上例中出現的print、標量、數組,以及控制結構for。
Perl語句是以分號(;)作為結束標志的。大部分情形,語句都可以在合適的位置插入空格或替換行。所以代碼1-1中的第6行也可以如下斷開:
print $arg, "\n";
該語句功能保持不變。
print是最常用的函數之一。如果第一個參數不是文件句柄或者其他句柄,那么它會使用默認的句柄—標準輸出(STDOUT),并把其余參數的內容都輸出到相應的句柄上。
注釋以#(井號)開始。注釋既可以是獨立的行,也可以在句末分號的后面。
1.2.1 標量
Perl有且只有3種變量類型:標量(saclar)、數組(array)和散列(hash)。
雖然Perl不強制聲明變量,但是在使用變量之前聲明它是很好的編程習慣,會提升代碼的質量。Perl使用my來聲明變量。每次可以聲明一個或多個變量,也可以在聲明的同時為變量賦值。
標量,就是存儲單一值的變量。存儲的內容可以是數字、字符串、引用、文件句柄等。引用和文件句柄分別在1.5.1節和2.2節中介紹。標量是不分類型的,同一個標量可以先存儲一個整數,然后再用一個有理數覆蓋,最后再用一個字符串覆蓋。Perl不會混淆它們,倒是我們自己很可能混淆,所以一般我們使用不同的標量存儲不同類型的內容。
標量的名稱,必須以$(美元符號)開始,后面緊跟一個字母或者下劃線,再后面可以繼續跟多個字母、數字或下劃線。變量的名稱是區分大小寫的,所以$abc與$aBc是兩個不同的標量。Perl的一些內建變量由全大寫字母組成,所以我們最好避免創建全大寫字母的變量名。
標量的賦值,使用=(等號),左側是標量名,右側是被賦予的值。my是聲明變量的命令,它的更多含義可參見9.2.9節。
my $num1 = 10; # 10 my $num2 = $num1 * 10; # 100 my ($num3, $num4, $num5) = (1, $num2 + 1, 3); $num1 = $num2 = $num3 = 0;
my既可以每次賦值一個標量,也可以賦值多個標量,還可以連續賦值。
如果標量的值是字符串,最常見的賦值方式是使用雙引號或者單引號來包圍字符串。使用雙引號和單引號的區別是,雙引號內如果含有變量,則此變量的值會被插值(interpolate),即變量名會被其內容替換,單引號內的變量則不會被插值。
my $str1 = 'ABC'; # ABC my $str2 = '$str1 xyz'; # $str1 xyz my $str3 = "$str1 xyz"; # ABC xyz
單引號包圍的字符串中,除了兩個特殊字符'(單引號)和\(反斜杠),其余字符都會保持它本來的樣子:
my $str4 = '~`!@#$%^&*()[]<>{}?...'; #### $str4 is: ~`!@#$%^&*()[]<>{}?...
如果需要表示單引號或反斜杠自身,則需要在它們之前添加一個反斜杠:
my $str5 = 'here is \' and \\'; # here is ' and \
字符串拼接,使用.(英文的句點):
my $str6 = $str1 . "_" . "xyz"; # ABC_xyz
點號“.”是操作符,操作符周圍緊挨著的空格都會被忽略。
1.2.2 數組
數組就是標量的有序集合,數組的下標(即序號)從0(零)開始。
數組的名稱,必須以@符號開始,后面緊跟一個字母或者下劃線,后面可以繼續跟多個字母、數字或下劃線。
數組可以這樣初始化:
my @nums = ( 1, 4, 9, 16 ); my @vars1 = ( "ZheJiang", "JiangXi", "XiZang" ); my @vars2 = ( "HangZhou", "NanChang", "LaSa" );
獲取下標的操作符是中括號[]。數組中的某個標量,經常被稱為元素(element)。可以如下所示,為元素賦值:
$nums[0] = 0; # now @nums is: (0, 4, 9, 16) $nums[4] = 17; # now @nums is: (0, 4, 9, 16, 17) $vars1[1] = "JIANGXI"; # now @vars1 is: ( "ZheJiang", "JIANGXI", "XiZang" )
由于數組就是標量的有序集合,因此Perl程序中任何位置的標量,都可以替換成數組中的某個元素。$vars[n]可以放在標量(如$str)可放置的任意位置。
數組的大小,即所含元素的數量,是可變的。不必像在某些語言中,需要預先定義大小。
$#后面緊跟數組名,表示該數組的最后一個元素的下標。
print 'last index of @vars is: ', $#vars1, "\n";
輸出:
last index of @vars is: 2
scalar函數,會返回數組的大小,即所含元素的數量:
$numofvars = scalar @vars; print '@vars has ', $numofvars, " element\n";
輸出:
@vars has 3 element
1.2.3 循環結構for
循環結構for常用來循環遍歷數組。
for my $var ( @someArray ) { sentences … }
一般會在for后面使用my聲明一個局部標量,這個局部標量$var僅在該for循環結構中有效,在該for外部,它是未定義的。循環結構每次從數組中按照次序取出一個值,并賦值給$var,然后執行循環體內的語句。直到遍歷完整個數組。
如果想中途退出循環體,我們可以使用last命令。
for my $var ( @someArray ) { if ( condition1 ) { last; } Other sentences … }
如果有嵌套的循環,last;一般只會跳出最內層的循環。如果需要跳出外層的循環,可以使用標記(label)。
LOOP_1: for my $var1 ( @someArray1 ) { for my $var2 ( @someArray2 ) { if ( condition1 ) { last LOOP_1; ## 跳出 for my $var1的循環 } Other sentences … } }
如果想略過循環體的后續的語句,跳到下一次循環,可以使用next命令。
for my $var ( @someArray ) { if ( condition2 ) { next; } Other sentences … }
- Mastering Ext JS(Second Edition)
- Mastering Entity Framework Core 2.0
- Learning Cython Programming
- JavaScript+DHTML語法與范例詳解詞典
- Learning Chef
- 深入理解Django:框架內幕與實現原理
- Visual C++數字圖像處理技術詳解
- 區塊鏈技術進階與實戰(第2版)
- Regression Analysis with Python
- MINECRAFT編程:使用Python語言玩轉我的世界
- Building Dynamics CRM 2015 Dashboards with Power BI
- Exploring SE for Android
- Python Deep Learning
- RESTful Web API Design with Node.js(Second Edition)
- H5匠人手冊:霸屏H5實戰解密