C©u lÖnh lÆp trong Pascal
A. PHẦN MỞ ĐẦU
I/ Lý do chọn đề tài
Trong thời đại của chúng ta, sự bùng nổ CNTT đã tác động lớn đến công cuộc
phát triển kinh tế xã hội người. Đảng và Nhà nước đã xác định rõ ý nghĩa và tầm quan
trọng của tin học và CNTT, truyền thông cũng như những yêu cầu đẩy mạnh của ứng
dụng CNTT, đào tạo nguồn nhân lực đáp ứng yêu cầu CNH, HĐH, mở cửa và hội nhập,
hướng tới nền kinh tế tri thức của nước ta nói riêng - thế giới nói chung.
Chính vì xác định được tầm quan trọng đó nên Nhà nước ta đã đưa môn tin học vào
trong nhà trường và ngay từ tiểu học học sinh được tiếp xúc với môn tin học để làm quen
dần với lĩnh vực CNTT, tạo nền móng cơ sở ban đầu để học những phần nâng cao trong
các cấp tiếp theo. Nhất là trong năm học 2009 - 2010 này, năm học của ứng dụng CNTT.
Chương trình Tin học lớp 11 nhằm trang bị cho học sinh một số khái niệm cơ bản
về lập trình và ngôn ngữ lập trình bậc cao. Trên cơ sở đó, nội dung Chương III – Cấu
trúc rẽ nhánh và lặp, cung cấp các cấu trúc điều khiển trong lập trình nói chung và các
câu lệnh thể hiện cấu trúc điều khiển cụ thể trong pascal nói riêng, nhờ đó học sinh có
thể bước đầu giải một số bài toán cơ bản. Để giúp học sinh hiểu rõ ý nghĩa và nội dung
của các cấu trúc điều khiển này, giáo viên nên hướng dẫn, gợi ý và tạo mọi cơ hội
cho học sinh tự giải những bài toán đơn giản. Từ lý do trên, tôi xin trình bày sáng
kiến kinh nghiệm “CÂU LỆNH LẶP TRONG PASCAL”.
II/ Mục đích của đề tài
- Hướng dẫn HS lập trình giải quyết các bài toán sử dụng cấu trúc lặp
- HS nhận thức sự cần thiết của việc sử dụng cấu trúc lặp để giải các bài toán. Từ đó
khơi gợi lòng ham thích giải toán bằng lập trình trên máy tính.
- Rèn luyện các phẩm chất: cẩn thận, chu đáo, sáng tạo….
III/ Đối tượng nghiên cứu
- Môn Tin học lớp 11
- Học sinh khối lớp 11 Trường THPT Số 2 Lào Cai
IV/ Phương pháp nghiên cứu
- Phỏng vấn học sinh khối 11.
- Kiểm tra việc học tập của học sinh (bài cũ, bài mới)
GV: Ph¹m Tè Loan
Lµo Cai
1
Trêng THPT Sè 2
C©u lÖnh lÆp trong Pascal
- Sử dụng bảng biểu đối chiếu.
- Thăm lớp, dự giờ.
- Kiểm tra chất lượng sau giờ học.
- Tận dụng tối đa các buổi học thực hành để các em được làm quen và luyện tập
thật tốt các bài học lý thuyết.
GV: Ph¹m Tè Loan
Lµo Cai
2
Trêng THPT Sè 2
C©u lÖnh lÆp trong Pascal
B. PHẦN NỘI DUNG
I/Câu lệnh lặp For
1. Câu lệnh FOR dạng 1:
a) Cú pháp, lưu đồ, cách thức hoạt động:
• Cú pháp:
FOR biến:= m1 TO m2 DO LệnhP;
• Yêu cầu:
biến phải thuộc kiểu dữ liệu đơn giản đếm được, thường là kiểu nguyên, ký tự
hay lô gic, không thể là kiểu thực hay chuỗi.
m1, m2 là các biểu thức có cùng kiểu dữ liệu với biến,
LệnhP có thể là một lệnh đơn giản, lệnh có cấu trúc, hoặc là một lệnh ghép
gồm nhiều lệnh đặt trong khối begin và end.
Hình 1 là sơ đồ khối của lệnh For với b là viết tắt của biến.
• Cách thức hoạt động của FOR:
Bước 1: Gán giá trị biến:= m1;
Bước 2: Nếu biến ≤ m2 thì làm LệnhP, rồi sang bước 3;
Nếu biến >m2 thì không làm LệnhP mà chuyển sang lệnh kế tiếp ở phía dưới.
Bước 3: Tăng gía trị của biến: biến:=Succ(biến);
Quay lại bước 2.
Tóm lại, LệnhP sẽ được làm đi làm lại, bắt đầu khi biến=m1, và kết thúc khi
biến =m2+1, cả thảy là m2-m1+1 lần. Vì thế, người ta gọi FOR là vòng lặp có
số lần lặp đã biết trước.
Hình 1: Sơ đồ câu lệnh For dạng 1
GV: Ph¹m Tè Loan
Lµo Cai
3
Trêng THPT Sè 2
C©u lÖnh lÆp trong Pascal
b) Các ví dụ cơ bản:
Ví dụ 1: Bài toán tính tổng:
Hãy tính tổng: S= 12 + 22+ 32+...+ 102
Thuật toán:
Bước 0: gán S:=0; { gán gía trị ban đầ? cho S}
Bước 1: gán S:=S+1*1; { được S=12 }
Bước 2: gán S:=S+2*2; { được S=12+22}
Bước 3: gán S:=S+3*3; { S=12+22+32}
.v.v.
Bước 10: gán S:=S+10*10; { được S=12+22+32+...+102}
Quá trình từ bước 1 đến bước 10 được gọi là phép cộng dồn vào biến S. Tại bước
thứ i, lấy gía trị của biến S cộng với i2, kết quả lại được gán cho biến S, do đó giá trị của
biến S được tăng thêm một lượng bằng i 2. Khi i thay đổi từ 1 đến 10 thì các số 1 2, 22,
32,..., 102 đều được cộng vào S, kết quả là sau bước thứ 10 gía trị của S đúng bằng tổng
12 + 22 + 32 +... + 102.
Tóm lại, lệnh: S:=S + i*i; được làm cả thảy 10 lầ?, ứng với i=1, 2,..., 10. Qúa trình
này được diễn đạt bằng lệnh FOR, như sau:
For i:=1 To 10 DO S:=S+ i*i ;
Một cách tổng quát, để tính tổng:S= 1 2 + 22+ 32+...+ N2, trong đó N là một số nguyên
dương bất kỳ, ta dùng hai lệnh:
S:=0;
For i:=1 To N DO S:=S+ i*i ;
Dưới đây là chương trình cụ thể:
PROGRAM VIDU1;
{ Tính tổng các bình phương các số tự nhiên <=N}
Var
N, i: Integer;
S: LongInt;
Begin
Write(‘ Nhập N:’); Readln(N);
S:=0;
For i:=1 to N do S:=S+i*i ;
Writeln(‘S= ‘, S);
Readln;
GV: Ph¹m Tè Loan
Lµo Cai
4
Trêng THPT Sè 2
C©u lÖnh lÆp trong Pascal
End.
Mở rộng bài toán tính tổng: Tính tổng đan dấu:
S = 12 - 22 + 32 - 42 +...+(-1)N-1 N2
Ta viết:
S = 12 + (- 22 ) + 32 + (- 42 ) +... +(-1)N-1 N2
Nhận thấy, số hạng thứ i của vế phải có gía trị tuyệt đối bằng i 2, mang dấu cộng nếu i
lẻ, mang dấu trừ nếu i chẵn. Nói cách khác, ta sẽ cộng dồn i 2 vào S nếu i lẻ, và cộng dồn
(- i2 ) vào S nếu i chẵn. Việc xác định i lẻ hay chẵn dựa vào hàm Odd(i) hay kết quả của
phép toán i Mod 2. Vậy, các lệnh sẽ dùng là:
S:=0;
For i:=1 To N DO
if i mod 2 <> 0 then S:=S+ i*i else S:= S- i*i ;
Ví dụ 2: Bài toán tính tích:
Tính S= 10!.
Ta viết S=1*2*3*...*10.
Thuật toán:
Bước 0: gán S:=1; { gán gía trị ban đầ? cho S}
Bước 1: gán S:=S*1; { được S=1 }
Bước 2: gán S:=S*2; { được S=1*2}
Bước 3: gán S:=S*3; { được S=1*2*3}
.v.v.
Bước 10: gán S:=S*10; { được S=1*2*3*...*10 =10!}
Nếu trong ví dụ 1, ta phải cộng dồn vào biến S thì trong ví dụ này ta phải nhân dồn
vào biến S. Tại bước thứ i, lấy giá trị của biến S nhân với i, rồi lại gán kết quả cho biến
S. Khi i thay đổi từ 1 đến 10 thì S sẽ tích lũy đủ các thừa số 1, 2, 3,...,10, và gía trị của S
sau bước thứ 10 đúng bằng 1*2*3*...*10 =10!.
Qúa trình thực hiện từ bước 1 đến bước thứ 10 được mô tả bằng câu lệnh For:
For i:=1 to 10 DO S:=S * i ;
Một cách tổng quát, để tính tích: S= 1*2*...*N, trong đó N là một số nguyên dương
bất kỳ, ta dùng hai lệnh:
S:=1;
GV: Ph¹m Tè Loan
Lµo Cai
5
Trêng THPT Sè 2
C©u lÖnh lÆp trong Pascal
For i:=1 To N DO S:=S* i ;
Dưới đây là chương trình cụ thể:
PROGRAM VIDU2;
{ Tính S=N! }
Var
N, i: Integer;
S: LongInt;
Begin
Write(‘Nhập số dương N: ‘); Readln(N);
S:=1;
For i:=1 to N do S:=S * i ;
Writeln(‘Giai thua = ‘, S);
Readln;
End.
Ví dụ 3: Bài toán tính lũy thừa:
Nhập số tự nhiên N và một số thực x bất kỳ, tính S= xN.
Tương tự như tính N!: đầu tiên ta gán S:=1, sau đó tại mỗi bước lặp, ta nhân dồn x
vào S bằng lệnh S:=S*x. Sau N bước như vậy, S sẽ được nhân với x đúng N lần. Vậy
hai lệnh cần dùng là:
S:=1;
For i:=1 TO N DO S:=S*x;
Dưới đây là chương trình cụ thể:
PROGRAM VIDU3;
{ Tính S=lũy thừa N của x }
Var
N, i: Byte ;
S, x: Real ;
Begin
Write(‘Nhập hai số x và N: ‘);
Readln( x, N);
S:=1;
For i:= 1 to N do S:= S * x ;
Writeln(‘Luy thua= ‘, S: 6:2);
Readln;
End.
Ví dụ 4: In bảng các chữ cái từ A đến Z thành bốn cột như sau:
KÝ TỰ MÃ KÝ TỰ MÃ
A
65
a
97
B
66
b
98
Yêu cầu in thành từng trang màn hình, mỗi trang 15 dòng.
GV: Ph¹m Tè Loan
Lµo Cai
6
Trêng THPT Sè 2
C©u lÖnh lÆp trong Pascal
Trong chương trình ta dùng biến Dem để đếm số dòng đã in, mỗi khi in xong một
dòng thì biến Dem được cộng thêm 1. Khi Dem = 15, 30, 45,... (tức Dem mod 15=0) thì
phải làm lệnh Readln; lệnh này sẽ dừng màn hình cho đến khi ta gõ Enter mới in tiếp.
PROGRAM VIDU4;
{ In bảng các chữ cái}
Uses Crt;
Var
ch, ch1: Char;
Dem: Integer;
Begin
CLRSCR;
Writeln(‘ KY TU MA KY TU MA’);
Dem:=0;
For ch:=‘a’ to ‘z’ do
begin
ch1:=Upcase(ch);
Writeln( ch1:3, Ord(ch1):6, ch:6, Ord(ch):6 );
Inc(Dem);
If Dem mod 15 = 0 then
begin
Write(‘ Enter để xem tiếp ‘);
Readln;
end;
end;
Writeln(‘ HET ‘);
Readln;
End.
Chương trình trên là một ví dụ về cách dùng biến chạy kiểu ký tự (ch) trong lệnh
FOR, ngoài ra, đóng vai trò LệnhP là một lệnh ghép, gồm nhiều lệnh đặt trong khối
begin và end.
2. Câu lệnh FOR dạng 2:
Cú pháp:
FOR biến:= m2 DOWNTO m1 DO LệnhP;
Cách thức hoạt động của FOR dạng 2:
Bước 1: gán gía trị biến:= m2;
Bước 2: Nếu biến ≥ m1 thì làm LệnhP, rồi sang bước 3.
Nếu biến
Bước 3: Giảm gía trị của biến: biến:=Pred(biến);
Quay lại bước 2.
Tóm lại, LệnhP sẽ được làm đi làm lại, bắt đầu khi biến=m2, và kết thúc khi
biến = m1-1, cả thảy là m2-m1+1 lần.
GV: Ph¹m Tè Loan
Lµo Cai
7
Trêng THPT Sè 2
C©u lÖnh lÆp trong Pascal
Hình 2: Sơ đồ câu lệnh FOR dạng 2
Ví dụ 5: Ðể tính S= N!, ta có thể viết:
S=N*(N-1)*(N-2)*...*2*1
Cách viết cho thấy ngay cách tính: đầu tiên gán S:=1, sau đó thực hiện việc nhân
dồn S:=S* i với i= N, N-1,..., 2, 1. Tức là:
S:=1;
For i:=N downto 1 do S:=S* i;
Tương tự, để tính S=xN, ta cũng có thể dùng FOR dạng 2:
S:=1;
For i:=N downto 1 do S:=S* x;
Như vậy, lệnh FOR dạng 2 về bản chất chỉ là một cách viết khác của dạng 1. Thông
thường người ta hay dùng lệnh FOR dạng 1, tuy nhiên có khá nhiều tình huống mà việc
dùng lệnh FOR dạng 2 tỏ ra rất hiệu quả, như ví dụ sau đây:
Ví dụ 6: In các chữ cái theo thứ tự ngược từ Z đến A thành hai dòng:
Z, Y, X,..., C, B, A
z, y, x,..., c, b, a
Chương trình được viết như sau:
PROGRAM VIDU96;
{ In các chữ cái theo thứ tự đảo ngược từ z đến a}
Var
Ch: Char;
Begin
For ch:=‘Z’ downto ‘A’ do write(ch:3 );
Writeln;
For ch:=‘z’ downto ‘a’ do write(ch:3 );
Writeln;
Readln;
End.
3. Câu lệnh FOR lồng nhau:
GV: Ph¹m Tè Loan
Lµo Cai
8
Trêng THPT Sè 2
C©u lÖnh lÆp trong Pascal
Trong cấu trúc FOR, khi LệnhP cũng là một lệnh FOR thì ta có cấu trúc FOR lồng nhau:
FOR biến1:= m1 TO m2 DO
{1}
FOR biến2:=n1 TO n2 DO LệnhP; {2}
Cách thức hoạt động của lệnh này như sau:
Ðầu tiên cho biến1:=m1 và làm lệnh ở dòng {2}. Vì dòng {2} là lệnh FOR
nên với mỗi gía trị của biến2=n1,..., n2, đều phải làm LệnhP, kết qủa là LệnhP được
làm n2- n1+1 lần.
Bây giờ tăng: biến1:=Succ(biến1), rồi lại làm lệnh FOR ở dòng {2}, kết quả
lệnhP được làm thêm n2-n1+1 lần nữa.
.v.v.v...
Quá trình trên cứ tiếp tục cho đến khi biến1=m2+1 thì dừng.
Lệnh FOR {1} làm m2-m1+1 lần lệnh FOR {2}, còn chính lệnh FOR {2} lại làm
n2-n1+1 lần LệnhP. Vì thế lệnhP được làm cả thảy là (m2-m1+1)*(n2-n1+1) lần.
Ví dụ 7: In hình chữ nhật đặc như dưới đây:
Ta thấy mỗi dòng gồm m chữ A, tức là chữ A được in liên tiếp cả thảy m lần, việc này
được làm bằng lệnh:
For j:=1 to m do write(‘A’);
Lệnh Write in m chữ A trên một dòng. In xong, con trỏ vẫn nằm ở cuối dòng đó, vì
thế trước khi in dòng tiếp theo, cần phải đưa con trỏ xuống dòng dưới bằng lệnh:
Writeln;
Tóm lại, muốn in dòng thứ i, cần phải làm hai lệnh:
For j:=1 to m do write(‘A’);
Writeln;
Cả thảy ta phải in n dòng như thế, tức là:
For i:=1 to n do In dòng i ;
GV: Ph¹m Tè Loan
Lµo Cai
9
Trêng THPT Sè 2
C©u lÖnh lÆp trong Pascal
Thay In dòng i bằng hai lệnh nói trên (đặt trong khối begin... end), ta có thuật toán để
in hình chữ nhật đặc là:
For i:=1 to n do
begin
for j:=1 to m do write(‘A’);
Writeln;
end;
Các bạn hãy viết chương trình cụ thể cho ví dụ này, ở đây m và n là hai số nguyên
dương nhập từ bàn phím.
4. Các ứng dụng khác của lệnh FOR:
Lệnh For rất thông dụng, dễ dùng và giải quyết được nhiều bài toán trong khoa học
kỹ thuật và trong thực tiễn. Dưới đây chỉ xin nêu hai ứng dụng.
Ví dụ 8: Tìm các số Fibonaci.
Dãy số Fibonaci { 1, 1, 2, 3, 5, 8, 13, 21,... } được nhắc nhiều trong giới khoa học kỹ
thuật, nó được xây dựng như sau:
U0=1, U1=1, Uk=Uk-1 + Uk-2 với mọi k= 2, 3, 4,...
Gọi U là số hạng thứ k, Uo và U1 lần lượt là hai số hạng đứng ngay trước U. Ðầu
tiên ta gán:
U0:=1;
U1:=1;
Bước 1: tính U:=U0+U1 và in U. Lúc này U=2 chính là U2.
Ðể chuẩn bị tính U3, ta cho U0 đóng vai trò của U1 và U1 đóng vai trò của U,
tức là gán:
U0:=U1;
U1:=U;
Kết qủa là U0=1 và U1=2.
Bước 2: tính U:=U0+U1 và in U. Lúc này U=3 chính là U3.
Ðể chuẩn bị tính U4, ta lại cho Uo đóng vai trò của U1 và U1 đóng vai trò của
U, tức là gán:
U0:=U1;
U1:=U;
Kết qủa là U0=2 và U1=3.
.v.v.
Tóm lại các lệnh phải lặp đi lặp lại là:
U:=U0+U1;
GV: Ph¹m Tè Loan
Lµo Cai
10
Trêng THPT Sè 2
C©u lÖnh lÆp trong Pascal
U0:=U1;
U1:=U;
Vì sang bước sau thì gía trị của U sẽ bị thay đổi nên tại mỗi bước ta đều phải in U.
chương trình được viết như sau:
PROGRAM VIDU8;
{ In N+1 số Fibonaci đầu tiên }
Var
N, i, U, U0, U1: Integer;
Begin
Write(‘ Nhập N:’);
Readln(N);
U0:=1;
U1:=1;
Writeln( N+1, ‘ số Fibonaci đầu tiên là:’ );
Write(U0:3, U1:3);
For i:=2 to N do
begin
U:=U0+U1;
Write(U:3);
U0:=U1;
U1:=U;
end;
Readln;
End.
Ví dụ 9: Bài toán tính tiền lãi gửi ngân hàng:
Nhập tiền vốn ban đầu, số tháng gửi N và lãi suất hàng tháng. Tính số tiền nhận được
sau mỗi tháng gửi biết rằng tiền lãi hàng tháng được gộp vào tiền vốn.
Ví dụ, tiền vốn là 100, lãi suất tháng là 2%. Sau 1 tháng gửi sẽ có số tiền là:
Số tiền=100 + 100*0.02 = 102
Sau 2 tháng gửi sẽ có số tiền là:
Số tiền=102 + 102*0.02 = 104.04
Công thức tính tiền thu được sau mỗi tháng gửi là:
Số tiền:= Tiền vốn + Tiền vốn * Lãi suất
Số tiền này lại trở thành tiền vốn của tháng sau, tức là:
Tiền vốn:= Số tiền;
Qúa trình cứ lặp đi lặp lại từ tháng 1 đến tháng N.
Chương trình cụ thể như sau:
PROGRAM VIDU99;
{ Tính tiền gửi ngân hàng sau N tháng}
Var
Tienvon, Laisuat, Sotien: Real;
N, i: Byte;
GV: Ph¹m Tè Loan
Lµo Cai
11
Trêng THPT Sè 2
C©u lÖnh lÆp trong Pascal
Begin
Write(‘ Nhập tiền vốn, lãi suất và số tháng gửi: ‘);
Readln(Tienvon, Laisuat, N);
For i:=1 to N do
begin
Sotien:= Tienvon + Tienvon*Laisuat;
Writeln(‘Số tiền sau ‘, i, ‘ tháng =‘, Sotien:8:2);
Tienvon:=Sotien;
end;
Readln;
End.
II/ Câu lệnh WHILE
1. Cú pháp, lưu đồ, cách thức hoạt động:
Cú pháp:
WHILE Ðiềukiện DO LệnhP ;
Ý nghĩa: Chừng nào Ðiềukiện còn đúng thì cứ làm LệnhP, cho đến khi Ðiềukiện
sai 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 WHILE:
Bước 1: Nếu Ðiềukiện sai thì chuyển ngay sang lệnh kế tiếp sau LệnhP, ngược lại,
nếu Ðiềukiện đúng thì làm LệnhP, rồi quay lại bước 1.
Hình 3: Sơ đồ của lệnh WHILE
Lệnh P được gọi là thân của vòng lặp WHILE.
Nếu Ðiềukiện không bao giờ sai 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, để dừng chương trình, hãy gõ đồng thời hai phím Ctrl và
Pause ( viết tắt là ^Pause).
Ðể tránh các vòng lặp vô hạn, trong thân của vòng WHILE 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ẽ sai và do đó vòng lặp sẽ kết thúc.
2. Các ví dụ về lệnh While:
GV: Ph¹m Tè Loan
Lµo Cai
12
Trêng THPT Sè 2
C©u lÖnh lÆp trong Pascal
Ví dụ 10: Nhập số tự nhiên N, dùng lệnh WHILE tính S=N!:
PROGRAM VIDU910;
{ Tinh S=N! bằng lệnh WHILE..}
Var
N, i: Integer;
S: LongInt;
Begin
Write(‘ Nhập N > 0: ‘ );
Readln(N);
S:=1;
i:=1;
{9}
While i<= N do
begin
S:=S*i;
i:=i+1;
{13}
end;
Writeln(‘ Giai thua = ‘, S);
Readln;
End.
Khởi đầu biến i được gán gía trị 1 (dòng {9}). Trong vòng lặp WHILE, sau mỗi lệnh
S:=S*i; biến i được tăng lên 1 đơn vị bằng lệnh i:=i+1; (dòng {13}). Khi i=N+1 thì điều
kiện i<=N bị sai và lúc đó vòng lặp kết thúc, kết qủa là lệnh S:=S*i; được thực hiện
đúng N lần ứng với i=1, 2, 3,..., N.
Trong chương trình trên, nếu không có dòng lệnh {13}: i:=i+1;
thì i luôn luôn bằng 1 nên điều kiện i<=N luôn luôn đúng (vì N ≥ 1), và do đó vòng lặp
sẽ vô hạn.
Sự khác nhau của lệnh WHILE so với FOR là ở chỗ: trong lệnh FOR, biến i được tự
động gán gía trị ban đầu và sau mỗi bước lặp được tự động tăng lên, còn trong WHILE
thì không, ta phải viết các lệnh đó.
Tất cả các bài toán giải quyết được bằng lệnh FOR thì đều giải quyết được bằng lệnh
WHILE. Ðặc điểm chung của các bài toán dạng này là số lần lặp của các vòng lặp đã
được biết trước.
Lệnh WHILE đặc biệt thích hợp với các vòng lặp có số lần lặp chưa biết trước, trong
khi lệnh FOR không giải quyết được. Ðây chính là điểm mạnh của lệnh WHILE. Hãy
xem ví dụ sau.
Ví dụ 11: Trở lại bài toán tính tiền gửi ngân hàng có tiền lãi hàng tháng gộp vào
vốn (ví dụ 9.9). Câu hỏi bây giờ là: cần gửi tối thiểu là bao nhiêu tháng để có được số
tiền? S cho trước.
GV: Ph¹m Tè Loan
Lµo Cai
13
Trêng THPT Sè 2
C©u lÖnh lÆp trong Pascal
Giả sử tiền vốn là 100, lãi suất hàng tháng là 2%, số tiền cần có là S=108. Ta tính số
tiền có được sau mỗi tháng gửi:
Sau 1 tháng gửi: Số tiền=100 + 100*0.02 = 102
Sau 2 tháng gửi: Số tiền=102 + 102*0.02 = 104.04
Sau 3 tháng gửi: Số tiền=104.04 + 104.04*0.02 = 106.1208
Sau 4 tháng gửi: Số tiền=106.1208 + 106.1208*0.02 = 108.2432
Vậy chỉ cần gửi N=4 tháng, số tiền sẽ có là 108.2431.
Qúa trình lặp kết thúc khi tới tháng đầu tiên có Số tiền ≥ S.
Chương trình như sau:
PROGRAM VIDU911;
{ Tính số tháng gửi ngân hàng để có số tiền S }
Var
Tienvon, Laisuat, Sotien, S: Real;
N: Byte;
Begin
Write(‘ Nhập tiền vốn, lãi suất và số tiền S cần có: ‘);
Readln(Tienvon, Laisuat, S);
Sotien:=Tienvon;
N:=0; { N là số tháng gửi }
While Sotien< S do
begin
N:=N+1;
Sotien:= Tienvon + Tienvon*Laisuat ;
Tienvon:=Sotien;
end;
Writeln(‘ Cần gửi ‘, N, ‘ tháng ‘);
Writeln(‘ Số tiền sẽ có = ‘, Sotien:6:2);
Readln;
End.
Số lần lặp của lệnh: While Sotien < S do... không phải do ta ấn định từ trước mà tùy
thuộc vào biểu thức Sotien < S là mau bị sai hay chậm bị sai. Số lần lặp ít hay nhiều phụ
thuộc vào gía trị S nhỏ hay lớn và vào tốc độ tăng nhanh hay chậm của số tiền.
III. Câu lệnh REPEAT
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.
GV: Ph¹m Tè Loan
Lµo Cai
14
Trêng THPT Sè 2
Hình 4: Sơ đồ của lệnh REPEAT
C©u lÖnh lÆp trong Pascal
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ệnh REPEAT 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ệ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
2. Các ví dụ về lệnh Repeat:
Ví dụ 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
Repeat
Write(‘ Nhập N (0
GV: Ph¹m Tè Loan
Lµo Cai
15
Trêng THPT Sè 2
C©u lÖnh lÆp trong Pascal
Readln(N);
If (N<=0) or (N>=20) then write(#7);
Until (0
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ụ 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ệnh repeat để 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.
Ví dụ 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) ?:’);
GV: Ph¹m Tè Loan
Lµo Cai
16
Trêng THPT Sè 2
C©u lÖnh lÆp trong Pascal
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
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
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ương trình 9.14 là 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 từ dòng {11} đến dòng {15}.
GV: Ph¹m Tè Loan
Lµo Cai
17
Trêng THPT Sè 2
C©u lÖnh lÆp trong Pascal
IV/ 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ệnh
Repeat thực hiện lệnhP rồi mới kiểm tra điều kiện. Vì thế, lệnh Repeat 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ệnh Repeat kết thúc khi điều kiện đúng.
V/ Một số bài toán
Bài 1
Năm nay con a tuổi, cha b tuổi. Dùng WHILE tính xem sau mấy năm nữa hoặc
trước đây mấy năm tuổi cha gấp đôi tuổi con
Hướng dẫn Nếu a*2=b thì ở hiện tại
Nếu a*2
Nếu a*2>b thì ở trong quá khứ
Chương trình cụ thể:
VAR a,b,so:integer;{a,b,so kiểu integer}
BEGIN
write('Nhap tuoi con, tuoi cha : ');
readln(a,b);{Nhập tuổi con, tuổi cha}
if a=b*2 then write('Hien tai tuoi cha gap doi con'){Nếu a=b thì ở hiện
tại}
else if a*2
begin
so:=0;{Gán so bằng 0}
while (a+so)*2
writeln('Sau ',so,' nam nua tuoi cha gap doi tuoi con');
end
else
begin
so:=0;{Gán so bằng 0}
while (a-so)*2>b-so do inc(so);{Trong khi (a-so)*2
writeln('Truoc day ',so,' nam tuoi cha gap doi tuoi con');
end;
readln;
END.
Bài 2:
Nhập số nguyên dương N (N<10). a. In ra màn hình các chỉnh hợp lặp chập 3 của
N phần tử b. In ra màn hình các chỉnh hợp không lặp chập 3 của N phần tử. c. In ra màn
hình các tổ hợp chập 3 của N.
Hướng dẫn
Chỉnh hợp lặp :
i=1->N j=1->N k=1->N : Xuất i,j,k
GV: Ph¹m Tè Loan
Lµo Cai
18
Trêng THPT Sè 2
C©u lÖnh lÆp trong Pascal
Chỉnh hợp không lặp :
i=1->N j=1->N k=1->N :
Nếu i<>j<>k thì xuất
Tổ hợp
i=1->N-2 j=i+1->N-1 k=j+1->N : Xuất i,j,k}
Chương trình cụ thể:
VAR
i,j,k,n:byte;{i,j,k,n kiểu byte}
BEGIN
write('N = ');readln(n);{Đọc N}
writeln('Cac chinh hop lap :');
for i:=1 to n do{Cho i chạy từ 1 đến N}
for j:=1 to n do{Cho j chạy từ 1 đến N}
for k:=1 to n do{Cho k chạy từ 1 đến N}
write(i,j,k,' ');
readln;
writeln('Cac chinh hop khong lap :');
for i:=1 to n do{Cho i chạy từ 1 đến N}
for j:=1 to n do{Cho j chạy từ 1 đến N}
for k:=1 to n do{Cho k chạy từ 1 đến N}
if(i<>j)and(j<>k)and(i<>k)then write(i,j,k,' ');
readln;
writeln('Cac to hop :');
for i:=1 to n-2 do{Cho i chạy từ 1 đến N-2}
for j:=i+1 to n-1 do{Cho j chạy từ i+1 đến N-1}
for k:=j+1 to n do{Cho k chạy từ j+1 đến N}
write(i,j,k,' ');
readln;
END.
Bài 3:
In ra màn hình bảng cửu chương từ 1->10
Hướng dẫn
Dùng hàm GOTOXY(x,y) để di chuyển tới toạ độ cột x dòng y trên màn hình
Ta chia chiều ngang màn hình thành 5 cột, chiều dọc màn hình thành 2 hàng. Từ hàng
2..11 ta in bảng 1,2,3,4,5. Từ hàng 13..22 ta in bảng 6,7,8,9,10
Khi ta tới hàng i x j thì toạ độ bắt đầu sẽ là
y = j+1 nếu i<6
= j+12 nếu i>=6
x = ((i-1)mod 5)*16+1;}
Chương trình cụ thể:
USES crt;
VAR
i,j,x,y:byte;{i,j,x,y kiểu byte}
BEGIN
clrscr;{Xoá màn hình}
for i:=1 to 10 do{Cho i chạy từ 1 đến 10 (i là bảng)}
for j:=1 to 10 do{Cho j chạy từ 1 đến 10}
begin
if i<6 then y:=j+1 else y:=j+12;{Tính y theo CT ở phần thuật
toán}
x:=((i-1)mod 5)*16+1;{Tính x theo CT ở phần thuật toán}
gotoxy(x,y);{Nhảy tới vị trí x,y}
GV: Ph¹m Tè Loan
Lµo Cai
19
Trêng THPT Sè 2
C©u lÖnh lÆp trong Pascal
write(i,' x ',j,' = ',i*j);
end;
readln;
END.
Bài 4:
Viết chương trình giải bài toán : Trăm trâu, trăm bó cỏ Trâu đứng ăn năm Trâu
nằm ăn ba Lụ khụ trâu già 3 con 1 bó. Hỏi mỗi loại có mấy con?.
Hướng dẫn Điều kiện trên thoả khi : 100 = (std*5+stn*3+stg3)và std+stn+stg3*3=100
Trong đó
std : Số trâu đứng <=20
stn : Số trâu nằm <=33
stg3 : Số bó cỏ trâu già ăn<=33
Chương trình
VAR
std,stn,stg3:byte;
BEGIN
clrscr;
for std:=1 to 20 do{Cho std chạy từ 1 đến 20}
for stn:=1 to 33 do{Cho stn chạy từ 1 đến 33}
for stg3:=1 to 33 do{Cho stg3 chạy từ 1 đến 33}
if(std*5+stn*3+stg3=100)and(std+stn+stg3*3=100)then{Nếu
thoả}
begin
writeln('So trau dung : ',std);{Xuất std}
writeln('So trau nam : ',stn);{Xuất stn}
writeln('So trau gia : ',stg3*3);{Xuất stg}
writeln;
end;
readln;
END.
Bài 5:
ĐK
đề
bài
Tìm tất cả các số có 3 chữ số sao cho abc = A^3 + B^3 + C^3}
Chương trình
VAR
a,b,c:byte;{a,b,c kiểu byte}
BEGIN
writeln('Cac so can tim la : ');
for a:=1 to 9 do{Cho a chạy}
for b:=0 to 9 do{Cho b chạy}
for c:=0 to 9 do{Cho c chạy}
if a*100+b*10+c=a*a*a+b*b*b+c*c*c then writeln(a,b,c);{Nếu ĐK thoả
thì xuất a,b,c}
readln;
END.
Bài 6:
Nhập số nguyên N. a. In ra màn hình N số nguyên dương lẻ đầu tiên là bội của 3
b. In ra màn hình số nguyên chẵn đầu tiên chia hết cho 3 dư 2, chia 5 dư 4
c. In ra màn hình các số chính phương nhỏ hơn hoặc bằng N*N
Hướng dẫn
a. Dễ thấy dãy là cấp số cộng. Số nguyên đầu tiên là 3, công sai là 6
Số nguyên dương lẻ thứ i là bội của 3
3+(i-1)*6
b. Dãy là cấp số cộng. Số nguyên đầu tiên là 14, công sai là 3*5*2=30. Số thứ i sẽ có công
thức
14+(i-1)*30;
GV: Ph¹m Tè Loan
Lµo Cai
20
Trêng THPT Sè 2
C©u lÖnh lÆp trong Pascal
c. Dễ dàng nhận ra đó là những số i*i(i<=N)}
Chương trình
VAR
i,n:integer;
{Khai báo i,n kiểu integer}
BEGIN
write('N = ');readln(n);{Đọc N} writeln('Cau a');
for i:=1 to n do write(3+(i-1)*6:5);{Cho i chạy và in ra n phần
tử theo CT ở thuật toán}
writeln;
writeln('Cau b');
for i:=1 to n do write(14+(i-1)*30:5);{Cho i chạy và in ra n phần tử
theo CT ở thuật toán}
writeln;writeln('Cau c');
for i:=1 to n do write(i*i:5);{Cho i chạy và in ra n phần tử theo
CT ở thuật toán}
readln;
END.
Bài 7: Tìm các số tự nhiên nhỏ hơn 1000 sao cho nó bằng tổng các ước của nó (không
kể chính nó)
Hướng dẫn
Cho i chạy từ 2 đến 1000
- Tính tổng các ước của i
- Nếu tổng = i thì xuất i
Chương trình
VAR
i,j,tong:integer;{i,j,tong kiểu integer}
BEGIN
writeln('Cac so can tim');
for i:=2 to 1000 do{Cho i chạy từ 2 đến 1000}
begin
tong:=0;{Gán tong bằng 0}
for j:=1 to i div 2 do{Cho j chạy từ 1 đến i div 2}
if i mod j=0 then tong:=tong+j;{Nếu i chia hết cho j thì cộng j vào
tong}
if tong=i then writeln(i);{Nếu tong=i thì xuất i}
end;
readln;
END.
Bài 8:
Nhập số N. Kiểm tra N xem nó có phải là số nguyên tố không?
Hướng dẫn
Cho i chạy từ 2 đến trunc(sqrt(n)). - Nếu trong lúc chạy N mod i=0 thì N không nguyên
tố - Ngược lại N nguyên tố
Chương trình
VAR
i,n:integer;{i,n kiểu integer}
kq:boolean;{kq kiểu boolean}
BEGIN
write('N = ');readln(n);{Đọc N}
kq:=true;{Gán kq bằng true}
for i:=2 to trunc(sqrt(n))do{Cho i chạy từ 2 đến trunc(sqrt(N))}
if n mod i=0 then{Nếu n chia hết cho i thì}
begin
kq:=false;{Gán kq=false}
break;{Bẻ gãy vòng lặp bằng lệnh Break}
end;
GV: Ph¹m Tè Loan
Lµo Cai
21
Trêng THPT Sè 2
C©u lÖnh lÆp trong Pascal
if kq then writeln('So nguyen to')else write('Khong la so nguyen
to');{Nếu kq thì N là số nguyên tố ngược lại thì không}
readln;
END.
GV: Ph¹m Tè Loan
Lµo Cai
22
Trêng THPT Sè 2