Cú pháp:
FOR biến := m1 TO m2 DO LệnhP;
Yêu cầu:
biếnphả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, m2là 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.
25 trang |
Chia sẻ: maiphuongdc | Lượt xem: 8203 | Lượt tải: 1
Bạn đang xem trước 20 trang tài liệu Pascal - Câu lệnh lặp for, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
CÂU LỆNH LẶP FOR
9.1.1. Câu lệnh FOR dạng 1:
9.1.1.1. 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 9.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.
9.1.1.2. Các ví dụ cơ bản :
Ví dụ 9.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}
Qúa 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 qủa lại được gán cho
biến S, do đó gía trị của biến S được tăng thêm một lượng bằ?g i2. Khi i thay
đổi từ 1 đến 10 thì các số 12, 22, 32, ..., 102 đều được cộng vào S, kết qủa 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ằ?g lệ?h 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= 12 + 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 VIDU91;
{ 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;
End.
Chạy
Chép file nguồn
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 i2 , 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 i2
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 qủa 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 ;
Các bạn hãy viết chương trình để tính tổng đan dấu này.
Ví dụ 9.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 gía trị của biến S nhân với i, rồi lại
gán kết qủa 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;
For i:=1 To N DO S:=S* i ;
Dưới đây là chương trình cụ thể :
PROGRAM VIDU92;
{ 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.
Chạy
Chép file nguồn
Ví dụ 9.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 VIDU93;
{ 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.
Chạy
Chép file nguồn
Ví dụ 9.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.
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 VIDU94;
{ 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ạy
Chép file nguồn
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.
9.1.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<m1 thì không làm LệnhP mà chuyển sang lệnh kế tiếp ở
phía dưới.
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.
Ví dụ 9.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 qủa, như ví
dụ sau đây:
Ví dụ 9.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.
Chạy
Chép file nguồn
9.1.3. Câu lệnh FOR lồng nhau :
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 qủa lệnhP được làm thêm n2-n1+1 lần nữa.
.v.v.
Qúa 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ụ 9.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 ;
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.
9.1.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ụ 9.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:
Uo:=1;
U1:=1;
Bước 1: tính U:=Uo+U1 và in U. Lúc này U=2 chính là U2 .
Ðể chuẩn bị tính U3, ta cho Uo đóng vai trò của U1 và U1 đóng
vai trò của U, tức là gán:
Uo:=U1;
U1:=U;
Kết qủa là Uo=1 và U1=2.
Bước 2: tính U:=Uo+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:
Uo:=U1;
U1:=U;
Kết qủa là Uo=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:=Uo+U1;
Uo:=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 VIDU98;
{ In N+1 số Fibonaci đầu tiên }
Var
N, i, U, Uo, U1 : Integer;
Begin
Write(‘ Nhập N :’);
Readln(N);
Uo:=1;
U1:=1;
Writeln( N+1 , ‘ số Fibonaci đầu tiên là :’ );
Write(Uo:3 , U1:3);
For i :=2 to N do
begin
U:=Uo+U1;
Write(U:3);
Uo:=U1;
U1:=U;
end;
Readln;
End.
Chạy
Chép file nguồn
Ví dụ 9.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;
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.
Chạy
Chép file nguồn
Các file đính kèm theo tài liệu này:
- cau_lenh_lap_for_5166.pdf