- Tạo mảng liên kết
%<tên_mảng> = (<chỉ_số>, <giá_trị>, <chỉ_số>, <giá_trị>, ...); hoặc dễ đọc hơn
%<tên_mảng> = (<chỉ_số>, => <giá_trị>, <chỉ_số>, =><giá_trị>, ...); Ví dụ:
%mt = (“Pen4”, 3, “Pen3”, 2, “Celeron”, 5);
Ví dụ:
@mt = (“Pen4”, 3, “Pen3”, 2, “Celeron”, 5);
%mt = @mt; # Vẫn tạo ra mảng như trên.
@mt2 = %mt; # Tạo ra @mt2 giống @mt
Tạo mới mảng liên kết bằng cách truy cập tới mảng bằng chỉ số mới và gán cho nó giá trị : $mt{“Pen2”} = 10;
- Xoá một phần tử của mảng dùng hàm delete: delete($mt{“Celeron”});
- Việc truy nhập tới một phần tử của mảng liên kết có thể thông qua một chỉ số là một giá trị vô hướng bất kì Cú pháp $<tên_mảng> {<chỉ_số>} Ví dụ: $manglk{“abc”} = 1; $manglk{$cs} = “xyz”; 3.3 Một số hàm trên Hash: 3.3.1.Hàm key
key(%manglk) cho ta danh sách các chỉ số của mảng liên kết. Ví dụ muốn in tất cả các phẩn tử của mảng liên kết %manglk :
foreach $ptu (keys(%manglk)) { print ("$ptu: $manglk{$ptu}\n"); }
vì hàm key trả lại danh sách, cho nên ta có thể dùng hàm sort để sắp xếp các chỉ số của mảng.
sort (keys(%manglk))
3.3.2.Hàm value
Hàm này trả lại giá trị là danh sách các giá trị của mảng liên kết @giatri = value(%manglk)
3.3.3. Hàm each
each(%manglk) trả lại gía trị là một cặp giá trị vô hướng gồm chỉ số của một phần tử bất kì (Perl lưu giữ phần tử của mảng liên kết không theo thứ tự nào) và giá trị tương ứng của nó. Hàm này thường được dùng cho vòng lặp
while (($cs, $gt) = each(%manglk)) { # Xử lí ở đây
}
3.3.4. Hàm exits
Kiểm tra xem có tồn tại phần tử trong danh sách liên kết
exits(@manglk{$key})
trả lại giá trị khác 0 nếu tìm thấy phần tử có khoá $key trong danh sách, bằng 0 nếu không tìm thấy.
3.4. Danh sách liên kết
3.4.1. Khái niệm:
Một danh sách liên kết là một cấu trúc dữ liệu đơn giản, trong đó các phần tử được nối với nhau bởi vùng kiên kết của chúng. Mỗi phần tử của danh sách liên kết gồm hai trường :
Giá trị của phần tử
Địa chỉ, hay con trỏ trỏ đến phần tử tiếp theo
Ngoài ra còn có biến địa chỉ đặc biệt để trỏ đến phần tử đầu tiên của danh sách
Trong Perl danh sách liên kết dễ dàng được tạo ra bằng cách sử dụng mảng liên kết, giá trị của phần tử này sẽ là chỉ số cho phần tử tiếp theo:
%tus = ("alpha", "beta", "beta", "gamma", "gamma", "delta", "delta", ""); $header = "alpha";
3.4.2. Các thao tác đối với danh sách liên kết:
Giả sử cần tạo ra danh sách liên kết chứa các từ, ta thực hiện các bước như sau a. Tạo danh sách rỗng
$header = “”;
b. Thêm một phần tử vào danh sách
- Nếu danh sách rỗng, thêm vào phần tử đầu tiên
if ($header eq"") { $header = $tu $dstu{$tu} = "";
- Nếu phải thêm vào đầu danh sách $dstu{$tu} = $header;
$header = $tu;
- Các trường hợp còn lại thêm vào sau phần tử trỏ bởi chỉ số $pointer
$dstu{$tu} = $dstu{$pointer}; $dstu{$pointer} = $tu;
c. Xoá một phần tử khỏi danh sách Giả sử cần xoá từ $tu trong danh sách $pointer = $header;
while ($dstu{$pointer} ne"" && $dstu{$pointer} ne $tu) { $pointer = $dstu{$pointer}; }
$dstu{pointer} = $dstu{$tu};
3.5.Kiểu dữ liệu có cấu trúc
3.5.1. Khái niệm
Kiểu dữ liệu có cấu trúc là một kiểu dữ liệu gồm tập hợp các phần tử dữ liệu có kiểu khác nhau nhưng có liên kết với nhau.
3.5.2. Dữ liệu có cấu trúc trong Perl
Trong Perl kiểu dữ liệu này không được định nghĩa một cách tường minh, mà ta phải dùng mảng liên kết để mô phỏng nó
Ví dụ:
C Perl
struct hocsinh { %hs = (“ten”,””. char ten[20] “tuoi”,””); int tuoi
CHƯƠNG IV: CHƯƠNG TRÌNH CON
1. Khái niệm:
- Trong Perl chương trình con là một đoạn chương trình nhằm thực hiện một công việc nào đó và được thực thi bằng cách gọi chương trình con đó ra.
- Mục đích sử dụng chương trình con:
+ Chia nhỏ chương trình thành những phần nhỏ hơn, làm cho nó dễ đọc và dễ hiểu hơn.
+ Giúp ta tránh phải viết lại nhiều lần những đoạn chương trình thực hiện một công việc giống nhau. - Một chươngtrình con có thể gọi một chương trình con khác, và chương trình cobn khác này đến lượt nó lại có thể gọi chương trình con khác nữa, và cứ như thế, cho tới khi tất cả bộ nhớ có sẵn đã bị chất đầy bằng địa chỉ quay vể và các biểu thức được tính toán hết
- Định nghĩa chương trình con :
sub <tên> { <các câu lệnh> }
Khối các câu lệnh đi sau tên chương trình con trở thành định nghĩa CT con. Khi Ct con được gọi tới thì khối các câu lệnh tạo nên CT con này sẽ được thực hiện, và bất kỳ giá trị trả về nào (được mô tả sau đây) đều được trả về cho nơi gọi
Chẳng hạn sau đây là một Ct con:
<tên> : Được định nghĩa như phần tên giới thiệu trong chương 1, gồm các chữ cái, chữ số và dấu gạch dưới.
<các câu lệnh> : có thể có một hay nhiều câu lệnh.
- Chương trình con trong Perl có thể được đặt ở bất kì đâu trong chương trình chính. Tuy nhiên, sẽ là tốt nhất nếu đặt chương trình con ở đầu hoặc cuối chương trình chính. Điều này làm cho chương trình dễ đọc hơn.
- Trong Perl chỉ có một loại chương trình con duy nhất là hàm, song đoi khi tuỳ theo cách sử dụng mà ta được một CT con tương đương như là một thủ tục, tức là có thể gọi nó ra mà không cần gán.
2.Cách gọi hàm:
- Bạn gọi một CT con từ bên trong bất kỳ biểu thức nào bằng việc ghi ra tên của CT con và theo sau là danh sách các tham số được đặt trong hai dấu (), nếu không có tham số thì ta dùng ();
<tên> ( <danh sách các tham số> )
- Đôi khi gọi hàm bằng cách này gây ra lỗi, chương trình không hiểu , ta còn có cách gọi khác như sau luôn đúng :
&<tên> ( <danh sách các tham số> ) hay
do <tên> ( < danh sách các tham số> ) Ví dụ:
3. Trả lại giá trị cho hàm
- Là hàm thì phải có giá trị. Trong Perl giá trị của hàm được tình bằng giá trị của biểu thức cuối cùng trong hàm.
Hàm cho_gia_tri sẽ có giá trị bằng giá trị của $x là 123. Như vậy chỉ cần viết ra biến hay giá trị cuối cùng trong hàm ta nhận được giá trị trả lại cho hàm chính là biến hay giá trị đó. Tuy nhiên làm như vậy sẽ làm cho chương trình rất khó đọc.
Nên sử dụng biến mảng retval để gán giá trị trả lại cho hàm $retval = $x;
@retval = @mang;
Tuy nhiên biểu thức cuối cùng ở đây là biểu thức được tính trong hàm chứ không phải là biểu thức cuối cùng xác đinh trong thân hàm.
Cũng có thể trả lại giá trị cho hàm bằng cách dùng câu lệnh
Câu lệnh return này hành động giống hệt như trong C : trả lại giá trị cho hàm và kết thúc hàm chuyển về chỗ đã gọi nó.
4. Biến cục bộ trong hàm:
- Biến cục bộ là biến được khai báo trong hàm và chỉ tồn tại trong thời gian hàm đó hoạt động. Khi ra khỏi hàm biến đó mất đi, khi gọi hàm một lần nữa biến cục bộ lạ được định nghĩa lại.
- Biến cục bộ được khai báo như sau : my <biến>;
local <biến> ;
Khai báo bằng từ khoá my làm cho biến đó chỉ tồn tại trong hàm đó. Ra khỏi ngoài hàm đó thì biến đó không còn tồn tại.
Khai báo bằng từ khoá local sẽ làm cho biến đó tồn tại trong hàm đó và cả trong những hàm được nó gọi. Nhưng sẽ không tồn tại trong chương trình chính.
Cũng như cách khai báo biến toàn cục, biến cục bộ có thể được gán giá trị trong khi khai báo
5. Truyền tham số cho hàm
- Trong Perl khi lời gọi hàm có một danh sách các tham số, các tham số đó sẽ tự động gán cho một danh sách với tên @_. Chương trình con xác định giá trị các tham số bằng cách truy cập vào danh sách các biến này.
Ví dụ:
Trong trường hợp này khi gọi hàm tổng biến $a được gán cho $_[0], biến $b được gán cho $_[1] và hàm tính tổng $a + $b.
Truyền cả một danh sách cho hàm : Xét ví dụ sau :
Với hàm này khi gọi, ta có thể truyền cho nó một mảng, một danh sách, hay một tập hợp danh sách hay tập hợp biến.
&addlist (@mang); &addlist ("1", "2", "3"); &addlist ($a, @mb, $c);
Và khi khai báo biến cục bộ ta cũng có thể làm: my (@list) = @_;
my (@list1, @list2) = @_; my ($a, @mb, $c) = @)_;
Trong trường hợp thứ 3, $_[0] được gán cho biến $a, các phần tử tiếp theo của @_ là phần tử của mảng @mb, tiếp theo phần tử cuối được gán cho $c. Tuy nhiên trong một số trường hợp có thể $c = null, các phần tử còn lại của @_ được gán cho các phần tử của mảng @mb.
Truyền tham số bằng cách dùng bí danh(Passing Arrays by Name Using Aliases Không biêt dich có đúng không)
Như đã thấy, Perl cho phép truyền cả một mảng như là một tham số. Khi hàm được gọi, tất cả các giá trị của mảng tham số sẽ được truyền cho mảng @_ được định nghĩa trong hàm.
Nếu mảng được truyền quá lớn, sẽ mất nhiều thiều thời gian và bộ nhớ. Để làm cho chương trình có hiệu quả hơn, Perl cho phép truyền mảng tham số qua tên bằng cách thay @ bởi * trong lúc định nghĩa mảng trong hàm và trong lời gọi hàm.
Khi hàm được thực hiện, nó sẽ dùng chính mảng thực truyền cho hàm để thao tác thay vì tạo ra một bản sao của nó. Lời gọi hàm với *mang thay vì @mang chỉ cho ta biết mảng thực @mang được sử dụng (và có thể được thay đổi nếu cần) trong hàm. Tức là khi hàm được thực hiện mảng @mang_con
chính là mảng @mang, hay tên mảng @mang_con được đồng nhất với tên mảng @mang. Hay nói cách khác khi hàm được thực hiện @mang con có bí danh là @mang, và khi hàm kết thúc
@mang_con không còn có bí danh @mang. Khi hàm được gọi lại với tham số khác, @mang_con lại có một bí danh mới.
Có thể nói đây là cách truyền tham bién trong Perl, bởi vì tất cả các sự thay đổi tham số trong hàm đều dẫn tới sự thay đổi trong chương trình chính.
Chú ý :
- Nếu có một biến và một mảng cùng tên thì cả biến và mảng đều có hiệu lực trong lời gọi hàm. Ví dụ:
- Ta cũng có thể truyền nhiều biến, mảng hay danh sách theo cách này
6. Hàm đệ qui
- Hàm đệ qui là hàm được định nghĩa qua chính nó và được xuất phát từ trường hợp cơ sở. Ví dụ:
7. Chỉ định thứ tự sắp xếp
- Ta có hàm sort trong Perl sẽ sắp xếp các phần tử theo thứ tự abc. @list1 = ("Trang", "An", "Nam");
@list2 = sort (@list1);
cho ta @list2 = ("An", "Nam", "Trang")
- Để sắp xếp cần phải so sánh từng đôi cặp phần tử một. Perl làm điều này bằng cách gọi một hàm đăc biệt được xây dựng sẵn tương tự như hàm sau :
- Perl cũng cho phép bạn tự định nghĩa hàm sort_criteria (tiêu chuẩn sắp xếp) để sắp xếp một danh sách theo ý muốn của mình. Hàm này cần phải có câu trúc tương tự như trên, phải dùng hai biến toàn cục $a và $b và phải có một trong các giá trị trả về sau :
-1 Nếu biến $a được đứng trước biến $b trong danh sách sắp xếp 0 Nếu biến $a ngang hàng với biến $b trong danh sách sắp xếp 1 Nếu biến $a đứng sau biến $b trong danh sách sắp xếp
Lưu ý : Mặc dù các biến $a, $b là các biến toàn cục, nhưng nó không hề gây ảnh hưởng tới các biến toàn cục $a, $b (nếu có) ở trong chương trình chính. Các biến này trong chương trình chính sẽ được lưu giữ lại khi thực hiện sắp xếp và được trả lại khi sắp xếp xong.
Sau khi định nghĩa tiêu chuẩn sắp xếp ta gọi hàm sort để sắp xếp theo ý muốn. sort <hàm tiêu chuẩn sắp xếp> (@list)
Kết quả chương trình: ba nam
bon nam 35 45
8. Một số hàm đặc biệt trong Perl8.1. Hàm BEGIN 8.1. Hàm BEGIN
- Hàm này sẽ được gọi khi chương trình bắt đầu chạy. BEGIN {
print “Chuong trinh ...\n”; }
Tất nhiên cũng như mọi hàm khác, hàm này có thể có biến cục bộ hoặc có thể gọi hàm khác trong chương trình.
8.2. Hàm END
- Hàm này được gọi khi chương trình kết thúc. END {
print “Ket thuc chuong trinh!”; }
8.3. Hàm AUTOLOAD
- Hàm AUTOLOAD rất có ích khi ta lập trình chia theo nhiều modul, nó sẽ kiểm tra sự tồn tại của một hàm nào đó được viết trong file khác khi hàm đó được gọi.
8.4. Các hàm toán học : sin, cos, atan2, sqrt, exp, log, abs
8.5. Hàm tạo số ngẫu nhiên : rand, srand
hex(hexnum) chuyển đổi số hexnum ở hệ 16 sang hệ 10. $he10 = hex(ff); # $he10 nhận giá trị 255
oct(octnum) chuyển đổi số octnum ở hệ 8 sang hệ 10. $he10 = oct(17); # $he10 nhận giá trị 15
int(floatnum) chuyển đổi số thực floatnum ra số nguyên. $nguyen = int(37.6); # $nguyen nhận giá trị 37
$nguyen = int(37.6 + 0.5); # $nguyen nhận giá trị 38
ord (char) cho giá trị là số thứ tự của kí tự char trong bảng mã ASCII char (num) cho giá trị là kí tự có số thứ tự là num trong bảng mã ASCII
CHƯƠNG V: TỆP (FILE)
1. Khái niệm về tệp :
Tệp tin hay tệp dữ liệu là một tập hợp các dữ liệu có liên quan với nhau và có cùng một kiểu được nhóm lại với nhau thành một dãy. Chúng thường được chứa trong một thiết bị nhớ ngoài của máy tính (đĩa mềm, đĩa cứng...) dưới một cái tên nào đó. Do đó tệp tồn tại ngay cả khi chương trình kết thúc hay mất điện.
Sau đây chúng ta sẽ tìm hiểu các thao tác trên tệp trong Perl :
Cú pháp open (filevar, filename);
filevar : là biến tệp dùng để thay thế cho tệp trong chương trình Perl.
filename : là tên có đường dẫn đầy đủ của tệp.
Biến filevar được đặt tên theo khái niệm về tên đã giới thiệu trong chương 1. Biến này không có kí tự đặc biệt ở đầu nên có thể lẫn lộn với tên biến hay một số từ dành riêng khác. Vì thế ta nên dùng chữ hoa để đặt tên biến tệp .
open (DULIEU, “c:\perl\eg\readme.txt”);
filename được Perl hiểu là một xâu nháy kép chỉ rõ vị trí của tệp. Vì thế ta có thể làm như sau : $ten_tep = “c:\bootlog.txt”;
open (DULIEU, $ten_tep);
Chế độ mở tệp : có 3 chế độ mở
Mở đọc : đây là chế độ ngầm định của Perl.
Mở ghi : chế độ này sẽ mở tệp, xoá nội dung của tệp và bắt đầu ghi mới. Cách mở : thêm kí tự > vào trước filename
open (DULIEU, “>c:\perl\eg\readme.txt”);
Mở ghi thêm vào : có thể thêm dữ liệu vào tệp mở mà không xoá nội dung của tệp. Cách mở : thêm >> vào trước filename
open (DULIEU, “>>c:\perl\eg\readme.txt”);
Mở vừa đọc, vừa ghi : khác với chế độ ghi thêm vào, chế độ này cho phép ghi đè lên dữ liệu đã có, lại còn cho phép đọc tệp.
open (DULIEU, “+>c:\perl\eg\readme.txt”); Cách mở : thêm +> vào trước filename
Kiểm tra quá trình mở : Hàm open sẽ trả lại giá trị 1/0 nếu quá trình mở tệp thành công hay không thành công. Vì thế ta có thể dùng lệnh if hay unless để thao tác :
if (open(MYFILE, "vanban.inp")) {
# xử lí tiếp nếu quá trình mở file thành công }
Perl còn cung cấp cho ta hàm die để hiển thị thông báo lỗi trong quá trình mở tệp với cú pháp như sau :
die (<thông báo> );
Ví dụ
unless (open(TEPVB, "dulieu.inp")) {
die (“khong mo duoc file ...\n”); }
hoặc gọn hơn
Nếu muốn có chính xác dòng gây ra lỗi ta bỏ kí tự \n trong dòng thông báo.
die (“Khong mo duoc file ... vi loi o dong”);
Mở tệp nhị phân : Phải khai báo sử dụng tệp ở chế độ nhị phân bằng cách dùng hàm binmode :
binmode (filevar)
hàm này phải được gọi sau khi mở tệp và trước khi đọc, ghi tệp.
2.2 Đọc tệp
Đọc một dòng
Để đọc một dòng từ tệp đã được mở ta dùng lệnh có cú pháp như sau :