Learning Perl - Chương 4: Cấu trúc điều khiển
1. Khối câu lệnh
2. Câu lệnh if/else
3. Câu lệnh while/until
4. Câu lệnh do {} while/until
5. Câu lệnh for
6. Câu lệnh foreach
7. Bài tập
4.1 Khối câu lệnh
Khối câu lệnh là một dãy các câu lệnh, được bao trong cặp dấu ngoặc nhọn ({ và }). Nó trông
tựa như thế này:
{
cau lenh thu nhat;
cau lenh thu hai;
cau lenh thu ba;
...
cau lenh cuoi;
}
Perl thực hiện từng câu lệnh theo trình tự, từ đầu đến cuối. Về mặt cú pháp, một khối các câu
lệnh được chấp nhận ở mọi vị trí của một câu lệnh.
4.2 Câu lệnh if/unless
Độ phức tạp tiếp theo trong các câu lệnh là câu lệnh if. Kết cấu này trông rất giống kết cấu
trong C: một biểu thức điều khiển (được tính theo tính đúng đắn của nó), và hai khối. Nói cách
khác, nó trông tựa như thế này:
if (mot bỉeu thuc nao do) {
cau lenh 1 trong truong hop dung ;
cau lenh 2 trong truong hop dung ;
cau lenh 3 trong truong hop dung ;
...
} else {
cau lenh 1 trong truong hop sai ;
chop($a);
if ($a < 18) {
print "Nay, bạn chua du tuoi bau cu dau nhe!\n";
} else {
print "Du tuoi roi! Hay binh than! Vay di bau cu di!\n";
$votes++; # den so phieu
}
Bạn có thể cắt bỏ khối else như trong:
print "Ban bao nhieu tuoi roi?"
$a = <STDIN>;
chop($a);
if ($a < 18) {
print "Nay, bạn chua du tuoi bau cu dau nhe!\n";
}
Đôi khi, bạn muốn bỏ đi phần if mà chỉ có phần else, vì sẽ tự nhiên hơn để nói "hãy làm điều
đó nếu điều này sai" so với "làm điều đó nếu điều không điều này là đúng". Perl giải quyết
điều này với biến thể unless:
print "Ban bao nhieu tuoi roi?"
$a = <STDIN>;
chop($a);
unless ($a < 18) {
print "Du tuoi roi! Hay binh than! Vay di bau cu di!\n";
$votes++; # den so phieu
}
Việc thay thế if bằng unless là có hiệu quả khi nói "Nếu biểu thức điều khiển là không đúng thì
hãy làm..." (một unless cũng có thể có một else, như if).
Nếu bạn có nhiều hơn hai chọn lựa thì bạn có thể thêm một nhánh elsif vào câu lệnh if, giống
như:
if (bieu thuc so 1) {
cau lenh 1 trong truong hop dung 1;
...
}
Để thực hiện câu lệnh while này, Perl tính biểu thức điều khiển. Nếu giá trị này là đúng (bằng
việc dùng ý tưởng về cái đúng của câu lệnh if), thì thân của câu lệnh while sẽ được tính một
lần. Điều này được lặp lại cho tới khi biểu thức điều khiển trở thành sai, tại điểm đó Perl
chuyển sang câu lệnh tiếp sau while. Chẳng hạn:
print "Ban bao nhieu tuoi roi?"
$a = <STDIN>;
chop($a);
whileless ($a > 0) {
print "Vao luc nay ban moi $a tuoi.\n";
$a--;
}
Đôi khi nói "hãy làm việc đó trong khi điều này sai" lại dễ hơn là nói "hãy làm việc đó trong
khi không điều này là đúng”. Một lần nữa, Perl lại có câu trả lời. Thay cho while là until, cũng
cho kết quả mong muốn:
until (bieu thuc) {
cau lenh 1;
cau lenh 2;
cau lenh 3;
...
}
Chú ý rằng trong cả hai dạng while và until, các câu lệnh thân sẽ bị bỏ qua hoàn toàn nếu biểu
thức điều khiển là giá trị kết thúc ngay từ lúc bắt đầu. Chẳng hạn, nếu người dùng đưa vào một
độ tuổi bé hơn 0 cho đoạn chương trình trên (chương trình while) thì Perl sẽ bỏ qua thân chu
trình.
Có thể là biểu thức điều khiển sẽ chẳng bao giờ để cho chu trình thoá ra được. Điều này hoàn
toàn hợp pháp, và đôi khi cũng là mong muốn nữa, và do vậy không bị coi như một lỗi. Chẳng
hạn, bạn có thể muốn một chu trình cứ lặp lại mãi chừng nào bạn còn chưa phạm phải lỗi, và
rồi có một đoạn trình giải quyết lỗi đi theo sau chu trình.
for (bieu thuc khoi dau; bieu thuc kiem tra; bieu thuc tang
bien dem) {
cau lenh 1;
cau lenh 2;
cau lenh 3;
....
}
Gỡ ra theo dạng ta đã thấy trước đây, điều này trở thành
bieu thuc khoi dau;
while (bieu thuc kiem tra) {
cau lenh 1;
cau lenh 2;
cau lenh 3;
....
bieu thuc tang;
}
Trong cả hai trường hợp, biểu thức khởi đầu đều được tính trước. Biểu thức này về điển hình
chỉ gán giá trị ban đầu cho một biến lặp, nhưng cũng chẳng có hạn chế nào về việc nó có thể
chứa cái gì - trong thực tế nó có thể rỗng. Rồi biểu thức kiểm tra sẽ được tính để xác định đúng
sai. Nếu giá trị tính được là đúng thì thân chu trình sẽ được thực hiện, tiếp theo đó là tính biểu
thức tăng (mà điển hình là được dùng để tăng bộ lặp). Perl tiếp đó sẽ tính lại biểu thức kiểm
tra, lặp lại khi còn cần.
Thí dụ này in ra các số từ 1 đến 10, mỗi số đều có sau nó một dấu cách:
for ($i = 1; $i <= 10; $i++)
print "$i ";
}
Ban đầu, biến $i được đặt là 1. Rồi, biến này được so sánh với 10, mà thực sự nó đang bé hơn
hay bằng. Thân của chu trình (mỗi câu lệnh print) được thực hiện, và rồi biểu thức tăng (biểu
thức tự tăng $i++) sẽ được thực hiện, thay đổi giá trị trong $i thành 2. Vì 2 vẫn còn bé hơn hay
bằng 10 nên ta lặp lại tiến trình, cho tới khi lần lặp cuối mà giá trị 10 của $i đổi thành 11. Rồi