Tải bản đầy đủ (.pdf) (274 trang)

Lap Trinh Voi Turbo Pascal

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 (3.05 MB, 274 trang )

<span class='text_page_counter'>(1)</span><div class='page_container' data-page=1>

<b>LơI NOI</b> <b>đầU</b>


<i>L mt ngụn ngữ lập trình có cú pháp chặt chẽ, đơn giản v</i>


<i>dễ hiểu, Pascal đợc giảng dạy cho sinh viên tin học ngay năm học </i>


<i>u tiờn. Nú l ngụn ng cơ sở để giới thiệu cho sinh viên lμm quen </i>


<i>với kĩ thuật xây dựng ch−ơng trình. Ngoμi ra, nó cịn đ−ợc dùng để </i>


<i>trình bμy nhiều chun đề khác nữa của tin học trong những năm </i>


<i>häc tiÕp theo. </i>


<i> Nắm vững các thnh phần cơ bản, hiểu rõ các yếu tố cú </i>


<i>pháp của ngôn ngữ lập tr×nh Pascal, lμ rÊt quan träng. Nh−ng vËn </i>


<i>dụng nó để xây dựng đ−ợc các ch−ơng trình mới lμ điều quan trng </i>


<i>nhất. </i>


<i>Qua kinh nghiệm nhiều lần giảng dạy ngôn ngữ Pascal cho </i>


<i>cỏc i tng sinh viờn khỏc nhau, có thể nhận thấy rằng sinh viên </i>


<i>lóng tóng nhất ở khâu vận dụng xây dựng chơng trình cụ thể, </i>


<i>không biết lm thế no, bắt đầu từ đâu. </i>


<i>Giáo trình nμy đặt trọng tâm vμo trình bμy kĩ thut xõy dng </i>



<i>chơng trình song song với việc giới thiệu ngôn ngữ lập trình </i>


<i>Pascal. Các ví dụ ứng dụng tổng hợp ở cuối chơng đợc chọn lọc </i>


<i> minh hoạ những vấn đề lí thuyết trình bμy trong chng ú. </i>


<i>Những ví dụ ứng dụng ny có liên quan chặt chẽ với nhau, đợc </i>


<i>phỏt trin hon thiện dần một cách có hệ thống để sinh viên hiểu </i>


<i>rõ các b−ớc xây dựng ch−ơng trình, từ thơ sơ, đơn giản đến hoμn </i>


<i>thiƯn, hiƯu qđa h¬n. </i>


<i>Vì đây l hệ thống lại các bi giảng lần đầu tiên nên chắc </i>


<i>chn cũn nhiu thiu sút. Rt mong sự đóng góp ý kiến của các </i>


<i>thầy, cơ đồng nghiệp cũng nh− của các bạn sinh viên lμ i tng </i>


<i>phục vụ của giáo trình ny.</i>




</div>
<span class='text_page_counter'>(2)</span><div class='page_container' data-page=2>

<b>NÔI </b>

<b>DUNG </b>



<b>LơI NOI đầU</b> <b>i</b>


<b>Chơng 1 - Giới thiệu chung </b> <b>1</b>



1. Các khái niệm cơ bản 1


1.1 Mở đầu. 1


1.2 C¸c kÝ tù. 2


1.3 C¸c tõ kho¸. 3


1.4 Tªn - Identifier 3


1.5 Tªn chuÈn 4


1.6 Câu lệnh 4


2. Phát triển một chơng trình Pascal 5
2.1 Cấu trúc một chơng trình Turbo Pascal. 5
2.2 Các bớc xây dựng chơng trình. 6
3. Môi trờng phát triển tích hợp Turbo Pascal. 7


3.1 Các công cụ phát triển. 7


3.2 Các chức năng v cách dùng. 8


3.3 Các bớc xây dựng một chơng trình trong môi trờng Turbo Pascal 11


Câu hỏi v bI tập 12


<b>Chơng 2 - Các kiểu dữ liệu chuẩn, các hm chuẩn 14</b>



1. Các kiểu dữ liệu chuẩn. 14


1.1 Khái niệm kiểu dữ liệu 14


1.2 Phân loại các kiểu d÷ liƯu trong TurboPascal. 14


1.3 Các kiểu đơn giản chuẩn 16


2. Các hm chuẩn. 18


2.1 Bảng các hm chuẩn. 19


2.2 Sư dơng. 20


C©u hái vμ bμi tËp 20


<b>Ch−ơng 3 - Các khai báo vμ câu lệnh đơn giản 21</b>


1. Khai b¸o h»ng vμ biÕn 21


1.1 Khai b¸o h»ng 21


1.2 Khai báo biến 22


2. Biểu thức trong ngôn ngữ Pascal. 23


2.1 Biêủ thức l gì. 23


2.2 Bảng thứ tự u tiên 24



2.3 Viết đúng biểu thức 25


3. Các câu lệnh đơn giản 25


3.1 LƯnh g¸n 26


3.2 Lệnh in ra mμn hình không kèm định dạng. 26
3.3 Quy cách mặc định in ra các kiểu dữ liệu. 27


</div>
<span class='text_page_counter'>(3)</span><div class='page_container' data-page=3>

3.5 LÖnh in ra máy in 29
3.6 Lệnh nhập dữ liệu từ bμn phÝm. 30
4. Mét sè hμm, thđ tơc tr×nh bμy mn hình. 32


Câu hỏi v bi tập 32


<b>Chơng 4- Các cấu trúc điều khiển 35</b>


1. Câu lệnh ghép 35


2. Câu lệnh IF. 35


2.1 Cú pháp v công dụng. 36


2.2 Các ví dụ minh hoạ. 37


2.3 If lồng nhau hay d·y if 38


2.4 AND hay IF lång nhau 39


3. C©u lƯnh CASE. 40



3.1 Có ph¸p vμ t¸c dơng. 40


3.2 VÝ dụ minh hoạ 41


3.3 Chú ý 42


3.4 Các lỗi thờng gặp. 42


4. Câu lệnh FOR. 43


4.1 Cú pháp v tác dụng 43


4.2 Ví dụ minh hoạ 44


5. Câu lƯnh Repeat. 45


5.1 Có ph¸p vμ t¸c dơng 45


5.2 Ví dụ minh hoạ 46


6. Câu lệnh While. 48


6.1 Cú pháp v công dụng. 48


6.2 Ví dụ minh hoạ 49


7. Xây dựng cấu trúc lặp. 50


7.1 Điều khiển vòng lặp bằng giá trị canh chừng. 50



7.2 Điều khiển vòng lặp bằng cờ báo 51


8. Các lệnh kết thúc sớm vòng lặp hoặc chơng trình. 51
8.1 Lệnh nhảy không điều kiện - goto 51


8.2 Lệnh chấm dứt sớm vòng lặp. 52


8.3 Lệnh thoát khỏi chơng trình con. 53
8.4 Lệnh dừng chơng trình bất thờng. 53


Câu hỏi v bi tập 53


<b>Chng 5 - Định nghĩa Các kiểu dữ liệu đơn gin 56</b>


1. Khai báo kiểu dữ liệu mới. 56


1.1 Cú pháp chung. 56


1.2 Ví dụ 56


2. Kiểu liệt kê. 57


2.1 Định nghĩa v cú pháp 57


2.2 Tính chất v các phép toán. 58


2.3 Ví dụ minh hoạ 60


3. Kiểu đoạn con. 60



3.1 Định nghĩa v cú pháp. 60


3.2 Ví dụ minh hoạ. 62


</div>
<span class='text_page_counter'>(4)</span><div class='page_container' data-page=4>

4.1 Định nghĩa v cú pháp. 62


4.2 Các phép toán trên tập hợp 63


4.3 Ví dụ minh hoạ 64


<b>Chơng 6 - Kiểu mảng 66</b>


1. Mảng một chiều 66


1.1 Định nghĩa v cú pháp. 66


1.2 Các tính chất. 67


1.3 Tại sao nên khai báo kiểu. 68


1.4 Ví dụ minh hoạ. 68


2. Mảng nhiều chiều. 69


2.1 Định nghĩa cú pháp v cấu trúc 69


2.2 Ví dụ minh hoạ. 70


3. Tìm kiếm trên mảng. 71



3.1 Tìm kiếm tuần tự. 71


3.2 Tìm kiếm nhị phân. 72


4. Một vi cách sắp xếp mảng. 73


4.1 Phng phỏp i ch trc tip. 73


4.2 Phơng pháp chèn trực tiếp. 75


4.3 Phơng pháp chọn trực tiếp. 77


Câu hỏi v bi tập 79


<b>Chơng 7 - Kiểu xâu kí tự 81</b>


1. Cú pháp v cấu trúc. 81


1.1 Cú pháp. 81


1.2 Cấu trúc kiểu xâu kÝ tù - Truy cËp trùc tiÕp tõng thμnh phÇn. 82


2. Thao tác với xâu kí tự 84


2.1 Các phép toán. 84


2.2 Các thủ tục v hm trên xâu kí tự. 84


Câu hỏi v bi tập 86



<b>Chơng 8 - Kiểu bản ghi 88</b>


1. Định nghĩa v khai báo 88


1.1 Định nghĩa. 88


1.2 Khai báo kiểu bản ghi. 88


2. Sử dụng. 90


2.1 Truy cập từng thnh phần. 90


2.2 Các phép toán với ton bộ bản ghi. 90
2.3 Đọc vo, viết ra với một biến kiểu bản ghi. 91


2.4 Câu lệnh With. 92


3. Bản ghi có cấu trúc thay đổi 93


3.1 Định nghĩa v cú pháp 93


3.2 S dng bn ghi có cấu trúc thay đổi. 94


<b>Ch−¬ng 9 - KiĨu tÖp 98</b>


1. Các khái niệm vμ định nghĩa 98


1.1 Mục đích sử dụng tệp. 98



</div>
<span class='text_page_counter'>(5)</span><div class='page_container' data-page=5>

1.3 TƯp truy cËp tuÇn tù. 99


2. Viết ra tệp, đọc vμo từ tệp 100


2.1 Mở tệp để viết ra. 100


2.2 ViÕt d÷ liÖu ra tÖp. 101


2.3 Mở tệp để đọc vμo. 102


2.4 §äc d÷ liƯu vμo tõ tƯp. 102


2.5 TƯp truy cËp trùc tiÕp. 103


3. C¸c thao t¸c kh¸c 104


3.1 Mét sè hm v thủ tục với tệp. 104


3.2 Bẫy lỗi khi mở tệp. 105


4. Tệp văn bản. 107


4.1 Định nghĩa v cấu trúc. 107


4.2 Viết ra tệp văn bản 108


4.3 Đọc vo từ một tệp văn bản. 108


4.4 Các hm, thủ tục chuẩn khác cho tệp văn bản 109



4.5 Các thiết bÞ vμo ra chn 111


5. Tệp khơng định kiểu. 112


5.1 Định nghĩa v cấu trúc. 112


5.2 Các hm, thủ tục khác. 112


Câu hỏi v bi tập 114


<b>Chơng 10 - Chơng trình con 115</b>


1. Chơng trình con - Hm v thủ tục 115
1.1 Tại sao cần sử dụng chơng trình con. 115


1.2 Khai báo chơng trình con. 115


1.3 Xây dựng chơng trình con 117


1.4 Lời gọi chơng trình con. 117


1.5 Ví dơ minh ho¹. 118


2. Hμm hay thđ tơc, tham biÕn hay tham trị. 120


2.1 Phân biệt hm với thủ tục. 120


2.2 Phân biệt tham biến v tham trị. 121
2.3 Một vi lu ý khi xây dựng chơng trình con 122



2.4 Khai báo trớc - Forward. 124


3. Chơng trình con lồng nhau. 125


3.1 Biến ton cục, biến cục bộ, tầm tác dụng 125


3.2 Minh hoạ 126


Câu hỏi v bi tập 128


<b>Chong 11 - Thiết kế chơng trình 129</b>


1. Phơng pháp xây dựng chơng trình 129


1.1 Khái niệm Công nghệ phần mềm. 129


1.2 Chu kì phát triển phần mềm. 129


1.3 Ví dụ minh ho¹ 130


1.4 Lập trình mơ đun - Modula programming 131
1.5 Thủ tục hoá - Procedural abstraction 133
2. Thiết kế chi tiết dần từng b−ớc. 133
2.1 Sơ đồ cấu trúc ch−ơng trình - structure chart 133


</div>
<span class='text_page_counter'>(6)</span><div class='page_container' data-page=6>

3. Tính đệ quy vμ thuật giải đệ quy. 138


3.1 Tính đệ quy 138


3.2 Thuật giải đệ quy. 139



3.3 Thiết kế giải thuật đệ quy. 140


4. Một số ví dụ về thuật giải đệ quy. 141


4.1 Bμi to¸n th¸p Hμ néi. 141


4.2 Bi toán vết mực. 142


4.3 Tìm kiếm nhị phân 144


4.4 Sắp xếp kiểu phân đoạn hay sắp xếp nhanh - Quick Sort. 145
5. Tự xây dựng th viện chơng trình con - Units 147
5.1 Sử dụng lại các chơng trình con 147


5.2 Cấu trúc của một unit. 147


5.3 Biên dịch v sử dụng. 149


5.4 Ví dụ minh hoạ. 149


5.5 So s¸nh viƯc dïng Unit víi chÌn trùc tiÕp tƯp m· ngn 150
5.6 C¸c unit chn cđa Turbo Pascal 150


6. Giíi thiƯu Unit CRT. 151


6.1 C¸c biÕn 151


6.2 C¸c hμm, thđ tơc 152



6.3 Mμu sắc vμ chế độ mμn hình văn bản. 153


6.4 Xư lÝ gâ phÝm. 156


6.5 C¸c thđ tơc kh¸c 156


7. VÝ dơ øng dơng - Lm bảng chọn. 157


7.1 Các bớc xây dựng bảng chọn. 157


7.2 Phân tích thiết kế chi tiết dần từng bớc. 158


7.3 Chơng trình chi tiết. 162


7.4 Chuyển thnh Unit bảng chọn. 165


8. Một chơng trình ứng dụng. 167


8.1 Ph©n tÝch thiÕt kÕ 167


8.2 TriĨn khai chi tiÕt chơng trình. 170


Câu hỏi v bi tập 174


<b>Chng 12 - Con trỏ vμ cấu trúc dữ liệu động 176</b>


1. Con trỏ 176


1.1 Bin tnh v bin ng. 176



1.2 Định nghÜa vμ khai b¸o. 177


1.3 Các phép tốn đối với con trỏ. 178


2. Biến động. 179


2.1 Cấp phát vùng nhớ vμ truy cập biến động. 179
2.2 Giải phóng biến động, thu hồi vùng nhớ 180
3. Con trỏ không định kiểu - Pointer 180


3.1 Định nghĩa 180


3.2 ứ<sub>ng dụng 181</sub>


4. Vùng ngăn xếp v vùng Heap. 182


4.1 Khái niệm 182


4.2 Giải toả heap 183


</div>
<span class='text_page_counter'>(7)</span><div class='page_container' data-page=7>

Câu hỏi v bμi tËp 184


<b>Ch−¬ng 13 Danh </b>
<b>s¸ch & danh s¸ch mãc nèi 187</b>


1. Danh s¸ch b»ng mảng. 187


1.1 Mô hình danh sách. 187


1.2 Danh sỏch biu diễn bằng cấu trúc mảng. 188


1.3 Các phép toán đối vi danh sỏch mng. 188


1.4 Các u, nhợc điểm. 189


1.5 Ví dụ minh hoạ 190


2. Danh sách kiểu ngăn xếp - Stack. 193


2.1 Định nghía danh sách kiểu ngăn xếp. 193
2.2 Biểu diễn danh sách kiểu ngăn xếp. 194
2.3 Các phép toán đối với kiểu ngăn xếp. 194
3. Danh sách kiểu hμng đợi - Queue. 195
3.1 Định nghĩa danh sách kiểu hμng đợi. 195
3.2 Biểu diễn danh sách kiểu hμng đợi bằng mảng. 196


3.2 C¸c phÐp to¸n. 196


4. Danh sách ni n. 198


4.1 Mô tả. 198


4.2 Cấu trúc móc nối. 198


4.3 C¸c phÐp to¸n. 200


5. Danh s¸ch nèi kÐp 202


5.1 CÊu tróc danh s¸ch nèi kÐp. 202


5.2 C¸c phÐp to¸n víi danh s¸ch nèi kÐp. 203


6. VÝ dơ øng dơng của danh sách móc nối. 205
6.1 Cải tiến chơng trình quản lí hồ sơ. 205


6.2 Phân tích thiết kế. 205


6.3 Triển khai chi tiết. 207


Câu hỏi v bi tập 213


<b>Chơng 14 - Dồ hoạ 215</b>


1. Các khái niệm cơ bản 215


1.1 Hai chế độ hiển thị mμn hình 215


1.2 Khởi tạo vμ đóng chế độ đồ hoạ 216
1.3 Một ch−ơng trình đồ hoạ đơn giản 218
1.4 Mμu sắc, kiểu nét vẽ, kiểu tô nền. 218
2. Các thủ tục đồ hoạ th−ờng dùng. 219
2.1 Di chuyển, vẽ một điểm, một đoạn thng. 219


2.2 Các thủ tục vẽ hình. 220


2.3 Tỷ lệ biĨu kiÕn. 221


2.4 Viết chữ ra mμn hình đồ hoạ 222


3. Các thủ tục về môi tr−ờng đồ hoạ 224


3.1 C¸c thđ tơc thiÕt lËp mμu. 224



3.2 C¸c thđ tơc vỊ mÉu t«, mÉu nÐt vÏ 225


3.3 ViewPort. 229


4. Vẽ đồ thị một hμm số 230


</div>
<span class='text_page_counter'>(8)</span><div class='page_container' data-page=8>

4.2 Ch−¬ng trình chi tiết. 232
4.3 Chuyển thnh chơng trình con. 234


5. Lm hoạt hình. 235


5.1 Di chuyển hình vẽ trên nền trơn 235
5.2 Di chuyển hình vẽ trên nền hình ảnh tĩnh. 236
5.3 Sử dụng phép lật trang mn hình. 240


Câu hái vμ bμi tËp 242


<b>Ch−ơng 15 - Thâm nhập hệ thống vμ Hệ điều hμnh DOS 244</b>
1. Gọi thực hiện các chức năng ROM-BIOS vμ DOS. 244
1.1 Các thanh ghi của 8086 vμ địa chỉ trong bộ nhớ 244


1.2 C¸c ngắt - interrupt 245


1.3 Thâm nhập trực tiếp qua thanh ghi v ngắt 246


1.4 Các ví dụ minh hoạ. 247


1.5 Sư dơng c¸c hμm, thđ tơc cđa unit DOS 250



2. Điều khiển chuột 251


2.1 To chut 251


2.2 Ngắt điều khiĨn cht $33 252


2.3 VÝ dơ minh ho¹. 253


2.4 Th− viƯn c¸c thđ tơc thao t¸c cht. 255


2.5 ø<sub>ng dụng v</sub><sub></sub><sub>o bảng chọn. 256</sub>


3. Thâm nhập trực tiếp vo bé nhí vμ cỉng 257


3.1 Th©m nhËp trùc tiÕp bé nhớ. 257


3.2 Thâm nhập cổng. 259


4. Chơng trình thờng trú 260


4.1 Khái niệm 260


4.2 Cách xây dựng một chơng trình th−êng tró 261


4.3 VÝ dơ minh ho¹. 261


</div>
<span class='text_page_counter'>(9)</span><div class='page_container' data-page=9>

<b>Ch−¬ng 1 </b>
<b>Giíi thiƯu chung </b>


Pascal lμ một ngơn ngữ lập trình cho máy tính, do Niklaus Wirth,


giảng viên tr−ờng Đại học Kĩ thuật Zurich, Thuỵ sĩ xây dựng nên vμo năm
1970 với mục đích để giảng dạy.


Lμ ngơn ngữ lập trình cấu trúc, trong sáng, dễ hiểu, Pascal đã v−ợt ra
khỏi nhμ tr−ờng, phát triển thμnh một ngơn ngữ mạnh, có thể dùng để phát
triển ch−ơng trình chuyên nghiệp.


N. Wirth đã đ−ợc giải Turing do công lao sáng tạo vμ phổ biến ngụn
ng Pascal.


Hiện nay ngôn ngữ lập trình Pascal có nhiều biến thể do các công ty
khác nhau bỉ xung hoμn thiƯn thªm: TURBO PASCAL cđa Borland,
QUICK PASCAL cđa Microsoft, ANSI PASCAL ...


Nói riêng Turbo Pascal cũng đã đ−ợc cải tiến hoμn thiện qua nhiều
phiên bản, từ bản 1.0 ban đầu cho đến bản 5.5 năm 1989, bản 6.0 năm 1990,
bn 7.0 nm 1992.


<b>1. </b> <b>Các khái niệm cơ bản </b>


<b>1.1 </b> <b>Mở đầu. </b>


Pascal l mt ngơn ngữ lập trình cấp cao, nghĩa lμ gần với ngôn ngữ
của con ng−ời. Khái niệm cấp cao, cấp thấp của một ngơn ngữ lập trình máy
tính để nói nó gần hơn với ngơn ngữ con ng−ời hay với ngơn ngữ của máy
tính chứ khơng phải để nói về khả năng.


T−ơng tự nh− ngơn ngữ thơng th−ờng, Pascal cũng sử dụng các kí tự để
tạo nên các từ, dùng các "từ" vμ các yếu tố cơ bản khác để tạo thμnh các
"câu" có ý nghĩa xác định. Các "câu" đ−ợc phối hợp thμnh một "văn bản"


hoμn chỉnh gọi lμ văn bản ch−ơng trình nhằm ra lệnh cho máy tính thực hiện
một số cơng việc xử lí thơng tin nμo đó.


§Ĩ minh hoạ ta xét một văn bản chơng trình Pascal sau ®©y
Program HinhTron;


</div>
<span class='text_page_counter'>(10)</span><div class='page_container' data-page=10>

Begin


Write(' Cho ban kinh = ');
Read(BanKinh);


If BanKinh > 0 then
begin


ChuVi:= 2* pi * BanKinh ;


DienTich:= pi * BanKinh * BanKinh ;
Write(' Chu vi la = ' , ChuVi );


Write(' Dien tich la = ' , DienTich);
End


Else


Write(' Ban kinh am, khong hop le !');
End.


Cã thể "dịch" văn bản chơng trình cho máy tính trên thnh ngôn ngữ
thông thờng nh sau.



<i>Chơng trình Hình Tròn; </i>


<i>Các biến: Bán Kính, Chu Vi, Diện Tích: l số thực; </i>


<i>Bắt đầu </i>


<i> Viết ra mn hình: Cho Bán Kính = </i>


<i> Đọc từ bn phím: Bán Kính. </i>


<i> NÕu B¸n KÝnh > 0 Thì </i>


<i> </i> <i>Bắt đầu </i>


<i> ChuVi = 2 x</i>

π

<i> x B¸n KÝnh. </i>


<i> </i> <i>DiƯnTÝch = </i>

π

<i>x B¸n KÝnh x B¸n KÝnh. </i>


<i> </i> <i> ViÕt ra: Chu vi lμ = giá trị ChuVi (tính đợc ở trên). </i>


<i> </i> <i> ViÕt ra: DiÖn tÝch lμ = giá trị DiệnTích (tính đợc ở trên). </i>


<i> KÕt thóc. </i>
<i> Trái lại </i>


<i>Viết: Bán Kính âm, Không hợp lệ ! </i>


<i>KÕt thóc</i>.


<b>1.2 </b> <b>C¸c kÝ tù. </b>



Turbo Pascal sử dụng các kí tự sau đây trong bảng mà ASCII:
- Các chữ cái thờng v hoa: a .. z, A .. Z.


- 10 ch÷ sè: 0 .. 9.
- DÊu nèi d−íi: _


- C¸c dÊu phÐp to¸n: + - * / = <>


- Một số kí hiệu đặc biệt: . , ; ! ? : ' " ( ) { } [ ] % @ & # $ ^. ý


</div>
<span class='text_page_counter'>(11)</span><div class='page_container' data-page=11>

<b>1.3 </b> <b>C¸c từ khoá. </b>


Nhìn lại chơng trình v bản "dịch" trong ví dụ trên ta thấy các từ


<i>Program, Var, Real, Begin, If, Then, Else, End</i> lμ nh÷ng thμnh phÇn hÕt søc


quan trọng. Chúng phối hợp với nhau để tạo nên phần khung của các câu
lệnh. Đó lμ các <i>từ khố.</i> Các từ khóa lμ các đơn vị từ vựng cơ sở của một
ngôn ngữ lập trình nói chung.


Khác với ngơn ngữ thơng th−ờng, một từ có thể nhiều nghĩa, một ý có
thể viết theo nhiều cách, mỗi từ khoá trong một ngơn ngữ lập trình có một ý
nghĩa xác định chính xác, những câu lệnh đ−ợc xây dựng theo những quy tc
ht sc cht ch.


Dới dây liệt kê những từ khoá của Turbo Pascal. Y nghĩa v cách sử
dụng chúng ta sẽ lm quen dần sau nμy.


And


Asm
Array
Begin
Case
Const
Constructor
Destructor
Div
Do
Downto
Else
End
File
For
Function
Goto
If
Implementation
In
Inline
Interface
Label
Mod
Nil
Not
Object
Of
Or
Packed
Procedure

Program
Record
Repeat
Set
Shl
Shr
String
Then
To
Type
Unit
Until
Uses
Var
While
With
Xor


Víi c¸c tõ khóa, Pascal không phân biệt chữ in hoa hay chữ thờng.
Trong văn bản chơng trình Pascal ta có thể tuỳ ý viết một từ khóa bằng các
chữ cái dạng in thờng hay in hoa hoặc xen kẽ cả hai dạng.


<b>1.4 </b> <b>Tên - Identifier </b>


Nhỡn li ch−ơng trình trong ví dụ ở trên, ngoμi các từ khố ta thấy cịn
có các thμnh phần khác nh− <i>BanKinh, ChuVi, DienTich</i>. Chúng lμ <i>tên</i> của
các đối t−ợng mμ ta xử lí trong ch−ơng trình.


Quy định đặt tên trong Pascal nh− sau:



- Tên l xâu kí tự gồm chữ cái , ch÷ sè, dÊu nèi d−íi ( _ ).
- Tên không đợc chứa dấu cách;


- Tên không đợc bắt đầu bằng số;


- Tên có thể di tuỳ ý nhng chỉ có <b>63</b> kí tự đầu tiên l có ý nghĩa;
- Tên không đợc trùng víi tõ kho¸;


</div>
<span class='text_page_counter'>(12)</span><div class='page_container' data-page=12>

Giống nh− đối với các từ khóa, trong văn bản ch−ơng trình Pascal, các


<i>tên</i> cũng đ−ợc viết bằng các chữ cái dạng in th−ờng hay in hoa, không phân
biệt. <i>BanKinh</i> hay <i>bankinh</i> đều chỉ lμ một tên. Ta có thể chọn một phong
cách viết thích hợp.


Để tách các âm tiết cho dễ đọc có thể dùng dấu nối d−ới ( _ ) hoặc
viết hoa chữ cái đầu tiên của mỗi âm tiết, ví dụ: <i>giai_pt_bac_hai, dinh_thuc, </i>


<i>HeSo, BanKinh , DienTich</i>... Trong tμi liƯu nμy sÏ dïng c¸ch viÕt hoa chữ cái


đầu của mỗi âm tiết.


Khỏi nin tên (<i>identifier</i> - ID) ở đây chính xác vμ chặt chẽ hơn khái
niệm tên gọi thông th−ờng (<i>name</i>). Tên phải đảm bảo đúng quy định, không
trùng lặp, t−ơng ứng một-một giữa tên vμ đối t−ợng gắn với nó.


<b>1.5 </b> <b>Tªn chuÈn </b>


Tên chuẩn lμ tên mμ Pascal đã sử dụng, có một ý nghĩa hoμn toμn xác
định trong mơi tr−ờng Pascal. Trong ví dụ trên các thμnh phần <i>Read, Write</i>



lμ các tên chuẩn. Đó lμ tên của hai thủ tục có sẵn trong Turbo Pascal.
Tên chuẩn khác từ khố ở chỗ, có thể dùng lại tên nμy vμo việc khác, định
nghĩa lại với nghĩa mới khác đi, do ng−ời dùng quy định. Tuy nhiên khơng
nên lμm thế vì mọi thay đổi khác lệ th−ờng, đều dễ đ−a đến nhầm lẫn.


C¸c tên chuẩn bao gồm


- Các kiểu dữ liệu: <i>boolean, char, integer, real, byte, text...;</i>


- Các hằng kiểu lô gic: <i>false, true</i> ;
- Các hμm, thủ tục chuẩn đã lμm sẵn:


<i>chr, odd, abs, sqr, sqrt, exp, ln .. </i>


<i> </i> <i>arctan, cos, sin, .. </i>


<i> </i> <i>eof, eoln, read, readln, write, writeln.. </i>


<b>1.6 </b> <b>C©u lƯnh </b>


Sử dụng các từ khố của ngơn ngữ Pascal, các tên đối t−ợng, các dấu
phép toán vμ các kí hiệu đặc biệt khác, ng−ời lập trình viết các câu lệnh. Câu
lệnh lμ một chỉ thị cho máy tính thực hiện một thao tác tính tốn, xử lí nμo đó.


VÝ dơ,


DienTich:= pi * BanKinh * BanKinh ;


l một câu lệnh yêu cầu máy tính bình phơng bán kính nhân với số rồi
gán cho diện tích hình tròn.



Có thể viết nhiều câu lệnh trên một dịng. Phải dùng dấu chấm phẩy
“ ; ” để ngăn cách hai câu lệnh dù lμ trên cùng một dòng hay trên hai dòng
khác nhau.


</div>
<span class='text_page_counter'>(13)</span><div class='page_container' data-page=13>

<b>2. </b> <b>Phát triển một chơng trình Pascal </b>


<b>2.1 </b> <b>Cấu trúc một chơng trình Turbo Pascal. </b>


cho d hiu từ đây ta quy −ớc khi trình bμy các thμnh phần cú pháp
của Pascal ta sẽ dùng cách nhấn mạnh bằng chữ in nghiêng để chỉ những
phần mμ ng−ời lập trình cần điền vμo tuỳ theo từng tr−ờng hợp cụ thể. Những
từ khố, tên chuẩn... của ngơn ngữ Pascal lμ phần khung phải giữ nguyên
không đ−ợc thay đổi sẽ đ−ợc thể hiện bằng kiểu chữ đứng m hn.


2.1.1 <i>Các thnh phần </i>


Về cấu trúc, một chơng trình Pascal gồm 3 phần: phần tên, phần khai
báo, phần thân.


<b>Program</b> <i>tên chơng trình</i> ; Phần tên


<b>Uses</b> <i>danh s¸ch c¸c unit ; </i>


<b>Const</b> <i>c¸c khai b¸o h»ng ;</i>


<b>Type</b> <i>c¸c khai b¸o kiĨu ; </i>


<b>Var</b> <i>c¸c khai b¸o biÕn ;</i>



<b>Procedure</b> .... ;


<b>Function </b> .... ;




Phần khai báo


Phần các chơng trình con.
BEGIN


<i>các câu lệnh của chơng trình</i>;
END .


Phần thân


Phần tên có thĨ kh«ng cã.


Phần khai báo phải theo đúng trình tự các mục: <i>uses, const, type, </i>
<i>var,</i>v.v. Có thể lặp lại các từ khoá ở trên nhiều lần, trên nhiều dịng nếu nh−
có nhiều nội dung. Phần khai bỏo cú th khụng cú.


Phần thân chơng trình bắt buộc phải có ! Lu ý rằng văn bản chơng
trình kết thúc với từ khoá END kèm dấu chấm .


</div>
<span class='text_page_counter'>(14)</span><div class='page_container' data-page=14>

ở đây có khai báo <i>nguyên mẫu</i> (tức l <i>tên, danh sách tham số, kiểu kết quả </i>


<i>trả về</i>) của mỗi chơng trình con kèm triĨn khai chi tiÕt cđa chóng. Ta sÏ t×m


hiĨu kĩ hơn sau ny trong chơng "Chơng trình con".


2.1.2


2.1.3


2.2.1


<i>Chú thích trong chơng trình Pascal. </i>


Trong vn bản ch−ơng trình th−ờng xen lẫn các lời chú thích nhằm
mục đích cung cấp các thơng tin bổ xung hoặc giải thích ý nghĩa, nội dung
câu lệnh cho ng−ời đọc dễ hiểu hơn. Trình biên dịch hoμn toμn bỏ qua các
chú thích. Cú pháp ngơn ngữ Pascal quy định đoạn lời chú thích phải đặt giữa
cặp dấu ngoặc nhọn “{ , }” hoặc cặp dấu ngoặc đơn kèm dấu sao “(* , *)”.
Đoạn chú thích có thể trên một dịng hay nhiều dịng.


VÝ dơ:
.. ..


{ nghiƯm thø nhÊt }


x1:= ( -b + sqrt (b*b – 4*a*c)) / (2*a);


.. ..


hc
.. ..


(* nghiƯm thø nhÊt *)


x1:= ( -b + sqrt (b*b – 4*a*c)) / (2*a);



<i>VÝ dô một chơng trình Pascal </i>


Chng trỡnh Pascal n gin sau đây sẽ lμm sạch mμn hình vμ in ra dịng
chữ "Xin Chμo Bạn !" tại góc trên trái của mμn hình.


program ChaoMung;
uses crt;


Begin


Clrscr;


Write(' Xin Chao Ban ! ');
Readln;


End.


<b>2.2 </b> <b>Các bớc xây dựng chơng trình. </b>


Xõy dựng ch−ơng trình giải quyết một bμi tốn cụ thể cần trải qua các
b−ớc nh− sau: xác định rõ u cầu của bμi tốn cần phải lμm gì; phân tích nội
dung; thiết kế thuật giải; triển khai viết chng trỡnh v chy th kim tra.


đây ta chỉ trình by những công việc cơ bản nhất của hai bớc cuối cùng l
viết chơng trình v chạy thử.


<i>Viết văn bản chơng trình. </i>


</div>
<span class='text_page_counter'>(15)</span><div class='page_container' data-page=15>

2.2.2



2.2.3


<i>Biên dịch v liên kết. </i>


Tệp văn bản chơng trình gồm các câu lệnh gần với ngôn ngữ thông
thờng, dễ hiểu với con ngời, nhng không phải l ngôn ngữ của máy tính.
Để máy tính hiểu v thực thi đợc các câu lệnh cần phải biên dịch chơng
trình từ tệp mà nguồn Pascal thnh tệp mà máy.


Trong quá trình biên dịch có thể máy sẽ phát hiện ra các <i>lỗi cú pháp - </i>


<i>syntax error</i>. Ta cần sửa chữa để đảm bảo ch−ơng trình hết lỗi cỳ phỏp, c


biên dịch thnh công v liên kết thnh tệp thi hnh đợc.
<i>Chạy thử v sửa lỗi </i>


Giống nh− một bμi văn gồm toμn những câu đúng ngữ pháp nh−ng vô
lý, không thể hiểu đ−ợc, một ch−ơng trình đã đúng cú pháp có thể vẫn ch−a
chạy thơng đ−ợc. Máy dừng khi ch−ơng trình thực hin na chng. Lỳc ny


l <i>lỗi khi chạy chơng tr×nh - run time error.</i>


Ngay khi ch−ơng trình đã chạy thơng cũng vẫn có thể cho kết quả sai.
Đây lμ<i> lỗi nội dung</i> thuật giải. Cần phải sửa lại thuật giải để đảm bảo ch−ơng
trình cho kết quả đúng nh− mong muốn.


Một bμi tốn th−ờng có nhiều tr−ờng hợp khác nhau. Ví dụ, ch−ơng
trình giải ph−ơng trình bậc hai sẽ có ba tr−ờng hợp khác nhau ứng với giá trị
của biệt thức (Delta) lμ âm, d−ơng hay bằng không. Ch−ơng trình đã chạy


đúng với tr−ờng hợp nμy có thể vẫn ch−a đúng hoặc thậm chí khơng chạy
thơng đ−ợc cho tr−ờng hợp khác. Cần chạy thử ch−ơng trình với nhiều bộ dữ
liệu đầu vμo khác nhau để kiểm tra tính đúng đắn của ch−ơng trình trong mọi
tr−ờng hp cú th xy ra.


<b>3. </b> <b>Môi trờng phát triển tích hợp Turbo Pascal. </b>


<b>3.1 </b> <b>Các công cụ ph¸t triĨn. </b>


Nh− đã trình bμy ở trên, việc triển khai một ch−ơng trình Pascal cần
tiến hμnh nhiều b−ớc, từ soạn thảo văn bản ch−ơng trình cho đến biên dịch,
liên kết, chạy thử vμ sửa lỗi. Mỗi b−ớc nh− vậy đều cần có một cơng cụ hỗ
trợ t−ơng ứng. Để soạn thảo văn bản ch−ơng trình cn dựng mt b son tho


<i>Editor</i>. Để biên dịch chơng trình cần có trình biên dịch <i>Compiler.</i> Để


liên kết các đoạn mà sau biên dịch thnh chơng trình cần dùng trình liên kết


<i>Linker</i>. Trỡnh h tr phát hiện vμ sửa lỗi gọi lμ <i>Debuger.</i> Turbo Pascal ó


</div>
<span class='text_page_counter'>(16)</span><div class='page_container' data-page=16>

phát triển tích hợp (IDE - <i>Integrated Development Environment</i>) cña Turbo


Pascal.


Bộ phần mềm Turbo Pascal gồm nhiều tệp. Dới đây lμ mét sè tƯp
chÝnh.


- <i>Turbo.exe</i>: so¹n thảo, biên dịch, liên kết, sửa lỗi, trợ giúp.v.v. Đây l


tệp chính tạo nên môi trờng phát triển tích hỵp cđa Turbo Pascal.



- <i>Turbo.tpl</i>: (<i>Turbo Pascal Library</i>) th− viƯn chn phơc vơ cho


<i>turbo.exe.</i>


- <i>Graph.tpu: (Turbo Pascal Units</i>) th− viện ch−ơng trình về đồ hoạ


- *.<i>CHR </i> : các phông chữ trong chế độ đồ hoạ


- *.<i>BGI</i> : (<i>Borland Graphics Interfaces</i>) các trình điều khiển mμn


hình đồ hoạ của Borland.


<b>3.2 </b> <b>C¸c chøc năng và cách dùng. </b>


Để mở môi trờng phát triển Turbo Pascal cần phải cho chạy tệp


<i>Turbo.exe</i>. Sau nhiều lần cải tiến, phiên bản phổ biến hiện nay l Turbo


Pascal 7.0. Phần trình by dới đây l căn cứ trên phiên bản ny.
3.2.1 <i>Mμn h×nh lμm viƯc </i>


Sau khi khởi động sẽ hiện ra mμn hình để bắt đầu việc soạn thảo, biên
dịch, chạy thử vμ sửa lỗi ch−ơng trình. Trên đỉnh mμn hình lμ thanh chọn
chính. D−ới đáy mμn hình lμ dòng nhắc lệnh. ở giữa lμ vùng lμm việc.


<i>Thanh chän chÝnh </i>
<b>F</b>ile <b>E</b>dit <b>S</b>earch <b>R</b>un <b>C</b>ompile <b>D</b>ebug <b>T</b>ools <b>O</b>ptions <b>W</b>indow <b>H</b>elp



<i>Vïng lμm viÖc </i>


F1 Help F2 Save F3 Open Alt+F9 Compile F9 Make Alt+F10 ...


<i>Dòng nhắc lệnh </i>


Mỗi mục tên trên thanh chọn chính cho phép mở ra một <i>bảng chọn </i>


<i>buông xuống</i>. Mỗi bảng chọn buông xuống chứa nhiều <i>mơc chän</i> thùc hiƯn


</div>
<span class='text_page_counter'>(17)</span><div class='page_container' data-page=17>

Gõ <i>Alt</i> + <i>chữ cái đ−ợc lμm nổi bật</i> để mở các bảng chọn bng


xuống t−ơng ứng. Ví dụ, gõ <i>Alt + F</i> để mở bảng chọn <i>File</i>, gõ <i>Alt + E</i> để mở
bảng chọn <i>Edit</i>, gõ <i>Alt + S</i> để mở bảng chọn <i>Search</i>, v.v. Cũng có thể dùng
các phím mũi tên sang phải, sang trái để di chuyển trên thanh chọn chính vμ
gõ Enter để mở bảng chọn buông xuống tại vị trí đó.


Dịng nhắc lệnh gồm nhiều cặp <i>phím gõ tắt - tên lệnh </i>cho biết cách
thực hiện nhanh các lệnh hay dùng. Cặp <i>F1 Help</i> nghĩa lμ gõ phím F1 để mở
phần trợ giúp, cặp <i>Alt+F9 Compile</i> nghĩa lμ gõ tổ hợp phím <i>Alt - F9</i> để
thực hiện biên dịch,v.v..


3.2.2 <i>Các bảng chọn </i>


Sau õy l ni dung ca cỏc bảng chọn vμ chức năng của các mục chọn
chứa trong đó. Y nghĩa của các mục chọn sẽ đ−ợc tìm hiểu kĩ hơn khi gặp
vấn đề có liên quan.


- B¶ng chän <b>File. </b>



B¶ng chän File tập hợp các thao tác với tệp văn bản chong tr×nh.
New


Open ... F3
Save F2
Save as ...


Save all


____________
Change dir ...
Print


Printer setup...
DOS shell


Exit Alt+X
____________


....


Mở cửa sổ soạn thảo mới


M tp ó có trên đĩa để sửa chữa, viết tiếp


Ghi l−u tệp ch−ơng trình đang soạn thảo lên đĩa với
tên cũ


Ghi l−u tệp ch−ơng trình đang soạn thảo lên a vi
tờn khỏc



Ghi lu tất cả các tệp đang mở trong các cửa sổ
soạn thảo


Chuyn sang lμm việc ở th− mục khác.
In văn bản ch−ơng trình ra máy in
Thiết đặt các tham số cho thao tác in
Tạm về DOS,


Tho¸t hẳn khỏi môi trờng Turbo Pascal trở về DOS.


Lu ý rằng ở bên phải, cạnh một số tên mục chọn hay dùng có ghi
kèm các phím gõ tắt ứng với mục chọn đó.




- B¶ng chän <b>Edit. </b>


Bảng chọn nμy có nhiều chức năng hỗ trợ cho việc soạn thảo văn bản
ch−ơng trình nh− sao chép, cắt dán. Tr−ớc khi thực hiện sao chép, cắt dán,
v.v. cần đánh dấu khối văn bản bằng cách nhấn tổ hợp phím <i>Shift + các phím </i>


</div>
<span class='text_page_counter'>(18)</span><div class='page_container' data-page=18>

Undo Alt+ BkSp
Redo


___________
Cut Shift + Del
Copy Ctrl + Ins
Paste Shift + ins
Clear Ctrl + Del


____________
Show clipboard


HoÃn việc vừa nhỡ lm.
Lặp lại việc vừa lμm.


Cắt bỏ vμ chép vμo vùng đệm
Sao vμo vùng đệm


Dán (từ vùng đệm) vμo vị trí từ chỗ con chạy
Xố đoạn đã đã đánh dấu.


Hiển thị vùng đệm.


- B¶ng chän <b>Run</b>


Bảng chọn Run gồm nhiều chức năng để cho thực hiện ch−ơng trình
trong các chế độ khác nhau. Có thể theo dõi hoạt động của ch−ơng trình từng
chặng một, thậm chí từng b−ớc một, qua từng câu lệnh. Gõ Enter để sang
b−ớc tiếp theo.


Run Ctrl + F9
Step over F8
Trace into F7
Go to cursor F4
Program reset
....


Dịch v chạy thử.



Thực hiện từng bớc, từng câu lệnh của chơng
trình. Lời gọi chơng trình con coi lμ mét b−íc.
Thùc hiƯn tõng b−íc, từng câu lệnh, kể cả vo trong
chơng trình con


Thực hiện ch−ơng trình cho đến dịng lệnh có con
chạy


Trở lại chế độ chạy bình th−ờng.


- B¶ng chän <b>Compile </b>


Bảng chọn nμy cho phép thiết lập các lựa chọn khác nhau khi biên dịch
vμ liên kết ch−ơng trình. Theo mặc định, sẽ biên dịch văn bản ch−ơng trình
trong cửa sổ soạn thảo đang lμm việc. Đó lμ tệp mã nguồn, có đi *.PAS .
Tệp kết quả sau biên dịch vμ liên kết lμ tệp thi hμnh - <i>executable</i>, có tên trùng
với tên tệp mã nguồn nh−ng có đi *.EXE.


Với ch−ơng trình lớn, có thể nhiều tệp mã nguồn. Trong đó chỉ có một
tệp lμ tệp chính – <i>Primary File</i>. Các tệp khác lμ tệp phụ kèm theo, bổ xung
cho tệp chính. Lựa chọn <i>Primary File</i> cho phép thiết lập tên tệp mã nguồn
chính. Dù ta đang soạn thảo một tệp khác, tệp mã nguồn chính thậm chí có
thể không đ−ợc mở, việc biên dịch vẫn bắt đầu từ <i>Primary File</i>.


Compile Alt + F9
Make F9
Build


</div>
<span class='text_page_counter'>(19)</span><div class='page_container' data-page=19>

____________
Destination


Memory


Primary file ...
Clear primary file
____________
Infomation


Th− mục để ghi tệp kết quả.


Ghi tệp *.exe nhận đ−ợc vμo bộ nhớ hay vμo đĩa
Memory / Disk


ThiÕt lËp tÖp m· nguån chÝnh.
Bá thiÕt lËp tƯp m· ngn chÝnh.


- B¶ng chän <b>Windows</b>


Bảng chọn Window để thao tác với các cửa sổ khác nhau đang đ−ợc
mở. L−u ý rằng, tại một thời điểm có thể đang mở nhiều cửa sổ nh−ng chỉ có
một cửa sổ đang lμm việc – <i>Active Window</i>. Có thể lựa chọn cho phép cửa
sổ đang lμm việc đè lên trên, che khuất các cửa sổ còn lại – <i>Cascade,</i> hay
nằm bên cạnh các cửa sổ khác, không che khuất nhau, giống nh− lát gạch
nền nhμ – <i>Tile</i>.


Có thể hình dung các cửa sổ đã đ−ợc mở ra xếp thμnh dãy có trình tự
tr−ớc sau theo thời điểm đ−ợc mở. Di chuyển <i>Next, Previous</i> lμ đối với dãy
theo trình tự nói trên.


Tile
Cascade


Close all


Refresh display
_____________
Size/Move Ctrl + F5
Zoom F5
Next F6
Previous Shift + F6
Close Alt + F3
_____________
List ...


Xếp các cửa sổ cạnh nhau
Xếp các cửa sổ đè lên nhau
Đóng mọi cửa sổ đang mở
Lμm t−ơi lại mμn hình


Co gi·n tõng chiỊu / Di chun
Phãng to, thu nhá


Chun sang lμm viƯc ë cưa sỉ tiÕp theo
Lïi vỊ cưa sỉ liỊn ngay tr−íc


§ãng cưa sỉ hiƯn hμnh


Hiện danh sách tên các cửa sổ đang mở (để chọn).
Chọn cái nμo thì cửa sổ đó thμnh cửa sổ lμm việc.


<b>3.3 </b> <b>Các b−ớc xây dựng một ch−ơng trình trong mơi tr−ờng Turbo Pascal </b>
- Khởi động Turbo Pascal.



- Mở tệp để soạn thảo văn bản ch−ơng trình: mở bảng chọn <i>File</i> ,
chọn <i>New</i> để mở tệp mới, hoặc <i>Open</i> (F3) để mở tệp đã có trên đĩa.


</div>
<span class='text_page_counter'>(20)</span><div class='page_container' data-page=20>

Pascal 7.0 còn hỗ trợ cho ngời lập trình qua việc hiển thị các từ khoá bằng
chữ mu trắng.


- Ghi l−u vμo đĩa. Lần đầu tệp ch−a có tên, khung cửa sổ soạn thảo tạm
đ−ợc đặt tên lμ <i>NoName00.pas</i>. Phải mở bảng chọn <i>File</i>, chọn <i>Save as</i> ...
vμ đặt tên cho tệp ch−ơng trình. Têp sẽ đ−ợc ghi lại với tên đã chọn vμ


đi .<i>pas </i> theo mặc định.


- DÞch v sửa lỗi cú pháp (<i>Alt + F9</i> hoặc <i>F9</i>). Nếu có lỗi cú pháp sẽ


xut hin một thơng báo lỗi mμu đỏ. Vị trí có lỗi th−ờng ở ngay tr−ớc con
chạy đang nhấp nháy trên mμn hình. Nếu dịch thμnh cơng, một tệp chạy đ−ợc
(có đi .<i>exe</i>) có tên trùng với tên tệp văn bản ch−ơng trình sẽ đ−ợc tạo ra.
Dịch vμ chạy ch−ơng trình (<i>Ctrl + F9</i>). Nếu đã hết lỗi cú pháp, dịch thμnh
cơng, thì máy sẽ tạm thốt khỏi mơi tr−ờng tích hợp của Turbo Pascal, trở về
DOS vμ cho thực hiện tệp <i>*.exe</i> v−μ tạo ra.


- Xem kết quả (<i>Alt + F5</i>). Nếu ch−ơng trình chạy thơng, nghĩa lμ
khơng bị dừng giữa chừng do lỗi khi chạy ch−ơng trình - <i>run time error, </i>thì
khi kết thúc thực hiện ch−ơng trình máy sẽ lập tức trở lại ngay môi tr−ờng
phát triển của Turbo Pascal. Ta không kịp xem các kết quả mμ ch−ơng trình
đã hiển thị ra mμn hình DOS. Gõ <i>Alt + F5</i> để cho hiện lại mμn hình nμy.
Cũng vì lí do nμy mμ nhiều ng−ời thêm câu lệnh <i>Readln</i> vμo cuối ch−ơng
trình để chờ gõ phím Enter, có thời gian để xem kết quả.



Bây giờ đã có thể sử dụng môi tr−ờng phát triển của Turbo Pascal để
soạn thảo văn bản ch−ơng trình, dịch vμ chạy thử ch−ơng trình đơn giản đã
nêu trong tiết tr−ớc.


Câu hỏi v bI tập


1. Từ khoá l gì, từ khoá khác tên chuẩn ở chỗ no.


2. Tìm trong các từ sau đây đâu lμ từ khố, tên chuẩn, tên đúng vμ không
đúng quy định của Turbo Pascal:


<i>End </i> <i>XYZ123 </i> <i>123ABC </i> <i>Tong So </i> <i>Prog#2 </i> <i>Write </i>


<i>X=Y Read 'MaxSize' Tyle "Delta" TimThay? </i>


3. a) Nêu cách chèn thêm chú thích vμo một ch−ơng trình Pascal.
b) Các chú thích dùng để lμm gì.


c) Viết đoạn chú thích nh− sau cú ỳng khụng ?


{ <i>Chơng trình giải phơng trình bậc hai {giả thiết a <> 0}, tác giả </i>


<i>Nguyễn Văn A</i>}.


</div>
<span class='text_page_counter'>(21)</span><div class='page_container' data-page=21>

5. Tệp văn bản chơng trình Pascal l tệp nh thế no. Có thể tạo ra nó bằng
cách no.


6. Phân biệt lỗi cú pháp v lỗi khi chạy chơng trình, lỗi no thờng dễ phát
hiện hơn, dễ sửa hơn.



7. Nêu các bớc khi xây dựng một chơng trình Pascal. Thực hiện các bớc
ny trong môi trờng phát triĨn tÝch hỵp Turbo Pascal nh− thÕ nμo.


9. Có thể soạn thảo, biên dịch v cho chạy một chơng trình Turbo Pascal từ
môi trờng DOS hay không ? Nếu có cần phải lm nh thế nμo ?


thùc hμnh


1. Khởi động Turbo Pascal, mở tệp mới để soạn thảo, gõ vμo nội dung văn
bản ch−ơng trình "chμo mừng". - Biên dịch vμ sửa lỗi chính tả nếu có. Ghi
lại tệp với tên lμ <i>ChaoMung.Pas</i>. - Chạy thử ch−ơng trình, xem kết quả in
ra nh− thế nμo.


2. ViÕt thªm dòng chú thích vo đầu chơng trình: <i>ngy tháng năm, tác </i>
<i>giả</i>...Biên dịch v cho chạy lại.


3. Ghi lu lại tệp ChaoMung.exe vμo đĩa.


</div>
<span class='text_page_counter'>(22)</span><div class='page_container' data-page=22>

<b>Ch−¬ng2 </b>
<b>Các kiểu dữ liệu chuẩn, các hm chuẩn </b>


<b>1. </b> <b>Các kiểu dữ liệu chuẩn. </b>


<b>1.1 </b> <b>Khái niệm kiểu dữ liệu </b>


Để có hình dung ban đầu về kiểu dữ liệu ta hÃy xét hai khái niệm rất
quen thuộc l số nguyên v sè thùc. Nãi r»ng <i>i</i> lμ mét sè nguyªn ta hiĨu
r»ng ngay r»ng <i>i </i> chỉ có thể nhận các gía trị <i>0,1,2,3</i> .... hay <i>-1,-2,-3</i> ... nghĩa
l không có phần lẻ. Nếu <i>x</i> lμ mét sè thùc th× nã cã thĨ nhËn bÊt cø gÝa trÞ sè
nμo. VËy yÕu tè thứ nhất phân biệt hai "kiểu" số khác nhau ny l miền giá


trị m chúng có thể nhận.


Nu xét đến các phép toán số học cộng trừ nhân chia, nhất lμ phép chia,
một lần nữa lại thấy rằng có sự khác biệt giữa các số nguyên vμ số thực. Phép
chia hai số ngun nói chung khơng cho ta một số nguyên. Do đó cần đặt ra
phép chia lấy kết quả nguyên đối với các số nguyên. Ta có thể nói đến phép
chia đồng d− trong tập hợp các số nguyên còn đối với số thực thì điều nμy
khơng có ý nghĩa.


Có những dữ liệu mang thơng tin khơng phải lμ số, ví dụ tên ng−ời, địa
chỉ, v.v.. lμ các dữ liệu kiểu xâu kí tự.


Tóm lại, dữ liệu có nhiều "kiểu" khác nhau. Những "kiểu" nμy đ−ợc
đặc tr−ng bởi miền giá trị có thể nhận, các phép tốn nμo có thể tác động lên,
kết quả của các phép toán nh− thế nμo...


Từ các kiểu đơn giản lμm cơ sở lại có thể xây dựng, "tổ chức" thμnh
các kiểu phức tạp hơn, có "cấu trúc" . Khi nhìn thấy bộ ba số viết nh− sau
19/08/1945 hầu nh− mọi ng−ời đều nghĩ ngay rằng đây lμ một ngμy tháng.
Ai đã quen biết với tóan học cao cấp thì hiểu ngay rằng véc tơ, ma trận... lμ
các "kiểu dữ liệu" đ−ợc "cấu trúc" từ các thμnh phần đơn giản hơn lμ các số.


<b>1.2 </b> <b>Phân loại các kiểu dữ liệu trong TurboPascal. </b>


</div>
<span class='text_page_counter'>(23)</span><div class='page_container' data-page=23>

những kiểu cơ sở, không thể phân chia nhỏ hơn nữa thnh một số thnh phần
có nghĩa. Các kiểu có cấu trúc l những kiểu đợc xây dựng nên bằng cách
phối ghép một số dữ liệu thμnh phÇn.


Trong mỗi loại trên, loại đơn giản hay loại có cấu trúc, lại có thể phân
chia lμm hai nhóm.



Nhóm thứ nhất bao gồm những kiểu đã có sẵn, đã đ−ợc xây dựng sẵn
với những tính chất hoμn toμn xác định, ta có thể sử dụng ngay mμ khơng cần
"gia cơng" gì thêm. Đây lμ những kiểu dữ liệu phổ biến, hay đ−ợc sử dụng
nhất nh− các kiểu số nguyên, số thực, kí tự, xâu kí tự .. Vì thế mμ Turbo
Pascal (vμ các ngơn ngữ lập trình khác nói chung) đã định nghĩa sẵn. Ta gọi
đó lμ các kiểu dữ liệu <i>chuẩn</i>.


Xếp vμo nhóm thứ hai lμ những kiểu cịn lại, nghĩa lμ ch−a có sẵn.
Những kiểu mμ ng−ời sử dụng phải gia công thêm, tự xây dựng tuỳ theo mục
đích sử dụng của mình.


Sơ đồ d−ới dây phân loại các kiểu dữ liệu trong Turbo Pascal nh− đã
nói trên.


















ở nhánh d−ới cùng trong sơ đồ trên lμ những kiểu dữ liệu có cấu trúc
do ng−ời lập trình tự xây dựng. Đó lμ <i>Stack</i> (Ngăn xếp), <i>Queue</i> (Hμng đợi),


<i>List</i> (danh sách), <i>Tree</i> (Cây), v.v.. Môn “Cấu trúc dữ liệu vμ thuật giải” sẽ
trình bμy đầy đủ về vấn đề nμy. <b> </b>


Kiểu
đơn
giản
Kiểu

cấu
trúc
Chuẩn
Do
ng−ơì
lập trình
định
nghĩa
Đã có
sẵn
Do
ng−ời
lập trình
xây
dựng


<i>Integer, </i>(nguyên)



<i>Byte, Char </i>(kí tự)


<i>Real</i>(thực)


Kiểu đoạn con
Kiểu liệt kê


<i>String</i> (xâu kí tự)


<i>Array</i> (mảng)


<i>Set</i> (tập hợp)


<i>Record</i> (bản ghi)


<i>File</i>(Tệp)


<i>Boolean</i> (lôgic)


</div>
<span class='text_page_counter'>(24)</span><div class='page_container' data-page=24>

<b>1.3 </b> <b>Các kiểu đơn giản chuẩn </b>


1.3.1 <i>KiĨu Boolean hay L«gic </i>


- Miền giá trị: Chỉ có hai giá trị <i>False, True</i>


- Thứ tự: quy định <i>False < True</i>


- C¸c phÐp to¸n AND, OR, XOR, NOT


Bảng dới đây minh häa ý nghÜa c¸c phÐp to¸n. KÝ hiƯu <i>p</i> vμ <i>q</i> lμ hai


biĨu thøc l«gic.


<i>p </i> <i>q </i> <i>NOT p </i> <i>p AND q </i> <i>p OR q </i> <i>p XOR q </i>


True
True
False
False
True
False
True
false
False
False
True
True
True
False
False
False
True
True
True
False
False
True
True
False


1.3.2 <i>Kiªđ Integer - sè nguyªn </i>



Khác với số ngun trong tốn học, có thể nhận bất cứ giá trị nguyên
nμo dù lớn đến đâu, kiểu số nguyên đối với máy tính bị hạn chế bởi khả năng
vật lí để thể hiện một số trong bộ nhớ. Ta dμnh cμng nhiều bit để thể hiện
một số nguyên thì miền các giá trị có thể t−ơng ứng sẽ cμng rộng. Trái lại
nếu ta tiết kiệm chỉ dμnh vμi bit để thể hiện một số nguyên thì miền các giá
trị có thể của nó cμng hẹp.


Cơ thĨ lμ, với 8 bit ta thể hiện đợc <i>28<sub> = 256</sub></i><sub> sè kh¸c nhau. NÕu chØ </sub>
xÐt c¸c sè không âm ta có miền giá trị l <i>0..255</i>. Nếu xét cả các số âm, sẽ có
miền giá trị cã thĨ lμ <i>-128 .. 127.</i> Víi 16 bit ta thể hiện đợc <i>216 = 65536</i>
khả năng khác nhau ...


Bng di õy lit kờ các kiểu số nguyên khác nhau trong Turbo
Pascal với miền giá trị có thể của những kiểu nμy. Ta thấy rằng có sự t−ơng
ứng chặt chẽ giữa miền giá trị có thể của một kiểu với số l−ợng byte nhớ
dμnh để biểu diễn chúng.




Tên Miền giá trị Số


byte
Giải thích
<i>Shortint </i>
<i>Integer </i>
<i>Longint </i>
<i>Byte </i>
<i>Word</i>
-128..127


-32768..32767
-2147483648..2147483647
000..255
00000..65535
1
2
4
1
2


28 = 2* 128
216<sub> = 2* 32768 </sub>


232<sub> = 2* 2147483648 </sub>
28= 256


</div>
<span class='text_page_counter'>(25)</span><div class='page_container' data-page=25>

- Các phép toán: Kiểu số nguyên có các phép toán số học thông thờng


l <i>cộng, trừ, nhân</i>. Dấu phép toán tơng ứng l +, -, “*”. L−u ý r»ng


phÐp chia “/” th«ng th−êng của hai số nguyên cho kết quả l số thực.
Hai phép toán chia của riêng kiểu số nguyên l:


DIV: chia lấy kết quả nguyên, ví dụ 7 DIV 3 = 2.
MOD: chia lÊy phÇn d−, vÝ dơ 7 MOD 3 = 1.


Khi thực hiện các phép toán với kiểu số phải l−u ý kết quả không đ−ợc
v−ợt ra ngoμi phạm vi biểu diễn của kiểu số đó. Trái lại kết qủa sẽ bị biến
dạng sai đi.



1.3.3 <i>KiÓu Real - sè thùc. </i>
- Miền giá trị:


Cng ging nh i vi s nguyên, số thực đ−ợc phân chia lμm nhiều
kiểu khác nhau với miền giá trị rộng hẹp khác nhau tuỳ theo l−ợng ô nhớ
dμnh để thể hiện một số. Nhớ lại rằng trong bộ nhớ của máy tính, số thực
đ−ợc biểu diễn d−ới dạng dấu chấm động. Bit đầu tiên dμnh riêng để ghi dấu.
Giá trị của số đ−ợc thể hiện bởi hai phần: phần định trị vμ phần bậc.


Trong bảng d−ới dây, ở cột miền giá trị chỉ nêu miền biến thiên của
giá trị tuyệt đối. Tr−ớc chữ E lμ phần định trị, sau chữ E lμ phần bậc. Bên trái
lμ giá trị tuyệt đối bé nhất có thể. Mọi giá trị nhỏ hơn nó đều đ−ợc coi lμ 0.
Bên phải lμ giá trị tuyệt đối lớn nhất có thể. Các giá trị v−ợt q nó đều
khơng biểu diễn đ−ợc vμ sẽ có lỗi trμn ơ nhớ.




Tªn Miền giá trị Số byte


cha


Số chữ sè cã nghÜa


<i>Single </i>
<i>Real </i>
<i>Double </i>
<i>Extended</i>


1.5 E-45 .. 3.4 E+38
2.9 E-39 .. 1.7 E+38


5.0 E-324 .. 1.7 E+308
3.4 E-4932 .. 1.1 E+4932


4
6
8
10


7- 8
11-12
15-16
19-20


Trong ch−ơng trình Pascal, một số thực có thể đ−ợc viết d−ới 2 dạng.
Dạng quen biết thông th−ờng lμ <i>phần nguyên, dấu chấm thập phân, phần lẻ</i>.
Đây gọi lμ dạng dấu chấm tĩnh. Dạng thứ hai lμ dấu chấm động nh− trình
bμy ở trên.


</div>
<span class='text_page_counter'>(26)</span><div class='page_container' data-page=26>

- C¸c phÐp to¸n: Bèn phÐp to¸n sè häc <i>céng, trõ, nh©n, chia</i> ( +, - , * ,
/ ) quen thuéc.


L−u ý r»ng nÕu kết quả phép toán vợt ra ngoi phạm vi biểu diễn của
kiểu tơng ứng thì sẽ mắc lỗi trn ô nhớ - <i>overflow</i>. Đặc biệt l khi chia cho
một số quá nhỏ, gần với không.


1.3.4


1.3.5


<i>KiÓu Char - kÝ tù </i>



- Miền giá trị: lμ bảng mã ASCII gồm 256 kí tự khác nhau. Mỗi kí tự
chiếm 1 byte. Mã của một kí tự nμo đó chính lμ <i>số thứ tự</i> của nó trong bảng
mã nμy.


Trong ch−ơng trình Pascal, một giá trị của kiểu kí tự phải đ−ợc viết
nằm giữa hai dấu nháy đơn. Ví dụ 'A', 'B', '?' ... . Cách thứ hai lμ dùng dấu #
kèm với mã của nó, ví dụ #65, #66, #63..


- Thứ tự: Kiểu <i>Char</i> có thứ tự đ−ợc quy định chính lμ thứ tự xuất hiện
của các giá trị kí tự trong bảng mã ASCII. Nghĩa lμ ‘a’ < ‘b’ < ‘c’.. hay #97
< #98 < #99


- L−u ý: 32 kí tự đầu tiên ( #0 .. #31) lμ các kí tự điều khiển, khơng
dùng để hiển thị các kí hiệu mμ có một ý nghĩa riêng.


<i>KiĨu String - x©u kÝ tù </i>


Kiểu <i>String</i> hay xâu kí tự sẽ đ−ợc nghiên cứu kĩ hơn sau nμy trong
ch−ơng "Kiểu xâu kí tự". ở đây chỉ tạm thời nêu những nét cơ bản nhất.
Dữ liệu kiểu xâu kí tự lμ một dãy gồm một số kí tự bất kì. Xâu kí tự lμ tổng
qt hố của một từ hay một cụm từ. Số kí tự trong xâu gọi lμ độ dμi của xâu.
Khai báo kiểu <i>String[n]</i> có nghĩa lμ xâu kí tự có độ dμi khơng q <i>n</i>.


- MiỊn giá trị của kiểu <i>String[n]</i> l tất cả các xâu kí tự có không quá <i>n</i>


kí tự.


- Trong ch−ơng trình Pascal, một giá trị xâu kí tự cũng cần phải viết
trong cặp dấu nháy đơn. Ví dụ ‘Pascal’, ‘Chuong trinh’, ..



- Thứ tự: quy định thứ tự trong tập hợp các xâu kí tự lμ thứ tự kiểu tự
điển. Tr−ớc hết so sánh hai kí tự đầu tiên, nếu trùng nhau thì so sánh tiếp kí
tự thứ hai, thứ ba ...


- Các phép toán của kiểu <i>String</i> sẽ trình by trong chơng Kiểu xâu kí
tự.


<b>2. </b> <b>Các hàm chuẩn. </b>


Các hμm số học, lô gic cơ bản rất hay đ−ợc sử dụng. Chúng cần đ−ợc
lμm sẵn để ng−ời lập trình sử dụng. Đó lμ các hμm chuẩn. Bảng các hμm
chuẩn d−ới đây liệt kê các hμm ấy.


</div>
<span class='text_page_counter'>(27)</span><div class='page_container' data-page=27>

báo sử dụng th− viện ta cần. Các <i>Unit</i> sẽ đ−ợc giới thiệu dần khi trình bμy cỏc
vn cú liờn quan.


<b>2.1 </b> <b>Bảng các hµm chuÈn. </b>


Cần l−u ý đến kiểu của tham đối vμ kiểu của kết quả nh− trong bảng đã
nêu.


Loại Tên Kiểu của
đối số
Kiểu của
kết quả
Y nghĩa
<b>Sqr </b>
<b>Abs </b>
Nguyên,


thực
Giống
kiểu của
đối số


<i>Sqr (x</i>

)

<i> = x2</i>


<i>Abs (x</i>

) = |

<i>x</i> |


<b>Sqrt </b>
<b>Sin </b>
<b>Cos </b>
<b>Arctan </b>
<b>Ln </b>
<b>Exp </b>
Nguyªn,
thực
Thực


<i>Square root -</i> Căn bậc hai.


<i>Sqrt(x)</i> = <i>x</i>


Logarit c¬ sè e


<i>Exponential</i> - hμm mị


<i>Exp(x) = ex</i>


Số học


<b>Trunc </b>
<b>Round </b>
Nguyên,
thực
Nguyên


Cắt bỏ phần lẻ. <i>Trunc</i>(3.7)= 3
Lm tròn. <i>Round</i>(3.7)=4.


<i>Round</i>(1.5) = 2


<b>Pred </b>
<b>Succ </b>
Nguyên
Logic
Kí tự
Giống
đối số


<i>Predecessor</i> - giá trị ngay


trớc. Pred(4) = 3, Pred (d)
= c.


<i>Successor </i>- giá trị ngay sau.


<i>Succ</i>(4) = 5, <i>Succ</i>(‘d’) = ‘e’.


<b>Ord </b>



KÝ tù Nguyªn


<i>Order</i> – thø tù. Cho sè thø


tù cña kÝ tù trong b¶ng m·.


<i>Ord</i>(‘a’) = 97.
Thø tù


<b>Chr </b> Nguyªn KÝ tù


<i>Character</i> – kÝ tù. Cho kí tự


có mà l số nguyên tơng
ứng. <i>Chr</i>(97) = ‘a’.


Logic <b>Odd </b> Nguyªn Logic


<i>Odd</i> lẻ. Hm trả lại <i>true</i>


nu i l s l, <i>false </i>nếu đối
lμ số chẵn, kết quả lμ


</div>
<span class='text_page_counter'>(28)</span><div class='page_container' data-page=28>

<b>2.2 </b> <b>Sư dơng. </b>


C¸c hμm đợc viết trực tiếp trong biểu thức nh thông th−êng.
VÝ dơ:


BiĨu thøc sè häc:



<i>a:= abs(x) + exp(3.5); </i>


BiĨu thøc tÝnh nghiƯm cđa tam thøc bËc hai:


<i>x1:= ( -b + sqrt (b*b - 4*a*c)) / (2*a)</i>

;



Biểu thức lợng giác:


<i>y:= sin(2*x) + 2* cos(x); </i>


C©u hái vμ bμi tËp


1. Những kiểu số ngun nμo khơng có giá trị số âm. Chúng th−ờng dùng để
lμm gì.


2. Nếu biến <i>N</i> có kiểu <i>integer</i> vμ ta dùng nó để chứa kết quả tính <i>N:= k!</i> thì
số <i>k</i> lớn nhất có thể lμ bao nhiêu để kết quả khụng sai.


3. Viết các số sau đây dới dạng thập phân thông thờng.


<i>103E-4 1.2345E+6 321.04E+2 </i>


4. Viết các số sau d−ới dạng dấu chấm động chuẩn hóa


<i>1300 345.67 0.00621 </i>


5. T×m d−íi đây những biểu thức l một <i>giá trị trực tiếp</i> hợp lệ v nhận biết
kiểu dữ liệu của chúng


<i>17 'abc' 25.14 $ </i> <i>$07AB -333 .102 102. </i>



<i>“x" </i> <i>'x' </i> <i>x </i> <i>'8' </i> <i>'-3' </i> <i>True </i> <i>'True' "True"</i>


6. TÝnh c¸c biĨu thøc sau


<i>22 DIV 7 </i> <i>7 DIV 22 </i> <i>22 MOD 7 </i> <i>7 MOD 22 </i>


<i>'c' < Succ('a') </i> <i>10 = Pred(11) </i> <i>Trunc(-15.8) </i>


<i>Round(-15.8) </i> <i>Round(3.5) Sqrt(Abs(Round(-15.8))) </i>


<i>ord('B') + 1</i>


7. ViÕt c¸c biĨu thøc sau dïng c¸c hμm chn cđa Turbo Pascal


<i>1 + e2x 2ax </i> <i>x1/2 </i> <i>x1/3 </i> <i>log<sub>10</sub> x</i>


Thùc hμnh.


</div>
<span class='text_page_counter'>(29)</span><div class='page_container' data-page=29>

<b>Ch−ơng 3 </b>
<b>Các khai báo vμ câu lệnh đơn giản </b>


<b>1. </b> <b>Khai b¸o h»ng vµ biÕn </b>


Một nguyên tắc chung khi viết một ch−ơng trình Pascal lμ mọi thứ đều
phải đ−ợc khai báo (vμ xây dựng) tr−ớc khi sử dụng. Vì lẽ đó mμ ngay sau
tên ch−ơng trình lμ phần khai báo, rồi sau đó mới lμ thân ch−ơng trình.


Nh− đã nêu trong phần giới thiệu cấu trúc một ch−ơng trình Pascal,
phần khai báo phải theo đúng trình tự d−ới đây. Phần nμo khơng cần đến thì


bỏ qua.


1- Khai báo các th− viện ch−ơng trình mẫu sẽ dùng đến trong ch−ơng trình.
Cú pháp: Từ khố <i>User</i>, sau đó lμ danh sách các Unit.


2- Khai b¸o c¸c h»ng.


Cú pháp: Từ khố <i>Const</i>, sau đó lμ danh sách khai báo hằng
3- Khai báo các kiểu.


Cú pháp: Từ khoá <i>Type</i>, sau đó lμ danh sách các khai báo kiểu
4- Khai báo các biến.


Cú pháp: Từ khoá <i>Var</i>, sau đó lμ danh sách các khai báo biến
5- Phần các ch−ơng trình con.


Từ khố <i>Procedure</i> để khai báo thủ tục.
Từ khoá <i>Function</i> để khai báo hμm.


D−ới đây sẽ trình bμy về khai báo hằng vμ khai báo biến. Cách thực
hiện các khai báo khác sẽ đ−ợc giới thiệu sau, khi bμn đến các chủ đề có liên
quan.


Để tiện trình bμy các quy định về cú pháp ta quy −ớc rằng ngoμi các từ
khoá, tên chuẩn của Turbo Pascal lμ phần khung phải giữ nguyên (đ−ợc in
đậm), những thμnh phần đ−ợc nhấn mạnh bằng kiểu chữ nghiêng lμ các thμnh
phần mμ ng−ời xây dựng ch−ơng trình cần phải bổ xung thêm vμo.


<b>1.1 </b> <b>Khai báo hằng </b>



1.1.1 <i>Hằng l gì. </i>


</div>
<span class='text_page_counter'>(30)</span><div class='page_container' data-page=30>

1.1.2


1.1.3


1.2.1


<i>Có ph¸p vμ vÝ dơ. </i>


<b>Có ph¸p</b>: <b>Const</b> <i>tên hằng = giá trị hằng ;</i>


ở vế phải, giá trị hằng l một <i>giá trị trực tiếp ( literal value)</i>. Giá trị
trực tiếp l một giá trị lấy từ trong miền giá trị của kiểu dữ liệu, không phải
thực hiện tính toán gì thêm.


Có thể viết nhiều khai báo hằng liên tiếp nhau.


<b>VÝ dô</b>: const


<i>maxSize</i> = 50 ;


<i>tieuDe</i> = 'Cong hoa xa hoi chu nghia Viet nam' ;


<i>sigma</i> = 0.1/ (2*pi) ;


<i>laiXuat</i> = 0.05 ;


<i>Tại sao nên khai báo hằng. </i>



Mt cõu hỏi tự nhiên đặt ra lμ, tại sao nên dùng khai báo giá trị hằng
thay cho việc viết trực tiếp giá trị ấy tại những nơi cần đến nó. Sử dụng khai
báo hằng sẽ có hai −u điểm sau õy:


- Chơng trình rõ rng, dễ hiểu hơn. Các tên hằng <i>maxSize, sigma, </i>


<i>laiXuat...</i> trong các ví dụ trên rõ rng l dễ hiểu, dễ nhớ hơn l các con số khô


khan m chúng thay thế.


- Ch−ơng trình dễ chỉnh sửa hơn. Ví dụ nếu sau nμy cần tăng kích
th−ớc lớn nhất cho phép lên 100 chứ khơng phải lμ 50 thì chỉ cần sửa duy
nhất một chỗ lμ dòng khai báo. Nếu lãi xuất đ−ợc điều chỉnh lại lμ 0.04 thì
cũng khơng phải sửa lại hết toμn bộ các công thức liên quan mμ chỉ cần sửa ở
dòng khai báo mức lãi xuất lμ đủ.


<b>1.2 </b> <b>Khai báo biến </b>


<i>Biến l gì. </i>


Bin l cỏc i l−ợng mμ gía trị có thể biến đổi trong ch−ơng trình.
Biến lμ cái dùng để chứa các dữ liệu phục vụ cho q trình tính tốn, xử lí
trong ch−ơng trình. Nó có thể chứa dữ liệu đầu vμo, kết quả trung gian hay
kết quả cuối cùng của q trình xử lí.


</div>
<span class='text_page_counter'>(31)</span><div class='page_container' data-page=31>

Khai báo biến lμ đăng kí <i>tên</i> của biến kèm với <i>kiểu</i> dữ liệu của nó.
Các biến khác nhau khơng đ−ợc trùng tên nhau. Trình biên dịch sẽ dμnh cho
mỗi biến một vùng nhớ xác định, đủ để chứa dữ liệu kiểu t−ơng ứng. Vùng
nhớ nμy rộng hay hẹp (dμi, ngắn) đến đâu lμ do kiểu dữ liệu của biến quyết


định.


1.2.2 <i>Có ph¸p vμ vÝ dơ. </i>


<b>Có ph¸p: </b> <b>Var </b> <i>tên biến: kiểu dữ liệu ;</i>


- Sau tõ kho¸ VAR cã thĨ viÕt nhiỊu khai báo biến liên tiếp nhau,
cách nhau dấu chấm phÈy.


- Có thể khai báo đồng thời nhiều biến <i>cùng kiểu</i>. Thay cho một tên
biến lμ danh sách các tên biến cách nhau dấu phẩy.


- Cã thĨ võa khai b¸o võa gán giá trị khởi đầu cho biến, viết dấu bằng,
theo sau l một giá trị trực tiếp.


Ví dụ: VAR


<i>x,y,z</i>: real ;


<i>GoPhim, Chon</i>: char;


<i>TimThay</i>: boolean = true ;


<i>Dem</i>: integer = 0 ;


<b>2. </b> <b>Biểu thức trong ngôn ngữ Pascal. </b>


<b>2.1 </b> <b>Biêủ thức là gì. </b>


Ta ó quen vi khỏi nim biu thc tốn học.


Ví dụ các biểu thức số học


<i>2 </i>

π

<i> R </i>


<i>10.34 + sin 2x </i>


<i>2 </i>

π

<i> R / (10.34 + sin 2x)</i>


vμ c¸c biĨu thøc l«gic

Δ

<i> 0 </i>


<i>(</i>

Δ

<i> 0) AND (a = 0).</i>


Nhận thấy rằng các thnh phần của biểu thức có thể l một giá trị trực
tiếpnh 2, 10.34, cã thÓ lμ mét h»ng nh− sè Pi, cã thÓ lμ biÕn nh− <i>x</i>, cã thÓ
lμ hμm nh− <i>sin2x</i> hc cịng cã thĨ lμ mét biĨu thức khác.


</div>
<span class='text_page_counter'>(32)</span><div class='page_container' data-page=32>

toán hạng có thể l một giá trị trực tiếp, một hằng, một biến, một hm hoặc
một biểu thức khác.


Vì toán hạng có thể l một biểu thức khác, nếu kết hợp nhiều biểu thức
bằng các dấu phép toán ta lại cã biĨu thøc míi. B»ng c¸ch nμy ta cã thĨ xây
dựng các biểu thức ngy cng lớn v phức t¹p.


Việc thực hiện các phép tốn để nhận đ−ợc kết quả cuối cùng gọi lμ
tính giá trị của biểu thức.


VÝ dơ, c¸c biĨu thøc sè häc ở trên có thể đợc viết lại trong Pascal nh
sau



<i>2 * pi * BanKinh </i>


<i> 1 + sin(2*x) </i>


<i>2 * pi * BanKinh / (1 + sin(2*x))</i>


v các biểu thức lôgic l


<i>Delta <> 0. </i>


<i>(Delta <> 0) AND (a = 0).</i>


<b>2.2 </b> <b>B¶ng thø tù −u tiªn </b>


Khi thực hiện các phép tốn trong biểu thức phải tuân theo quy định về
"thứ t u tiờn".


Dới dây l bảng thứ tự u tiên của các phép toán xếp theo mức u
tiên giảm dần từ trên xuống dới.


Loại Phép toán Kí hiệu Kiểu của toán
hạng


Kiu ca kt quả
đổi dấu - Nguyên, thực Giống tốn hạng
Một ngơi


Phủ định NOT Logic logic


Nhân * Nguyên, thực Giống toán hạng


Chia
Chia bỏ
d
Chia lấy
d
/
DIV
MOD
Nguyên, thực
Nguyên
Nguyên
Thực
Nguyên
Nguyên
Nhân


Vμ AND Logic logic


Céng
Trõ
+
-
Nguyªn hoặc
thực


Giống toán hạng
Cộng


Hoặc OR Logic logic



So s¸nh = <>
< <=
> >=


</div>
<span class='text_page_counter'>(33)</span><div class='page_container' data-page=33>

<b>2.3 </b> <b>Viết đúng biểu thức </b>
L−u ý:


1- Không đ−ợc bỏ qua dấu phép nhân “ * ” giữa hai thừa số. Biểu thức
toán học <i>2x</i>, trong Pascal phải viết đầy đủ lμ <i>2*x. </i>


2- Dấu phép chia l kí hiệu gạch xiên / . VÝ dơ <i>1 / (2* Pi)</i>. Kh«ng
dïng dấu hai chấm. Không dùng cách viết tử số v mẫu số trên hai dòng
khác nhau.


3- Nếu dÃy liỊn nhau nhiỊu phÐp to¸n cã cïng thø tù −u tiên thì thực
hiện từ trái sang phải.


4- thay đổi thứ tự −u tiên, dùng cặp dấu ngoặc đơn “( , )”. Một cặp
dấu ngoặc đơn sẽ xác định một biểu thức con, nh− một toán hạng tham gia
cấu thμnh biểu thức lớn hơn chứa nó.


Để thể hiện đúng vμ rõ rμng một biểu thức phức tạp cần phải sử dụng
các cặp dấu ngoặc đơn.


VÝ dơ: TÝnh nghiƯm cđa tam thøc bËc hai, nÕu ta viÕt


<i>x1:= -b + sqrt (delta</i>

)

<i> / 2*a </i>


sẽ nhận đợc <i>x1 = -b + (sqrt(delta) /2) * a.</i>



Để tính đúng nghiệm của ph−ơng trình bậc hai cần sửa lại lμ


<i>x1:= ( -b + sqrt (delta)) / (2*a) </i>

;



<b>3. </b> <b>Các câu lệnh đơn giản </b>


Turbo Pascal lμ một ngôn ngữ lập trình cấu trúc. Ngoμi những câu lệnh
đơn thực hiện một cơng việc xác định, có những câu lệnh cho phép phối hợp
tổ chức nhiều công việc theo một quy tắc nhất định. Đó gọi lμ các câu lệnh
tạo cấu trúc điều khiển hay ngắn gọn lμ các lệnh cấu trúc.


Ta có sơ đồ phân loại các câu lệnh nh− sau
1 - Câu Lệnh đơn giản:


-LƯnh g¸n :=
-LƯnh xt <i>write</i>


-LƯnh nhËp <i> read</i>


-C¸c lƯnh kh¸c: <i>goto, halt, exit ..</i>


2- C©u lƯnh cÊu tróc


-LƯnh ghÐp <i>begin - end</i>


-LÖnh lùa chän <i>if, case</i>


-LƯnh lỈp <i>for, repeat, while</i>


</div>
<span class='text_page_counter'>(34)</span><div class='page_container' data-page=34>

<b>3.1 </b> <b>Lệnh gán </b>



Gán giá trị cho một biến.


Ngôn ngữ Pascal quy định dấu phép gán lμ dấu hai chấm, tiếp theo lμ
dấu bằng “:=”, đọc lμ “gán bằng”.


<b>Có ph¸p: </b> <i>biÕn:= biĨu thøc</i> ;


Thực hiện: tính biểu thức ở vế phải, sau đó gán cho biến ở vế trái.
Ví dụ: <i>x:= 2 + 3*sin(2*a) ; </i>


<i> </i> <i>i:= maxSize MOD 3; </i>


L−u ý:


- Chỉ có biến mới đ−ợc thay đổi giá trị, do đó vế trái của lệnh gán bắt
buộc phải lμ mt bin.


- Phép gán phải tơng thích về kiểu dữ liệu, nghĩa l biến ở vế trái phải
có kiểu giống nh giá trị của biểu thức ở vế ph¶i.


- Phép gán chấp nhận một số chuyển đổi kiểu "tự nhiên". Ví dụ, có thể
gán một giỏ tr nguyờn cho bin thc.


<b>Đề phòng:</b> nhầm lẫn viÕt dÊu phÐp g¸n chØ cã dÊu b»ng, thiÕu dÊu hai
chÊm. DÊu b»ng “=” lμ dÊu cña phÐp “so s¸nh b»ng nhau”.


<b>3.2 </b> <b>Lệnh in ra màn hình khơng kèm định dạng. </b>


3.2.1



3.2.2


<i>Có ph¸p </i>


Cã 4 dạng câu lệnh in ra mn hình:


<b>Write</b>( <i>biÓu thøc</i>) ; (1)


<b>Write</b>( <i>biÓu thøc1 , biÓu thøc2 , ... , biÓu thøc n</i> ) ; (2)


<b>Writeln</b>( <i>biÓu thøc1 , biÓu thøc2 , ... , biÓu thøc n</i> ); (3)


<b>Writeln</b> ; (4)


<i>Thùc hiƯn </i>


Nh− đã biết, mμn hình ở chế độ văn bản đ−ợc chia bởi các cột vμ các
dịng thμnh các ơ hình chữ nhật (thơng th−ờng có 80 cột vμ 25 dịng, tức lμ
2000 ơ chữ nhật). Mỗi ơ có thể hiển thị một kí tự trong bảng mã ASCII. Ta
gọi mỗi ơ kí tự lμ một vị trí.


</div>
<span class='text_page_counter'>(35)</span><div class='page_container' data-page=35>

Dạng (1): bắt đầu từ vị trí con chạy, in ra mμn hình g<i>iá trị </i>của biểu
thức theo quy cách mặc định đối với kiểu dữ liệu của biểu thức đó<i>.</i> In xong
con chạy dừng tại vị trí cuối cùng.


Dạng (2): bắt đầu từ vị trí con chạy, in ra mμn hình lần l−ợt các <i>giá trị</i>
của các biểu thức 1 đến biểu thức n, nối tiếp liền nhau. Giá trị của từng biểu
thức đ−ợc in ra theo quy cách mặc định đối với từng kiểu dữ liệu. In xong
con chạy dừng tại vị trí cuối cùng.



Nh− vËy, thùc chÊt c©u lệnh dạng 2 l viết gọn của n câu lệnh dạng 1
liền nhau.


Dạng (3): tác dụng nh dạng (1) nhng in xong thì thêm một dấu
xuống dòng, con chạy dừng tại cột đầu tiên của dòng dới.


Dạng (4): chỉ in ra một dấu xuống dòng tức l con chạy xuống cột đầu
dòng d−íi.


<b>3.3 </b> <b>Quy cách mặc định in ra các kiểu dữ liệu. </b>


3.3.1 <i>Minh häa </i>


LÖnh SÏ in ra


Write(1234); <sub>1234 </sub>


Write(-123.456); <sub>-1.2345600000E+02 </sub>
Write('A');


write(chr(65));
write(#7);


A
A


<Ph¸t mét tiÕng bip>
Write(2>1); <sub>TRUE </sub>



Write(' Ha
noi' );


Ha noi


3.3.2 <i>Quy c¸ch </i>


Tóm lại quy cách mặc định in ra của từng kiểu dữ liệu lμ:


- Số ngun: có bao nhiêu chữ số thì in ra đúng bấy nhiêu.


- Số thực: in ra d−ới dạng dấu phẩy động, theo trình tự nh− sau: dấu +/-,
một chữ số phần nguyên (luôn khác 0), dấu chấm thập phân, 10 chữ số phần
lẻ (thêm số 0 vμo bên phải nếu cần), chữ E, dấu của phần mũ, hai chữ số giá
trị của phần mũ.


- Kí tự: chiếm đúng một vị trí. Nếu lμ kí tự điều khiển thì thực hiện
hμnh vi t−ơng ứng.


</div>
<span class='text_page_counter'>(36)</span><div class='page_container' data-page=36>

3.3.3 <i>Ví dụ tổng hợp. </i>


Chơng trình bên trái sẽ in ra mn hình nh trình by ở cột bên phải
Program In_ra_khong_dinh_dang;


Uses crt;


Var i: integer = 123;
R: real = 123.456;
Ch: char ='a';
B: boolean = 2>1;



Xau: string = ' Vietnam
';


BEGIN


Write(i); write(r);
writeln;


Writeln(i,r);
Write(ch,Xau,B);
END.


<i>KÕt qu¶ in ra </i>


123 1.2345600000E+02
123 1.2345600000E+02
a VietnamTRUE


Ta đã có thể viết thử những ch−ơng trình Pascal đơn giản đầu tiên thực
hiện một vμi tính tốn có ích.


Program HinhChuNhat;
Uses crt;


Var Dai,Rong,ChuVi,DienTich: real;
Begin


Clrscr;



Dai:= 5.0;


Rong:= 3.5;


ChuVi:= 2* (Dai + Rong);
DienTich:= Dai * Rong ;


Writeln(' Chu vi la = ' , ChuVi );


Writeln(' Dien tich la = ' , DienTich);
End.


<b>3.4 </b> <b>LƯnh in ra cã kÌm quy c¸ch </b>


Để bố trí mμn hình kết quả đẹp đẽ vμ dễ đọc hơn, ta cần sắp xếp các
mục in ra sao cho đúng vị trí, dóng thẳng hμng, cột.


Turbo Pascal cung cÊp c¸c lƯnh in ra có quy cách. Nguyên tắc chung
l:


</div>
<span class='text_page_counter'>(37)</span><div class='page_container' data-page=37>

<b>Có ph¸p: </b>


<b>Write</b>( <i>biĨu thøc</i>: <i>n</i>);


Phần “<i>: n”</i> thêm vμo sau biểu thức gọi lμ phần định dạng in ra.


- Riªng víi <i>sè thùc,</i> cã thể in ra dới dạng biểu diễn thập phân thông
thờng bằng cách chỉ rõ số vị trí dnh cho toμn bé con sè lμ <i>n</i> vμ sè vị trí
dnh cho phần lẻ l <i>m</i>.



<b>Cú ph¸p: </b>


<b>Write</b>( <i>biĨu thøc sè thùc</i>: n: m);


VÝ dụ, với các khai báo v gán trị nh trong chơng trình trên ta sẽ có


Lệnh Sẽ in ra


Write (i:10); <sub> 123 </sub>
Write (r:10);


Write (r:12:5);


-1.234E+02
-123.45600
Write (ch:12); <sub> a </sub>
Write (b:12); <sub> TRUE </sub>


Tóm lại, nếu có ấn định quy cách máy sẽ dμnh số vị trí để in ra giá trị
của biểu thức, căn lề từ bên phải, bỏ trống số vị trí thừa bên trái, cắt cụt (lμm
sai giá trị !) nếu thiếu chỗ.


<b>3.5 </b> <b>LÖnh in ra máy in </b>


Để in ra máy in trớc hết cần bổ xung thêm vo đầu chơng trình dòng
khai b¸o sư dơng m¸y in.


<b>Uses</b> printer;


Sau đó trong mỗi câu lệnh Write, tr−ớc dãy các mục cần in ra, cần


thêm tham số LST lμ biến tệp đại diện cho máy in:


</div>
<span class='text_page_counter'>(38)</span><div class='page_container' data-page=38>

<b>3.6 </b> <b>Lệnh nhập dữ liệu từ bàn phím. </b>


3.6.1


3.6.2


3.6.3


<i>Có ph¸p </i>


Có 4 dạng câu lệnh đọc dữ liệu từ bμn phím


<b>Read</b>( <i>biÕn</i>); (1)


<b>Read</b>( <i>biÕn 1 , biÕn 2 , ... , biÕn n</i>) ; (2)


<b>Readln</b>( <i>biÕn 1 , biÕn 2 , ... , biÕn n</i> ); (3)


<b>Readln</b> ; (4)


<i>Thùc hiÖn. </i>


Khi nhập dữ liệu từ bμn phím thì mỗi mục dữ liệu lμ một <i>giá trị trực </i>
<i>tiếp</i>. Các câu lệnh trên sẽ gán các giá trị trực tiếp đọc đ−ợc cho biến t−ơng
ứng.


Dạng (1): khi gặp lệnh nμy máy sẽ đọc từ bμn phím một mục dữ liệu,
chuyển thμnh một giá trị trực tiếp của kiểu dữ liệu của <i>biến</i> vμ gán cho biến.



Dạng (2): khi gặp lệnh nμy máy sẽ đọc từ bμn phím <i>n</i> mục dữ liệu lμ


<i>n</i> giá trị trực tiếp vμ gán lần l−ợt cho <i>n</i> biến theo đúng trình tự. Đây lμ viết
gọn của <i>n</i> câu lệnh dạng 1.


Dạng (3): nh− dạng (2), sau đó tìm đọc thêm 1 dấu xuống dòng. Con
chạy dừng sau dấu xuống dịng.


Dạng (4): Tìm đọc một dấu xuống dòng. Sau câu lệnh nμy, con chạy ở
đầu dòng tiếp theo. Câu lệnh nμy th−ờng dùng để tạm dừng ch−ơng trình, đợi
gõ phím <i>Enter</i>. Ng−ời sử dụng ch−ơng trình có thì giờ xem các thơng báo,
kết quả trung gian, kết quả cuối cùng khi thực thi ch−ơng trình.


<i>Quy cách đọc dữ liệu vμo</i>


1- ChØ cã thĨ nhập từ bn phím các kiểu dữ liệu: số nguyên, số thực, kí
tự v xâu kí tự. Không thể nhËp tõ bμn phÝm d÷ liƯu kiĨu logic.


2- Phải đảm bảo gõ vμo <i>t−ơng ứng</i> số mục dữ liệu vμ đúng kiểu dữ liệu.
Dữ liệu đ−ợc gõ vμo phải lμ một giá trị trực tiếp hợp lệ. Một giá trị số thực
phải viết d−ới dạng thập phân với<i> dấu chấm </i>thập phân. Giá trị kiểu kí tự vμ
xâu kí tự khơng có cặp dấu nháy đơn bao quanh.


Để hiểu rõ hμnh vi của thủ tục <i>Read</i> khi đọc nhiều mục dữ liệu liên
tiếp cần nắm vững dấu hiệu phân cách giữa các mc d liu.


1- Các mục dữ liệu <i>kiểu số</i> (số nguyên, số thực) đợc phân cách nhau
bằng một (hoặc vi) dấu cách, hoặc dấu <i>Tab</i>, hoặc dÊu xuèng dßng<i> Enter</i>.



2- Mục dữ liệu kiểu kí tự khơng có dấu phân cách phía tr−ớc vμ phía
sau. Nghĩa lμ với kiểu kí tự máy đọc đúng một kí tự tiếp theo kể từ vị trí hiện
tại, kể cả đó lμ kí tự khoảng trống.


</div>
<span class='text_page_counter'>(39)</span><div class='page_container' data-page=39>

trống. Dãy kí tự xếp liền nhau sẽ đ−ợc ngắt đúng theo độ dμi <i>n </i>của từng
biến xâu kí tự t−ơng ứng.


Do đó, khi đọc vμo nhiều mục dữ liệu cần l−u ý sử dụng dấu phân cách
cho đúng. Máy chỉ đọc vμ phải đọc đúng <i>n</i> mục dữ liệu, sau đó thực hiện
câu lệnh tiếp theo. Nếu ch−a đủ <i>n</i> mục dữ liệu thì máy vẫn chờ đọc tiếp.
Nếu gõ nhiều hơn thì các mục sau lμ thừa.


3.6.4 <i>Các ví dụ minh hoạ </i>


Giả sử <i>m, n</i> lμ biÕn nguyªn, <i> x</i> lμ biÕn thùc.


Ví dụ: Câu lệnh đọc vμo


lμ <i>Read(m,n,x);</i>


Cã thĨ gâ d÷ liƯu vμo nh− sau:


<i>1 2 3.4 <Enter> </i>


hc


<i>1 2 <Enter> 3.4 <Enter> </i>


hc



<i>1 <Enter> 2 <Enter> 3.4 <Enter> </i>


KÕt qu¶ sÏ cã <i>m:=1, n:=2, x:= 3.4.</i>


Ví dụ 2: Giả sử đã khai báo các biến xâu kí tự có độ dμi 5 kí tự


<i>Var s1,s2,s3: string[5]; </i>


C©u lƯnh nhËp d÷ liƯu vμo lμ


<i>Readln (s1,s2,s3); </i>


NÕu gâ tõ bμn phÝm


<i>AB12CD34 Hanoi <Enter> </i>


th× sÏ cã <i>s1:= AB12C s2:= D34 Ha, s3:= noi.</i>


3: Minh hoạ cách sử dụng c¸c thđ tơc <i>Readln</i>.
VÝ dơ


Giả sử <i>m, n</i> lμ biến nguyên, <i> x</i> lμ biến thực nh− trong ví dụ 1.
Nếu có các lệnh đọc vμo


<i>readln(m,n); </i>
<i>readln(x); </i>


vμ ta gâ vμo


<i>1 2 3.4 <Enter> </i>



thì máy sẽ đọc vμ gán đ−ợc <i>m:=1, n:=2</i> sau đó sẽ xuống dịng. Máy sẽ chờ
để nhận tiếp giá trị cho <i>x</i> do câu lệnh sau ch−a nhận đ−ợc dữ liệu vμo. Để
nhập đúng cần sửa lại thμnh


</div>
<span class='text_page_counter'>(40)</span><div class='page_container' data-page=40>

<b>4. </b> <b>Mét sè hµm, thđ tơc trình bày màn hình. </b>


Nhc li rng mn hỡnh chế độ văn bản đ−ợc chia bởi các cột vμ các
dịng thμnh các ơ hình chữ nhật (thơng th−ờng có <i>80</i> cột vμ <i>25</i> dịng, tức lμ
2000 ơ chữ nhật). Mỗi ơ có thể hiển thị một kí tự trong bảng mã ASCII.
Để trỏ đến một ô nμo đó, ta dùng cặp 2 số nguyên <i>x,y</i> gọi lμ tọa độ mμn
hình <i>(x:= 1..80, y:=1..25</i>).


Turbo Pascal cung cấp một số hμm, thủ tục phục vụ việc trình bμy mμn
hình ở chế độ văn bản. Đây lμ một th− viện mẫu các ch−ơng trình con gọi lμ
unit CRT - <i>Catot Ray Tube</i>.


Để sử dụng các hμm, thủ tục đó phải khai báo sẽ sử dụng unit CRT tại
đầu chng trỡnh:


<b>Uses crt; </b>


Phần dới đây sẽ trình bμy c«ng dơng cđa mét sè hμm, thđ tơc chÝnh
hay dùng.


<b>Clrscr</b>: <i>Clear screen</i> xoá sạch mn hình, con chạy về vị trí (1,1) góc trên


trái.


<b>GotoXY</b>(x,y) : Di chuyển con chạy đến toạ độ (x,y)



<b>Clreol: clear to end of line</b> - xoá các kí tự từ vị trí con chạy đến cuối dịng.
Sau đó, con chạy dừng tại vị trí tr−ớc khi thực hiện thủ tục nμy.


<b>Delline</b>: Xố toμn bộ dịng có con chạy. Sau đó, con chạy dừng tại vị trí tr−ớc
khi thực hiện thủ tục nμy.


<b>WhereX</b>: hμm cho biết con chạy đang ở cột no.


<b>WhereY</b>: hm cho biết con chạy đang ở dòng no.


<b>Windows</b> <i>(x1,y1,x2,y2)</i>: thiết lập một khung vơ hình của cửa sổ hiển thị mới.
Góc trên trái lμ <i>(x1,y1)</i> góc d−ới phải lμ <i>(x2,y2).</i> Từ lúc nμy trở đi, mμn
hình coi nh− thu nhỏ lại trong hình chữ nhật nμy. Toạ độ <i>x=1,</i> <i>y=1</i> sẽ
trùng với góc trên-trái của mμn hình thu nhỏ. Tóm lại, các toạ độ đ−ợc
tính lại nh− sau


<i>Xmíi = Xcị - x1 + 1. </i>


<i>Ymíi = Ycị - y1 + 1</i>.


C©u hái vμ bμi tËp


</div>
<span class='text_page_counter'>(41)</span><div class='page_container' data-page=41>

2. Các câu lệnh sau đây thực hiƯn viƯc g×.


<i>Writeln(' Cho 2 so '); Readln(M,N); </i>
<i>M:=M+5; N:=N*3; </i>


<i>Writeln(' M = ', M); </i>
<i>Writeln(' N = ', N); </i>



3. Trong một ch−ơng trình có các khai báo kiểu dữ liệu vμ các câu lệnh nh−
d−ới đây. Tìm ra các câu lệnh đúng, tính giá trị biểu thức, tìm các câu
lệnh sai vμ giải thích tại sao.


<i>Const MaxI = 1000; </i>


<i>Var x,y: real; </i>


<i>M,N, I: integer; </i>


<i>Y:= -1.0; M:=3; N:=4; </i>
<i>I:= M mod N; </i>


<i>I:=(990 - maxI) div M; </i>
<i>I:= M mod y; </i>


<i>X:= PI * y; </i>
<i>I:= M/N; </i>
<i>X:= M/N; </i>


<i>X:= M mod (M/N); </i>


<i>I:= M mod (990 - maxI); </i>


<i>I:= (maxI - 990) div M; X:= M/y; </i>
<i>I:= PI * M; </i>


<i>X:= PI div y; </i>
<i>X:= M div N; </i>



<i>I:= (maxI - 990) mod M; </i>
<i>I:= M mod 0; </i>


<i>I:= M mod (maxI - 990); </i>


4. Trình by kết quả thực hiện c¸c lƯnh sau.


<i>Write</i> (-88:4);


<i>Writeln</i>(‘Ha noi’: 10);


<i>Writeln</i>(‘-88’: 4, 88: 8: 2);


5. Giả sử<i> x</i> lμ biến thực, nhận giá trị -23.621. Các định dạng in sau đây sẽ in
ra <i>x</i> nh− thế nμo.


x:8:4 x:8:3 x:8:2 x:8:0 x:8


6. Giả sử dùng thủ tục <i>Readln </i>(a,b) để đọc vμo 2 số từ bμn phím. Phải gõ
phím nμo sau khi gõ xong số thứ nhất ? sau khi gõ xong số thứ hai ? Nếu
đọc vμo hai biến kiểu kí tự a,b thì có gì thay đổi khơng.


7. Giả sử dùng thủ tục <i>Read</i> để đọc vμo nhiều mục dữ liệu từ bμn phím.
Điều gì sẽ xảy ra nếu ta gõ thừa, gõ thiếu so với số mục cần thiết.


thùc hμnh.


HÃy viết chơng trình thực hiện các công việc sau:
1. Giải phơng trình bậc nhất <i>ax + b = 0.</i>



2. Giải hệ phơng trình tuyến tính cấp 2: <i>ax+ by = e , cx + dy = f,</i> gi¶ thiet
r»ng hƯ duy nhÊt nghiƯm.


3. L·i xt tiÕt kiƯm hμng th¸ng lμ <i>k</i>= 1%. Tính số tiền có đợc sau 12
tháng nếu số gửi ban đầu l <i>x</i>.


</div>
<span class='text_page_counter'>(42)</span><div class='page_container' data-page=42>

5. Cho số đo độ dμi 3 cạnh của một tam giác lμ <i>a,b,c.</i> Tính diện tích tam
giác.


</div>
<span class='text_page_counter'>(43)</span><div class='page_container' data-page=43>

<b>Ch−¬ng4 </b>
<b>Các cấu trúc điều khiển </b>


Pascal lμ một ngơn ngữ lập trình có cấu trúc. Một ngơn ngữ lập trình
cấu trúc có các câu lệnh tạo cấu trúc điều khiển. Những câu lệnh cấu trúc nμy
cho phép kết hợp - hay "cấu trúc" - nhiều câu lệnh thμnh một đơn vị thống
nhất, liên quan chặt chẽ với nhau.


Những câu lệnh có cấu trúc lμm cho ch−ơng trình trong sáng dễ hiểu,
đễ theo dõi hơn.


Cã 3 lo¹i cấu trúc điều khiển: tuần tự, rẽ nhánh, vòng lặp.


<b>1. </b> <b>C©u lƯnh ghÐp </b>


Cã thĨ nhãm nhiỊu c©u lƯnh kh¸c nhau thμnh mét khèi, dïng 2 tõ
kho¸ <i>Begin, End</i>.


<b>Có ph¸p:</b> <i>Begin </i>



<i> c©u lƯnh 1 ; </i>


<i> ... </i>


<i> câu lệnh n ; </i>


<i>End; </i>


Tác dụng:


Cỏc lnh bên trong vẫn đ−ợc thực hiện tuần tự từ câu lệnh 1 đến câu
lệnh <i>n</i> nh− thông th−ờng, khơng có gì thay đổi. Tuy nhiên câu lệnh ghép có
tác dụng để nhóm nhiều lệnh lại thμnh <i>một câu lệnh</i> duy nhất để phù hợp với
cú pháp của các cấu trúc điều khiển sau nμy.


<b>2. </b> <b>C©u lƯnh IF. </b>


</div>
<span class='text_page_counter'>(44)</span><div class='page_container' data-page=44>

<b>2.1 </b> <b>Cú pháp và công dụng. </b>
Cú pháp:


- Trng hợp đầy đủ


<b>If </b> <i>biÓu thøc l« gic then</i>


<i>c©u lƯnh 1 </i>
<b>else </b>


<i>c©u lƯnh 2 ; </i>



Thực hiện: nếu <i>biểu thức lơ gic</i> đúng thì thi hμnh câu lệnh 1, nếu trái
lại, <i>biểu thức lô gic</i> lμ sai thì thi hμnh câu lệnh 2.


- Tr−êng hợp một lựa chọn:


Trong cấu trúc trên có thể thiếu thnh phần <i>Else</i>. Lúc ny câu lệnh sẽ
trë thμnh


<b>If </b> <i> biÓu thøc logic then</i>


c©u lƯnh ;


Thực hiện: nếu <i>biểu thức lơ gic</i> đúng thì thi hμnh câu lệnh 1, nếu trái
lại, <i>biểu thức lô gic</i> lμ sai thì khơng lμm gì cả.


D−ới đây lμ l−u đồ (<i>flow chart</i>) minh hoạ.


<i>true false true false </i>


<i>C©u lƯnh</i>


<i>C©u lƯnh 1 </i> <i>C©u lƯnh 2</i>


<i>Hình 4.1: L−u đồ minh hoạ ý nghĩa của câu lệnh If. </i>


VÝ dô:


IF <i>a>b</i> THEN <i>max:= a</i>



ELSE <i>max:=b;</i>


IF <i>a <> 0</i> THEN <i>x:= -b/a;</i>


Chó ý:


1- Tr−íc tõ kho¸ <i>Else</i> kh«ng cã dÊu chÊm phÈy “ ; ”.


</div>
<span class='text_page_counter'>(45)</span><div class='page_container' data-page=45>

<b>2.2 </b> <b>C¸c vÝ dơ minh hoạ. </b>


Ví dụ 1. Viết chơng trình nhận vo từ bn phím một số khác không,
nếu l số dơng thì in ra thông báo "số dơng", nếu l số âm thì in ra thông
báo "số ©m".


<i>True false </i>



x>0


Số dơng Số âm


<i>Hỡnh 4.2: Lu ca chng trỡnh xét dấu. </i>


Program XetDau ;
Var x: real;
Begin


Write(' cho mot so thuc khac khong' ); Readln(x) ;
IF x > 0 then write(' so duong' )



ELSE write (' so am' ) ;
End.


Ví dụ 2. Giải ph−ơng trình bậc hai <i>a x2 + b x + c</i>. Để đơn giản, ta chỉ
xét tr−ờng hợp hệ số <i>a </i> khác không.


<i>True false </i>


Delta < 0




<i>True False </i>


Delta = 0


<i>V« nghiƯm</i> <i>Cã nghiƯm</i>


</div>
<span class='text_page_counter'>(46)</span><div class='page_container' data-page=46>

<i>Hình 4.3: L−u đồ của ch−ơng trình giải tam thức bậc hai. </i>


Program PhuongTrinhBacHai;
Uses crt;


Var a,b,c,delta,x1,x2: real;
Begin


Clrscr;



Write(' Cho ba he so a b c:') ; Readln (a,b,c) ;
Delta:= b*b - 4*a*c;


If Delta < 0 then


Writeln(' Phuong trinh vo nghiem !')
Else if delta = 0 then


Writeln(' Phuong trinh co nghiem kep
x1=x2= -b/(2*a)


Else {truong hop delta > 0}
Begin


x1:= (-b + sqrt(delta)) /(2*a) ;
x2:= (-b - sqrt(delta)) /(2*a) ;
Writeln(' Phuong trinh co 2 nghiem


x1= ',x1: 10:4,' x2 = ', x2:10:4 );
End;


End.


<b>2.3 </b> <b>If lång nhau hay d∙y if </b>


Khi nhiÒu lùa chän cã thĨ dïng c©u lƯnh <i>If</i> lồng nhau. Ví dụ, khi giải
phơng trình bậc hai, ta cã 3 tr−êng hỵp <i>delta <0, delta=0, delta >0</i> vμ sư
dơng c©u lƯnh <i>If</i> lång nhau nh− trong vÝ dơ trªn.


Nh−ng cũng hay gặp cách dùng dÃy câu lệnh <i>If</i>:



IF delta < 0 THEN write('phơng trình vô nghiêm');
IF delta = 0 THEN write('phơng tr×nh cã nghiƯm kÐp');
IF delta > 0 THEN write('phơng trình có hai nghiệ');


Về mặt lô gic hai cách viết l tơng đơng, nhng với câu lƯnh <i>If</i> lång
nhau th× cã thĨ chØ kiĨm tra một điều kiện v câu lệnh kết thúc, trong khi nếu
dùng dÃy câu lệnh <i>If</i> thì luôn phải kiểm tra mọi điều kiện. Nếu các điều
kiện l phức tạp thì mất thì giờ vô ích.


Theo quy định cú pháp, khi viết nhiều câu lệnh <i>If</i> lồng nhau, thμnh
phần <i>Else</i> luôn gắn với <i>If</i> gần nhất.


Phong cách viết để tránh nhm ln:


<b>if</b> <i>điều kiện_1</i> <b>then</b>


câu lƯnh_1


</div>
<span class='text_page_counter'>(47)</span><div class='page_container' data-page=47>

c©u lƯnh_2
...


<b>else if</b> <i>điều kiện_n</i> <b>then</b>


câu lệnh_n


<b>else </b>


câu lệnh_E



Nếu nh các điều kiện không loại trừ nhau, một giá trị đầu vo có thể
thoả mÃn nhiều hơn một điều kiện thì thứ tự của các điều kiện l quan trọng.


Ví dụ: Xếp hạng học sinh căn cứ theo điểm tổng kết nh sau


<i>Điểm </i> <i>Xếp hạng </i>


9
≥ 7
≥ 5


<i>còn lại </i>


Giỏi
Khá


Trung bình
Kém


Các câu lệnh của ch−ơng trình thực hiện việc xếp hạng học sinh phải
đ−ợc viết đúng thứ tự nh− sau


If Diem >= 9 then Writeln(' Giái')


Else if Diem >= 7 then Writeln(' Kh¸')


Else if Diem >= 5 then Writeln(' Trung bình')
Else Writeln(' Khơng đạt ');


Nếu đảo ng−ợc lại thứ tự thì kết quả sai vì chỉ điều kiện đúng đầu tiên


đ−ợc thực hiện. Bất kì học sinh nμo có điểm ≥ 5 đều bị xếp hạng trung bình.


CÇn l−u ý tiết kiệm thời gian, điều kiện hay xảy ra nhất, có xác suất
thoả mÃn cao nhất, nên kiểm tra tr−íc.


<b>2.4 </b> <b>AND hay IF lång nhau </b>


Có những trờng hợp cần lựa chọn nhiều điều kiện phụ thuộc nhiều
biến khác nhau. Ví dụ, tiêu chuẩn tuyển nhân viên: nam, tuổi 18-25, cao
>=170, ... Thông thờng các điều kiện đợc kết hợp bằng các toán tử lô gic


<i>And, Or</i> ....


Cịng cã thĨ dïng c©u lƯnh <i>If</i> lång nhau nh− sau.
IF gioi = nam THEN


IF tuoi >= 18 THEN
IF tuoi <= 25 THEN


</div>
<span class='text_page_counter'>(48)</span><div class='page_container' data-page=48>

Cã tr−êng hợp chỉ nên dùng <i>If</i> lồng nhau. Ví dơ ®iỊu kiƯn <i>(x <> 0) </i>


<i>AND (y/x > 2.5) </i>có thể gây ra lỗi chia cho không nếu trình biên dịch thực


hin ỏnh giỏ biểu thức lôgic từ phải sang. Nên chuyển thμnh
IF x<> 0 THEN


IF y/x > 2.5 THEN ...


<b>3. </b> <b>C©u lƯnh CASE. </b>



Khác với lệnh <i>If</i>, chỉ rẽ hai nhánh tuỳ theo <i>biểu thức logic </i>đúng hay
sai, câu lệnh <i>Case</i> để rẽ nhiều nhánh, tuỳ theo các giá trị khác nhau của một


<i>biÓu thøc. </i>BiÓu thøc nμy gäi lμ c¸i chän - <i>selector</i>.


<b>3.1 </b> <b>Có ph¸p và tác dụng. </b>


3.1.1


3.1.2


<i>Cỳ phỏp. </i>
- Trng hp đầy đủ


<b>Case</b> <i>biÓu thøc</i> <b>of</b>


<i>TËp h»ng 1 : c©u lƯnh 1 ; </i>


...


<i>TËp h»ng n : c©u lƯnh n </i>
<b>else </b>


<i>c©u lƯnh n+1 ; </i>
<b>end ; </b>


- Cã thĨ kh«ng có thnh phần <i>Else</i>, lúc ny câu lênh <i>Case</i> trë thμnh


<b>Case</b> <i>biÓu thøc</i> <b>of</b>



<i>TËp h»ng 1 : c©u lƯnh 1 ; </i>
<i> ... </i>


<i>TËp h»ng n : c©u lƯnh n</i>


<b>end ; </b>


<i>Thực hiện </i>


- Tính giá trị của biÓu thøc lùa chän.


- So khớp lần l−ợt với các giá trị hằng trong các tập hằng <i>i</i>, từ trên
xuống d−ới. Nếu <i>tập hằng i</i> lμ tập <i>đầu tiên</i> chứa một giá trị hằng trùng với
giá trị của biểu thức lựa chọn thì máy sẽ thực hiện <i>câu</i> <i>lệnh i</i> t−ơng ứng, sau
đó thoát khỏi lệnh <i>Case</i>.


</div>
<span class='text_page_counter'>(49)</span><div class='page_container' data-page=49>

<b>3.2 </b> <b>VÝ dơ minh ho¹ </b>


Ví dụ 1: Viết ch−ơng trình nhận vμo từ bμn phím một số ngun
d−ơng thuộc khoảng 0..10, coi lμ điểm tổng kết mơn học của học sinh, sau
đó phân loại học sinh theo quy định sau: điểm từ 0 đến 4 lμ <i>kém</i>, điểm 5 lμ


<i>trung bình</i>, điểm 6 đến 8 lμ <i>khá,</i> điểm 9,10 lμ <i>giỏi</i>.


DƠ nhËn thÊy r»ng khung chÝnh cđa chơng trình l một câu lệnh lựa
chọn <i>Case</i>.


Uses crt;


Var diem: integer;



XepLoai: String;
Begin


Write(' cho biet diem cua hoc sinh: ') ; Readln(diem) ;
Case diem of


0..4: XepLoai:= ' Kem ';


5 : XepLoai:= ' Trung binh';
6..8: XepLoai:= ' Kha ';


9..10: XepLoai:= ' Gioi ';
else


begin


writeln(' Khong co muc diem ', diem) ;


halt(1);


end
End;


Writeln(' Hoc sinh duoc xep loai ', XepLoai);
End.


Ví dụ 2 - Một bảng chọn đơn giản: Viết ch−ơng trình in ra một thực
đơn bữa sáng vμ cho phép khách hμng gõ các số 1,2,3... để chọn, sau đó in ra
thông báo khẳng định lựa chọn của khách hμng.



Uses crt;


Var Chon: integer;
Begin


Writeln(' 1 - Ca phe va banh ngot ');
Writeln(' 2 - Sua va banh mi ');


Writeln(' 3 - Xoi ');
Writeln(' 4 - Pho ');
Writeln;


Write(' Ban chon mon gi: ') ; Readln(Chon) ;
Case Chon of


</div>
<span class='text_page_counter'>(50)</span><div class='page_container' data-page=50>

3: Write(' Ban muon dung Xoi ');
4: Write(' Ban muon dung Pho ');
End;


End.


<b>3.3 </b> <b>Chó ý </b>


1- C¸c <i>tËp h»ng</i> <i>i</i> cã thĨ gåm mét h»ng, gåm nhiỊu h»ng c¸ch nhau
dấu phẩy, hoặc l một đoạn hằng. Ví dụ


CASE <i>biÓu thøc sè häc kiÓu Integer</i> OF
0: <i>lÖnh 1</i> ;



1,3,5 : <i>lÖnh 2</i> ;


2,4,6..10: <i>lÖnh 3</i> ;
END;


2 - <i>biểu thức</i> lựa chọn trong câu lệnh <i>Case</i> phải nhận giá trị thuộc
kiểu vô h−ớng đếm đ−ợc (rời rạc) nh−: số nguyên, kí tự, logic, liệt kê.


3 - c©u lệnh <i>If - Then - Else</i> tơng đơng víi
CASE <i>biĨu thøc logic</i> OF


True: <i>lÖnh 1 </i>;
False: <i>lƯnh 2</i> ;
END;


4 - Cã thĨ dïng c©u lƯnh <i>If</i> lång nhau thay cho c©u lƯnh <i>Case</i>. Tuy
nhiên so sánh với câu lệnh <i>If</i> lồng nhau thì <i>Case</i> dƠ hiĨu, dƠ dïng h¬n


Mặt khác, <i>Case</i> khơng dùng đ−ợc khi biểu thức điều kiện để chọn lựa
có kiểu giá trị số thực hoặc xâu kí tự. Lúc nμy chỉ có thể dùng <i>If</i> lồng nhau.


<b>3.4 </b> <b>Các lỗi thờng gặp. </b>


Khi xây dựng cấu trúc lựa chọn với các câu lệnh <i>If</i>, <i>Case</i> thờng hay
mắc các lỗi sau:


a)- Có dÊu chÊm phÈy “;” tr−íc <i>Else</i>.


b)- Dïng biểu thức lựa chọn có kiểu số thực hoặc xâu kÝ tù trong c©u lƯnh



<i>Case.</i>


c) - Viết sai biểu thức lôgic, thiếu dấu ngoặc khi kết hợp nhiều điều kiện. Ví
dụ nếu viết <i>x > 0 And y > 0</i> thì do thứ tự −u tiên của phép so sánh
thấp hơn phép tốn lơgic <i>And</i>, máy đánh giá biểu thức nμy thμnh <i>x > </i>


<i>(0 And y) > 0, </i>hon ton không phải điều ta mong muèn.


</div>
<span class='text_page_counter'>(51)</span><div class='page_container' data-page=51>

cuèi cïng khi biÖt thức <i>delta </i>dơng ta cần thực hiện nhiều việc: tính
nghiƯm thø nhÊt, tÝnh nghiƯm thø hai, in kÕt qu¶. NÕu thiÕu lÖnh ghÐp


<i>Begin - End</i> nh dới đây thì câu lệnh <i>If - Then - Else</i> coi nh− kÕt


thóc sau khi tÝnh nghiƯm <i>x1</i>. C©u lƯnh tÝnh <i>x2</i> tiÕp theo sẽ không
thuộc vo cấu trúc rẽ nhánh điều khiển bởi <i>If</i>. Nó sẽ luôn đợc thực
hiện trong mọi trờng hợp. Chơng trình sẽ mắc lỗi khi <i>delta</i> d−¬ng.
....


Else {truong hop delta > 0}
{Begin}


x1:= (-b + sqrt(delta)) /(2*a) ;
x2:= (-b - sqrt(delta)) /(2*a) ;


Writeln(' Phuong trinh co 2 nghiem x1= ',
x1: 10:4,' x2 = ', x2:10:4 );


{End;}


<b>4. </b> <b>C©u lƯnh FOR. </b>



Cấu trúc lặp lμ cấu trúc nhằm cho phép thực hiện lặp đi lặp lại một số
công việc nhiều lần. Câu lệnh <i>For</i> lμ để xây dựng một cấu trúc lặp với số lần
lặp đã biết rõ từ tr−ớc.


<b>4.1 </b> <b>Có ph¸p và tác dụng </b>


4.1.1


4.1.2


<i>Cú pháp. </i>
- D¹ng tiÕn


<b>For</b> <i>biÕn:= biÓu thøc</i> 1 <b>to </b> <i>biÓu thøc 2</i> <b>do </b><i>c©u lƯnh</i> ;


- D¹ng lïi


<b>For</b> <i> biÕn:= biÓu thøc 1 downto </i> <i>biÓu thøc</i> 2 <b>do </b> c<i>âu lệnh</i> ;


Thnh phần <i>biến</i> trong câu lệnh <i>For</i> gọi l biến điều khiển vòng lặp.
Kiểu của biến điều khiển vòng lặp, của các <i>biểu thức 1, biểu thức 2</i> phải l


kiu vơ h−ớng đếm đ−ợc (số ngun, kí tự, liệt kê). <b> </b> <i> </i> <i> </i> <b> </b> <i> </i> <b> </b>


<i>Thùc hiện. </i>


- Trờng hợp <i>For</i> dạng tiến , c¸c b−íc sÏ lμ
1- <i>biÕn</i> nhËn gi¸ trị của <i>biểu thức 1</i>.



2- kiểm tra điều kiƯn <i>biÕn</i> ≤ <i>biĨu thøc 2</i>


3- NÕu điều kiện l sai thì vòng lặp <i>For</i> kết thóc, m¸y chun xng
lƯnh tiÕp theo.


</div>
<span class='text_page_counter'>(52)</span><div class='page_container' data-page=52>

- thùc hiƯn <i>c©u lƯnh</i>


- tăng <i>biến</i> lên một bớc, <i>biến</i> := Succ(<i>biến</i>) v quay lại bớc 2.
- Trờng hợp <i>For</i> dạng lùi , các bớc sẽ l


1- <i>biến </i>nhận giá trị của <i>biểu thức 1</i>.


2- kiĨm tra ®iỊu kiƯn <i>biÕn</i> ≥ <i>biểu thức 2</i>


3- Nếu điều kiện l sai thì vòng lặp <i>For</i> kết thúc, máy chuyển xuống
lệnh tiÕp theo.


Nếu điều kiện còn đúng thì:
- thực hiện <i>câu lệnh</i>


- gi¶m <i>biÕn</i> ®i mét b−íc, <i>biÕn</i>:= Pred(<i>biÕn</i>) vμ quay l¹i b−íc 2.


4.1.3 <i>Chó ý. </i>


1- Khơng đ−ợc lμm thay đổi giá trị của <i>biến</i> điều khiển vịng lặp bởi
một câu lệnh nμo đó ở bên trong vịng lặp, vì nh− thế số lần lặp sẽ thay đổi
theo, thậm chí dẫn đến lặp vơ hạn không kết thúc đ−ợc.


2- Giá trị của <i>biến</i> điều khiển khi ra khỏi vịng lặp <i>For</i> lμ khơng xác
định.



3- Giá trị của các <i>biểu thức 1, biểu thức 2</i> trong câu lệnh <i>For</i> đ−ợc tính
tr−ớc khi vμo vịng lặp. Vì thế, có thể thay đổi giá trị của các biến tham gia
vμo các biểu thức 1, biểu thức 2 ở bên trong vòng lặp mμ khơng ảnh h−ởng gì.
<b>4.2 </b> <b>Ví dụ minh hoạ </b>


Ví dụ 1: Viết ch−ơng trình in ra mμn hình bảng nhân với 5 của các số
từ 1 đến 10, trình bμy nh− sau


1 x 5 = 5
2 x 5 = 10
...


Rõ rμng vịng lặp <i>For</i> lμ cơng cụ tiện lợi nhất để thực hiện công việc trên.
Uses crt;


Var i: integer;
BEGIN


Clrscr;


FOR i:= 1 TO 10 DO
Begin


Write(i); write(' x 5 = '); writeln(i*5);
end


END.


</div>
<span class='text_page_counter'>(53)</span><div class='page_container' data-page=53>

Tr−ờng hợp nμy ta cũng dùng vịng lặp <i>For</i> nh−ng có thể sử dụng ngay


một biến kiểu kí tự để lμm biến đếm vòng lặp.


Uses crt;


Var ch: char;
BEGIN


FOR ch:= 'a' TO 'z' DO


Writeln(ch, ' co ma ASCII la = ', ord(ch));
END.


<b>5. </b> <b>C©u lƯnh Repeat. </b>


Có nhiều tr−ờng hợp cần thực hiện nhiều lần một cơng việc nμo đó
nh−ng số lần lặp lại không đ−ợc biết tr−ớc. Ta chỉ biết một điều kiện kiểm tra,
cần lặp đi lặp lại công việc cho đến khi điều kiện nμy đ−ợc thoả mãn. Ví dụ,
giải gần đúng một ph−ơng trình, một hệ ph−ơng trình bằng ph−ơng pháp lặp
với yêu cầu về độ chính xác cho tr−ớc hay việc cho chạy thử một ch−ơng
trình nhiều lần để kiểm tra, chỉ dừng lại khi ta chọn K cho câu hỏi C/K (có
tiếp tục nữa hay khơng?).


Câu lệnh <i>Repeat - Until</i> dμnh để thực hiện những cấu trúc lặp nh− thế.
<b>5.1 </b> <b>Cú pháp và tác dng </b>


5.1.1


5.1.2


<i>Cú pháp </i>



<b>Repeat </b>


<i>Câu lệnh 1</i> ; ….


....


<i>c©u lƯnh n ; </i>
<b> Until</b> <i>biĨu thøc logic ;</i>


<i>False</i>


<i>True</i>
<i>C©u lƯnh 1 </i>


<i>C©u lƯnh n </i>


<i>Hình 4.4: L−u đồ minh hoạ hoạt đọng của câu lệnh Repeat-Until. </i>


<i>Thùc hiƯn. </i>


</div>
<span class='text_page_counter'>(54)</span><div class='page_container' data-page=54>

2 - Sau đó tính <i>biểu thức logic</i>, nếu sai thì quay lại b−ớc 1, nếu đúng
thì kết thúc câu lệnh <i>Repeat - Until</i>.


5.1.3 <i>Chó ý. </i>


1- Khơng cần dùng câu lệnh ghép <i>Begin-End</i> để nhóm các <i>câu lệnh</i>
<i>1</i>, .., <i>câu lệnhn</i> nằm trong vòng lặp <i>Repeat - Until</i>. Chúng đã đ−ợc giới hạn
nằm giữa 2 từ khố <i>Repeat, Until</i>.



2- Trong vịng lặp phải có một lệnh nμo đó để thay đổi giá trị của <i>biu </i>


<i>thức logic</i>. Nếu không sẽ bị lặp vô hạn, mÃi không dừng.


<b>5.2 </b> <b>Ví dụ minh hoạ </b>


Ví dụ 1: Viết chơng trình nhận từ bn phím một số nguyên, in ra
thông báo số vừa cho có bao nhiêu chữ số.


Phõn tớch: Nu m s ch số từ phải sang trái tức lμ từ hμng đơn vị trở
lên hμng chục, hμng trăm,v.v. thì điều nμy t−ơng đ−ơng với việc lặp lại nhiều
lần phép chia số đã cho cho 10 giữ lại phần nguyên, cho đến bao giờ kết quả
bằng khơng thì dừng. Số lần thực hiện phép chia chính lμ số chữ số.


Uses crt;


Var i: integer;
Dem: byte;
BEGIN


Clrscr;


Write(' Cho mot so nguyen: '); readln(i);


Dem:= 0;


REPEAT


i:= i div 10;
dem:= dem + 1:


UNTIL i = 0;


Write(' so vua nhap co ',dem,' chu so ');
Readln;


END.


Các trờng hợp th−êng dïng c©u lƯnh <i>Repeat - Until</i>.


- Để kiểm tra việc nhập dữ liệu từ bμn phím sao cho đúng kiểu, đúng
phạm vi. Nếu dữ liệu vμo không đúng phải lμm lại cho đến khi đúng mới thôi.


- Để chạy kiểm tra (test) một ch−ơng trình nhiều lần với các dữ liệu
đầu vμo khác nhau, cho đến khi ng−ời dùng thoả mãn vμ kết thúc.


- Để xây dựng chơng trình điều kiển bằng bảng chän.


</div>
<span class='text_page_counter'>(55)</span><div class='page_container' data-page=55>

Repeat


Write(' Cho Gio Phut Giay: ');
Readln( Gio, Phut, Giay);


Until (0 <= Gio) AND (Gio <= 23) AND (0<= Phut) AND
(Phut <= 59) AND (0 <= Giay) AND (Giay <= 59);


Ví dụ 3: Để thực hiện giải phơng trình bậc hai nhiều lần với các hệ
số a,b,c khác nhau ta cần thêm vo chơng trình một biến <i>TiepTơc</i> kiĨu


<i>Char</i> vμ mét vßng lỈp <i>Repeat - Until</i> nh− sau.
Begin



Clrscr;
REPEAT


Write(' Cho ba he so a b c:') ;
Readln (a,b,c) ;


<i> các lệnh thực hiện giải phơng trình bậc hai </i>


Write('Go phim bat ki de tiep tuc,
go n de ket thuc !');
Readln(TiepTuc);


UNTIL TiepTuc = 'n';
End.


VÝ dơ 4: Lμm b¶ng chän.


Một ch−ơng trình điều khiển bằng bảng chọn cho phép ng−ời sử dụng
chọn một trong số nhiều cơng việc có thể để thi hμnh. Sau khi kết thúc một
công việc lại quay về bảng chọn chính để ng−ời dùng có thể tiến hμnh chọn
lμm việc khác. ch−ơng trình chỉ kết thúc khi ng−ời dùng chọn mục "Kết
thúc".


Nếu đã đánh số các mục chọn lμ 1,2,3... thì giá trị 0 hoặc -1 lμ khơng
hợp lệ. Có thể lấy nó lμm giá trị canh chừng để kết thúc hoạt động của bảng
chọn. Khuôn mẫu của đoạn ch−ơng trình điều khiển bảng chọn nh− sau.
VAR Chon: integer ;


....


REPEAT


Writeln(' 1- <i>C«ng viƯc 1</i> ');
Writeln(' 2- <i>C«ng viƯc 2 </i>');
Writeln(' 3- <i>Công việc 3</i> ');
....


Write(' Bạn chän môc nμo: '); Readln(Chon);
CASE Chon OF


1: begin các lệnh thực hiện công việc 1 end;
2: begin c¸c lƯnh thùc hiƯn c«ng viƯc 2 end;
3: begin các lệnh thực hiện công việc 3 end;


</div>
<span class='text_page_counter'>(56)</span><div class='page_container' data-page=56>

END;
UNTIL Chon = 0;


<b>6. </b> <b>C©u lƯnh While. </b>


Câu lệnh <i>While</i> cũng để xây dựng cấu trúc lặp với số lần lặp ch−a biết
tr−ớc giống nh− câu lệnh <i>Repeat-Until</i>. Điểm khác nhau lμ ở chỗ, với câu
lệnh <i>Repeat-Until</i> thì cơng việc đ−ợc lặp lại khi điều kiện ch−a thoả mãn, vẫn
còn sai vμ chỉ kết thúc khi điều kiện trở thμnh đúng. Trái lại, với câu lệnh


<i>While</i> công việc sẽ đ−ợc lặp lại trong khi điều kiện vẫn cũn ỳng v ch kt


thúc khi điều kiện không đợc thoả mÃn nữa, trở thnh sai.
<b>6.1 </b> <b>Cú pháp và công dụng. </b>


<i>True False</i>



6.1.1


6.1.2


6.1.3


<i>Có ph¸p </i>


<i> </i>


<b>While</b> <i>biÓu thøc logic</i> <b>do </b> <b> </b>


<i>c©u lƯnh</i> ;


<i>Hình 4.5: L−u đồ minh hoạ hoạt động của câu lệnh While </i>


<i>Thùc hiƯn </i>


Xem l−u đồ hình trên.


1 - TÝnh gi¸ trÞ cđa <i>biĨu thøc logic</i>,


2 - Nếu đúng, thực hiện <i>câu lệnh</i> vμ quay lại b−ớc 1
3 - Nếu sai, kết thúc câu lệnh <i>While</i>.


<i>Chó ý. </i>


1- Trong phần <i>câu lệnh </i> tức lμ phần thân của vịng lặp, phải có lệnh


lμm biến đổi giá trị của <i>biểu thức lôgic</i> điều khiển vịng lặp. Nếu khơng vịng
lặp sẽ khơng thể kết thúc.


2- Nếu vòng lặp gồm nhiều hơn một câu lệnh thì phải dùng <i>Begin - </i>
<i>End</i> để ghép thμnh một <i>câu lệnh</i> duy nhất cho đúng cú pháp của cấu trúc
lặp với <i>While</i>. Nếu ta quên điều nμy thì chỉ một câu lệnh đơn đầu tiên sau từ
khố <i>Do</i> lμ thuộc vịng lặp. Các lệnh tiếp theo sẽ nằm ngoμi, không thuộc
cấu trúc lặp.


</div>
<span class='text_page_counter'>(57)</span><div class='page_container' data-page=57>

3- Điểm khác nhau căn bản hơn giữa <i>While</i> vμ <i>Repeat - Until</i> cần nắm
vững để vận dụng đúng tình huống lμ nh− sau. Trong cấu trúc <i>Repeat - Until,</i>


phần <i>câu lệnh</i> đựơc thực hiện tr−ớc rồi mới kiểm tra điều kiện sau. Trái lại
trong cấu trúc <i>While</i>, điều kiện đ−ợc kiểm tra tr−ớc, nếu đúng mới thực hiện
lệnh. Do đó nếu dùng <i>Repeat - Until</i> thì phần <i>câu lệnh</i> đ−ợc thực hiện ít nhất
lμ một lần, cịn với <i>While</i> có thể <i>câu lệnh </i>không đ−ợc thực hiện lần nμo.


<b>6.2 </b> <b>VÝ dô minh ho¹ </b>


VÝ dơ 1: Tỉng <i>n</i> sè hạng đầu tiên của chuỗi điều ho l <i>S = 1+1/2 </i>


<i>+1/3 + ... + 1/n</i>. Hỏi <i>n</i> nhỏ nhất phải lμ bao nhiêu để <i>S</i> v−ợt quá một


ng-−ìng lμ sè <i>A</i> cho tr−íc.
Uses crt;


Var i, A: integer;
S: real;
Begin



Clrscr;


Write(' cho so A:' ) ; Readln(A) ;


I:=1; S:=1;


<b>While S < A do </b>
Begin


I:=i+1;


S:=S+ 1/i ;


End;


Write(' Can it nhat ' , i , 'so hang' );
End.


VÝ dụ 2: Tính giá trị của hm <i>sin(x)</i> theo công thøc xÊp xØ


<i>sinx = x- x3<sub>/3! + x</sub>5<sub>/5! + x</sub>7<sub>/ 7! ... </sub></i>


cho đến khi đạt độ chính xác epsilon cho tr−ớc. So sánh với kết quả nhận
đ−ợc khi dùng hμm chuẩn <i>sin(x)</i> của Turbo Pascal.


uses crt;


var eps,x,y,s: real;
i, sign: integer;
BEGIN clrscr;



write(' Cho do chinh xac eps= '); readln(eps);
write(' Cho x= '); readln(x);


y:=x;s:=x;i:=3;sign:=-1;
While (s >= eps) do


Begin


s:= s*x*x / ((i-1)*i);


</div>
<span class='text_page_counter'>(58)</span><div class='page_container' data-page=58>

sign:= -sign;


i:=i+2;


end;


writeln(' Sin(x) = ',y:1:5);


write(' Sai khac voi ham chuan sin(x) cua TurboPascal
la = ', y-sin(x):0:5);


readln;
END.


<b>7. </b> <b>X©y dùng cÊu tróc lỈp. </b>


Phần nμy sẽ trình bμy một số mẫu hình xây dựng các cấu trúc lặp để
xử lí các tình huống hay gặp nhất.



<b>7.1 </b> <b>Điều khiển vòng lặp bằng giá trị canh chừng. </b>


Ví dụ: Viết ch−ơng trình để nhập vμo vμ cộng tích luỹ để tính tổng số
tiền bán hμng từng ngμy của một cửa hμng. Số lần bán hμng nói chung thay
đổi từng ngμy, khơng biết tr−ớc. Vì số tiền bán hμng lμ một số d−ơng nên giá
trị 0 không phải lμ một giá trị hợp lệ. Ta có thể lấy giá trị nμy lμm dấu hiệu
chấm hết dãy số liệu cần nhập. Số 0 lμ <i>giá trị canh chừng</i> để kết thúc công
vic.


1- <i>dữ liệu vo := giá trị đầu tiên ; </i>


2- <b>While</b> <i>d÷ liƯu vμo <> giá trị canh chừng</i> <b>do</b>


<b>begin </b>


....


<i>dữ liệu vo:= giá trị tiếp theo ; </i>


<b>end; </b>


Cơ thĨ vòng lặp đợc xây dựng nh sau


Write(' cho so tien, 0 – ket thuc ');
Readln(SoTien);


WHILE SoTien <> 0 DO
Begin


TongSo:= TongSo + SoTien;



</div>
<span class='text_page_counter'>(59)</span><div class='page_container' data-page=59>

<b>7.2 </b> <b>Điều khiển vòng lặp b»ng cê b¸o </b>


Một bμi tốn th−ờng hay gặp trong xử lí thơng tin lμ tìm kiếm. Thực
chất của việc tìm kiếm lμ lặp lại nhiều lần phép kiểm tra một điều kiện nμo
đó cho đến khi thoả mãn điều kiện tức lμ tìm thấy.


Khn mẫu chung để thực hiện việc tìm kiếm lμ xây dựng một cấu
trúc lặp điều khiển bằng cờ báo nh− sau. Một biến kiểu <i>boolean</i> đ−ợc dùng
để đánh dấu sự kiện tìm thấy. Nó đ−ợc gọi lμ <i>cờ báo</i>. Tr−ớc khi vμo cấu trúc
lặp, cờ báo đ−ợc đặt lμ <i>False</i>. Khi tìm thấy, cờ báo đ−ợc thiết lập lμ <i> True</i> vμ
vòng lặp kết thúc.


1- <i>cê b¸o</i>:= false;


2- <b>While</b> <b>not</b> <i>cê b¸o</i> <b>do</b>


<b>begin </b>


...


<b>if </b><i>t×m thÊy </i> <b>then</b> <i>cê b¸o</i>:= true;


<b>end; </b>


Ví dụ: Tìm số chính ph−ơng nhỏ nhất lớn hơn <i>x</i>, số <i>x</i> nhập từ bμn
phím. Ta duyệt từng số, bắt đầu từ <i>x</i>, để tìm số chính ph−ơng. Khi tìm thấy số
đầu tiên thì kt thỳc.


Cấu trúc lặp đợc xây dựng nh sau.


TimThay:= False;


So:= x;


WHILE not TimThay DO


If Trunc(sqrt(So)) = sqrt(So) then


TimThay:= True


Else So:=So+1;


Writeln(' So chinh phuong = ', So);


<b>8. </b> <b>C¸c lệnh kết thúc sớm vòng lặp hoặc chơng trình. </b>


<b>8.1 </b> <b>Lệnh nhảy không điều kiện - goto </b>


<b>Goto</b> <i>nh·n</i> ;


<i>Goto</i> lμ lệnh nhảy không điều kiện, cho phép nhảy từ bất kì nơi nμo
bên trong ch−ơng trình hay ch−ơng trình con đến vị trí đã đánh dấu bằng


</div>
<span class='text_page_counter'>(60)</span><div class='page_container' data-page=60>

1- Khai b¸o nh·n: Phải khai báo nhÃn tại đầu phần khai báo, trớc khi
khai b¸o c¸c h»ng.


Có ph¸p khai b¸o nh·n: <i>tõ kho¸ Label, danh s¸ch nh·n, dÊu chÊm phẩy</i>.
Danh sách nhÃn l dÃy các tên nhÃn, cách nhau dÊu phÈy.



2- Đánh đấu đích: Trong thân ch−ơng trình vị trí đích sẽ nhảy đến
bằng lệnh <i>Goto</i> cần đánh dấu tr−ớc.


Cú pháp đánh dấu đích bằng tên nhãn: tên nhãn, dấu hai chấm, câu lệnh đích.
3- Viết câu lệnh <i>Goto nhãn; </i>


L−u ý, với lệnh nhảy không điều kiện <i>Goto</i>


- Có thể nhảy từ trong vòng lặp ra ngoi.


- Không cho phép nhảy từ ngoi vo trong vòng lặp, từ ngoi vo trong
chơng trình con.


Nói chung nên tránh dùng câu lệnh nhảy không điều kiện <i>Goto</i> khi có
thể đợc vì nó phá vỡ cấu trúc của các lệnh điều khiĨn, khã theo dâi.


<b>8.2 </b> <b>LƯnh chÊm døt sím vòng lặp. </b>


<b>Break; </b>


Lệnh <i>Break</i> có tác dụng chấm dứt giữa chừng một vòng lặp dù cha
kết thúc.


Ví dụ: Kiểm tra một số nguyên <i>q</i> nhập từ bμn phím có phải lμ số
ngun tố hay không. Ta duyệt phép chia <i>q MOD i</i> với <i>i</i> từ 2 đến căn
bậc hai của <i>q</i>. Nếu chỉ một phép chia chẵn thì <i>q</i> khơng phải lμ số nguyên tố
vμ có thể kết thúc ngay vòng lặp.


var i,q: integer;



NguyenTo: boolean;
begin


write('cho so q: '); readln(q);
NguyenTo:= True;


for i:=2 to trunc(sqrt(q))+1 do
if q mod i = 0 then


begin NguyenTo:= False;


break;


end;


if NguyenTo then Write(q,' la so nguyen to ')
else write(q,' khong nguyen to');


</div>
<span class='text_page_counter'>(61)</span><div class='page_container' data-page=61>

Để giải bμi toán tìm số nguyên tố lớn nhất nhỏ hơn một số nguyên <i>n</i>
nhập vμo từ bμn phím, có thể lμm t−ơng tự. Ta lại dùng vòng lặp <i>For</i> để
duyệt từ <i>n</i> trở xuống vμ dừng khi tìm thấy số nguyên tố đầu tiên.


For q:= n downto 1 do


If <i>q lμ sè nguyªn tè</i> then break;
Chó ý:


- LƯnh <i>Break</i> cho phÐp tho¸t khái mäi kiểu vòng lặp <i>For, While</i> hay <i></i>
<i>Repeat-Unitl.</i>



- Nếu có nhiều vòng lặp lồng nhau thì câu lệnh <i>Break</i> cho phép tho¸t ra khái


<i>một</i> vịng lặp bên trong nhất chứa nó. Các vịng lặp bên ngoμi vẫn hoạt động
bỡnh thng.


<b>8.3 </b> <b>Lệnh thoát khỏi chơng trình con. </b>


<b>Exit; </b>


Lệnh kết thúc v thoát khỏi chơng trình con.


- Nếu ở bên trong ch−ơng trình con thì lệnh nμy lμm chấm dứt ch−ơng
trình con (mặc dù ch−a đến câu lệnh cuối) vμ trở về ch−ơng trình bên ngoμi
đã gọi ch−ơng trình con.


- NÕu ở chơng trình chính thì lệnh ny chấm dứt chơng trình chính
v dừng.


<b>8.4 </b> <b>Lệnh dừng chơng trình bất thờng. </b>


<b>Halt; </b>


L lệnh dừng chơng trình chính. Lệnh ny đợc sử dụng khi xảy ra
những lỗi, sai sót nghiêm trọng, việc tiếp tục thực hiện chơng trình l nguy
hiểm hoặc không có ý nghĩa nữa.


Câu hỏi v bi tập


1. Các lỗi hay mắc phải khi viết câu lệnh <i>If</i>, câu lệnh <i>Case</i> l gì.



</div>
<span class='text_page_counter'>(62)</span><div class='page_container' data-page=62>

3. Khi no thì dùng vòng lỈp <i>For</i> ?


4. Số lần lặp ít nhất có thể của các vòng lặp <i>For, While, Repeat</i> lμ bao nhiêu.
5. Vòng lặp nμo dùng để thực hiện một bảng chọn.


6. Vòng lặp nμo th−ờng dùng để kiểm tra việc nhập dữ liệu hợp lệ.


Thùc hμnh.


1. Viết các ch−ơng trình giải ph−ơng trình bậc nhất, ph−ơng trình bậc hai, hệ
ph−ơng trình tun tính 2 ẩn. Xét đủ các tr−ờng hợp.


2. ViÕt ch−¬ng trình in ra thông báo gõ phím loại no: dấu phÐp to¸n + - * /
< > .. , dÊu chÝnh t¶ . ,: ; ! ? .. chữ số <i>0,1.. 9</i> chữ cái <i>A..Z, a..z</i> hay c¸c kÝ
hiƯu kh¸c.


3. Lμm bμi 2 nh−ng dïng c©u lƯnh <i>If</i> lång nhau.


4. Nhập một số nguyên N gồm 3 chữ số, in ra mμn hình cách đọc số nμy
bằng lời.


5. Lập ch−ơng trình để tính số ngaỳ trôi qua kể từ đầu năm khi gõ vμo một
ngμy bất kì trong năm.


6. BiÕt ngμy hôm nay l ngy thứ mấy. Viết chơng trình in ra thứ trong tuần
của một ngy bất kì <i> D, M, Y. (1<=D<=31, 1<=M<=12, Y= 2001).</i>


7. ViÕt ch−¬ng trình in ra thứ trong tuần của ngy bất kì <i>d,m,y.</i> ThuËt to¸n:
thø = <i>{d+2m+3(m+1) div 5 + y + y div 4 + 1} div 7,</i> víi quy ớc tháng
1=tháng 13 năm trớc, tháng 2= tháng 14 năm trớc, các tháng khác giữ


nguyên, 0=thứ 7, 1= chđ nhËt, 2=thø hai,v.v..


8. Viết ch−ơng tình tính c−ớc điện thoại, đầu vμo lμ thời gian bắt đầu cuộc
gọi vμ độ dμi (theo phút). Có giảm giá 1/3 nếu ngoμi giờ lμm việc, giảm
giá một nửa nếu từ 21.00 đến 6.00. Giá chuẩn lμ <i>x</i> đ/1 phút.


9. LËp chơng trình in ra bảng nhân (bảng cửu chơng).


10. Tìm tất cả các nghiệm nguyên d−ơng của ph−ơng trình vụ nh <i>2x+4y = </i>


<i>100</i>.


11. Giải bi toán cổ:"vừa g vừa chó.." v "trăm trâu trăm cỏ.." bằng cách thử
hết các trờng hợp có thể.


12. Tìm tất cả các số nguyên dơng <i>a,b</i> trong khoảng [1..100] sao cho <i>a2<sub> + </sub></i>


<i>b2</i><sub> lμ sè chÝnh ph−¬ng. </sub>


13. TÝnh tỉng <i>sinx/cosx + (sinx + sin2x/cox+ cos2x) + .. + (sinx +..+ </i>


<i>sinnx/cox+..+ cosnx</i>), số n nhập từ bn phím.


14.Tính giá trị đa thức (theo phơng pháp Horne)


<i>P(x) = x + 2x2 + 3x3 + .. + 10x10</i>


15. Kiểm tra xem số đã cho có phải lμ số ngun tố khơng.
16. Tìm vμ in ra các số nguyên tố <1000.



17. In ra mn hình các hình tam giác vuông, tam giác cân bằng các dấu *,
chiều cao 10 dòng mn hình.


</div>
<span class='text_page_counter'>(63)</span><div class='page_container' data-page=63>

19. In ra mà ASCII của kí tự gõ từ phím. Chơng trình dõng khi gâ phÝm sè
0.


20. Kiểm tra việc nhập từ bμn phím một ngμy tháng hợp lệ. Yêu cầu gõ lại
cho đến khi đúng.


21. T×m −íc chung lớn nhất của 2 số nguyên dơng <i>a,b</i> nhập tõ bμn phÝm.
T×m −íc chung lín nhÊt cđa 4 sè <i>a,b,c,d.</i>


22. Tạo một bảng chọn đơn giản gồm các mục sau: 1- giải ph−ơng trình bậc
nhất; 2-giải ph−ơng trình bậc hai; 3-giải hệ ph−ơng trình tuyến tính 2 ẩn;
4- Kết thúc. Gõ các số 1,2,3,4 để chọn cơng việc t−ơng ứng.


23. Tìm số <i>n</i> nhỏ nhất để <i>Sn= 1+1/2 +1/3 + .. + 1/n > a.</i> Số <i>a</i> nhập từ bμn
phím.


24. Tính gần đúng số π theo cơng thức


π/4 = <i>1-1/3 + 1/5 - 1/7 + .. + (-1)n.1/(2n+1)</i>


a-) Khi cho tr−íc sè <i>n</i>


b-) Khi cho tr−ớc độ chính xác <i>Epsilon</i> = 10-5. (chuỗi đan dấu nên sai số
< số hạng cuối cùng).


25. Tính gần đúng <i>sin x = x - x3/3 + x5/5 - x7/7 + ..</i> với sai số <i>Epsilon</i> cho
tr−ớc. So sánh kết quả vơi hμm chuẩn <i>sin x</i> của Turbo Pascal.



26. Cho các phơng trình
<i>a) y = ex + sinx - 2 = 0, </i>


<i> b) y= x.2x - 1 = 0. </i>


</div>
<span class='text_page_counter'>(64)</span><div class='page_container' data-page=64>

<b>Ch−ơng5 </b>
<b>Định nghĩa Các kiểu dữ liệu đơn giản </b>


<b>1. </b> <b>Khai báo kiểu dữ liệu mới. </b>


Cỏc kiu <i>chun</i> có sẵn nh− <i>integer, real, char, boolean...</i> lμ các kiểu
thơng dụng nhất. Vì thế chúng đã đ−ợc định nghĩa sẵn vμ ta có thể sử dụng
ngay để khai báo các biến nh− đã thấy.


Các kiểu chuẩn có sẵn không thể đáp ứng đầy đủ nhu cầu xử lí các bμi
tốn thực tế hết sức phong phú vμ đa dạng. Các ngơn ngữ lập trình nói chung
vμ Turbo Pascal nói riêng, đều cho phép ng−ời sử dụng có thể định nghĩa các
kiểu dữ liệu mới phù hợp với bμi tốn của mình.


<b>1.1 </b> <b>Có ph¸p chung. </b>


Khung cú pháp chung để khai báo kiểu dữ liệu mới lμ:
<b>Type </b> <i>tên kiểu = mơ tả kiểu dữ liệu mới ;</i>


DiƠn giải: <i>Từ khoá TYPE, tên kiểu dữ liệu mới, dấu bằng, mô tả kiểu </i>


<i>dữ liệu mới, dÊu chÊm phÈy</i>.


Chỉ sau khi khai báo kiểu dữ liệu mới thì mới đ−ợc sử dụng nó trong


ch−ơng trình. Nghĩa lμ có thể khai báo các biến có kiểu đó hoặc xây dựng
những kiểu khác dựa trên nó.


<b>1.2 </b> <b>VÝ dơ </b>


VÝ dơ 1: Ta cã thể "Việt hoá" một số tên kiểu tiếng Anh bằng c¸ch sau.
TYPE


<i>SoNguyen</i> = integer;


<i>SoThuc</i> = real;


<i>KiTu</i> = char;


Sau đó có thể sử dụng những tên kiểu Việt hoá nμy trong các khai báo biến:
VAR


</div>
<span class='text_page_counter'>(65)</span><div class='page_container' data-page=65>

a,b,c: <i>SoThuc</i>;


GoPhim, Chon: <i>KiTu</i>;


Ví dụ 2: Xét bμi tốn giải một hệ ph−ơng trình đại số tuyến tính gồm
10 ph−ơng trình, 10 ẩn. Rõ rμng lμ ta sẽ phải lμm việc với các véc tơ vμ ma
trận. Cần phải định nghĩa các "kiểu véc tơ gồm 10 thμnh phần" vμ "kiểu ma
trận 10 x 10" vì chúng khơng phải lμ một kiểu chuẩn, đã có sẵn.


TYPE


<i>Vecto10</i> = array [1..10] of real ;



<i>Matran10</i> = array [1..10,1..10] of real ;


Bên trái dấu bằng lμ các tên kiểu mới. Bên phải dấu bằng lμ mơ tả xây
dựng kiểu đó. Kiểu <i>Vecto10</i> sẽ lμ một dãy 10 số thực liền nhau, kiểu


<i>Matran10</i> sÏ lμ bé 100 sè thùc ®−ỵc xÕp thμnh 10 hμng, 10 cét. Y nghÜa cđa


từ khoá <i>Array</i> v cách sử dụng nó sẽ đợc trình by chi tiết trong chơng nói
về mảng.


Sau khi đã định nghĩa các kiểu <i>Vecto10, Matran10</i> ta khai báo các
biến thuộc kiểu đó nh− quy định chung:


VAR


X,Y: <i>Vecto10;</i>


A,B,C: <i>Matran10;</i>


Ta sÏ cßn gặp nhiều ví dụ về khai báo kiểu dữ liệu mới trong các phần
tiếp theo.


<b>2. </b> <b>Kiểu liệt kê. </b>


<b>2.1 </b> <b>Định nghĩa và cú pháp </b>


Kiu lit kê <i>- Enumerated Scalar Type - </i>lμ kiểu dữ liệu thô sơ nhất,
xác định bằng cách <i>liệt kê</i> tất cả các "giá trị" có thể có của dữ liệu, mỗi giá
trị đ−ợc đại diện bằng một tên gọi do ng−ời lập trình đặt ra.



2.1.1 <i>Có ph¸p </i>


Phần mô tả kiểu dữ liệu mới trong khai báo kiểu liệt kê có cú pháp nh−
sau: <i>dấu mở ngoặc, danh sách các tên giá trị, dấu đóng ngoặc</i>.


</div>
<span class='text_page_counter'>(66)</span><div class='page_container' data-page=66>

ở đây, mỗi <i>tên giá trị</i> lμ một <i>tên</i> theo đúng quy định đặt tên của Pascal. Danh
sách gồm các <i>tên giá trị</i>, cách nhau dấu phẩy. L−u ý cặp dấu ngoặc đơn bao
quanh danh sách các giá trị.


Sau khi đã khai báo kiểu liệt kê, ta khai báo biến theo đúng quy tắc
thơng th−ờng.


<b>Var</b> tªn biÕn: tªn kiĨu ;
2.1.2


2.2.1


<i>VÝ dơ. </i>


TYPE <i>NgayTrongTuan</i> = (CN, Thu2, Thu3, Thu4, Thu5, Thu6,Thu7);


<i>MauCoBan</i> = (Do, Xanh, Vang);


<i>XeMoTo</i> = (Honda, Yamaha, Suzuki, Vespa);


VAR NgayHocToan, NgayHocTin: <i>NgayTrongTuan</i> ;
Xe1, Xe2: <i>XeMoTo</i> ;


Mau1, Mau2: <i>MauCoBan</i> ;



- Có thể kết hợp khai báo biến kiểu liệt kê kèm với mô tả xác định kiểu
cùng một lúc nh− sau:


VAR


<i>NgayHocToan, NgayHocTin</i>: (CN, Thu2, Thu3, Thu4, Thu5,


Thu6, Thu7);


<i>Mau1, Mau2</i>: (Do,Xanh,Vang);


Cácbiến <i>NgayHocToan, NgayHocTin</i> vμ <i>Mau1, Mau2 </i> cũng vẫn lμ
những biến kiểu liệt kê, nh−ng ta <i> không đặt tên cho kiểu</i> mμ thôi. Việc đặt
thêm một tên kiểu mới, dùng từ khoá <i>Type</i> sẽ tiện hơn trong sử dụng vμ lμm
ch−ơng trình d hiu hn.


<b>2.2 </b> <b>Tính chất và các phép toán. </b>


<i>Thứ tự trong kiểu liệt kê. </i>


Kiu lit kờ lμ kiểu có thứ tự. Thứ tự của các giá trị chính lμ thứ tự liệt
kê chúng trong danh sách. Giá trị đứng tr−ớc trong danh sách thì nhỏ hơn giá
trị đứng sau.


VÝ dô:


Thu2 < Thu3 cho kÕt qu¶ lμ <i>True,</i>


</div>
<span class='text_page_counter'>(67)</span><div class='page_container' data-page=67>

2.2.2



2.2.3


2.2.4


<i>Gán giá trị </i>


Phép gán với vế phải l một <i>tên giá trị</i> trong danh sách.
Ví dụ:


<i>HomNay</i>:= Thu2;


<i>XeMoiNhap</i>:= Honda;


<i>Mau1</i>:= Xanh;


<i>- C¸c hμm chuÈn. </i>


<b>Ord</b> : cho thứ tự của giá trị đối số trong danh sách liệt kê. Thứ tự bắt đầu tính
từ 0.


<i>Ord (CN) = 0; Ord (Thu2) = 1</i>, v.v.


<b>Pred</b>: cho giá trị đứng tr−ớc trong danh sách,


<i>Pred (Thu2) = CN; Pred (Thu3) = Thu2,</i> v.v.


Hμm <i>Pred</i> không xác định khi đối số lμ giá trị đứng đầu danh sách liệt kê.


<i>Pred (CN)</i> khơng xác định, sẽ có lỗi khi chạy ch−ơng trình - <i>run time </i>



<i>error</i>


<b>Succ</b>: cho giá trị đứng sau trong danh sách


<i>Succ (Thu3) = Thu4; Succ (Thu4) = Thu5,</i> v.v.


Hμm <i>Succ</i> không xác định khi đối số lμ giá trị đứng cuối danh sách liệt


kê. <i>Succ (Thu7)</i> khơng xác định, sẽ có lỗi khi chạy ch−ơng trình - <i>run </i>


<i>time error.</i>


<i>- §äc vμo vμ viết ra một giá trị kiểu liệt kê. </i>


a) Không thể nhập trực tiếp giá trị cho biến kiểu liệt kê từ bn phím.
Nghĩa l không thể gán cho biến <i>HomNay</i> giá trị <i>Thu2</i> bằng cách gõ từ bn
phím xâu kí tự <i>Thu2</i>, dùng cặp câu lÖnh nhËp liÖu quen thuéc:


<i>Write(' Hom nay la thu:'); </i>
<i>Readln( HomNay);</i>


Để lm việc ny, phải xử lí gián tiếp. Chẳng hạn có thể viết:


<i>Write(' Hom nay la thu:'); Readln( St); </i>
<i>If St = 'Thu2' Then HomNay:= Thu2;</i>


b) Không thể in ra trực tiếp một giá trị của kiểu liệt kê giống nh− đối
với các kiểu dữ liệu khác. Nghĩa lμ, nếu biến <i>HomNay</i> có gía trị lμ <i>Thu2</i> thì
khơng thể viết trực tiếp chữ <i>Thu2 </i>bằng câu lệnh <i>Write(HomNay).</i>



</div>
<span class='text_page_counter'>(68)</span><div class='page_container' data-page=68>

CASE HomNay OF


CN: Write(' Chu Nhat ');
Thu2: Write(' Thu hai ');
....


END;
Chó ý:


1-Về thực chất, máy sẽ xử lí kiểu liệt kê bằng cách đặt t−ơng ứng dãy
các giá trị đã liệt kê với dãy số 0,1,2, ... Ta hoμn toμn có thể khơng dùng
kiểu liệt kê mμ cũng tự xử lí trực tiếp giống nh− máy tính lμm. Chẳng hạn, có
thể ghi riêng ra bên cạnh một danh sách quy −ớc <i>CN = 0, Thu2 = 1, v.v</i>. Tuy
nhiên dùng kiểu liệt kê lμm ch−ơng trình dễ hiểu hơn vμ ta khơng phải nhớ
các quy −ớc trên.


2- Cã thĨ sư dụng biến kiểu liệt kê lm biến điều khiển trong vòng lặp


<i>For</i>, biến lựa chọn trong câu lệnh <i>Case,</i> chỉ số cho các mảng (sẽ trình by
trong phần kiểu mảng!).


<b>2.3 </b> <b>Ví dụ minh hoạ </b>


Ch−ơng trình sau đây sử dụng biến kiểu liệt kê để in ra thứ tự của các
ngμy trong tuần


Uses crt;


Type NgayTrongTuan = (CN, Thu2, Thu3, Thu4, Thu5, Thu6,
Thu7);



Var Ngay: NgayTrongTuan ;
BEGIN


For Ngay:= Thu2 to Thu7 do


Writeln('Thu',ord(Ngay)+1,'la ngay


thu',ord(Ngay),'trong tuan');
END.


<b>3. </b> <b>Kiểu đoạn con. </b>


<b>3.1 </b> <b>Định nghĩa và có ph¸p. </b>


Nếu ta hạn chế bớt miền giá trị của một kiểu vô h−ớng đếm đ−ợc
(nguyên, ký tự, liệt kê) vμo trong một đoạn con nμo đó của miền giá trị của
kiểu đó thì sẽ nhận đ−ợc kiểu dữ liệu mới lμ <i>kiểu đoạn con</i>.


</div>
<span class='text_page_counter'>(69)</span><div class='page_container' data-page=69>

3.1.1


3.1.2


3.1.3


<i>Cú pháp </i>


Phần mô tả kiểu dữ liệu mới trong khai báo kiểu đoạn con cã có ph¸p
nh− sau: <i>cËn d−íi, dÊu chÊm, dÊu chÊm, cËn trªn.</i>



<b>Type</b> <i>tªn kiĨu = cËn dới .. cận trên ;</i>


ở đây hai thnh phần <i>cận dới</i> v <i>cận trên</i> l các hằng, cùng thuộc kiểu cơ
sở, thoả mÃn điều kiện <i>cËn d−íi</i> < <i>cËn trªn</i>.


Miền giá trị của kiểu đoạn con xác định nh− trên sẽ lμ đoạn con từ <i>cận </i>
<i>d−ới</i> đến <i>cận trên.</i>


Sau khi đã xác định kiểu, ta có thể khai báo biến với kiểu dữ liệu lμ
kiểu vừa định nghĩa nh− thơng th−ờng


<b>Var</b> <i>tªn biÕn : tªn kiĨu</i> ;


<i>VÝ dơ. </i>


TYPE <i>ChuSo</i> = '0' .. '9' ;


<i>ChuCaiThuong</i> = 'a' .. 'z' ;


<i>§iem</i> = 0..10 ;


<i>NgayLamViec</i> = Thu2 .. Thu6 ;


Các định nghĩa kiểu đoạn con ở trên dựa trên các kiểu cơ sở lμ kiểu
chuẩn có sẵn hoặc kiểu đã định nghĩa tr−ớc. Đó lμ:


<i>- ChuSo, ChuCaiThuong</i> l kiểu đoạn con trên cơ sở kiểu kí tự<i>.</i>


- <i>Điem </i> l kiểu đoạn con trên cơ sở kiểu số nguyên.



- <i>NgayLamViec</i> l kiểu đoạn con trên cơ sở kiểu liệt kê


<i>NgayTrongTuan</i> đã định nghĩa trong tiết tr−ớc. Phải hiểu rằng bên trên dịng


khai báo kiểu <i>NgayLamViec</i> đã có dịng khai bỏo kiu lit kờ


<i>NgayTrongTuan</i>.


<i>Tính chất. </i>


Kiểu đoạn con kế thừa các tính chất của kiểu cơ sở. Mọi phép toán của
kiểu cơ sở áp dụng đợc cho kiểu đoạn con của nó. Điểm khác biệt duy nhất
l miền giá trị thu hẹp hơn.


Công dụng: kiểu đoạn con lμ một ph−ơng tiện nhờ ch−ơng trình dịch
kiểm tra tính phù hợp của dữ liệu, đảm bảo giá trị của các biến kiểu đoạn con
không v−ợt quá miền đã xác định. Nếu trong ch−ơng trình có những câu lệnh
vi phạm <i>hiển</i> điềù nμy thì trình biên dịch sẽ báo lỗi. Mặt khác, kiểu đoạn con
lμm ch−ơng trình chặt chẽ hơn, dễ đọc hơn.


</div>
<span class='text_page_counter'>(70)</span><div class='page_container' data-page=70>

<b>3.2 </b> <b>VÝ dụ minh hoạ. </b>


Chơng trình sau đây sẽ báo lỗi khi biên dịch do giá trị biến <i>d</i> v−ỵt ra
ngoμi miỊn cho phÐp


Type Diem = 0..10;


Var d: Diem; i: integer;
Begin



For d:= 0 to 11 do ...
End.


Tuy nhiªn, nÕu ta sửa lại phần thân chơng trình nh dới đây thì
chơng trình vẫn chạy bình thờng !


Begin


For i:= 0 to 10 do d:= i * 2;
End.


<b>4. </b> <b>Kiểu tập hợp. </b>


<b>4.1 </b> <b>Định nghĩa và cú pháp. </b>


Kiu tp hp th hin mụ hình dữ liệu tập hợp trong tốn học. Nó
thể hiện loại dữ liệu có thể nhận các giá trị không phải chỉ lμ một phần tử đơn
lẻ trong miền xác định mμ lμ một tập hợp nhiều phần tử cùng thuộc một kiểu
vô h−ớng đếm đ−ợc nμo đó.


Kiểu vơ h−ớng đếm đ−ợc nμy gọi lμ <i>kiu c s</i>.


4.1.1 <i>Cú pháp. </i>


Phần mô tả kiểu mới trong khai báo kiểu tập hợp cã có ph¸p nh− sau:


<i>tõ kho¸ Set of, tên kiểu cơ sở.</i>


<b>Type</b> <i>tên kiểu tập hợp = set of tên kiểu cơ sở ;</i>



ở đây kiểu cơ sở có thể lμ một kiểu vơ h−ớng đếm đ−ợc bất kì, kể cả kiểu liệt
kê, kiểu đoạn con.


</div>
<span class='text_page_counter'>(71)</span><div class='page_container' data-page=71>

Sau khi đã khai báo kiểu tập hợp, ta khai báo biến có kiểu tập hợp nh−
thơng th−ờng.


<b>Var</b> <i>tªn biến: tên kiểu tập hợp</i> ;


4.1.2


4.1.3


4.2.1


<i>Ví dô. </i>


TYPE <i>BoKiTu</i> = SET OF Char ;


<i>NgayMonhoc</i> = SET OF NgayTrongTuan;


<i>BangMau</i> = SET OF (Đỏ, Hồng, Xanh, Lơ, Vng, TÝm);


<i>VungDiem</i> = SET OF 0..10 ;


VAR NguyenAm, PhuAm : <i>BoKiTu</i> ;


NgayHocToan, NgayHocTin : <i>NgayMonhoc</i> ;
Kem, TrungBinh, Kha, Gioi: <i>VungDiem</i> ;



<i>Mét sè tÝnh chÊt. </i>


- Một giá trị của dữ liệu kiểu tập hợp đ−ợc thể hiện bằng cách liệt kê
mọi phần tử của tập, cách nhau dấu phẩy, đóng trong hai dấu ngoặc
vuụng.


- Thứ tự liệt kê các phần tử không quan trọng.


- Có thể gán gía trị cho biến tập hợp nh thông thờng
Ví dụ: <i>NgayHocToan:= [ Thu2, Thu5 ] ;</i>


<i>NgayHocTin := [ Th3, Thu6 ] ; </i>


<i>Kem := [0,1,2,3,4] ; </i>


- Tập rỗng kÝ hiƯu lμ [].


<b>4.2 </b> <b>C¸c phÐp to¸n trên tập hợp </b>


<i>Phép toán quan hệ </i>


- Hai toán hạng phải cùng kiểu.


So sánh bằng nhau: A = B lμ <i>True</i> nÕu A vμ B hoμn toμn nh− nhau.
So s¸nh kh¸c nhau: A <> B chØ cho kÕt qu¶ <i>False</i> khi A v B hon ton nh
nhau.


So sánh nhỏ hơn hay b»ng:


A <= B lμ <i>True</i> nÕu A lμ tËp con của B.


So sánh lớn hơn hay bằng:


</div>
<span class='text_page_counter'>(72)</span><div class='page_container' data-page=72>

<b>Chú ý:</b> Khơng có so sánh nhỏ hơn, lớn hơn chặt “< , >” đối với kiểu tập
hợp. Muốn thể hiện quan hệ "lμ tập con thực sự " ta phải kết hợp hai điều
kiện: <i>(A <= B</i>

)

<i> And (A <> B</i>

)



4.2.2


4.2.3


<i>Phép tìm kiếm "thuộc về" </i>


- Từ khoá <i>In </i>cã ý nghÜa nh− dÊu thuéc vÒ “∈”.


VÝ dô: Thu2 <i>In</i> NgayHocToan cho kÕt qu¶ <i>True</i>


Thu2 <i>In</i> NgayHocTin cho kết quả <i>False</i>


<i>Phép Hợp, Giao, Hiệu </i>


- Hai toán hạng phải cùng kiểu.


Phép Hợp thể hiÖn b»ng dÊu + : A + B lμ A ∪ B theo nghÜa to¸n
häc.


PhÐp Giao thĨ hiƯn b»ng dÊu * : A * B lμ A ∩ B theo nghÜa to¸n
häc.


PhÐp lÊy hiƯu thĨ hiƯn b»ng dÊu - : A - B lμ A \ B theo nghĩa toán
học.



<b>4.3 </b> <b>Ví dụ minh hoạ </b>


Ví dụ 1: Đếm số kí tự lμ nguyên âm, lμ phụ âm trong một dãy kí tự. Để
đơn giản ta dùng kí tự số 0 để đánh dấu kết thúc dãy.


Dễ thấy rằng cần phải có hai tập hợp chữ cái lμ các nguyên âm vμ các
phụ âm để phục vụ cho việc kiểm tra từng kí tự đọc vμo. Ch−ơng trình cần
phải định nghĩa kiểu dữ liệu <i>TapKiTu</i> vμ hai biến <i>NguyenAm, PhuAm </i> có
kiểu lμ tập hợp bộ chữ cái nh− đã nêu trên.


type BoKiTu = Set of Char;
var NguyenAm, PhuAm: TapKiTu;
ch: char;


So_NguyenAm, So_PhuAm: byte;
begin


So_NguyenAm:= 0; So_PhuAm:= 0;
NguyenAm:= ['a','e','i','o','u'];
PhuAm:= ['a'..'z'] - NguyenAm;


Write(' cho day ki tu, ket thuc bang so 0: ');
read(ch);


while ch <> '0' do
begin


if ch in NguyenAm then So_NguyenAm:= So_NguyenAm + 1;
if ch in PhuAm then So_PhuAm:= So_PhuAm + 1;



read(ch);
end;


</div>
<span class='text_page_counter'>(73)</span><div class='page_container' data-page=73>

end.


VÝ dô 2: Tìm các số nguyên tố trong khoảng 1..N
Thuật toán sng <i>Eratosthene.</i>


Phân tích: Sng ban đầu chứa ton bộ dÃy số 2 .. N. Bắt đầu từ số nhá
nhÊt lμ 2, ta lo¹i bá khái sμng tÊt cả các số l bội số của 2. Số nhỏ nhất còn
lại trên sng sẽ l số nguyên tố thø nhÊt lμ 3. Bá sè nμy ra khái sμng, ghi nã
vμo tËp sè nguyªn tè.


TiÕp tơc loại bỏ khỏi sng các số l bội số của các số nguyên tố vừa
chọn đợc. Số nhỏ nhất còn lại trên sng sẽ l số nguyên tố tiếp theo.


Lặp lại việc ny ta sng dần đợc hết các số nguyên tố.
Program Sang_Eratosthene ;


Const N=100;


Type Nguyen = 1.. N;
Var


NguyenTo, Sang: Set of Nguyen ;
Number: Nguyen ;


I: Integer ;
BEGIN



NguyenTo:= [ ] ;
Sang:= [ 2..N] ;


Number:= 2;


Repeat


While not (Number IN Sang) do Number:= Number + 1;
NguyenTo:= NguyenTo + [Number] ;


Write ( Number , ' ' );


i:= Number ;


While i <= N do
Begin


Sang:= sang - [i] ;


I:= i + Number ;


End.


</div>
<span class='text_page_counter'>(74)</span><div class='page_container' data-page=74>

<b>Ch−¬ng 6 </b>
<b>KiĨu m¶ng </b>


<b>1. </b> <b>M¶ng mét chiỊu </b>


<b>1.1 </b> <b>Định nghĩa và cú pháp. </b>



1.1.1 <i>Định nghÜa. </i>


Mảng lμ một kiểu dữ liệu có cấu trúc, tạo nên từ nhiều thμnh phần dữ
liệu <i>cùng kiểu</i>, ghép lại cạnh nhau, d−ới một tên chung. Các thμnh phần nμy
đ−ợc xếp tuần tự liền nhau thμnh dãy liên tục. Mỗi thμnh phần đ−ợc gọi lμ
một phần tử mảng. Kích th−ớc mảng hay số phần tử của mảng lμ cố định. Có
thể truy cập đến từng phần tử mảng thông qua tên chung của mảng kèm <i>chỉ </i>
<i>số</i> t−ơng ứng. Chỉ số nμy thể hiện vị trí của từng thμnh phần trong dãy liên
tục núi trờn.


Hình ảnh một mảng có tên l <i>a</i>


<i>a</i>[1] <i>a</i>[2] <i>a</i>[3] <i>a</i>[4] <i>a</i>[5] ....


1.1.2 <i>Cú pháp. </i>


Khai báo kiểu mảng:


<b> Type</b> <i>tên kiểu mảng</i> = <b>array</b> [ <i>tập chỉ số</i> ] <b>of</b> <i>kiểu phần tử</i> ;
Trong đó:


- <i>kiĨu phÇn tử</i> l kiểu dữ liệu của các phần tử mảng, có thể l bất kì


kiểu gì;


- <i>tp chỉ số</i> lμ tập hợp các chỉ số dùng để truy cập đến các phần tử


m¶ng. Nã cã thÓ lμ:



</div>
<span class='text_page_counter'>(75)</span><div class='page_container' data-page=75>

TYPE <i>vecto10</i> = ARRAY [<i>1..10</i>] OF Integer ;
b) Một danh sách liệt kê trực tiếp, ví dụ:


TYPE <i>BngTc</i>


= ARRAY [ (XeĐạp, XeMáy, ôtô, MáyBay) ] OF real;


c) Mt kiu dữ liệu (vơ h−ớng đếm đ−ợc hữu hạn gía trị), vớ d kiu


<i>Byte, </i>kiểu liệt kê<i> PhơngTiệnGiaoThông</i> nh dới đây:


TYPE <i>BangASCII</i> = ARRAY [ <i>Byte</i>] OF Char ;


<i>PhơngTiệnGiaoThông</i> = (XeĐạp, XeMáy, ôtô, MáyBay) ;


BngTc = ARRAY [ <i>PhẩngTinGiaoTh</i>ng ] OF real ;
Khai bÌo biến mảng:


<b> </b> <b> Var</b> <i>biến mảng: Tên kiểu mảng</i> ;


Ví dụ, sau khi đã xác định các kiểu mảng nh− trên ta có thể khai báo các biến
mảng.


VAR x,y: <i>Vecto10</i>;


V: <i>Tộcườ</i> ;


<b>Chú ý</b>: Có thể kết hợp khai báo biến mảng cùng với xác định kiểu trực tiếp:



<i>VAR x,y : array [1..10] of integer ; </i>


<i>V: array [(XeĐạp, XeMáy, ôtô, MáyBay</i>

)

<i>] of real ; </i>


Tuy nhin, lục nμy ta sé khẬng cọ cÌc kiểu dứ liệu <i>Vecto10, BảngTộcườ </i>Ẽể
sữ dừng. CÌc mảng <i>x,y</i> hay <i>V</i> sé cọ kiểu dứ liệu khẬng cọ tàn vμ cọ mờt sộ
bất lùi nh− ta sé thấy sau nμy.


<b>1.2 </b> <b>C¸c tÝnh chÊt. </b>


1- Có thể truy cập đến từng phần tử của một biến mảng, sử dụng tên
mảng vμ chỉ số t−ơng ứng. Ví dụ:


x[2]:= 1.23 ;
V[xe_đạp]:= 12;


2- Cã thĨ thùc hiƯn phÐp g¸n một biến mảng cho một biến mảng khác
cùng kiểu.


VÝ dơ c©u lƯnh <i>x:= y</i> tơng đơng với 10 lệnh gán <i>x[1]:= y[1] ; </i>


</div>
<span class='text_page_counter'>(76)</span><div class='page_container' data-page=76>

<b>1.3 </b> <b>Tại sao nên khai b¸o kiĨu. </b>


Khi thực hiện các phép tốn với toμn thể mảng nh− một toán hạng theo
cách trên, phải đảm bảo t−ơng thích <i> hiển </i>về kiểu. Các phép tốn sẽ bị coi lμ
khơng hợp lệ ngay cả khi thực chất lμ cùng kiểu nh−ng ta dùng hai tên kiểu
khác nhau hoặc ta khai báo biến kèm mô tả kiểu dữ liệu trực tiếp (tức lμ kiểu
dữ liệu khơng tên).


Víi c¸c khai b¸o kiĨu v biến dới đây:



TYPE Vecto10 = array [1..10] of integer ;


VectoNguyen10 = array [1..10] of integer ;
VAR x: Vecto10;


y: VectoNguyen10;


z: array [1..10] of integer ;


thì các câu lệnh gán <i>x:= y ; x:= z ; y:= z ...</i> đều sai cú pháp. Thế nh−ng nếu
thực hiện phép gán từng phần tử <i>x[1]:= y[1] ; x[2]:= y[2] ; ...</i> thì khơng có
vấn đề gì xảy ra !


Một điểm nữa cho thấy cần khai báo kiểu lμ khi dùng mảng lμm tham
số cho một ch−ơng trình con. Ta không thể mô tả kiểu mảng trực tiếp trong
danh sách tham số của ch−ơng trình con mμ phải khai báo một kiểu dữ liệu
"có tên". Ví dụ, khi viết một hμm tìm phần tử cực đại của mảng 10 số
ngun:


Hỵp lƯ:


Function <i>MaxDay</i>( x: Vecto10): integer ;
Không hợp lệ:


Function <i>MaxDay</i>( x: array [1..10] of integer): integer;


<b>1.4 </b> <b>VÝ dơ minh ho¹. </b>


VÝ dơ 1: ViÕt chơng trình thực hiện phép cộng hai véc tơ, nhân vô


hớng hai véc tơ.


Program TichVoHuong;
Uses crt;


Type Vecto10 = array [1..10] of real;
Var a,b: Vecto10;


I: integer;
Tich: real;
BEGIN


Clrscr;


Writeln(' Nhap hai vec to a, b');


Write(' Cho 10 thanh phan cua vec to a: ');
For i:=1 to 10 do Read(a[i]) ;


Writeln;


</div>
<span class='text_page_counter'>(77)</span><div class='page_container' data-page=77>

For i:=1 to 10 do Read(b[i]) ;
Writeln;


Tich:=0;


For i:=1 to 10 do Tich:= Tich + a[i]*b[i];
Write(' Tich vo huong a.b = ', Tich:10:2) ;
END.



Ví dụ 2: Viết ch−ơng trình đếm trong 50 lần gõ các kí tự từ bμn phím,
mỗi kí tự từ 'a' đến 'z' đ−ợc gõ bao nhiêu lần.


Vì có thể dùng một đoạn con của kiểu <i>Char </i>lμm tập chỉ số mảng, do
đó ta dùng một mảng có kiểu <i>Array ['a' .. 'z'] of word</i> để chứa số lần kí tự
t−ơng ứng đ−ợc gõ vμo.


Program DemTanSo;
Uses crt;


Var Dem: array ['a'..'z'] of word;
I: integer;


KiTu, ch: char;
BEGIN


Clrscr;


For ch:='a' to 'z' do Dem[ch]:= 0;


Writeln('Nhap 50 ki tu bat ki,go lan luot tung ki tu');
For i:=1 to 50 do


begin


read(KiTu);


for ch:='a' to 'z' do


if KiTu = ch then Dem[ch]:=Dem[ch]+1;


end ;


For ch:='a' to 'z' do


Writeln(' Ban da go ki tu ',ch,': ', Dem[ch], ' lan');
readln;


END.


<b>2. </b> <b>Mảng nhiều chiều. </b>


<b>2.1 </b> <b>Định nghĩa cú pháp và cấu trúc </b>


2.1.1 <i>Định nghĩa v cú pháp </i>


Nếu mỗi thnh phần của mảng lại l một dữ liệu kiểu mảng thì ta có
mảng của các mảng hay mảng hai chiều. Có thể hình dung mảng hai chiều l
mô hình hoá khái niệm ma trận


</div>
<span class='text_page_counter'>(78)</span><div class='page_container' data-page=78>

<b>Type</b> tên kiểu mảng = <b>Array</b> [ tËp chØ sè 1 , tËp chØ sè 2 ] <b>of</b> kiĨu phÇn tư;


<b>Var</b> biến mảng: tên kiểu mảng ;
Ví dụ:


TYPE <i>MaTran3x4</i> = ARRAY [1..3 ,1..4 ] OF real;


<i>ÔChữ</i> = ARRAY [1..10, 1..10] OF char ;
VAR A,B: <i>MaTran3x4</i> ;


LờiGiải1, LờiGiải2: <i>ÔChữ</i> ;



- ChØ sè thø nhÊt th−êng gäi lμ chØ sè hμng, chØ sè thø hai lμ chØ sè cét.
NghÜa lμ với mảng A khai báo ở trên ta có ma trËn nh− sau:


<i>A[1,1] A[1,2] A[1,3] A[1,4] </i>
<i>A[2,1] A[2,2] A[2,3] A[2,4] </i>
<i>A[3,1] A[3,2] A[3,3] A[3,4] </i>
<i>A[4,1] A[4,2] A[4,3] A[4,4] </i>


2.1.2 <i> CÊu tróc. </i>


Các phần tử của mảng hai chiều đ−ợc sắp xếổctng bộ nhớ theo thứ tự
−u tiên hμng, nghĩa lμ lần l−ợt hết hμng 1 đến hμng 2 , hμng 3,v.v. Ví dụ đối
với mảng A ở trên, các phần tử sẽ đ−ợc xếp tuần tự trong bộ nhớ nh− sau:


<i>A[1,1] A[1,2] A[1,3] A[1,4] A[2,1] A[2,2] A[2,3] A[2,4] A[3,1] ... </i>


Để truy cập đến một phần tử thuộc hμng <i>i</i> , cột <i>j</i> dùng tên mảng vμ
hai chỉ số t−ơng ứng. Vi d:


Gán giá trị: A[2,3]:= 0.5 ; A[2][3]:= 0.5


§äc ra: write ( A[1,2]: 10:5 ) ; write ( A[1][2]: 10:5 ) ;
Tơng tự nh mảng một chiều ta cịng cã thĨ thùc hiƯn phÐp g¸n cho
toμn thể mảng nhiều chiều nh một toán hạng.


<b>2.2 </b> <b>VÝ dơ minh ho¹. </b>


Viết ch−ơng trinh nhập một ma trận thực từ bμn phím, sau đó tính tổng
các phần tử thuộc một hμng, thuộc một cột, thuộc đ−ờng chéo chính.



Uses crt;


Type MaTran_5x5 = array [1..5,1..5] of real;
Var a: MaTran_5x5;


i,j: integer;


TongHang2, TongCot3, TongDuongCheo: Real;
BEGIN


Clrscr;


</div>
<span class='text_page_counter'>(79)</span><div class='page_container' data-page=79>

For i:=1 to 5 do
begin


Write('cho 5 pt hang thu ',i, ': ');
for j:=1 to 5 do read(a[i,j]);


end;


TongHang2:=0;


For j:=1 to 5 do TongHang2:= TongHang2 + a[2,j];


Writeln('Tong hang 2 cua ma tran la:', TongHang2:10:4);
TongCot3:=0;


For i:=1 to 5 do TongCot3:= TongCot3 + a[i,3];



Writeln('Tong cot 3 cua ma tran la:', TongCot3:10:4);
TongDuongCheo:=0;


For i:=1 to 5 do TongDuongCheo:= TongDuongCheo + a[i,i];
Writeln('Tong duong cheo cua ma tran la:',


TongDuongCheo:10:4);
readln;


END.


<b>3. </b> <b>Tìm kiếm trên mảng. </b>


<b>3.1 </b> <b>Tìm kiếm tuần tự. </b>


Tìm kiếm l một trong những bi toán cơ sở trong xử lí thông tin.
Nhiều bi toán tìm kiếm có thể quy về tìm kiếm trên mảng nh sau. Có mảng
các phần tử (thờng gọi l dÃy các giá trị khoá) v một giá trị <i>x</i> cùng kiểu dữ
liệu. HÃy tìm xem có phần tử mảng no có giá trị bằng <i>x</i> hay kh«ng.


Thủ tục <i>tìm kiếm tuần tự</i> lμ duyệt lần l−ợt các phần tử mảng, so sánh
giá trị của nó với <i>x</i>. Việc tìm kiếm dừng khi tìm thấy hoặc đã hết mảng, tức
lμ phát hiện ra lμ mảng khơng có giá trị khố nμo bằng <i>x</i>.


Cã thĨ triĨn khai thđ tục tìm kiếm trên mảng bằng một vòng lặp <i>While</i>,
dïng cê b¸o lμ biÕn <i>TimThay</i> kiĨu Boolean nh− sau.


function TimKiem(x: real; kt_mang: byte; a: mang): boolean;
var i: integer;



TimThay: boolean;
begin


TimThay:= False;
i:=1;


while (i<= kt_mang) and not TimThay do
begin


if a[i] = x then TimThay:= True;
i:=i+1;


end;


</div>
<span class='text_page_counter'>(80)</span><div class='page_container' data-page=80>

end;


Vì số phần tử của mảng lμ cố định, đã biết tr−ớc nên cũng có thể triển
khai thủ tục tìm kiếm tuần tự bằng vịng lặp <i>For</i> với câu lệnh <i>Break</i> để kết
thúc sớm vòng lặp khi đã tìm thấy.


function TimKiem(x: real; kt_mang: byte; a: mang): boolean;
var i: integer;


TimThay: boolean;
Begin


TimThay:= False;


For i:=1 to kt_mang do


if a[i] = x then
begin


TimThay:= True;
Break;


end;


TimKiem:= TimThay;
end;


<b>3.2 </b> <b>Tìm kiếm nhị phân. </b>


Nu cỏc phn t mảng thuộc kiểu dữ liệu có thứ tự vμ chúng đã đ−ợc
sắp theo thứ tự thì có thể cải tiến để thủ tục tìm kiếm thực hiện nhanh hơn.
Ta chia mảng lμm hai nửa bằng phần tử ở giữa mảng. So sánh giá trị khoá <i>x</i>
cần tìm với giá trị của phần tử "giữa mảng" sẽ loại ngay đ−ợc một nửa mảng
chắc chắn khơng chứa phần tử nμo có giá trị bằng <i>x.</i> Thủ tục nμy lặp lại cho
đến khi độ dμi mảng lμ 1.


Đây lμ khái quát hoá cách mμ ng−ời ta th−ờng lμm khi tìm một từ
trong tự điển, tìm một tên ng−ời trong một danh sách đã xếp thứ tự, v.v.
Thủ tục tìm kiếm đã nêu trên gọi lμ tìm kiếm nhị phân.


function TimKiemNhiPhan(x: real; kt: byte; a: mang):
boolean;


var l,r,m: integer;
TimThay: boolean;
begin



TimThay:= False;
l:=1; r:= kt;


while (l<=r) and not TimThay do
begin


if l=r then begin TimKiem:= (a[r]=x); exit; end;
m:=(l+r) div 2;


if x=a[m] then
begin


</div>
<span class='text_page_counter'>(81)</span><div class='page_container' data-page=81>

exit;
end


else
begin


if x<a[m] then r:=m-1 else l:=m+1;
end;


end;


TimKiem:= TimThay;
end;


<b>4. </b> <b>Mét vài cách sắp xếp mảng. </b>


Sp xp l mt trong những bμi tốn cơ sở trong xử lí thơng tin. Từ dãy


dữ liệu ban đầu ch−a có thứ tự, cần tiến hμnh sắp xếp để nhận đ−ợc dãy kết
quả có thứ tự tăng (hoặc giảm) dần theo một tr−ờng khố đ−ợc chọn nμo đó.
Bμi tốn quy về sắp xếp một mảng các phần tử thuộc kiểu có thứ tự, ví dụ
mảng số (thực, nguyên)


D−ới đây sẽ trình bμy một số ph−ơng pháp sắp xếp rất trực quan vμ dễ
hiểu. Để xác định ta ln sắp xếp để mảng kết quả có thứ tự tăng dần.


<b>4.1 </b> <b>Ph−ơng pháp đổi chỗ trực tiếp. </b>


ý t−ởng chính của ph−ơng pháp đúng nh− tên gọi của nó. Ta thực hiện
duyệt từng cặp phần tử của mảng, nếu cặp nμo ch−a đúng thứ tự cần có thì
đổi chỗ hai phần tử cho nhau. Lặp lại việc nμy cho đến khi mảng đ−ợc sắp
đúng th t.


4.1.1 <i>Mô tả </i>


Bớc 1: Bắt đầu từ đầu mút phải <i>a[n],</i> xét cặp phần tử c¹nh nhau <i>a[n], </i>


<i>a[n-1],</i> đổi chỗ chúng cho nhau nếu sai thứ tự. Nếu đã đứng thứ tự rồi thì thơi.


Tiến thêm về trái mội vị trí, nghĩa lμ xét cặp <i>a[n-1], a[n-2].</i> Lặp lại phép
kiểm tra vμ đổi chỗ trên cho đến khi tới mút trái.


Sau bớc ny phần tử nhỏ nhất sẽ ở vị trí 1.


Bớc <i>i:</i> Bắt đầu từ đầu mút phải <i>a[n]. </i>Xét cặp phần tử cạnh nhau <i>a[n], </i>


<i>a[n-1], </i>đổi chỗ chúng cho nhau nếu sai thứ tự. Tiến thêm về trái mội vị trí,



lặp lại phép kiểm tra vμ đổi chỗ trên <i>cho đến khi tới vị trí i</i>.


Sau b−ớc nμy phần tử nhỏ thứ i sẽ ở vị trí i. Dãy con a[1], a[2], ... a[i] đã
đúng thứ tự.


</div>
<span class='text_page_counter'>(82)</span><div class='page_container' data-page=82>

Hình ảnh: Nếu viết mảng theo chiều đứng thμnh một cột vμ bắt đầu từ
d−ới lên thì mỗi phần tử mảng giống nh− lμ các bọt n−ớc nhẹ hơn phải nổi
dần lên, nặng hơn phải chìm dần xuống cho tới đúng múc trọng l−ợng của nó.
Vì lẽ đó mμ ph−ơng pháp nμy cịn có tên gọi lμ sắp xếp kiểu nổi bọt - <i>Bubble </i>
<i>sort. </i>


4.1.2 <i>Minh ho¹. </i>


Bảng dới đây trình by diễn biến qua từng bớc việc sắp xếp mảng ban
đầu gồm 8 số, xÕp theo chiỊu däc tõ trªn xng trong cét 0. Kết quả sắp xếp
sau các bớc 1,2,3,4... đợc viÕt trong c¸c cét tiÕp theo.


B−íc 0 1 2 3 4 5 6 7


44 06 06 06 06 06 06 06


55 44 12 12 12 12 12 12
12 55 44 18 18 18 18 18


42 12 55 44 42 42 42 42
94 42 18 55 44 44 44 44
18 94 42 42 55 55 55 55
06 18 94 67 67 67 67 67
67 67 67 94 94 94 94 94



4.1.3 <i>Thđ tơc chi tiÕt. </i>


<i>for i:= 2 to n do </i>


<i> for j:= n downto i do </i>


<i> if a[j-1] > a[j] then </i>“<i> đổi chỗ a[j-1] cho a[j] </i>”


var i,j: integer;
x: real;


begin for i:=2 to size-1 do


begin for j:= size downto i do
if a[j-1] > a[j] then


begin x:=a[j-1]; a[j-1]:=a[j]; a[j]:=x;
end


</div>
<span class='text_page_counter'>(83)</span><div class='page_container' data-page=83>

<b>4.2 </b> <b>Phơng pháp chèn trực tiếp. </b>


4.2.1 <i>Mô tả </i>


Phng phỏp ny ging nh ngi chơi bμi nhặt từng quân đ−ợc chia
rồi chèn vμo đúng chỗ trong phần bμi đã cầm trên tay. Cụ thể lμ: xuất phát từ
đầu dãy nguồn, lấy dần từng phần tử ra vμ chèn thêm vμo đúng chỗ của nó
trong dãy đích.


Để tiết kiệm chỗ, ta khơng bố trí dãy đích ra một nơi khác mμ xếp
ngay vμo phần bỏ trống tại đầu dãy nguồn, do lấy dần từng phần tử ra. Nh−


vậy dãy đích vμ dãy nguồn ln liền nhau, cộng li vn ch chim ỳng <i>n </i>


chỗ.


B−íc xt ph¸t:


<i>Dãy nguồn </i>
<i>Dãy đích </i>


<i> rỗng</i>


Bc 1: Rỳt phn t <i>a[1]</i> từ dãy nguồn xếp vμo dãy đích. Vì dãy đích chỉ
có 1 phần tử <i>a [1]</i> nên nó đã ở đúng vị trí theo thứ tự cần sắp xếp.




<i>Dãy đích </i> <i>Dãy nguồn </i>


a<sub>1</sub>


B−ớc i: Rút phần tử <i>a[i]</i> từ dãy nguồn chèn thêm vμo dãy đích sao cho đúng
chỗ của nó. Dãy đích gồm <i>i</i> phần tử đã xếp đúng thứ tự.




<i>Dãy đích</i> <i>Dãy nguồn</i>


a<sub>i</sub>






<i>Chèn vμo đúng chỗ </i>


Lặp cho đến khi hết dãy nguồn, tức lμ cho đến khi <i>i = n</i>, mảng đ−ợc sắp xếp
xong.


<i>Dóy ớch</i>


DÃy
nguồn
rỗng


</div>
<span class='text_page_counter'>(84)</span><div class='page_container' data-page=84>

4.2.2


4.2.3


<i>Minh ho¹ </i>


Bảng d−ới đây trình bμy diễn biến của quá trình sắp xếp mảng gồm 8
số theo thuật giải chèn trực tiếp nh− mô tả ở trên. Dấu vạch chéo lμ vách
ngăn giữa dãy đích ở bên trái vμ dãy nguồn ở bên phải.


XuÊt ph¸t: 44 55 12 42 94 18 06 67
B−íc 1: 44 / 55 12 42 94 18 06 67
B−íc 2: 44 55 / 12 42 94 18 06 67
B−íc 3: 12 44 55 / 42 94 18 06 67
B−íc 4: 12 42 44 55 / 94 18 06 67


B−íc 5: 12 42 44 55 94 / 18 06 67
B−íc 6: 12 18 42 44 55 94 / 06 67
B−íc 7: 06 12 18 42 44 55 94 / 67
B−íc 8: 06 12 18 42 44 55 67 94


<i>Thđ tơc chi tiÕt. </i>
for i:=2 to size do
begin x:= a[i];


"<i>chèn x vμo đúng của nó trong dãy đã sắp thự tự a[1] ... a[i-1]"</i>
end;




Chi tiết hơn nữa thao tác "<i>chèn x vμo đúng chỗ của nó trong dãy đã </i>


<i>s¾p thù tù a[1] ... a[i-1]</i>" nh− sau. So sánh <i>x</i> với phần tử kề sát bên trái, nếu


<i>x</i> bé hơn thì dịch sang trái một vị trí. Tiến dần về bên trái. Lặp lại công việc
nμy cho đến khi <i>x</i> lớn hơn phần tử bên trái thì dừng vì <i>x</i> đã tiến đến đúng vị
trí của nó.


- Bắt đầu <i>j:=i-1</i>; so sánh <i>x</i> víi <i>a[j];</i>


- NÕu <i>a[j] > x</i> tiÕn sang tr¸i: <i>j=j-1</i>;


- Dừng khi gặp <i>a[j]</i> bé hơn <i>x</i>, hoặc đã đến mút trái.


j:=i-1;



while (x < a[j]) and (j>0) do


begin a[j+1]:= a[j]; j:= j-1;
end;


a[j+1]:= x; { <i>đã đến chỗ cần chèn x vμo</i> }


Có thể lμm đơn giản điều kiện dừng trong câu lệnh While bằng cách
thêm phần tử canh chừng vμo đầu mút trái, đặt <i>a[0] = x</i>;


Tãm l¹i cã thuËt gi¶i nh− sau.


begin


for i:=2 to size do


</div>
<span class='text_page_counter'>(85)</span><div class='page_container' data-page=85>

j:= i-1;


while x < a[j] do


begin a[j+1]:= a[j]; j:= j-1;
end;


a[j+1]:= x;
end


end;



<b>4.3 </b> <b>Phơng pháp chọn trực tiếp. </b>


4.3.1 <i>Mô tả </i>


Phng phỏp ny giống nh− sắp lại toμn bộ các quân bμi theo thứ tự
bằng cách rải rộng trên mặt bμn vμ nhặt dần từ con bμi thấp nhất trở lên. Cụ
thể lμ: chọn phần tử nhỏ nhất trong dãy nguồn, xếp nó vμo vị trí đầu tiên
trong dãy đích. Đây lμ phần tử thứ nhất vμ cũng lμ phần tử cuối cùng của dãy
đích. Chọn phần tử nhỏ nhất trong dãy nguồn còn lại, đây lμ phần tử nhỏ thứ
hai, xếp nó vμo vị tri thứ hai vμ cũng lμ vị trí cuối của dãy đích vμo lúc nμy.
Lặp lại việc nμy cho đến khi hết dãy nguồn.


Để tiết kiệm chỗ, ta cũng xếp dãy đích vμ dãy nguồn liền nhau trong
mảng, giống nh− trong ph−ơng pháp tr−ớc. Do đó, ở b−ớc thứ <i>i</i>, thao tác
"<i>xếp vμo cuối dãy đích</i>" chính lμ "<i>đổi chỗ cho a[i]".</i>


XuÊt ph¸t


Dãy nguồn
Dóy ớch


rỗng


B−íc 1: - Chän phÇn tư bÐ nhÊt tõ d·y ngn,
- §ỉi chỗ cho phần tử <i>a[1]</i> .


Dãy đích Dãy nguồn
a<sub>1</sub>





<i> Chän phÇn tư min </i>


B−íc <i>i</i>:


</div>
<span class='text_page_counter'>(86)</span><div class='page_container' data-page=86>

<i>Dãy đích</i> <i>Dãy nguồn</i>


a<sub>i</sub>


<i>Chän phÇn tư min </i>



Lặp cho đến khi hết dãy nguồn, <i>i = n.</i>


So sánh với phơng pháp chèn:


- Ph−ơng pháp chèn lμ lấy phần tử <i>đầu tiên</i> trong dãy nguồn còn lại,
chèn vμo <i>đúng chỗ</i> trong dãy đích. Lμm việc với dãy đích lμ chính.


- Ph−ơng pháp chọn lμ lấy phần tử<i> nhỏ nhất </i>trong dãy nguồn cịn lại
xếp vμo <i>cuối</i> dãy đích. Lμm việc với dãy nguồn lμ chính.


4.3.2


4.3.3


<i>Minh ho¹: </i>



XuÊt ph¸t: 44 55 12 42 94 18 06 67
B−íc 1: 06 / 55 12 42 94 18 44 67
B−íc 2: 06 12 / 55 42 94 18 44 67
B−íc 3: 06 12 18 / 42 94 55 44 67
B−íc 4: 06 12 18 42 94 55 44 67
B−íc 5: 06 12 18 42 44 / 55 94 67
B−íc 6: 06 12 18 42 44 55 / 94 67
B−íc 7: 06 12 18 42 44 55 67 / 94
B−íc 8: 06 12 18 42 44 55 67 94


<i>Thđ tơc chi tiÕt. </i>


<i>for i:=1 to n -1 do </i>
<i> begin </i>


<i> </i>“<i> chän phÇn tư min cđa d·y a[i],a[i+1],...,a[n] </i>”


<i> </i>“<i> đổi chỗ cho a[i]</i>”


<i>end </i>


var i,j,k: integer;
x: real;


begin for i:=1 to size-1 do
begin k:=i; x:=a[i];


for j:=i+1 to size do



if a[j]<x then begin k:=j; x:=a[j];


end;


</div>
<span class='text_page_counter'>(87)</span><div class='page_container' data-page=87>

end
end;


Câu hỏi v bi tập


1. Các phần tử mảng có thể l những kiểu gì? Chỉ số của mảng có thể l
những kiểu gì?


2. Cỏc khai bỏo kiểu mảng d−ới đây đúng hay sai, mô tả rõ cấu trúc mảng.


<i>Array [10..0] of Real; </i> <i>Array ['0'..'9'] of Real; </i>


<i>Array ['a'..'z'] of Char; </i> <i>Array [A..Z] of Integer; </i>


<i>Array [(A,B,C)] of (-10..10); </i> <i>Array [Byte] of Boolean; </i>


<i>Array [Integer] of Integer; Array [Char] of Byte; </i>


3. §Ĩ xư li mọi phần tử của mảng thờng dùng vòng lặp gì? Có thể dùng
những vòng lặp no?


4. Trong Pascal kiĨu m¶ng cã thĨ nhiỊu nhÊt lμ mÊy chiỊu.


5. Thế no l mảng sắp theo u tiên hng, u tiên cột. Mảng trong Pascal
thuộc kiểu no?



Thực hnh.


1. Nhập dãy <i>n</i> số thực. Tính trung bình cộng, tìm trung vị (median), tìm
phần tử lớn nhất, nhỏ nhất; tìm phần tử lớn thứ nhì; đếm số phần tử d−ơng,
âm; Tìm chỉ số của phần tử âm đầu tiên, cuối cùng; kiểm tra dãy đan dấu.
2. Nhập dãy số; trich ra dãy con lμ cấp số cộng, cấp số nhân có nhiều phần tử


nhÊt.


3. Cho số nguyên d−ơng hệ <i>10</i>, hãy in ra số đó ở hệ <i>2, 8, 16</i>.


4. Nhập dãy n giá trị quan trắc của một đại l−ợng ngẫu nhiên. Tìm ph−ơng
sai vμ độ lệch tiêu chuẩn.


5. Tính tích vô hớng của hai véc tơ


6. Nhập d·y <i>n</i> sè vμ mét sè <i>x</i>. T×m xem cã bao nhiªu sè trong d·y trïng víi


<i>x</i>. Chúng ở các vị trí no?


7. Cho ma trận các số nguyên <i>A[1..7; 8..14]</i> với <i>A[i,j]:= i*j.</i> Tính tổng các
phần tử trên một cột, trên một hng, trên đờng chéo chính, trên đờng
chéo phụ.


8. Cho ma trận vuông. Tách thnh hai ma trận tam giác trên v tam giác dới
rồi in ra mμn h×nh.


9. NhËp tõ bμn phÝm mét dÃy số nguyên, in ra các giá trị khác nhau kèm số
lần xuất hiện.



10. Viết chơng trình sắp xếp một dÃy số, dùng các thủ tục
a -) chÌn trùc tiÕp,


</div>
<span class='text_page_counter'>(88)</span><div class='page_container' data-page=88>

c -) đổi chỗ trực tiếp


11. NhËp hai d·y sè nguyªn cïng cã <i>n</i> phÇn tư. KiĨm tra xem có phải một
dÃy chỉ l hoán vị của dÃy kia hay kh«ng.


12. Cho <i>n </i> ®iĨm kh¸c nhau <i> p<sub>i</sub> = (x<sub>i</sub>, y<sub>i</sub>)</i> vμ ®−êng gấp khúc khép kín nối các
điểm ny theo thø tù tõ <i>p<sub>1</sub>, p<sub>2</sub>, ... , p<sub>n</sub>, p<sub>1</sub></i>.


a) kiĨm tra xem ®−êng gÊp khúc có tự cắt không.


</div>
<span class='text_page_counter'>(89)</span><div class='page_container' data-page=89>

<b>Chơng7 </b>
<b>KiĨu x©u kÝ tù </b>


<b>1. </b> <b>Cú pháp và cấu trúc. </b>


<b>1.1 </b> <b>Cú pháp. </b>


Xâu kí tự l một kiểu dữ liệu nhận giá trị l dÃy kí tự ASCII bất kì.
1.1.1


1.1.2


<i>Khai báo kiểu v biến </i>
Cú pháp khai báo kiểu xâu kí tự:


TYPE <i>tªn kiĨu</i> = STRING ;



hoặc TYPE <i>tên kiểu </i>= STRING [ <i>độ dμi cực đại</i>] ;


Trong đó <i>độ dμi cực đại </i>lμ một số <i>n</i> nguyên d−ơng, <i>n <= 255</i>. Độ
dμi của một biến xâu kí tự đ−ợc hiểu lμ số kí tự của dãy, kể các các kí tự
khoảng trống xen giữa hoặc nằm ở hai đầu. Với cách khai báo thứ nhất,
khơng ấn định độ dμi cực đại thì mặc định lμ độ dμi cực đại bằng 255.


VÝ dơ:


TYPE <i>HäVμTªn</i> = STRING[20] ;


<i>DòngMnHình</i> : String [80] ;


Khai b¸o biÕn:


VAR SV1, SV2 : <i>HọVTên</i> ;


Dòng1, Dòng2: <i>DòngMnHình</i> ;


Cũng có thể khai báo biến kiểu xâu kí tự bằng mô tả kiểu trực tiếp:
VAR SV1, SV2 : String [20] ;


</div>
<span class='text_page_counter'>(90)</span><div class='page_container' data-page=90>

Một hằng xâu kí tự lμ một dãy kí tự ASCII nằm trong cặp dấu nháy
đơn. Cú pháp ngơn ngữ Pascal quy định viết giá trị xâu kí tự trong cặp dấu
nháy đơn (single quote). Ví dụ, ‘Turbo Pascal’, ‘Dai hoc Quoc gia Ha Noi”,
v.v.


Xâu rỗng lμ xâu khơng có kí tự nμo vμ có độ dμi bằng 0. Viết xâu rỗng
chỉ có cặp dấu nháy đơn liền nhau, khơng có kí tự nμo bên trong. Cần chú ý
phân biệt xâu rỗng với xõu ch gm cỏc kớ t khong trng.



Xâu rỗng: .


Xâu chỉ có một kí tự khoảng trống: ’.


1.1.3


1.2.1


<i>Viết ra, đọc vμo một xâu kí tự. </i>
Viết ra.


Cã thĨ in biĨu thøc x©u kÝ tự ra mn hình, máy in hay tệp văn bản b»ng
c¸c lƯnh <i>Write</i>. Thđ tơc <i>Write (St)</i> sẽ in ra nguyên văn xâu kí tự <i>St</i>, kể cả
các dấu trống ở đầu v cuối xâu.


Ví dụ: Giả sử <i>Dòng1, Dòng2</i> l hai biÕn x©u kÝ tù vμ ta thùc hiƯn
phÐp gán


Dòng1:= 'CONG HOA XHCN VIET NAM' ;
Dßng2:= ' ***** ' ;


Khi in ra bằng các lệnh <i>Writln(Dòng1); Writeln(Dòng2);</i> ta sẽ nhận đ−ợc
hai dịng chữ bố trí đúng nh− trên:


CONG HOA XHCN VIET NAM
*****


Chi tiết hơn về sử dụng thủ tục <i>Write </i> để viết ra vμ quy cách định dạng
viết ra đã đ−ợc trình bμy trong Ch−ơng 3.



§äc vμo.


Có thể đọc vμo từ bμn phím vμ gán gía trị cho một biến kiểu xâu kí tự
bằng các lệnh <i>Read</i>.


Chi tiết hơn về sử dụng thủ tục <i>Read</i> để đọc dữ liệu vμo từ bμn phím đã
đ−ợc trình bμy trong Ch−ơng 3.


<b>1.2 </b> <b>CÊu tróc kiĨu x©u kÝ tự - Truy cập trực tiếp từng thành phần. </b>


<i>Cấu tróc mét x©u kÝ tù</i>.


</div>
<span class='text_page_counter'>(91)</span><div class='page_container' data-page=91>

VÝ dơ, nÕu giá trị của biến xâu kí tự <i>SV1</i> lμ <i>'Nguyen Van A'</i> th×
trong bé nhí sÏ lμ


#12 N g u y e N V a n A * * * * * * * *


Trong đó, #12 lμ kí tự có mã ASCII bằng 12. Các dấu sao “ *” nghĩa lμ kí tự
bất kì nμo đó khơng xác định.


1.2.2


1.2.3


<i>Có ph¸p truy cËp c¸c kÝ tù thnh phần. </i>


Cấu trúc của một biến xâu kí tự l một mảng kí tự nh vừa mô tả ở trªn
nªn ta cã thĨ thùc hiƯn mét sè thao tác truy cập trực tiếp vo từng thnh phần


của biÕn x©u kÝ tù.


- Có thể truy cập vμo từng kí tự trong xâu, dùng tên biến vμ số thứ tự
của nó trong xâu đặt trong dấu ngoặc vng, giống nh− đối với mảng một
chiều. Ví dụ, phép so sánh <i>SV1 [8] = 'V'</i> cho kết quả <i> True</i>.


- Có thể lấy độ dμi thực sự của xâu kí tự <i>St</i> bất kì, thông qua mã ASCII của
phần tử <i>St[0]</i>, tức lμ độ dμi của xâu <i>St</i> bằng <i>Ord (St[0])</i>

.



L−u ý rằng ta cũng có hμm chuẩn cho biết độ dμi của xâu kí tự <i>St</i> lμ


<i>Length (St).</i>


<i>VÝ dơ </i>


Viết ch−ơng trình nhập một xâu kí tự từ bμn phím vμ in ra xâu đảo
ng−ợc từ phải sang trái.


Uses crt;


Var Xau: String;
I: byte ;
BEGIN


Writeln('Cho mot xau ki tu: '); Readln( Xau );


For i:= lenght (Xau) downto 1 do write (Xau[i]);
Readln;


END.



</div>
<span class='text_page_counter'>(92)</span><div class='page_container' data-page=92>

<b>2. </b> <b>Thao tác với xâu kí tự </b>


<b>2.1 </b> <b>Các phép toán. </b>


2.1.1


2.1.2


2.1.3


<i>BiĨu thøc x©u kÝ tù vμ phÐp gán </i>


Phép cộng + hai toán hạng kiểu xâu kí tự l ghép nối hai xâu lại
thnh mét. Cã thĨ “céng” hai biÕn kiĨu x©u kÝ tù, nột biến với một giá trị trực
tiếp hoặc hai giá trị trực tiếp (kiểu xâu kí tự).


Ví dơ 1:


BiÕn <i>SV1</i> cã gÝa trÞ lμ ‘<i>Nguyen Van A</i>’ th× biĨu thøc ' <i>Hä v tên:</i> ' +


<i>SV1</i> sẽ có giá trị l ' <i>Ho va tên: Nguyen Van A </i>'.
VÝ dô 2:


Path:= 'C:\TP\bin\' ;
FileName:= 'Turbo.exe' ;
St:= Path + FileName;


sẽ nhận đợc St:= ' C:\ TP\bin\Turbo.exe '.



<i>PhÐp so s¸nh. </i>


So s¸nh b»ng nhau “ = ” vμ kh¸c nhau “ <> ”


Phép so sánh hai biểu thức xâu kí tự "bằng nhau" cho kết quả <i>True</i>


nếu từng cặp kí tự tơng ứng ở hai xâu l trùng nhau. Trái lại, phép so sánh
bằng nhau sẽ cho kết quả <i>False</i>.


Ví dụ: Nếu biến kiểu xâu kí tự <i>SV1</i> đã đ−ợc gán giá trị nh− trong ví
dụ ở trên thì


<i>SV1</i> = <i>'Nguyen Van A'</i> cho giá trị <i>True</i>.


SV1 = 'Nguyen Van A' cho giá trị False.
<i>Thứ tù cđa kiĨu x©u kÝ tù. </i>


X©u kÝ tù lμ kiĨu cã thø tù. Thø tù cđa kiĨu x©u lμ thứ tự từ điển.
Phép so sánh thứ tự hai xâu kí tự đợc thc hiện qua so sánh lần lợt
từng cặp kí tự tơng ứng ở hai xâu, từ trái sang phải. Thứ tự của xâu l thứ tự
của cặp kí tự đầu tiên không trïng nhau.


VÝ dô:


'abcd' < 'abed' cho giá trị <i>True.</i>


'abc' < 'abcdef' cho gi¸ trÞ <i>True</i>.


</div>
<span class='text_page_counter'>(93)</span><div class='page_container' data-page=93>

Trong th− viện các hm, thủ tục lm sẵn của Pascal có mét sè hμm, thđ
tơc vỊ xư lÝ x©u kÝ tù.



2.2.1 <i>C¸c thđ tơc </i>


<b>Delete</b><i>(St, Pos, Num</i>

)

<i>:</i>
- <i>St</i> lμ biÕn kiểu <i>String.</i>


- <i>Num, Pos</i> l các giá trị nguyên.


- Tác dụng: xoá khỏi xâu <i>St</i> một số lợng <i>Num</i> kí tự, bắt đầu từ vị trí


<i>Pos</i>, từ trái sang phải.


Ví dụ: St:= 'ABCDEF' ;


Delete(St,2,4); sÏ cho St = 'AFG'
Delete(St,2,10) ; sÏ cho St ='A'


Delete(St,10,3); sÏ cho St = 'ABCDEF' ;


<b>Insert</b> (<i>St2, St, Pos</i>

)

<i> ;</i>


- <i>St2 </i> lμ biÓu thøc kiÓu <i>String.</i>


- <i>St1</i> lμ biÕn kiẻu <i>String.</i>


- <i>Pos </i>l giá trị nguyên.


Tỏc dng: chèn thêm xâu <i>St2</i> vμo xâu <i>St1</i> tại vị trí <i>Pos</i>. Nếu <i>Pos</i>
v−-ợt quá độ dμi xâu đích thì <i>St2</i> sẽ đ−ợc nối thêm vμo đuôi.



VÝ dô: insert('123' , St, 4); sÏ cho St = 'ABCD123EF'.
insert('123' , St,10) ; sÏ cho St = 'ABCDEF123'.


<b>Str</b> (<i>Value, St</i>

);



- <i>Value</i> lμ biĨu thøc nguyªn hay thùc, cã quy c¸ch in ra


- <i>St</i> lμ biÕn kiĨu <i>String</i>.


Tác dụng: đổi gía trị số thμnh xâu kí số rồi gán cho xâu <i>St</i>.
Ví dụ:


i:= 123;


Str (i:5 , St) ; sÏ nhận đợc St = ' 123' .
x:= 123.456 ;


Str (x:10:5 , St); sẽ nhận đợc St = ' 123.45600'


<b>Val</b> (<i>St, Var , Code</i>

)

<i>;</i>


- <i>St</i> lμ biĨu thøc <i>String.</i>


- <i>Var</i> lμ biÕn nguyªn hay thùc.


- <i>Code </i> lμ biÕn nguyªn.


</div>
<span class='text_page_counter'>(94)</span><div class='page_container' data-page=94>

VÝ dô 1: i, e: integer;
St = '123' ;



<i>Val (St, i , e);</i> sẽ nhận đợc <i>i = 123 , e = 0.</i>


VÝ dô 2: St = '12ba' ;


<i>Val (St, i, e</i>

)

<i>;</i> sẽ nhận đ−ợc <i>i</i> khơng xác định, <i>e = 3</i>.


2.2.2 <i>C¸c hμm </i>


<b>Length</b> (<i>St</i>): cho biết độ dμi của xâu <i>St.</i>


<b>Copy</b><i>(St, Pos, Num):</i>


- <i>St</i> lμ biÓu thøc x©u kÝ tù,


- <i>Pos, Num</i> biĨu thøc kiểu nguyên.


Tác dụng: trích ra một xâu con từ xâu con từ xâu <i>St</i>, bắt đầu từ vị trÝ


<i>Pos</i> vμ dμi <i>Num</i> kí tự. Nếu <i>Pos + Num</i> lớn hơn độ dμi xâu <i>St</i> thì xâu kết
quả chỉ gồm các kí tự cuối trong xâu <i>St</i>. Nếu <i>Pos</i> lớn hơn độ dμi của <i>St</i> thì
xâu kết quả lμ rỗng.


VÝ dô: St:= 'ABCDEF' ;


<i>St_con:= Copy (St, 3, 3</i>

) ;

sÏ cho <i>St_con = 'CDE'.</i>


<i>St_con:= Copy (St, 4,4</i>

)

<i> ;</i> sÏ cho <i>St_con = 'DEF'.</i>


<i>St_con:= Copy (St, 10,5</i>

)

<i> ;</i> sÏ cho <i>St_con = ' ' .</i>



<b>Concat</b> <i>(St1, St2, ... , Stn</i>

):



Ghép nối tất các xâu thnh một xâu.


- Nếu tổng chièu di các xâu > 255 máy sẽ báo lỗi.
- Có thể dùng phép + .


<b>Pos</b> <i>(St1, St2</i>

)

<i>;</i>


Tìm xâu <i>St1</i> trong xâu <i>St2 </i>v cho biết vị trí đầu tiên gặp xâu <i>St1</i>
trong xâu <i>St2</i>. Nếu không tìm thấy thì <i>Pos = 0.</i>


Ví dơ: St:='ABCDEF' ;
th×: <i>Pos ('CD', St</i>

)

<i> = 3; </i>


<i>Pos ('CX' ,St</i>

)

<i> = 0.</i>


C©u hái vμ bμi tËp


</div>
<span class='text_page_counter'>(95)</span><div class='page_container' data-page=95>

3. Xâu kí tự khác mảng kí tự nh thế no. Tại sao sử dụng kiểu xâu lại tiện
lợi hơn dùng mảng kí tự.


Thực hnh


1. Tạo một dòng chữ chạy từ trái sang phải (hoặc từ phải sang trái) trong một
khung hình chữ nhật trên mn hình.


2. Tự viết lại các hm thủ tục xử lí xâu kí tự trong tiết 2.


3. Viết chơng trình chuyển <i>n</i> số thực dới dạng một xâu các chữ số cách


nhau khoảng trắng vo một mảng <i>n</i> số thực, không dùng hm chuÈn


</div>
<span class='text_page_counter'>(96)</span><div class='page_container' data-page=96>

<b>Ch−¬ng8 </b>
<b>Kiểu bản ghi </b>


<b>1. </b> <b>Định nghĩa và khai báo </b>


<b>1.1 </b> <b>Định nghĩa. </b>


Cỏc kiu d liệu đ−ợc xây dựng đều lμ mơ hình hố các loại dữ liệu từ
thế giới thực. Các đối t−ợng thực tế th−ờng phức tạp, hμm chứa nhiều thông
tin khác kiểu nhau. Ví dụ, thơng tin về một cán bộ bao gồm họ tên, quê quán
(có kiểu xâu kí tự), giới tính (kiểu logic), tuổi (kiểu số nguyên), mức l−ơng
(kiểu số thực) ... Thông tin về một sản phẩm hμng hóa bao gồm mã số, tên
gọi (kiểu xâu kí tự), ngμy sản xuất (kiểu ngμy tháng), giá thμnh (kiểu số
thực),v.v.


Để tiện xử lí các đối t−ợng nμy, cần có cơ chế ghép nhiều thμnh phần
dữ liệu có kiểu khác nhau thμnh một đơn vị thống nhất.


Kiểu bản ghi - <i>Record</i> chính lμ cấu trúc dữ liệu đáp ứng đòi hỏi nμy.
Một dữ liệu kiểu bản ghi tạo nên từ nhiều thμnh phn, gi l cỏc trng


<i>field</i>. Mỗi trờng l một mục dữ liệu có thể khác kiểu nhau.


<b>1.2 </b> <b>Khai báo kiểu bản ghi. </b>


1.2.1


1.2.2



<i>Cú pháp. </i>


Cú pháp khai báo kiểu bản ghi nh sau.


<b>Type</b> <i>tªn kiĨu </i>= <b>Record</b>


<i>tên trờng 1 : mô tả kiểu dữ liệu 1; </i>


...


<i>tên trờng n : mô tả kiểu dữ liệu n ; </i>


<b>end</b> ;
<i>VÝ dô </i>


</div>
<span class='text_page_counter'>(97)</span><div class='page_container' data-page=97>

<i>Ngay: 1..31 ; </i>


<i> Thang: 1..12 ; </i>


<i>Nam: Word ;</i>


END ;
Ví dụ 2: Kiểu địa chỉ


TYPE <i>Adress</i> = RECORD


<i>SoNha: Word ; </i>
<i>Phè: String [20] ; </i>
<i>TØnh: String [15] ; </i>



END ;


VÝ dô 3: Kiểu hồ sơ nhân sự
TYPE <i>HoSo</i> = RECORD


<i>HoDem: String [20] ; </i>


<i> Tªn: String [20] ; </i>


<i>Gioi: boolean ; </i>


<i> NgaySinh: Date ; </i>


<i>L−¬ng: real; </i>


<i>CoGiaDinh: boolean ; </i>


<i> DiaChi: Adress ;</i>


END;


<b>Chú ý:</b> - Có thể viết các định nghĩa kiểu bản ghi lồng nhau. Nếu tr−ớc
đó ta ch−a định nghĩa kiểu <i>Date</i> thì có thể viết lồng trực tiếp định nghĩa kiểu


<i>Date</i> bên trong định nghĩa kiểu <i>HoSo</i> nh− sau:
TYPE HoSo = RECORD


<i>HoDem: String [20] ; </i>



<i> Tªn: String [20] ; </i>


<i> Gioi: boolean ;</i>


<i>NgaySinh</i>: RECORD


<i>Ngay: 1..31 ; </i>


<i> Thang: 1..12 ; </i>


<i>Nam</i>: Word ;
END ;


<i>L−¬ng: real; </i>


<i>CoGiaDinh: boolean ; </i>
<i>DiaChi: Adress ; </i>


END;


Sau khi đã định nghĩa các kiểu bản ghi nh− trên ta có thể khai báo các
biến để sử dụng nh− thông th−ờng.


</div>
<span class='text_page_counter'>(98)</span><div class='page_container' data-page=98>

Ví dụ.


VAR KhơiCông, KhanhThanh, NgSinh_1, NgSinh_2 : <i>Date</i> ;
CanBo1, CanBo2: <i>HoSo</i> ;


<b>2. </b> <b>Sư dơng. </b>



<b>2.1 </b> <b>Truy cËp từng thành phần. </b>


Kiểu bản ghi cho phép truy cập tõng thμnh phÇn, tøc lμ tõng tr−êng
cđa nã.


<b>Cú pháp</b>: <i>tên biến, dấu chấm, tên trờng dữ liệu muốn truy cập.</i>
Gán giá trị <i>tên biến . tên trờng := giá trị; </i>


Đọc giá trị <i>vế trái:= tên biến . tên trờng;</i>


Ví dụ:


Để gán cho biến NgSinh_1 giá trị ngy 10/02/1970 ta sử dụng các
câu lệnh sau:


<i>NgSinh_1.Ngay:= 10; </i>


<i> NgSinh_1.Thang:= 2; </i>


<i>NgSinh_1.Nam := 1970 ;</i>


Để in ra mn hình họ tªn cđa CanBo1:


<i>St:= CanBo1.HoDem + CanBo1.Ten ; </i>
<i>Write(' Ho va ten:' , St) ;</i>


<b>2.2 </b> <b>Các phép toán với toàn bộ bản ghi. </b>


Có thĨ thùc hiƯn mét sè phÐp to¸n víi toμn bé biến kiểu bản ghi nh
một toán hạng.



2.2.1


2.2.2


<i>PhÐp g¸n. </i>


Cho phép gán đối với hai biến bản ghi cùng kiểu.
Tiếp tục ví dụ 1 ở trên có thể viết


<i>CanBo1. NgaySinh := NgSinh_1 ; </i>


<i>PhÐp so s¸nh. </i>


</div>
<span class='text_page_counter'>(99)</span><div class='page_container' data-page=99>

PhÐp so s¸nh "b»ng nhau" thực hiện qua so sánh từng cặp các trờng
tơng ứng. Hai bản ghi l bằng nhau nếu các trờng tơng ứng trùng nhau
hon ton. Trái lại lμ kh¸c nhau.


VÝ dơ: Sau lƯnh g¸n


<i>CanBo2 := CanBo1</i> ;


th× phÐp so s¸nh <i>CanBo1 = CanBo2</i> cho kÕt qu¶ lμ <i>true</i> ;


- Kiểu bản ghi khơng có thứ tự, do đó khơng cho phép các so sánh < ,
> , >= , >=


2.2.3 <i>L−u ý vỊ tªn kiĨu. </i>


Khi thực hiện các phép toán với toμn thể bản ghi nh− một tốn hạng


cần phải đảm bảo t−ơng thích <i>hiển</i> về kiểu. Các phép toán sẽ bị coi lμ không
hợp lệ ngay cả khi thực chất lμ cùng kiểu nh−ng ta dùng hai tên kiểu khác
nhau hoặc ta khai báo biến kèm mô tả kiểu dữ liệu trực tiếp (tức lμ kiểu dữ
liệu không tên).


Giả sử có các khai báo kiểu v biến dới ®©y:
TYPE <i>Date</i> = RECORD


<i>Ngay: 1..31; </i>
<i>Thang: 1..12 ; </i>


<i>Nam: Word</i> ;


END;


<i>NgThang</i> = RECORD


<i>Ngay: 1..31; </i>
<i>Thang: 1..12 ; </i>


<i>Nam: Word ;</i>


END;
VAR N1: <i>Date; </i>


N2: <i>NgThang; </i>


N3: RECORD


<i>Ngay: 1..31; </i>


<i>Thang: 1..12 ; </i>
<i>Nam: Word ; </i>


END;


Các câu lệnh sau đều sai cú pháp


<i>N1:= N2 ; N2:= N3; </i>


<b>2.3 </b> <b>Đọc vào, viết ra với một biến kiểu bản ghi. </b>


</div>
<span class='text_page_counter'>(100)</span><div class='page_container' data-page=100>

VÝ dô, nÕu mèn nhËp tõ bn phím các dữ liệu cho biến kiểu bản ghi


<i>NgSinh_1</i> nh ở ví dụ trên thì không thĨ dïng lƯnh <i>Read( NgSinh_1)</i> råi


nhËp tõ bμn phÝm c¸c sè 10 2 1970 m phải dùng 3 cặp lệnh liên tiếp nh
sau.


<i>Write(' cho ngay sinh ') ; Readln(NgSinh_1.Ngay ); </i>
<i>Write(' cho th¸ng sinh ') ; Readln(NgSinh_1.Thang ); </i>
<i>Write(' cho năm sinh ') ; Readln(NgSinh_1.Năm ); </i>


Tng t nh vậy, nếu muốn viết ra biến <i>NgSinh_1</i> thì cũng không
thể dùng lệnh <i>Write(NgSinh_1)</i> mμ phải truy cập vμ viết ra lần l−ợt từng
tr−ờng thμnh phần có kiểu dữ liệu chuẩn đơn giản.


<b>2.4 </b> <b>C©u lƯnh With. </b>


Ta thấy rằng để truy cập các tr−ờng của bản ghi phải chỉ rõ tên biến
bản ghi vμ sau đó lμ các tên tr−ờng. Nếu bản ghi gồm nhiều tr−ờng thì tên


biến bản ghi c lp i lp li nhiu ln.


Để tránh lặp lại việc viết tên biến kiểu bản ghi khi mn truy cËp tíi
nhiỊu tr−êng cđa nã cïng lóc, ta có thể dùng câu lệnh WITH


<b>Cú pháp</b>: <b>With </b> <i>tên biến</i> <b>do</b> <i>câu lệnh</i> ;
Ví dụ:


Có thể viết lại đoạn lệnh gán giá trÞ cho <i>NgSinh_1</i> nh− sau
WITH <i>NgSinh_1</i> DO


Begin Ngay:= 10 ;
Thang:= 2 ;
Nam:= 1970
end ;


Có thể viết đoạn lệnh gán trị cho biến <i>CanBo1</i> nh sau:
WITH <i>CanBo1</i> DO


Begin


HoDem:= ' Nguyen Van ' ;
Ten:= ' Hung ' ; ...


End ;


Có thể sử dụng câu lệnh <i>With</i> lồng nhau để truy cập các tr−ờng của
một biến có cấu trúc kiểu bản ghi lồng nhau nhiều tầng. Ví dụ, muốn gán
trực tiếp ngμy tháng năm sinh cho <i>CanBo1</i> ta có thể dùng hai câu lệnh <i>With </i>



lång nhau nh− sau


</div>
<span class='text_page_counter'>(101)</span><div class='page_container' data-page=101>

WITH <i>NgaySinh</i> DO
Begin


Ngay:= 10 ;


Thang:= 2 ;


Nam:= 1970 ;


End;


ThËm chí còn có thể viết gọn hơn nữa
WITH <i>CanBo1. NgaySinh</i> DO ...


Nghĩa lμ khi A lμ biến kiểu bản ghi, B lμ một tr−ờng của A vμ B lại lμ một
biến bản ghi thì để thâm nhập vμo các tr−ờng của B thì chỉ cần viết


WITH <i>A.B</i> DO ...


<b>3. </b> <b>Bản ghi có cu trỳc thay i </b>


<b>3.1 </b> <b>Định nghĩa và cú ph¸p </b>


3.1.1


3.1.2


<i>Đặt vấn đề. </i>



Ta đã xét kiểu bản ghi có cấu trúc cố định, số các tr−ờng, kiểu t−ơng
ứng của các tr−ờng lμ không thể thay i.


Đôi khi có các dữ liệu gồm nhiều thnh phần kiểu giống nhau, chỉ
khác nhau ở một vi điểm. Ví dụ, nếu xét thêm trờng dữ liệu nghề nghiệp
trong kiểu bản ghi <i>HồSơ</i> thì thấy ngay có nhiều kiểu khác nhau. <i>Công nhân </i>


cần ghi bậc thợ, <i>Trí thức</i> cần ghi học hm học vị, <i>Doanh nhân</i> cần ghi ngnh
kinh doanh, số vốn...


Hai giải pháp:


- Tạo ra nhiều kiểu bản ghi: <i>CôngNhân, TríThức, DoanhNhân</i>, chỉ
khác nhau ở trờng nghỊ nghiƯp.


- Hoặc định nghĩa một kiểu bản ghi nh−ng có 3 tr−ờng nghề nghiệp
khác nhau vμ chỉ dùng một trong ba tr−ờng đó tuỳ tr−ờng hợp.


Cả hai cách lμm trên đều cồng kềnh vμ lãng phí.


Cần đặt ra kiểu mới linh hoạt hơn, đó lμ <i>bản ghi có cấu trúc thay đổi</i>.
<i>Mô tả cú pháp kiểu bản ghi cấu trúc thay đổi. </i>


Trong định nghĩa kiểu bản ghi cho phép có <i>một tr−ờng </i>mμ cấu trúc của
nó tuỳ thuộc một biến lựa chọn bởi câu lệnh <i>Case</i>. Ví dụ, để giải quyết


tr−ờng hợp các nghề nghiệp khác nhau cần ghi các thông tin khác nhau nh−
đã nêu trên ta có thể xây dựng một kiểu bản ghi với tr−ờng <i>NghềNghiệp</i> có
cấu trúc thay đổi nh− sau:



</div>
<span class='text_page_counter'>(102)</span><div class='page_container' data-page=102>

<i>Ngμnh = (KhaiThác, CơKhi, HóaChất, DầuKhí, ĐiệnLực) ; </i>


<i>ChuyênMôn = (Toán,Lý,Hoá,Sinh </i>

)

<i> ; </i>


<i>TrỨnhườ = (CÈSỡ, TrungHoc, ưỈiHồc, ThỈcSị, PTS, TS )</i>

;



<i>HåS¬</i> = RECORD


<i>HọĐệm: String [20] ; </i>
<i>Tên: String [20] ; </i>


CASE <i>NghỊNghiƯp: NghỊ</i> OF


<i>CẬngNhẪn</i>: ( NgμnhCN: Ngμnh ; Bậc: Byte) ;
<i>KịS−:</i> ( NgμnhKS: Ngμnh; TrỨnhườKS: TrỨnhườ);


<i>TrÝThực:</i> (MẬn: ChuyànMẬn ; TrỨnhườTT: TrỨnhườ);


<i>DoanhNh©n</i>: ( ) ;


END ;


Nh− vậy, tr−ờng <i>NghềNghiệp</i> có cấu trúc thay đổi tuỳ theo <i>Nghề</i> lμ gì.


<i>Nghề</i> lμ biến lựa chọn vμ đ−ợc gọi lμ <i>tr−ờng đánh dấu</i>. ứng với mỗi giá trị
của tr−ờng đánh dấu - lμ các nhãn của lệnh <i>Case</i> - ta có các cấu trúc bản ghi
khác nhau thể hiện bằng danh sách tr−ờng nằm trong cặp dấu ngoặc đơn.
L−u ý rằng cú pháp quy định phải có cặp dấu ngoặc đơn dù rằng danh sách
tr−ờng lμ rỗng (xem tr−ơng hợp nghề lμ <i>Doanh Nhân</i>).



Từ khố <i>Case</i> ở đây khơng hoμn toμn giống câu lệnh <i>Case</i> nhiều lựa
chọn đã biết.


3.1.3 <i>Các quy định </i>


- Chỉ đ−ợc phép có một tr−ờng thay đổi. Tuy nhiên các bản ghi có cấu
trúc thay đổi lại có thể lồng nhau.


- Tr−ờng thay đổi phải lμ tr−ờng cuối cùng.


- Trong phần thay đổi tất cả các tên biến không đ−ợc trùng nhau dù lμ
nằm trong hai tr−ờng hợp khác nhau. Trong ví dụ trên ta phải phân biệt


<i>NgμnhCN</i> vợi <i>NgμnhKS</i> cúng nh− phẪn biệt <i>TrỨnhườKS</i> vợi <i>TrỨnhườTT</i> dủ
rÍng chụng thuờc hai tr−ởng hùp khÌc nhau. Nếu lμ hai kiểu bản ghi phẪn
biệt thỨ ró rμng Ẽiều nμy khẬng cần thiết.


<b>3.2 </b> <b>Sử dụng bản ghi có cấu trúc thay đổi. </b>


Về nguyên tắc, truy cập các biến bản ghi cấu trúc thay đổi cũng giống
nh− truy cập bản ghi thông th−ờng. Điểm khác nhau duy nhất lμ ở tr−ờng tuỳ
chọn. Ta phải sử dụng một câu lệnh <i>Case</i> để tuỳ biến theo mỗi tr−ờng hợp.


</div>
<span class='text_page_counter'>(103)</span><div class='page_container' data-page=103>

program VariableRecord;


type Nghe = (CongNhan,KiSu,TriThuc, DoanhNhan);


Nganh = (KhaiThac,CoKhi, HoaChat, DauKhi, DienLuc);
Mon = (Toan,Ly, Hoa, Sinh);



TrinhDo = char; {ki hieu A,B,C,D .. cho don gian}
HoSo = record


HoTen: String[20];
NamSinh: integer;


CASE NgheNghiep: Nghe of


CongNhan: (NganhCN: Nganh; Bac:byte);


KiSu: (NganhKS: Nganh; TrinhDoKS: TrinhDo);
TriThuc:(ChuyenMon: Mon; TrinhDoTT: TrinhDo);
DoanhNhan: ();


END;


var a_cn,b_ks,c_tt,d_dn,v: HoSo;


procedure ShowVariableRecord(v: HoSo);
var ne: Nghe;


nh: nganh;
m: mon;


td: TrinhDo;
begin


With v do
begin



Writeln(' Ho Ten: ', HoTen);
Writeln(' Nam sinh: ', NamSinh);
Write(' Nghe Nghiep: ');


ne:= v.nghenghiep;
case ne of


CongNhan:


begin writeln(' Cong Nhan ');
nh:= v.nganhCN;


case nh of


KhaiThac: write(' Khai thac ');
CoKhi: write (' co khi ');


HoaChat: write(' hoa chat ');
DauKhi: write (' dau khi ');
DienLuc: write (' dien luc ');
end;


writeln(' bac ', v.bac);
end;


<b> KiSu: </b>


begin writeln(' Ki Su ');
nh:= v.nganhKS;


case nh of


KhaiThac: write(' Khai thac ');
CoKhi: .. ..


</div>
<span class='text_page_counter'>(104)</span><div class='page_container' data-page=104>

writeln(' Trinh Do ', v.TrinhDoKS);
end;




TriThuc:


begin writeln (' Tri Thuc , mon ');
m:= v.ChuyenMon;


case m of


Toan: write(' Toan ');
Ly: write(' Ly ');
Hoa: write(' Hoa ');
Sinh: write(' sinh ');
end;


writeln ( ' Trinh do ', v.TrinhDoTT);
end;




<b>DoanhNhan: writeln (' Doanh Nhan '); </b>
end;



end;
end;
BEGIN


with a_cn do
begin


HoTen:= 'Anh Cong Nhan';
Namsinh:= 1971;


NgheNghiep:= CongNhan;
NganhCN:= CoKhi;


Bac:=7;
end;


with b_ks do
begin


HoTen:= 'Nguyen Ki Su';
Namsinh:= 1972;


NgheNghiep:= KiSu;
NganhKs:= DauKhi;
TrinhDoKs:= 'A';
end;


with c_tt do
begin



HoTen:= 'Tran Tri Thuc';
Namsinh:= 1973;


NgheNghiep:= TriThuc;
ChuyenMon:= Toan;
TrinhDoTT:= 'C';
end;


V:= a_cn;


ShowVariableRecord(v);
V:= b_ks;


</div>
<span class='text_page_counter'>(105)</span><div class='page_container' data-page=105></div>
<span class='text_page_counter'>(106)</span><div class='page_container' data-page=106>

<b>Ch−¬ng9 </b>
<b>KiĨu tƯp </b>


<b>1. </b> <b>Các khái niệm và định nghĩa </b>


<b>1.1 </b> <b>Mục đích sử dụng tệp. </b>


Tệp lμ ph−ơng tiện chính để l−u trữ thơng tin. Có thể nói mọi ch−ơng
trình xử lí thông tin đều phải lμm việc với tệp. L−u thông tin ra tệp đặc biệt
cần thiết trong các tr−ờng hợp nh−:


-Khi cần l−u giữ kết quả để dùng v sau.


-Khi có nhiều dữ liệu đầu vo hoặc nhiều kết quả xuất ra.
-Khi chạy thử chơng trình nhiều lần với cùng một dữ liệu vo.
-Khi đầu ra của chơng trình ny phục vụ lm đầu vo của chơng


trình khác, v.v.


Trong nhng trng hp trờn không thể nhập dữ liệu bằng cách gõ trực
tiếp từ bμn phím hay l−u kết quả bằng cách chép lại từ mμn hình mμ phải tổ
chức ghi thμnh các tệp trên đĩa để tiện sử dụng.


<b>1.2 </b> <b> Tệp định kiểu. </b>


Nh− đã nêu ở phần trên, tệp lμ cấu trúc để l−u trữ nhiều dữ liệu. Nếu
tệp l−u các phần tử dữ liệu cùng kiểu thì ta có tệp định kiểu.


- Tệp định kiểu lμ tập hợp các phần tử dữ liệu <i>cùng kiểu</i>, <i>xếp liền nhau</i>;
- Số phần tử hay kích th−ớc của tệp <i>có thể thay đổi </i>trong thời gian thực
hiện ch−ơng trình ;


- Kích thứơc tệp khơng đ−ợc xác định khi khai báo.


1.2.1 <i>Có ph¸p </i>
Khai b¸o kiĨu tƯp


</div>
<span class='text_page_counter'>(107)</span><div class='page_container' data-page=107>

Trong đó kiểu phần tử của tệp gọi lμ <i>kiểu cơ sở</i>, có thể lμ bất kì kiểu gì, trừ
kiểu tệp.


1.2.2


1.3.1


<i>VÝ dô </i>


TYPE <i>TepSoThuc</i> = FILE OF Real ;


<i>TepSoNguyen</i> = FILE OF Integer ;


<i>TepHoSo</i> = FILE OF LyLich ;


VAR F1: <i>TepSoThuc </i>;
F2: <i>TepSoNguyen ;</i>


F3: <i>TepHoSo ;</i>


Còng có thể khai báo tắt, kết hợp khai báo biến với mô tả kiểu tệp:
F1: FILE OF Real ;


F2: FILE OF Integer;
F3: FILE OF LyLich ;


Biến kiểu tệp lμ biến đại diện cho tệp. Mọi việc truy cập tệp đều phải
thơng qua biến tệp.


<b>1.3 </b> <b>TƯp truy cập tuần tự. </b>


<i>Mô tả cấu trúc </i>


Theo nh ngha, tệp lμ tập hợp các phần tử dữ liệu <i>cùng kiểu</i>, <i>xếp liền </i>
<i>nhau</i>, do đó có thể coi tệp nh− một mảng với kích th−ớc co giãn đ−ợc.


Cấu trúc của mảng có khn mẫu cố định nên có thể truy cập trực tiếp
vμo các phần tử qua chỉ số mảng. Trái lại, các phần tử lμm nên tệp khơng
đ−ợc đánh chỉ số, vì có thể bị di chuyển do các thao tác thêm bớt vμo nội
dung.



Tại một thời điểm chỉ có thể truy cập vμo một phần tử thông qua giá trị
của một biến đệm.


Có thể minh hoạ biến đệm nh− một cửa sổ di động dọc theo tệp để
nhìn vμo các phần tử tệp. Tại một thời điểm của sổ nμy nằm ở một vị trí xác
định.


</div>
<span class='text_page_counter'>(108)</span><div class='page_container' data-page=108>

Có dấu hiệu đặc biệt <i>EOF</i> tại vị trí kết thúc tệp vμ hμm chuẩn <i>Eof (F)</i>


cho biết cửa sổ tệp của tệp F đã ở phần tử cuối tệp hay ch−a. <i>Eof (F) = </i>
<i>True</i> nếu đã ở vị trí cuối tệp, <i>Eof (F) = False</i> nếu trỏi li.


Tệp đợc tổ chức nh trên gọi l tƯp truy cËp tn tù - <i>Sequential </i>


<i>access</i>.


Với tệp truy cập tuần tự, muốn đọc một phần tử nμo đó phải đi qua các
phần tử đứng tr−ớc. Muốn thêm một phần tử phải đ−a cửa sổ về cuối tệp.
Hình ảnh của tệp truy cập tuần tự lμ băng từ.


Tóm lại, tệp truy cập tuần tự có cấu trúc đơn giản vμ dễ xây dựng
nh−ng kém linh hoạt.


Pascal chuẩn chỉ định nghĩa tệp truy cập tuần tự. TurboPascal có cung
cấp kiểu tệp truy cập trực tiếp, cho phép đặt của sổ tệp vμo một vị trí bất kì
trong tệp vμ truy cập các phần tử tệp t−ơng tự nh− truy cập mảng.


<b>2. </b> <b>Viết ra tệp, đọc vào từ tệp </b>


<b>2.1 </b> <b>Mở tệp để viết ra. </b>



Nh− đã biết mọi thao tác truy cập tệp trong một ch−ơng trình Pascal đều
phải thơng qua biến tệp. Mặt khác, tệp lμ một đối t−ợng vật lí tồn tại thực sự
trên ổ đĩa. Việc gắn kết một tệp cụ thể trên ổ đĩa với biến tệp đại diện cho nó
trong ch−ơng trình đ−ợc thực hiện bằng thủ tục <i>Assign </i>( <i>biến tệp, tên tệp </i>),
trong đó <i>tên tệp</i> lμ một xâu kí tự gồm đ−ờng dẫn vμ tên tệp để chỉ ra tệp trên
ổ đĩa mμ ta muốn truy cập.


Muốn ghi vμo một tệp phải dùng hai thủ tục liền nhau. Thủ tục đầu tiên
thực hiện việc gắn kết biến tệp với tệp mới đ−ợc tạo ra trên ổ đĩa theo nguyên
tắc chung đã nêu trên. Thủ tục tiếp theo đặt tệp vμo trạng thái sẵn sμng để
viết dữ liệu vμo.


Có ph¸p.


<b>Assign</b> ( biÕn tƯp, tªn tƯp );


<b>Rewrite</b> ( <i>biÕn tƯp</i> );
VÝ dô


</div>
<span class='text_page_counter'>(109)</span><div class='page_container' data-page=109>

Tác dụng: trong th− mục lμm việc hiện hμnh trên đĩa sẽ đ−ợc tạo ra
một tệp mới có tên lμ <i>Luong.Dat</i> ch−a có phần tử nμo. Cửa sổ tệp khơng
xác định vì trỏ vμo <i> EOF</i>.


Chó ý:


- NÕu mn t¹o ra tƯp trong mét th− mục khác thì tên tệp phải bao
gồm cả đờng dÉn.


- Nếu trên đĩa đã có sẵn một tệp trùng tên thì nội dung của tệp nμy sẽ


bị xố. Tệp trở thμnh rỗng.Trong ví dụ trên, nếu đã có sẵn tệp<i> Luong.Dat </i>


trong cïng th mục thì tệp ny sẽ trở thnh rỗng.


<b>2.2 </b> <b>ViÕt d÷ liƯu ra tƯp. </b>


Sau khi tệp đã đ−ợc mở ra sẵn sμng để ghi vμo, thủ tục ghi các mục dữ
liệu vμo tệp có dạng sau.


<b>Write</b> ( <i>biến tệp , biểu thức 1, biểu thức 2 , ... , biểu thức n</i> ) ;
Trong đó các <i>biểu thức 1, biểu thức 2 , ... , biểu thức n</i> lμ các mục dữ liệu
cần ghi vμo tệp. Chúng phải có kiểu lμ kiểu phần tử của tệp.


Tác dụng: thủ tục nμy tính gía trị của <i>biểu thức 1, biểu thức 2... </i>vμ ghi
lần l−ợt vμo tệp bắt đầu từ vị trị hiện hμnh của cửa sổ tệp. Cửa sổ tệp sẽ tự
động dịch chuyển xuống vị trí tiếp theo sau khi ghi xong một mục. Sau lệnh
nμy cửa sổ tệp sẽ tiến thêm <i>n</i> vị trí.


Sau khi ghi xong phải đóng tệp để tránh mất dữ liệu bằng lệnh đóng
tệp:




<b>Close</b> ( <i>biÕn tƯp</i> );
VÝ dơ.


Tạo một tệp có tên lμ <i>Nguyên.Dat</i> chứa các số nguyên <i>n</i> từ 1 đến
100.


Program TaoTep;


Var i: integer;


F: FILE OF Integer;
BEGIN


Assign (F, 'Nguyen.Dat');


Rewrite (F);


For i:=1 to 100 do write (F,i);


Close (F);


</div>
<span class='text_page_counter'>(110)</span><div class='page_container' data-page=110>

<b>2.3 </b> <b>Mở tệp để đọc vào. </b>


Mở tệp để đọc dữ liệu từ tệp vμo bộ nhớ cũng phải dùng hai thủ tục
liền nhau, t−ơng tự nh− trong tr−ờng hợp viết vμo tệp.


Cú pháp.


<b>Assign</b> ( biến tệp, tên tệp );


<b>Reset</b> ( <i>biÕn tÖp</i> );


Tác dụng: tệp đ−ợc mở ra, cửa sổ tệp đặt vμo phần tử đầu tiên, sẵn
sμng để đọc dữ liệu ra. Nếu tệp ch−a tồn tại trên đĩa thì sẽ báo li.


<b>2.4 </b> <b>Đọc dữ liệu vào từ tệp. </b>


Th tục đọc dữ liệu từ tệp rồi gán cho các biến có dạng sau.



<b>Read</b> ( <i>biÕn tƯp, biÕn 1, biÕn 2 , ... , biÕn n</i> );


Lu ý các thnh phần <i>biến 1, biến 2, ... , biến n</i> phải l các biến <i>cùng </i>
<i>kiểu</i> dữ liệu nh kiểu cơ sở của tệp.


Tỏc dụng: đọc giá trị của phần tử mμ của sổ tệp đang trỏ vμo, gán giá
trị đó cho <i>biến 1</i>, dịch cửa sổ xuống vị trí tiếp theo, đọc giá trị của phần tử
t−ơng ứng vμ gán cho <i>biến 2</i>, ... cứ thế cho đến <i>biến n</i>.


Sau khi đọc xong cần đóng tệp bằng lệnh


<b>Close</b> ( <i>biÕn tÖp</i> ) ;


Chú ý: Nếu cửa sổ tệp đã đến cuối tệp mμ vẫn đọc thì sẽ bị lỗi. Do đó
cần có động tác kiểm tra xem đã ở cuối tệp hay ch−a. Chẳng hạn, có thể sử
dụng cấu trúc sau:


IF NOT <i>Eof </i>( <i>biÕn tÖp</i>) THEN Read( <i>biÕn tƯp</i>, X) ;...
Hc: WHILE NOT <i>Eof </i>( <i>biÕn tÖp</i> ) DO


Begin


Read( <i>biÕn tÖp</i> , X);
...


</div>
<span class='text_page_counter'>(111)</span><div class='page_container' data-page=111>

Đoạn ch−ơng trình sau sẽ mở vμ đọc phần tử thứ 2 vμ phần tử thứ 5
của tệp <i>Nguyên.Dat</i> đã tạo ra trong ví dụ tr−ớc, gán vμo hai biến nguyên


<i>p,q</i> t−ơng ứng, sau đó in ra để kiểm tra.


Var p,q : integer;


F: File of Integer ;
BEGIN


Assign (F,'Nguyen.Dat');


Reset (F);


Read (F,p); {đọc phần tử thứ 1 }
Read (F,p); {đọc phần tử thứ 2 }
Read (F,q); {đọc phần tử thứ 3 }
Read (F,q); {đọc phần tử thứ 4 }
Read (F,q); {đọc phần tử thứ 5 }
Close (F);


Writeln ( p,' ',q);
END.


VÝ dơ 2.


Đoạn ch−ơng trình sau sẽ tạo tệp chứa 50 số nguyên sinh ngẫu nhiên,
sau đó đọc từ tệp ra ghi vμo mảng.


Program TepSoNgauNhien;
Var i,p: integer;


F: FILE OF Integer;


a: array [1..50]of integer;


BEGIN


Assign (F, 'Random.int');


Rewrite (F);


Randomize;


For i:=1 to 50 do write (F,random (1000));


Close (F);


.. ..


Assign (F,'Random.int');
Reset (F); i:= 1;


While not eof(F) do
begin


Read (F,p);


a[i]:= p;


i:=i+1;
end;


END.


<b>2.5 </b> <b>TÖp truy cËp trùc tiÕp. </b>



Pascal chuẩn chỉ định nghĩa một kiểu tệp truy cập tuần t.


</div>
<span class='text_page_counter'>(112)</span><div class='page_container' data-page=112>

ny thực hiện đợc vì các phần tử của tệp l cùng kiểu, chiếm chỗ bằng nhau
trong bé nhí.


Thủ tục định vị cửa sổ tệp tại một vị trí cho tr−ớc có dạng sau.


<b>Seek</b> ( biÕn tƯp , vÞ trÝ ) ;


Trong đó <i>vị trí</i> lμ một số ngun, chỉ ra vị trí (thứ tự) của phần tử cần truy
cập trong tệp. <i>Phần tử đầu tiên của tệp ở vị trí 0</i>.


Để đọc / viết vμo một phần tử của tệp truy cập trực tiếp cần các b−ớc
sau:


Mở tệp ở chế độ đọc hoặc ghi t−ơng ứng


Dùng câu lệnh <i>Seek</i> để định vị cửa sổ tệp trỏ vμo phần tử mong muốn.
Sau đó nếu đọc vμo thì dùng thủ tục <i>Read</i>, nếu viết ra tệp thì dùng thủ tục


<i>Write</i> nh− th«ng th−êng.


VÝ dơ.


Ch−ơng trình đọc tệp ở trên nh−ng thay việc thâm nhập tuần tự bằng
thâm nhập trực tiếp


BEGIN



Assign (F,'Nguyen.Dat');


Reset (F);


Seek (F,1); { tìm phần tử thứ 2 }
Read (F,p); { đọc phần tử thứ 2 }
Seek (F,4); { tìm phần tử thứ 5 }
Read (F,q); { đọc phần tử thứ 5 }
Close (F);


Writeln ( p,' ',q);
Readln ;


END.


<b>3.</b> <b>C¸c thao t¸c khác</b>


<b>3.1 </b> <b>Một số hàm và thủ tục với tệp.</b>


Trc khi sử dụng các hμm vμ thủ tục d−ới đây phải thực hiện động tác
gắn kết biến tệp với tệp vật lí trên đĩa bằng câu lệnh <i>Assign.</i>


- <b>FileSize</b> ( <i>biÕn tÖp</i> ): LongInt;


</div>
<span class='text_page_counter'>(113)</span><div class='page_container' data-page=113>

VÝ dô: <i>Assign (F, 'Nguyen .Dat'); </i>


<i> </i> <i> </i> <i>Sz:= FileSize (F)</i> ;


sẽ nhận đợc <i>Sz = 100</i>.



L−u ý: Có thể dùng hμm nμy kết hợp với thủ tục <i>Seek</i> để viết nối thêm
vμo cuối một tệp. (Tác dụng giống nh− lệnh <i>Append</i> vμo cuối tệp kiểu văn
bản)




Seek( <i>biÕn tÖp</i> , FileSize( <i>biÕn tÖp</i> )) ;


Write( <i>biÕn tƯp, biĨu thøc 1, ... , biĨu thøc n</i> );
- <b>FilePos</b> ( <i>biÕn tÖp</i> ): LongInt;


Hm cho biết vị trí hiện tại của cửa sổ tệp. Phần tử đầu tiên ở vị trí 0.
Ví dô: Assign(F, 'Nguyen.Dat')


Reset(F);


I:= FilePos(F); {sÏ cho I = 0 }
- <b>Erase </b>( <i>biÕn tƯp</i> ) ;


Thđ tơc xo¸ tƯp.


VÝ dô: <i>Assign(F, 'Nguyen .Dat'); </i>


<i>Erase(F) </i>


- <b>Rename</b> ( <i>biÕn tƯp , tªn míi</i> ) ;


Thủ tục đổi tên tệp thμnh tên mới. Tên mới nμy phải không đ−ợc trùng
với tên các tệp đã có trong cùng th− mục.



VÝ dơ: <i>Assign(F, 'Nguyen .Dat') </i>
<i> Rename( F, ' So1_100. Int' ) ;</i>




<b>3.2 </b> <b>Bẫy lỗi khi më tÖp. </b>


3.2.1 <i>Đặt vấn đề </i>


Khi thực hiện thao tác mở tệp để đọc / ghi có thể bị lỗi nếu:
- mở tệp ch−a tồn tại trên đĩa, tên sai ...


- hết chỗ trên đĩa để ghi thêm vμo tệp.


TurboPascal cung cấp chỉ thị để trình biên dịch thêm các mã lệnh thực
hiện kiểm tra lỗi trong quá trình thực hiện đọc / ghi tệp mμ d−ới đây sẽ gọi
ngắn gọn lμ chỉ thị kiểm tra I/O.


</div>
<span class='text_page_counter'>(114)</span><div class='page_container' data-page=114>

{ $ I - }: tắt việc kiểm tra I/O. Ch−ơng trình khơng dừng dù có lỗi I/O.
Tuy nhiên nó sẽ bỏ qua (treo, tạm dừng) tất cả các thủ tục vμo/ra sau đó cho
đến khi gặp lời gọi hμm <i>IOResult</i>. <i>IOResult</i> lμ hμm trả về mã lỗi khi thực
hiện các thao tác đọc ghi ra đĩa. Nếu cơng việc thμnh cơng thì mã lỗi lμ 0.
Trái lại, mã lỗi lμ một số khác không.


Sử dụng cơ chế kiểm tra I/O có thể thực hiện việc bẫy lỗi khi mở tệp,
nhất lμ tiến hμnh <i>mở tệp mới an toμn,</i> tránh việc vơ tình xố mất tệp cùng tên
khi mở tệp mới để viết vμo bằng thủ tục <i>Rewrite</i>.


3.2.2



3.2.3


<i>Các b−ớc để mở tệp an toμn. </i>


Tắt chế độ kiểm tra vμ thử mở tệp ra để đọc.
Gọi hμm <i>IOResult</i>.


Nếu <i>IOResult</i> bằng 0, nghĩa lμ mở tệp thμnh công tức lμ đã có tệp


cùng tên. Cần thơng báo cho ng−ời dùng biết để xử lí, nhập lại tên khác
chng hn.


Nếu <i>IOResult </i> khác không nghÜa lμ ch−a cã tƯp nμo cã tªn nh− thÕ. Có
thể yên tâm tạo tệp bằng lệnh <i>Rewrite.</i>


<i>VÝ dơ minh ho¹. </i>


Assign( biÕn tƯp , tªn tƯp);
{$I-}


Reset( <i>biÕn tƯp</i> );
{$I+}


If IOResult <> 0 then {không có tệp no trùng tên}
Begin


Writeln(' Ban muon tao tep moi ? Enter=Yes ');
if ReadKey = #13 then Rewrite( <i>biÕn tÖp</i> )


else exit;


end;


Else
Begin


Writeln(' Da co tep trung ten '); ....
End;


</div>
<span class='text_page_counter'>(115)</span><div class='page_container' data-page=115>

<b>4. </b> <b>Tệp văn bản. </b>


<b>4.1 </b> <b>Định nghĩa và cấu trúc. </b>


Tp vn bản lμ một kiểu tệp phổ biến, đã đ−ợc định nghĩa sẵn, để l−u
trữ xử lí các "văn bản". Khái niệm “văn bản” ở đây khác với khái niệm văn
bản thơng th−ờng trong các phần mềm xử lí văn bản. “Văn bản” ở đây chỉ
gồm các kí tự ASCII vμ đ−ợc phân thμnh các dòng. Ngoμi ra, khơng có bất
cứ định dạng nμo khác về trình bμy nh− cỡ chữ, kiểu chữ, mμu sắc, v.v.


4.1.1


4.1.2


<i> Có ph¸p. </i>


Kiểu tệp văn bản đã đ−ợc định nghĩa sẵn với tên chuẩn lμ <i>Text</i>. Ta
khơng cần phải khai báo kiểu.


Có ph¸p khai báo <i>biến</i> tệp văn bản:


<b>Var</b> <i>biÕn tƯp</i>: <b>Text ;</b>



VÝ dơ.


VAR <i>F1, F2 : Text</i> ;
<i> CÊu tróc. </i>


Thμnh phÇn chÝnh cđa tệp văn bản l các kí tự ASCII. Tuy nhiên, tệp
văn bản đợc chia thnh các dòng. Đánh dấu hết dòng bằng dấu <i>Eoln</i> (<i>end </i>


<i>of line</i>). Đó l cặp kí tự CR (<i>cariage return)</i> - nhảy về đầu dòng, mà ascii


lμ 13 - vμ LF (<i>line feed)</i> - nhảy xuống dòng d−ới, mã ascii lμ 10.
Dấu hết tệp <i>Eof</i> đối với tệp văn bản lμ <i>Ctrl-Z</i> có mã ascii lμ 26.
Trong mơi tr−ờng DOS có thể dùng lệnh <i>Type</i> để hiển thị nội dung
của tệp văn bản lờn mn hỡnh.


Tệp văn bản không phải l tệp c¸c kÝ tù <i>File of Char</i>. <i>File of Char</i>
kh¸c víi tƯp kiĨu <i>Text </i> ở chỗ nó không nhận biết cặp kÝ tù CR, LF nh− dÊu
hÕt dßng mμ coi nh− hai kÝ tù ascii b×nh th−êng.


VÝ dơ.


TƯp <i>TieuDe.txt</i> chøa ba dßng
CH XHCN VIETNAM
Doc lap - Tu do - Hanh phuc
*****


Néi dung cđa tƯp lμ d·y kÝ tù liªn tiÕp nh− sau


</div>
<span class='text_page_counter'>(116)</span><div class='page_container' data-page=116>

<b>4.2 </b> <b>Viết ra tệp văn bản </b>



Cú th ghi cỏc giỏ trị kiểu <i>nguyên, thực, logic, xâu kí tự</i> ra tệp văn bản
bằng các lệnh <i>Write</i>. Các thủ tục <i>Write</i> viết ra tệp văn bản sẽ tự động tính
các biểu thức vμ chuyển đổi các giá trị sang dạng biểu diễn xâu kí tự thơng
th−ờng để có thể ghi vμo tệp văn bản.


<b>Write </b>( <i>biÕn tƯp , biĨu thøc 1, biĨu thøc 2 , ... , biÓu thøc n</i> ) ;


<b>Writeln </b>( <i>biÕn tƯp , biĨu thøc 1, biÓu thøc 2 , ... , biÓu thøc n</i> );


<b>Writeln </b>( <i>biÕn tÖp</i> );


Sau các biểu thức có thể kèm phần định dạng (quy cách) in ra.
Tác dụng của các câu lệnh trên hoμn toμn t−ơng tự nh− trong tr−ờng
hợp xuất ra mμn hình đã trình bμy ở Ch−ơng 3. Chỉ khác lμ ở đây khơng phải
in ra mμn hình mμ lμ viết ra tệp văn bản ứng với <i>biến tệp</i>. Về bản chất, mμn
hình cũng giống nh− một tệp văn bản.


VÝ dô.


F: TEXT;


i,j: Integer;


X: Real;


B: Boolean;
St: String [8];


Write(F, (i+ j):5, 3*X:0:2, St:10, ' The End ');



<b>4.3 </b> <b>Đọc vào từ một tệp văn bản. </b>


4.3.1 <i>Cú ph¸p. </i>


Các thủ tục <i>Read</i> quen biết có thể đọc từ tệp văn bản rồi gán cho các
biến khơng những các kí tự mμ cả các kiểu dữ liệu khác nữa: số nguyên, thực,
logic .... Thủ tục <i>Read</i> sẽ tự động chuyển đổi các xâu kí tự biểu diễn dữ liệu
thμnh giá trị có kiểu t−ơng ứng của biến sẽ đ−ợc gán


<b>Read</b> ( <i>biÕn tÖp , biÕn 1 , biÕn 2 , ... , biÕn n </i>);


<b> Readln</b> ( <i>biÕn tÖp , biÕn 1 , biÕn 2 , ... , biÕn n</i> ) ;


</div>
<span class='text_page_counter'>(117)</span><div class='page_container' data-page=117>

Tác dụng: hoμn toμn giống nh− các lệnh đọc dữ liệu từ bμn phím đã
quen biết, chỉ khác lμ ở đây không phải nhập dữ liệu từ bμn phím mμ các mục
dữ liệu đã viết sẵn trong tệp văn bản ứng với <i>biến tệp</i>.


Tuỳ theo kiểu của <i>biến i</i> mμ lệnh <i>Read</i> thực hiện đọc một dãy kí tự từ
tệp văn bản, chuyển đổi nó thμnh một <i>giá trị</i> <i>trực tiếp</i> thuộc kiểu dữ liệu của


<i>biÕn i</i> vμ g¸n cho biÕn nμy.


Quy định về phân cách các mục dữ liệu kiểu số, kiểu kí tự, kiểu xâu kí
tự đã đ−ợc trình bμy chi tiết trong Ch−ơng 3.




4.3.2 <i> VÝ dơ. </i>



D−ới đây lμ đoạn ch−ơng trình minh hoạ quy cách đọc vμo từ tệp văn
bản. Kết quả thực hiện các thủ tục <i>Read</i> đ−ợc viết trong phần chú thích sau
mỗi câu lệnh. Đầu vμo của ch−ơng trình lμ tệp <i>vanban.txt</i> có nội dung nh−
hình sau


abcdefg hiklm
-3.2


1.5 2


var f: text;
x: real;


i: integer;


s1,s2,s3: string[5];
S : string;



begin


assign(f,'vanban.txt');
reset(f);


read(f,x); { x:= 1.5 }


read(f,i); { i:= 2 }


readln(f,x); { x:= -3.2 vμ xuèng dßng}



read(f,s1); { s1:= 'abcde' }


read(f,S); { S:= 'fg hiklm' , không xuống dòng}


read(f,s2); { s2:= '' xâu rỗng }


readln(f);


read(f,s3); { s3:= 'nnnnn' }


...
end.


<b>4.4 </b> <b>Các hàm, thủ tục chuẩn khác cho tệp văn b¶n </b>


</div>
<span class='text_page_counter'>(118)</span><div class='page_container' data-page=118>

- <b>Eof</b>( <i>biÕn tƯp</i> ): boolean ;


Kiểm tra đã ở cuối tệp ch−a.


- <b>Eoln</b> ( <i>biÕn tÖp</i> ): boolean ;


Kiểm tra đã ở cuối dòng ch−a.
- <b>Append</b> ( <i>biến tệp</i> );


Mở tệp văn bản để viết vμo, của sổ tệp đặt tại cuối tệp.
- <b>SeekEoln</b>( <i>biến tệp</i> ): boolean ;


T−¬ng tù nh− <i>Eoln</i> nh−ng trớc khi kiểm tra nó nhảy qua các dấu
cách vμ dÊu Tab. <i>SeekEoln </i> cho kÕt qu¶ <i>True</i> nÕu trên phần còn lại của dòng,
kể từ vị trí hiện tại, không còn mục dữ liệu no nữa.



- <b>SeekEof</b>( <i>biÕn tÖp</i> ): boolean ;


T−ơng tự nh− Eof nh−ng tr−ớc khi kiểm tra nó nhảy qua các dấu cách,
dấu Tab vμ dấu xuống dòng.<i> SeekEof </i> cho kết quả True nếu từ vị trí hiện tại
đến cuối tệp khơng cịn mục dữ liệu nμo nữa.


<b>- Flush</b>( <i>biÕn tÖp</i> );


Xả hết nội dung bộ đệm của một tệp kiểu văn bản đang đ−ợc mở để
viết vμo.


F lμ mét biÕn kiểu tệp văn bản <i>Text</i>, đợc mở bằng <i>Rewrite</i> hc


<i>Append</i> để viết ra. Khi đó lời gọi <i>Flush</i> sẽ xả hết phần nội dung còn đọng


trong bộ đệm, viết nốt ra tệp F. Thủ tục nμy đ−ợc dùng để đảm bảo rằng mọi
lệnh viết ra tệp F đều đ−ợc thực hiện trọn vẹn, khơng bỏ sót dữ liệu.


<i>Flush</i> khơng có tác dụng nếu tệp F đựơc mở để đọc.


- <b>SetTextBuf</b>( <i>biến tệp, vùng đệm, kích th−ớc </i>);


Gán một vùng đệm I/O cho tệp văn bản. Tham biến <i>Vùng đệm</i> lμ một
vùng trong bộ nhớ dùng lμm trung gian, tạm chứa dữ liệu trong các thao tác
truy cập đọc ra hoặc viết vμo tệp trên ổ đĩa. Tham trị <i>kích th−ớc</i> lμ tuỳ chọn,
có thể khơng có mặt.


Thủ tục nμy th−ờng dùng để tăng kích th−ớc vùng đệm nhằm đẩy
nhanh tốc độ trao đổi dữ liệu với ổ đĩa. Ta đã biết tốc độ truy cập đĩa chậm


hơn nhiều so với truy cập bộ nhớ trong. Nếu có một vùng đệm thì các thao
tác xử lí đọc / viết tạm ra đây. Khi đầy vùng đệm mới tiến hμnh thao tác đọc /
viết thực sự ra đĩa, không lμm lắt nhắt nhiều lần.


<i>SetTextBuf</i> không nên gọi cho tệp đang mở vμ đã có thao tỏc trao i


dữ liệu. Nó có thể đợc gọi ngay sau <i>Reset, Rewrite,</i> hay <i>Append.</i> NÕu gäi


<i>SetTextBuf</i> cho tệp đang mở thì khi có thao tác I/O , có thể bị mất dữ liệu do


kích th−ớc của vùng đệm thay đổi.
Ví dụ.


</div>
<span class='text_page_counter'>(119)</span><div class='page_container' data-page=119>

var


F: Text;
Ch: Char;


Buf: array[1..4095] of Char; { 4K buffer }
begin


{Lấy tên tệp từ tham số dòng lệnh}
Assign(F, ParamStr(1));


{Tăng bộ đệm lớn để đọc nhanh}
SetTextBuf(F, Buf);


Reset(F);


{§−a toμn bé nội dung tệp văn bản ra mn hình}


while not Eof(f) do


begin


Read(F, Ch);
Write(Ch);
end;


end.


<b>4.5 </b> <b>C¸c thiết bị vào ra chuẩn </b>


Bn phím v mn hình l các thiết bị vo / ra chuẩn nh đợc coi nh
tệp văn bản, có thể sử dụng m không cần khai báo.


OUTPUT


L tp xut chuẩn, đ−ợc tự động gắn cho mμn hình.


NÕu trong các câu lệnh <i>Write</i> không chỉ rõ <i>biÕn tƯp</i> th× cã nghÜa lμ
sư dơng tệp xuất chuẩn <i>Output</i>. Đó l lí do tại sao khi in ra mμn h×nh cã thĨ
bá qua thnh phần biến tệp. Câu lệnh có dạng


<b>Write</b> ( <i>biÓu thøc 1, biÓu thøc 2 , ... , biỴu thøc n</i> ) ;
INPUT


Lμ tệp vμo chuẩn, đ−ợc tự động gắn cho bμn phím.


T−¬ng tù nh− víi lƯnh xt ra, nếu trong các câu lệnh <i>Read</i> không chỉ
râ biÕn tƯp th× cã nghÜa lμ sư dơng tƯp vo chuẩn.



<b>LST</b> l tệp xuất gắn với máy in.


Để in ra máy in từ trong một chơng trình Pascal cần chỉ rõ <i>biến tệp </i>


bây giờ l máy in.


</div>
<span class='text_page_counter'>(120)</span><div class='page_container' data-page=120>

<b>5. </b> <b>Tp khụng nh kiu. </b>


<b>5.1 </b> <b>Định nghĩa và cÊu tróc. </b>


Tệp khơng định kiểu - <i>Untyped File</i> - lμ tệp không định rõ kiểu của
phần tử khi khai báo, coi dữ liệu chính lμ các mã nhị phân 0,1 khơng cần
biết nó biểu thị cái gì. Đơn vị xử lí lμ từng khối bít, có kích th−ớc do ta quy
định, gọi lμ các Record. L−u ý rằng record ở đây không phải lμ kiểu bản ghi
nh− đã biết.


Tệp không định kiểu chủ yếu dùng để tăng tốc độ thao tác vμo ra dữ
liệu.


<b>Có ph¸p. </b>


Khai b¸o: dïng tõ kho¸ FILE


<b>Var</b> <i>biÕn tÖp</i> : <b>File ; </b>


Truy cập: Các thủ tục <i>Reset, Rewrite</i> đối với tệp khơng định kiểu cần
có thêm tham trị <i>kich th−ớc Rec</i>. Tham trị <i> kích th−ớc Rec</i> lμ một số nguyên
(kiểu <i>Word</i>) để ấn định kích th−ớc của khối dữ liệu đơn vị (record) trong các
thao tác tệp. Kích th−ớc nμy tính theo byte.



<b>Reset</b> ( <i>biÕn tƯp , kÝch th−íc Rec</i> );


<b>Rewrite</b> ( <i>biÕn tƯp , kÝch th−íc Rec</i> );
VÝ dô.


Reset(F,4); đọc ra từng khối 4 byte một.
Rewrite(F,2); viết vμo từng khối 2 byte một.


Nếu tham số nμy khơng có mặt thì record có kích th−ớc mặc định lμ


<i>128</i> byte.


<b>5.2 </b> <b>C¸c hàm, thủ tục khác. </b>


Ngoi ra, tng nhanh tốc độ xuất nhập dữ liệu, cịn có hai thủ tục
dμnh riêng cho tệp không định kiểu lμ <i>BlockRead</i> vμ <i>BlockWrite</i>.


<b>BlockRead</b>( <i>biến tệp , vùng đệm , số Rec , kết quả</i> );


<i>Vùng đệm</i>: vùng đệm trong bộ nhớ, lμ một tham biến, nơi chứa dữ liệu


đọc vμo


</div>
<span class='text_page_counter'>(121)</span><div class='page_container' data-page=121>

<i>Kết quả</i> : tham biến kiểu <i>Word,</i> lμ số khối thực đọc đ−ợc.
Tác dụng.


<i>BlockRead</i> đọc một l−ợng <i>số Rec</i> khối bit từ tệp ứng với <i>biến tệp</i> rồi


ghi vμo bộ nhớ, bắt đầu từ byte thứ nhất của <i>Vùng đệm</i>. Số khối bit thực sự


đọc đ−ợc đ−ợc trả về trong biến <i>kết qủa</i>. L−u ý rằng số khối bít thực sự đọc
đ−ợc có thể bé hơn <i>sơ Rec</i> dự định đọc nếu đã đến cuối tệp.


Nếu không có tham biến <i>kết qủa</i> thì khi số khối thực sự đọc đ−ợc
không bằng <i>số Rec</i> sẽ có lỗi I/O xảy ra.


Số byte đọc đ−ợc nhiều nhất lμ <i> số Rec</i> * <i>kích th−ớc Rec</i>, ở đây <i>kích </i>


<i>th−íc Rec</i> lμ kÝch th−íc cđa khèi. KÝch th−íc khèi lμ sè l−ỵng byte trong mét


khối, đ−ợc ấn định khi mở tệp nh− đã trình bμy ở trên.


NÕu <i>sè Rec</i> * <i>kÝch th−íc Rec</i> > 65,535 (64K) thì sẽ có lỗi.


<b>BlockWrite</b>( <i>bin tp , vùng đệm , số Rec , kết quả</i> );


<i>Vùng đệm</i>: vùng đệm trong bộ nhớ, lμ một tham biến, nơi chứa dữ liệu


để xuất ra.


<i>Sô Rec</i> : tham trị kiểu Word, lμ số khối dự định xuất ra.


<i>KÕt qu¶</i> : tham biÕn kiÓu Word, lμ sè khèi thùc sù xuÊt ra đợc.


Y nghĩa của các tham số v công dơng cđa <i>BlockWrite</i> cịng t−¬ng tù
nh− <i>BlockRead</i> ở trên. Chỉ có thao tác truy cập ở đây lμ <i>viÕt tõ bé nhí ra tƯp</i>.
VÝ dơ


Ch−¬ng trình dới đây minh hoạ cách dùng <i>BlockRead, BlockWrite.</i>



Nú thc hiện sao chép tệp nhanh, đơn giản không kiểm tra lỗi.
program CopyFile;


var


FromF, ToF: file;


NumRead, NumWritten: Word;
Buf: array[1..2048] of Char;
begin


Assign(FromF, ParamStr(1)); { Mo tep du lieu vao}


Reset(FromF, 1); { Record size = 1 }


Assign(ToF, ParamStr(2)); { Mo tep du lieu ra}


Rewrite(ToF, 1); { Record size = 1 }


Writeln('Copying ', FileSize(FromF), ' bytes...');
repeat


BlockRead(FromF, Buf, SizeOf(Buf), NumRead);
BlockWrite(ToF, Buf, NumRead, NumWritten);
until (NumRead = 0) or (NumWritten <> NumRead);
Close(FromF);


</div>
<span class='text_page_counter'>(122)</span><div class='page_container' data-page=122>

C©u hái vμ bμi tËp


1. Tệp văn bản có thể dùng để đọc/viết các kiểu dữ liệu nμo. Tệp đinh


kiểu có thể dùng để đọc/viết các kiểu dữ liệu nμo. Khi chỉ có mơt kiểu
dữ liệu thì tệp kiểu nμo sẽ đ−ợc thao tác nhanh hơn.


2. Những hμm, thủ tục nμo chỉ áp dụng cho tệp định kiểu mμ không áp
dụng đ−ợc cho tệp văn bản vμ ngc li.


3. Khi no thì trong phần khai báo bién không có biến tệp. Khi no thì
trong phần khai báo kiểu không có kiểu tệp.


4. Khi no tệp có thể l một tham trị trong danh sách tham số của chơng
trình con.


5. S ln nhất các bản ghi có thể viết vμo một tệp lμ bao nhiêu.
6. Tệp không định kiểu đặt ra nhằm mục đích gì.


Thùc hμnh.


1. Viết ch−ơng trình tạo tệp <i>Ran100.int </i>chứa 100 số nguyên d−ơng i đ−ợc
sinh ngẫu nhiên (0 < i <= 50). In nội dung tệp nay ra mμn hình thμnh
10 dịng. b) Lấy tệp nμy lμm đầu vμo để nhập ma trận. Hai số đầu tiên
lấy lμm số hμng, số cột của ma trận, tiép theo lμ các phần tử ma trận,
nếu thiếu thì gán giá trị bằng khơng.


2. Viết ch−ơng trình nhân hai ma trận với dữ liệu đọc từ tệp vμ kết quả in
ra tệp. a) Dùng tệp số nguyên vμ ma trận nguyên. b) Dùng tệp số thực
với ma trận thực. c) Dùng tệp văn bản.


3. Thùc hiƯn s¾p xÕp hoμ nhËp hai ®−êng: ®Çu vμo lμ 2 tƯp sè thùc cã thø
tự tăng dần. Tẹp kết quả l trộn của hai tệp, cũng có th tự tăng dần.
4. Viết chơng trình thống kê số lần xuất hiện của 26 chữ cái trong một



tệp văn bản.


5. Viết chơng trình thống kê số lần xuất hiện của một từ cho trớc trong
tệp văn bản.


6. vit chng trỡnh đếm số từ trong tệp văn bản. chuẩn hoá lại tệp để các
từ cách nhau không quá một khoảng trắng (từ lμ một cụm kí tự khơng
chứa các dấu cách nh− khoảng trắng, tab, xuống dòng) nằm giữa hai
dấu cách.


</div>
<span class='text_page_counter'>(123)</span><div class='page_container' data-page=123>

<b>Ch−¬ng10 </b>
<b>Chơng trình con </b>


<b>1. </b> <b>Chơng trình con - Hàm và thủ tục </b>


<b>1.1 </b> <b>Tại sao cần sử dụng chơng trình con. </b>


- Trong một chơng trình có thể có những phần công việc phải lặp đi
lặp lại nhiều lần, với các dữ liệu đầu vo l khác nhau. Để tránh viết lại các
đoạn chơng trình dùng nhiều lần, ta cần tổ chức thnh các chơng trình con.


- Cú mt s chng trỡnh hay dùng, đã d−ợc xây dựng hoμn chỉnh
thμnh các ch−ơng trình mẫu. Cần tổ chức thμnh th− viện các ch−ơng trình con
để sử dụng lại sau nμy. Ví dụ, Turbo Pascal đã có th− viện các hμm mẫu: <i>sin, </i>


<i>cos, tan, sqrt... </i>Ngời lập trình có thể xây dựng thêm các chơng trình con


khỏc, vớ d tính các biểu thức hay gặp, tạo bảng chọn, vẽ đồ thị ...
- Khi phát triển một phần mền cỡ lớn vμ phức tạp thì tất yếu lμ phải


chia lμm nhiều mô đun nhỏ độc lập nhau, giao cho các nhóm phát triển độc
lập. Một ch−ơng trình lớn lμ cấu trúc phối hợp nhiều ch−ơng trình con.


- Ngay cả khi chơng trình không phải l quá di thì việc tổ chức
thnh các chơng trình con còn có tác dụng hỗ trợ, lm cho việc quản lý, gỡ
rối, bảo trì tiện lợi v dễ dng hơn.


<b>1.2 </b> <b>Khai báo chơng trình con. </b>


Trong Pascal các ch−ơng trình con cần phải đ−ợc khai báo vμ triển
khai đầy đủ tr−ớc khi có thể sử dụng. Trong khung cấu trúc một ch−ơng
trình Pascal, phần dμnh cho khai báo vμ xây dựng các ch−ơng trình con lμ ở
sau phần khai báo nhãn, hằng, kiểu, biến vμ ở ngay tr−ớc phần thân ch−ơng
trình chớnh.


<b>Program</b> <i>Tên chơng trình</i>;


</div>
<span class='text_page_counter'>(124)</span><div class='page_container' data-page=124>

<b>Label</b> ... ;


<b>Const</b> ... ;


<b>Type</b> ... ;


<b>Var</b> ...;


Phần dnh cho các chơng trình con;


BEGIN


<i>Các câu lệnh ; </i>



END.


Chơng trình con gồm có hai loại, gọi l hm v thủ tục, đợc xây
dựng theo khung cÊu tróc nh− sau.


<b>function</b> <i>Tªn hμm ( Danh sách các tham số hình thức): Kiểu dữ liệu trả về;</i>




<i>Các khai báo hằng, kiểu, biến cđa riªng hμm nμy; </i>


<i> Các chơng trình con dùng trong hm ny; </i>


Begin


<i>Các câu lệnh của hm; </i>


<i> .... </i>


<i>tên hm:= giá trị trả về ; </i>


End;


<b>Procedure</b> <i>Tên thủ tục ( Danh sách các tham số hình thức) ; </i>
<i> </i>


<i>C¸c khai b¸o h»ng, kiĨu, biÕn của riêng thủ tục ny; </i>


<i> Các chơng trình con dùng trong thủ tục ; </i>



Begin


<i>Các câu lệnh của thủ tục; </i>


End;


Phân tích chi tiết từng thnh phần nh− sau.


</div>
<span class='text_page_counter'>(125)</span><div class='page_container' data-page=125>

Danh s¸ch c¸c tham sè hình thức l một dÃy các khai báo dạng <i> tên </i>


<i>tham số: kiểu dữ liệu </i>cách nhau dấu chÊm phÈy “ ; ”. Tr−íc tªn tham sè cã


thể có từ khố VAR để chỉ thị cách truyền theo tham biến (ý nghĩa của nó sẽ
giải thích sau). Nếu có vμi tham số cùng kiểu dữ liệu thì có thể khai báo
chung. Nếu danh sách tham số lμ <i>rỗng</i> thì có thể bỏ cả hai dấu ngoặc đơn.


Tóm lại, với mỗi ch−ơng trình con, dũng u tiờn nhm mc ớch khai


bá<i>o tên v "kiểu</i>" của chơng trình con. Kiểu của chơng trình con ở đây bao


gồm: chơng trình con loại gì, hm hay thủ tục; có bao nhiêu tham số dữ liệu
đầu vo, đầu ra v kiểu của các tham số ấy.


Ví dụ về dòng khai báo nguyên mẫu của chơng trình con:
Procedure <i>NhapSoLieu</i>;


Function <i>MaxDay</i>( SoPhanTu: word; Var A: MangSoNguyªn):
integer ;



Procedure <i>GiaiPTBacHai</i>(a,b,c: real ; Var Nghiem_1, Nghiem_2:
real);


....


<b>1.3 </b> <b>Xây dựng chơng trình con </b>


Sau dũng khai bỏo nguyên mẫu (tên vμ kiểu) lμ phần triển khai chi tiết
ch−ơng trình con. Phần nμy có cấu trúc <i>hoμn toμn t−ơng tự</i> nh− của một
ch−ơng trình Pascal bình th−ờng. Bắt đầu cũng lμ các khai báo (units, hằng,
kiểu, biến, ...) của riêng ch−ơng trình con. Sau đó lμ phần thân ch−ơng trình
con gồm các câu lệnh nằm giữa hai từ khoá <i>Begin, End.</i> Chú ý rằng tr−ớc khi
bắt đầu phần thân ch−ơng trình con lại có thể có các ch−ơng trình con của
chính ch−ơng trình con nμy. Khái niệm ch−ơng trình con có tính <i> quy</i>.


Các chơng trình con kết thúc bằng <i>End</i> với <i>dấu chấm phẩy</i> chứ không
phải dấu chấm nh chơng trình chính.


Nếu chơng trình con l một hm thì trong phần thân, trớc khi kết
thúc phải có câu lệnh dạng


<i>tên hm:= giá trị trả về ; </i>


<b>1.4 </b> <b>Lời gọi chơng trình con. </b>


Để cho thực hiện một chơng trình con, ta cần viết mét lêi gäi. Lêi gäi
hμm, thđ tơc cã d¹ng chung nh sau


<i>Tên hm ( Danh sách các tham sè thùc sù ); </i>



</div>
<span class='text_page_counter'>(126)</span><div class='page_container' data-page=126>

Trong lời gọi hμm, thủ tục thì danh sách các tham số thực sự phải
t−ơng ứng một - một với danh sách tham số hình thức: đúng số l−ợng, thứ tự
vμ kiểu dữ liệu.


Tại một điểm trong ch−ơng trình chính, khi gặp lời gọi ch−ơng trình
con thì ch−ơng trình chính tạm dừng. Các tham số hình thức sẽ đ−ợc gán các
giá trị hiện tại của tham số thực sự vμ các lệnh xử lí trong thân ch−ơng trình
con đ−ợc tiến hμnh. Khi kết thúc ch−ơng trình con, điều khiển sẽ đ−ợc trả về
cho ch−ơng trình chính vμ cơng việc của ch−ơng trình chính tiếp tục lại từ
chỗ tạm dừng để nhảy vμo ch−ơng trình con.


Dới đây l ví dụ lời gọi các chơng trình con đợc khai báo nh nêu
trên.


<i>NhapSoLieu; </i>


Lời gọi thủ tục ny sẽ cho thực hiện lần lợt các lệnh trong thân thủ


tc <i>NhapSoLieu</i> ging nh ta chèn toμn bộ các câu lệnh đó vμo đúng chỗ mμ


lêi gäi cã mỈt.


<i>TuoiCaoNhat:= MaxDay( 50, Tuoi ); </i>


Khi thực hiện lời gọi hμm nh− trên, tham số <i> SoPhanTu</i> sẽ đ−ợc gán
trị 50, <i>Tuoi</i> phải lμ mảng số nguyên có 50 phần tử. Ch−ơng trình con sẽ tìm
giá trị cực đại của mảng <i>Tuoi</i> vμ gán cho biến <i>TuoiCaoNhat</i>.


<i>GiaiPTBacHai( 2.3, -0.5, 1.0, x1, x2); </i>



Lời gọi thủ tục nμy sẽ có tác dụng gán <i>a:=2.3; b:=-0.5, c:=1.0.</i> Sau
đó giải ph−ơng trình bậc hai với ba hệ sơ <i>a,b,c</i> có giá trị nh− trên vμ đặt kết
quả vμo <i>x1, x2</i> lμ các biến thực đã đ−ợc khai báo tr−ớc đó.


<b>1.5 </b> <b>VÝ dơ minh ho¹. </b>


Hãy viết một ch−ơng trình nhập vμo hai dãy số liệu lμ nhiệt độ cao
nhất vμ nhiệt độ thấp nhất của từng ngμy trong một tuần. Tìm vμ in ra nhiệt
độ cao nhất, thấp nhất trong tuần.


Nếu không sử dụng ch−ơng trình con ta sẽ viết một ch−ơng trình đại
loại nh− sau


const kt_mang = 7;


type MangSoThuc = array [1..kt_mang] of real;
var NhietDoCao, NhietDoThap: MangSoThuc;


m,max,min: real;
i: integer;


</div>
<span class='text_page_counter'>(127)</span><div class='page_container' data-page=127>

write('Cho day nhiet do cao:');
for i:=1 to kt_mang do


read(NhietDoCao[i]);


write('Cho day nhiet do thap:');
for i:=1 to kt_mang do


read(NhietDoThap[i]);


m:= NhietDoCao[1];


for i:=2 to kt_mang do


if NhietDoCao[i]> m then m:= NhietDoCao[i];
max:= m;


m:= NhietDoThap[1];
for i:=2 to kt_mang do


if NhietDoThap[i] < m then m:= NhietDoThap[i];
min:= m;


Writeln('Nhiet do cao nhat trong tuan la', max:3:1);
Writeln('Nhiet do thap nhat trong tuan la', min:3:1);
END.


Ta nhận thấy rằng ch−ơng trình trên bao gồm 4 phần cơng việc rõ rμng,
trong đó việc nhập dãy số liệu ban đầu đ−ợc lặp lại hai lần giống nhau. Có
thể tổ chức lại ch−ơng trình trên phân thμnh các ch−ơng trình con. Mỗi
ch−ơng trình con đảm nhận một phần cơng việc. Đó lμ:


Thủ tục nhập mảng một chiều. Thủ tục nμy sẽ đ−ợc gọi để thực hiện
việc nhập dãy 2 số liệu đầu vμo.


Hμm tính giá trị lớn nhất của các phần tử mảng một chiều. Hμm sẽ
đ−ợc gọi để tính nhiệt độ cao nhất.


Hμm tính giá trị nhỏ nhất của các phần tử mảng một chiều. Hμm sẽ
đ−ợc gọi để tính nhiệt độ thấp nhất.



Ch−ơng trình chính bây giờ chỉ gồm vμi dịng lệnh lμ các lời gọi
ch−ơng trình con, giống nh− bản liệt kê những cơng việc chính cần lμm. Nó
trở nên đơn giản, sáng sủa vμ dễ hiểu hơn nhiều.


const kt_mang = 7;


type MangSoThuc = array [1..kt_mang] of real;
var NhietDoCao, NhietDoThap: MangSoThuc;


max,min: real;


procedure nhap_mang(var v: MangSoThuc);
var i: integer;


begin


</div>
<span class='text_page_counter'>(128)</span><div class='page_container' data-page=128>

function max_mang( v: MangSoThuc): real;


var i: integer;


m: real;
begin m:=v[1];


for i:=2 to kt_mang do


if v[i]>m then m:=v[i];
max_mang:= m;


end;



function min_mang( v: MangSoThuc): real;


var i: integer;


m: real;
begin m:=v[1];


for i:=2 to kt_mang do


if v[i]< m then m:=v[i];
min_mang:= m;


end;


BEGIN


Writeln('Cho day nhiet do cao');
nhap_mang(NhietDoCao);writeln('');
Writeln('Cho day nhiet do thap');
nhap_mang(NhietDoThap);writeln('');
Max:= max_mang(NhietDoCao);


Min:= min_mang(NhietDoThap);


Writeln('Nhiet do cao nhat trong tuan la', max:3:1);
Writeln('Nhiet do thap nhat trong tuan la', min:3:1);
END.


<b>2. </b> <b>Hµm hay thủ tục, tham biến hay tham trị. </b>



<b>2.1 </b> <b>Phân biệt hàm với thủ tục. </b>


Kết quả cuối cùng của một hm l trả về <i>một giá trị mới</i>. Trong thân
hm luôn phải có lệnh gán <i>tên hm:= giá trị trả về</i> . Chính tên hm ny coi
nh một biến, dùng lm nơi chứa giá trị trả về.


Th tc khụng cú phn gớa tr trả về. Nh− thế khơng có nghĩa lμ nó
khơng tạo ra kết quả gì. Kết quả của một thủ tục lμ lμm thay đổi giá trị của
một hay nhiều biến đã tồn tại tr−ớc khi gọi thủ tục.


VÝ dơ:


</div>
<span class='text_page_counter'>(129)</span><div class='page_container' data-page=129>

- Tìm phần tử cực đại của một dãy số <i>nên</i> <i>lμ một hμm vì ch−ơng trình </i>
con nμy sẽ trả về giá trị lớn nhất của các phần tử trong dãy


<b>2.2 </b> <b>Phân biệt tham biến và tham trị. </b>


Các tham số trong danh sách tham số hình thức của chong trình con
chia lm hai loại, tuỳ theo cách truyền giá trị từ chơng trình chính gọi nó.


Loi th nhất lμ tham số đ−ợc truyền theo giá trị hay gọi tắt lμ <i>tham trị</i>.
Truyền theo giá trị nghĩa lμ chép lại giá trị của biến từ ch−ơng trình chính tại
thời điểm gọi ch−ơng trình con để sử dụng trong ch−ơng trình con, khơng
thay đổi bản gốc.


Loại thứ hai lμ <i>tham biến</i>. Tham biến nghĩa lμ chuyển trực tiếp biến từ
ch−ơng trình chính sang cho ch−ơng trình con sử dụng. Ch−ơng trình con sẽ
d−ợc trỏ đến tận địa chỉ gốc của biến, nó thực hiện các tính tốn trực tiếp tại
đó vμ do đó lμm thay đổi đ−ợc nội dung của tham bin.



Tham biến đợc khai báo kèm từ khoá VAR trong danh sách tham số
hình thức.


T ý ngha của hai cách truyền tham số vừa giải thích ở trên, ta thấy
ngay rằng đối vơí các ch−ơng trình con thì các tham số lμ dữ liệu đầu vμo -


<i>input-</i> nhận từ chơng trình chính có thể l tham trị hoặc tham biến, nhng


cỏc tham s l kết quả đầu ra - <i>output</i> - của thủ tục <i>phải lμ tham biến</i>. Nếu
quên điều nμy thì khi thủ tục kết thúc cũng mất luôn các kết quả vì các tính
tốn, xử lí thực hiện trên bản sao tạo ra trong ch−ơng trình con, bị huỷ khi
ch−ơng trình con kết thúc. Giá trị của bản chính, nghĩa lμ của biến trong
ch−ơng trình chính khơng thay đổi.


VÝ dơ minh ho¹ .
Program Tham_tri;
var a,b,c: integer;


procedure GapDoi(x,y,z: integer);
begin x:= x*2; y:=y*2; z:=z*2;


writeln('Trong procedure co 3 so:',x,' ',y,' ',z);
end;


BEGIN


a:= 1; b:= 10; c:= 100;


writeln('Truoc procedure co 3 so:',a,' ',b,' ',c);


GapDoi(a,b,c);


writeln('Sau procedure co 3 so:',a,' ',b,' ',c)
END.


</div>
<span class='text_page_counter'>(130)</span><div class='page_container' data-page=130>

<i>Tr−íc procedure cã 3 so 1 10 100 </i>
<i>Trong procedure cã 3 so 2 20 200 </i>
<i>Sau procedure cã 3 so 1 10 100 </i>


Nếu sửa lại danh sách tham số của thủ tục trên, khai báo <i>x,y,z </i>đ−ợc
truyền nh− tham biến với từ khố VAR thì kết quả sẽ lμm biến đổi thực sự
giá trị của <i>a,b,c</i>. Dòng kết quả cuối cùng sẽ lμ


<i>Sau procedure cã 3 so 2 20 200 ! </i>


Program Tham_bien;
var a,b,c: integer;


procedure GapDoi_var(VAR x,y,z: integer);
....


<b>2.3 </b> <b>Một vài lu ý khi xây dựng chơng tr×nh con </b>


2.3.1 <i> Xác định danh sách tham số. </i>


Tên, danh sách các tham số đầu vμo, đầu ra kèm với kiểu dữ liệu của
các tham số đó trong ngun mẫu của một ch−ơng trình con lμ toμn bộ <i>giao </i>
<i>diện</i> của ch−ơng trình con với bên ngoμi. Để sử dụng một ch−ơng trình con
chỉ cần biết tên, chức năng, các tham số đầu vμo lμ gì vμ kết quả đầu ra kiểu
gì, để ở đâu. Ng−ời sử dụng ch−ơng trình con khơng cần biết đến nội dung


các câu lệnh bên trong thân ch−ơng trình con.


Tuy nhiên, khơng nhất thiết mọi dữ liệu đầu vμo của một ch−ơng trình
con đều phải xuất hiện trong danh sách tham số hình thức. Đ−a những tham
số nμo vμo danh sách tham số hình thức trong dịng khai báo ngun mẫu của
ch−ơng trình con lμ vấn đề mở những cổng giao tiếp nμo để cho ng−ời sử
dụng có thể tuỳ biến khi gọi thực hiện ch−ơng trình con.


Nguyên tắc chung lμ: nếu một tham số hình thức mμ trong tất cả các
lần gọi thực hiện ch−ơng trình con đều đ−ợc gán giá trị tham số thực sự giống
nhau thì có thể loại khỏi danh sách tham số hình thức trong nguyên mẫu của
ch−ơng trình con.


</div>
<span class='text_page_counter'>(131)</span><div class='page_container' data-page=131>

sách tham số. Chỉ những tham số sẽ nhận những giá trị khác nhau trong
những lần sử dụng khác nhau mới cần đa vo danh sách tham số hình thức.


Xét trờng hợp viết chơng trình con thực hiện in một ma trận ra mn
hình thnh bảng hình chữ nhật dóng thẳng hng, cột.


1- Nếu trong chơng trình chính sẽ cần thực hiện in ra mμn h×nh nhiỊu
ma trËn víi nhiỊu kÝch th−íc khác nhau thì tất cả các dữ liệu sau đây phải
đa vo danh sách tham số hình thức: số hμng cña ma trËn, sè cét cña ma
trËn, m¶ng chøa ma trËn.


2- Nếu trong ch−ơng trình chính các ma trận đều cùng một kích th−ớc
thì các tham số: số hμng của ma trận, số cột của ma trận không cần đ−a vμo
danh sách tham số hình thức. Trong danh sách tham số hình thức chỉ cần có
mảng chứa ma trận cần in ra.


3- Nếu ta chỉ gọi ch−ơng trình con nμy một lần để in ra ma trận kết


quả chẳng hạn thì thậm chí khơng cần đ−a mảng chứa ma trận vμo danh sách
tham số. Danh sách tham số lμ rỗng.


2.3.2


2.3.3


2.3.4


<i>Phong c¸ch viÕt danh s¸ch tham sè. </i>


Để cho rõ rμng, dễ theo dõi, nên chia danh sách tham số lμm hai phần,
thậm chí trên hai dịng khác nhau, chú thích rõ đâu lμ các tham số lμm dữ
liệu đầu vμo {<i>input</i>}, đâu lμ các tham số để chứa kết quả đầu ra {<i>output</i>}. Ví
dụ,


Procedure <i>NhapMang</i> ({<i>input</i>} so_pt: integer,
{<i>output</i>} Var Dayso: mang)


<i>Lùa chän hμm hay thđ tơc. </i>


Hoμn toμn cã thĨ chun mét hμm thnh một thủ tục bằng cách coi giá
trị trả về nh một tham số đầu ra, đợc khai báo lμ tham biÕn.


VÝ dô:


Procedure <i>MaxDay</i> ({<i>input</i>} so_pt: integer; Dayso: mang ;
{<i>output</i>} Var giatrimax: real);


Tuy nhiªn, hμm cã thÓ tham gia trùc tiÕp vμo biÓu thøc nh một toán


hạng, còn thủ tục thì không !


<i>Lựa chọn tham biến hay tham trị. </i>


Đối với lợng dữ liệu lớn thì việc truyền theo tham trị không hiệu quả
vì nó sẽ chiếm mất nhiều chỗ trong ngăn xếp do việc tạo ra bản sao chép lại
dữ liệu đợc truyền. Một số kiểu dữ liệu có cấu trúc không cho phép truyền
theo tham trị m chØ cã thĨ trun theo tham biÕn.


Tuy nhiên, nếu chọn cách truyền theo tham biến cần l−u ý đến các


</div>
<span class='text_page_counter'>(132)</span><div class='page_container' data-page=132>

2.3.5 <i>TÖp lμm tham số của chơng trình con. </i>


Khi cn truyn hoc nhận nhiều dữ liệu, có thể dùng biến tệp để truyền
tham số cho ch−ơng trình con. Nó bắt buộc phải lμ tham biến. Ch−ơng trình
con thực sự truy cập tệp chứ không phải tạo bản sao khác.


VÝ dô.


Thủ tục <i>TaoTep</i> d−ới đây sẽ tạo một tệp các số nguyên rồi ghi vμo đó
các số nguyên từ 1 đến 100. Tên tệp đ−ợc cung cấp nh− một tham số đầu vμo
của thủ tục.


Procedure TaoTep( Var F: TepSoNguyen; Ten: String[30]);
Var i: integer;


Begin Assign (F, Ten);


Rewrite (F);



For i:=1 to 100 do Write(F,i);
Close(F);


End;


<b>2.4 </b> <b>Khai b¸o tr−íc - Forward. </b>


Quy tắc chung trong một ch−ơng trình Pascal lμ mọi thứ đều phải tuân
theo trình tự khai báo, xây đựng rồi mới đ−ợc sử dụng. Các ch−ơng trình con
cũng khơng ngoμi thơng lệ đó. Ta chỉ có thể sử dụng, tức lμ viết câu lệnh có
lời gọi tới một ch−ơng trình con sau khi đã triển khai nó đầy đủ.


Tuy nhiên, có những tr−ờng hợp mμ hai ch−ơng trình con sử dụng lẫn
nhau nh− minh hoạ d−ới đây. Trong thân thủ tục <i>Proc1</i> có lời gọi đến thủ
tục <i>Proc2</i> vμ ng−ợc lại trong thân thủ tục <i>Proc2</i> lại có lời gọi đến thủ tục


<i>Proc1.</i>


Procedure<i> Proc1(...); </i>
<i>... </i>


<i>Begin </i>


<i> ... </i>


<i> Proc2(...); </i>
<i> ... </i>


<i>End; </i>



Procedure<i> Proc2(...); </i>
<i>... </i>


<i>Begin </i>


<i> ... </i>


</div>
<span class='text_page_counter'>(133)</span><div class='page_container' data-page=133>

<i> ... </i>
<i>End; </i>


Trong tình huống nμy sẽ có lỗi cú pháp khi gặp lời gọi <i>Proc2</i> vì trình
biên dịch ch−a biết đ−ợc <i>Proc2</i> lμ cái gì. Dù đặt thủ tục nμo lên tr−ớc thì
cũng vẫn mc li.


Turbo Pascal cung cấp khả năng <i>khai báo trớc</i> bằng chỉ thị <i>Forward. </i>


Cần thêm một dòng khai báo nguyên mẫu của thủ tục <i>Proc2</i> kÌm chØ thÞ


<i>Forward</i> tr−íc khi bắt đầu khai baó v xây dựng thủ tục <i>Proc1</i>. Sau khi kÕt


thóc viƯc x©y dùng thđ tơc <i>Proc1</i> ta tiÕn hμnh x©y dùng thđ tơc <i>Proc2</i> nh−
th«ng th−êng.


Procedure <i>Proc2( ... )</i> ; <b>Forward ; </b>


Procedure <i>Proc1( ... );</i>


...


<i>Begin </i>



<i> ... </i>


<i> Proc2(...); </i>


<i> ... </i>


<i>End; </i>


Procedure <i>Proc2;</i>
...


<b>3. </b> <b>Chơng trình con lång nhau. </b>


<b>3.1 </b> <b>BiÕn toµn cơc, biÕn cơc bộ, tầm tác dụng </b>


3.1.1 <i>Phân biệt biến ton côc vμ biÕn côc bé. </i>
BiÕn toμn côc:


- Đợc khai báo ở đầu chơng trình chính.


- Tồn tại trong suốt thời gian lm việc của chơng trình.


- Có thể truy cập (đọc giá trị, biến đổi giá trị) từ bất kì chỗ nμo trong
ch−ơng trỡnh.


Biến cục bộ:


- Khai báo ở đầu một chơng trình con.



- Ch tn ti trong thi gian hoạt động của ch−ơng trình con.


</div>
<span class='text_page_counter'>(134)</span><div class='page_container' data-page=134>

3.1.2


3.1.3


<i>Gi¶i thÝch b¶n chÊt. </i>


Nếu tìm hiểu kỹ việc tổ chức thực hiện một ch−ơng trình trong máy
tính thì ta sẽ thấy nh− sau. Khi một ch−ơng trình đ−ợc nạp vμo bộ nhớ để
thực hiện thì phần mã của các câu lệnh đ−ợc bố trí trong đoạn mã lệnh. Các
dữ liệu đầu vμo của ch−ơng trình đ−ợc khai báo ở đầu ch−ơng trình chính, tức
lμ các hằng, kiểu, biến.. toμn cục đ−ợc cấp phát vùng nhớ cần thiết trong một
đoạn khác gọi lμ đoạn dữ liệu của ch−ơng trình. Vùng nμy tồn tại trong bộ
nhớ cho đến khi ch−ơng trình chính kết thúc.


Mỗi khi gặp một lời gọi ch−ơng trình con thì một vùng nhớ (kích
th−ớc mặc định lμ 16 KB) đ−ợc dμnh riêng để chứa các dữ liệu đầu vμo cho
ch−ơng trình con nμy nh− các tham số của ch−ơng trình con, các hằng, kiểu,
biến cục bộ ... Nó đ−ợc gọi lμ vùng ngăn xếp (<i>Stack</i>) của ch−ơng trình con.
Khi ch−ơng trình con kết thúc thì toμn bộ vùng ngăn xếp dμnh cho nó đ−ợc
giải phóng. Điều nμy cũng đúng khi các ch−ơng trình con lồng nhau nhiều
cấp.


Từ đó ta thấy các tính chất khác nhau của biến toμn cục vμ biến cục bộ
nh− nêu trên lμ hoμn toμn hiển nhiờn.


<i>Trờng hợp trùng tên. </i>


Mt trng hp cn xem xét kĩ hơn lμ khi có một biến toμn cục vμ một


biến cục bộ trùng tên nhau. Điều nμy đ−ợc phép vì dù trùng tên, chúng vẫn lμ
hai biến khác nhau, tồn tại ở hai nơi khác nhau vμ có "đời sống" dμi ngắn
khác nhau.


Khi có một câu lệnh truy cập đến một biến bị trùng tên nh− nêu trên
thì nó sẽ tác động lên biến nμo? Nếu câu lệnh nằm ngoμi ch−ơng trình con thì
dĩ nhiên đối t−ợng tác động lμ biến toμn cục vì biến cục bộ lúc đó khơng tồn
tại. Nếu câu lệnh nằm bên trong ch−ơng trình con thì đối t−ợng tác động sẽ lμ
biến cục bộ của ch−ơng trình con đó chứ khơng phải lμ biến toμn cc.


Tóm lại ta có quy tắc xử lí trờng hợp trùng tên l:


- Bin cc b che khuất biến toμn cục, biến trong che lấp biến ngoμi
- Nếu có nhiều hơn hai biến trùng tên, nghĩa lμ trùng tên nhiều tầng,
thì lệnh truy cập sẽ tác động đến biến "gần" nó nhất mμ nó nhìn thấy.


Mặc dù máy tính khơng nhầm lẫn khi có các biến có phạm vi khác
nhau mμ trùng tên nhau nh−ng để cho ng−ời lập trình khơng nhầm lẫn thì nên
tránh trùng tên. Sử dụng các tên khác nhau cho các biến khác nhau.


<b>3.2 </b> <b>Minh ho¹ </b>


Trong hình vẽ trên, mỗi hình chữ nhật t−ợng tr−ng cho phạm vi của
một ch−ơng trình con. Hình chữ nhật ngoμi cùng t−ợng tr−ng cho ch−ơng
trình chính. Các biến <i>a,b,c,V</i> lμ biến toμn cục. Các biến còn lại lμ cục bộ
trong ch−ơng trình con định nghiã chúng.


</div>
<span class='text_page_counter'>(135)</span><div class='page_container' data-page=135>

Từ trong ch−ơng trình con <i>Proc111</i> có thể truy cập đến các biến <i>a111, </i>


<i>b111, c111, a11, b11, c11, a1, b1, c1, a, b, c</i> nh−ng không thấy, không truy



cập đợc các biến <i>a12, b12, c12, a2, b2, c2.</i>


Một câu lệnh trong chơng trình con <i>Proc1</i> m không nằm trong


<i>Proc11, Proc12</i> thì chØ cã thĨ truy cËp c¸c biÕn <i>a1, b1, c1, a, b, c.</i>


Đối với biến trùng tên <i>V</i> thì một câu lệnh truy cập trong <i>Proc12</i> sẽ tác
động lên biến <i>V</i> thuộc ch−ơng trình con <i>Proc1</i>.


Proc21; Var <i>a21,b21,c21..</i>


<i>V: ... </i>


Proc2; Var <i>a2,b2,c2..</i>
Program Prog000;


Var <i>a,b,c:..</i>
<i> V: ... </i>


Proc12; Var <i>a12,b12,c12...</i>


<i>V:... </i>


Proc11; <i>Var a11, b11,c11..</i>


<i>V:... </i>


Proc111;



Var <i>a111, b111,c111..</i>


Var <i>a1,b1,c1</i>


Proc<i>1;</i>


</div>
<span class='text_page_counter'>(136)</span><div class='page_container' data-page=136>

C©u hái vμ bμi tËp


1. Trình by các bớc công việc khi gặp một lời gọi thực hiện chơng trình
con


2. Sử dụng chơng trình con tiết kiệm thời gian cho máy tính hay cho ng−êi
lËp tr×nh.


3. Phân biệt ch−ơng trình con đ−ợc gọi vμ ch−ơng trình con gọi nó. Trong
Pascal các ch−ơng trình con có thể lồng nhau bao nhiêu cấp, điều gì quyết
định việc nμy.


4. Các tham số trong danh sách tham số của ch−ơng trình con đóng vai trị gì.
5. Các tham số của thủ tục <i>Read</i> lμ tham số đầu vμo hay đầu ra. Câu hỏi


t−¬ng tù cho thđ tơc <i>Write</i>.


6. Trong một chơng trình có các khai báo v lời gọi chơng trình con nh
dới đây. Tìm xem lời gọi no sai


<i>const MaxInt = 32767; </i>
<i>Var x,y,z: real; </i>


<i> m,n: integer; </i>



<i>Procedure ThuTuc1(var a,b: real; x:integer); .. </i>


C¸c lêi gäi:


<i>ThuTuc1(x,y,z); </i> <i>ThuTuc1(2.5,y,3); </i> <i>ThuTuc1(x,y,n); </i>


<i>ThuTuc1(x,y,m+2); ThuTuc1(x-y,x+y,5); ThuTuc1(z,y,5,10); </i>
<i>ThuTuc1(x,y,MaxInt);</i>


7. Phân biệt biên toμn cục, biến cục bộ. Quy tắc để xác định tầm tác dụng
của các biến.


8. Tên các tham số hình thức của ch−ơng trình con có thể trùng với tên các
bién toμn cục hay khơng, có thể trùng với tên các bién cục bộ của ch−ơng
trình con đó hay khơng.


Thùc hμnh.


1. Viết hμm <i>LuyThua</i> có hai tham số <i>x,n</i> để tính <i>xn</i>. Chuyển thμnh thủ tục,
ghi kết quả vμo tham số <i>y.</i>


2. Viết một thủ tục đổi mọi chữ trong xâu chữ cái thμnh chữ in hoa. Nếu
muốn chuyển thμnh một hμm thì cần thay đổi nh− thế nμo.


3. Viết một hμm tính định thức cấp 3 vμ sử dụng nó để giải hệ ph−ơng trình
tuyến tính cấp 3 theo quy tắc Cramer.


</div>
<span class='text_page_counter'>(137)</span><div class='page_container' data-page=137>

<b>Ch−ong 11 </b>
<b>thiết kế chơng trình </b>



<b>1. </b> <b>Phơng pháp xây dựng chơng trình </b>


<b>1.1 </b> <b>Khái niệm Công nghệ phần mềm. </b>


Cho n nay ta mới chỉ viết một số ch−ơng trình giải các bμi tốn nhỏ
nh− lμ các ví dụ minh hoạ. Lập trình trong tr−ờng học, nhất lμ ở mức sơ khởi,
khác nhiều với xây dựng phần mềm chuyên nghiệp trong thực tế.


Công nghệ phần mềm lμ một thuật ngữ để chỉ môn khoa học về các
quy trình, kĩ thuật, cơng cụ, v.v.. hỗ trợ cho các nhμ phát triển phần mềm
chuyên nghiệp trong việc thiết kế ch−ơng trình, viết mã nguồn, thử nghiệm
vμ bảo trì một phần mềm cỡ lớn sao cho hiệu quả.


Trong thực tế, mầm mống của một dự án phần mềm bắt đầu từ nhu cầu
tự động hoá bằng máy tính những cơng việc xử lí thơng tin cho đến nay vẫn
lμm thủ cơng. Vì ng−ời sử dụng phần mềm nói chung khơng có các hiểu biết
đầy đủ vμ chuyên sâu về công nghệ thông tin, nhμ <i>phân tích hệ thống </i> cần
tiến hμnh trao đổi kĩ l−ỡng với khách hμng để xác định chính xác yêu cầu đặt
ra đối với hệ thống mμ mình phải xây dựng. Qua đó ng−ời sử dụng cũng hiểu
rõ thêm có thể địi hỏi những gì ở phần mềm t−ơng lai. Dựa trên các yêu cầu
đã đ−ợc xác định cụ thể, nhμ phân tích hệ thống sẽ lựa chọn giải pháp vμ thiết
kế hệ thống để đáp ứng các yêu cầu đặt ra. ở b−ớc nμy chiến l−ợc chia để trị
sẽ đ−ợc áp dung. Yêu cầu đặt ra sẽ đ−ợc phân chia thμnh nhiều bμi toán nhỏ
hơn, thực hiện từng chức năng cụ thể, gọi lμ các mơ đun. Q trình phân chia
chi tiết dần sẽ tiếp tục cho đến khi các mơ đun ch−ơng trình đủ đơn giản. Chỉ
đến khi đó <i>lập trình viên</i> mới bắt đầu cơng việc viết ch−ơng trình, tức lμ
chuyển thμnh mã nguồn bản thiết kế chi tiết đã có. Việc chạy thử để kiểm tra,
sửa lỗi, hoμn thiện ... lμ các b−ớc tất yếu sau đó.



Q trình phát triển một phần mềm th−ờng lμ theo vịng xốy trơn ốc,
lặp lại nhiều lần các b−ớc trên cho đến khi ch−ơng trình đáp ứng đ−ợc yêu
cầu của ng−ời dùng.


<b>1.2 </b> <b>Chu kì phát triển phần mềm. </b>


</div>
<span class='text_page_counter'>(138)</span><div class='page_container' data-page=138>

Ng−ời ta gọi đó lμ <i>chu kì </i>
<i>phát triển phần mm - Software Life Cycle.</i>


Dới đây l các bớc trong chu kì phát triển phần mềm.


1- c t chi tiết yêu cầu - <i>Requirements Specification</i> : Xác định
chính xác u cầu của bμi tốn đặt ra, trả lời câu hỏi ch−ơng trình cần phải
lμm những gì. Kết quả của giai đoạn nμy lμ văn bản đặc tả yêu cầu đối với
phần mềm t−ơng lai, đ−ợc cả hai bên - khách hμng vμ nhμ phát triển - nhất trí
thơng qua.


2- Ph©n tÝch bμi toán - <i>Analysis</i>: Cụ thể hoá yêu cầu trên, đầu vo, đầu
ra, các mối quan hệ, các quy luật, công thức có liên quan. Đa ra các giải
pháp v lựa chọn giải pháp thích hợp.


3- Thit kế - <i>Design</i>: Xác định các mô đun với từng chức năng cụ thể,
đầu vμo, đầu ra của từng mô đun. Kết quả của giai đoạn nμy lμ một sơ đồ cấu
trúc, cho thấy rõ các mô đun trong ch−ơng trình vμ mối quan hệ của chúng
với nhau.


4- Triển khai, viết mà lệnh chơng trình - <i>Implementation</i>: Thể hiện
bản thiết kế bằng một ngôn ngữ chơng trình cụ thể. Kết thúc giai đoạn ny
ta có văn bản mà nguồn của chơng trình.



5- Chy thử vμ kiểm tra - <i>Test and Verification:</i> biên dịch vμ chạy thử
ch−ơng trình với nhiều bộ dữ liệu đầu vμo khác nhau, gồm các tr−ờng hợp
thông th−ờng, các tr−ờng hợp đặc biệt, kiểm tra kết quả có đúng đắn khơng,
hμnh vi của ch−ơng trình có phù hợp khơng. Sửa chữa các sai sót.


Víi những bi toán lớn v phức tạp, ngời ta còn chia nhỏ hơn thnh
một quy trình 7 bớc hoặc 9 b−íc.


Một trong những khuyết điểm mμ những ng−ời mới học lập trình hay
mắc phải lμ th−ờng hay bỏ qua 3 b−ớc đầu, vội vã bắt đầu ngay bằng việc
viết các dịng lệnh mμ khơng để thì giờ tìm hiểu kĩ bμi tốn, hình dung một
cách rõ rμng các yêu cầu của nó, phác thảo một vμi cách giải quyết vμ lựa
chọn cách tốt nhất. Rèn luyện cách xây dựng ch−ơng trình theo đúng ph−ơng
pháp lμ một việc cần lμm.


Trong khu«n khỉ của giáo trình ny ta chỉ tập trung vo bớc thiết kế
v triển khai chơng trình.


<b>1.3 </b> <b>Ví dơ minh ho¹ </b>


</div>
<span class='text_page_counter'>(139)</span><div class='page_container' data-page=139>

1.1.1 <i>VÝ dơ. </i>


Viết chơng trình thực hiện nhân hai ma trận.


1- Xác định yêu cầu: Thực hiện phép nhân hai ma trận. Dữ liệu đầu vμo lμ
hai ma trận nhập từ bμn phím. Ma trận kết quả đ−ợc in ra d−ới dạng
một bảng hình chữ nhật dóng thẳng hμng, cột. Nếu kích th−ớc của 2
ma trận đầu vμo khơng phù hợp thì thơng báo lỗi.


2- Ph©n tÝch bi toán:



- Đầu vo l dữ liệu về hai ma trËn <i>A, B</i> cơ thĨ gåm: <i> rA</i> = sè hμng cña
ma trËn <i>A. cA</i> = sè cét cña ma trËn <i>A. rB</i> = sè hμng cña ma trËn <i>B. cB </i>
<i>=</i> sè cét cña ma trận <i>B</i>. các phần tử <i>A<sub>ij</sub></i> của ma trận <i>A</i>, <i>B</i>B


<i>ij</i> của ma trận


<i>B.</i>


- Đầu ra l ma trận tích C.


- Các công thức tính to¸n: <i>rC = rA</i> (sè hμng cđa <i>C</i> b»ng sè hμng cña


<i>A</i>). <i>cC = cB</i> (sè cét cđa <i>C</i> b»ng sè cét cđa <i>B</i>). C¸c phÇn tư cđa <i>C</i> lμ


<i>C<sub>ij</sub> = </i>

Σ

<i> A<sub>ik</sub> * B<sub>kj</sub></i>.


- Phải kiểm tra điều kiện nhân đợc <i>cA=rB</i>. Nếu không thoả mÃn thì
báo lỗi v dừng chơng trình. Nếu thoả mÃn thì tính v in ra ma trËn C.
3- ThiÕt kÕ.


Thùc hiÖn chi tiết dần từng bớc theo cách tiếp cận <i>top-down</i> sẽ trình
by kì hơn trong phần thiết kế chi tiÕt dÇn tõng b−íc


4- TriĨn khai, viÕt m· lƯnh.


Chun thiÕt kÕ chi tiÕt cđa b−íc tr−íc thnh các câu lệnh Pascal.
5- Chạy thử v kiểm tra.


- Trờng hợp nhân đợc.



- Trờng hợp không nhân đợc.


- Cỏc trng hp c biệt: ma trận suy biến thμnh véc tơ, chỉ có mt
hng, mt ct, v.v.


<b>1.4 </b> <b>Lập trình mô ®un - Modula programming </b>
1.1.2 <i>KiÕn tróc theo mô đun </i>


</div>
<span class='text_page_counter'>(140)</span><div class='page_container' data-page=140>

<i>u điểm của kiến trúc theo mô đun. </i>
1.1.3


Kiến trúc theo mô đun nh trên có nhiều u điểm.


Nó tạo ra khả năng mềm dẻo v linh hoạt khi xây dùng hƯ thèng. Cã
thĨ dïng s¶n phÈm cđa nhiỊu nh sản xuất khác nhau miễn l phù hợp về
th«ng sè kÜ tht.


Nó cho phép dễ dμng bảo trì, phát hiện vμ sửa chữa các hỏng hóc vμ
nâng cấp. Do từng mô đun đảm nhiệm một chức năng công việc rõ rμng. Khi
một khâu công việc nμo đó bị trục trặc hoặc kém hiệu quả, ta xác định đ−ợc
ngay mô đun liên quan vμ chỉ cần sửa chữa hay thay thế mơ đun đó.


Nã cho phép tái sử dụng những mô đun còn lm việc đợc vì có thể
tháo ra v mang lắp vo hệ thống mới.


1.1.4 <i>Lập trình theo mô ®un </i>


Lập trình theo mơ đun lμ áp dụng mơ hình kết cấu mơ đun nh− trên
vμo xây dựng ch−ơng trình. Một ch−ơng trình lớn, phức tạp cần đ−ợc phân


chia lμm nhiều mơ đun ch−ơng trình. Mỗi mơ đun ch−ơng trình hoμn thμnh
một phần cơng việc t−ơng đối độc lập. Một mô đun, đối với các mô đun khác
giống nh− một "hộp đen". Nghĩa lμ nội dung cụ thể ở bên trong của nó, các
lệnh xử lí, tính tốn lμm theo cách nμy hay theo cách khác lμ không quan
trọng miễn lμ hoμn thμnh phần công việc đ−ợc giao. Các mô đun ch−ơng
trình đ−ợc "ráp nối" với nhau thơng qua các giao diện - <i>interfaces</i> - lμ các
đầu vμo, đầu ra. Đầu vμo của mô đun nμy lμ đầu ra của mô đun khác. Cứ nh−
thế dữ liệu sẽ đ−ợc chuyển tiếp xử lí giữa các mơ đun cho đến khi đạt kết quả
cuối cùng.


Giống nh− việc kết cấu các máy móc thiết bị theo mơ đun, lập trình
theo mơ đun cũng có đầy đủ những −u điểm t−ơng tự. Nó hỗ trợ cho phát
hiện vμ sửa chữa lỗi, bảo trì vμ nâng cấp ch−ơng trình, sử dụng lại các mơ
đun ch−ơng trình con đã hoμn thiện vμ tổ chức các nhóm cộng tác thực hiện
ch−ơng trình một cách mềm dẻo linh hoạt.


1.1.5 <i>VÝ dơ. </i>


Sau khi đã phân tích ch−ơng trình lμm phép nhân hai ma trận ta có thể
thiết kế ch−ơng trình nμy theo mơ đun nh− sau:


- Mô đun 1: đảm bảo phần công việc nhập ma trận từ bμn phím.
- Mơ đun 2: thực hiện phép nhân hai ma trận sau khi đã kiểm tra điều
kiện nhân đ−ợc.


- M« đun 3: hiển thị ma trận (kết quả) ra mn h×nh.


Mơ đun 1 sẽ đ−ợc sử dụng hai lần để nhập lần l−ợt hai ma trận đầu vμo


</div>
<span class='text_page_counter'>(141)</span><div class='page_container' data-page=141>

<b>1.5 </b> <b>Thđ tơc ho¸ - Procedural abstraction </b>



Các mơ đun ch−ơng trình lμ các ch−ơng trình con trong một ch−ơng
trình lớn hơn. Thực hiện thiết kế theo mô đun cũng lμ sử dụng hμm vμ thủ tục
để xây dựng ch−ơng trình hay thủ tục hố khi xây dựng ch−ơng trình.


Ph−ơng pháp để lμm việc nμy lμ


- Xác định rõ <i>chức năng</i> của từng mơ đun nh− một ch−ơng trình con,
nó sẽ lμm gì, ch−a quan tâm lμm nh− thế nμo, khơng đi ngay vμo chi tiết. Đây
lμ viêc phân chia biên giới giữa các ch−ơng trình con, đảm bảo tính độc lập
t−ơng đối của chúng với nhau.


- Xây dựng khung lắp ghép các ch−ơng trình con thμnh ch−ơng trình
chính. Mỗi ch−ơng trình con lμ một mơ đun riêng rẽ, giống nh− từng tấm bê
tông để xây thμnh một toμ nhμ lắp ghép. Để kiến trúc nên toμ nhμ cần bố trí
các tấm bê tơng đúng vị trí đã định. Để xây dựng thμnh ch−ơng trình chính
cần xác định đúng quan hệ của các mơ đun ch−ơng trình con với nhau.


- Xác định chất kết dính để liên kết các mơ đun với nhau. Nó giống
nh− vơi vữa xi măng trong xây dựng nhμ cửa. Cái kết dính các ch−ơng trình
con với nhau lμ việc truyền tham số. Đầu vμo của ch−ơng trình con nμy lμ
đầu ra của một ch−ơng trình con khác. Cần hoạch định cách thức truyền dữ
liệu giữa các ch−ơng trình. Truyền thơng qua danh sách tham số hay gián
tiếp qua biến toμn cục, theo cách tham trị hay tham biến.


- Sau khi đã tiến hμnh thủ tục hố nh− trên, có thể viết ngay đ−ợc
ch−ơng trình chính tr−ớc khi thực hiện chi tiết các ch−ơng trình con.


<b>2. </b> <b>ThiÕt kÕ chi tiÕt dÇn tõng b−íc. </b>



<b>2.1 </b> <b>Sơ đồ cấu trúc ch−ơng trình - structure chart </b>


Theo ph−ơng pháp thiết kế <i>top-down</i> chi tiết dần từng b−ớc ta cần lập
một sơ đồ cấu trúc của ch−ơng trình. Sơ đồ cấu trúc của ch−ơng trình gồm
nhiều mức, giống hình cây lật ng−ợc mμ gốc cây lμ bμi toán ban đầu. Sơ đồ
cấu trúc sẽ phát triển dần xuống d−ới, chia ra nhiều nhánh con, ứng với việc
chi tiết dần mỗi bμi toán thμnh các bμi toán con nhỏ hơn. Quá trình phân
nhánh tiếp tục cho đến khi các bμi toán con đã đủ đơn giản.


</div>
<span class='text_page_counter'>(142)</span><div class='page_container' data-page=142>

<i>Møc 0 </i>


<i>Møc 1 </i>


<i>Møc 2 </i>.. .. .. ..
Bμi to¸n ban đầu


Bi toán 1 Bi toán 2 Bi toán 3


Bμi to¸n
1.1


Bμi to¸n
2.1
Bμi to¸n


1.2


<i>Møc 3</i> ...


<i>Hình 11.1: sơ đồ cấu trúc của một ch−ơng trình </i>



Ph−ơng châm hμnh động khi thiết kế ch−ơng trình theo kiểu <i>top-down</i>


chi tiÕt dÇn tõng b−íc lμ:


- Đi từ tổng thể đến bộ phận, từ khái quát đến chi tit


- ở mỗi bớc chỉ trả lời câu hỏi <i>lm gì,</i> cha vội đi vo chi tiết <i>lm </i>


<i>nh thÕ nμo.</i> ViƯc lμm nh− thÕ nμo sÏ râ dÇn qua từng bớc phân chia công


việc, từng việc lm g×.
<b>2.2 </b> <b>VÝ dơ. </b>


2.2.1 <i>VÝ dơ. </i>


Thiết kế ch−ơng trình nhân hai ma trận đã phân tích trong tiết tr−ớc.
Chi tiết mức 1.


C¸c bi toán nhỏ phải giải quyết l.
1. Nhập ma trận.


Đầu vo: số hng của ma trận, số cột của ma trận, các phần tử của ma
trận gõ từ bn phím.


Đầu ra: mảng 2 chiều biểu diễn ma trận trong bộ nhớ đợc gán trị.
2. Kiểm tra điều kiện nhân đợc.


Đầu vo: số hng của A, số cột của B.



Đầu ra: kết luận có thực hiện đợc phép nhân AB không.
3. Nh©n 2 ma trËn.


Đầu vμo: hai mảng 2 chiều biểu diễn hai ma trận A,B thoả mãn điều
kiện nhõn c, ó cú trong b nh.


Đầu ra: ma trËn tÝch C = A.B.
4. In ma trËn ra mn hình.


</div>
<span class='text_page_counter'>(143)</span><div class='page_container' data-page=143>

Đầu ra: Hiển thị các phần tử của ma trận thnh bảng chữ nhật, dóng
thẳng hng cột trên mn hình.


Chơng trình nh©n hai
ma trËn


1.NhËp
ma trËn


3. Nh©n hai
ma trận


4. In ma
trận
2.Kiểm tra


nhân đợc


<i>Hình 11.2: sơ đồ cấu trúc ch−ơng trình nhân ma trận sau khi chi tiết mức 1. </i>


Giả sử đã có 4 mơ đun ch−ơng trình con thực hiện các chức năng trên,


với tên gọi t−ơmg ứng lμ <i>NhapMaTran, KiemTraNhanDuoc, NhanMaTran </i>


v <i> InMaTran</i>. Chơng trình chính sẽ chỉ gồm các lệnh gọi chơng trình con


thực hiện tuần tự các công việc sau: nhập ma trận A; nhập ma trận B; kiểm
tra điều kiện nhân đợc; nếu thoả mÃn tính ma trận tích C = A.B vμ in ma
trËn C ra mμn h×nh.


Ta có thể viết ngay phần mà lệnh của chơng trình chÝnh
BEGIN


Writeln(' nhap ma tran thu nhat:');
NhapMaTran(rA,cA,A);


Writeln(' nhap ma tran thu hai:');
NhapMaTran(rB,cB,B);


If not KiemTraNhanDuoc Then exit
Else


begin


NhanMaTran(rA,cA,rB,cB,rC,cC,A,B,C);
Writeln(' ma tran tich la: ');


InMaTran(rC,cC,C);
End;


END.



Chi tiÕt møc 2.
1. NhËp ma tr©n.


1.1 NhËp kÝch th−íc (sè hμng, sè cét) cđa ma trận.
1.2 Nhập các phần tử của ma trận.


- Nhập từ hμng thứ nhất cho đến hμng cuối.
2. Kiểm tra nhân đ−ợc:


</div>
<span class='text_page_counter'>(144)</span><div class='page_container' data-page=144>

nếu đúng trả kết quả lμ True.


3. Nhân hai ma trận A*B đặt vμo ma trận C


3.1 G¸n sè hμng cña C b»ng sè hμng cña A, sè cét cña C b»ng sè cét
cña B


3.2 Tính các phần tử của ma trận tích C theo cơng thức đã biết.
- Tính các phần tử theo từng hμng, từ hμng thứ nhất cho đến
hμng cuối.


4. In ma trËn ra mμn h×nh.


4.1 LÊy kÝch th−íc cđa ma trËn.


4.2 In ra lần lợt từng hng của ma trận thnh bảng dóng th¼ng cét:
- In hμng thø nhÊt.


- xuãng dßng.


- In hμng tiếp theo vμ lặp lại cho đến khi hết mọi hμng.


Sơ đồ cấu trúc của ch−ơng trình nh− sau.


§äc sè hμng,
sè cét


§äc lần
lợt từng


hng


Lấy số
hng , số


cột


In ra lần
lợt từng


hng


Tính lần lợt
từng C ij
TÝnh sè


hμng, cét cđa
C


Ch−¬ng trình nhân hai
ma trận



Nhập ma
trận


Nhân hai ma
trận


In ma
trận
Kiểm tra


nhân đợc


<i>Hỡnh 11.3: Sơ đồ cấu trúc ch−ơng trình nhân ma trận sau khi chi tit mc 2. </i>


Chơng trình chi tiết nh− sau.


program TichMaTran;
uses crt;


const max_size = 50;


</div>
<span class='text_page_counter'>(145)</span><div class='page_container' data-page=145>

var A,B,C: matrix;


rA,cA,rB,cB,rC,cC: word;


Procedure NhapMaTran(Var SoHang,SoCot: word; Var M: matrix);
var


i,j: byte;


begin


write(' cho so hang, so cot cua ma tran: ');
readln(SoHang,SoCot);


Writeln(' Cho cac phan tu cua ma tran:');
for i:=1 to SoHang do


for j:=1 to SoCot do
begin


Write('pt[',i,',',j,']= ');Readln(M[i,j]);
end;


end;


Function NhanDuoc(SoCotA, SoHangB: word): Boolean;
begin


if SoCotA <> SoHangB then
begin


writeln('kich thuoc ma tran khong hop le !!');
NhanDuoc:= false;


End
Else


NhanDuoc:= true;
end;



Procedure InMaTran(Var M: matrix);
var


i,j: byte;
begin


for i:=1 to SoHang do
begin


for j:=1 to SoCot do Write(M[i,j]:4);
writeln;


end;
end;


Procedure NhanMaTran(rA,cA,rB,cB: word; Var rC,cC: word; Var
A,B,C: matrix);


var


i,j,k: byte;
begin


rC:=rA; cC:=cB;


for i:=1 to rC do
for j:=1 to cC do
begin



C[i,j]:=0;


for k:=1 to cA do


</div>
<span class='text_page_counter'>(146)</span><div class='page_container' data-page=146>

end;


end;


BEGIN


Writeln(' nhap ma tran thu nhat:');
NhapMaTran(rA,cA,A);


Writeln(' nhap ma tran thu hai:');
NhapMaTran(rB,cB,B);


If not NhanDuoc Then exit
Else


begin


NhanMaTran(rA,cA,rB,cB,rC,cC,A,B,C);
Writeln(' ma tran tich la: ');


InMaTran(rC,cC,C);
End;


END.


<b>3. </b> <b>Tính đệ quy và thuật giải đệ quy. </b>



<b>3.1 </b> <b>Tính đệ quy </b>


Nhiều sự vật, hiện t−ợng có tính chất đặc biệt lμ nó đồng dạng với một
bộ phận của chính nó. Một hình ảnh th−ờng thấy lμ khi TV phát hình một
phát thanh viên bên cạnh một mμn hình TV cũng đang có hình trực tiếp của
chính buổi phát hình đó, ta sẽ có một chuỗi vơ tận các mμn hình TV lồng
nhau, chiếu cùng mt khung hỡnh.


Khái niệm "cnh cây" l một ví dụ khác. Một cnh con bẻ ra từ một
cnh c©y cịng lμ mét cμnh c©y.


Trong tốn học có khái niệm giai thừa có thể đ−ợc định nghĩa qua
chính nó nh− sau


1 nÕu n = 0
n! =


n*(n-1)! nÕu n > 0.


Trong phần tin học cơ sở ta đã lμm quen với khái niệm đ−ờng dẫn. Một
phần của đ−ờng dẫn sau khi bớt đi một vμi tên th− mục ở cuối cũng lμ một
đ−ờng dẫn. Nhiều kiểu dữ liệu có cấu trúc mμ sau nμy ta sẽ nghiên cứu cũng
có tính chất t−ơng tự.


</div>
<span class='text_page_counter'>(147)</span><div class='page_container' data-page=147>

Đệ quy lμ một khái niệm mạnh. Nó cho phép diễn đạt ngắn gọn chính
xác cái vơ hạn qua các "công thức" hữu hạn.


<b>3.2 </b> <b>Thut gii quy. </b>



3.2.1


3.2.2


<i>Định nghĩa. </i>


Một thủ tục lμ đệ quy nếu trong thủ tục có lời gọi đến chính nó.


Nếu việc giải bμi toán T thực hiện bằng việc giải bμi tốn T’ có dạng
hoμn toμn giống T thì đây lμ một thuật giải đệ quy.


Nếu ta viết thủ tục thực hiện thuật giải nμy thì bên trong nó lại chứa
chính một thủ tục t−ơng tự, nghĩa lμ có một lời gọi đến chính nó hay một lời
gọi đệ quy.


Liệu một thủ tục nh− thế có luẩn quẩn khơng, có kết thúc đ−ợc khơng?
Câu trả lời lμ khơng, vì T’ khơng phải giống hệt T mμ T’ đồng dạng với T,
nh−ng có “quy mơ” bé hơn. Do đó hy vọng rằng sau khi lặp lại nhiều lần gọi
đệ quy thì "quy mơ" của bμi tốn cần giải sẽ giảm đến mức thủ tục có thể
chấm dứt.


VÝ dơ: 1 nÕu n = 0
n! =


n*(n-1)! nÕu n > 0.


Thủ tục tự nhiên nhất để tính giai thừa, gần nh− chép lại định nghĩa
trên lμ:


Function Factorial(n: integer):integer;


begin


if n=0 then Factorial:=1


else Factorial:= n* Factorial(n-1);
end;


Vậy thuật giải đệ quy lμ thuật giải tự nhiên nhất để giải bμi tốn có
tính đệ quy.


<i>VÝ dơ </i>


Ta xét một ví dụ gần với thực tế đời sống hơn. Đó lμ việc tìm kiếm số
điện thoại của một ng−ơì trong sổ điện thoại hay tra cứu giải nghĩa của một
từ trong tự điển. Trình tự tiến hμnh cơng việc nμy th−ờng lμ nh− sau.


- Më −íc chõng ë gi÷a, chia tự điển lm 2 phần.


</div>
<span class='text_page_counter'>(148)</span><div class='page_container' data-page=148>

- Lặp lại việc lμm trên cho đến khi tìm thấy từ cần tra hoặc kết luận
đ−ợc lμ khơng có t ú trong t in.


Mô hình hóa thao tác tìm kiếm trên thnh thuật giải sau


<i>Procedure TimKiem (D: TuDien; w: MotTu); </i>
<i>begin </i>


<b>If </b> <i>Tõ ®iĨn D lμ mét tõ<b> </b></i><b>then</b><i><b> </b>cho kÕt qu¶</i>


<i> </i><b>else </b>



<i>begin </i>


<i><b>- </b>Chia đôi D = D1 </i>

<i> D2</i>


<i> </i> <i>if w </i>

<i> D1 then TimKiem (D1, w) </i>


<i> </i> <i>else TimKiem (D2, w) </i>


<i> end </i>
<i>end; </i>


Đây lμ thủ tục tìm kiếm nhị phân dạng đệ quy.


<b>3.3 </b> <b>Thiết kế giải thuật đệ quy. </b>


3.3.1 <i>Hai đặc điểm của thuật giải đệ quy. </i>


1- Sau mỗi lần gọi đệ quy thì kích th−ớc của bμi tốn giảm đi.


2- Có một tr−ờng hợp suy biến: khi bμi toán đã đủ đơn giản thì có ngay
lời giải trực tiếp, khơng phải gọi đệ quy nữa.


Dựa vμo hai đặc điểm trên, để thiết kế một thuật giải đệ quy cần phân
tích bμi toán vμ thực hiện các b−ớc sau.


- Xác định rõ kích th−ớc của bμi tốn phụ thuộc vμo cái gì ?
- Phân tích đ−a bμi tốn về một hoặc một vμi bμi tốn đồng dạng
nh−ng có kích th−ớc nhỏ hơn.



- Khi nμo th× cã tr−êng hợp suy biến. Lời giải trực tiếp cho trờng hợp
nμy.


VÝ dơ, nÕu bμi to¸n xt ph¸t cã kÝch th−íc lμ n:


- Giả sử bμi tốn với kích th−ớc nhỏ hơn hay bằng n-1 đã giải đ−ợc thì
lời giải bμi tốn với kích th−ớc n có tìm đ−ợc hay khơng ?


</div>
<span class='text_page_counter'>(149)</span><div class='page_container' data-page=149>

3.3.2


4.1.1


4.1.2


4.1.3


<i>Khuôn mẫu viết thuật giải đệ quy </i>


Khuôn mẫu chung của một thủ tục đệ quy lμ


<b>If</b> <i>tr−êng hỵp suy biÕn</i> <b>Then </b> <i>cho lêi gi¶i trùc tiÕp</i>


<b>Else </b>
<b> Begin</b>


<i> - dẫn về bi toán có kích thớc nhỏ hơn; </i>


<i> - gọi đệ quy;</i>
<b> End; </b>



<b>4. </b> <b>Một số ví dụ về thuật giải quy. </b>


<b>4.1 </b> <b>Bài toán tháp Hà nội. </b>


<i>Phát biĨu bμi to¸n. </i>


Truyền thuyết kể rằng tại một ngơi chùa ở Hμ nội có 3 cọc bằng kim
c−ơng vμ 64 chiếc đĩa bằng vμng, đ−ờng kính khác nhau, có lỗ trịn ở giữa.
Đầu tiên 64 đĩa nμy xếp nằm trên một cọc, to nằm d−ới, bé nằm trên. Để tu
tâm, rèn luyện tính nhẫn nại, hμng ngμy các nhμ s− niệm kinh Phật vμ di
chuyển các đĩa từ cọc nμy sang cọc khác. Quy tắc di chuyển lμ mỗi lần chỉ
chuyển đ−ợc một đĩa ở trên cùng vμ không đ−ợc đặt đĩa to hơn lên trên đĩa bé
hơn.


Bμi toán: chuyển toμn bộ 64 đĩa từ cọc <i>x</i> (= xuất phát) ban đầu sang
một cọc mới lμ <i>d </i> (=đích). Trong q trình di chuyển có thể xếp tạm lên một
cọc cịn lại <i>tg</i> lμm trung gian.


<i>Ph©n tÝch. </i>


Kích th−ớc của bμi tốn lμ số đĩa <i>n</i> = 64.


Giả sử đã biết cách giải bμi toán với <i>n</i> nhỏ hơn: chuyển <i>n-1</i> đĩa theo
đúng các quy tắc nêu trên, từ một cọc ban đầu sang một cọc khác, dùng cọc
còn lại lμm trung gian. Thế thì có thể giải bμi toán với <i>n</i> đĩa nh− sau:


- Chuyển <i>n-1</i> đĩa từ <i>x</i> sang <i>tg</i> lấy <i>d</i> lμm trung gian.
- Chuyển nốt <i>1</i> đĩa từ <i>x</i> sang <i>d</i>.


- Chuyển <i>n-1</i> đĩa từ <i>tg</i> sang <i>d </i>lấy <i>x</i> lμm trung gian.



- Tr−ờng hợp suy biến: <i>n = 1</i>. Lúc nμy có ngay lời giải trực tiếp.
Chuyển một đĩa từ <i>x</i> sang <i>d</i>.


</div>
<span class='text_page_counter'>(150)</span><div class='page_container' data-page=150>

- Tham số 1: số đĩa.


- Tham số 2: cọc đĩa xuất phát.
- Tham số 3: cọc đích.


- Tham số 4: cọc lm trung gian.
Tham số đầu ra: kh«ng cã.


Theo đúng khn mẫu viết thủ tục đệ quy, thủ tục <i>Hanoi</i> bắt đầu với
tr−ờng hợp suy biến, khi chỉ có 1 đĩa. Tr−ờng hợp số đĩa nhiều hơn 1, bμi
toán đ−ợc phân rã ra nh− đã trình bμy ở trên. Hai lời gọi đệ quy đ−ợc thực
hiện để giải 2 bμi toán nhỏ hơn với <i>n-1</i> đĩa. L−u ý <i>thứ tự</i> của các tham số đầu
vμo thứ 2, thứ 3, thứ 4 lμ <i>rất quan trọng</i> vì nó t−ơng ứng với vai trị lμ cọc đĩa
xuất phát, cọc đích, cọc trung gian trong thao tác chuyển đĩa.


procedure hanoi(n: integer ; x,d,tg: char);
begin


if n=1 then


writeln(' chuyen dia: ',x,' -> ',d)
else


begin


hanoi(n-1,x,tg,d);


hanoi(1,x,d,tg);
hanoi(n-1,tg,d,x);
end


end;


<b>4.2 </b> <b>Bài toán vÕt mùc. </b>
4.2.1


4.2.2


<i>Ph¸t biĨu bμi to¸n. </i>


Có một tờ giấy kẻ ô l−ới vuông. Một số vết mực loang trên tờ giấy.
Cần tính diện tích của từng vết loang. Coi diện tích lμ số ơ dính mực. Nếu gọi
những ơ dính mực gọi lμ ơ đen, những ơ khơng dính mực lμ ơ trắng thì bμi
tốn trở thμnh đếm cụm số ơ đen liên thơng chứa một ơ đã chọn.


Bμi to¸n nμy cã nhiỊu ứng dụng trong xử lí ảnh.
<i>Phân tích. </i>


Cú th đề xuất một thuật giải đệ quy nh− sau. Diện tích của vết mực
giả sử lμ <i>n</i> ơ. Nếu ta đã biết cách đếm số ô đen của mọi vết có diện tích nhỏ
hơn hay bằng <i>n -1</i> thì hoμn toμn giải quyết đ−ợc bμi tốn bằng cách: xuất
phát từ một ô đen trong vùng; đếm 1; đánh dấu ô đã chọn thμnh ô trắng;
chọn một ơ kề nó; đếm cụm ơ đen liên thông với ô nμy. Việc nμy lμm đ−ợc
theo giả thiết vì vết đen nμy có diện tích bằng <i>n-1</i>.


Lu ý rằng một ô bất kì có 8 ô kề nó nên trong hm <i>Dem_O_Den</i>



</div>
<span class='text_page_counter'>(151)</span><div class='page_container' data-page=151>

Tr−ờng hợp suy biến: khơng cịn ô kề nμo lμ ô đen nữa. Ô đang xét lμ
ơ trắng thì kết thúc vμ trả về số đếm bằng 0.


x x
x x


x x x x
x x x


x x x
x x x x
x x x
x x x
x x x x


x x x


<i>Hình 11.4: Minh hoạ bi toán vết mùc </i>


4.2.3 <i>Viết hμm đệ quy. </i>


Hμm đệ quy <i>Dem_O_Den </i>triển khai thuật giải đệ quy nh− trình by
trờn.


Tham số đầu vo:


- Tham số 1: <i>Luoi </i> lμ mét m¶ng hai chiỊu mμ mỗi phần tử của nó chỉ
nhận hai giá trị <i>Den</i> hc <i>Trang</i>.


- Tham số 2: <i>x</i> toạ độ x của ô xuất phát.


- Tham số 3: <i>y</i> toạ độ y của ô xuất phát.
Tham số đầu ra: tên hμm chứa kết quả đếm.


const MaxX = 10; MaxY = 10;


type MangBit = array[1..MaxX,1..MaxY] of (Den,Trang);
var A: MangBit;


i,j: integer;
Dau: byte;


function Dem_O_Den(Var Luoi: MangBit; x,y: integer): word;
begin


if (x<1) or (x>MaxX) or (y<1) or (y>MaxY) then
Dem_O_Den:=0


else if Luoi[x,y] = Trang then Dem_O_Den:= 0
else {Ô Đen}


begin


Luoi[x,y]:= Trang;


Dem_O_Den:= 1+ Dem_O_Den(Luoi,x-1,y-1)


</div>
<span class='text_page_counter'>(152)</span><div class='page_container' data-page=152>

end;
end;



BEGIN


Writeln(' Cho mang 10 x 10 so 0/1 theo tung hang ');
for i:=1 to MaxX do


begin


write('cho hang ',i,': ');
for j:=1 to MaxY do


begin


read(Dau);


if Dau = 1 then A[i,j]:= Den
else A[i,j]:=Trang;


end;
readln;
end;


Writeln('So o Den la ', Dem_O_Den(A,1,2));


END.


Để kiểm tra hoạt động của hμm vừa xây dựng ta dùng mảng <i>10 x 10</i> số
0/1 nhập từ bμn phím theo từng hμng, mỗi lần một hμng 10 số 0 hoặc 1. Số 0
ứng với ô trắng, số 1 ứng với ô đen.


Cã thể chọn ô xuất phát l bất cứ ô no, miƠn lμ thc vÕt mùc cÇn tÝnh


diƯn tÝch.


Nếu nhập đúng dữ liệu vμo nh− hình vẽ trên thì ch−ơng trình phải cho
két quả tính đúng diện tích lμ <i>16 </i>của vết mực chứa ô (1,2) .


<b>4.3 </b> <b>Tìm kiếm nhị phân </b>
4.3.1


4.3.2


<i>Phân tích. </i>


Giả sử có dãy khố đã sắp theo thứ tự tăng dần. Cho một giá trị khoá <i>x</i>.
Hãy viết thủ tục tìm kiếm xem dãy có chứa giá trị khố <i>x</i> khơng. Đây lμ
khái qt hố của các bμi tốn kiểu nh− tìm một từ trong tự điển, tìm một tên
ng−ời trong một danh sách đã xếp thứ tự...


Thủ tục tìm kiếm nhị phân lμ thích hợp nhất cho tr−ờng hợp nμy. Một
thủ tục tìm kiếm nhị phân sử dụng vịng lặp đã đ−ợc trình bμy khi nói về tìm
kiếm trong mảng. D−ới đây lμ triển khai d−ới dạng một thủ tục đệ quy. Thủ
tục tìm kiếm đệ quy sẽ tiến hμnh chia đơi dãy khố vμ gọi đệ quy để xử lí
một trong hai dãy con có chứa khố <i>x</i>. Tr−ờng hợp suy biến lμ dãy chỉ còn
một phần tử, có ngay kết quả trực tiếp.


<i>Viết hμm đệ quy. </i>
Tham số đầu vμo:


- Tham sè 1: chỉ số đầu mút trái của d·y con ®ang xÐt. <i>l </i>


</div>
<span class='text_page_counter'>(153)</span><div class='page_container' data-page=153>

- Tham số 3: giá trị khoá <i>x</i> cần tìm.


- Tham số 4: mảng <i>a</i> chứa các kho¸.


Tham số đầu ra: tên hμm, chứa kết quả tìm thấy hay khơng.
Theo đúng khn mẫu chung của một tủ tục đệ quy, hμm


<i>TimKiemNhiPhan</i> bắt đầu bằng trờng hợp suy biến, khi dÃy khoá chỉ gồm


một phần tử.


function TimKiemNhiPhan(l,r: integer; x: real; var a: mang):
boolean;


var m: integer;


TimThay: boolean;
begin


if l=r then begin TimKiemNhiPhan:= (a[r]=x); exit; end;
TimThay:= False;


m:=(l+r) div 2;
if x=a[m] then
begin


TimThay:= True;
exit;


end
else



begin


if x<a[m] then r:=m-1 else l:=m+1;
TimThay:= TimKiemNhiPhan(l,r,x,a);
end;


TimKiemNhiPhan:= TimThay;
end;


<b>4.4 </b> <b>Sắp xếp kiểu phân đoạn hay sắp xÕp nhanh - Quick Sort. </b>
4.4.1 <i>Ph©n tÝch. </i>


Sắp xếp kiểu phân đoạn hay sắp xếp nhanh lμ một thuật giải sắp xếp
khá hiệu quả do C.A.R. Hoare đề xuất. ý t−ởng của thuật toán xuất phát từ
việc phân tích cải tiến ph−ơng pháp đổi chỗ kết hợp với sử dụng thủ tục đệ
quy.


Nội dung cụ thể của thuật tốn có thể mơ tả nh− sau:
- Chọn một phần tử <i>x </i> nμo đó trong dãy lμm phần tử chốt.
- Tiến dần từ trái sang phải cho đến khi gặp <i>a[i] > x;</i>


- Tiến dần từ phải sang trái cho đến khi gặp <i>a[j] < x;</i>
- Đổi chỗ <i>a[i]</i> cho <i>a[j].</i>


</div>
<span class='text_page_counter'>(154)</span><div class='page_container' data-page=154>

chia lμm hai phần, nửa trái gồm ton các phần tử <i>< x</i>, nửa phải gồm ton
các phần tử ><i> x</i>. Điều ny giải thích tại sao lại gọi phần tử <i>x</i> l chốt.


Nh− vậy dãy ban đầu đã đ−ợc phân rã thμnh hai dãy con, bμi toán ban
đầu đ−ợc phan rã thμnh hai bμi toán con đồng dạng. Sử dụng thủ tục đệ quy ở
đây lμ một điều tự nhiên. Tr−ờng hợp suy biến lμ dãy con chỉ còn một phần


tử.


4.4.2 <i>Viết thủ tục đệ quy. </i>
Tham s u vo.


- Tham số 1: chỉ số đầu mút trái của dÃy con đang xét. <i>l </i>


- Tham số 2: chỉ số đầu mút phải <i>r </i> cđa d·y con ®ang xÐt.


Tham số đầu ra: khơng có. Kết quả thủ tục phân đoạn lμm thay đổi vị
trí của các phần tử của một mảng lμ biến toμn cục nên không cần đ−a
vμo danh sách tham số.


procedure PhanDoan (l,r: integer);
var x,w:...;


begin


i:=l; j:=r; { l=left; r=right }
“chon mot phan tu x lam chot”
repeat


while a[i] < x do i:=i+1;
while x < a[j] do j:=j-1;
if i<=j then


begin w:=a[i];a[i]:=a[j];a[j]:=w;
i:=i+1; j:=j-1;


end


until i>j;


if l<j then PhanDoan(l,j);
if i<r then PhanDoan(i,r);
end;


L−u ý rằng trong thủ tục trên, điều kiện "cho đến khi gặp nhau" để kết
thúc một b−ớc phân đoạn đ−ợc thể hiện bằng câu lệnh <i>until i>j</i> chứ khơng
phải <i>until i=j</i>. Lí do lμ vì điều kiện <i>i>j</i> ln sẽ xảy ra, cịn điều kiện <i>i=j</i>
có thể khơng xảy ra trong q trình trên.


Thủ tục sắp xếp nhanh chỉ bao gồm duy nhất một lời gọi đến thủ tục
phân đoạn áp dụng cho dãy xuất phát ban đầu.


procedure Quicksort;
begin


</div>
<span class='text_page_counter'>(155)</span><div class='page_container' data-page=155>

<b>5. </b> <b>Tự xây dựng th viện chơng trình con - Units </b>
<b>5.1 </b> <b>Sử dụng lại các chơng trình con </b>


Các ch−ơng trình con th−ờng dùng, cần lμm sẵn để sử dụng lại nhiều
lần trong ch−ơng trình chính cũng nh− trong t−ơng lai về sau nμy. Có hai
cách để sử dụng lại các ch−ơng trình con:


1- Chỉ thị cho trình biên dịch chèn trực tiếp tệp mà nguồn của chơng
trình con vo chỗ cần thiết khi tiến hnh biên dịch chơng trình. Theo cách
ny ta thêm chỉ thị biên dịch (<i>compiler directive</i>) sau đây vo vị trí muốn
chèn thêm tệp mà nguồn của chơng trình con.





{$I <i>tên tệpmà nguån</i> }


Công dụng của chỉ thị trên hoμn toμn giống nh− ta sao lại vμ chèn thêm
một cách thủ cơng đoạn mã nguồn của ch−ơng trình con vμo vị trí đó.


2- Tỉ chøc thμnh c¸c th− viện chơng trình con - các <i>Unit</i>


Cỏc hm, th tc mẫu hay dùng trong ch−ơng trình có thể tổ chức
riêng thμnh một th− viện ch−ơng trình con. Nếu có nhiều ch−ơng trình con
thì ng−ời ta chia lμm nhiều th− viện, nhóm theo chức năng, mỗi phần lμ một
Unit. Khi xây dựng một ch−ơng trình rất lớn, có thể cần đến nhiều Unit
ch−ơng trình con.


TurboPascal đã lμm sẵn một th− viện các ch−ơng trình con th−ờng sử
dụng nhất. Đây lμ các Unit chuẩn.


Các hμm thủ tục có sẵn trong các Unit chuẩn mặc dù rất phong phú
nh−ng vẫn ch−a thể đáp ứng tr−ớc tất cả các nhu cầu vô cùng đa dạng của khi
viết các ch−ơng trình ứng dụng. Ng−ời lập trình hoμn toμn có thể lμm thêm
các th− viện bổ xung các ch−ơng trình con cần thiết cho lĩnh vực chun
ngμnh của mình, cho bμi tốn thực tiễn của mình, theo ý muốn của mình.


<b>5.2 </b> <b>CÊu tróc cđa mét unit. </b>


Để xây dựng một Unit vμ sử dụng nó trong ch−ơng trình ta phải theo
những quy định chính xác trong từng cơng đoạn. D−ới đây sẽ trình bμy lần
l−ợt từng b−ớc.


5.2.1 <i>Khung cÊu tróc. </i>



Khung cấu trúc để viết một Unit nh− sau:


</div>
<span class='text_page_counter'>(156)</span><div class='page_container' data-page=156>

<b>Uses</b> .... ;
INTERFACE


<b>Const</b> <i>tªn h»ng = giá trị; </i>


<b>Type</b> <i>tên kiểu = mô tả kiểu</i>;


<b>Var </b> <i>tên biến: kiểu dữ liệu ;</i>


<b>Procedure</b> <i>tên thủ tục (ds các tham số);</i>
<b>Function</b> <i>tên hm (ds các tham số): kiểu</i>


<i> dữ liệutrả vÒ;</i>


Giao diện với bên ngoμi:
Phần khai báo các hằng, biến,
kiểu vμ <i>nguyên mẫu</i> của các
hμm, thủ tục để cho bên ngoμi
sử dụng. Triển khai mã lệnh
chi tit s c thc hin
trong on <i>Implementation</i>


dới đây.
IMPLEMENTATION


<b>Uses</b> ...;



<b>Const</b> ....;


<b>Type</b> ... ;


<b>Var</b> ...;


Khai b¸o c¸c h»ng, biÕn, kiĨu


<i>nội bộ</i> để dùng ở bên d−ới,


trong c¸c hμm, thđ tơc


<b>Procedure </b>....;
Begin
....
End;


<b>Function </b>.... ;
Begin
....
End;


TriĨn khai m· lƯnh chi tiÕt
c¸c hμm, thđ tơc <i>néibé</i> vμ
c¸c hμm thđ tơc <i>lμm giao diƯn</i>


đã khai báo trong phần


<i>Interface</i>.



END. {<i>cña Unit</i>} L−u ý không có BEGIN
tơng ứng


5.2.2 <i>Các thnh phần. </i>


Nh vậy, các thnh phần trong Unit gồm hai lo¹i.


Loại <i>nội bộ</i> nghĩa lμ chỉ sử dụng bên trong Unit, sẽ dùng đến khi triển
khai các mã lệnh bên trong thân Unit, chỉ ng−ời xây dựng Unit biết. Những
thμnh phần nμy không khai báo trong phn <i>Interface</i>.


Loại <i>lm giao diện</i> l những cái dnh cho bên ngoi sử dụng, phải khai
báo trong phần <i>Interface.</i>


Những điểm khác với khung cấu trúc của một chơng trình bình
thờng l:


</div>
<span class='text_page_counter'>(157)</span><div class='page_container' data-page=157>

- Cú thêm phần giao diện bắt đầu bằng từ khoá <i>Interface</i> để khai báo
tất cả các <i>hằng, kiểu, biến</i> vμ <i>các ch−ơng trình con</i> dμnh cho bên ngoμi sử
dụng. L−u ý rằng trong phần nμy các hμm, thủ tục chỉ đ−ợc khai báo <i>nguyên </i>
<i>mẫu</i> gồm tên, danh sách tham số hình thức vμ kiểu dữ liệu trả về, còn phần
triển khai mã lệnh, tức lμ phần thân lại nằm trong phần <i>Implementation</i>.


- Phần triển khai –<i>Implementation</i> - lμ nội dung chính của unit, sẽ
chứa thân của tất cả các hμm, thủ tục đã khai báo trong phần giao diện ở trên
cùng với các ch−ơng trình con khác nữa phục vụ cho việc thực hiện các hμm,
thủ tục lμm giao diện nếu có.


<b>5.3 </b> <b>Biên dịch và sử dụng. </b>
5.3.1



5.3.2


<i>Biên dịch </i>


Tiến hnh biên dịch tệp mà nguồn của các unit cũng hon ton nh
biên dịch một chơng trình thông thờng. Chọn <i>Compile</i> hoặc gõ phím tắt


<i>Alt+F9.</i> Tuy nhiên, tệp kết quả nhận đợc sẽ có phần mở rộng l TPU


(<i>Turbo Pascal Units</i>) chứ không phải lμ mét tƯp cã phÇn më réng <i>exe</i>.


Phải thiết lập mục chọn <i>Compile / Destination ... Disk</i> để ghi tệp kết
quả ra đĩa chứ không chỉ để trong bộ nhớ (<i>Destination ... Memory</i>).


L−u ý xác định nơi đặt tệp kết quả thông qua mục chọn <i>Options / </i>


<i>Directories / TPU & EXE Directory</i>. Có thể đặt chung trong th− mục các


Unit chuẩn của Turbo Pascal bằng cách điền đ−ờng dẫn đầy đủ


"<i>C:\tp\Units</i>" vμo trong ô " <i>TPU & EXE Directory</i> ". Cũng có thể đặt trong
một th− viện các unit của riêng mình, ví dụ "<i>C:\tp\MyUnits</i>".


<i> Sư dơng </i>


Muốn sử dụng một Unit trong một ch−ơng trình thì phải khai báo tại
đầu ch−ơng trình giống nh− đối với các Unit chuẩn của Turbo Pascal.


<b>Uses</b> <i>danh s¸ch c¸c Unit</i> ;



Để trình biên dịch có thể tìm đ−ợc tệp TPU t−ơng ứng, cần chỉ rõ nơi
đặt nó. Mở mục chọn <i>Options / Directories </i>vμ bổ xung thêm đ−ờng dẫn, ví
dụ "<i>C:\tp\MyUnits</i>" trong ơ "<i>Units Directories</i>".


<b>5.4 </b> <b>VÝ dơ minh ho¹. </b>


</div>
<span class='text_page_counter'>(158)</span><div class='page_container' data-page=158>

unit tools;
interface


const EscKey = #27;


procedure Say(x,y: byte; St: string);
implementation


uses Crt;


procedure Say;


begin gotoXY(x,y);
write(St);
end;


END. {unit tools}


Soạn thảo một tệp <i>Tools.pas</i> có nội dung nh− trên. Biên dịch thμnh
tệp <i>Tools.tpu</i>, đặt trong th− mục nμo đó, ví dụ <i>C:\tp\MyUnits</i>. Ta đã có Unit


<i>Tools</i> sẵn sμng s dng.



Chơng trình dới đây sử dụng Unit <i>Tools.</i>
program ViDu1Unit;


Uses Crt, Tools;
BEGIN Clrscr;


Say(10,10,' Day la thu tuc Say trong Tools unit !');
repeat


until Readkey = EscKey;
END.


<b>5.5 </b> <b>So s¸nh viƯc dïng Unit víi chÌn trùc tiÕp tƯp m∙ nguån </b>


Nh− đã trình bμy trên, để sử dụng lại các ch−ơng trình con đă đ−ợc xây
dựng hoμn chỉnh có thể chèn trực tiếp mã nguồn của chúng vμo ch−ơng trình
hoặc tổ chức thμnh các Unit.


Tổ chức thnh Unit thì mỗi khi dịch chạy thử chơng trình chính, các
Unit không cần phải dịch lại.


Nếu chèn trực tiếp mà nguồn vo tệp chơng trình chính bằng chỉ thị
cho trình biên dịch


{$I <i>tên tệp mà nguồn</i> }


thỡ tt cả những đoạn mã chèn thêm nμy đều đ−ợc dịch lại toμn bộ mỗi khi
chạy thử. Do đó khơng nên theo cách nμy khi có nhiều ch−ơng trình con dμi
vμ phức tạp.



</div>
<span class='text_page_counter'>(159)</span><div class='page_container' data-page=159>

TurboPascal cung cấp các th− viện lμm sẵn, đó lμ các Unit chuẩn. Các
Unit chuẩn chứa các hằng, các kiểu dữ liệu, các biến, các hμm thủ tục mẫu để
ng−ời lập trỡnh Pascal s dng.


Các Unit chuẩn đợc chứa trong tệp <i>Turbo.tpl</i>. Chúng đợc tổ chức
theo từng nhóm chức năng. Danh sách các Unit chuẩn nh sau.


Tên Néi dung


<i>Crt </i>
<i>Dos </i>
<i>Graph </i>
<i>Graph3 </i>
<i>Overlay </i>
<i>Printer </i>
<i>System </i>


<i>Turbo3 </i>
<i>WinDos</i>


Hiển thị mμn hình, đọc mã bμn phím...
Khai thác các chức năng của DOS
Các hμm, thủ tục đồ hoạ


Các hμm, thủ tục đồ hoạ t−ơng thích với phiên bản 3.0
Cho chế độ overlay


Phơc vơ sư dơng m¸y in


Các hμm, thủ tục chuẩn hay dùng. Unit <i>System</i> luôn tự


động đ−ợc gọi, không cần khai báo trong danh sách sau từ
khoá Uses


Để tơng thích lùi với phiên bản 3.0
Để lập trình cho môi trờng window


Cn tham khảo tμi liệu để biết đ−ợc nội dung chi tiết về tên gọi, giá trị
vμ ý nghĩa của các hằng, kiểu, biến cũng nh− chức năng vμ cách sử dụng các
ch−ơng trình mẫu đã đ−ợc lμm sẵn trong từng unit.


<b>6. </b> <b>Giíi thiƯu Unit CRT. </b>


Unit CRT (<i>Catot Ray Tube</i>) lμ Unit chứa các hằng, biến, hμm, thủ tục
điều khiển việc hiển thị lên mμn hình ở chế độ văn bản, xử lí mã bμn phím vμ
âm thanh của loa trong máy tính.


<b>6.1 </b> <b>C¸c biÕn </b>


Các biến đã đ−ợc định nghĩa trong <i>Crt:</i>


Tªn biÕn KiĨu


<i>CheckBreak </i>
<i>CheckEOF </i>
<i>DirectVideo </i>
<i>CheckSnow </i>
<i>LastMode </i>


<i>Boolean </i>


<i>Boolean </i>
<i>Boolean </i>
<i>Boolean </i>


</div>
<span class='text_page_counter'>(160)</span><div class='page_container' data-page=160>

<i>TextAttr </i>


<i>WindMin </i>
<i>WindMax </i>


<i>Byte </i>


<i>Word </i>


<i>Word</i>


(Xem c¸c thđ tơc <i>TextColor, </i>


<i>TextBackGround, Highvideo</i>,


<i>LowVideo</i>)


(Xem thđ tơc <i>Window</i>)
(Xem thđ tơc <i>Window</i>)


Y nghĩa của chúng sẽ đ−ợc giải thích kĩ hơn khi nói đến các hμm, thủ
tục có liên quan.


<b>6.2 </b> <b>Các hàm, thủ tục </b>


Phn ny s kho sỏt tóm tắt các hμm, thủ tục có trong Unit <i>Crt</i>.


Nguyên mẫu của từng hμm thủ tục sẽ d−ợc trình bμy để cung cấp giao diện
cho ng−ời sử dụng. Công dụng hay chức năng sẽ đ−ợc nêu vắn tắt.


<b>ClrEol</b>;


Xố từ vị trí con chạy đến cuối dịng.


<b>ClrScr</b>;


Xoá sạch mn hình bằng mu nền hiện tại, đa con chạy mn hình vỊ
vÞ trÝ (1,1)




<b>DelLine</b>;


Xoá dòng có con chạy mn hình, các dòng dới dồn lên.


<b>InsLine</b>;


ChÌn thªm mét dòng trắng tại vị trí con chạy.


<b>GotoXY</b>(<i>x,y:byte</i>);


Đa con chạy mn hình về vị trí (x,y)


<b>WhereX</b>: <i>byte</i>;


Hμm trả lại toạ độ X của con chạy mμn hình hiện tại



<b>WhereY</b>: <i>byte</i>;


Hμm trả lại toạ độ Y của con chạy mμn hình hiện tại


Vị trí toạ độ trên mμn hình nói đến trong các hμm, thủ tục trên đều lμ


<i>giá trị t−ơng đối</i> trong cửa sổ mμn hình hiện tại, thiết lập bi th tc <i>Window</i>


trình by dới đây.


<b>Window</b>(<i>x1,y1,x2,y2:byte</i>) ;


</div>
<span class='text_page_counter'>(161)</span><div class='page_container' data-page=161>

ghi t−¬ng øng trong 2 biÕn <i>WinMin, WinMax</i>. Cơ thĨ h¬n, <i>x1 = </i>


<i>Lo(WinMin) , y1 = Hi(WinMin), x2 = Lo(WinMax), y2 = Hi(WinMax)</i>.


Sau lời gọi thủ tục <i>Window</i> thì phạm vi tác dụng của nhiều hμm,
thủ tục điều khiển việc hiển thị ra mμn hình sẽ giới hạn trong khung
của sổ nμy. Mμn hình coi nh− đ−ợc thu nhỏ lại. Điểm góc trên-trái của
khung cửa sổ sẽ có toạ độ <i>(1,1).</i>


<i>Window(1,1,80,25)</i> sẽ trả lại vùng hiển thị l ton mn h×nh.


<b>6.3 </b> <b>Màu sắc và chế độ màn hình văn bản. </b>


Mμn hình có nhiều chế độ hiển thị văn bản khác nhau., goi lμ các


<i>Mode</i> mμn h×nh. Dới đây l bảng các giá trị của <i>Mode</i> v ý nghĩa của chúng.



Tên hằng Gía
trị


Y nghÜa


<i>BW40 </i>
<i>C40 </i>
<i>BW80 </i>
<i>C80 </i>
<i>Mono </i>
<i>Font8x8</i>


0
1
2
3
7
256


40 x 25, đen- trắng trên mn hình mu
40 x 25 trên mn hình mu,


80 x 25 đen trắng trên mn hình mu
80 x 25 trên mμn h×nh mμu


80 x 25 trên mμn hình đơn sắc.


45 / 50 dßng cho mμn h×nh EGA / VGA.


<b>TextMode</b>(<i>Mode: Integer</i>);



Đặt chế độ (mode) hiển thị của mμn hình văn bản.
Tác dụng:


- Cưa sỉ mμn h×nh hiƯn tại sẽ trở lại l ton bộ mn hình, con chạy
mn hình về vị trí <i>(1,1).</i>


- Thuc tính video hiển thị văn bản đ−ợc trả về giá trị xuất phát, tr−ớc
khi ch−ơng trình bắt đầu, thơng qua việc gọi thủ tục <i>NormVideo </i>(xem
phần d−ới về biến <i>TextAttr </i>vμ các thủ tục về chế độ video).


- Chế độ video hiện hμnh đ−ợc ghi l−u lại vμo biến <i>LastMode</i>. Do đó
lời gọi thủ tục <i>TextMode(LastMode)</i>

sẽ trở lại chế độ video đã áp



dụng ngay tr−ớc chế độ hiện tại.


</div>
<span class='text_page_counter'>(162)</span><div class='page_container' data-page=162>

...
begin


OrigMode:= LastMode; {Ghi l−u l¹i mode hiĨn thÞ cị }
...


TextMode(OrigMode);
End;


D−ới đây lμ bảng các hằng về mμu sắc, dùng để quy định mμu nền,
mμu chữ vμ độ sáng khi hiển th vn bn.


Tên mu Gía
trị



Tên mu Giá
trÞ
<i>Black </i>
<i>Blue </i>
<i>Green </i>
<i>Cyan </i>
<i>Red </i>
<i>Magenta </i>
<i>Brown </i>
<i>lightGray</i>
0
1
2
3
4
5
6
7
<i>DarkGray </i>
<i>LightBlue </i>
<i>LightGreen </i>
<i>LightCyan </i>
<i>LightRed </i>
<i>LightMagenta </i>
<i>Yellow </i>
<i>White</i>
8
9
10


11
12
13
14
15


Các mμu thuộc cột trái lμ thuộc chế độ <i>LowVideo</i>, khơng sáng chói.
Các mμu thuộc cột phải lμ thuộc chế độ <i>HighVideo</i>, lμ mμu t−ơng ứng ở cột
trái nh−ng sáng chói hơn.


Có thể dùng tên tiếng Anh hoặc giá trị số.


<b>TextBackground</b>(<i>Color: byte</i>);


Đặt mu nền. Các mu nền cã thÓ lμ <i>0..7</i> hay <i>Black .. LightGray</i>
<b>TextColor</b>(<i>Color: byte</i>);


Đặt mu chữ. Các mu chữ có thể lμ <i>0..15</i> hay <i>Black ..White</i>


BiÕn <i>TextAttr </i> l−u giữ giá trị hiện tại của các thuộc tính hiển thị văn
bản (trong 1 byte) với các ý nghĩa cña tõng bit nh− sau.


7 6 5 4 3 2 1 0


B b b b V f f f


Ba bit từ số 0 đến số 2 để xác định mμu chữ (<i>f = foreground</i>). Chúng
có thể nhận các giá trị 0..15. Ba bit từ số 4 đến số 6 để xác định mμu nền



(<i>b = background</i>). Bit số 3 để chuyển đổi giữa độ sáng thấp - <i>LowVideo</i> vμ


</div>
<span class='text_page_counter'>(163)</span><div class='page_container' data-page=163>

<b>HighVideo; </b>


Lμm mμu chữ tăng độ sáng (chói) hơn, t−c lμ đặt bit số 3 lμ 1


<b>LowVideo</b>;


Lμm mμu chữ giảm độ sáng đi, tức lμ đặt bit số 3 lμ 0


Nh− vËy, thủ tục <i>HighVideo</i> l chuyển mu chữ từ cột trái sang mu
tơng ứng trong cột phải ở bảng trên; thủ tục <i>LowVideo</i> l chuyển mu chữ
từ cột phải sang mu tơng ứng trong cột trái.


Mun lm ch nhấp nháy thì đặt bit số 7 bằng 1. Có thể dùng cách
thiết lập mμu chữ lμ <i>mμu + Blink</i> hoặc <i>mμu + 128</i>.


<b>NormVideo; </b>


Lấy lại thuộc tính hiển thị văn bản có tại vị trí con chạy ngay tr−ớc khi
ch−ơng trình bắt đầu. <i>NormVideo</i> đặt biến <i>TextAttr</i> trở lại giá trị ban
đầu tr−ớc khi chạy ch−ơng trình.


Tóm lại, việc thiết lập các thuộc tính video hiển thị văn bản đ−ợc thực
hiện thông qua việc gọi các thủ tục nói trên. Thực chất, các thủ tục nμy tiến
hμnh đặt lại các bít t−ơng ứng của biến <i>TextAttr</i>.


Ta hoμn toμn có thể can thiệp đặt giá trị của chúng một cách trực tiếp.
Ví dụ lệnh gán <i>TextAttr:= Yellow + Blue * 16 + 128</i> sẽ cho chữ mμu vμng
trên nền xanh vμ nhấp nháy.



VÝ dơ sư dơng c¸c thđ tơc <i>NormVideo, TextBackGround, TextColor</i>
uses Crt;


begin


{Chữ xanh trên nền đen}
TextColor(Green);


TextBackground(Black);
WriteLn('Hey there!');


{ Chữ mμu đỏ sáng trên nền xám }
TextColor(LightRed+Blink);


TextBackground(LightGray);
WriteLn('Hi there!');


{ Chữ vng trên nền xanh}


TextColor(14); { Yellow = 14 }
TextBackground(Blue);


WriteLn('Ho there!');


NormVideo; {Trë l¹i thuéc tính ban đầu }
WriteLn('Back to normal...');


</div>
<span class='text_page_counter'>(164)</span><div class='page_container' data-page=164>

<b>6.4 </b> <b>Xö lÝ gâ phÝm. </b>



<b>KeyPressed</b>: <i>boolean;</i>


Hμm kiÓm tra khi gâ phÝm bÊt k× .


<b>ReadKey</b>: <i>char;</i>


Trả lại mà quét của phím đợc gõ từ bn phím.


Cỏc phớm thng khi gõ tạo ra một mã. Các phím mở rộng khi gõ tạo
ra hai mã, trong đó mã đầu ln lμ kí tự <i>NUL = #0</i>. Do đó để nhận biết các
phím mở rộng cần bỏ qua kí tự <i>NUL</i> vμ đọc tiếp mã thứ hai:


Gophim:= ReadKey;


If gophim = #0 then gophim:= ReadKey;
...


Mét sè m· phÝm v tổ hợp phím thờng dùng.


Các phím thờng: <i>Esc =#27 , Tab = #9, Enter = #13 ...</i>


C¸c phÝm më réng vμ tỉ hỵp phÝm:
#0 / #72


#0 / #80
#0 / #77
#0 / #75


Home #0 / #71
End #0 / #79


PgUp #0 / #73
PgDn #0 / #81


F1 #0 / #59
F2 #0 / #60 ...
F10 #0 / #68
Ctrl +F1 #0 / #94
Ctrl + F2 #0 / #95 ...


<b>6.5 </b> <b>C¸c thđ tơc kh¸c </b>
<b>Delay</b> (<i>ms): word</i>;


Tạm ng−ng hoạt động của máy tính trong khoảng thời gian <i>ms</i>


milliseconds


<b>NoSound;</b>


Tắt âm thanh của loa trong máy tính.


<b>Sound</b>(<i>Hz: Word</i>);
Phát âm có tần số <i>Hz</i>,


Ví dụ: Chơng trình chơi nhạc từ bn phím.
Uses crt;


Var ch: char;
BEGIN


</div>
<span class='text_page_counter'>(165)</span><div class='page_container' data-page=165>

Repeat



Ch:= readkey;


Case ch of


'd': begin nosound; sound(262) end;
'r': begin nosound; sound(294) end;
'm': begin nosound; sound(330) end;
'p': begin nosound; sound(349) end;
's': begin nosound; sound(392) end;
...


end; {case}


until ch = esc;
nosound;
END.


<b>7. </b> <b>VÝ dơ øng dơng - Lµm b¶ng chän. </b>


Bảng chọn lμ một cơng cụ rất hay đ−ợc dùng đến. Vận dụng những
kiến thức đã trình bμy trong ch−ơng nμy, ta viết một ch−ơng trình con tạo
bảng chọn kiểu <i>popup</i>. Sau đó sẽ thử tổ chức nó thμnh Unit ch−ơng trình mẫu
để sử dng li sau ny.


<b>7.1 </b> <b>Các bớc xây dựng b¶ng chän. </b>


<i>Xác định u cầu</i>: Ch−ơng trình con vẽ bảng chọn nổi lên trên mμn


hình văn bản; cho phép chọn bằng các phím mũi tên <i>Up, Down</i> (chứ khơng


phải gõ một số hay chữ), có đổi mầu lμm nổi mục chọn; gõ phím <i>Enter</i> để
xác nhận việc chọn; gõ phím <i>Esc</i> để thốt.


<i>Phân tích bμi toán</i>: Mặc dù yêu cầu đặt ra lμ viết một ch−ơng trình con


tạo vμ xử lí bảng chọn nh−ng ta vẫn phải thực hiện một ch−ơng trình hoμn
chỉnh chứa ch−ơng trình con nói trên để có thể kiểm tra nú hot ng ỳng
yờu cu.


Chơng trình con lm bảng chọn có chức năng nh sau:


- Đầu vμo: toạ độ góc trên trái của bảng chọn trên mμn hình, số mục
chọn, nhãn tên từng mục chọn, mμu chữ, mμu nền khi bình th−ờng vμ mμu
chn khi cn lm ni mc ang chn...


- Đầu ra:


1- Hiển thị trên mμn hình một bảng chọn hình chữ nhật, có một mục
chọn nổi bật, lμ lựa chọn mặc định ban đầu.


2- Xö lÝ sù kiƯn khi gâ c¸c phÝm:


- NÕu gõ phím mũi tên <i>Up, Down</i> thì mục chọn đợc lm nổi bật cũng
di chuyển theo lên trên hoặc xng d−íi;


- Nếu gõ <i>Enter</i> thì phải trả lại một giá trị để nhận biết lμ đã chọn mục
nμo. Thông th−ờng giá trị nμy lμ số thứ tự của mục chọn trên bảng chọn.


</div>
<span class='text_page_counter'>(166)</span><div class='page_container' data-page=166>

- Nếu gõ bất kì phím no khác thì không có tác dụng gì hoặc phát
chuông cảnh báo.



- Tr−ờng hợp đặc biệt: gõ phím mữi tên <i>Up</i> khi đang ở mục chọn đỉnh
bảng vμ gõ mũi tên <i>Down</i> khi đang ở mục chọn đáy bảng thì xử lí cho phép
"xoay vịng trịn".


<i>ThiÕt kÕ ch−¬ng trình</i>: Chơng trình con tạo v xử lí bảng chọn sẽ


đợc triển khai chi tiết dần từng bớc trong tiÕt sau.


<i>TriĨn khai, viÕt m· lƯnh</i>: Chun thiÕt kế chi tiết bớc trớc thnh các


câu lệnh Pascal.


<i>Chạy thử để kiểm tra: </i>


- Thay đổi số mục chọn, các nhãn tên mục chọn, mμu nền, mμu chữ ...
- Theo dõi hμnh vi khi gõ các phím khác nhau.


<b>7.2 </b> <b>Ph©n tÝch thiÕt kÕ chi tiÕt dÇn tõng b−íc. </b>


Tiết nμy sẽ minh hoạ ph−ơng pháp thiết kế chi tiết dần từng b−ớc để
xây dựng ch−ơng trình tạo bảng chọn đã nêu trên.


Để tiện trình bμy ta sẽ dùng 1 chữ số để đánh số các bμi toán con ở
mức chi tiết 1, sẽ dùng hai chữ số để đánh số các bμi tốn con chi tiết cơng
việc ở mức 2. Chữ số thứ nhất kế thừa từ mức 1, chữ số thứ 2 lμ thứ tự trong
chi tiết mức 2. Với những công việc ch−a đủ chi tiết sau b−ớc 2, ta lμm thêm
một b−ớc chi tiết nữa, dùng 3 chữ số để liệt kê theo quy −ớc trên. Vμ tiếp tục
nh− vậy nếu cần, chỉ kết thúc khi đã đủ đơn giản.



7.2.1 <i>Chi tiết mức 1 </i>


Chơng trình chính gồm 3 công việc:
- NhËp d÷ liƯu vμo.


- Ch−ơng trình con tạo vμ xử lí bảng chọn.
- Kiểm tra hoạt động của ch−ơng trình con.
1- Đọc dữ liệu vμo.


Đầu vo: vị trí góc trên trái, số mục chọn, tên các mục chọn, mu nền,
mu chọn.


Đầu ra: các hằng, biến đợc gán giá trị tơng ứng.
2- Vẽ v xử lí bảng chọn (chơng trình con b¶ng chän).


Đầu vμo: các tham số của bảng chọn đã đ−ợc gán trị cụ thể sau phần 1.
Đầu ra:


- Vẽ bảng chọn trên mn hình.


</div>
<span class='text_page_counter'>(167)</span><div class='page_container' data-page=167>

Đầu vo: một số nguyên (l kết quả trả về của mô đun xử lí bảng chọn,
khi ng−êi sư dơng gâ c¸c phÝm kh¸c nhau).


Đầu ra: In dịng thơng báo " Bạn đã chọn mục ..." trên mμn hình.


Sau b−ớc chi tiết lần thứ nhất ta có sơ đồ cấu trúc d−ới đây.


Chơng trình lm
bảng chọn popup



1.Đọc
dữ liệu vo


2: Xây dựng
bảng chọn


3: Kim tra
hot ng


<i>Hình 11.5: Sơ đồ cấu trúc của ch−ơng trình bảng chọn - chi tiết mức 1 </i>


7.2.2 <i>Chi tiÕt møc 2. </i>


1- <i>Đọc dữ liệu vμo</i>: đã đơn giản vμ quen thuộc, không cần chi tiết thêm nữa.


3- <i>Kiểm tra hoạt động của bảng chọn</i>: Khuôn mẫu chung để sử dụng bảng


chän lμ dïng c©u lƯnh lùa chän <i>Case.</i> Ta cịng sư dơng c©u lƯnh <i>Case</i>


để kiểm tra hoạt động của bảng chọn. Đầu vμo lμ số ngun <i>n.</i> Đầu ra
lμ dịng thơng báo “Chọn mục <i>n</i>”. Đây lμ một việc đơn giản, không
cần chi tit thờm na.


2- <i>Tạo v xử lí bảng chọn.</i>


Có 2 công việc rõ rng:
- Vẽ bảng chọn ban đầu.
- Xử lí gõ phím.


2.1- Vẽ bảng chọn ban đầu.



u vo: cỏc tham số đã đ−ợc gán giá trị bởi thủ tục nhập dữ liệu.
Đầu ra: Hiển thị một khung hình chữ nhật, mỗi dịng lμ nhãn tên một
mục chon, một mục nμo đó (ví dụ mục đầu tiên) đ−ợc lμm nổi bật.


2.2 - Xö lÝ khi gõ các phím.


</div>
<span class='text_page_counter'>(168)</span><div class='page_container' data-page=168>

Đầu vo: mà phím gõ vo.
Đầu ra:


- Nếu gõ <i>Enter</i>, trả về số thứ tự mục chọn hiện tại. Kết thóc.
- NÕu gâ <i>Esc</i>, tr¶ vỊ - 1. Kết thúc


- Nếu gõ các phím mũi tên <i>Up,Down,</i> thì cập nhật lại số thứ tự mục
chọn hiện tại v hiển thị bảng chọn với mục đợc chọn mới.


- Nếu gõ các phím khác. Không lμm g×.


Sau b−ớc chi tiết lần thứ hai ta nhận đ−ợc sơ đồ d−ới đây.


2.1: VÏ bảng
chọn ban đầu


2.2: Xử lí gõ
phím


Chơng trình lm
bảng chọn popup



1: Đọc dữ
liệu vo


2: Xây dựng
bảng chọn


3: Kim tra hot
ng


<i>Hình 11.6: Sơ đồ cấu trúc của ch−ơng trình bảng chọn - chi tiết mức 2 </i>


7.2.3 <i>Chi tiÕt mức 3. </i>


2.1: Vẽ bảng chọn ban đầu. Chi tiết tõng b−íc nh− sau:


2.1.1: Tính chiều dμi, chiều rộng cần thiết. Chiều dμi của bảng chọn
tính theo dịng chính lμ số mục chọn. Chiều rộng của bảng chọn phải
đủ hiển thị nhãn tên mục chọn dμi nhất.


2.1.2: Vẽ khung hình chữ nhật với mu nền.
2.1.3: Viết lần lợt tên các mục chọn.


2.1.4: Lm ni bật một mục chọn mặc định ban đầu bằng mμu chọn.
2.2: Xử lí khi gõ các phím.


Chia thnh hai trờng hợp, khi gõ các phím mũi tên <i>Up, Down</i> v khi
gõ các phím khác.


</div>
<span class='text_page_counter'>(169)</span><div class='page_container' data-page=169>

2.2.2: Xư lÝ khi gâ c¸c phÝm kh¸c.



2.1.1.Tính
chiều di,
chiều rộng.


2.1.2.Vẽ
khung hình
chữ nhật với
mu nền.


2.1.3. Viết
lần lợt tên
các mục
chọn.


2.1.4. Lμm
nổi bật một
mục chọn
mặc định.
2.1: V bng


chọn ban đầu


2.2.1: Xử lí khi
gõ mũi tên lên,
xuống


2.2.2: Xử lí khi
gõ các phím khác
2.2: Xử lí gõ



phím


<i>Hình 11.7: Chi tiết mức 3 các công việc 2.1 v 2.2</i>


n õy ta thấy hầu nh− mọi công việc đã đủ đơn giản. Phần duy nhất
cần lμm chi tiết thêm lμ mơ đun 2.2.1 - xử lí khi gõ các phím mũi tên <i>Up, </i>


<i>Down</i>.


7.2.4 <i>Chi tiÕt møc 4. </i>


NÕu kÝ hiÖu <i>i</i> lμ sè thø tự của mục chọn hiện hnh thì công việc 2.2.1
(xử lí khi gõ phím mũi tên <i>Up, Down</i>) cần thùc hiƯn lμ nh− sau.


2.2.1.1: Lμm ch×m mơc chän <i>i</i> cị tøc lμ hiĨn thÞ mơc chän <i>i</i> b»ng mμu
nỊn b×nh th−êng


2.2.1.2: CËp nhËt l¹i mơc chän <i>i</i> míi.


- G¸n <i>i:= i + 1 / i:= i - 1</i> tuú theo gâ <i>Up, Down</i>.


</div>
<span class='text_page_counter'>(170)</span><div class='page_container' data-page=170>

2.2.1.3: Lμm nỉi bËt mơc chän <i>i</i> míi. HiĨn thÞ mơc chän <i>i </i> b»ng mμu
chän.


2.2.1: Xư lÝ khi
gâ mịi tªn lªn,
xng


2.2.1.1. Lμm
ch×m mơc


chäncị


2.2.1.2. CËp
nhËt mơc chän
míi


2.2.1.3.Lm
nổi mục chọn
mới


<i>Hình 11.7: chi tiết mức 4 công viƯc 2.2.1</i>


Tóm lại, sau bốn b−ớc chi tiết dần, các công việc đã trở thμnh đơn giản.
Việc triển khai viết ch−ơng trình sử dụng Turbo Pascal hay một ngơn ngữ lập
trình nμo đó chỉ đơn thuần lμ chuyển từng công việc thμnh các câu lệnh t−ơng
ứng mt cỏch mỏy múc.


<b>7.3 </b> <b>Chơng trình chi tiết. </b>


D−ới đây lμ ch−ơng trình tạo bảng chọn nhận đ−ợc sau khi triển khai
sơ đồ trên thμnh các câu lệnh Turbo Pascal.


uses crt;


const max_SoMucChon = 8; {sè môc chän tèi ®a}


type mang_string = array[0..max_SoMucChon-1] of string;
var Ten_Muc_Chon: mang_string; {mảng các tên muc chọn}
So_Muc_Chon: word; {sè môc chän}



Mau_nen, Mau_Chon: byte;


Chon: integer; {danh so tu 0..(SoMucChon - 1),ESC = -1}
Procedure NhapThamSoBangChon;


{phÇn nhËp d÷ liƯu}
begin


So_Muc_Chon:=3;


Ten_Muc_Chon[0]:=' muc chon 1 ';
Ten_Muc_Chon[1]:=' muc chon 2 ';
Ten_Muc_Chon[2]:=' thoat ';


End;


Procedure KiemTraHoatDong;


{kiểm tra các thao tác sử dụng bảng chän}
begin;


</div>
<span class='text_page_counter'>(171)</span><div class='page_container' data-page=171>

0: begin


clrscr;


gotoXY(1,1); writeln('ban da chon:', Chon);
end;


1: begin



clrscr;


gotoXY(5,5); writeln('ban da chon:', Chon);
end;


2: begin


clrscr;


gotoXY(10,10); writeln('ban da chon:', Chon);
end;


-1: begin


clrscr;


gotoXY(20,20); writeln('ban da chon thoat !');
end;


end; {case}
end;


function BangChon(x,y,SoMucChon:word;TenMucChon:
mang_string; MauNen,MauChon: byte): integer;
{vẽ bảng chọn, xử lý thao tác chọn}
const esc=#27; {các phím để chọn}


enter =#13;
up = #72 ;
down = #80;



var rong: word; {chiều rộng bảng = tên mục chọn dμi nhÊt}
i: integer; {thø tù mơc chän hiƯn t¹i}


procedure LamNoiMucChon(i: integer); {lμm nỉi bËt mơc
chän}


begin


TextBackGround(MauChon);
gotoXY(1,i+1);


ClrEol;


write(TenMucChon[i]);
end;


procedure LamChimMucChon(i:integer); {th«i lμm næi}
begin


TextBackGround(MauNen);
gotoXY(1,i+1);


clreol;


write(TenMucChon[i]);
end;


procedure VeBangChon;
var i: integer;



begin


{tinh chieu rong}


rong:=length(TenMucChon[0]);
for i:=1 to SoMucChon -1 do


if rong < length(TenMucChon[i]) then
rong:= length(TenMucChon[i]);


</div>
<span class='text_page_counter'>(172)</span><div class='page_container' data-page=172>

TextBackGround(MauNen);
clrscr;


for i:=0 to SoMucChon -1 do
writeln(TenMucChon[i]);


{mặc định tr−ờng hợp đầu tiên đ−ợc chọn}
LamNoiMucChon(0);


end;


procedure XuLiGoPhim;
var i: integer;


gophim: char;
begin





i:=0; {mặc định ban đầu lμ mục chọn thứ nhất}


repeat


if keyPressed then
begin


gophim:=readkey;


if gophim=#0 then gophim:=readkey;


case gophim of


enter: begin BangChon:= i; exit end;
esc : begin BangChon:=-1; exit end;
up: begin


{xoa hight light}
LamChimMucChon(i);


i:= ((i+SoMucChon) -1) mod SoMucChon;
LamNoiMucChon(i);


BangChon:=i;
end;


down:



begin


LamChimMucChon(i);


i:=(i+1) mod SoMucChon;
LamNoiMucChon(i);


BangChon:=i;
end;


else ; {gõ các phím khác sẽ không có tác dụng gì}
end; {case}



end;


until (gophim=enter) or (gophim=esc);
end;


begin {function BangChon}
VeBangChon;


XuLiGoPhim;


</div>
<span class='text_page_counter'>(173)</span><div class='page_container' data-page=173>



textMode (lastMode);


end; {function BangChon}
BEGIN



NhapThamSoBangChon;
Chon:=


BangChon(10,5,So_Muc_Chon,Ten_Muc_Chon,Blue,Red);
KiemTraHoatDong;


Readln;
END.


<b>7.4 </b> <b>Chuyển thành Unit bảng chọn. </b>


Chuyn ch−ơng trình con tạo bảng chọn đã xây dựng trong tiết tr−ớc
thμnh một Unit vμ đặt vμo th− viện các Unit chuẩn của Turbo Pascal s
dng sau ny.


Để một chơng trình khác có thể sử dụng đợc hm tạo bảng chọn,
phần giao diện phải cung cấp mẫu hm <i>BangChon</i> v các dữ liệu đầu vo
nh vị trí, số mục chọn, mảng các tên mục chọn v bộ mu (mu nền bình
thờng v mu khi đợc chọn).


Nhn thấy rằng các tham số nói trên đều đã có trong danh sách tham
số của hμm bảng chọn. Các kiểu dữ liệu <i>word, byte</i> lμ các kiểu chuẩn đã
đ−ợc định nghĩa sẵn. Chỉ có kiểu <i>mang_string</i> mảng các xâu kí tự khơng
phải lμ một kiểu chuẩn nên phải khai báo nó trong phần giao diện, sau từ
khoá <i>Interface</i>.


Phần triển khai chi tiết của Unit khơng có gì khác hơn lμ thực hiện chi
tiết hμm bảng chọn nh− đã viết trong ví dụ ở tiết 3. Tóm lại, tệp <i>BgChon.pas</i>



cã néi dung nh− sau.
Unit BgChon;


<b>INTERFACE </b>


type <b>mang_string</b> = array[0..7] of string;


function <b>BangChon</b>(x,y,SoMucChon:word;TenMucChon:mang_string;
MauNen,MauChon: byte): integer;


<b>IMPLEMENTATION </b>
uses crt;


function BangChon(x,y,SoMucChon:word;TenMucChon:
mang_string; MauNen,MauChon: byte): integer;
const esc=#27;


</div>
<span class='text_page_counter'>(174)</span><div class='page_container' data-page=174>

down = #80;


var rong: word; {chieu rong bang = nhan muc chon dai nhat}
i: integer; {thu tu muc chon hien tai}


procedure LamNoiMucChon(i: integer); {lam noi bat muc chon}
begin


....
end;


procedure LamChimMucChon(i:integer); {thoi lam noi}
begin



....
end;


procedure VeBangChon;
var i: integer;


begin
....
end;


procedure XuLiGoPhim;
var i: integer;


gophim: char;
begin


....
end;


begin {function BangChon}


....


end; {function BangChon}


END. {Unit BgChon}


Biên dịch tệp <i>BgChon.pas</i> thμnh tệp <i>BgChon.tpu</i> vμ đặt vμo th− mục
các Units chuẩn của Turbo Pascal nh− đã h−ớng dẫn ở trên. Bây giờ có thể


kiểm tra thử hoạt động của bảng chọn bằng một ch−ơng trình ngắn gọn nh−
sau.


program testUnitBgChon;
uses crt, BgChon;


var SoMC: word;


TenMC: Mang_String;
Chon: integer;


Procedure NhapThamSoBangChon;
...


</div>
<span class='text_page_counter'>(175)</span><div class='page_container' data-page=175>

BEGIN


NhapThamSoBangChon;


Chon:= BangChon(10,5,SoMC,TenMC,Blue,Red);
KiemTraHoatDong;


Readln;
END.


<b>8. </b> <b>Một chơng trình ứng dụng. </b>


<i>Bi toán</i>: Xây dựng chơng trình quản lí hồ sơ của sinh viên. Chơng


trỡnh cn cú cỏc chức năng tạo tệp dữ liệu mới, mở tệp dữ liệu đã có, liệt kê
toμn bộ danh sách, tìm kiếm thơng tin về một sinh viên nμo đó, thêm một


sinh viên (vμo cuối) danh sách. Ch−a xét đến việc sửa đổi thơng tin, xố tên
một sinh viên khỏi danh sách hay sắp xếp danh sách theo mơt trật tự nμo đó
khi thêm vμo.


<b>8.1 </b> <b>Phân tích thiết kế </b>
8.1.1


8.1.2


<i>Cấu trúc dữ liÖu. </i>


Các mục dữ liệu trong hồ sơ của một sinh viên tổ chức thμnh một bản
ghi. Một danh sách sinh viên ghi lại trên đĩa sẽ lμ một tệp các bản ghi.


KiĨu d÷ liƯu hå sơ sinh viên v tệp các hồ sơ sẽ dùng trong chơng
trình có thể đợc khai báo nh sau.


Type HoSo= Record


maso:integer;
hoten:String[20];
namsinh:string[2];
end;


Var TepHoSo:File of HoSo;


<i>Chi tiÕt b−íc 1 </i>


Ch−¬ng trình gồm hai phần, phần giao diện l một bảng chọn v phần
xử lí các yêu cầu của ngời sư dơng.



Ta đã xây dựng Unit lμm bảng chọn nên bây giờ chỉ cần gọi ra sử dụng.
D−ới đây sẽ phân tích chi tiết phần xử lí các yêu cầu. Rõ rμng cần chia
ra 4 mô đun thực hiện 4 chức năng công việc chính nh− đặc tả ở trên.


<i>1 - Mở tệp</i> mới hoặc tệp đã có trên đĩa.


- Đầu vo: tên tệp cần mở


</div>
<span class='text_page_counter'>(176)</span><div class='page_container' data-page=176>

<i> 2 - Liệt kê</i> nội dung toμn bộ các bản ghi trong tệp.
- Đầu vμo: tệp đã mở sẵn sng.


- Đầu ra: hiển thị ton bộ nội dung các bản ghi có trong tệp ra mn
hình.


<i>3 - Tìm kiếm</i>: tìm một bản ghi cụ thể, hiển thị kết quả tìm kiếm lên mn hình.


- u vμo: tệp đã mở sẵn sμng, mã số của sinh viờn cn tỡm gừ t bn
phớm.


- Đầu ra: hiển thị nội dung bản ghi tìm thấy hoặc thông báo không tìm
thấy.


<i>4- Thêm</i> một bản ghi vo cuối tÖp.


- Đầu vμo: tệp đã mở sẵn sμng, mã số của sinh viên vμ các thông tin
khác nhập t bn phớm


- Đầu ra: nếu sinh viên cha có trong danh sách thì bản ghi mới đợc
thêm vo cuối tệp.



Giả sử tên của 4 thủ tục thực hiện các công việc tơng ứng l <i>Mở tệp, </i>


<i>Liệt kê, Tìm kiếm, Thêm.</i> Ta có thể viết ngay chơng trình chính, chỉ bao


gồm một số lời gọi các mô đun chơng trình con nh dới đây.


Ch−ơng trình sử dụng lại ch−ơng trình con lμm bảng chọn mμ ta đã
chuyển thμnh Unit.


BEGIN { chơng trình chính }


Clrscr;
repeat


chon:= BangChon(60,15,SoMC,TenMC,Blue, Red) + 1;
case chon of


0:exit;
1:MoTep;
2:LietKe;
3:TimKiem
4:Them;
else ;


end;


until chon = SoMC;



END.


8.1.3 <i>C¸c b−íc chi tiÕt tiÕp theo </i>


1- <i>Më tƯp</i>:


Chi tiÕt h¬n về các công việc nh sau.
1.1 - Nhập tên tƯp cÇn më


1.2 - Kiểm tra có tệp trên đĩa hay ch−a


</div>
<span class='text_page_counter'>(177)</span><div class='page_container' data-page=177>

1.4 - Xö lÝ khi ch−a cã tƯp:


1.4.1 - KiĨm tra xem ngời dùng muốn tạo tệp dữ liệu mới hay
gõ nhầm tên.


1.4.2 - Trờng hợp 1, tạo tệp mới v thông báo thnh công
1.4.3 - Trờng hợp 2, thoát ra, cho phép lm lại.


2- <i>Liệt kê</i> ton bộ danh sách.


Chi tiết các công việc nh− sau.


2.1 - Trình bμy phần tiêu đề để hiển thị danh sách.
2.2 - Đ−a cửa sổ tệp v u tp.


2.3 - Đọc bản ghi vo biến trung gian v viết ra mn hình.
2.4 - Dịch xuèng b¶n ghi tiÕp.


2.5 - Kiểm tra hết tệp, úng tp v kt thỳc.



<i>3. Tìm kiếm. </i>


Các bớc công việc


3.1 - Nhập mà số cần tìm.
3.2 - Tiến hnh tìm kiếm.


3.2.1- Đa cửa sổ tệp về đầu tệp.


3.2.2 - Đọc từng bản ghi vo biến trung gian.
3.2.3 - So sánh với mà số cần tìm


3.2.4 - Dng khi ó thấy hoặc hết tệp.
3.3 - Hiển thị kết quả.


3.3.1 - Trờng hợp tìm thấy, hiển thị nội dung biến trung gian.
3.3.2 - Trờng hợp không tìm thấy, hiển thị thông báo.


3.4 - Hỏi lại ngời dùng có cần tìm kiếm tiếp hay không.
3.5 - Xử lí tuỳ theo yêu cầu của ngời sử dụng.


3.5.1 - Có: lặp lại việc tìm kiếm
3.5.2 - Không: kÕt thóc


3.6 - §ãng tƯp vμ kÕt thóc


<i>4. Thêm hồ sơ mới. </i>


Các bớc chi tiết.



4.1 - Nhập mà số cần thêm.


4.2 - Tìm kiếm: gọi thủ tục tìm kiếm ở trên.
4.3 - Xử lí kết quả tìm kiếm


4.3.1 Trng hp ó có hiển thị thơng báo


4.3.2 Tr−êng hỵp cha có, thêm vo cuối danh sách.
4.3.2.1 Nhập dữ liƯu vμo biÕn trung gian
4.3.2.2. §−a cưa sỉ tƯp vỊ ci tƯp.


</div>
<span class='text_page_counter'>(178)</span><div class='page_container' data-page=178>

4.5 - Xư lí câu trả lời:


4.5.1 Có: lặp lại từ 4.1


4.5.2 Không: sang bớc tiếp theo.
4.6 - Đóng tệp vμ kÕt thóc.


<b>8.2 </b> <b>TriĨn khai chi tiÕt ch−¬ng tr×nh. </b>


D−ới đây lμ các mơ đun ch−ơng trình con thực hiện 4 chức năng cơng
việc chính nh− đã phân tích.


<i> 1. </i>Thđ tơc<i> Më tƯp </i>


procedure MoTep;
const Enter = #13;


var tenfile: String[32];


begin


clrscr;


Write(' Cho ten tep '); Readln(tenfile);
Assign(TepHoSo,tenfile);


{$I-}


reset(TepHoSo);
{$I+}


if ioresult <> 0 then {không có tệp no trùng tên }
begin


Writeln(' Ban muon tao tep moi ? Enter=Yes ');
if ReadKey = Enter then Rewrite(ds)


else exit;
end;


close(ds);


Writeln(' Tep da san sang !');
end;


2. Thđ tơc <i>LiƯt kª</i>
procedure LietKe;
var i:integer;
begin



clrscr;


reset(TepHoSo);
i:=0;


writeln(' DANH SACH SINH VIEN ');
writeln;


writeln('---');
writeln('|TT |MASO | HO TEN |NAM SINH|');
writeln('---');
while not eof(TepHoSo) do


</div>
<span class='text_page_counter'>(179)</span><div class='page_container' data-page=179>

read(TepHoSo,sv);
if sv.maso<>0 then
begin


i:=i+1;
with sv do
begin


writeln('|',i:2,' |',maso:2,' |
',hoten:20,'|',namsinh:4,' |');
end;


end;
end;


close(TepHoSo);


end;


3. Thđ tơc <i>T×m kiÕm.</i>


procedure TimKiem;
var TimThay:boolean;
traloi:char;
i,h:integer;
begin


clrscr;
repeat


write(' Ma so SV can xem thong tin: ');
readln(ma);


reset (TepHoSo); TimThay:=false;


while (not TimThay) and (not eof(TepHoSo)) do
begin


read(TepHoSo,sv);
if sv.maso=ma then
begin


TimThay:=true;


writeln(' Sv co ma so: ',ma,': ');
writeln(' Ho ten: ',sv.hoten);
writeln(' Nam sinh: ',sv.namsinh);


end;


end;


if not Timthay then writeln('*Ma so SV: ',ma,' khong co
trong tep ');


write(' Can xem tiep (Y/N) ?: ');readln(traloi);
until upcase(traloi)='N';


close(TepHoSo);
end;


</div>
<span class='text_page_counter'>(180)</span><div class='page_container' data-page=180>

Clrscr;


write(' Ma so SV (0:Stop): ');readln(ma);
while ma<>0 do


begin


reset(TepHoSo);
DaCo:=false;


while (not DaCo) and (not eof(TepHoSo)) do
begin


read(TepHoSo,sv);


if sv.maso=ma then DaCo:=true
end;



if DaCo=true then writeln('Ma so: ',ma,'da co ')
else


begin


with sv do
begin


write(' Ho ten: ');readln(hoten);
write(' Nam sinh ( 2 so cuoi ):
');readln(namsinh);


maso:=ma;
end;


seek(TepHoSo,filesize(TepHoSo));
write(TepHoSo,sv);


end;


write(' Ma so SV (0:Stop): ');readln(ma);
end;


close(TepHoSo);
end;


Toμn bộ những chức năng cơ bản của ch−ơng trình quản lí hồ sơ sinh
viên nh− yêu cầu đã đ−ợc triển khai chi tiết. Bây giờ cần lắp ráp chúng vμo
một khung ch−ơng trình chính. Ch−ơng trình chính sử dụng ngay bảng chọn


đã xây dựng trong Unit <i>BgChon</i> ở ch−ơng tr−ớc.


Tãm l¹i, ta nhận đợc chơng trình hon chỉnh nh sau đây.


program QLSV;
uses crt, BgChon;
Const maxSize=10;
Type HoSo= Record


maso:integer;
hoten:String[20];
namsinh:string[2];
end;


Var TepHoSo:File of HoSo;
sv:HoSo;


tenfile:String[32];
ma:integer;


</div>
<span class='text_page_counter'>(181)</span><div class='page_container' data-page=181>

SoMC: word;


TenMC: Mang_String;
Chon: integer;


Procedure NhapThamSoBangChon;
Begin


{khởi tạo các tham sè b¶ng chän}


SoMC:= 5;


TenMC[0]:=' Mo tep du lieu ';
TenMC[1]:=' Liet ke ';


TenMC[2]:=' Tim kiem ';


TenMC[3]:=' Them vao danh sach ';
TenMC[4]:=' Ket thuc ';


End;


procedure MoTep;
Var i:integer;
begin


....
end;


procedure LietKe;
var i:integer;
begin


....
end;


procedure TimKiem;
var TimThay:boolean;
traloi:char;
i,h:integer;


begin


....
end;


procedure Them;
var i,ma: integer;
DaCo:boolean;
begin


....
end;
BEGIN


Clrscr;
repeat


chon:= BangChon(60,15,SoMC,TenMC,Blue, Red) + 1;
case chon of


0:exit;
1:MoTep;
2:LietKe;
3:TimPhanTu;
4:ThemPhanTu;
else ;


end;



</div>
<span class='text_page_counter'>(182)</span><div class='page_container' data-page=182>

END.


C©u hỏi v bi tập


1. Nguyên tắc chung khi thiết kế chi tiết dần từng bớc l gì.


2. Cỏc mơ đun trong một ch−ơng trình liên kết với nhau bằng cách nμo.
3. Sơ đồ cấu trúc ch−ong trình khác gì với l−u đồ thuật giải.


4. Khi nμo thì có thể vμ cần dùng thuật giải đệ quy.


5. So sánh thuật giải đệ quy với thuật giải lặp.Thuật giải nμo hiệu quả hơn.
6. Câu lệnh nμo ln có trong một thủ tục đệ quy.


7. Tên của mọt hμm đệ quy phải xuất hiện ít nhất lμ bao nhiêu lần bên trong
phần thân của nó.


8. Tại sao nếu <i>n</i> lμ tham số của một hμm, thủ tục đệ quy thì <i> n</i> phải lμ tham
biến.


Thùc hμnh.


1. Phân tích thiết kế v triển khai một chơng trình quản lí các đầu sách của
th viện. Mỗi đầu sách gồm các thông tin: mà số, tên, số lợng bản.
Chơng trình cho phép liệt kê kho sách, tìm kiếm một đầu sách, thêm số
bản sách cho một đầu sách, thêm đầu sách mới.


2. Phân tich thiết kế v triển khai một chơng trình soạn thảo một dòng văn
bản, cho phép chèn, xoá, thay thế mét x©u con.



3. Phân tich thiết kế vμ triển khai một trò chơi đơn giản hỏi đáp về địa lí nh−
sau: đ−a ra tên một n−ớc vμ một số tên thủ đô, ng−ời chơi chọn câu trả lời,
có thống kê vμ tính điểm.


4. ViÕt ch−¬ng trình quản lí kết quản học tập của học sinh một lớp, gồm 10
học sinh. Mỗi học sinh có các thông tin sau: Họ v tên, điểm, xếp loại. Họ
tên v điểm nhập từ bn phím. Chơng trình có các chơng trình con:


<i>NhapDuLieu, PhanLoai, DiemTB, XetLenLơp</i>. Cho trớc chơng trình


chính nh sau.


<i>NhapDuLieu; {thủ tục nhập dữ liệu} </i>


<i>PhanLoai (4,6,8); {kém:0..4; trung bình:5,6; khá 7,8; giỏi: 9,10} </i>
<i>Writeln(' Điểm trung bình cả lơp: ', DiemTB); </i>


<i>Writeln(' Danh sach học sinh đợc lên lớp '); </i>


<i>XetLenL¬p</i>.


</div>
<span class='text_page_counter'>(183)</span><div class='page_container' data-page=183>

6. Viết thủ tục đệ quy in các phần tử mảng theo thứ tự xi, theo thứ tự
ng−ợc.


7. Liệt kê mọi hốn vị của <i>n</i> phần tử dùng thuật giải đệ quy.


</div>
<span class='text_page_counter'>(184)</span><div class='page_container' data-page=184>

<b>Ch−¬ng 12 </b>


<b>Con trỏ vμ cấu trúc dữ liệu động </b>



<b>1. </b> <b>Con trá </b>


<b>1.1 </b> <b>Biến tĩnh và biến động. </b>
1.1.1


1.1.2


<i>BiÕn tÜnh </i>


Cho đến nay ta biết rằng muốn sử dụng một biến trong ch−ơng trình
hay ch−ơng trình con thì phải khai báo. Sau khi đã khai báo, tức lμ đã đăng kí
tên vμ kiểu dữ liệu của biến ở đầu ch−ơng trình, ch−ơng trình con thì ta có
thể n tâm sử dụng mμ không cần phải lμm thêm bất cứ viêc nμo khác. Mọi
cơng việc về quản lí các biến sẽ do trình biên dịch vμ hệ điều hμnh đảm
nhiệm. Chúng sẽ đ−ợc cấp phát vùng nhớ khi bắt đầu ch−ơng trình, ch−ơng
trình con vμ đ−ợc giải phóng khi ch−ơng trình, ch−ơng trình con kết thúc.
Nh− vậy, biến toμn cục sẽ tồn tại trong suốt thời gian hoạt động của ch−ơng
trình chính, biến cục bộ sẽ tồn tại trong suốt thời gian hoạt động của ch−ơng
trình con dù rằng có thể đã đ−ợc sử dụng xong sớm hơn ngay từ lúc bắt đầu
ch−ơng trình hoặc đến gần thời điểm kết thúc mới cần đến nơi.


Vì lí do nμy mμ ng−ời ta gọi đó lμ các biến tĩnh. Sử dụng các biến tĩnh
dễ dμng vμ đơn giản. Tuy nhiên chúng không cho phép tận dụng triệt để bộ
nhớ.


<i>Biến động </i>


Để khắc phục nh−ợc điểm trên của các biến tĩnh, ng−ời lập trình cần
phải có khả năng can thiệp trực tiếp vμo việc cấp phát vμ giải phóng vùng nhớ.
Chỉ xin cấp phát bộ nhớ cho một biến khi bắt đầu thực sự dùng đến nó, cần


bao nhiêu xin cấp phát đúng bấy nhiêu, tránh lãng phí vμ khi dùng xong có
thể giải phóng ngay khơng để chiếm chỗ vơ ích.


Khái niệm biến động đ−ợc đề xuất chính lμ để đáp ứng địi hỏi trên.
Nó mang lại khả năng sử dụng bộ nhớ linh hoạt vμ mềm dẻo hơn, tuy nhiên
cũng yêu cầu ng−ời lập trình phải lμm việc nhiều hơn, có trình độ cao hn.


</div>
<span class='text_page_counter'>(185)</span><div class='page_container' data-page=185>

<b>1.2 </b> <b>Định nghĩa và khai b¸o. </b>
1.2.1


1.2.2


<i>BiÕn con trá </i>


Biến con trỏ (<i>Pointer variable</i>) lμ loại biến đặc biệt, chiếm 2 byte. Nội
dung của nó khơng phải lμ một giá trị, một dữ liệu, mμ lμ một địa chỉ. Đây lμ
địa chỉ ô nhớ đầu tiên của vùng nhớ để chứa biến động t−ơng ứng. Vùng nhớ
nμy dμi đến đâu lμ do kiểu dữ liệu của biến động quyết định.


VËy cÇn chØ râ con trá kiĨu (dữ liệu) gì! Khi một con trỏ <i>có kiểu</i> đợc
khai báo thì trình biên dịch nhận đợc các thông tin sau:


-KÝch th−íc cđa biÕn


-Cấu trúc của biến, nghĩa lμ địa chỉ t−ơng đối của các tr−ờng thμnh
phần nếu có vμ kích th−ớc của mỗi tr−ờng.


BiÕn con trá


$1234


$1234


Vùng nhớ chứa biến động


<i>Hình 12.1: biến con trỏ để trỏ vμo một địa chỉ </i>


<i>Khai b¸o. </i>


Có thể khai báo <i>kiểu</i> con trỏ vμ sau đó khai báo <i>biến</i> con trỏ. Cũng có
thể khai báo trực tiếp ngay biến con trỏ, khơng định nghĩa kiểu.


Có ph¸p: <i>tõ kho¸ Type, tªn kiĨu con trá, dÊu b»ng, dÊu mị, kiĨu d÷ </i>
<i>liƯu trá tíi. </i>


<b>Type </b> <i>kiĨu con trá = ^ kiĨu d÷ liƯu</i> ;


<b>Var</b> <i>biÕn con trá : kiÓu con trá ;</i>


hc


<b>Var </b> <i>biÕn con trá : ^ kiểu dữ liêu ;</i>


Ví dụ 1: Type RealPtr = <i>^ Real</i>;
Var a,b, kq: <i>RealPtr</i>;
hc


Var a,b, kq: <i>^ Real;</i>


VÝ dô 2: Type Sv = Record



Ho_dem: string[24];


</div>
<span class='text_page_counter'>(186)</span><div class='page_container' data-page=186>

diemm_tb: real;
end;


<i>SvPtr = ^ Sv</i>;


Var SinhVien1, SinhVien2: <i>SvPtr</i>;
hc




Var SinhVien1, SinhVien2, LopTruong: <i>^ Sv;</i>


L−u ý r»ng trong khai báo kiểu hoặc biến con trỏ <i>không chấp nhận </i>


<i>kiểu dữ liệu vô danh </i>Sau kí hiệu con trỏ ^ chỉ chấp nhận các kiểu dữ liệu


chun ó có sẵn hoặc các kiểu đã đ−ợc khai báo tr−ớc.


Ví dụ, trình biên dịch sẽ khơng chấp nhận cách khai báo con trỏ đến
mảng nh− sau:


VAR <i>MangPtr: ^ array[1..10] of real; </i>


ThËm chÝ mét khai b¸o kiĨu


TYPE <i>MangPtr = ^ array[1..10] of real;</i>


cũng không hợp lệ. Cần phải khai báo kiểu mảng tr−ớc đã.


TYPE <i>Mang = array[1..10] of real; </i>


<i>MangPtr = ^Mang; </i>


VAR <i>A,B: MangPtr;</i>


Hc


TYPE <i>Mang = array[1..10] of real;</i>


VAR <i>A,B: ^MangPtr; </i>


<b>1.3 </b> <b>Các phép toán đối với con trỏ. </b>
1.3.1 <i> Gán giá trị cho biến con trỏ. </i>


Nội dung của một biến con trỏ lμ một địa chỉ. Có thể gán giá trị cho
một biến con trỏ, nghĩa lμ cho con trỏ nμy trỏ đến một địa chỉ cụ thể nμo đó
bằng các cách nh− sau


1- Gán trực tiếp địa chỉ của một biến tĩnh cho con trỏ cùng kiểu dữ
liệu, dùng toán tử lấy địa chỉ @. Lệnh gán nμy lμm cho biến con trỏ sẽ trỏ
đến biến đó:


<i>biÕn con trá = @ biÕn tÜnh ; </i>


VÝ dô.


Var i: Integer;


ip: ^Integer;


....


</div>
<span class='text_page_counter'>(187)</span><div class='page_container' data-page=187>

2- Dùng các thủ tục <i>New</i> hoặc <i>GetMem</i> để khởi tạo biến động vμ gán
giá trị cho con trỏ t−ơng ứng nh− sẽ xét trong tiết sau.


3- Dùng hμm <i>Ptr</i> để chuyển đổi một địa chỉ đoạn vμ một <i>offset</i> thμnh
một địa chỉ rồi gán cho con trỏ (sẽ xét đến trong phần lập trình hệ thống).


4- Có thể gán giá trị của một biến con trỏ cho một biến con trỏ khác
cùng kiểu. Sau phép gán nμy hai con trỏ có cùng gía trị, nghĩa lμ trỏ đến cùng
một biến động. Ví dụ,


<i>LopTruong:= SinhVien1; </i>


1.3.2


1.3.3


2.1.1


<i>So s¸nh </i>


ChØ cã thĨ so s¸nh hai con trá b»ng nhau hay kh¸c nhau.


Hai biến con trỏ lμ bằng nhau nếu cùng kiểu vμ cùng giá trị, tức lμ
cùng trỏ đến một địa chỉ.


<i>Con trá NIL. </i>


- <i>NIL </i>Lμ một giá trị đặc biệt, nói rằng con trỏ nμy khơng trỏ vμo đâu


cả.


- Có thể gán giá trị <i>NIL</i> cho bất cứ con trá kiÓu nμo.


Việc đặt ra giá trị <i>NIL</i> nhằm mục đích sau. Nội dung của biến con trỏ
đ−ợc hiểu lμ một địa chỉ. Sau khi khai báo biến con trỏ mμ ch−a khởi tạo biến
động t−ơng ứng, hoặc khi đã giải phóng biến động, vùng nhớ mμ con trỏ trỏ
tới có thể chứa các dữ liệu quan trọng. Dữ liệu có thể bị vơ tình lμm hỏng nếu
để con trỏ "vu vơ". Việc gán giá trị đặc biệt <i>NIL</i> trong các tình huống trên
nhằm tránh hậu quả bất th−ờng có thể xảy ra.


<b>2. </b> <b>Biến động. </b>


<b>2.1 </b> <b>Cấp phát vùng nhớ và truy cập biến động. </b>


<i>Cấp phát vùng nhớ cho biến động </i>
Cú pháp: Dùng thủ tục <i>New</i>


<b>New</b> ( <i>biÕn con trá</i> );


</div>
<span class='text_page_counter'>(188)</span><div class='page_container' data-page=188>

2.1.2 <i>Truy cập biến động. </i>


Cần phân biệt đây lμ gán giá trị vμ đọc giá trị của biến động (mμ biến
con trỏ trỏ đến) chứ không phải lμ gán giá trị vμ đọc giá trị của biến con trỏ.


: <i>biÕn con trá</i> ^ := <i>gi¸ trị</i> ;


Gán trị


Đọc giá trị: <i>biến</i> := <i>biÕn con trá</i> ^ ;


VÝ dô 1:


Var P: SvPtr;
New (P);


P^.HoDem:= 'nguyen van';
P^.Ten:= 'Nam';


P^. Diem_tb:= 7.5;
VÝ dô 2:


LopTruong:= P; Nguoi1:= P;


New(P) ; { lúc nμy P sẽ chứa địa chỉ khác }
....


Nguoi2:= P;


<b>2.2 </b> <b>Giải phóng biến động, thu hồi vùng nhớ </b>


Khi sử dụng xong, nên giải phóng vùng nhớ đã cấp cho biến động.


<b>Dispose</b> ( <i>biÕn con trá</i> );


<i>biÕn con trá</i> := <i>NIL</i>;


Thủ tục nμy trả lại phần bộ nhớ mμ biến động đã đ−ợc cấp. nghĩa lμ
đánh dấu rằng nó trở thμnh vùng nhớ rỗi, có thể dùng vμo việc khác.
Ví dụ:



Writeln(‘Lớp tr−ởng:’, <i>LopTruong^.HoDem</i>, ‘ ’ , <i>LopTruong ^ .Ten</i>);
Writeln(‘ Điểm trung bình cuối năm:’ , <i>LopTruong ^ . Diem_tb</i> );
{ đã sử dụng xong biến động <i>LopTruong^</i> , có thể giải phóng}
Dispose ( <i>LopTruong</i> );


<b>3. </b> <b>Con trỏ không định kiểu - Pointer </b>


</div>
<span class='text_page_counter'>(189)</span><div class='page_container' data-page=189>

Trái với con trỏ có kiểu, con trỏ <i>không định kiểu</i> hay con trỏ <i>kiểu </i>


<i>chung</i> - <i>generic pointer</i> - chỉ để trỏ đến một địa chỉ ô nhớ đầu tiên của vùng


nhớ mμ ta sẽ cần đến. Kích th−ớc của vùng nhớ nμy cịn <i>ch−a xác định</i>, cấu
trúc cũng <i>ch−a có</i>. Ng−ời sử dụng phải tự lo lấy việc ấn định một kích th−ớc
vμ một cấu trúc khi truy cập.




Khai b¸o: <b>Var</b> <i>biÕn con trá</i>: <b>Pointer ;</b>


Xin cÊp ph¸t vïng nhí: <b>GetMem</b> ( <i>biÕn con trá , kich th−íc</i> );
Gi¶i phãng vïng nhí: <b>FreeMem</b> ( <i>biÕn con trá , kÝch th−íc</i> );
ở đây <i>kích thớc</i> l kích thớc khối nhớ liên tôc tÝnh b»ng <i>word</i>.


<b>øng dông </b>
<b>3.2 </b>


Khi cần xử lí cả một khối nhớ liên tục, khơng cần truy cập đến từng
thμnh phần, ví dụ cần xử lí một l−ợng gồm <i>size * Word </i>dữ liệu, chẳng hạn
một tệp hình ảnh, tệp âm thanh, một mμn hình, một khung cửa sổ, ... thì để
tăng tốc độ truy cập ng−ời ta th−ờng dùng con trỏ không định kiểu.



Các ch−ơng trình đồ hoạ vμ tạo hoạt hình th−ờng phải thực hiện nhiều
lần việc l−u giữ rồi lại cho hiển thị toμn bộ hay một phần mμn hình. Ta sẽ
thấy nhiều ví dụ về sử dụng con trỏ khơng định kiểu ở đó.


Cũng do tính chất khơng định kiểu hay nói đúng hơn lμ ch−a định kiểu
mμ con trỏ chung <i>Pointer</i> có thể t−ơng thích với mọi kiểu dữ liệu bất kì. Ta
có thể dùng phép ép kiểu để truy cập vùng nhớ trỏ bởi con trỏ chung <i>Pointer </i>


nh− đây lμ một biến có kiểu cụ thể nμo đó.


D−ới đây lμ một ví dụ minh hoạ, sử dụng con trỏ không định kiểu vμ
thủ tục <i>GetMem </i>xin cấp phát động vùng nhớ để tiết kiệm khi dùng mảng.
Ta đã biết rằng khi khai báo biến mảng thì kích th−ớc phải lμ hằng cho tr−ớc.
Điều nμy dẫn đến phải khai báo dự phòng kích th−ớc tơí đa. Sử dụng con trỏ
vμ biến động ta không dùng biến tĩnh mμ dùng một con trỏ khơng định kiểu.
Khi biết kích th−ớc cụ thể sẽ xin cấp vừa đủ vùng nhớ cần thiết. Việc truy
cập từng phần tử mảng sẽ thông qua phép ộp kiu.


Chơng trình dới đây tạo v in ra một ma trận vuông có các phần tử
l các sè nguyªn, sinh ngÉu nhiªn. KÝch th−íc (sè hμng = sè cét) cña ma
trËn gâ tõ bμn phÝm.


uses crt;


const max_size = 50;


type matrix = array[1..max_size,1..max_size] of word;
var P: Pointer ;



sz,i,j: byte;
BEGIN


</div>
<span class='text_page_counter'>(190)</span><div class='page_container' data-page=190>

write(' cho kich thuoc ma tran: '); readln(sz);
Getmem(P, sz*sz);


for i:=1 to sz do
for j:=1 to sz do


( matrix (P^))[i,j]:= random(100);
for i:=1 to sz do


begin


for j:=1 to sz do


write( (matrix (P^))[i,j]:4);
writeln;


end;


freeMem( P, sz*sz);
END.


Có thể khai báo P lμ con trỏ đến kiểu mảng <i>matrix</i> ở trên.


<i>Var P: ^ matrix; </i>


Thủ tục <i>GetMem</i> vẫn dùng đ−ợc để cấp vùng nhớ cho P nh− cũ. Phép
truy cập các phần tử của mảng trỏ bởi P sẽ nh− thơng th−ờng, khơng phải ép


kiểu. Ch−ơng trình dễ hiểu hơn. Tuy nhiên, ví dụ trên cho thấy tính linh hoạt
trong sử dụng con trỏ khơng định kiu.


<b>4. </b> <b>Vùng ngăn xếp và vùng Heap. </b>


<b>4.1 </b> <b>Kh¸i niƯm </b>


Vùng ngăn xếp hay<i> Stack</i> lμ vùng nhớ dμnh cho các biến cục bộ của
ch−ơng trình con. Mỗi khi gọi một ch−ơng trình con, một <i>stack</i> (kích th−ớc
mặc định lμ <i>16 KB</i>) đ−ợc tạo ra. Khi kết thúc vμ ra khỏi ch−ơng trình con,


<i>stack</i> ny đợc giải phóng.


Vựng nh dnh ch cho các <i>stack</i> lμ vùng thấp, kế tiếp phần vùng nhớ
đã l−u giữ mã của ch−ơng trình.




<i> stack segment Heap segment </i>




Chơng
trình vμ c¸c
biÕn tÜnh


ch−a
dïng


đã


dùng


đã
dùng


ch−a dïng


<i>Vùng điạ chỉ thấp</i> ← → <i>Vùng địa chỉ cao</i>


<i>H×nh 12.2: Tỉ chøc bé nhí khi thực hiện môt chơng trình </i>


Vựng <i>Heap</i> l vựng nhớ dμnh để cấp cho các biến động bằng thủ tục


</div>
<span class='text_page_counter'>(191)</span><div class='page_container' data-page=191>

Con trỏ <i>Heap</i> luôn trỏ vμo ơ nhớ đầu tiên cịn rỗi của vùng <i>Heap</i>. Sau
mỗi lần xin cấp phát bằng <i>New</i> con trỏ di chuyển một khoảng bằng kích
th−ớc của bin ng va cp phỏt


Do cáp phát, giải phóng xen kẽ nhau, hậu quả l vùng <i>Heap</i> phân
thnh nhiều mảnh, không liền.


Trớc khi xin cấp phát một mảng nhớ lớn cần kiểm tra tránh trn <i>Heap</i>


bằng hai hm sau đây


<b>MemAvail</b>: Tổng số ô nhớ còn rỗi


<b>MaxAvail </b>: Kích thứơc lớn nhất có thể của một vùng nhớ liên tục còn rỗi.


<b>4.2 </b> <b>Gi¶i to¶ heap </b>



ở trên ta đã biết cách giải phóng biến động bằng thủ tục <i>Dispose</i>. Thủ


tục <i>Dispose </i>tham số đầu vμo lμ con trỏ đến biến động cần giải phóng vμ mỗi


lần gọi giải phóng một biến động.


Có những tr−ờng hợp cần tạo ra vμ giải phóng nhiều biến động cùng
một lúc. Các thủ tục d−ới đây hỗ trợ thực hiện việc nμy.


<b>Mark</b> ( <i>Pmark </i>);


Ghi laị giá trị của con trỏ <i>Heap</i> vμo <i>Pmark. Pmark</i> lμ một biến con trỏ.
Kể lừ lệnh nμy, mọi thủ tục <i> New</i> đều đ−ợc cấp vùng nhớ từ đây trở đi.


<b>Release</b> ( <i>Pmark</i> );


Giải phóng tất cả các biến động đ−ợc cấp phát kể từ khi đánh dấu bằng


<i>Mark</i>( <i>Pmark</i>).


VÝ dô:


Var P,Q,R, Pmark: …
Begin


...
New(R);
...


Mark(Pmark);



New(P); ...


New(Q); ...


{giải phóng vùng nhớ đã cấp cho P,Q }
Release(Pmark);


...


End.


</div>
<span class='text_page_counter'>(192)</span><div class='page_container' data-page=192>

Con trỏ vμ biến động lμ một cơng cụ rất linh hoạt. Nó cho phép xây
dựng nhiều câú trúc dữ liệu động rất cần thiết mμ ta sẽ nghiên cứu trong
ch−ơng sau. ở đây chỉ nêu một ví dụ nhằm minh hoạ ý nghĩa quan trọng vμ
cách sử dụng chúng.


Ta đã biết rằng vùng nhớ dμnh cho các biến tĩnh bị giới hạn bởi 640
KB vùng nhớ cơ sở. Hơn nữa, khi khai báo một mảng cỡ lớn thì kích th−ớc
cũng không thể v−ợt quá một phân đoạn bộ nhớ (<i>segment</i>) lμ 64 KB. Ví dụ,
với mảng số thực kiểu <i>real</i>, một dữ liệu kiểu <i>real</i> chiếm 6 byte thì mảng lớn
nhất khơng thể v−ợt q 10922 phần tử (vì 10922 * 6 = 65532 byte < 64
KB = 65536 byte).


Nếu trong bμi tốn cần xử lí nhiều mảng cỡ lớn thì phải dùng các biến
động để xin cấp phát vùng nhớ trên <i>Heap</i> vμ giải phóng ngay sau khi đã sử
dụng xong.


Ví dụ d−ới đây nhằm minh hoạ điều đó. Vùng <i>Heap</i> sẽ bị vét cạn rất
nhanh nếu ta khơng giải phóng chỗ.



const nMax=10922;


type MangLon=array[1..nMax] of real;
Var Mp: ^MangLon ;


i: integer;
BEGIN


i:=0;
repeat
i:=i+1;


writeln('tong vung nho roi tren Heap: ', MemAvail);
writeln('khoi nho lien lon nhat tren heap:', MaxAvail);
if MaxAvail < sizeof(MangLon) then


begin


writeln('khong du vung nho cho mang thu ',i,' !');
halt;


end
else
begin


new(Mp);


writeln('Heap dang chua ',i,' mang 10922 so thuc



=', i * 65532,' byte !');


readln;


end;
until false;
END.


C©u hái vμ bμi tËp


</div>
<span class='text_page_counter'>(193)</span><div class='page_container' data-page=193>

2. Phân biệt biến tĩnh vμ biến động. Các biến tĩnh đ−ợc cấp phát vùng
nhớ khi nμo. Các bién động đ−ợc cấp phát vùng nhớ bằng cách nμo.
3. Câu lênh <i>GetMem</i> khác với <i>New</i> ở điểm nμo. Nó có thể dùng để cấp


phát vùng nhớ cho các biến động kiểu gì. Có thể dùng <i>FreeMem</i> để
giải phóng vùng nhớ cấp phát bởi <i>New</i> hay không.


4. Trong một ch−ơng trình có các khai báo vμ câu lệnh nh− sau. Câu lệnh
nμo đúng cú pháp, câu lệnh nμo sai cú pháp, tại sao.


a) Type <i>mang = array[1..10] of integer; </i>


<i> MangPtr = ^mang</i>;


Var <i>A: mang; </i>


<i> Aptr: mangPtr; </i>


<i> p,q: ^integer; </i>



<i> i: integer</i>;


c¸c c©u lƯnh:


p:=i; @i:=p; p:=@i; p:=q;
A[5]:= i; A[5]:= p^; A[5]:= q;
Aptr^[5]:= q^; Aptr[5]^:= i;
b) Type <i>HoSo = record </i>


<i> HoVaTen: String; </i>


<i> NamSinh: word; </i>


<i>L−¬ng: real; </i>


<i>End; </i>


<i>HoSoPtr = ^HoSo; </i>


Var <i>CB1, CB2: HoSo; </i>


<i> NV1, NV2: HoSoPtr;</i>


Các câu lệnh:


CB1:= NV1; NV1^:= CB1; CB1:= NV1^;
@NV1:= CB1; NV2:= @CB2;


NV1.L−¬ng:= 500.0;



NV1^.HoVaTen:=' nguyen van A';
NV1.NămSinh^:= 1970.


<b>5. </b>Có các khai báo


Type <i>vecto_10 = array [1..10] of Integer ; </i>


<i> vecto_nguyen_10 = array [1..10] of Integer ; </i>
<i> vecto_10_Ptr = ^ vevto_10;</i>


Var <i>x: vecto_10; </i>


<i> y: vecto_nguyen_10; </i>


<i>z: array [1..10] of Integer ; </i>


<i> P: pointer; </i>


</div>
<span class='text_page_counter'>(194)</span><div class='page_container' data-page=194>

b) Type Vevto_10_Ptr = ^ array [1..10] of Integer ;
2 - a) x:=y b) y:= z c) x:= z


</div>
<span class='text_page_counter'>(195)</span><div class='page_container' data-page=195>

<b>Ch−¬ng 13 </b>


<b>Danh s¸ch & danh s¸ch mãc nèi </b>


Ch−ơng nμy nghiên cứu mơ hình danh sách lμ một mơ hình dữ liệu hay
gặp trong các bμi toán thực tế. Đặc biệt có hai kiểu danh sách ngăn xếp vμ
danh sách hμng đợi lμ những kiểu dữ liệu rất cơ bản, lμm cơ sở để thực hiện
nhiều thuật giải điển hình.



Ngoμi ra, ch−ơng nμy cịn có mục đích minh hoạ tính linh hoạt của con
trỏ vμ biến động trong các cấu trúc dữ liệu. Sau khi trình bμy về danh sách
mảng vμ những −u nh−ợc điểm của nó, ta sẽ xét việc biểu diễn danh sách
bằng cấu trúc danh sách móc nối, dùng con trỏ vμ biến động. Cấu trúc linh
hoạt nμy đã khắc phục đ−ợc các nh−ợc điểm thuộc bản chất của danh sỏch
mng.


<b>1. </b> <b>Danh sách bằng mảng. </b>


<b>1.1 </b> <b>Mô hình danh sách. </b>


Danh sách tuyến tính (<i>List</i>) l một mô hình dữ liệu khái quát hoá các
danh sách liệt kê. Có rất nhiều ví dơ vỊ danh s¸ch trong c¸c bμi to¸n xư lÝ
thông tin. Danh sách các nhân viên trong một cơ quan, danh sách hnh khách
giữ chỗ một chuyến bay, danh sách các công việc cần phải tiến hnh trong
một quy trình công nghệ...


Cú th khỏi quỏt hoá các đặc tr−ng cơ bản nhất của danh sách nh− sau:
- Danh sách lμ tập các phần tử dữ liệu <i>cùng kiểu,</i> giữa các phần tử <i> có </i>


<i>một trình tự đứng tr−ớc, đứng sau.</i>


- Cho phép thêm phần tử mới vo danh sách hoặc xoá bỏ bớt phần tử
khỏi danh sách.


- S phn tử hay kích th−ớc của danh sách lμ <i>khơng cố định</i>, có thể
thay đổi tăng lên, giảm đi trong thời gian thực hiện ch−ơng trình. Đây lμ
điểm khác với mảng.


</div>
<span class='text_page_counter'>(196)</span><div class='page_container' data-page=196>

<b>1.2 </b> <b>Danh s¸ch biĨu diƠn b»ng cÊu tróc m¶ng.</b>



Theo mơ tả các đặc tr−ng của danh sách ở trên, dễ thấy rằng ta có thể
triển khai xây dựng một danh sách bằng cấu trúc mảng. Để thể hiện đ−ợc
kích th−ớc thay đổi của danh sách cần xét kèm thêm một biến để ghi số phần
tử hiện có. Nh− vậy, danh sách lμ một bộ gồm một mảng <i>PhanTu </i> để chứa
các phần tử vμ một biến nguyên <i>kt </i> lμ số phần tử hiện có mặt trong danh
sách.


<b>Type</b> <i>DanhSach</i> = <b>Record </b>


PhanTu: array [1.. <i>max_kt</i> ] of <i>kiÓu phÇn tư </i>;
kt: word;


<b>end; </b>




ở đây <i>max_kt</i> l kích thớc (dự phòng) lớn nhất có thể của danh sách.
Ví dụ, một danh sách tên ngời, mỗi phần tử của nó l một xâu kí tự
đợc khai b¸o nh− sau:


TYPE <i>Ten</i> = String[8];
<i>DSTen</i> = Record


<i>PhanTu</i>: array [1.. 100] of <i>Tªn</i>;
<i>kt</i>: word;


end;


VAR L: DSTªn;



<b>1.3 </b> <b>Các phép toán đối với danh sách mảng. </b>


Sử dụng mảng lμ một cấu trúc có sẵn, các thao tác đối với danh sách
nói trên dễ dμng đ−ợc thực hiện.


1.3.1 <i>Truy cËp mét phÇn tư. </i>


Truy cËp vo một phần tử của danh sách chính l truy cập vo một
phần tử mảng.


Gán trị: L.PhanTu[i]:= <i>giá trị</i> ;
Đọc giá trí: <i>biến</i>:= L.PhanTu[i];
Ví dụ,


{ gán tên l Hïng cho ng−êi thø 5 trong danh s¸ch }
L.PhanTu[5]:='Hïng';


{ Đọc tên ngời thứ 10 }


</div>
<span class='text_page_counter'>(197)</span><div class='page_container' data-page=197>

1.3.2


1.3.3


1.3.4


1.3.5


<i>Dut danh s¸ch. </i>



Duyệt một danh sách lμ thao tác truy cập đến tất cả các phần tử của
danh sách để thực hiện một xử lí nμo đó sao cho đảm bảo <i>khơng sót</i> vμ <i>khơng </i>
<i>lặp</i>. Khơng sót nghĩa lμ mọi phần tử đều đ−ợc xử lí, khơng lặp nghĩa lμ
khơng phần tử nμo bị xử lí q một lần.


PhÐp dut có thể thực hiện nhờ một vòng lặp <i>For</i>


For <i>i:= 1</i> to <i>L.kt</i> do " <i>xư lÝ L.PhanTu[i]"</i> ;
VÝ dơ


Thay toμn bé tên bằng chữ in hoa


For <i>i:= 1</i> to <i>L.kt</i> do <i>L.PhanTu[i]:= upper(L.PhanTu[i]);</i>


<i>T×m kiÕm </i>


Tìm kiếm một phần tử trong danh sách lμ nhằm phát hiện phần tử có
chứa một thμnh phần dữ liệu trùng khớp với mẫu đã cho. Mẫu nμy th−ờng
đ−ợc gọi lμ <i>khóa</i> tìm kiếm.


Tuỳ theo danh sách có đ−ợc sắp xếp thứ tự theo khoá đã cho hay
khơng mμ có các cách tìm kiếm khác nhau.


<i>T×m kiÕm tuÇn tù - Sequential Searching </i>


Khi danh sách ch−a đ−ợc sắp xếp thì cách duy nhất để thực hiện tìm
kiếm lμ duyệt từ đầu, cho đến khi tìm thấy hoặc phát hiện khơng có.


<i>T×m kiếm nhị phân - Binary Searching </i>



Khi danh sỏch ó đ−ợc sắp xếp đúng thứ tự theo khố cần tìm thì có
thể tiến hμnh tìm kiếm theo cách chia đơi dần. Đây lμ thủ tục tìm kiếm nhị
phân đã xét đến trong phần thủ tục đệ quy.


<i> Thêm phần tử. </i>


- Hoc ni vo cui, khi ú danh sách không đ−ợc sắp theo thứ tự.
Thực hiện đơn giản nh−ng sẽ phải chi phí nhiều khi tìm kiếm.


- Hoặc chèn đúng chỗ, theo cách nμy buộc phải tìm đúng vị trí vμ sau
đó dịch chuyển cả phần đuôi. Thực hiện phức tạp hơn nh−ng bù lại khi tìm
kiếm sẽ nhanh hơn.


<i>Gì bá phÇn tư </i>


- Tìm đến phần tử cần gỡ bỏ vμ huỷ phần tử nμy bằng cách chép dồn
lên


<b>1.4 </b> <b>Các u, nhợc điểm. </b>


</div>
<span class='text_page_counter'>(198)</span><div class='page_container' data-page=198>

- n giản, có thể cμi đặt đễ dμng bằng kiểu mảng đã quen biết.
- Bất tiện khi th−ờng xuyên có thao tác thêm bớt phần tử ở giữa danh
sách.


<b>1.5 </b> <b>VÝ dơ minh ho¹ </b>


Để thấy đ−ợc các −u nh−ợc điểm của danh sách mảng hãy cải tiến
ch−ơng trình quản lí hồ sơ của sinh viên đã phát triển trong ch−ơng 3.



Ch−ơng trình nμy đã cho phép tiến hμnh các thao tác tạo lập, liệt kê, tìm kiếm
vμ thêm một hồ sơ <i>vμo cuối </i>danh sách. Cần bổ xung thêm chức năng thứ 5
lμ cho phép <i>huỷ</i> một hồ sơ.


1.5.1 <i>Ph©n tÝch, thiÕt kÕ. </i>


Chức năng <i>huỷ</i> một hồ sơ trong danh sách sinh viên lμ thủ tục phức
tạp hơn cả vì bản ghi cần huỷ có thể nằm ở giữa tệp. Cần có thao tác dồn lấp
chỗ trống. Nội dung tệp phải viết lại hoμn toμn. Do đó cần đọc toμn bộ thông
tin ra một mảng trong bộ nhớ để tiện xử lí. Chỉ viết lại vμo tệp ở thời điểm
cuối cùng, khi mọi thay đổi đã hon tt.


Một danh sách các hồ sơ đợc thực hiện bằng mảng các bản ghi. Ta
cần khai báo một danh sách mảng nh sau.


Type <i>DSHoso</i> = Record


PhanTu: array [1..max_kt] of <i>Hoso</i>;


Kt: word;


End;
Var L: <i>DSHoso</i>


Chi tiÕt dÇn tõng b−íc thđ tơc hủ mét hå sơ khỏi danh sách nh sau.
5. Huỷ một hồ s¬.


- Đầu vμo: tệp đã mở sẵn, mã số của hồ sơ cần huỷ gõ từ bμn phím
- Đầu ra: tệp khơng cịn chứa bản ghi cần huỷ.



Chi tiÕt dÇn tõng b−íc.


5.1 ChÐp toμn bé néi dung tệp ra mảng các bản ghi.


5.2.1 Đa cửa sổ tệp về đầu tệp; gán chỉ số đầu tiên của mảng.
5.2.2 Đọc từ tệp ra phần tử mảng


5.2.3 Tăng chỉ số mảng lên mét
5.2.4 Dõng khi hÕt tÖp.


5.2 NhËp mà số của hồ sơ cần huỷ.


5.3 Tỡm kim phần tử mảng lμ bản ghi có mã số đã cho:
5.3.1 Gọi thủ tục Tìm kiếm.


5.4 Xử lí kết quả tìm kiếm.


</div>
<span class='text_page_counter'>(199)</span><div class='page_container' data-page=199>

5.4.2 Trờng hợp thấy, tiến hnh gỡ bỏ bản ghi khỏi mảng:
5.4.2.1 Chép dồn các phần tử mảng lên một vị trí lấp vo
chỗ phần tử mảng bị gõ bỏ,


5.4.2.2 hiển thị thông báo thnh công.
5.5 Hỏi lại ngời dùng có cần huỷ tiếp hay không.
5.6 Xử lí trả lời có: lặp lại từ bớc 5.2;


5.7 Viết nội dung của mảng ra tệp
5.8 Đóng tệp v kÕt thóc.


1.5.2 <i>TriĨn khai chi tiÕt. </i>



Từ bảng phân tích chi tiết dần từng b−ớc ở trên, dễ dμng chuyển thμnh
một thủ tục Pascal nh− d−ới đây. L−u ý rằng để nhấn mạnh cấu trúc danh
sách vμ dễ theo dõi ta không sử dụng câu lệnh <i>with</i> mμ viết đầy đủ các cấp
của kiểu bản ghi lồng nhau.


procedure Huy;


var TimThay:boolean;
CoHuy:boolean;
traloi:char;


i, csTimThay: integer;
begin


CoHuy:= false;
reset(TepHoso);
i:=0;


{chep lai vao danh sach de xu ly thao tac huy}
while not eof(TepHoso) do


begin read(TepHoso,L.PhanTu[i]);
i:=i+1;


end;
L.kt:= i-1;
repeat


write('Ma so SV can huy thong tin: ');
readln(ma);



TimThay:= false; i:= 0;
while (not TimThay) do
begin


if L.PhanTu[i].maso=ma then


begin TimThay:=true; CoHuy:=true;
csTimThay:=i;


end;
i:=i+1;
end;


if TimThay then


begin {chep lai mang, tru SV can huy}
L.kt:= L.kt - 1;


for i:= csTimThay to L.kt do
begin


</div>
<span class='text_page_counter'>(200)</span><div class='page_container' data-page=200>

L.PhanTu[i].namsinh:= L.PhanTu[i+1].namsinh;
end


end


else writeln(' Ma so SV: ',ma,' khong co trong danh
sach');



write(' Can huy tiep (Y/N) ?: ');readln(traloi);
until upcase(traloi)='N';


if CoHuy then


begin {chep tu L vao tep}
rewrite(TepHoso);


for i:=0 to L.kt do


write(TepHoso,L.PhanTu[i]);
close(TepHoso);


end
else


close(TepHoso);
end;


Chơng trình sau khi đợc bổ xung thêm chức năng huỷ hồ s¬.
program QLSV;


uses crt, bgchon;
Const maxSize=10;
Type HoSo= Record


maso:integer;
hoten:String[20];
namsinh:string[2];
end;



DSHoso = record


PhanTu: array[0..maxSize] of HoSo;
Kt: word;


End;


Var TepHoso:File of HoSo;
L: DSHoso;


sv:HoSo;


tenfile:String[8];
ma:integer;


SoMC: word;


TenMC: Mang_String;
Chon: integer;


procedure MoTep;
....


procedure LietKe;
....


procedure TimKiem;
....



</div>

<!--links-->

Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Tải bản đầy đủ ngay
×