- Các chơng trình con cần đợc viết bên trên thân chơngtrình và đợc sử dụng trong thân chơng trình hoặc khai báo trớcbằng từ khóa Forward viết sau tên chơng trình con thì có thể sử dụng c
Trang 1Chơng 1 : Chơng trình con
I Lý do tách chơng trình thành nhiều chơng trình con.
- Trong khi lập trình ta thờng gặp nhiều đoạn chơng trình
đợc lặp đi lặp lại ở những chỗ khác nhau Để tránh rờm rà,những đoạn chơng trình này đợc thay thế bằng các chơngtrình con tơng ứng và khi cần chỉ việc gọi các chơng trình con
đó (với các tham số khác nhau) mà không cần viết lại đoạn chơngtrình
- Một vấn đề lớn dẫn đến một chơng trình phức tạp gâykhó khăn trong việc gỡ rối và hiệu chỉnh Ta có thể phân tích cácvấn đề phức tạp thành các vấn đề nhỏ tơng ứng với các chơngtrình con để dễ kiểm tra và gỡ rối sau đó lại ghép thành mộtchơng trình lớn
II Các loại chơng trình con
- Trong Pascal có hai loại chơng trình con là Procedure ( thủtục) và Function (hàm)
- Các chơng trình con cần đợc viết bên trên thân chơngtrình và đợc sử dụng trong thân chơng trình hoặc khai báo trớcbằng từ khóa Forward (viết sau tên chơng trình con) thì có thể
sử dụng chơng trình con trớc khi xây dựng nó
1 Thủ tục: Là các chơng trình con không có giá trị trả về.
Cú pháp:
Procedure Ten-thu-tuc( Khai báo tham số);
{Các khai báo trong thủ tục}
Trang 2{Các lệnh trong chơng trình con;}
End;
Gọi thủ tục: chỉ cần gọi tên thủ tục và truyền cho nó một danh
sách các tham số Việc gán giá trị cho tham số sẽ thực hiện theothứ tự của danh sách khi gọi, hoàn toàn không liên quan gì đếntên gọi của biến
Cú pháp: Ten-thu-tuc(Danh sách tham số);
2 Hàm: là một đoạn chơng trình con sau khi thực hiện xong trả
lại chơng trình gọi một giá trị kết quả vô hớng hoặc con trỏ
Trang 3III Biến toàn cục và biến cục bộ.
- Biến toàn cục: là các biến đợc khai báo trong chơng trình
chính, các biến này có thể đợc dùng ở mọi nơi trong chơngtrình
- Biến cục bộ: là biến đợc khai báo trong một chơng trình
con nó chỉ có tác dụng trong chơng trình con đó
IV Truyền tham số cho chơng trình con.
- Chơng trình con có thể đợc khai báo mà không dùng tham
số khi các chơng trình con tính toán trực tiếp với các biếntoàn cục hoặc chơng trình con không dùng đến bất cứbiến, hằng nào
- Việc truyền tham số cho chơng trình con là một cơ cấuthay thế tơng ứng, nó cho phép một quá trình có thể đợclặp đi lặp lại nhiều lần với các tham số khác nhau
- Các tham số truyền cho chơng trình con phải khai báotrong tiêu đề của chơng trình con, danh sách nhóm cáctham số hình thức khác kiểu sẽ đợc đặt cách nhau bằngdấu chấm phẩy(;) các tham số trong cùng nhóm kiểu đợccách nhau bằng dấu phẩy(,)
- Danh sách các tham số thực sự phải tơng ứng và nhấtquán với danh sách các tham số hình thức đợc khai báotrong tiêu đề của chơng trình con
- Có hai cách truyền tham số:
Trang 4+ Tham biến (variable parameter): khai báo đặt sau từ
khoá Var, các tham số thực sự phải là biến Các tham số thực
là tham biến có thể đợc thay đổi trong chơng trình con vàkhi ra khỏi chơng trình con vẫn giữ nguyên giá trị thay đổi
đó
+ Tham trị (value parameter): khai báo tham số không
cần từ khoá var Các tham số thực có thể là một biểu thức,
biến hay giá trị Các tham trị có thể đợc thay đổi trong
ch-ơng trình con nhng không làm thay đổi giá trị tham sốthực
Các tham số lu kết quả tính toán của chơng trình con luôn
là tham biến
Các tham số đóng vai trò cung cấp “ dữ kiệu đầu vào” sẽ làcác tham trị
III Hoạt động của CT
Chơng trình bắt đầu từ câu lệnh đầu tiên và kết thúc khi thựchiện xong câu lệnh cuối cùng của chơng trình Khi gặp một lờigọi chơng trình con máy sẽ:
+ Cấp phát bộ nhớ cho các biến cục bộ
+ Truyền giá trị của các tham số thực sự cho các đối
+ Thực hiện các lệnh trong thân chơng trình con
+ Giải phóng các biến cục bộ và trở về nơi gọi nó
+Nếu chơng trình con là hàm thì khi trở về mang theomột giá trị
Trang 5VI Tính đệ quy của CTC.
( Thông thờng các hàm và thủ tục có thể tham trỏ đến các
hàm và thủ tục khác Trong pascal cũng nh một số ngôn ngữ lập trình khác, một hàm hay một thủ tục có thể tham trỏ tới chính
nó, hiện tợng này gọi là tính đệ quy của chơng trình con)
1 Định nghĩa:
Chơng trình con đợc gọi là đệ quy nếu trong thân của nó
có lời gọi trực tiếp hoặc gián tiếp đến chính bản thân nó
2 Thiết kế giả thuật đệ quy.
Để thiết kế giải thuật đệ quy ta phân tích bài toán theo các bớc:
+ Xác định rõ, kích thớc của bài toán phụ thuộc vào cái gì +Phân tích bài toán về một hay vài bài toán đồng dạng nh-
- Giả thiết bài toán đã đợc giải quyết với mọi k < n-1;
- Với n = 0, n = 1 -> trờng hợp suy biến
- Phân rã bài toán thành một hoặc nhiều bài toán có kíchthớc nhỏ hơn n-1;
4 Cấu trúc:
Trang 6If (trờng hợp suy biến) then (lời giải trực tiếp)
5 Trong thuật toán đệ quy thờng có hai thành phần:
- Thành phần không chứa khái niệm định nghĩa, đó là
điều kiện để kết thúc quá trình đệ quy
- Thành phần chứa khái niệm định nghĩa, sau mỗi bớcphạm vi của thành phần này sẽ thay đổi cho đến khikhông thể thay đổi đợc nữa, đó là điều kiện kết thúc
Ví dụ: N! = N*giaithua(N-1) là thành phần chứa địnhnghĩa
0! = 1 là điều kiện kết thúc
6 Một số ví dụ về chơng trình đệ quy
Ví dụ 1: Bài toán tháp Hà Nội.
Tơng truyền rằng ở một ngôi đền lớn tại Benaves ấn Độ cómột tấm đế bằng đồng trên có 3 cái cọc bằng kim cơng Trên đóthợng đế đã xếp 64 cái đĩa trên một cái cọc với đờng kính giảmdần Các nhà s phải dịch chuyển đĩa sang một cái cọc khác vớinguyên tắc:
Trang 7+ Mỗi lần chỉ dịch chuyển một đĩa.
+ Một đĩa có thể đợc chuyển từ cọc này sang cọc khác bấtkì
+ Không đợc để 1 đĩa lên trên một đĩa có kích thớc nhỏhơn
Kết quả: công việc sẽ kết thúc sau 58 tỉ năm!
Thuật toán:
Đánh số 3 cọc là c1, c2, c3 Giả sử có n đĩa đợc xếp ở c1
Với n = 2 Chuyển đĩa 1 từ c1 => c3
Chuyển đĩa 2 từ c1 => c2Chuyển đĩa 1 từ c3 => c2Với n=3 Chuyển đĩa 1,2 từ c1 => c3 theo cách trên
Chuyển đĩa 3 từ c1 => c2Chuyển đĩa 1,2 từ c3 => c2 theo cách trên Tổng quát hoá thuật toán:
Chuyen(n đĩa, từ cọc, tới cọc, qua cọc trung gian);N=2 Chuyen(1,c1,c3,c2);
Trang 8BEGIN {main program}
Write(‘ So dia n=’); Readln(n);
Chuyen(n,c1,c2,c3) END.
End;
Trang 9If x>y then x:=x-y else y:=y-x;
until x=y;
USCLN:=x;
End;
Cách 3: (Dùng đệ quy )
Ví dụ 4: Chơng trình đảo số
Nhập một số nguyên dơng n từ bàn phím In số đó ra mànhình theo chiều ngợc lại (Ví dụ: nhập số 123, in ra màn hình321)
Trang 10for i:=1 to length(s) div 2 do Begin
Trang 11(* Thủ tục đảo ký tự sử dụng đệ quy*)
2 Viết các chơng trình con tính: xn, n! áp dụng, tính giá trịbiểu thức:
A =
! n
x +
+
! 3
x +
! 2
x + x +
Trang 12chơng 2: Cấu trúc dữ liệu kiểu bản ghi
( record)
( Các kiểu dữ liệu đã xét nh mảng, tập hợp chỉ mô tả đợc một nhóm các phần tử có cùng một kiểu giá trị Bản ghi cho phép
xử lý các đối tợng bao gồm nhiều kiểu dữ liệu khác nhau Đây là một công cụ mạnh để mô tả và xử lý các cấu trúc dữ liệu phức tạp thờng gặp trong các bài toán quản lý.)
1 Khai báo kiểu
Type Tên kiểu = Record
V1: T1;
V2: T2; Danh sách các trờng
Vn: Tn;
End;
Trong đó: V1, V2, , Vn là tên các trờng của bản ghi
T1, T2, , Tn là các kiểu dữ liệu tơng ứng với các trờng
Kích thớc của một bản ghi bằng tổng kích thớc các trờng
Ví dụ: Sizeof(date) = 1+1+2=4 (byte)
Trang 13Một kiểu bản ghi đã đợc định nghĩa có thể dùng để khaibáo các trờng của một bản ghi khác Khi đó ta có các bản ghi lồngnhau.
Ví dụ: Sử dụng kiểu Date để khai báo ( định nghĩa ) một kiểu bản ghi phức tạp hơn :
Type
NS = Record
Hoten : String [30] ;Ngaysinh : Date ;End ;
2 Khai báo biến Record:
Cách 1 : Khai báo trực tiếp :
Var Tên biến : Record
{Danh sách các trờng;}
End ;Cách 2 : Khai báo biến thông qua kiểu bản ghi đã địnhnghĩa trớc
Var Tên biến : Tên kiểu Rec ;
Trang 14Ví dụ : Type
Hoso = Record
Hoten : String[30] ; Ngaysinh : Date;
End ; Var Canbo : array[1 100] of Hoso;
HS : Hoso;
II Các thao tác
1 Truy xuất các trờng trong Record
( Thành phần của bản ghi có vai trò nh một biến hay phần
tử mảng Phép toán nào thực hiện đợc trên các biến thì phép toán đó cũng thực hiện đợc trên các thành phần Các lệnh nào dùng đợc cho biến thì lệnh đó cũng áp dụng đợc cho các thành phần của bản ghi )
Để truy nhập vào một thành phần của bản ghi ta cũng dùng cách viết :
Tên bản ghi Tên trờng
HS Hoten := “Nguyen Van A”;
HS Ngaysinh.Ngay := 16;
HS Ngaysinh.Thang: =11;
Ví dụ áp dụng :
Nhập toạ độ 1 điểm trong mặt phẳng toạ độ In toạ độ điểm
đó ra màn hình :
Var M : Record
X, Y :Integer;
End;
Begin
Trang 15Writeln (‘ Nhap toa do diem M:’);
Write(‘Nhap hoanh do X= ’); Readln ( M X );
Write(‘Nhap tung do Y= ’); Readln ( M Y ); Writeln ( ‘Toa do diem vua nhap la (‘, M.X, ‘,’,M.Y,’)’);
Write(‘Nhap hoanh do X= ’); Readln ( X );
Write(‘Nhap tung do Y= ’); Readln ( Y );
Writeln(‘Toa do diem vua nhap la(‘, X, ‘,’,Y,’)’);
End;
Có ph¸p 2: C©u lÖnh With do lång nhau :
With BiÕn b¶n ghi1 do
Trang 16End ;
VÝ dô : With HS do
Begin Hoten := ‘Nguyen Van A’;
Có ph¸p 3: D¹ng rót ng¾n cña c©u lÖnh With do lång nhau :
With BiÕn b¶n ghi 1, BiÕn b¶n ghi 2 do
Trang 17- Không đợc sử dụng các phép toán số học, logic và quan
hệ với các biến bản ghi
Trang 18IV Bản ghi có cấu trúc thay đổi
< Các kiểu bản ghi đã trình bày ở trên là kiểu bản ghi cố định, mỗi bản ghi đều có một tập hợp các trờng nh nhau Bản ghi cố
định dùng để mô tả 1 lớp đối tợng mà mỗi đối tợng có cùng một tập tính nh nhau Trong trờng hợp, ngoài các thuộc tính chung, mỗi đối tợng lại có một số thuộc tính riêng thì ta sử dụng ẩn ghi
có cấu trúc thay đổi >
1 Cách định nghĩa bản ghi có cấu trúc thay đổi:
+ Phần cố định đợc khai báo trớc
+ Trong số các chỉ tiêu chung, chọn ra một chỉ tiêu dùng đểphân chia ra các trờng hợp mà mỗi trờng hợp có cùng một nhómchỉ tiêu riêng (gọi là trờng phân loại)
+ Dùng trờng phân loại và toán tử Case of để khai báo từngnhóm chỉ tiêu riêng (Case không kết thúc bằng end)
+ Tất cả các biểu trg phần thay đổi phải khác nhau
Ví dụ: Type hinh =record
dientich: real;
chuvi: real;
Case tenhinh : string[15] of
‘tamgiac’: (canh1, canh2, canh3 : real);
‘chunhat’ : (dai, rong : real );
‘hinhtron’: (bankinh : real);
End;
Var h1 : HINH;
2 Truy nhập đến các thành phần của Record thay đổi
h1 tenhinh
Trang 19h1 dientichh1 chuvih1 canh1h1 canh2
Trang 20Filereal = File of Real;
2 Khai báo biến tệp
Cách 1: Khai báo biến theo kiểu đã đợc định nghĩa trớc:
Var Tên biến : Tên kiểu;
Ví dụ:
Var f1, f2 : FileInt;
f : Fns;
Trang 21Cách 2: Khai báo biến trực tiếp
Var Tên biến : File of Kiểu phần tử;
Ví dụ:
Var f3, f4 : File of real;
* Chú ý: Các phần tử tệp có thể thuộc bất kì kiểu dữ liệu nào(kiểu vô hớng, kiểu có cấu trúc nh kiểu bản ghi ) trừ kiểu tệp
II Cấu trúc và phân loại tệp
1 Cấu trúc tệp
- Các phần tử của tệp không có tên và đợc sắp xếp thànhmột dãy ở mỗi thời điểm chơng trình chỉ có thể truynhập vào một phần tử của tệp thông qua giá trị của mộtbiến đệm gọi là cửa sổ tệp
- Có những lệnh sẽ làm dịch chuyển của sổ tệp sang vịtrí tiếp theo hay về vị trí đầu của tệp
- Mỗi tệp đều đợc kết thúc bằng một dấu đặc biệt làEOF Hàm chuẩn EOF(biến tệp) nhận kiểu boolean
EOF(f) = false nếu cửa số cha ở cuối tệp
EOF(f) = true nếu ngợc lại
2 Phân loại tệp (dựa trên việc bố trí các phần tử của tệp trong
bộ nhớ và cách truy nhập vào tệp.)
+ Tệp có cấu trúc tuần tự (Sequence Access): Đọc một phần
tử bất kì buộc phải tuần tự đi qua các phần tử trớc đấy, cònmuốn ghi thêm 1 phần tử vào tệp phải đặt cửa sổ vào vị trí
Trang 22cuối tệp (Bộ nhớ ngoài điển hình tơng ứng với cấu trúc này làbăng từ);
+Tệp truy nhập trực tiếp (Direct access): Là tệp có thể đặtcửa sổ tệp vào phần tử bất kì của tệp qua phần chỉ số thứ tựcủa phần tử trong tệp
Ví dụ: Write(f, a1, a*b, 5);
Cuối cùng của việc ghi tệp là đóng tệp: Close(biếntệp);
Ví dụ: Tạo một tệp chứa 100 số nguyên đầu tiên với tên tệp là
‘Songuyen.dat’
Trang 23b Mở tệp để đọc dữ liệu
Assign(Biến tệp, Tên tệp);
Reset(Biến tệp);
Đọc dữ liệu từ tệp vào bộ nhớ trong:
Read(Biến tệp, danh sách các biến số);
(Khi gặp câu lệnh này, chơng trình đọc giá trị tại vị trí cửa
sổ đang trỏ, gán cho biến tơng ứng cùng kiểu Sau đó cửa sổ dịch chuyển cửa sổ sang vị trí tiếp theo và đọc giá trị cho các biến khác cho đến hết tệp.)
Chú ý:
Nếu dùng lệnh Reset để mở tệp cha tồn tại trên đĩa thìchơng trình sẽ báo lỗi và dừng lại Vì vậy, trớc khi mở tệpbằng lệnh Reset phải kiểm tra sự tồn tại của tệp theomẫu:
Trang 24End;
Giải thích: Dẫn hớng {$ i + } mở việc kiểm tra vào ra Khi gặp lỗi vào ra chơng trình sẽ báo lỗi và dừng lại Mặc định dẫn h- ớng {$ i -} không kiểm tra lỗi vào ra Khi gặp lỗi vào ra chơng trình không dừng lại nhng sẽ treo tất cả các thủ tục vào ra khác cho đến khi có lời gọi hàm IOResult Hàm IOResult=0 khi mọi việc xảy ra tốt đẹp.
Việc đọc một phần tử của tệp cần điều kiện cửa sổ chatrỏ đến cuối tệp Do vậy trớc khi đọc giá trị tệp gán chobiến X phải kiểm tra xem tệp đó đã kết thúc cha Nếutệp kết thúc rồi mà vẫn sử dụng thủ tục read để đọc dữliệu thì máy sẽ báo lỗi và dừng chơng trình
While NOT EOF(biến tệp) do
Begin
Read(Biến tệp, X);
Trang 25
While not EOF(f) do
Begin
Read(F,X);
Write(X:4);
End;
Trang 26End.
2 Các thủ tục và hàm xử lý tệp của Turbo Pascal
- Filesize( Biến tệp); hàm cho số phần tử của tệp và
nhận giá trị bằng 0 khi tệp rỗng
- Filepos(Biến tệp); Hàm cho giá trị tức thời của con trỏ
tệp với phần tử đầu tiên đợc đánh số là 0
- Seek( Biến tệp, N0); Thủ tục đặt cửa số tệp vào vị trí thứ N0 (với phần tử đầu tiên đợc đánh số là 0)
- IOResult: Integer Hàm cho biết kết quả của thao tác
vào ra Hàm cho giá trị bằng 0 nếu thao tác vào ra thực hiện tốt Cho giá trị khác 0 nếu thao tác vào ra lỗi
- Erase( Biến tệp); Thủ tục xoá file trên đĩa
- Rename( Biến tệp, Str); Thủ tục thay đổi tên tệp bởi
xâu Str
B Tệp văn bản (Text file)
I Khai báo:
Var Biến Tệp văn bản : Text;
Các phần tử của tệp Text là các kí tự, song Text File khác với File ofchar ở chỗ Text File đợc tổ chức thành từng dòng, với độ dài mỗidòng khác nhau nhờ dấu hết dòng hay dấu chấm:
CR(# 13): nhảy về đầu dòng
LF( # 10):nhảy thẳng xuống dòng tiếp theo
II Các thao tác:
Trang 28- Nên kiểm tra sự tồn tại của tệp văn bản trớc khi quyết định
mở nó theo kiểu gì
2 Ghi vào tệp văn bản:
- Việc ghi dữ liệu lên tệp văn bản đợc thực hiện giống nh việc
đa dữ liệu lên màn hình hay ra máy in nhờ các thủ tục Write vàWriteln
- Thông tin trên tệp đợc tổ chức thành các dòng kí tự có độdài khác nhau Các dòng đợc phân cách nhau bởi một cặp hai ki
tự điều khiển là CR( #13) và LF(#10)
Write( biến tệp, danh sách các tham số);
(Ghi giá trị các tham số lên tệp)
Writeln(biến tệp, danh sách các tham số);
(Sau khi ghi giá trị các tham số lên tệp thì tự động ghi
Trang 29Close(f);
End
-> 3 4 5 CR LF 6 7 CR LF 8 CR LF EOF (1) (2) (3)
3 Đọc từ tệp văn bản:
- Đọc từ tệp văn bản giống nh việc đọc dữ liệu từ bàn phím
Thủ tục: Read( biến tệp, danh sách các biến);
Readln( biến tệp, danh sách các biến);
Readln( biến tệp); (nhảy qua một dòng trên tệp )
Trang 30 Khi đọc ta đợc kết quả: Tuoi =30 425, Bac luong = 0
Qui tắc: Để đọc đúng các dữ liệu, khi ghi cần thực hiện theo quitắc :
- Mỗi khi kí tự hoặc dãy kí tự ghi trên một dòng
- Với các giá trị số (nguyên, thực) thì:
+ Hoặc mỗi giá trị ghi trên một dòng
+ Hoặc nhiều giá trị ghi trên một dòng nhng các giá trị cần
đợc tách biệt bởi ít nhất một khoảng trống
Ví dụ áp dụng: Viết chơng trình nạp tên tệp từ bàn phím.Nếu tệp cha tồn tại thì xây dựng một tệp mới ghi các giá trịnguyên lên đó Nếu đã tồn tại, ghi bổ xung lên nó Sau đó, đọctất cả các số liệu từ tệp đang xét
Program tepvb;
Uses crt;
Var f: Text;
Ten: string[12] ; a,b,i: integer ; begin
Write(‘nhap ten tep:’);readln(ten);
{$I-}