Chương 2. Các kiểu dữ liệu đơn giản chuẩn
6.2. Các câu lệnh lặp
Trong lập trình giải các bài toán thực tế chúng ta luôn gặp phải cấu trúc lặp để thực hiện một công việc nào đó lặp đi lặp lại theo một quy luật. Có hai loại câu lệnh lặp là câu lệnh lặp có số b−ớc lặp xác
định và câu lệnh lặp có số bước lặp không xác định.
6.2.1. Câu lệnh lặp có số bước lặp xác định
Cấu trúc For cho phép lặp lại nhiều lần một hoặc một nhóm lệnh.
Số lần lặp lại nhóm lệnh đã biết trước. Cấu trúc For có 2 dạng sau:
Dạng 1: For <Biến điều khiển := Giá trị đầu>
To <giá trị cuối> Do <lệnh>;
Dạng 2: For <Biến điều khiển:=Giá trị cuối>
DownTo <giá trị đầu> Do <lệnh>;
Ch−ơng 6: Các câu lệnh có cấu trúc 47
Trong đó:
- Biến điều khiển, Giá trị đầu, Giá trị cuối có kiểu thuộc kiểu vô
hướng đếm được như Byte, ký tự, nguyên...
- Lệnh: bao gồm một lệnh hay nhiều lệnh (nhiều lệnh thì phải đặt trong khèi Begin.. End).
Giả sử Giá trị đầu là giá trị đứng trước Giá trị cuối trong tập dữ
liệu có kiểu vô hướng đếm được, khi đó vòng lặp For thực hiện từng b−íc nh− sau:
B−ớc 1. Đầu tiên Biến điều khiển (BĐK) nhận Giá trị ban đầu.
Bước 2. Máy kiểm tra xem BĐK đã vượt quá Giá trị cuối hay chưa hay nói cách khác, máy kiểm tra điều kiện Ord(BĐK) <= Ord(Giá trị cuối).
Bước 3. Nếu điều kiện nói trên sai thì máy thoát khỏi chu trình để xét tiếp các lệnh tiếp theo ngoài vòng lặp. Nếu điều kiện trên là đúng thì:
- Máy thực hiện câu lệnh sau từ khóa Do.
- Sau đó BĐK đ−ợc tăng tới giá trị tiếp theo: BĐK:= Succ(BĐK);
- Trở lại b−ớc 2.
Lưu đồ vòng lặp xác định For..To..Do...
False Begin
Biến điều khiển := Giá trị đầu
Biến điều khiển > Giá trị cuối
Do <Các lệnh lặp>
Biến điều khiển := Succ(Biến điều khiển)
End;
Hình 6.2. Lưu đồ lệnh For
Vòng lặp For..DownTo..Do... cũng hoạt động tương tự như
For..To..Do.
Mỗi lần câu lệnh sau từ khóa Do đ−ợc thực hiện thì biến điều khiển tự động nhận giá trị tiếp theo so với giá trị cũ trong kiểu dữ liệu của nó.
Sau từ khóa Do chỉ đ−ợc phép thực hiện một câu lệnh, do đó nếu muốn sử dụng nhiều câu lệnh trong vòng lặp thì nhất thiết dùng câu lệnh hợp thành hay còn gọi là lệnh ghép với các từ khóa BEGIN ... END;
Trong các câu lệnh sau DO không nên tùy tiện thay đổi giá trị của biến điều khiển vì ta sẽ không còn kiểm soát đ−ợc biến điều khiển.
Ví dụ 1: Hiện ra màn hình 5 dòng chữ TURBO PASCAL
Program vidu1;
var i: integer;
Begin
For i := 1 to 5 do
Writeln('TURBO PASCAL');
Readln;
End.
Ví dụ 2: Ch−ơng trình sau sẽ đ−a ra màn hình dãy số 5 4 3 2 1.
Program vidu2;
var i: integer;
Begin
For i := 1 Downto 5 do Write(i:2); Readln;
End.
Ví dụ 3: Viết ch−ơng trình nhập n và tính tổng S = 1 + 1/2 + 1/3 +1/4 ... (n số hạng)
Program vidu3;
uses crt;
var i, n, S: integer;
Ch−ơng 6: Các câu lệnh có cấu trúc 49
Begin clrscr;
Write('Nhap n=');
S:=0;
For i := 1 to n do S:= S +1/i;
Write('Tong S=',S);
Readln;
End.
6.2.2. Câu lệnh lặp có số bước lặp không xác định Repeat..Until
Đây là cấu trúc th−ờng dùng trong tr−ờng hợp biến điều khiển không có kiểu vô hướng đếm được và nhất là khi không biết trước số lần lặp.
Cú pháp:
Repeat:
Lệnh 1;
Lệnh 2;
...
Until <Điều kiện>
Trong đó: điều kiện là một biểu thức Boolean.
Hoạt động của cấu trúc nμy nh− sau:
B−ớc 1. Máy thực hiện lần l−ợt Lệnh 1, Lệnh 2, ... Lệnh N.
Bước 2. Xác định giá trị của biểu thức "Điều kiện". Nếu biểu thức này cho giá trị TRUE thì ra khỏi chu trình, trái lại nếu biểu thức điều kiện cho giá trị FALSE thì quay trở lại b−ớc 1.
Nói cách khác: Các lệnh nằm giữa hai từ khóa Repeat và Util sẽ
đ−ợc thực hiện lặp đi lặp lại cho tới khi điều kiện đúng thì thoát ra khỏi vòng lặp để thực hiện câu lệnh tiếp theo. Các lệnh đặt giữa Repeat và Until bao giờ cũng đ−ợc thực hiện ít nhất một lần. Không hạn chế số lệnh đặt giữa REPEAT và UNTIL.
Đúng Begin
Biểu thức Boolean có giá trị True Các lệnh lặp
End Sai
Hình 6.3. Lưu đồ lệnh Repeat .. Until
Ví dụ: Viết ch−ơng trình nhập vào một dãy số nguyên từ bàn phím cho đến khi gặp số 0, sau đó tính tổng các số dương và trung bình cộng các số âm.
Program minhhoa_1;
uses crt;
var
i, a, sd, sa, d: integer;
Begin clrscr;
i:=1; sd:=0; sa:=0; d:=0;
writeln('Hay nhap cac so nguyen, go 0 de dung nhap');
repeat
write(' Nhap so thu ',i, ' = '); readln(a);
if a>0 then sd:= sd + a else if a <0 then begin
d:= d + 1;
sa:= sa + 1;
end;
Ch−ơng 6: Các câu lệnh có cấu trúc 51
i:= i +1;
until a = 0;
writeln('Tong cac so duong =',sd);
if d=0 then writeln('Khong co so am') else
writeln('Trung binh cong cac so am =', sa/d: 10:3);
readln;
End.
6.2.3. Câu lệnh lặp có số bước lặp không xác định While..Do Trong cấu trúc lệnh Repeat.. Until ở trên ta thấy, lệnh nằm trong thân chu trình đ−ợc thực hiện ít nhất một lần vì điều kiện sau Until
đ−ợc kiểm tra sau. Trong Pascal còn có một cấu trúc lặp cho phép máy tính kiểm tra điều kiện tr−ớc khi thực hiện lệnh trong thân chu trình.
Nếu ngay từ đầu điều kiện lặp là sai thì lệnh nằm trong thân ch−ơng trình sẽ không đ−ợc thực hiện một lần nào:
Cú pháp:
While <Biểu thức Boolean> Do Begin
<Các lệnh lặp>
End;
Hoạt động của cấu trúc lệnh nh− sau:
1. Đầu tiên máy tính sẽ kiểm tra <Biểu thức Boolean>, là biểu thức logic chỉ có thể nhận một trong 2 giá trị TRUE và FALSE. Nếu
<Biểu thức Boolean> cho giá trị đúng (TRUE), máy tính sẽ thực hiện các lệnh lặp đặt giữa Begin và End.
2. Máy tính quay về kiểm tra <Biểu thức Boolean>, nếu giá trị
<Biểu thức Boolean> là sai (FALSE) thì máy sẽ thoát khỏi cấu trúc lặp
để thi hành các lệnh sau từ khóa END;
Hình 6.4. Lưu đồ lệnh While.. do..
NhËn xÐt:
1. Hai cấu trúc lệnh Repeat .. Until và While .. Do đều có số lần lặp không xác định trước, cú pháp hai lệnh này không tự thay đổi biến trong biểu thức Boolean, do đó trong số các câu lệnh nằm trong vòng lặp phải có ít nhất một câu lệnh làm thay đổi ít nhất một biến số có mặt trong biểu thức Boolean. Điều này sẽ giúp cho biểu thức Boolean thay đổi giá trị nhằm kết thúc vòng lặp.
2. Từ khóa Do chỉ đ−ợc phép thực hiện một câu lệnh, do đó nếu muốn dùng nhiều câu lệnh trong vòng lặp thì phải sử dụng câu lệnh hợp thành.
Ví dụ 1: Lãi suất hàng tháng gửi tiết kiệm không kỳ hạn là k = 0,5%. Một ng−ời gửi vào số tiền ban đầu là a. Hãy viết ch−ơng trình để tính xem sau bao nhiêu tháng người đó đạt số tiền không nhỏ hơn b?
Program minh_hoa2;
uses crt;
const k = 0.005;
var a, b: real; t: integer;
Begin
clrscr; t:= 0;
write('Cho so tien gui ban dau a= '); readln(a);
write('Cho so tien muon dat duoc b= '); readln(b);
Ch−ơng 6: Các câu lệnh có cấu trúc 53
while a <b do begin
a:= a + a*k;
t:= t +1;
write('Can gui ',t:3, 'thang va se co ',a:9:2,'Viet nam dong');
end readln;
end.
Ví dụ 2: Tính tổng sau: A = 1 + 1/2 + 1/3 + ... + 1/N:
Bài toán này đã đ−ợc giải bằng cấu trúc lệnh For, song ở đây ta dùng vòng lặp không xác định để làm ví dụ minh họa.
Program Tinh_tong;
var
I, N: Integer;
A: Real;
Begin
Write('n = '); Readln(n);
A:=0; I:=1;
Repeat A:=A+1/I;
I:=I + 1; (*Thay đổi giá trị biểu thức Boolean*) Until I>N;
Writeln('Tong la: ',A:10:8);
Readln;
End.
Hoặc viết cách khác dưới dạng "đếm lùi":
Program Tinh_tong;
var
N: Integer;
A: Real;
Begin
Write('n = '); Readln(n);
A:=0;
Repeat A:=A+1/N;
N:=N - 1; (*Thay đổi giá trị biểu thức Boolean*) Until N = 0;
Writeln('Tong la: ',A:10:8);
Readln;
End.
Ch−ơng 6: Các câu lệnh có cấu trúc 55
Bài tập chương 6
Bμi 1: Viết ch−ơng trình tính tổng
a) Các bình ph−ơng của n số tự nhiên đầu tiên:
2 2 2
S= +1 2 +3 + +... n
b) Các lập ph−ơng của n số tự nhiên đầu tiên c) Các nghịch đảo của n số tự nhiên đầu tiên Bμi 2: Tìm n biết rằng: 44 + 64 + 84 + 94 + 144 = 15n
Bμi 3: Viết ch−ơng trình tính n! với n là số tự nhiên bất kỳ cho tr−ớc.
Bμi 4: Giải bài toán dân gian sau:
Tr¨m tr©u tr¨m cá Trâu đứng ăn năm Trâu nằm ăn ba Lụ khụ trâu già Ba con mét bã
Hỏi có bao nhiêu trâu đứng, bao nhiêu trâu nằm, bao nhiêu trâu già?
Gợi ý: Đây là bài toán tìm nghiệm nguyên không âm của hệ phương trình bậc nhất 3 ẩn. Gọi số trâu đứng là x, số trâu nằm là y và số trâu già là z.
Ta có hệ ph−ơng trình:
x y z 100
5x 3y z / 3 100 + + =
⎧⎨ + + =
⎩
Đặt z/3 = t, ta có hệ ph−ơng trình:
x y 3t 100 5x 3y t 100 0 x 20 0 y 33 0 t 33
+ + =
⎧⎪ + + =
⎪⎪ ≤ ≤
⎨⎪ ≤ ≤
⎪ ≤ ≤
⎪⎩
Bμi 5: Lập ch−ơng trình nhập vào hai số a, b rồi tính y = 15x2 + x + 72.
Trong đó:
2 2
a b
b khi a b 3
x 15,172 khi a b a b
khi a b
a b
⎧ + + <
⎪⎪
=⎨ =
⎪ −
⎪ >
+
⎩
Bμi 6: Tính hàm số sinx theo công thức sau với n<=100
5 2n 1
x x n x
sin x x ... ( 1)
3! 5! (2n 1)!
= − + + + − +
+
Gợi ý: cần tìm đ−ợc số hạng tổng quát của các số hạng bên vế phải. Nếu gọi các số hạng này T0, T1,.. Tn ta có:
T0 = x; k x k 1
T T
2k(2k 1) −
= − + víi k = 1, 2,.. 100;
Bμi 7: Lập ch−ơng trình phân tích số nguyên n thành thừa số nguyên tố.
Bμi 8: Cho một dãy số, hãy viết chương trình để xem trong dãy có bao nhiêu lần đổi dấu.
Bμi 9: Lập chương trình đọc x, eps từ bàn phím với điều kiện x 1< , tính tổng:
2 3 n n
x x ( 1) x
S 1 x .. ...
2! 3! n!
= − + − + + − +
Ch−ơng 7: Ch−ơng trình con 57
Chương 7
CHƯƠNG TRÌNH CON