intTypePromotion=1
zunia.vn Tuyển sinh 2024 dành cho Gen-Z zunia.vn zunia.vn
ADSENSE

Learning Perl - Các cấu trúc điều khiển khác

Chia sẻ: AJFGASKJHF SJHDB | Ngày: | Loại File: PDF | Số trang:5

96
lượt xem
8
download
 
  Download Vui lòng tải xuống để xem tài liệu đầy đủ

9.1 Toán tử last Toán tử last tương đương c âu lệnh break của C, để thoát sớm khỏi chu trình. Toán tử last ngắt khối c hu trình bao quanh ở bên trong nhất, gây ra việc thực hiện tiếp tục với câu lệnh đi ngay sau khối đó. Chẳng hạn: while (something) { something; something; something; if (somecondition) { somethingother; somethingother; lase; #thoat khoi chu trinh while } morething; morething;

Chủ đề:
Lưu

Nội dung Text: Learning Perl - Các cấu trúc điều khiển khác

  1. D iễn đàn tin học | Tutorial Room Mục lục «« C hương 8 »» C hương 1 0 Learning Perl - Chương 8: Các cấu trúc điều khiển khác 1. Xác định một hàm tiện íc h 2. Gọi một hàm tiện ích 3. Giá t rị trả về 4. Đối số c ủa hàm 5. Biến c ục bộ trong hàm 6. Bài t ập 9.1 Toán tử last Toán tử last t ương đương c âu lệnh break của C, để thoát sớm khỏi chu trình. Toán tử last ngắt khối c hu trình bao quanh ở bên trong nhất, gây ra việc thực hiện tiếp tục với câu lệnh đi ngay sau khối đó. Chẳng hạn: while (something) { something; something; something; if (somecondition) { somethingother; somethingother; lase; #thoat khoi chu trinh while } morething; morething; } #last se nhay den cho nay Nếu somecondition là đúng (true), thì somethingother sẽ được thực hiện, và c uối c ùng t oán tử last buộc c hu trình while phải kết thúc . Toán tử last c hỉ tính t ới khối c hu trình, không tính khối cần để tạo nên kết c ấu c ú pháp nào đó. Điều này c ó nghĩa là khối tạo nên c âu lệnh if hay else hoặc do không được tính tới - chỉ khối tạo nên f or, foreac h, w hile và khối "trần" mới được tính (khối "trần" là khối không thuộc phần khác của một kết c ấu lớn hơn, như một c hu t rình, hay một trình c on, hay một câu lệnh if/then/else). Giả sử tôi muốn xem liệu thông báo thư đã được c ất giữ trong một tệp c ó là từ merlyn hay không. Một thông báo như vậy c ó thể giống như là: From: merlyn@ora.com (Jenny L. Schwartz) To: stevet@ora.com Date: 01-SEP-93 08:16:24 PM PDT - 0700 Subject: A sample mail message Here’s the body of the mail message. And here is some more. Tôi phải duyệt qua thông báo này và tìm dòng bắt đầu với F rom: v à rồi để ý liệu dòng này c ó c hứa tên đăng nhập merlyn hay không. T ôi c ó t hể làm điều đó như thế này: while () { #doc du lieu if (/^From:/) { #bat dau voi "From:"? Neu co... (/merlyn/) { #no co chua chuoi "merlyn" hay khong? if print "Email from Jenny! Its about time!\n";
  2. } last ; #khong can tim "From:" nua nen thoat khoi vong lap } #ket thuc "if /^From:/" if (/^$/) { #neu la dong trong? last ; #thi khong can kiem tra them nua } } #ket thuc while Lưu ý rằng một khi dòng có chứa F rom: được tìm thấy thì c húng ta đi ra khỏi chu trình c hính bởi vì tôi muốn xem chỉ dòng F rom: đầu tiên. Cũng lưu ý rằng một đầu đề thư kết thúc tại dòng trống đầu tiên, cho nên c húng ta c ó t hể ra khỏi chu trình c hính nữa. 9.2 Toán tử next Giống như last , next c ũng làm thay đổi luồng thực hiện theo trình tự thông t hường. Tuy nhiên, toán tử next làm c ho việc thực hiện bỏ qua phần c òn lại c ủa khối c hu trình được bao bên trong nhất mà không kết t húc khối này (khác với last, last sẽ làm kết thúc khối c hu trình). Nó được dùng như thế này: while (mot_cai_gi_do) { phan_thu_nhat; ... if (dieu_kien) { phan_nao_do; ... next; #nhay den cuoi chu trinh while } phan_khac; ... #next se nhay toi day } Nếu dieu_kien là đúng, thì phan_nao_do sẽ được thực hiện và phan_khac sẽ bị bỏ qua (nếu dieu_kien là sai thì phan_nao_do sẽ không được thực hiện và phan_khac s ẽ được thực hiện như bình thường) Một lần nữa, khối c ủa một c âu lệnh if không được tính tới như khối chu t rình. 9.3 Toán tử redo Các h thứ ba mà bạn c ó thể nhảy qua trong một khối c hu trình là bằng c ác h dùng toán tử redo. Toán tử này nhảy tới c hỗ bắt đầu của khối hiện tại (không tính lại biểu thức điều kiện), kiểu như: while (cai_gi_do) { #redo se nhay toi cho nay phan_1; ... if (dieu_kien_nao_do) { phan_nao_do; ... redo; } phan_khac; ... } Một lần nữa, khối if không được tính tới. Chỉ tính c ác khối c hu trình. Lư u ý rằng với redo và last dùng trong một khối trần, bạn c ó t hể tạo nên c hu trình vô hạn mà đi ra từ giữa, kiểu như:
  3. { phan_bat_dau; ... if (dieu_kien_nao_do) { last; } phan_sau; ... redo; } Điều này sẽ phù hợp c ho một chu trình kiểu while mà cần tới việc có một phần nào đó c ủa c hu trình này được thực hiện như việc khởi đầu trước phép kiểm thử thứ nhất. (Trong mục "Bộ thay đổi biểu thức " dưới đây, sẽ c hỉ ra c ho bạn các h viết c âu lệnh if v ới ít kí tự ngắt hơn.) 9.4 Khối có nhãn Điều gì xảy ra nếu bạn muốn ra khỏi một khối c ó c hứa khối bên trong nhất, hay nói theo c ác h khác, ra khỏi hai khối lồng nhau ngay một lúc ? T rong C, bạn phải viện tới toán tử goto để đi ra. Không c ần phải làm như vậy trong Perl - bạn có thể dùng last , next v à redo t ại bất kì khối kết nào bằng việc cho khối một c ái tên c ó nhãn. Nhãn là một kiểu tên khác từ một không gian tên khác mà tuân theo c ùng qui tắc như vô hướng, mảng, mảng kết hợp và trình con. T uy nhiên, như chúng ta thấy, một nhãn không c ó kí tự ngắt đi đầu đặc biệt (như $ c ho vô hướng, @ c ho mảng...), c ho nên một nhãn c ó t ên print sẽ xung đột với từ dành riêng print và sẽ không được phép. Bởi lí do này, Larry gợi ý bạn hãy chọn c ác nhãn bao gồm toàn chữ hoa và s ố, mà anh ấy đảm bảo sẽ không bao giờ bị c họn nhầm thành một từ dành riêng t rong tương lai. Bên c ạnh đó, tất c ả c ác c hữ hoa cho phép dễ nhìn thấy hơn trong một văn bản chương trình mà phần lớn là chữ thường. Một khi bạn đã c họn c ẩn thận nhãn, thì nó sẽ đứng ngay trước c âu lệnh c ó chứa khối, theo sau dấu hai c hấm, kiểu như thế này: NHAN: while (dieu_kien) { cau_lenh_1; cau_lenh_2; ... if (dieu_kien_khac) { last NHAN; } } Lư u ý rằng ta đã thêm NHAN, như một tham biến vào c âu lệnh last . Tham biến này bảo c ho Perl ra khỏi khối có tên NHAN, t hay vì ra khỏi khối bên trong nhất. Trong trường hợp này, c húng ta không có cái gì khác ngoài khối bên trong nhất. Nhưng giả sử c ó c ác chu trình lồng nhau: OUTER: for ($i = 1; $i = 10; $j++) { if ($i * $j == 63) { print "$i x $j = 63!\n"; last OUTER; } if ($j >= $i) { next OUTER ; } } }
  4. T ập hợp các c âu lệnh này thử tất cả các giá trị kế t iếp của hai số nhỏ nhất được nhân với nhau cho tới khi nó tìm ra một cặp c ó t íc h là 63 (7 và 9). Lưu ý rằng một khi đã tìm được một c ặp thì không c ần phải kiểm tra c ác số khác nữa, c ho nên c âu lệnh if t hứ nhất ra khỏi cả hai c hu trình f or bằng việc dùng last v ới nhãn OUTER. Câu lệnh if t hứ hai c ố gắng đảm bảo rằng số lớn hơn trong hai số bao giờ c ũng là số thứ nhất bằng việc bỏ qua việc lặp tiếp của chu trình bên ngoài ngay khi điều kiện này không c òn xảy ra nữa. Điều này c ó nghĩa là c ác số sẽ được kiểm thử với ($i, $j) sẽ là (1,1), (2,1), (2,2), (3,1), (3,2), (3,3), (4,1)... Cho dù khối bên trong nhất được gắn nhãn, thì các t oán tử last , next , và redo không có tham biến tuỳ chọn (nhãn) vẫn vận hành t ôn trọng khối bên trong nhất. Cũng vậy, bạn không thể dùng nhãn để vào trong một khối - chỉ để ra khối. Các toán tử last , next hay redo phải ở bên trong khối. 9.5 Bộ thay đổi biểu thức Xem như một c ác h khác để chỉ ra "nếu thế này, thì thế kia," Perl c ho phép bạn gắn nhãn cho một bộ sửa đổi if lên một biểu thức vốn là một biểu thức đứng riêng. Kiểu như: bieu_thuc_nao_do if bieu_thuc_dieu_kien; Trong trường hợp này, bieu_thuc_dieu_kien được tính trước để xét giá trị chân lí của nó (bằng việc dùng c ùng qui tắc như thường lệ), và nếu đúng, t hì biểu_thuc_nao_do s ẽ được t ính tiếp. Điều này đại thể tương đương với: if (bieu_thuc_dieu_kien) { bieu_thuc_nao_do; } ngoại trừ rằng bạn không cần thêm dấu ngắt phụ, c âu lệnh này đọc ngược lại, và biểu thức phải là một biểu thức đơn (không phải là một khối c âu lệnh). Tuy nhiên, nhiều lần c ác h mô tả ngược này lại biến thành c ách tự nhiên nhất để phát biểu vấn đề. Chẳng hạn, sau đây là c ác h bạn có thể ra khỏi c hu trình khi một điều kiện nào đó nảy sinh: LINE: while () { last LINE if /^From: /; } Các dạng song song khác bao gồm những dạng s au: exp2 unless exp1;# giống: unless (exp1) { exp2 } exp2 while exp1; # giống: while (exp1) { exp2 } exp2 until exp1; # giống: until (exp1) { exp2 } Lư u ý rằng tất cả các dạng này đều tính exp1 t rước rồi dựa trên đó, tính hay không tính c ái gì đó với exp2. Chẳng hạn, sau đây là c ách tìm ra luỹ thừa đầu t iên c ủa hai số lớn hơn một số đã cho: chop ($n = ); $i = 1; #khoi dau $i *= 2 until $i > $n; #lap lai cho toi khi tim ra no Các dạng này không lồng nhau - bạn không thể nói được exp3 while exp2 if exp1. Là vì dạng exp2 if exp1 không còn là một biểu thức , mà là một c âu lệnh hoàn toàn, và bạn không thể gắn thêm một trong các bộ sửa đổi này vào sau c âu lệnh. 9.6 &&, || và ?: xem như các cấu trúc điều khiển Những cấu trúc này trông tựa như c ác kí t ự ngắt, hay một phần c ủa biểu thức. Liệu c húng c ó thể thực sự được coi là c ác c ấu trúc điều khiển không? Thế này, theo c ác h nghĩ Perl, gần như bất kì cái gì cũng đều c ó thể c ả, c ho nên bạn hãy xem điều tôi nói ở đây.
  5. c ũng đều c ó thể c ả, c ho nên bạn hãy xem điều tôi nói ở đây. Thông thường, bạn bắt gặp "nếu c ái này, thì c ái nọ". Trước đây chúng ta đã thấy hai dạng này: #một c ác h if (cai_nay) { cai_no } #các h khác cai_no if cai_nay; Đây là c ách thứ ba (c ó thể vẫn c òn nữa đấy): cai_nay && cai_no; Tại sao nó lại làm việc? Nó chẳng phải là toán tử logic "và" sao? Uhh, bạn hãy kiểm tra xem c ái gì xảy ra khi cai_nay lấy giá trị T RUE hay F ALSE: Nếu c ai_nay là TRUE, thế thì giá trị c ủa toàn bộ biểu thức vẫn còn c hưa được biết tới, vì nó phụ thuộc vào giá trị c ủa cai_kia. Cho nên c ai_kia phải được tính. Nếu c ai_nay là FALSE t hế t hì chẳng cần nhìn vào c ai_kia nữa, bởi vì lúc này giá trị của toàn bộ biểu thức phải là FALSE rồi. Vì c hằng c ần gì phải tính c ai_kia nên c húng ta có thể bỏ qua. Và trong thực tế, đây là điều mà Perl làm. Perl t ính c ai_kia c hỉ khi c ai_nay là đúng, làm c ho nó thành tương đương với hai dạng t rước . Giống thế, toán tử logic hoặc giống như câu lệnh unless (hay bộ sửa đổi unless). Cho nên bạn c ó thể thay t hế: unless (cai_nay) { cai_kia } bằng cai_nay || cai_kia; Nếu bạn quen thuộc với việc dùng c ác toán tử này t rong c ác c hương trình shell để kiểm soát các c hỉ lệnh thực hiện điều kiện, thì bạn sẽ thấy rằng c húng vận hành t ương tự trong Perl. Cuối c ùng toán tử ba ngôi kiểu C: exp1 ? exp2 : exp3; tính exp2 nếu exp1 đúng, ngược lại t ính exp3. Cũng dường như là chúng ta nói: if (exp1) { exp2 } else { exp3 } nhưng một lần nữa không c ó tất c ả c ác dấu ngắt đó. Chẳng hạn, bạn có thể viết: ($a < 10) ? $b = $a : $a = $b; Ta nên dùng c ái nào đây? Tuỳ vào tâm trạng bạn t hôi, đôi khi, hay tuỳ theo từng phần biểu thức lớn đến đâu, hay liệu ta c ần t hêm đóng mở ngoặc nào bởi vì sự xung khắc thứ tự ưu tiên. Bạn hãy nhìn vào c hương trình c ủa người khác và xem chúng làm gì. Có lẽ bạn sẽ thấy đôi điều ở đó. Larry gợi ý rằng bạn hãy đặt phần quan trọng nhất c ủa biểu thức lên trước , để c ho nó nổi bật ra. 9.7 Bài tập 1. Bạn hãy viết lại bài tập ở chương trước sao c ho vòng lặp được thực hiện mãi c ho đến khi từ end được nhập vào. 2. Bạn hãy viết lại bài tập ở chương 4: c ộng tất c ả c ác số nguyên từ 1 đến 999, sử dụng vòng lặp và thoát ở giữa vòng lặp M ục lục «« C hương 8 »» C hương 1 0
ADSENSE

CÓ THỂ BẠN MUỐN DOWNLOAD

 

Đồng bộ tài khoản
4=>1