!"
แผนการสอนประจําบทเรียน รายชือ่ อาจารยผจู ดั ทํา สุณี รักษาเกียรติศักดิ์ หัวขอของเนื้อหา ตอนที่ 4.1 การจัดสรรเนื้อที่ในหนวยความจําใหกับตัวแปร (1 คาบ) เรือ่ งที่ 4.1.1
การจัดสรรเนือ้ ทีแ่ บบสแตติก
เรือ่ งที่ 4.1.2
การจัดเนื้อที่แบบไดนามิก
ตอนที่ 4.2 ลิงคลิสต (2 คาบ) เรือ่ งที่ 4.2.1
การกําหนดคุณลักษณะเฉพาะของลิงคลสิ ตอยางงาย
เรือ่ งที่ 4.2 2
การสรางลิงคลสิ ตอยางงาย
เรือ่ งที่ 4.2.3
การใชลงิ คลสิ ตอยางงาย
แนวคิด 1. การจัดสรรเนื้อที่ในหนวยความจําแบงเปน 2 แบบคือ การจัดสรรเนื้อที่ในหนวยความจําแบบ สแตติกและแบบไดนามิก 2. ชนิดของตัวแปรสวนใหญที่เราใช เชน integer, boolean, char, real, array, และ record จะเปน ชนิดที่มีการจัดสรรเนื้อที่หนวยความจําใหกับตัวแปรระหวางการคอมไพล ซึง่ เราเรียกวาการจัด สรรเนื้อที่หนวยความจําแบบสแตติก 3. ในภาษาคอมพิวเตอรภาษาสูงสวนใหญมักจะมีชนิดของตัวแปรอีกชนิดหนึ่งคือตัวแปรพอยน เตอร ซึ่งเนื้อที่ในหนวยความจําจะถูกจัดสรรเมื่อมีการใชงานตัวแปรนั้นจริง ๆ นัน้ คือเนือ้ ทีจ่ ะ ถูกจัดสรรเมือ่ มีการเรียกใชระหวางการประมวลผลโปรแกรม ซึง่ เราเรียกวาเปนการจัดสรรเนือ้ ที่หนวยความจําแบบไดนามิก 4. ลิงคลิสตอยางงายเปนชนิดขอมูลที่มีโครงสรางแบบเชิงเสน ที่สรางมาจากตัวแปรชนิดพอยน เตอร วัตถุประสงค หลังจากศึกษาบทเรียนที่ 4 แลว นักศึกษาสามารถ 1. เปรียบเทียบขอแตกตางระหวางการจัดสรรเนื้อที่ในหนวยความจําแบบสแตติกและแบบไดนา มิกได
!# 1. บอกคุณลักษณะเฉพาะของชนิดขอมูลแบบลิงคลสิ ตอยางงายได 2. สรางชนิดขอมูลแบบลิงคลสิ ตอยางงายได กิจกรรมการเรียนการสอน กิจกรรมทีน่ กั ศึกษาตองทําสําหรับการเรียนการสอน ไดแก 1. ศึกษาเอกสารชุดวิชา/โฮมเพจชุดวิชา ตอนที่ 4.1 และตอนที่ 4.2 2. ทํากิจกรรมของบทเรียนที่ 4 3. ทําแบบประเมินผลของบทเรียนที่ 4 เอกสารประกอบการสอน 1. เอกสารชุดวิชา สื่อการสอน 1. โฮมเพจชุดวิชา 2. สไลดประกอบการบรรยาย (Powerpoint) 3. โปรแกรมคอมพิวเตอร ประเมินผล 1. ประเมินผลจากกิจกรรมที่ทํา 2. ประเมินผลจากคําถามทายบทเรียน
!$ ตอนที่ 4.1 การจัดสรรเนื้อที่ในหนวยความจําใหกับตัวแปร หัวเรื่อง เรือ่ งที่ 4.1.1
การจัดสรรเนือ้ ทีแ่ บบสแตติก
เรือ่ งที่ 4.1.2
การจัดเนื้อที่แบบไดนามิก
แนวคิด 1. การจัดสรรเนื้อที่ในหนวยความจําแบงเปน 2 แบบคือ การจัดสรรเนื้อที่ในหนวยความจําแบบ สแตติกและแบบไดนามิก 2. ชนิดของตัวแปรสวนใหญที่เราใช เชน integer, boolean, char, real, array, และ record จะเปน ชนิดที่มีการจัดสรรเนื้อที่หนวยความจําใหกับตัวแปรระหวางการคอมไพล ซึง่ เราเรียกวาการจัด สรรเนื้อที่หนวยความจําแบบสแตติ เชนตัวแปรชนิดอะเรย จะตองมีการกําหนดขนาดของอะเรย ลวงหนาวาจะมีขนาดเทาใด ซึ่งโดยปกติแลวมักจะเปนขนาดใหญสุดที่คาดวาจะตองใชงาน ซึง่ ในบางครัง้ ถาขอมูลของอะเรยมีนอ ย เนื้อที่ที่จองไวก็จะเสียประโยชน 3. ในภาษาคอมพิวเตอรภาษาสูงสวนใหญมักจะมีชนิดของตัวแปรอีกชนิดหนึ่งคือตัวแปรพอยน เตอร ซึ่งเนื้อที่ในหนวยความจําจะถูกจัดสรรเมื่อมีการใชงานตัวแปรนั้นจริง ๆ นัน้ คือเนือ้ ทีจ่ ะ ถูกจัดสรรเมือ่ มีการเรียกใชระหวางการประมวลผลโปรแกรม ซึง่ เราเรียกวาเปนการจัดสรรเนือ้ ที่หนวยความจําแบบไดนามิก วัตถุประสงค หลังจากที่ศึกษาตอนที่ 4.1 แลว นักศึกษาสามารถ 1. เปรียบเทียบขอแตกตางของการจัดสรรเนื้อที่หนวยความจําแบบสแตติกและแบบไดนามิกได 2. ใชพอยนเตอรสําหรับตัวแปรแบบไดนามิกได เรื่องที่ 4.1.1 การจัดสรรเนื้อที่แบบสแตติก การจัดสรรเนื้อที่ในหนวยความจําแบบสแตติก หมายถึงเนื้อที่ในหนวยความจําจะถูกจัดสรรใหแกให แกตัวแปรกอนการประมวลผล (execute) นัน่ คือระหวางการแปลโปรแกรม (compile) ตัวแปรที่นิยามไวใน สวนของการนิยามจะไดรับการจัดสรรเนื้อที่ในหนวยความจําทันที ถึงแมตัวแปรเหลานั้นจะไมไดถูกใชในการ เขียนคําสัง่ ซึ่งจะทําใหเสียเนื้อที่ในหนวยความจํา ตัวแปรแบบอะเรยจะเปนตัวแปรแบบมีโครงสรางซึ่งจะมีการจัดสรรเนื้อที่หนวยความจําแบบสแตติก นั้นคือเนื่อที่ในหนวยความจําจะถูกจัดสรรเทากับขนาดที่กําหนดไวในอะเรย เชน
!% TYPE StdElement = RECORD Key : KeyType; Data : DataType; END; VAR A1 : ARRAY[1..100] OF StdElement; A2 : ARRAY[1..50,1..100] OF integer;!
จะมีการจัดสรรเนื้อที่ในหนวยความจําใหกับตัวแปร A1 100 ตัว ไดแก A1[1], A1[2], A1[3], … A1[100] และจะมีการจัดสรรเนื้อที่ในหนวยความจําใหกับตัวแปร A2 5000 ตัว ไดแก A2[1,1], A2[1,2], …A2[1,100], A2[2,1], A2[2,2], …A2[2,100],……….A2[50,1], A2[50,2], …..A2[50,100] ถึงแมเมื่อรันโปรแกรมกับขอมูลจริงจะมีขอมูลสําหรับ A1 เพียง 25 ตัวและทําใหเราตองเสียเนื้อที่ที่ จองไวสําหรับตัวแปรตัวที่ A1[26], A1[27], …A1[100] ก็ตาม เราก็ตอ งจองเนือ้ ทีส่ งู สุดทีเ่ ราคาดวาโปรแกรม ของเราจะรองรับขอมูลได การจัดสรรเนื้อที่หนวยความจําแบบสแตติกจะจัดสรรจากหนวยความจําที่เราเรียกวาสแตก (ดูการ ประยุกตใชสแตกของบทเรียนที่ 5) กิจกรรม 4.1 ถามีการนิยามตัวแปรแบบอะเรย ดังนี้ VAR
A3 : ARRAY[5..10, 3..5] OF real;
A3 จะมีตัวแปรทั้งหมดกี่ตัว และชือ่ อะไรบาง หากตองการกําหนดใหตัวแปรดัชนีที่ 3 ของมิติ 1 และดัชนีที่ 4 ของมิติ 2 มีคาเปน 12.5 จะเขียนคําสั่งอยางไร เรื่องที่ 4.1.2 การจัดสรรเนื้อที่แบบไดนามิก การจัดสรรเนื้อที่ในหนวยความจําแบบไดนามิก เปนการจัดสรรเนื้อที่หนวยความจําใหกับตัวแปร ระหวางการประมวลผล ตัวแปรที่มีคุณสมบัติดังกลาวนี้คือ ตัวแปรแบบพอยนเตอร ดังตัวอยาง TYPE StdElement = RECORD Key : KeyType; Data : DataType; END; TYPE pointer = ^StdElement VAR P : pointer!
จากตัวอยางขางตน เมื่อมีการนิยามหรือประกาศตัวแปร P ซึ่งมีชนิดเปน pointer นัน้ เมือ่ คอมไพล โปรแกรมเสร็จจะยังไมมีการจัดสรรเนื้อที่หนวยความจําใหกับตัวแปร P หนวยความจําจะถูกจัดสรรใหกับตัว แปร P ก็ตอเมื่อมีการรองขอหนวยความจําในระหวางการประมวลผลโปรแกรมดวยคําสั่ง new(P)
!& หลังจากคําสัง่ new(P) สิง่ ทีเ่ กิดขึน้ คือ ระบบปฏิบัติการจะจัดสรรเนื้อที่จากฮีปชนิด StdElement ให สมมติที่เริ่มจากตําแหนง (address) ที่ 188 ดังนัน้ P จะเก็บคาของตําแหนงหนวยความจํา คือ 188 (จริง ๆ แลว P จะไดรับการจัดสรรเนื้อที่แบบสแตติกหลังจากที่คอมไพลโปรแกรมแลวแต P ยังไมมีคา เมื่อมีการ ประมวลผลคําสัง่ new(P) จะมีการจัดสรรเนื้อที่ในหนวยความจําจากฮีปใหมีชนิดเปน StdElement ตัวแปรนี้ จะชื่อ P^ ซึ่งเปนตัวแปรชนิดระเบียนประกอบดวยตัวแปรยอย 2 ตัวคือ P^.Key และ P^.Data แตตัวแปรทั้ง สองนี้ยังไมมีคา P P^ Key Data 188 ถาสมมติวา StdElement มีชนิดเปน StudentRec (จากตัวอยาง 3.8) ซึ่งนิยามดังนี้ TYPE StudentRec = RECORD Id : string[9]; {Key part} Name : string[20]; Math, Stat, Comp : integer; END;
เมือ่ มีการเรียกใช new(P) และสมมติวาเนื้อที่ที่จัดสรรใหในฮีปเริ่มที่ตําแหนง 200 P จะมีคาเปน 200 และตัวแปร P^ ซึ่งมีชนิดเปน StudentRec ยังไมมีคา P Id
P^ Name
Math Stat Comp
P^ Name
Math Stat Comp
200 หากมีการกําหนดคาใหกับตัวแปร P^ ดังนี้ P^.Id := ‘411021003’; P^.Name := ‘Krisada’; P^.Math := 70; P^.Stat := 65; P^.Comp := 85; ผลทีเ่ กิดขึน้ จะเปนดังนี้ P Id 200
411021003
Krisada
70
65
85
!! หากเราไมมีความจําเปนตองใชเนื้อที่นี้อีกแลว เราก็ควรคืนเนื้อที่ในหนวยความจําใหกับระบบปฏิบัติ การไปโดยใชคําสั่ง dispose เชน dispose(P) เปนตน กิจกรรม 4.2 หากมีการนิยามดังนี้ TYPE StudentRec = RECORD Id : string[9]; {Key part} Name : string[20]; Math, Stat, Comp : integer; END; pointer = ^StudentRec; VAR Q : pointer;!
จงเขียนคําสั่งเพื่อเก็บคาของขอมูลชนิด StudentRec ใหมีคาดังนี้ Id = 411021005 Name = Worrawut Math = 60 Stat = 75 Comp = 81
!' ตอนที่ 4.2 ลิงคลสิ ต หัวเรื่อง เรือ่ งที่ 4.2.1
การกําหนดคุณลักษณะเฉพาะของลิงคลสิ ตอยางงาย
เรือ่ งที่ 4.2 2
การสรางลิงคลสิ ตอยางงาย
เรือ่ งที่ 4.2.3
การใชลงิ คลสิ ตอยางงาย
แนวคิด 1. ลิงคลิสตอยางงายเปนชนิดขอมูลที่มีโครงสรางแบบเชิงเสน ที่สรางมาจากตัวแปรชนิดพอยน เตอร 2. ลิงคลสิ ตอยางงายเปนชนิดขอมูลทีเ่ ปรียบไดกบั อะเรย โดยทีอ่ ะเรยจะเปนการจัดสรรเนือ้ ที่ หนวยความจําแบบสแตติก แตลิงคลิสตจะเปนการจัดสรรเนื้อที่หนวยความจําแบบไดนามิก 3. ในที่นี้จะนําเสนอชนิดขอมูลแบบลิงคลิสตอยางงายดวยหลักการของขอมูลแบบคัดยอ นัน้ คือ การกําหนดคุณลักษณะเฉพาะของลิงคลสิ ตอยางงาย (โดยกําหนดการดําเนินงานหลัก ๆ บาง ตัวเทานั้น) การสรางลิงคลสิ ตอยางงาย และทดสอบการใชงาน วัตถุประสงค หลังจากที่ศึกษาตอนที่ 4.2 แลว นักศึกษาสามารถ 1. เขียนคุณลักษณะเฉพาะของลิงคลสิ ตอยางงายได 2. สรางลิงคลสิ ตอยางงายได 3. ทดสอบการใชงานของลิงคลสิ ตอยางงายได เรื่องที่ 4.2.1 การกําหนดคุณลักษณะเฉพาะของลิงคลิสตอยางงาย คุณลักษณะเฉพาะ 4.1 : คุณลักษณะเฉพาะของลิงคลิสตอยางงาย สมาชิก:
โครงสราง:
โหนดซึง่ เปนเรคคอรดของ 2 สวน คือ สวนของขอมูล (El ซึ่งมีชนิดเปน StdElement ) และ สวนของพอยนเตอร ซึ่งชี้ไปที่ (หรือเก็บตําแหนงหนวยความจํา) สมาชิกหรือโหนดตัวถัด ไป ความสัมพันธระหวางสมาชิกเปนแบบเชิงเสน (linear)
การดําเนินงาน: ในทีน่ จ้ี ะกลาวถึงการดําเนินงานบางสวนเทานัน้ สวนการดําเนินงานทัง้ หมดจะไดกลาวถึง ในรายละเอียดอีกครัง้ หนึง่ เมือ่ เรียนถึงชนิดขอมูลแบบลิสต ในบทเรียนที่ 7 สัญลักษณ: ให
L–pre แทน ลิสตกอ นการดําเนินงาน
!( C–pre แทน โหนดปจจุบัน กอนการดําเนินงาน C-next แทน โหนดถัดจากโหนดปจจุบัน กอนการดําเนินงาน C-prior แทน โหนดกอนโหนดปจจุบัน กอนการดําเนินงาน {สรางลิสตขน้ึ เปนลิสตวา ง}
Create Pre:
ไมมี
Post:
สรางลิสตขน้ึ ซึง่ เปนลิสตวา ง {ใส E หลังสมาชิกตัวปจจุบัน}
Insert (E : StdElemant ) Pre:
ไมมี
Post:
E เปนสมาชิกตัวถัดจากตัวปจจุบันของลิสต และ E จะเปนสมาชิกตัวปจจุบัน { ลบสมาชิกตัวปจจุบันออกจากลิสต }
Delete Pre:
ลิสตตอั งไมเปนลิสตวา ง
Post:
C–pre ตองไมอยูในลิสต ถา C–pre เปนโหนดแรก แลว C–next จะเปนโหนดแรกไมเชนนั้น C–next จะเปนโหนด ตอจาก C – prior
ถาลิสตไมเปนลิสตวางแลวโหนดปจจุบันจะเปนโหนดแรกไมเชนนั้นโหนดแรกไมมี Retrieve (VAR E : StdElement ) {นําขอมูลของโหนดปจจุบนั มาแสดง} Pre:
ลิสตตอ งไมเปนลิสตวา ง
Post:
E มีคาเทากับคาของโหนดปจจุบัน {เปลี่ยนแปลงขอมูลของโหนดปจจุบัน}
Update (E : StdElement) Pre:
ลิสตตอ งไมเปนลิสตวา ง
Post:
C–pre มีคาเทากับ E {ใหโหนดแรกเปนโหนดปจจุบัน}
Findfirst Pre:
ลิสตตอ งไมเปนลิสตวา ง
Post: - โหนดแรกจะเปนโหนดปจจุบนั Findnext (VAR Fail : boolean)
{ใหโหนดถัดไปเปนโหนดปจจุบัน}
Pre:
ลิสตตอ งไมเปนลิสตวา ง
Post:
ถา C-pre ไมใชโหนดสุดทายแลว C–next จะเปนโหนดปจจุบัน ไมเชนนั้น Fail จะเปนจริง
Empty : boolean
{ ทดสอบวาเปนลิสตวา งหรือไม }
!) Pre:
ไมมี
Post:
ถาลิสตไมมีโหนดเลยแลว Empty จะเปนจริง ไมเชนนั้น Empty จะเปนเท็จ
เรื่องที่ 4.2.2 การสรางลิงคลิสตอยางงาย ในการสรางลิงคลสิ ตอยางงายนัน้ เราตองคํานึงถึงสองสิง่ คือ การเลือกการแทนทีข่ อ มูลของลิงคลสิ ต และการสรางการดําเนินงานของลิงคลสิ ต ใหสมาชิกของลิสตมีชนิดเปน StdElement เราสามารถนิยามการแทนทีข่ อ มูลของลิงคลสิ ต เปนดัง นี้ TYPE
pointer = ^Node Node = RECORD El : StdElement; Next : pointer END VAR Head, Current : pointer
แผนภาพของลิงคลิสตอยางงาย แทนไดดงั นี้ Head
Current
ในสวนของการดําเนินงานแตละการดําเนินงาน สามารถจะนําเสนอในรูปของแผนภาพและโปรแกรม ไดดงั นี้ Create L-post: Head
nil , Current
PROCEDURE Create; BEGIN Head := nil; Current := nil; END;!
Insert (E) E:
Key
Data
=
5
nil
'* Current L – pre :
Head
4
7
L – post :
8
nil
Current
Head
4
7
5
8
nil
แผนภาพแสดงขัน้ ตอนการทํางานเปนดังนี้ new ( p ) P กําหนดคาใหกับโหนด โดยมีคาเทากับ E P
5
nil
ใสโหนด P หลังโหนด Current และใหโหนด Current เปนโหนด P L – post : Head
Current P 4
7
PROCEDURE Insert (E:StdElement); VAR P : pointer; BEGIN new(P); P^.El := E; IF Head = nil THEN Head := P; ELSE BEGIN P^.Next := Current^.Next; Current^.Next := P; END; Current := P; END;
5
8
nil
'" Delete L – pre: Head
L – post: Head
Current 1
2
3
4
nil
2
3
4
nil
Current 1
dispose ในการเขียนโคตนั้น จะตองพิจารณาสถานะทีเ่ ปนไปไดใหครอบคลุม ไดแก Current อยูที่โหนดใด ๆ นอกจากโหนดสุดทาย หรือ Current อยูที่โหนดสุดทาย หรือ Current อยูที่โหนดเดียวกับ Head เปนตน PROCEDURE Delete; VAR P : pointer; BEGIN IF Current <> Head THEN {Find the predecessor of the current node} BEGIN P := Head; WHILE P^.Next <> Current Do P := P^.Next; {Link it to the successor of the current} P^.Next := Current^.Next; dispose(Current); Current := Head; END ELSE BEGIN P := Head; Head := Head^.Next; Current := Head; dispose(P); END; END;
Retrieve (E)
'# L – pre: Head
Current 1
2
L – post: Head
3
4
nil
3
4
nil
3
4
nil
7
4
nil
Current 1
2 E:
3
PROCEDURE Retrive(VAR E:StdElement); BEGIN E := Current^.El; END;
Update (E) E:
Key
Data =
7
L – pre: Head
Current 1
2
L – post: Head
Current 1
2
PROCEDURE Update(E:StdElement); BEGIN Current^.El:=E; END;
'$ Findfirst L – pre: Head L – post: Head
Current 1
2
3
4
nil
2
7
4
nil
4
nil
4
nil
Current 1
PROCEDURE FindFirst; BEGIN Current := Head; END;
FindNext L – pre: Head
Current 1
2
3
L – post: Head
Current 1
2
7
PROCEDURE Findnext(VAR Fail:boolean ); BEGIN Fail:=flase; IF Current^.Next <> nil THEN Current := Current^.Next ELSE Fail := true; END;
Empty L – pre : Head
nil , Current
nil
'% Empty : true L – pre:
Current
Head
1
2
3
4
nil
Empty : false FUNCTION Empty : boolean; BEGIN IF Head <> nil THEN Empty := false ELSE Empty := true; END;
การสรางชนิดขอมูลลิงคลสิ ตอยางงายตามคุณลักษณะเฉพาะทีร่ ะบุขา งตน ไดแสดงไวในโปรแกรมที่ 4.1 UNIT LinkLisU; INTERFACE TYPE StudentRec = RECORD Id :integer; Name : string[15]; Math,Stat,Comp : integer; END; Node = RECORD EL : StudentRec; Next : pointer; END; pointer = ^Node; VAR Head, Current : pointer; PROCEDURE PROCEDURE PROCEDURE PROCEDURE PROCEDURE PROCEDURE PROCEDURE FUNCTION
Create; Insert(E : StudentRec); Delete; Retrive(VAR E : StudentRec); Update(E : StudentRec); FindFirst; FindNext(VAR Fail : boolean); Empty:boolean;
IMPLEMENTATION PROCEDURE Create; BEGIN
'& Head := nil; Current := nil; END; PROCEDURE Insert(E : StudentRec); VAR P:pointer; BEGIN new(P); P^.El := E; IF Head = nil THEN Head := P; ELSE BEGIN P^.Next := Current^.Next; Current^.Next := P; END; Current := P; END;
PROCEDURE Delete; VAR P : pointer; BEGIN IF Current <> Head THEN {Find the predecessor of the current node} BEGIN P := Head; WHILE P^.Next <> Current Do P := P^.Next; {Link it to the successor of the current} P^.Next := Current^.Next; dispose(Current); Current := Head; END ELSE BEGIN P := Head; Head := Head^.Next; Current := Head; dispose(P); END; END; PROCEDURE Retrive(VAR E : StudentRec); BEGIN E := Current^.El; END; PROCEDURE Update(E : StudentRec); BEGIN
'! Current^.El:=E; END; PROCEDURE FindFirst; BEGIN Current := Head; END; PROCEDURE Findnext(VAR Fail : boolean); BEGIN Fail := false; IF Current^.Next <> nil THEN Current := Current^.Next ELSE Fail := true; END; FUNCTION Empty : boolean; BEGIN IF Head <> nil THEN Empty := false ELSE Empty := true; END; END.
โปรแกรม 4.1 การสรางชนิดขอมูลแบบลิงคลิสต กิจกรรม 4.3 การทดสอบการสรางขอมูลแบบลิงคลิสต จงทดสอบโปรแกรม 4.1 เรื่องที่ 4.2.3 การใชลิงคลิสตอยางงาย จากตัวอยางในเรื่องที่ 3.3.2 ใหดาํ เนินการในลักษณะเดียวกันแตใชลงิ คลสิ ตอยางงายในการจัดเก็บ ขอมูลแทนการใชอะเรย สมมติมีขอมูลแสดงถึงคะแนนสอบของนิสิต 3 วิชา ของนักเรียนชั้นหนึ่งในไฟลชื่อ Student.dat จง เขียนโปรแกรมเพือ่ พิมพรายงานผลการสอบของนักเรียนในชัน้ นี้ พรอมทั้งหาคาเฉลี่ยของแตละรายวิชา ตัว อยางโปรแกรมการใชแสดงในโปรแกรม 4.2 กิจกรรม 4.4 การทดสอบการใชลิงคลิสตอยางงาย จงเขียนโปรแกรม 4.2 ใหสมบูรณ พรอมทดสอบการใชงาน
'' PROGRAM LinkListTest(InFile); USES wincrt, LinkLisU; CONST Size = 100; VAR E : StudentRec; SumMath, SumStat, SumComp : integer; MeanMath, MeanStat, MeanComp : real; InFile:text; PROCEDURE ReadData; PROCEDURE ReadElement(VAR E:StudentRec); BEGIN WITH E DO readln(InFile,Id,Name,Math,Stat,Comp); END; BEGIN WHILE NOT EOF(InFile) DO BEGIN ReadElement(E); Insert(E); END; END; PROCEDURE PrintData; VAR Fail : boolean; BEGIN writeln('Id':5,' Name ':15,'Math':5,'Stat':5,'Comp':5); writeln('-------------------------------------'); FindFirst; REPEAT Retrive(E); WITH E DO writeln(Id:5,Name:15,Math:5,Stat:5,Comp:5); FindNext(Fail); UNTIL Fail; END; PROCEDURE CalculateMean; BEGIN END; BEGIN create; assign(InFile,'Data.Dat'); reset(InFile); ReadData; PrintData; CalculateMean; END.
โปรแกรม 4.2 โปรแกรมทดสอบการใชลิงคลิสตอยางงาย