Do đó trong giáo trình này một phần thích đáng được dành cho các kỹ thuật sửa lỗi và chống lỗi.. CHƯƠNG I LÀM QUEN VỚI LẬP TRÌNH I-1 CÁC KHÁI NIỆM MỞ ĐẦU: Chúng ta sẽ dùng một vài chươn
Trang 1TRƯỜNG ĐẠI HỌC ĐÀ LẠT
F 7 G
GIÁO TRÌNH
KỸ THUẬT LẬP TRÌNH
PASCAL NGUYỄN DANH HƯNG
2001
Trang 2MỤC LỤC
MỤC LỤC 1
LỜI NÓI ĐẦU 4
-Chương I LÀM QUEN VỚI LẬP TRÌNH 5
I1 CÁC KHÁI NIỆM MỞ ĐẦU: 5
I2 BIẾN VÀ NHẬP DỮ LIỆU 7
I3 XUẤT DỮ LIỆU 9
I.4 LỆNH GÁN VÀ BIỂU THỨC 10
I5 CÁC HÀM CHUẨN 12
I6 CHỐNG LỖI VÀ SỬA LỖI 13
-Bài đọc thêm Vẻ đẹp của giải thuật 14
BÀI TẬP CHƯƠNG I 16
-Chương II THỦ TỤC và HÀM 18
II1 LẬP TRÌNH VỚI THỦ TỤC 18
II.2 BIẾN TOÀN CỤC VÀ BIẾN ĐỊA PHƯƠNG 19
II.3 THỦ TỤC CÓ THAM SỐ 21
II.4 HÀM 22
II.5 PHƯƠNG PHÁP LẬP TRÌNH TỪ TRÊN XUỐNG 23
II.6 CHỐNG LỖI VÀ SỬA LỖI 24
BÀI TẬP CHƯƠNG II 26
-Chương III CASE VÀ FOR 29
III1 LẬP TRÌNH VỚI CẤU TRÚC CASE 29
Khái niệm hành động của chương trình Pascal 30
III2 LẬP TRÌNH VỚI CẤU TRÚC FOR 31
III3 CHỐNG LỖI VÀ SỬA LỖI: 35
BÀI TẬP CHƯƠNG III 39
-Chương IV IF WHILE REPEAT…UNTIL 42
IV1 BIỂU THỨC BOOLEAN 42
IV2 LẬP TRÌNH VỚI CẤU TRÚC IF 42
IV3 CẤU TRÚC VÒNG LẶP KHÔNG XÁC ĐỊNH 46
IV4 ĐỆ QUY 53
IV5 SỬA LỖI VÀ CHỐNG LỖI 55
BÀI TẬP CHƯƠNG IV 58
Chương V PHƯƠNG PHÁP LẬP TRÌNH 64
V1 PHÂN TÍCH VÀ ĐẶC TẢ VẤN ĐỀ: 64
-V-2.CHỌN LỰA CẤU TRÚC DỮ LIỆU VÀ PHÁT TRIỂN THUẬT TOÁN: 65
V3.MÃ HOÁ CHƯƠNG TRÌNH: 66
Trang 3V4 THỰC HIỆN VÀ THỬ CHƯƠNG TRÌNH 68
V5 BẢO TRÌ CHƯƠNG TRÌNH: 68
BÀI TẬP CHƯƠNG V 69
Chương VI MỞ RỘNG KIỂU DỮ LIỆU THỨ TỰï 70
VI –1 KIỂU THỨ TỰ DO NGƯỜI DÙNG ĐỊNH NGHĨA 70
VI2 KIỂU MIỀN CON 72
BÀI TẬP CHƯƠNG VI 74
-Chương VII MẢNG và CHUỖI 75
VII1 MẢNG: 75
Định nghĩa và khai báo mảng 75
Truy xuất mảng 75
Mảng và vòng lặp for 76
VII2 SẮP XẾP 78
VII3 TÌM KIẾM 82
Tìm tuần tự 82
Tìm kiếm nhị phân 83
KHI NÀO NÊN DÙNG MẢNG? 85
VII4 CHUỖI 86
VII5 SỬA LỖI VÀ CHỐNG LỖI: 91
Từ khoá Pascal mới 93
Khái niệm mới 93
BÀI TẬP CHƯƠNG VII 94
Chương VIII KIỂU RECORD 97
VIII1 RECORD CÓ CẤU TRÚC CỐ ĐỊNH: 97
VIII2 RECORD CÓ CẤU TRÚC THAY ĐỔI: 99
Từ khoá Pascal mới 100
Khái niệm mới 100
BÀI TẬP CHƯƠNG VIII 101
-Chương IX KIỂU FILE 102
IX1 FILE VĂN BẢN 102
IX2 FILE ĐỊNH KIỂU: 105
IX3 TRUY CẬP NGẪU NHIÊN TRÊN FILE ĐỊNH KIỂU 107
IX4 TRỘN FILE 110
IX5 CHỐNG LỖI VÀ SỬA LỖI: 112
Từ khoá Pascal mới 112
Khái niệm mới 113
BÀI TẬP CHƯƠNG IX 114
-Chương X KIỂU TẬP HỢP (SET) 115
Trang 4X1 KIỂU TẬP HỢP: 115
Ví dụ 115
X2 LẬP TRÌNH VỚI KIỂU TẬP HỢP: 116
Từ khoáù Pascal mới 119
Khái niệm mới 119
BÀI TẬP CHƯƠNG X 120
PHỤ LỤC A 121
-CÁC THÔNG BÁO LỖI CỦA TURBO PASCAL KHI BIÊN DỊCH - 121 PHỤ LỤC B 131
CÁC THÔNG BÁO LỖI KHI CHẠY CHƯƠNG TRÌNH 131
TÀI LIỆU THAM KHẢO 133
Trang 5-LỜI NÓI ĐẦU
Ngày nay cùng với sự phát triển mạnh mẽ của Tin học, lập trình trở nên một kỹ năng cần thiết cho mọi cán bộ khoa học kỹ thuật Giáo trình này nhằm giúp cho sinh viên Vật lý tìm hiểu về kỹ thuật lập trình
Ngôn ngữ được chọn là Pascal chuẩn, có bổ sung một vài phần mở rộng của TurboPascal Mặc dù ngày nay có nhiều ngôn ngữ hiện đại hơn, Pascal vẫn là ngôn ngữõ thích hợp nhất cho một giáo trình căn bản về lập trình Các kỹ thuật lập trình chủ yếu được trình bày tương đối đầy đủ, ngoại trừ các kỹ thuật dùng con trỏ Các ví dụ được chọn lọc ở nhiều mức độ khác nhau, không chỉ dừng ở mức độ minh hoạ ngôn ngữ, mà còn để cho sinh viên làm quen với những thuật toán thông dụng có độ phức tạp vừa phải
Ngoài ra qua thực tế giảng dạy, chúng tôi nhận thấy khi lập trình sinh viên phạm rất nhiều lỗi cơ bản Do đó trong giáo trình này một phần thích đáng được dành cho các kỹ thuật sửa lỗi và chống lỗi Hy vọng là phần này sẽ giúp ích nhiều cho các bạn sinh viên
Giáo trình nay được in lần đầu vào năm 2001 Trong lần tái bản này, chúng tôi sửa chữa những điểm sai sót và bổ sung môt vài điểm mới Đặc biệt là chúng tôi đưa vào một số lượng khá lớn các bài tập Những bài tập này được chọn lọc để sinh viên áp dụng kỹ thuật lập trình trong việc giải quyết các bài toán khoa học kỹ thuật
Chúng tôi chân thành cảm ơn sự góp ý của các đồng nghiệp cũng như các bạn sinh viên để làm cho giáo trình ngày càng hoàn thiện
Đà lạt tháng 5-2004 Nguyễn Danh Hưng Huỳnh Thị Thu Thuỷ
Trang 6CHƯƠNG I LÀM QUEN VỚI LẬP TRÌNH
I-1 CÁC KHÁI NIỆM MỞ ĐẦU:
Chúng ta sẽ dùng một vài chương trình rất đơn giản để minh hoạ các khái niệm của Pascal
program Dautien; { Đây là chương trình đầu tiên}
begin
end
Từ khoá đầu tiên của mọi chương trình Pascal (dù không bắt buộc) là
program Trong giáo trình này các từ khoá sẽ được in đậm Sau từ
khoá program là tên của chương trình Tên của chương trình phải đặt
theo qui tắc đặt tên
Tên phải bắt đầøu bằng một chữ cái và có thể chứa một dãy bất kỳ cácchữ cái và chữ số
Chú ý là trong tên không được phéùp có khoảng trống Nếu cần tách các từ có thể dùng dấu nối _ Ký tự chuẩn của Pascal là bảng mã ASCII do đó các tên tiếng Việt có dấu cũng là không hợp lệ Tên cũng không được trùng với các từ khoá của Pascal, do đó các từ này còn được gọi là
từ dành riêng
Ví dụ: R2D2 So_tien là các tên hợp lệ
2XY So tien Số tiền là các tên không hợp lệ
Các chú thích được đặït trong cặp dấu {} hoặc (* *)
Ví dụ: { Đây là chú thích }
(* Đây cũng là chú thích *)
Dòng đầu tiên của một chương trình gọi là đầu chương trình Một dấu
chấm phẩy( ; )được dùng để ngăn cách nó với dòng kế tiếp
Ví dụ : program Dautien;
Chúng ta có sơ đồ cú pháp cho đầu chương trình như sau:
đầu chương trình
program Ỉ tên Ỉ;
Trang 7Trong chương trình Dautien, vì không có tính toán gì cả nên chúng ta không dùng tới biến Do đó ngay sau phần đầu chương trình, chúng ta
đi ngay đến phần lệnh Phần này bắt đầu bằng từ dành riêng begin
Phần lệnh bao gồm dãy các lệnh Việc in ra một hàng trong Pascal
được thực hiện bởi một thủ tục chuẩn là writeln (đọc là write line)
Ví dụ:
writeln (‘Mọi thứ nằm trong dấu nháy sẽ được in ra ‘)
(Văn bản trong dấu nháy có thể là tiếng Việt, phụ thuộc vào hệ cài đặt)
Chương trình Pascal được kết thúc bằng từ dành riêng end Chú ý từ end kết thúc chương trình luôn có dấu chấm đi theo
Bạn ăn cơm chưa?
Chú ý là sau lệnh writeln đầu tiên có dấu ; Dấu ; trong Pascal dùng để ngăn cách giữa hai câu lệnh, không phải là phần bắt buộc của câu lệnh (Đây là điểm khác biệt với ngôn ngữ C )
Để in ra không xuống hàng, ta dùng thủ tục chuẩn write
program Mot_hang;
{Minh hoạ cách dùng write}
begin
write (‘ Những từ này’);
write ( ‘sẽ được in ra’);
writeln(‘trên cùng một hàng’)
Trang 8I-2 BIẾN VÀ NHẬP DỮ LIỆU
Program Nhapso;
{ Nhập và và in ra một số }
var So : integer; { Khai báo một biến}
Biến phải được khai báo thuộc một kiểu dữ liệu nào đó
Bốn kiểu dữ liệu nguyên thuỷ của Pascal là integer, char, boolean và real
Các kiểu integer, char và boolean được gọi là các kiểu thứ tự( hay còn
gọi là kiểu vô hướng đếm được)
Qui tắc: Biến nào trị nấy, tức là kiểu dữ liệu của biến và trị của nó phải phù hợp với nhau
Việc khai báo biến đước bắt dầu bằng từ dành riêng var (viết tắt của từ
variable), tiếp đó là danh sách các biến cùng với kiểu dữ liệu tương ứng
(tên biến được phân cách với kiểu dữ liệu bởi dấu :) , các biến khai báo được phân cách bởi dấu ;
var sothutu: integer;
Trang 9Chúng ta có thể khai báo nhiều tên biến với cùng một kiểu dữ liệu, lúc này các tên biến cách nhau bởi dấu ,
var sothutu, vithu , siso : integer;
dtoan, dly, dhoa : real;
Chú ý là ngôn ngữ Pascal không phân biệt chữ hoa và chữ thường, do đó các tên biến như sau là giống nhau
Với khai báo trên, chúng ta có thể viết lại như sau:
var sothutu, vithu , siso : integer; dtoan, dly, dhoa : real;xeploai:
Các cách nhập dữ liệu
readln có thể chứa danh sách nhiều biến, ngăn cách bằng dấu phẩy
readln(so, tuoi, luong)
Khi nhập dữ liệu integer hoặc real các khoảng trống được bỏ qua Kết thúc nhập bằng phím Enter
Nếu nhập AB thì Chu1 = ‘A’, Chu2= ‘B’ nhưng nếu nhập A B thì
Chu1 = ‘A’, Chu2= ‘ ’
readln không kèm theo biến tức là có dạng readln; đòi hỏi người nhập
gõ phím Enter
Một dạng khác của lệnh nhập dữ liệu là read Lệnh này không đòi hỏi
kết thúc nhập bằng phím Enter (thường dùng khi đọc dữ liệu từ tập tin)
Trang 10Qui tắc: Phải đảm bảo nhập đủ dữ liệu
I-3 XUẤT DỮ LIỆU
program Tinhtoandongian;
{Minh hoạ việc biểu thức được tính trước khi xuất}
var So1,So2 :real;
Định dạng dữ liệu xuất
Dữ liệu xuất nếu không có chỉ ra định dạng sẽ thuận theo định dạng mặc nhiên của Pascal
program Dinhdangmn;
{Trình bày định dạng mặc nhiên của Pascal}
var Chu : char;
Trang 11Nhập vào một chữ cái, một số thực và một số nguyên
B 281.5 66 Å|
B
2.8150000000000000E+02
66
Khi xuất dữ liệu, số nguyên và số thực được canh biên phải với một số
khoảng cố định gọi là độ rộng trường Thường độ rộng trường in cho số
ra canh biên phải Ví dụ , nếu I = 123 ta có
writeln(‘Số nguyên = ’,I:1)
Chú ý trong ví dụ cuối cùng ta thấy số thực được làm tròn
Lệnh writeln không có đối số tức là dạng writeln; sẽ xuốâng dòng mới
I.4 LỆNH GÁN VÀ BIỂU THỨC
Xét chương trình sau:
program Tinhdientich;
{ Minh họa cách dùng lệnh gán }
var dai, rong, dientich : real;
begin
Trang 12write (‘Nhập vào chiều dài : ‘);
readln(dai);
write (‘Nhập vào chiều rộng : ‘);
readln(rong);
dientich := dai * rong;
writeln (‘ Diện tích hình chữ nhật : ‘, dientich:8:2);
Toán tử nguyên
Phép chia nguyên div 10 div 3 (=3)
Phép lấy phần dư mod 10 mod 3 ( = 1)
Nếu biểu thức chứa số nguyên và số thực thì kết quả sẽ là số thực Kết quả của phép chia thực (/) là số thực
Độ ưu tiên toán tử
* / div mod :Các toán tử này có độ ưu tiên cao hơn
+ -
Có thể thay đổi độ ưu tiên toán tử bằng cách dùng dấu ngoặc
Trang 13I-5 CÁC HÀM CHUẨN
Các hàm số học
hai
trunc(3.5)=3
Các hàm thứ tự
pred(‘B’)=’A’
chr(65)=’A’
Các hàm boolean
eoln Trả về true nếu hết dòng
Để sử dụng các hàm , chúng ta phải dùng lời gọi hàm gồm tên hàm và đối đặt trong dấu ngoặc
Các hàm như round và trunc được gọi là các hàm chuyển kiểu vì chúng
chuyển dữ liệu từ kiểu này sang kiểu khác
Khai báo hằng
Để thuận tiện trong tính toán, trong chương trình đôi khi cần khai báo hằng Xét chương trình sau:
program Tinh chuvi_hinhtron;
const pi = 3.1416
var chuvi, duongkinh : real;
begin
Trang 14write(‘Nhập vào đường kính: ‘);
readln(duongkinh);
chuvi := pi * duongkinh;
writeln(‘Chu vi của hình tròn là:’,chuvi)
end
Cú pháp khai báo hằng
const tên hằøng = trị;
I-6 CHỐNG LỖI VÀ SỬA LỖI
Sửa lỗi (debug) là tìm ra lỗi sai trong chương trình
Chống lỗi (antibug)là viết chương trình sao cho ít gặp lỗi
Chống lỗi và sửa lỗi là hai việc cực kỳ quan trọng trong kỹ thuật lập trình Trong giáo trình này, chúng ta sẽ dành một phần thích đáng cho các kỹ thuật này
Các lỗi nói chung chia làm hai loại: lỗi cú pháp và lỗi ngữ nghĩa Các
lỗi cú pháp(syntax error) thường được phát hiện ngay lúc biên dịch Ví dụ lỗi thường gặp là thiếu dấu ; để ngăn cách hai lệnh Lúc biên dịch , sẽ có thông báo lỗi:
; expected Các lỗi này thường dễ sửa Ngay từ đầu bạn nên rèn luyện thói quen viết đúng cú pháp
Các lỗi trầm trọng hơn là lỗi lúc chạy chương trình(run-time error) Ví dụ thường gặp là lỗi chia cho số 0:
Divided by zero
Các lỗi này cũng có thể sửa được vì máy tiùnh có báo lỗi Nguy hiểm
nhất là các lỗi ngữ nghĩa(logic) Những lỗi này khó sửa hơn vì chương
trình không sai về mặt cú pháp mà chỉ sai về ý nghĩa Lỗi càng khó phát hiện vì có thể chỉ gặp khi dùng với một số dữ liệu nào đó Do đó thử chương trình với nhiều dữ liệu khác nhau là rất quan trọng
Quy tắc vàng về sửa lỗi Đừng sửa cái không hư Đừng làm những thay đổi ngẫu nhiên Một vài lỗi thường gặp trong chương này:
- Khởi tạo khi khai báo biến (như kiểu ngôn ngữ C)
Trang 15Ví dụ var Trial :=: integer;
Test: char; Test := ‘A’;
- Dùng lệnh gán không hợp lệ
A:=B := C:=D :E := 0;
- Dùng sai đối của hàm, ví dụ dùng đối số âm với hàm sqrt
Tóm tắt:
Trong chương này chúng ta đã biết các khái niệm sau:
• Cấu trúc của một chương trình Pascal gồm có
phần đầu chương trình
phần khai báo hằng
phần khai báo biến
- cách đặt tên chương trình, tên hằng, biến
- lệnh gán và biểu thức
- các hàm chuẩn
Từ khoá Pascal mới
program begin var end write writeln
read readln integer char boolean real
:= div mod const
sqr sqrt
sin cos arctan
ln exp
abs round trunc
pred succ ord chr
Khái niệm mới
chương trình hằng biến biểu thức toán tử
nhập xuất giải thuật
Bài đọc thêm Vẻ đẹp của giải thuật
Một chương trình đẹp là điều chúng ta luôn mơ ước Một chương trình
là đẹp nếu thuật toán của nó đơn giản và gọn gàng, nhưng giải quyết vấn đề một cách trong sáng và toàn vẹn Tuy nhiên, một giải thuật đẹp không chỉ giới hạn trong phạm vi lập trình Chúng ta xét một vài ví dụ trong đó có giải thuật đẹp
Trang 16Xét bài toán sau: Một người đạp xe đạp đang ở cách nhà 2km Người đó đạp xe về nhà với vận tốc không đổi 20km/h Tại thời điểm này một con ruồi đậu trên mũi người đi xe đạp, bay về nhà rồi quay ngay lại chỗ người đi xe đạp rồi lại quay về nhà và cứ tiếp tục như thế cho đến khi người đi xe đạp về đến nhà và kẹp chết con ruồi Giả sử con ruồi bay với vận tốc không đổi là 40km/h Hãy tìm quãng đường con ruồi đã bay?
Trước khi đọc tiếp bạn hãy tự giải bài toán này
Lời giải là như sau Vì con ruồi bay với vận tốc không đổi nên ta có Quãng đường = Vận tốc * Thời gian
Mặt khác từ chuyển động đều của người đi xe đạp ta có:
Thơì gian = 2/ 20 = 0,1h
Vậy quãng đường con ruồi đã bay là:
0,1*40 = 4 km
Rõ ràng đây là một lời giải rất đẹp
Xét ví dụ khác Năm 1686, khi Gauss 9 tuổi, thầy giáo của Gauss muốn cho cả lớp làm việc trọn buổi sáng, đã ra bài tập sau đây
Cộng tất cả các số từ 1 đến 100
Không ngờ chỉ một chút sau khi ra bài tập, Gauss đã giải xong bài toán Bạn thử nghĩ xem Gauss đã làm như thế nào?
Cách giải của Gauss là chia các số từ 1 đến 100 thành 50 cặp,mỗi cặp gồm 2 số cách đều nhau từ 2 biên.Tổng của mỗi cặp là 101 và có tất cả 50 cặp như vậy Do đó tổng cần tìm là
50 * 101 = 5050
Bạn có thể nói là: Lời giải đó dễ hiểu, nhưng nghĩ ra mới khó Dù sao, cố gắng thử bước đầu tiên bằng cách tự đặt câu hỏi ‘Có công thức để giải bài toán này, và những công thức khác tương tự không?” cũng không phải là quá khó Dần dần bạn sẽ quen suy nghĩ và tự tìm ra được những lời giải đẹp
Trang 17BÀI TẬP CHƯƠNG I
1.Viết chương trình tính năng lượng theo công thức E= mc2 khi biết khối lượng
2 Độ rọi của một nguồn sáng tới một điểm giảm tỉ lệ nghịch với bình phương khoảng cách Viết chương trình nhập vào khoảng cách x,y và độ rọi ở khoảng cách x, chương trình tính ra độ rọi ở khoảng cách y
3.Viết chương trình tính quãng đường ra km khi biết số năm ánh sáng
4.Thay mỗi cặp lệnh gán dưới đây bằng một lệnh gán
5.Viết chương trình nhập vào khoảng thời gian tính bằng giây rồi đổi
ra giờ, phút, giây
6.Cho tam giác vuông ABC vuông ở A Các cạnh góc vuông là a và
b được tính theo cạnh huyền c theo các công thức sau
writeln(‘Chiều dài cạnh a là:’,a);
writeln(‘Chiều dài cạnh b là:’,b);
end
Trang 187.Chu kỳ của con lắc đơn được cho bởi công thức
) 2 1 ( ) 2 1 (x x y y
Viết chương trình tính khoảng cách với toạ độ hai diểm được nhập vào
9.Các kỹ sư thường đo tỉ số giữa hai công suất bằng decibel Tỉ số
giữa hai công suất tính theo decibel là
1
2 10
log 10
P
P
dB=
trong đó P2 là mức công suất đang xét và P1 là mức công suất quy
chiếu Giả sử P1 là 1 milliWatt; viết chương trình nhận vào giá trị P2 và tính ra giá trị dB
10.Tần số cộng hưởng của một mạch thu tín hiệu cho bởi
Viết chương trình tính f0 theo L vàC nhập vào
11.Lực hấp dẫn giữa hai vật có khối lượng m1 và m2 được cho bởi
2 2 1
r
m Gm
F =
trong đó G là hằng số hấp dẫn (6,672x10-11Nm2/kg2), và r là khoảng cách giữa hai vật Viết chương trình tính lực hấp dẫn giữa hai vật khi biết khối lượng và khoảng cách giữa chúng Kiểm tra chương trình bằng cách tính lực tác dụng lên một vệ tinh 800kg ở quỹ đạo cách trái đất 38000km (Khối lượng trái đất là 5,98x1024kg)
Trang 19CHƯƠNG II THỦ TỤC VÀ HÀM
II-1 LẬP TRÌNH VỚI THỦ TỤC
Các chương trình trong chương đầu tiên đều đơn giản Khi viết những chương trình phức tạp hơn, chúng ta thường phải chia chương trình
thành các phần nhỏ Một phần nhỏ đó là một thủ tục
Ví dụ, xét chương trình đổi chỗ 2 số Chúng ta cần làm ba việc: nhập hai số, đổi chỗ 2 số, rồi in kết quả ra Chúng ta viết mỗi việc đó thành một thủ tục
program Doicho;
var So1, So2 : integer;
procedure Nhapso;
begin
writeln(‘ Chương trình này đổi chỗ hai số nguyên’ );
write(‘Nhập số thứ nhất’); readln(So1);
write(‘Nhập số thứ hai’); readln(So2);
Trang 20phần khai báo hằng
phần khai báo biến
phần khai báo các thủ tục
phần lệnh (thân chương trình chính)
II.2 BIẾN TOÀN CỤC VÀ BIẾN ĐỊA PHƯƠNG
Các biến toàn cục là các biến đước khai báo trong chưong trình chính Chúng có thể được dùng ở mọi nơi trong chương trình Các biến địa phương là các biến được khai báo trong các chương trình con và chúng
chỉ được sử dụng trong các chương trình con đó thôi Khi chương trình
con kết thúc thì các biến này cũng mất đi Phạm vi của một biến là một phần của chương trình (gọi là khối) sử dụng biến đó Pascal là
ngôn ngữ có cấu trúc khối :
procedure B
procedure D
program A
Trang 21Kết quả cho ra:
Chú ý:
Trang 22• Chúng ta cần khai báo biến trước khi sử dụng chúng trong một
thủ tục
• Trong cùng một khối, một thủ tục có thể gọi một thủ tục khác đã
được khai báo trước nó
II.3 THỦ TỤC CÓ THAM SỐ
Chương trình đổi chỗ hai số có thể viết lại như sau bằng cách dùng thủ tục có tham số
program Doicho;
var Solon, Sobe : integer;
procedure Doihaiso( var So1,So2:integer);
var Tam : integer;
Tham số được chia làm hai loại: tham trị và tham biến
Tham trị là biến điạ phương của chương trình con Trị đầu của nó được truyền bởi đối trong lời gọi thủ tục
Vì tham trị là biến địa phương, sự thay đổi của nó không ảnh hưởng gì đến trị của đối truyền cho nó
Tham biến là biến địa phương dùng thay cho một biến toàn cục Nó là
một tên khác (bí danh) của đối số
Sự thay đổi lên tham biến làm thay đổi trực tiếp lên đối mà nó thay tên
Trang 23Sự khác nhau giữa hai loại tham số này được minh họa bởi chương trình sau:
program Thu_Thamso;
var a,b : integer;
procedure Thamso( x : integer; var y:integer);
Ta nên nhớ quy tắc sau khi truyền đối cho tham số:
Quy tắc: Đối của tham trị có thể là một hằng, một biến hay một biểu thức Đối của tham biến chỉ có thể là biến
II.4 HÀM
Giống như thủ tục, hàm cũng là một loại chương trình con Khác biệt giữa hàm và thủ tục là hàm luôn luôn trả về một giá trị
Ví dụ: Hàm sau tính quãng đường đi theo thời gian và vận tốc
function QuangDuong(vantoc:real ; thoigian : real):real;
Trang 24function tên hàm(danh sách tham số):kiểu dữ liệu trả về ;
Phần khai báo biến
var So, Cotang :real;
function Tang(gocdo:real ): real;
Ví dụ trên cũng cho thấy các hàm có thể lồng nhau
II.5 PHƯƠNG PHÁP LẬP TRÌNH TỪ TRÊN XUỐNG
Phương pháp lập trình từ trên xuống gồm các bước sau:
Trang 251 Chia bài toán vấn đề ra thành những phần nhỏ
2 Nếu có thể lập trình được ngay cho một phần nhỏ thì viết thủ tục cho phần này Nếu một phần vẫn còn quá phứùc tạp thì chuyển sang bước 3
3 Chia phần phứùc tạp này thành những phần đơn giản hơn rồi viết thủ
tục cho các phần đơn giản này Việc làm này gọi là tinh chế từng bước
Xét ví dụ về việc lập trình quản lý thư viện
Đầu tiên , chúng ta phân chia việc quản lý thư viện ra thành những công việc sau:
• Quản lý sách
• Quản lý thẻ
• Quản lý người đọc
Tiếp đó, chúng ta thực hiện từng công việc trên
a/ Quản lý sách : Công việc này bao gồm
• Làm thư mục sách
• Quản lý số sách hiện có
b/ Quản lý thẻ
•
…
II.6 CHỐNG LỖI VÀ SỬA LỖI
Một kỹ thuật chống lỗi quan trọng là lập trình có tính đơn thể (modular)
Một chương trình là có tính đơn thể nếu các chương trình con của nó là độc lập tương đối với nhau và đối với chương trình chính Các chương trình con có thể được thử riêng bằng các dữ liệu giả trước khi ghép vào chương trình chính Nếu chương trình con có lỗi thì lỗi đó có thể được cô lập và sửa dễ dàng
Một đặc trưng khác của lập trình đơn thể là hạn chế dùng biến toàn cục Nói chung biến toàn cục không nên dùng trong chương trình con
Sự thay đổi của biến toàn cục trong chương trình con có thể gây ra hiệu ứng phụ Hiệu ứng phụ làm cho chương trình khó đọc và khó hiểu
Thay vì dùng biến toàn cục nên dùng tham số Nếu một thủ tục chỉ
dùng một trị chúng ta khai báo một tham trị Nếu thủ tục thay đổi hoặc trả về một trị chúng ta sử dụng tham biến
Trang 26Các lỗi thường gặp khi truyền đối cho tham số là thiếu hoặc thừa đối số hoặc kiểu dữ liệu của đối số và tham số là không phù hợp
Quy tắc vàng thứ hai về sửa lỗi Khi bạn tin chắc rằng mọi điều bạn làm là đúng, và chương trình của
bạn vẫn không chạy, một trong những điều bạn tin chắc là sai
Từ khoá Pascal mới:
procedure function
Khái niệm mới:
Chương trình con Chương trình chính Thủ tục Hàm Danh sách tham số Lời gọi thủ tục Lời gọi hàm Phạm vi
Biến toàn cục Biến địa phương Khối chương trình
Kỹ thuật lập trình từ trên xuống Tính đơn thể
Trang 27BÀI TẬP CHƯƠNG II
1.Kết quả của chương trình sau là gì?
Program Quiz;
Var A,B,C :integer;
Procedure Subprogram(D:integer;var E:integer;C:integer);
Trang 283 Kết quả của chương trình sau là gì?
Procedure AddAndDouble(var First,Second:integer);
Begin
First := 1+First;
Second := 2*Second End;
4 Viết chương trình tính điện trở tương đương của các cách ghép khác nhau của 3 điện trở R1,R2,R3 Chú ý cách dùng thủ tục và cách truyền tham số
5 Viết chương trình tính điện dung tương đương của các cách ghép khác nhau của 3 tụ điện C1,C2,C3
6 Viết hàm tính luỹ thừa
7.Viết các hàm để tính các hàm lượng giác hypecbolic
2 )
sinh(
x x
e e x
−
−
=
2 )
cosh(
x x
e e x
−
+
e e
e e
Trang 298.Viết các hàm trong Pascal thể hiện các hàm số thực sau:
f(x,y) = (x+2y)/(x+y)
g(x,y) = (f(x,y)+ f(x,y)/(2f(x,x+y))
Aùp dụng để tính f(a,b) và g(a,b) với a, b nhập từ bàn phím
Trang 30CHƯƠNG III CASE VÀ FOR
Chương này khảo sát cấu trúc case và for Đó là những cấu trúc điều
khiển có biểu thức điều khiển là kiểu thứ tự
III-1 LẬP TRÌNH VỚI CẤU TRÚC CASE
Cấu trúc case dùng khi có nhiều lựa chọn
Xét chương trình sau:
program InSoNgay;
{In số ngày của một tháng không tính tới năm nhuận}
var thang : integer;
4, 6, 9, 11 :writeln(‘ Tháng’,thang, ‘co 30 ngày !’);
2 : writeln(‘ Tháng’,thang, ‘co 28 ngày !’);
end {case}
end
Dạng thông thường của cấu trúc case như sau:
case biểu thức chọn of
hằng 1: hành động ; hằng 2: hành động ; hằng 3, hằng 4, hằng 5: hành động ;
… hằng N: hành động
end;
Biểu thức chọn là biểu thức kiểu thứ tự tức là kiểu integer, char hoặc boolean và thường là một biến
Trang 31Các hằng phải cùng kiểu với biểu thức chọn
Danh sách các hằng phải chứa đủ các giá trị có thể có của biểu thức chọn
Nếu biểu thức chọn có trị không nằm trong danh sách các hằng thì chương trình có lỗi
Khái niệm hành động của chương trình Pascal
Trong bản thảo gốc của ngôn ngữ Pascal Niklaus Wirth đã chỉ ra rằng:
“Hành động là bản chất cho mọi chương trình máy tính…Một chương trình phải làm một việc nào đó lên dữ liệu của nó – ngay cả khi hành động đó là không làm gì cả! “
Một chương trình Pascal có nhiều loại hành động được liệt kê sau đây:
lệnh gán lời gọi thủ tục
Chúng ta đã biết khái niệm lệnh gán và lời gọi thủ tục Lệnh hợp thành
là một nhóm lệnh đặt giữa begin và end
Một dấu chấm phẩy có thể dùng để biểu diễn một lệnh rỗng như trong
ví dụ sau đây:
procedure DocSoDo;
begin
case sodo of
0: writeln(‘Dung cu bo qua so do.’);
1,2,3 :writeln(‘So do qua nho’);
4,5,6,7 : ; {lệnh rỗng}
8,9, 10: writeln(‘So do qua lon.’);
end {case}
end;
Cấu trúc case lồng nhau
Vì hành động có thể là lệnh cấu trúc nên chúng ta có thể gặp cấu trúc này lồng trong cấu trúc khác sau đây chúng ta xét một ví dụ cấu trúc
case lồng nhau
Trang 32Chương trình sau mô tả trò chơi oẳn tù tì ( one, two, three)
Ta ký hiệu B là búa, K là kéo, T là túi
‘K’ : writeln(‘ Keo hue keo’);
‘B’ :writeln(‘ Keo bi bua dap gay’);
‘T’:writeln (‘Keo cat tui’);
end; {case }
‘B’ : case nguoi2 of
‘K’ : writeln(‘ Bua dap gay keo’);
‘B’ :writeln(‘ Bua hue bua’);
‘T’:writeln (‘Bua bi tui boc lai’);
end; {case }
‘T’ : case nguoi2 of
‘K’ : writeln(‘ Tui bi keo cat ’);
‘B’ :writeln(‘ Tui boc bua’);
‘T’:writeln (‘Tui hue tui’);
end; {case } end {case ben ngoai}
Trang 33Cú pháp câu lệnh for
for biếnđếm := trị đầu to trị cuối do hành động;
Vòng lặp có thể lặp từ trên xuống, khi đó câu lệnh có dạng :
for biến đếm := trị đầu downto trị cuối do hành động;
Chú ý : biến đếm phải là kiểu thứ tự nghĩa là không nhất thiết phải là kiểu integer
Khi viết vòng for ta phải tuân theo 5 quy tắc sau đây:
1 Biến đếm, trị đầu và trị cuối phải cùng kiểu thứ tự
Lỗi thường gặp là viết vòng for với số thực
Ví dụ:
for dem = 1.0 to 5.0 do hanhdong;
2 Biểu thức cho trị đầu và trị cuối phải có giá trị xác định khi bước vào vòng lặp Hệ quả là trị đầu và trị cuối không thể đặt lại trong thân vòng lặp
Ví dụ trong đoạn chương trình sau
lower := 1;
upper := 3;
for counter := lower to upper do
Trang 34chỉ in ra Hello 3 lần chứ không phải là 1001 lần
3 Biến đếm phải được khai báo địa phương Như vậy, nếu trong một thủ tục có vòng for thì biến đếm phải khai báo trong thủ tục đó
4 Gán lại trị cho biến đếm trong thân vòng lặp là một lỗi
5 Trị của biến đếm là không xác định khi ra khỏi vòng lặp for
Cấu trúc vòng for lồng nhau
Chúng ta dễ thấy giải thuật của chương trình có thể trình bày như sau:
for số dòng
do in ra một dòng
Mỗi dòng sẽ được in ra bằng cách lập lại các dấu * bằng số cột , tức là
for số cột
do in ra một dấu *
Phối hợp lại ta có thể viết
for số dòng
for số cột
do in ra một dấu *
Trang 35Kỹ thuật phân tích chương trình như trên gọi là phương pháp dùng mã giả Mã giả là một loại ngôn ngữ trung gian giữa ngôn ngữ bình thường
và Pascal Kỹ thuật mã giả được sử dụng rộng rãi trong lập trình Từ mã giả trên ta có chương trình sau
for demcot := 1 to socot do write(‘* ‘);
writeln; {xuống dòng sau khi in ra một dòng}
end {for ben ngoai{
end
Phối hợp cấu trúc for và case
Đôi khi bên trong cấu trúc for có thể cấu trúc case
Ví du: Chúng ta cần viết chương trình in ra dãy số Fibonacci Đó là dãy số tuân theo quy luật là bắt đầu bằng 0 và 1, số tiếp theo sẽ bằng tổng hai số đứng trước Dãy số này có nhiều ứng dụng trong thực tế Chúng ta muốn in ra dãy số này trên màn hình mỗi hàng 5 số , chương trình như sau:
program DaysoFibonacci;
var Dem, Cantren, Sohientai, Sotiep : integer;
procedure TinhSotiep(var Socu, Somoi:integer);
var Tam :integer;
Trang 36Sotiep :=1; {khoi tao day}
for dem := 1 to Cantren do
III-3 CHỐNG LỖI VÀ SỬA LỖI:
Lỗi thường gặp là thiếu end của cấu trúc case, phải đảm bảo luôn luôn kết thúc case bằng một chữ end
Lỗi thường gặp khi viết vòng for là không viết đúng hành động do đặt
sai dấu chấm phẩy Ví dụ:
Trang 37case of
for to downto
Khái niệm mới
cấu trúc case biểu thức chọn biểu thức thứ tự
hành động lệnh hợp thành lệnh cấu trúc lệnh rỗng
vòng lặp for biến đếm cấu trúc lồng nhau
Bài đọc thêm Giải pháp thô sơ và hiệu suất
Chúng ta có thể dùng vòng lặp for để giải quyết bài toán của Gauss
Đó có vẻ là một giải pháp thô sơ Giải pháp thô sơ có nghĩa là chúng ta
dùng một giải pháp không tinh vi lặp lại rất nhiều lần Ví dụ cổ điển về giải pháp thô sơ là câu chuyện về bá tước Monte Cristo Ông không có một kế hoạch tinh vi để vượt ngục Trái lại ông chỉ có một cái muỗng và dùng nó để đào một đường hầm trong 14 năm liền
Thoạt nhìn giải pháp thô sơ có vẻ là một điều tệ hại so với những giải pháp thông minh, đẹp dẽ Tuy nhiên trong thực tế không phải lúc nào cũng vậy, Ví dụ, giả sử bạn muốn tìm số tổ hợp gồm 2 chữ cái khác nhau tạo bởi a,b,c d và e (ví dụ ab,ac,ad.v.v ) Dĩ nhiên là có công thức để tính điều đó Nhưng trong khi bạn cố tìm ra công thức này, bạn có thể viết ra trực tiếp các tổ hợp có thể có rồi đếm và để thời gian suy nghĩ đến những chuyện khác hay hơn
Hãy trở lại với bài toán của Gauss Mặc dù đã có lời giải rất đẹp, chúng
ta có thể giải nó trên máy tính bằng cách cộng lần lượt
program Tinhtong;
var Tong, Dem: integer;
begin
Tong := 0;
for Dem :=1 to 100 do Tong := Tong + Dem;
writeln( ‘Tổng là :’,Tong:1)
end
Trang 38Giải pháp thô sơ là một chủ đề nhạy cảm đối với vài lập trình viên vì
một mối quan tâm khác – hiệu suất Một giải pháp sẽ ít hiệu suất hơn
nếu nó tốn nhiều thời gian máy tính hơn Chương trình Tinhtong rõ ràng là kém hiệu suất hơn công thức của Gauss, trong trường hợp này tỉ lệ hiệu suất là 1/100 Vậy tại sao phải mất công nghĩ đến những giải pháp thô sơ? Có ba lý do
Lý do 1: Khảo sát giải pháp thô sơ có thể hiểu vấn đề tốt hơn
Giải pháp thô sơ là một chiến lược suy nghĩ, cũng như các chiến lược
suy nghĩ khác Nó dùng để mở rộng vấn đề, để tách biệt vấn đề với các thành phần của nó, để mô phỏng quá trình máy tính giải quyết vấn đề, để tập trung vào chi tiết v.v Đôi khi cách tốt nhất để có một giải
pháp thông minh là tạo ra một giải pháp không thông minh, rồi cải tiến nó
Lý do 2: Hiệu suất là một khái niệm tương đối
Thời gian chạy máy tính không phải là chi phí duy nhất của phần mềm Thời gian của người lập trình thường còn đắt hơn thời gian của máy, và khoảng cách đó ngày càng lớn Điều đó không có nghĩa là phải chấp nhận những phương pháp lập trình kém cỏi Tuy nhiên, khi cố gắng suy nghĩ đến một giải pháp đẹp, phải luôn luôn suy nghĩ đến tỉ số chất lượng/giá cả Hơn nữa một giải pháp “cải tiến” có thể làm cho chương trình phức tạp và khó hiểu
Lý do 3: Giải pháp thô sơ thường dễ áp dụng Chúng thường dễ sửa đổi hơn các giải pháp đẹp
Hãy xét thuật toán của Gauss Nó vô ích để giải những vấn đề tính tổng khác Làm sao để tính tổng bình phương, lập phương, hay căn bậc hai của các số từ 1 đến 100? Giải pháp thô sơ giải quyết nhanh chóng các vấn đề này
Vấn đề cốt lõi của lập trình rút cuộc là chương trình có chạy được không? Trong sách The Psychology of Computer Programing (Tâm lý
lập trình máy tính), Gerald Weiberg đã kể câu chuyện về một lập trình viên chữa cháy cho một dự án sản xuất xe hơi Lập trình viên trước đó của dự án đã ra sức chê bai chương trình của người mới đến là kém hiệu quả, không bằng chương trình đã bị vứt đi của hắn Lập trình viên
Trang 39mới trả lời “Tuy nhiên chương trình của tôi chạy còn của anh thì không Nếu chương trình không cần phải chạy tôi có thể tìm ra thuật toán còn hiệu quả gấp đôi chương trình của anh! “ Vâng, đúng vậy!
Trang 40BÀI TẬP CHƯƠNG III
1.Viết chương trình để tính trọng lựợng của một người tại các thiên thể trong hệ mặt trời so với trọng lựơng của người đó trên trái đất Dùng số liệu trọng lượng tỉ đối trong bảng sau(trọng lượng trên trái đất là 1):
Người dùng chương trình nhập vào chiều dài và chiều rộng
3 Viết chương trình vẽ hình sau:
* * * * * *
* ###### *
* ###### *
* * * * * *
Người dùng chương trình nhập vào chiều dài và chiều rộng
4 Viết chương trình vẽ hình sau:
5 Viết chương trình vẽ hình sau Chiều cao của hình tam giác
* được nhập từ bàn phím
* *
* *
* * * * *