CÂULỆNHREPEAT 9.3.1. Cú pháp, lưu đồ, cách thức hoạt động : Cú pháp: REPEAT LệnhP; UNTIL Ðiềukiện ; Ý nghĩa: Chừng nào Ðiềukiện còn sai thì cứ làm LệnhP, cho đến khi Ðiềukiện đúng thì không làm LệnhP nữa mà chuyển sang lệnh kế tiếp ở phía dưới. Cách thức hoạt động của REPEAT: Bước 1: Làm LệnhP, rồi kiểm tra Ðiềukiện, nếu Ðiềukiện đúng thì chuyển sang lệnh tiếp theo ở phía dưới, ngược lại, nếu Ðiềukiện sai thì quay lại bước 1. LệnhP cũng được gọi là thân của vòng lặp REPEAT, nếu nó gồm nhiều lệnh thì các lệnh đó không cần phải đặt trong khối begin va?end. Nếu Ðiềukiện không bao giờ đúng thì LệnhP sẽ phải làm hoài, lúc đó ta có vòng lặp vô hạn. Trong trường hợp này, muốn dừng chương trình, hãy gõ đồng thời hai phím Ctrl và Pause (^Pause). Ðể tránh các vòng lặp vô hạn, trong thân của lệnhREPEAT cần có ít nhất một lệnh có tác dụng làm biến đổi các đại lượng tham gia trong Ðiềukiện để đến một lúc nào đó thì Ðiềukiện sẽ đúng và do đó vòng lặp sẽ kết thúc. Các vòng lặp có số lần lặp biết trước đều có thể giải được bằng lệnh REPEAT. Ðặc biệt, cũng như lệnh WHILE, lệnhREPEAT rất thích hợp với các vòng lặp có số lần lặp không biết trước 9.3.2. Các ví dụ về lệnhRepeat : Ví dụ 9.12: Ðảm bảo tính hợp lý của dữ liệu nhập từ bàn phím. Khi giải phương trình bậc hai Ax 2 +Bx+C=0, ta thường giả thiết A 0, khi tính S=N!, ta thường yêu cầu N 0. Sự hạn chế phạm vi đối với các dữ liệu nhập sẽ đảm bảo tính hợp lý của chúng và làm giảm bớt các phức tạp khi biện luận. Ðể buộc người sử dụng phải nhập A 0, nếu nhập A=0 thì bắt nhập lại cho tới khi nhập A 0 mới thôi, ta dùng cấu trúc : Repeat Write(‘Nhập A khác không : ‘); Readln(A); Until A<> 0; Ðể đảm bảo chắc chắn nhập N thỏa điều kiện 0<N<20, ta dùng cấu trúc : Repeat Write(‘ Nhập N (0<N<20) : ‘); Readln(N); If (N<=0) or (N>=20) then write(#7); Until (0<N) and (N<20) ; Lệnh write( chr(7) ) hay write(#7) có công dụng phát ra tiếng kêu bip để cảnh báo người dùng đã nhập dữ liệu sai yêu cầu. Ví dụ 9.13: Tìm bội số chung nhỏ nhất của hai số nguyên dương M và N. Bài toán này có những cách giải khác nhau, dưới đây là một cách đơn giản. Trước hết, hãy xem cách tìm BSCNN của hai số M=5 và N=9. Vì N>M nên ta sẽ tìm trong tập các bội số của N :{ 9, 18, 27, 36, 45, } số nhỏ nhất chia hết cho M, đó là số 45. Một cách tổng quát, gọi Max là số lớn nhất của M và N. Ðầu tiên ta gán : BSCNN:=0; Sau đó cứ làm lệnh BSCNN:=BSCNN+Max ; hoài cho đến khi BSCNN chia hết cho cả M và N thì dừng. Trong chương trình ta dùng lệnhrepeat để nhập hai số M, N đảm bảo dương. PROGRAM VIDU913; { Tìm BSCNN của M và N } Var M, N, Max, BSCNN : Integer; Begin Repeat Write(‘ Nhập M và N dương :’); Readln(M, N); Until (M>0) and (N>0); If N>M then Max:=N else Max:=M; BSCNN:=0; Repeat BSCNN:=BSCNN + Max; Until (BSCNN mod N=0) and (BSCNN mod M=0) ; Writeln(‘ Bội số chung nhỏ nhất= ‘, BSCNN) ; Readln; End. Chạy <VD913.EXE> Chép file nguồn <VD913.PAS> Ví dụ 9.14: Thiết kế để chạy nhiều lần một chương trình. Trong Turbo Pascal, mỗi lần muốn chạy chương trình ta phải gõ cặp phím Ctrl và F9 (viết tắt là ^F9), điều này sẽ bất tiện nếu cần chạy chương trình nhiều lần ứng với các bộ dữ liệu thử khác nhau. Cấu trúc sau đây cho phép ta chạy chương trình một số lần theo ý muốn: REPEAT { Các lệnh của chương trình} Write(‘ Tiếp tục nữa không (Y/N) ? :’); Readln(Traloi); {5} UNTIL (Traloi =‘N’) or ( Traloi=‘n’); Ở đây, Traloi là một biến kiểu ký tự (Char); Sau khi thực hiện xong {các lệnh của chương trình }, nếu muốn chạy tiếp thì ta gõ phím Y , nếu muốn dừng thì gõ N . Chú ý : lệnh Readln(Traloi); ở dòng thứ {5} có thể thay bằng: Traloi:=Readkey; Hàm Readkey thuộc thư viện CRT cho kết qủa là một ký tự gõ từ bàn phím, nó khác lệnh Readln(Traloi) ở chỗ là khi nhập ký tự ta không cần phải Enter. Chương trình dưới đây cho phép thực hiện một số lần việc : in tam giác cân đặc có chiều cao m (0<m<20) : PROGRAM VIDU914; { In tam giác cân đặc } Uses CRT; Const sao =‘*’; Var k, j, m: integer; Traloi : Char ; Begin REPEAT {9} Clrscr; Repeat {11} Write(‘ Nhập m (0<m<20) : ‘); Readln(m); If (m <= 0) or ( m>=20) then write(#7); Until (m>0) and ( m<20) ; {15} Writeln(sao :m); { in đỉnh } { In hai cạnh bên của tam gíac } For k:=1 to m-2 do begin Write(chr(32): m-k-1); { in m-k-1 ký tự trắng} For j:=1 to 2*k+1 do Write(sao); { in 2k+1 dấu *} Writeln; end; For k:=1 to 2*m-1 do Write(sao); {in cạnh đáy} Writeln; Write(‘ Tiếp tục nữa không (Y/N) ?: ‘); Readln( Traloi); UNTIL (Traloi=‘N’) or ( Traloi=‘n’); {28} End. Chạy<VD914.EXE> Chép file nguồn <VD914.PAS> Chương trình 9.14 là một ví dụ về hai câulệnhRepeat lồng nhau, điều này xảy ra khi thân của một lệnh Repat lại chứa một lệnhRepeat khác: lệnhRepeat thứ nhất, từ dòng {9} đến dòng {28}, chứa lệnhRepeat thứ hai từ dòng {11} đến dòng {15}. 9.3.3. So sánh các lệnh For, While và Repeat: Lệnh For dùng cho các vòng lặp có số lần lặp đã biết trước Lệnh While hay Repeat tổng quát hơn lệnh For, dùng được cho tất cả các loại vòng lặp, nhưng thường dùng cho các vòng lặp có số lần lặp chưa biết trước. Lệnh While và Repeat khác nhau ở điểm sau: lệnh While kiểm tra điều kiện trước, nếu đúng mới thực hiện các lệnh ghi trong thân của nó ( lệnhP ), còn lệnhRepeat thực hiện lệnhP rồi mới kiểm tra điều kiện. Vì thế, lệnhRepeat sẽ thực hiện các lệnh ghi trong thân của nó ít nhất được một lần. Ngoài ra, lệnh While kết thúc khi điều kiện sai, lệnhRepeat kết thúc khi điều kiện đúng. . một ví dụ về hai câu lệnh Repeat lồng nhau, điều này xảy ra khi thân của một lệnh Repat lại chứa một lệnh Repeat khác: lệnh Repeat thứ nhất, từ dòng {9} đến dòng {28}, chứa lệnh Repeat thứ hai. trước. Lệnh While và Repeat khác nhau ở điểm sau: lệnh While kiểm tra điều kiện trước, nếu đúng mới thực hiện các lệnh ghi trong thân của nó ( lệnhP ), còn lệnh Repeat thực hiện lệnhP rồi. có thể giải được bằng lệnh REPEAT. Ðặc biệt, cũng như lệnh WHILE, lệnh REPEAT rất thích hợp với các vòng lặp có số lần lặp không biết trước 9.3.2. Các ví dụ về lệnh Repeat : Ví dụ 9.12: