Tải bản đầy đủ (.doc) (4 trang)

CHUYÊN ĐỀ BỒI DƯỠNG HỌC SINH GIỎI MÔN TIN HỌC – PHẦN LẬP TRÌNH Bài: TIẾT KIỆM BỘ NHỚ STACK TRONG KHAI BÁO BIẾN

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 (126.76 KB, 4 trang )

UBND HUYỆN SÓC SƠN
TRƯỜNG THCS TIÊN DƯỢC
CHUYÊN ĐỀ BỒI DƯỠNG HỌC SINH GIỎI
MÔN TIN HỌC – PHẦN LẬP TRÌNH
Bài: TIẾT KIỆM BỘ NHỚ STACK TRONG KHAI BÁO BIẾN
I – Yêu cầu:
1. Kiến thức:
- Biết được kích thước dung lượng của một số kiểu dữ liệu thường dùng;
- Biết lợi ích của việc tiết kiệm khai báo biến.
2. Kỹ năng:
- Rè kỹ năng sử dụng ngôn ngữ lập trình Pascal.
- Thực hiện được việc khai náo đúng và đủ biến mà không thừa biến, không thừa
rộng quá của kiểu dữ liệu.
- Phát triển tư duy tốt hơn.
3. Thái độ: Nghiêm túc, xây dựng, tìm tòi, khám phá, phát huy sáng tạo
II – Nội dung
Hoạt động 1: Giới thiệu về kích thước một số kiểu dự liệu thường dùng
Hoạt động của thầy

Nội dung

Trong Pascal có một số kiểu dữ liệ
thường dùng như Integer, Real,
Longint, String, … Trong quá trình
viết chương trình ta không để ý đến
kích thước của các kiểu dữ liệu này bời
vì chưa phải là các bài toán lớn, bài
toán cần nhiều biến. Ta cũng cần phải
biết, mặc định trong Pascal thì bộ nhớ
Stack chỉ cấp cho 16384 byte. Đã bao
giờ em gặp lỗi thông báo “structure


too large” chưa? Đây là thông báo
“cấu trúc qua lớn” do khai báo biến có
tổng kích thước bộ nhớ vượt quá cho
phép của bộ nhớ Stack. Làm thế nào để
biết được khi nào ta khai báo vượt quá 1. Kích thước bộ nhớ của kiểu dữ liệu
Kích
cho phép?
Tên
STT

Riêng kiểu dữ liêu String là 256 byte,
nếu String[100] thì là 101 byte. Vậy
kích thước khai báo string là báo n thì
tốn hết n+1 byte.
Mỗi biến hay thành phần của biến nào
đều dùng đến số lượng byte tương ứng.
Nếu khai báo:
Var n,m: integer; thì đã dùng hết 8byte.

1
2
3
4
5
6
7
8
9
10
11


kiểu
Integer
Byte
Word
Longint
Sortint
Real
Single
Double
Char
Boolean
String

Phạm vi giá trị

thước
(byte)

-32768..32767
0 .. 255
0 .. 65535
-2147483648..2147483647
-128 .. 127
2.9e-39..1.7e38
1.5e-45..3.4e38
5.0e-324..1.7e308
Kí tự bất kì
True, False
Xâu tối đa 255 kí tự


2
1
2
4
1
6
4
8
1
1
1 … 256


Var a:array[1..100] of real; thì đã dùng
hết 100x6 = 600 byte.

- Ví dụ:
Var a,b,c : Integer;

Dùng hết 3x2 = 6 byte.
Var a,b : Array[1..100] of longint;
Dùng hết 2x100x6 = 1200 byte.
Var tb : string;
ten: Array[1..50] of String[30];
Khi lập trình chúng ta cần phải tiết
dùng hết 256 + 50x31 = 1806 byte.
kiệm bộ nhớ trong khai báo biến, đặc
biệt cần thiết khi giải một bài toán lớn
có cần sử dụng nhiều biến. Vậy làm

thế nào ta tìm hiểu thêm qua bài toán
cụ thể
Hoạt động 2: Áp dụng
Hoạt động của thầy
Bây giờ chúng ta tìm hiểu qua một bài
toán cụ thể xem nên tiết kiệm bộ nhớ
như thế nào khi khái bái biến để viết
chương trình giải một bài toán
- Khi viết chương trình xong để kiểm
tra nghiệm và chỉnh sửa lại chương
trình thi ta hay dùng bộ nghiệm có giá
trị nhỏ để còn dễ nhẩm. Thế nhưng cần
chú ý đến điều kiện là K có thể khá
lớn, có thể phải thông báo giá trị của
F1000.
- Theo công thức đệ quy của dãy Fibo
thì dễ nhận thấy K càng lớn thì Fk cũng
càng lớn. Chắc chắn kiểu Integer
không đủ để biểu diễn số lớn như vậy.
Có thể kiểu Longint cũng vẫn là chưa
đủ. Vậy cần phải sử dụng kiểu Int64
trong Free Pascal. Như thế thì M có thể
cũng là số nguyên rất lớn nên M cũng
phải có kiểu Int64.
Vậy chương trình được viết như thế
nào?

Nội dung
2. Vận dụng
Bài toán: Dãy số Fibonaci cho bởi công thức

F1 = F2 = 1, Fn = Fn-1 + Fn-2 (n≥3).
a) Hãy tìm số Fibonaci thứ K (1≤K≤1000)
b) Hãy tìm số Fibonaci lớn nhất nhưng
không vượt quá số M (1trước.
* Yêu cầu nhập vào số nguyên K và M rồi
thông báo kết quả.

Program Fibonaci;
Var i,K:integer;
F:Array[1..1000] of longint;
M:longint;
Begin
Write(' Nhap K = '); Readln(K);
Write(' Nhap M = '); Readln(M);
F[1] := 1; F[2] := 1;
For i := 3 to K do
F[i] := F[i-1] + F[i-2];
Writeln(' F',K,' = ',F[K]);
For i := 2 to K do
If F[i] > M then
Writeln(F[i-1]);
Readln;


- Rõ ràng chương trình trên chỉ đúng
với giá trị của M ≤ Fk. Nếu giá trị của
M > Fk+1 thì sẽ không đưa ra thông báo
kết quả. Vậy chương trình trên được
hiệu chỉnh thế nào?


- Như vậy chương trình trên hoàn toàn
có thể thực hiện được và đúng. Tuy
nhiên ở đây ta lại thấy việc khai báo
biến F là một mảng có nhiều nhất là
1000 phần tử (hầu như không có
chương trình nào klhai báo mảng rộng
đến như vậy), nhưng Fmax≤ M lại là
F1000 + 1 trở lên thì sẽ không có giá trị F
nào như thế. Và lại việc khai báo như
vậy sẽ tốn rất nhiều bôn nhớ.
- Để ý sẽ thấy ta chỉ cần lấy giá trị F k
còn các giá trị nhỏ hơn thì không cần.
Tuy nhiên ta lại cần có các giá trị F i<
Fk để còn tìm được Fk. Khi tìm được Fk
thì cần thêm Fk-1 để tính tiếp đến giá trị
Fk+1 nên Fk-2 sẽ không còn cần dùng
đến nữa. Như vậy, mỗi lần tìm ra một
số Fibo ta chỉ cần biẻt giá trị của hai số
trước đó. Tóm lại mỗi một lần tìm ta
chỉ cần có ba biến để lưu giá trị của các
số Fibo cần thiết.
Chương trình sẽ được viết thế nào?

End.

Program Fibonaci;
Var i,K:integer;
F:Array[1..1000] of longint;
M:longint;

Begin
Write(' Nhap K = '); Readln(K);
Write(' Nhap M = '); Readln(M);
F[1] := 1; F[2] := 1;
For i := 3 to K do
F[i] := F[i-1] + F[i-2];
Writeln(' F',K,' = ',F[K]);
i := 2;
While F[i]<=M do
Begin
i := i + 1;
F[i] := F[i-1] + F[i-2];
End;
Writeln(F[i-1]);
Readln;
End.

Program Fibonaci;
Var i,K:integer;
F,a,b: longint;
M:longint;
Begin
Write(' Nhap K = '); Readln(K);
Write(' Nhap M = '); Readln(M);
a := 1; b := 1;
For i := 3 to K do
Begin


F := a + b;

a := b;
b := F;

- Bây giờ ta kiểm tra hai chương trình
đèu đúng này xem nên sử dụng chương
trình nào hợp lý hơn? Ở đây ta chỉ xét
đến mỗi chương trình tiêu tốn hết bao
nhiêu bộ nhơ khi khai báo biến? Ở cả
hai chương trình khác nhau ở phần
khai báo biến mảng (CT trước) và
không có biến mảng (CT sau).

End;
Writeln(' F',K,' = ',F);
a := 1; b := 1; F := 1;
While F<=M do
Begin
F := a + b;
a := b;
b := F;
End;
Writeln(a);
Readln;
End.

- Khai báo F:Array[1..1000] of longint; đã
dùng hết 1x1000x4 = 4000 byte
- Khai báo F,a,b: longint; đã dùng hết 3x4 =
Như thế ta thấy sự chênh lệch rất nhiều 12 byte.
trong hai chương trình.

* Đây chỉ là một bài toán nhỏ, sử dụng
rất ít biến và kiểu dữ liệu của biến
cũng không phải là lớn lắm. Nếu khi
gặp bài toán lớn thì việc khai báo lãng
phí ngư CT đầu thì liệu điều gì sẽ xảy
ra?
* Nếu khai bào i, K: Integer ta cũng
khai báo kiểu dữ liệu rộng ra là
Longint thì có nên không?
Chúng ta phải biết tiết kiệm bộ nhơ vì
bộ nhớ có hạn, nhưng việc phải sử
dụng đến kiểu dữ liệu lại là bắt buộc.
III – Giao nhiệm vụ
- Tìm hiểu thêm kích thước của một số kiểu dữ liệu khác;
- Khi định nghĩa kiểu dữ liệu mới là đoạn con thì kích thước của nó so với kiểu cơ
sở như thế nào?



×