Tải bản đầy đủ (.docx) (35 trang)

SÁNG KIẾN Rèn luyện kĩ năng sử dụng cấu trúc lặp trong lập trình Pascal cho học sinh lớp 11”

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (4.62 MB, 35 trang )

SỞ GIÁO DỤC VÀ ĐÀO TẠO VĨNH PHÚC
TRƯỜNG THPT YÊN LẠC 2
-----     -----

BÁO CÁO KẾT QUẢ
NGHIÊN CỨU, ỨNG DỤNG SÁNG KIẾN

Tên sáng kiến:
RÈN LUYỆN KĨ NĂNG SỬ DỤNG CẤU TRÚC LẶP TRONG
LẬP TRÌNH PASCAL CHO HỌC SINH LỚP 11

Tác giả sáng kiến: NGUYỄN THỊ NỤ
Mã sáng kiến: 28.62.02

Vĩnh Phúc, năm 2020
Trang


DANH MỤC CÁC CHỮ VIẾT TẮT
1.
2.
3.
4.
5.
6.

THPT: Trung học phổ thông
HSG: Học sinh giỏi
HS: Học sinh
SKKN: Sáng kiến kinh nghiệm
NXB: Nhà xuất bản


SGK: Sách giáo khoa

Trang


MỤC LỤC
1. LỜI GIỚI THIỆU........................................................................................................1
2. TÊN SÁNG KIẾN.......................................................................................................1
3. TÁC GIẢ SÁNG KIẾN..............................................................................................1
4. CHỦ ĐẦU TƯ SÁNG TẠO RA SÁNG KIẾN...........................................................1
5. LĨNH VỰC ÁP DỤNG SÁNG KIẾN.........................................................................1
6. NGÀY SÁNG KIẾN ĐƯỢC ÁP DỤNG.....................................................................1
7. MÔ TẢ BẢN CHẤT CỦA SÁNG KIẾN....................................................................1
7.1. Tổng quan các vấn đề nghiên cứu..........................................................................2
7.1.1.

Mục đích nghiên cứu......................................................................................2

7.1.2.

Bản chất đối tượng nghiên cứu.......................................................................2

7.1.3.

Đối tượng, phạm vi nghiên cứu......................................................................2

7.1.4.

Phương pháp nghiên cứu................................................................................2


7.1.5.

Giới hạn về không gian của phương pháp nghiên cứu....................................2

7.2. Phần nội dung.........................................................................................................3
7.2.1.

Cơ sở lý luận..................................................................................................3

7.2.2.

Cơ sở thực tiễn...............................................................................................3

7.2.3.

Nội dung cụ thể..............................................................................................3

I.

Lặp.................................................................................................................3

II.

Lặp với số lần biết trước và câu lệnh FOR – DO...........................................4
1.

Cú pháp và hoạt động của câu lệnh For – do..............................................4

2.


Một số ví dụ................................................................................................6

III. Lặp với số lần chưa biết trước......................................................................16
1.

2.
IV.

Cú pháp và hoạt động của lệnh lặp với số lần chưa biết trước..................16
a.

Câu lệnh While – do..............................................................................16

b.

Câu lệnh lặp repeat_until.......................................................................16
Một số ví dụ..............................................................................................18
Bài tập áp dụng.........................................................................................23

7.3. Khả năng áp dụng của sáng kiến..........................................................................24
8. NHỮNG THÔNG TIN CẦN BẢO MẬT..................................................................24
9. CÁC ĐIỀU KIỆN CẦN THIẾT ĐỂ ÁP DỤNG SÁNG KIẾN..................................24
10. LỢI ÍCH THU ĐƯỢC...............................................................................................24
11. DANH SÁCH TỔ CHỨC, CÁ NHÂN ĐÃ THAM GIA ÁP DỤNG SÁNG KIẾN. .29
KẾT LUẬN...................................................................................................................... 30
TÀI LIỆU THAM KHẢO................................................................................................31
Trang


Trang



BÁO CÁO KẾT QUẢ
NGHIÊN CỨU, ỨNG DỤNG SÁNG KIẾN
1. LỜI GIỚI THIỆU
Một trong những yếu tố quan trọng và không thể thiếu của một trương trình là “việc
điều khiển”, cụ thể là các cấu trúc điều khiển, cũng là thành tố kết hợp đồng thời giữa
dữ liệu và tác vụ. Cấu trúc điều khiển là một trong các đặc trưng cơ bản của phương
pháp lập trình cấu trúc. Trong đó người ta sử dụng ba cấu trúc điều khiển để tạo nên
logic của chương trình. Mọi vấn đề về logic đều được giải quyết bằng cách sử dụng
linh hoạt ba cấu trúc điều khiển là:
 Cấu trúc tuần tự
 Cấu trúc rẽ nhánh
 Cấu trúc lặp
Trong chương trình tin học lớp 11, các em học sinh đã được làm quen với lập trình có
cấu trúc trong đó có cấu trúc lặp nhưng trong quá trình học tập và rèn luyện học sinh
vẫn gặp phải một số khó khăn trong lập trình, chưa biết cách tối ưu hóa thuật toán,
thậm chí còn mắc sai lầm khi lập trình giải các bài toán có sử dụng cấu trúc lặp. Vì
những lý do trên tôi chọn đề tài “Rèn luyện kĩ năng sử dụng cấu trúc lặp trong lập
trình Pascal cho học sinh lớp 11” nhằm cung cấp cho học sinh những kiến thức khái
quát hơn về cấu trúc lặp và rèn luyện kỹ năng lập trình cho học sinh thông qua một số
bài toán cụ thể.
2. TÊN SÁNG KIẾN
“Rèn luyện kĩ năng sử dụng cấu trúc lặp trong lập trình Pascal cho học sinh lớp
11”
3. TÁC GIẢ SÁNG KIẾN
-

Họ tên: Nguyễn Thị Nụ


-

Địa chỉ: Trường THPT Yên Lạc 2 – Huyện Yên Lạc – Tỉnh Vĩnh Phúc

-

Số điện thoại: 0965170380

-

E_mail:

4. CHỦ ĐẦU TƯ SÁNG TẠO RA SÁNG KIẾN
-

Họ tên: Nguyễn Thị Nụ

-

Trình độ chuyên môn: Cử nhân Tin Học

-

Đơn vị công tác: Trường THPT Yên Lạc 2 – Huyện Yên Lạc – Tỉnh Vĩnh Phúc

5. LĨNH VỰC ÁP DỤNG SÁNG KIẾN
Trang


Rèn luyện kĩ năng sử dụng cấu trúc lặp trong lập trình Pascal giảng dạy môn Tin

học lớp 11 và bồi dưỡng học sinh tham gia kì thi chọn học sinh giỏi các cấp môn Tin
học.
6. NGÀY SÁNG KIẾN ĐƯỢC ÁP DỤNG
Từ ngày 01/08/2019
7. MÔ TẢ BẢN CHẤT CỦA SÁNG KIẾN
7.1. Tổng quan các vấn đề nghiên cứu
7.1.1. Mục đích nghiên cứu
Góp phần đổi mới phương pháp dạy học sinh giỏi môn Tin học theo hướng phát
huy tính tích cực, chủ động và sáng tạo của học sinh giúp học sinh tiếp thu tri thức một
cách có hiệu quả.
Góp phần gây hứng thú học tập môn Tin học cho học sinh tham gia thi chọn học
sinh giỏi, tránh việc học thụ động, học vẹt. Giúp học sinh lĩnh hội tri thức một cách
khoa học, củng cố và khắc sâu kiến thức.
Qua đề tài này tôi mong muốn cung cấp cho học sinh một những vấn đề mà các
em đang gặp phải về kĩ năng sử dụng cấu trúc lặp trong khi lập trình giúp các em chủ
động hơn trong học tập, tích luỹ kiến thức, kỹ năng lập trình.
7.1.2. Bản chất đối tượng nghiên cứu
Đưa ra hệ thống lý thuyết về cấu trúc lặp và ứng dụng cấu trúc lặp giải các bài
tập trong ngôn ngữ lập trình Pascal giúp học sinh lĩnh hội tri thức, giúp các em tích
cực, chủ động tích lũy kiến thức. Qua đó, học sinh phát triển được tư duy logic thông
qua hệ thống bài tập giúp các em rèn luyện được tính tự giác, tính kỉ luật, thói quen tự
học đó là những đức tính rèn luyện tốt của học sinh.
7.1.3. Đối tượng, phạm vi nghiên cứu
-

Đối tượng: Cấu trúc lặp trong lập trình

-

Phạm vi: Các vấn đề về cấu trúc lặp trong chương trình tin học lập trình trên ngôn

ngữ Pascal.

7.1.4. Phương pháp nghiên cứu
Phương pháp
Nghiên cứu lí luận chung.
Khảo sát điều tra thực tế dạy học.
Tổng hợp đúc rút kinh nghiệm.
Cách thực hiện
Trao đổi với đồng nghiệp, tham khảo ý kiến giáo viên cùng bộ môn. Liên hệ thực
tế trong nhà trường, áp dụng và đúc rút kinh nghiệm qua quá trình giảng dạy. Thông
Trang


qua việc giảng dạy trực tiếp học sinh lớp 11 và học sinh tham gia thi chọn học sinh
giỏi môn Tin học khối 10 tại trường THPT Yên Lạc 2 năm học 2019 -2020.
7.1.5. Giới hạn về không gian của phương pháp nghiên cứu
Đề tài được đề cập với đồng nghiệp và thực nghiệm sư phạm qua các em học
sinh lớp 11A2 và các em học sinh tham gia dự kì thi chọn học sinh giỏi môn Tin học
lớp 10 năm học 2019-2020
7.1.6. Phạm vi nghiên cứu
Tôi đã nghiên cứu đề tài này trong suốt quá trình giảng dạy và thực nghiệm đề tài
này trong năm học 2019-2020.
7.2.

Phần nội dung

7.2.1. Cơ sở lý luận
Cấu trúc lặp là là một trong ba cấu trúc cơ bản trong lập trình có cấu trúc. Tuy
nhiên trước một bài toán lập trình tin học có các thao tác lặp đi lặp lại nhiều học sinh
thường lúng túng, không biết nên lựa chọn và sử dụng câu lệnh lặp nào cho phù hợp

với yêu cầu bài toán và tối ưu hóa thuật toán? Một số học sinh khá, giỏi có thể sử dụng
cấu trúc lặp để mô tả nhưng đa số chưa biết tối ưu hóa thuật toán để giảm số lần lặp và
điều đó gây tâm lý chán nản cho các em. Với tình hình ấy để giúp học sinh có kĩ năng
tốt hơn trong việc sử dụng cấu trúc lặp để mô tả thuật toán, thì người giáo viên cần
tăng cường rèn luyện cho học sinh kĩ năng sử dụng cấu trúc lặp từ các các bài toán cơ
bản quen thuộc mà các em đã biết, khai thác các yếu tố đặc trưng của một số bài toán
cơ bản để tìm thuật toán cho các bài toán mới, dựa vào đặc điểm cụ thể của từng bài
toán để tối ưu hóa thuật toán. Việc rèn luyện kĩ năng lập trình cho học sinh từ những
bài toán cơ bản để xây dựng thuật toán cho các bài toán tương tự hoặc các bài toán mở
rộng từ các bài toán cơ bản đó là một quá trình giúp học sinh rèn luyện kỹ năng lập
trình.
7.2.2. Cơ sở thực tiễn
Trường THPT Yên lạc 2 là ngôi trường ở vùng nông thôn nằm dưới chân đê dải
sông Hồng nên đa số học sinh chưa có cơ hội, điều kiện tiếp xúc với công nghệ và máy
tính. Vì vậy, tin học là một môn học tương đối lạ lẫm và khó đối với học sinh trường
tôi. Đặc biệt là chương trình tin học 11, với các em học lập trình còn khó hơn học toán,
lí, hóa, .. vì điều kiện cơ sở vật chất của trường còn nhiều khó khăn, học sinh chỉ học
chính khóa trên lớp về nhà lại không có máy tính để thực hành. Điều này dẫn đến ý
thức tự giác của học sinh chưa cao, đặc biệt là các em học để thi học sinh giỏi lại càng
khó. Với đội tuyển học sinh giỏi 10, hầu hết các em đều chưa có bất kì kiến thức cơ
bản nào liên quan đến lập trình, gia đình chưa có máy tính để các em thực hành. Vì
vậy giáo viên dạy đội tuyển phải bắt đầu rèn luyện cho các em từ những câu lệnh cơ
bản nhất. Cơ sở trên đã giúp tôi áp dụng đề tài rèn luyện kĩ năng sử dụng cấu trúc lặp
trong lập trình Pascal giảng dạy cho học sinh khối 11 và áp dụng cho học sinh tham dự
kì thi chọn học sinh giỏi Tin học 10 tại trường THPT Yên Lạc 2.
Trang


7.2.3. Nội dung cụ thể
Tất cả các nội dung, các ví dụ, bài tập trong đề tài này được xây dựng trên ngôn

ngữ lập trình Pascal
I. Lặp
Xét 2 bài toán sau đây:
Bài toán 1: Tính và đưa kết quả ra màn hình tổng
S = 1+2+3+…+100
Bài toán 2: Tính và đưa kết quả ra màn hình tổng
S = 1+2+3+..+n+… cho đến khi S > 105
Với cả 2 bài toán trên, dễ thấy cách để tính tổng S có nhiều điểm tương tự:
 Xuất phát, S được gán giá trị 0;
 Tiếp theo công vào tổng S một giá trị i với i = 1,2,3,4,5,….
Việc cộng này được lặp lại một số lần.
Đối với bài toán 1, số lần lặp là 100 và việc cộng vào tổng S sẽ kết thúc khi thực
hiện cồn việc 100 lần.
Đối với bài toán 2, số lần lặp chưa biết trước nhưng việc cộng vào tổng S sẽ kết
thúc khi điều kiện S > 105 được thỏa mãn.
Nói chung, ta thấy trong một số thuật toán có những thao tác phải lặp đi lặp lại
nhiều lần. Cấu trúc lặp mô tả thao tác lặp được phân biệt 2 loại là lặp với số lần biết
trước và lặp với số lần chưa biết trước.
Các ngôn ngữ lập trình đều có các câu lệnh để mô tả cấu trúc lặp.
II. Lặp với số lần biết trước và câu lệnh FOR – DO
1. Cú pháp và hoạt động của câu lệnh For – do
Có 2 thuật toán tong1a và tong1b để giải bài toán 1 như sau:
Thuật toán tong1a
Bước 1: S ← 0; i ← 0;
Bước 2: i ← i+1;
Bước 3: Nếu i < 1 thì chuyển đến bước 5;
Bước 4: S ← S+i rồi quay lại bước 2;
Bước 5: Đưa S ra màn hình rồi kết thúc.
Thuật toán tong1b
Bước 1: S ← 0; i ← 101;

Bước 2: i ← i-1;
Bước 3: Nếu i > 100 thì chuyển đến bước 5;
Bước 4: S ← S+i rồi quay lại bước 2;
Trang


Bước 5: Đưa S ra màn hình rồi kết thúc.
Trong thuật toán tong1a, giá trị i khi bắt đầu tham gia vòng lặp là 1 và sau mỗi lần lặp i
tăng lên 1 đơn vị cho đến khi i > 100 thì kết thúc lặp (thực hiện 100 lần). Trong thuật
toán tong1b giá trị i khi bắt đầu tham gia vòng lặp là 100 và sau mỗi lần lặp giảm đi 1
cho đến khi i < 1 thì kết thúc lặp (thực hiện 100 lần). Cách lặp trong thuật toán tong1a
gọi là dạng lặp tiến và trong thuật toán tong1b là dạng lặp lùi.
Trong Pascal, cấu trúc lặp với số lần biết trước ứng với 2 dạng lặp tiến và lặp lùi được
mô tả với cú pháp như sau:
 Dạng lặp tiến:
For <biến đếm> := <giá trị đầu> to <giá trị cuối> do <câu lệnh>;
Dạng lùi:
For <biến đếm> := <giá trị cuối> downto <giá trị đầu> do <câu lệnh>;
Trong đó:
+ Biến đếm là biến đơn thường có kiểu nguyên hoặc kiểu kí tự;
+ <giá trị đầu>, <giá trị cuối> là các biểu thức cùng kiểu với biến đếm, đầu> phải nhỏ hơn hoặc bằng <giá trị cuối>. Nếu <giá trị đầu> lớn hơn cuối> thì vòng lặp không được thực hiện.
Hoạt động:
+ Ở dạng lặp tiến: câu lệnh viết sau từ khóa do được thực hiện tuần tự, với biến đếm
lần lượt nhận các giá trị liên tiếp tăng từ <giá trị đầu> đến <giá trị cuối>;
+ Ở dạng lặp lùi: câu lệnh viết sau từ khóa do được thực hiện tuần tự, với biến đếm lần
lượt nhận các giá trị lien tiếp giảm từ <giá trị cuối> đến <giá trị đầu>.
Chú ý:
+ Giá trị biến đếm được điều khiển tự động vì vậy câu lệnh sau do không được thay

đổi giá trị biến đếm;
+ Không giống với các ngôn ngữ khác pascal không kiểm tra <biến đếm> > cuối> trong câu lệnh for –to-do để kết thúc vòng lặp mà kiểm tra <biến đếm> = trị cuối> để thực hiện lần lặp cuối cùng. Vì lẽ đó việc can thiệp vào biến đếm có thể
gây ra sự cố “vòng lặp vô tận”. Ngay cả khi biến đã duyệt hết phạm vi của kiể dữ liệu
thì biến lại quay lại giá trị 0 và mọi thứ lại tiếp tục… trừ khi gõ CTRL+ Break;
+ Trong câu lệnh for <giá trị cuối> , <giá trị đầu> được tính từ khi bắt đầu vòng lặp
để tính số lần lặp, nên trong vòng lặp dù có câu lệnh thay đổi <giá trị cuối> , đầu> thì số lần lặp vẫn không thay đổi.
Sử dụng cấu trúc lặp dạng tiến và dạng lùi như trên để mô tả quá trình lặp trong thuật
toán tong1a và tong1b chương trình có thể được cài đặt như sau:
Program tong1a;
Trang


Var S, i: longint;
Begin
S:=0;
For i:= 1 to 100 do
S:= S+i;
Write (‘Tong S la: ‘, S);
Readln;
End.

Program tong1b;
Var S, i: longint;
Begin
S:=0;
For i:= 100 downto 1 do
S:= S+i;

Write (‘Tong S la: ‘, S);
Readln;
End.
2. Một số ví dụ
Ví dụ 1:
Viết chương trình in ra các số lẻ nhỏ hơn hoặc bằng n (0<=n<=106).
a. Ý tưởng
- Sử dụng vòng lặp tiến với biến đếm i chạy từ đến n để duyệt lần lượt các số từ 1 đến
n;
- Nếu i lẻ ( i mod 1 <> 0) thì in ra số i.
b. Code tham khảo
Program In_So_le;
Uses crt;
var i,n: longint;
Begin
Clrscr;
Trang


Write('Nhap so n ='); readln(n);
For i:=1 to n do
if i mod 2 <>0 then Write(i,', ');
readln
end.
Ví dụ 2:
Viết chương trình đếm xem có bao nhiêu số lẻ trong đoạn từ 20 đến 100.
a. Ý tưởng
- Dùng 1 biến đếm kiểu nguyên (dem) để đếm số lượng số lẻ. Ban đầu khởi tạo
dem:=0;
- Sử dụng vòng lặp for tiến với biến đếm i chạy từ 20 đến 100 ( vì xét trong đoạn từ 20

đến 100 ( KH:[20,100] nên ta phải xét cả 2 đầu mút: i=20 và i=100)
- Nếu i lẻ ( i mod 2 <> 0) thì tăng biến đếm dem lên 1 đơn vị.
b. Code tham khảo
Program dem_So_le;
Uses crt;
var i, dem: integer;
Begin
Clrscr;
dem:=0;
For i:=20 to 100 do
if i mod 2 <>0 then inc(dem);
write(‘Co ‘,dem,’ so le trong doan tu 20 den 100’);
readln
end.
Ví dụ 3:
Viết chương trình đếm xem có bao nhiêu số chẵn, bao nhiêu số lẻ trong khoảng từ
n đến m (0a. Ý tưởng
- Dùng 2 biến đếm kiểu nguyên (d_chan, d_le) để đếm số lượng số chẵn và số lượng
số lẻ. Ban đầu khởi tạo d_chan:=0; d_le:=0;
- Sử dụng vòng lặp for tiến hoặc lùi với biến đếm i chạy từ n+1 đến m-1
Trang


- Nếu i chẵn ( i mod 2 = 0) thì tăng biến d_chan lên 1 đơn vị. Nếu i lẻ ( i mod 2 <> 0)
thì tăng biến d_le lên 1 đơn vị.
b. Code tham khảo
Program dem_So_chan_le_2;
Uses crt;
var i,n,m, d_chan, d_le: qword;

Begin
Clrscr;
Write('Nhap so n ='); readln(n);
Write('Nhap so m ='); readln(m);
d_chan:=0;
d_le:=0;
For i:=n+1 to m-1 do
if i mod 2 <>0 then inc(d_le)
else inc(d_chan);
Writeln(‘Co ‘,d_chan,’ so chan trong khoang tu ‘,n,’ den ‘,m);
Writeln(‘Co ‘,d_le,’ so le trong khoang tu ‘,n,’ den ‘,m);
readln
end.
Ví dụ 4:
Một số có tổng các ước thực sự (là các ước không kể chính nó) bằng chính nó
được gọi là số hoàn chỉnh.
Ví dụ: Số nguyên 6 có các ước thực sự là 1, 2, 3. Tổng là 1 + 2 + 3 = 6.
Viết chương trình xét xem một số n (n<1018) được nhập từ bàn phím có phải là số hoàn
chỉnh không.
a. Ý tưởng
- Dùng biến n lưu số cần xét.
- Biến S lưu trữ tổng các ước thực sự, khởi tạo s:= 0;
- Sử dụng vòng lặp for với biến đếm i chạy từ 1 đến n-1. nếu i là ước của n thì cộng
thêm i vào S.
- Nếu S = n thì đưa ra thông báo n là số hoàn chỉnh, ngược lại đưa ra thông báo n
không là số hoàn chỉnh .
b. Code tham khảo
Trang



Program So_Hoan_Chinh;
uses crt;
var n, i, s: int64;
begin
write('nhap so n: ');readln(n);
s:=0;
for i:= 1 to n -1 do
if n mod i = 0 then s:=s+i;
if s = n then write(n, ' la so hoan chinh')
else writeln(n, ' khong phai la so hoan chinh');
readln
end.
c. Nhận xét
Ước lớn nhất của số nguyên N không kể chính nó luôn <= N div 2. Vì vậy, thay vì
duyệt i từ 1 đến n-1 ta chỉ cần duyệt i từ 1 đến n div 2, việc làm này sẽ làm giảm đáng
kể số lần lặp do đó có thể tiết kiệm time chạy chương trình (nhất là với n lớn).
Chương trình giải bài toán trên có thể được cài đặt lại như sau:
Program So_Hoan_Chinh;
uses crt;
var n, i, s: int64;
begin
write('nhap so n: ');readln(n);
s:=0;
for i:= 1 to n div 2 do
if n mod i = 0 then s:=s+i;
if s = n then write(n, ' la so hoan chinh')
else writeln(n, ' khong phai la so hoan chinh');
readln
end.
Ví dụ 5:

Viết chương trình tìm các số hoàn chỉnh nhỏ hơn n (n<1015).
a. Ý tưởng
- Sử dụng 2 vòng lặp for lồng nhau để kiểm tra tính hoàn hảo của các số từ 1 đến n-1.
Trang


b. Code tham khảo
Program Tim_uoc_2;
uses crt;
Var S, n, i, j: longint;
Begin
clrscr;
Write('Nhap so n ='); readln(n);
For i:=1 to n-1 do
Begin
S:=0;
For j:=1 to i div 2 do
if i mod j = 0 then S:=S+j;
if S = i then write(i,', ');
end;
readln
end.
Ví dụ 6:
Viết chương trình xét xem một số n có phải là số nguyên tố không (0Số nguyên tố là số chỉ có 2 ước là 1 và chính nó
a. Ý tưởng
- Nếu n không chia hết mọi số i trong đoạn từ 2 đến n - 1 thì n là số nguyên tố.
- Sử dụng biến ok có kiểu boolean và có giá trị ban đầu là true.
- Cho biến i chạy từ 2 đến n – 1. Xét n mod i = 0 thì gán ok = false.
- Nếu ok = true thì n là số nguyên tố, ngược lại thì n không phải là số nguyên tố

b. Code tham khảo
Program Nguyen_to_1;
uses crt;
var n, i: integer;
ok: boolean;
begin
ok:=true;
write('Nhap n: ');readln(n);
Trang


for i:= 2 to n-1 do
if n mod i = 0 then

ok :=false;

if ok then write(n,' la so nguyen to')
else write(n, ' khong la so nguyen to');
readln
end.
c. Nhận xét
+ Ở đây ta sử dụng biến có kiểu logic (Đúng, sai). Chỉ cần một lần n mod i = 0 thì sau
khi thực hiện xong vòng lặp ok có giá trị là false.
+ Mọi số nguyên N nếu có ước khác 1 và chính nó thì chắc chắn có ước trong đoạn
từ 2 đến phần nguyên căn bậc 2 của N. Vì vậy thay vì kiểm tra n có chia hết cho số
nào trong đoạn từ 2 đến n -1 hay không, ta chỉ cần kiểm tra n có chia hết cho số nào
trong đoạn từ 2 đến trunc(sqrt(n)) hay không, việc làm này sẽ giúp giảm đáng kể số
lần lặp, giúp tiết kiệm thời gian thực hiện chương trình.
Giá trị của N


Các ước của N ( Khác 1 và N)

Trunc(sqrt(n))

2

1

3

1

4

2

2

5
6

2
2, 3

2

7

2


8

2, 4

2

9

3

3

10

2, 5

3

11
12

3
2,3, 4,6

3

13

3


14

2, 7

3

15

3, 5

3
Trang


16

2,4, 8

4

17

4

18

2, 6,9

4


Chương trình trên có thể được viết lại như sau:
Program Nguyen_to_2;
uses crt;
var n, i: integer;
ok: boolean;
begin
ok:=true;
write('Nhap n: ');readln(n);
for i:= 2 to trunc(sqrt(n)) do
if n mod i = 0 then ok :=false;
if ok then write(n,' la so nguyen to')
else write(n, ' khong la so nguyen to');
readln
end.
+ Trong chương trình Nguyen_to_2 nếu đã phát hiện n chia hết cho 1 số trong đoạn từ
2 đến trunc(sqrt(n)) rồi (thuật toán có thể kết thúc và thông báo kết quả) nhưng vòng
lặp vẫn tiếp tục kiểm tra các số tiếp theo. Điều này làm thời gian thực hiện chương
trình chưa được tối ưu
Để khắc phục nhược điểm này ta sử dụng thủ tục Break, cho phép thoát khỏi vòng lặp
gần nhất chứa nó.
Chương trình có thể viết lại:
Program Nguyen_to_3;
uses crt;
var n, i: integer;
ok: boolean;
begin
ok:=true;
write('Nhap n: ');readln(n);
for i:= 2 to trunc(sqrt(n)) do
Trang



if n mod i = 0 then begin
ok :=false;
break;
end;
if ok then write(n,' la so nguyen to')
else write(n, ' khong la so nguyen to');
readln
end.
Ví dụ 7:
Lập trình tính giai thừa của số nguyên n (n<=8)
a. Ý tưởng
N! = 1.2.3…n (tích các số tự nhiên từ 1 đến n). Không có công thức tổng quát để
tính n! nhưng ta có công thức truy hồi sau:
0!= 1;
N!= n . (n-1)!
Đặt gtn = n!, theo công thức trên ta có

gt0 = 1;
gtn = gtn-1 . n

b. Code tham khảo
Var

n, i, gt: longint;

Begin
Writeln(‘Nhap n: ‘);
Readln(n);

gt:=1;
For i:= 1 to n do
gt:= gt*1;
Writeln(‘n! = ‘, gt);
Readln
End.
Ví dụ 8:
Dãy số fibonaci được định nghĩa như sau:
f1 = 1, f2=1
fn = fn-1 + fn-2
Trang


Viết chương trình in ra số fibonaci thứ n (n <= 1000);
a. Ý tưởng
-

Nếu n <= 2, ta có f1 = f2 = 1;

Nếu n > 2: Dựa vào công thức truy hồi của dãy fibonaci ta có thể dẽ dàng tính
được fn dựa vào fn-1 và fn-2. Sử dụng biến f để tính fi ứng với mỗi giá trị của i (i= 3..n) ,
theo công thức truy hồi ta có f = f 1+f2, sau đó f1 và f2 được thay đổi giá trị để tính phần
tử tiếp theo của dãy.
b. Code tham khảo
Var i, f, f1, f2: longint;
Begin
Write(‘Nhap n: ‘);
Readln(n);
If n <= 2 then writeln(‘So fibonacithu ‘,n,’ la: ‘,1)
Else


begin
f1:=1;
f2:=1;
For i:=3 to n do
Begin
f:=f1+f2;
f1:=f2;
f2:=f;
End;
Write(‘So fibonaci thu ‘,n,’ la: ‘,f);
End;

Readln
End.
Ví dụ 9:
Lập trình tính tổng sau:

(SGK Tin học 11 – Trang 51)

a. Ý tưởng
Với bài toán trên có thể sử dụng cấu trúc lặp với số lần biết trước dạng tiến hay lùi
đều được. Nếu sử dụng cấu trúc lặp For …downto … do ta có thể xây dựng công thức
truy hồi để tính giá trị Y như sau:
Yn  0
Trang


Yn 1  Yn 


n
n 1

Với n từ 50 giảm dần về 1

Việc cộng vào tổng Y được lặp lại 50 lần, giá trị n khi tham gia vòng lặp là 50
và sau mỗi lần lặp n giảm đi 1 cho đến khi n =1 thì dừng. Như vậy số lần lặp là biết
trước, biến n được sử dụng là một biến đếm giảm từ 50 về 1, tổng cần tính là Y0
b. Code tham khảo
var

Y: real;
n : integer;

begin
Y := 0;
for n := 50 downto 1 do
Y := Y + n/(n+1);
writeln('Tong Y la: ',Y:10:4);
readln;
end.
Tuy nhiên trong một số trường hợp thì chỉ có thể dùng một cấu trúc, đặc biệt là khi
tính các công thức truy hồi. Ta xét một ví dụ dùng for … downto … do thích hợp hơn:
Ví dụ 10:
Tính tổng

S=

với n là một số tự nhiên nhập từ bàn phím.


a. Ý tưởng
Đặt ntadấu
có công
căn thức truy hồi sau:
Tổng cần tính là si. Công thức truy hồi là truy hồi ngược (vì tính si qua s i+1) nên
dùng for … down … to là thích hợp nhất.
b. Code tham khảo
Var i,n : integer;
s : real;
begin
write('Nhap mot so tu nhien n = ');
readln(n);
s:=0;
for i := n downto 1 do
Trang


s := sqrt (2 * i + s);
writeln('Ket qua can tinh: s = ',s:10:5);
readln;
end.
III.

Lặp với số lần chưa biết trước

1. Cú pháp và hoạt động của lệnh lặp với số lần chưa biết trước
a. Câu lệnh While – do
Cú pháp:
While <điều kiện> do <câu lệnh>;
Trong đó:

+ Điều kiện là biểu thức logic
+ Câu lệnh là một câu lệnh trong pascal

Điều kiện

Đúng

Sai
Câu lệnh

Hoạt động:

Sơ đồ hoạt động của câu lệnh While – do

B1: Máy tính và kiểm tra điều kiện sau while
B2: Nếu điều kiện đúng thì thực hiện câu lệnh sau do rồi quay lại B1(quá trình lặp)
B3: Thực hiện câu lệnh tiếp theo trong chương trình (câu lệnh sau while- do)
Nói một cách khác ta có thể hiểu: Câu lệnh while - do là lệnh lặp kiểm tra điều kiện
trước, câu lệnh sau do sẽ được thực hiện cho đến khi điều kiện nhận giá trị sai
b. Câu lệnh lặp repeat_until
Cú pháp:
Trang


Repeat
<dãy lệnh>;
Until <điều kiện>;
Trong đó: <điều kiện> là biểu thức quan hệ hoặc logic.

Câu lệnh


Sai

Điều kiện

Đúng

Hoạt động:

Sơ đồ hoạt động của câu lệnh repeat – until

B1: Thực hiện dãy lệnh nằm giữa repeat và until
B2: Kiểm tra điều kiện sau until, nếu điều kiện sai thì quay lại B1(quá trình lặp)
B3: Thực hiện câu lệnh tiếp theo của chương trình (câu lệnh sau repeat – until)
Nói cách khác câu lệnh repeat – until là câu lệnh lặp kiểm tra điều kiện sau.
Chú ý:
+ Không giống với vòng lặp for - do, cả repeat - until và while - do đều là các vòng
lặp không xác định trước số lần lặp. Vì vậy cần có câu lệnh thay đổi giá trị biến điều
khiển vòng lặp để đến một lúc nào đó có thể thoát ra khỏi vòng lặp;
+ Nếu dùng while - do và repeat - until để cùng giải một bài toán, cùng một giải thuật
như nhau thì điều kiện sau while và điều kiện sau until là phủ định nhau;
+ Các câu lệnh trong vòng lặp repeat- until không cần phải đặt trong cặp từ khóa
begin_end.
 Sự giống và khác nhau giữa while – do và repeat – until
-

Giống nhau: Cả hai đều là câu lệnh lặp với số lần chưa biết trước

-


Khác nhau
While - do

Repeat - until
Trang


Là câu lệnh lặp kểm tra điều kiện
trước

Là câu lệnh lặp kiểm tra điều kiện
sau

Câu lệnh sau while được lặp lại khi
điều kiện đúng

Dãy lệnh nằm giữa repeat – until
được lặp lại khi điều kiện sai

Câu lệnh sau while có thể không được
thực hiện lần nào (Khi ngay từ đầu
điều kiện đã sai)

Dãy lệnh nằm giữa repeat – until
được thực hiện ít nhất 1 lần (dù ngay
từ đâu điều kiện đã đúng)

3. Một số ví dụ
Ví dụ 11:
Viết chương trình tính tổng sau:

S = 1+2+3+..+n+… cho đến khi S > 105
a. Ý tưởng
Ta có thể mô tả thuật toán giải bài toán trên bằng cách liệt kê như sau:
B1: Gán s ← 0, i ← 0;
B2: Nếu s>105 thì chuyển đến b5
B3: i ← i+1
B4: s = s+i, rồi quay lại b2
B5: Đưa ra S rồi kết thúc
b. Code tham khảo
Var

i, s: longint;

Begin
S:=0;
i:=1;
While s<= 100000 do
Begin
i:=i+1;
S:=s+i;
End;
Write(‘S= ‘, s);
Readln
Trang


End.
Ví dụ 12:
Viết chương trình tìm ước chung lớn nhất của hai số nguyên dương M và N.
Viết chương trình tìm ước chung lớn nhất (UCLN) của hai số với yêu cầu sử dụng

thuật toán Euclid.
Thuật toán Euclid: Nếu a chia hết cho b (a chia b dư 0) thì UCLN(a,b) bằng b
Nếu a chia b dư r thì UCLN(a,b) = UCLN(b,r)
a. Ý tưởng
- Nhập a, b và gán r = a mod b.
- Lặp với điều kiện r <> 0: b = r, a = b, r = a mod b.
b. Code tham khảo
Program UCLN;
uses crt;
var a,b,r:byte;
begin
clrscr;
writeln('CHUONG TRINH TIM UCLN CUA HAI SO');
write('Nhap a: ');readln(a);
write('Nhap b: ');readln(b);
r:=a mod b;
while r<> 0 do
begin
b:=r;
a:=b;
r:=a mod b;
end;
write('UCLN cua hai so la: ',b);
readln
end.
Ví dụ 13:
Viết chương trình cho phép tính tổng của nhiều số (chưa biết bao nhiêu số). Nhập
số 0 để kết thúc quá trình nhập.
Trang



a. Ý tưởng
- Sử dụng câu lệnh repeat – until để kiểm tra số nhập vào. Kho nào số nhập vào =0 thì
thoát khỏi vòng lặp
b. Code tham khảo
Program tong_repeat;
uses crt;
var i: byte;
so, tong: real;
begin
write('NHAP CAC SO - NHAP 0 DE NGUNG ');
readln;
repeat
clrscr;
write('Nhap so thu ',i,': ');
readln(so);
tong:=tong+so;
i:=i+1;
until so=0;
write('Tong la: ',tong:0:2);
readln
end.
Ví dụ 14:
Viết chương trình sử dụng lệnh repeat – until in ra dãy Fibonacy có phần tử lớn
nhất nhỏ hơn n?
a. Ý tưởng
- Cần hai biến F_1 và F có giá trị đầu là 1, 1.
- Thực hiện lặp cho đến khi F >= n.
- Do yêu cầu chỉ in các số bé hơn n nên khi in cần thêm một lệnh kiểm tra.
b. Code tham khảo

Program Fi_Bo_na_xi;
Var n, F_2,F_1, F: Longint;
Begin
Trang


Write('Nhap n: ');Readln(n);
F_1:=1; F_2:=1;
Write(F_2,';',F_1,';');
Repeat
F:=F_2+F_1;
if F< n then Write(F,';');
F_2:=F_1; F_1:=F;
Until F>n;
R eadln;
End.
Ví dụ 15:
Viết chương trình sử dụng vòng lặp while – do tính tổng:
S=1 + 2 +…+100
a. Ý tưởng
-

Khởi tạo i=1

-

Sử dụng vòng lặp while – do với điều kiện i<=100 để tính tổng

-


Sau mỗi lần lặp tăng i lên 1

b. Code tham khảo
Var s,i: word;
Begin
s:=0;
i:=1;
While i<=100 do
Begin
s:=s+i;
i:=i+1;
End;
Write(‘S= ‘,s);
Readln
End.
Ví dụ 16
Trang


×