โปรแกรมย่อย (Procedure) และฟังก์ชัน (Function)
ภาษาปาสคาล เรียกโปรแกรมย่อยว่า Procedure ซึ่งเป็นโปรแกรมเล็ก ๆ ภายในโปรแกรมใหญ่ทั้งหมด แต่โปรแกรมหลักจะมีความเป็นอิสระในตัวเอง ส่วน Procedure จะเป็นอิสระและจบในตัวเอง แต่จะถูกเรียกใช้จากโปรแกรมหลัก หรือ Procedure อื่น ๆ
โปรแกรมย่อย (Procedure)
วัตถุประสงค์ของการสร้างโปรแกรมย่อย
1. เป็นส่วนโปรแกรมที่ใช้ซ้ำกันในหลาย ๆ แห่ง และจะแยกออกมาทำเป็นโปรแกรมย่อย
2. เป็นคำที่สร้างขึ้นใหม่ เพื่อเก็บไว้ใช้ต่อไป
3. เมื่อต้องการเขียนโปรแกรมเป็น โมดูล จุดประสงค์ของการเขียนโปรแกรมเป็น โมดูล ก็เพื่อตรวจหาที่ผิดได้ง่าย ดังนั้น โปรแกรมย่อยหนึ่ง ๆ ก็คือ โมดูล ๆ หนึ่ง
4. เพื่อสนองความต้องการของการเขียนโปรแกรมจากบนลงล่าง
รูปแบบของ Procedure
PROCEDURE ชื่อ Procedure (argument);
VAR ชื่อตัวแปรที่จะใช้ใน Procedure;
BEGIN
คำสั่ง;
END;
การเรียกใช้ Procedure จากโปรแกรมหลัก ทำได้โดยการเรียกชื่อของ Procedure โดยถือว่า Procedure เป็นคำสั่ง ๆ หนึ่ง เช่น ถ้าโปรแกรมใหญ่มี Procedure yyy; ในโปรแกรมหลักจะเรียกใช้ Procedure ได้โดยใช้คำสั่งภายในโปรแกรมหลักว่า yyy;
ตัวอย่าง
PROGRAM EXAM16;
VAR I:INTEGER;
PROCEDURE MMM;
BEGIN
WRITELN(‘THIS IS MMM PROCEDURE’);
END;
PROCEDURE NNN;
VAR J:INTEGER;
BEGIN
FOR J:=1 TO I DO
WRITELN(‘THIS IS NNN PROCEDURE’);
WRITELN(‘END OF NNN LOOP’);
WRITELN(‘NOW CALL MMM FROM NNN’);
MMM;
END;
BEGIN {MAIN}
WRITELN(‘THIS IS MAIN PROGRAM’);
WRITELN(‘ENTER NUMBER’);
READLN(I);
WRITELN;
WRITELN(‘NOW CALL NNN FROM MAIN’);
NNN;
WRITELN;
WRITELN(‘NOW CALL MMM FROM MAIN’);
MMM;
READLN;
END.
ฟังก์ชัน (Function)
ภาษาปาสคาลจัดให้ฟังก์ชันเป็นรูปแบบหนึ่งของโปรแกรมย่อย เทียบเท่า Procedure ดังนั้น Function และ Procedure จึงมีลักษณะคล้ายกัน คือ เป็นส่วนหนึ่งของ program ใหญ่ ที่เขียนแยกออกไปจากโปรแกรมหลัก มีความสมบูรณ์ในตัวเอง และสามารถส่งผ่านค่าของตัวแปรระหว่างโปรแกรมหลักกับ Function หรือระหว่าง Procedure กับ Function
รูปแบบ
FUNCTION ชื่อฟังก์ชัน (อากิวเมนต์) : Type;
VAR ชื่อตัวแปรที่ใช้เฉพาะในฟังก์ชัน
BEGIN
คำสั่งต่าง ๆ ;
END;
เปรียบเทียบ FUNCTION กับ PROCEDURE
1. ช่วยให้การเขียนโปรแกรมแบบ top-down design ง่ายและสะดวก
2. ช่วยให้หน่วยย่อย ๆ ของโปรแกรมเป็นอิสระต่อกัน
3. สามารถเรียกใช้ส่วนของโปรแกรมที่ทำงานซ้ำ ๆ กันได้โดยไม่ต้องเขียนโปรแกรมส่วนนั้นซ้ำ ๆ กันหลายครั้ง
4. เพื่อช่วยให้ตรวจสอบจุดต่างๆ ภายในโปรแกรม หรือทำให้การคำนวณที่ใช้สูตรต่าง ๆ ภายในโปรแกรมง่ายขึ้น
5. เพื่อช่วยให้เกิดคำสั่งใหม่ ๆ (Function) และส่วนของ program (Procedure) ที่สามารถนำไปใช้กับโปรแกรมอื่น ๆ ได้
6. Procedure จะเป็นส่วนของโปรแกรมใหญ่ที่เขียนขึ้นเพื่อทำงานเฉพาะอย่าง ส่วน Function จะเป็นโปรแกรมย่อยเหมือนเป็นการสร้างคำใหม่ขึ้นมา
7. Procedure จะถูกเรียกใช้จากโปรแกรมหลักหรือจาก Procedure อื่น ๆ ด้วยกันได้โดยที่แต่ละ Procedure ทำงานเป็นอิสระต่อกัน ส่วน Function จะถูกใช้ทำงานภายในโปรแกรมหลักหรือภายใน Procedure ส่วนมากเป็นการสร้างคำเพื่อใช้ในการคำนวณที่ซับซ้อน หรือเป็นคำที่ใช้กำหนดเงื่อนไขในการดำเนินการต่าง ๆ ภายในโครงสร้างของโปรแกรมใหญ่ทั้งหมด
ตัวอย่าง
PROGRAM EX17;
USES CRT;
VAR X,Y,Z:INTEGER;
PROCEDURE SW (VAR N1,N2:INTEGER);
VAR T:INTEGER;
BEGIN
T:=N1;
N2:T;
END;
FUNCTION MAX (N1,N2:INTEGER):INTEGER;
BEGIN
IF N1>N2 THEN MAX:=N1
ELSE MAX:=N2;
END;
BEGIN {MAIN PROGRAM}
WRITE(‘ENTER TWO NUMBER :’);
READLN(X,Y);
SW(X,Y);
WRITELN(‘X= ‘,X,’Y= ‘,Y);
Z:=MAX(X,Y);
WRITELN(‘MAX VALUE BETWEEN X AND Y= ‘,Z);
END.
อธิบาย
1. รูปแบบของ Procedure ต่างจาก Function คือ Procedure SW จะระบุค่าอาร์กิวเมนต์ 2 ตัวแปร คือ N1 และ N2 เป็นตัวแบบจำนวนเต็ม เพื่อรับค่าพารามิเตอร์ X,Y แต่ฟังก์ชัน MAX จะระบุอาร์กิวเมนต์ 2 ตัวแปร คือ N1 และ N2 เหมือนกัน เป็นแบบจำนวนเต็ม เพื่อรับค่าพารามิเตอร์ X,Y และระบุว่าผลลัพธ์ของ MAX เป็นจำนวนเต็ม คือผลลัพธ์ของค่าสูงสุดเท่ากับ X หรือ Y
2. ฟังก์ชัน MAX จะถูกอ้างอิงภายใน Begin…End; จากตัวอย่างของฟังก์ชัน ใช้คำนวณค่าของ MAX และส่งกลับไปยัง Main Program ที่เรียกใช้ฟังก์ชันนี้อยู่
3. การเรียกใช้ Procedure แล Function ต่างกันคือ ชื่อของ Procedure จะถูกเรียกใช้เหมือนคำสั่ง ๆ หนึ่ง แต่ฟังก์ชันจะถูกเรียกใช้ในรูปของนิพจน์หรือเป็นส่วนหนึ่งของคำสั่งอื่น ๆ
4. การส่งผ่านค่าพารามิเตอร์ X,Y ไปยัง Procedure SW คือเมื่อส่งค่า X,Y ไปแล้วค่า X,Y จะถูกสลับค่า ได้ X,Y ใหม่มาในโปรแกรมหลัก แต่การส่งผ่านค่า parameter X,Y ไปยังฟังก์ชัน MAX จะไม่มีการเปลี่ยนค่า X,Y (N1 และ N2) เพียงแต่นำเอาไปคำนวณหาค่า MAX ซึ่งจะได้ผลลัพธ์ 1 ค่า คือ ชื่อของฟังก์ชัน MAX ที่กลับมาเป็นค่าของตัวแปร Z ในโปรแกรมหลัก ส่วนตัวแปร X,Y ในโปรแกรมหลักมีค่าเท่าเดิม
ตัวอย่าง
PROGRAM EXAM17;
USES CRT;
VAR Y:INTEGER;
PROCEDURE HEAD1(N:INTEGER);
VAR I:INTEGER;
BEGIN
WRITELN(‘BANGNA COMMERCIAL COLLEGE’);
FOR I:=1 TO N DO
WRITELN(‘------------------------------------------------‘);
END;
BEGIN {MAIN PROGRAM}
CLRSCR;
WRITELN(‘CALL PROCEDURE FIRST TIME’);
HEAD1(2);
WRITELN(‘CALL PROCEDURE SECOND TIME’);
Y:=3;
HEAD1(Y);
WRITELN(‘END PROGRAM’);
END.
ผลลัพธ์
CALL PROCEDURE FIRST TIME
BANGNA COMMERCIAL COLLEGE
-----------------------------------------------
-----------------------------------------------
CALL PROCEDURE SECOND TIME
BANGNA COMMERCIAL COLLEGE
-----------------------------------------------
-----------------------------------------------
-----------------------------------------------
END PROGRAM
ตัวอย่าง
PROGRAM EXAM18;
USES CRT;
VAR A,B:INTEGER;
PROCEDURE HEAD2(M,N:INTEGER);
VAR I:INTEGER;
BEGIN
FOR I:=1 TO M DO
WRITELN(‘**********************************’);
WRITELN(BANGNA COMMERCIAL COLLEGE’);
FOR I:=1 TO N DO
WRITELN(‘**********************************’);
END;
BEGIN {MAIN PROGRAM}
CLRSCR;
HEAD2(3,2);
END.
ผลลัพธ์
*************************************
*************************************
*************************************
BANGNA COMMERCIAL COLLEGE
*************************************
*************************************
ตัวอย่าง
PROGRAM EXAM;
USES CRT;
VAR ANS:CHAR;
I:INTEGER;
NAME,CODE:ARRAY[1..20] OF STRING;
TEST,MID,FINAL:ARRAY[1..20] OF INTEGER;
PROCEDURE ENTERDATA;
BEGIN
CLRSCR;
FOR I:=1 TO 20 DO
BEGIN
WRITE(‘ENTER CODE :’);READLN(CODE[I]);
WRITE(‘ENTER NAME :’);READLN(NAME[I]);
WRITE(‘ENTER TEST :’);READLN(TEST[I]);
WRITE(‘ENTER MIDTERM :’);READLN(MID[I]);
WRITE(‘ENTER FINAL :’);READLN(FINAL[I]);
END;
END;
PROCEDURE MENU;
BEGIN
CLRSCR;
WRITELN;WRITELN;WRITELN;WRITELN;WRITELN;
WRITELN(‘MAIN MENU’:30);
WRITELN(‘***************’:30);
WRITELN(‘1.TEST’:30);
WRITELN(‘2.MIDTERM’:30);
WRITELN(’3.FINAL’:30);
WRITELN(‘4.QUIT’:30); WRITELN; WRITELN;
WRITELN(‘ENTER YOUR CHOICE:’);READLN(ANS);
CASE ANS OF
‘1’ : BEGIN
CLRSCR; WRITELN; WRITELN; WRITELN;
WRITELN(‘CODE NAME TEST’:45);
FOR I:=1 TO 3 DO
BEGIN
WRITELN(CODE[I]:25,NAME[I]:10,TEST[I]:10);
END;
WRITELN; WRITELN; WRITELN;
WRITELN(‘…PRESS ENDTER…’:45);READLN;
END;
‘2’ : BEGIN
CLRSCR; WRITELN; WRITELN; WRITELN;
WRITELN(‘CODE NAME MIDTERM’:45);
FOR I:=1 TO 3 DO
BEGIN
WRITELN(CODE[I]:25,NAME[I]:10,MID[I]:10);
END;
WRITELN; WRITELN; WRITELN;
WRITELN(‘…PRESS ENDTER…’:45);READLN;
END;
‘3’ : BEGIN
CLRSCR; WRITELN; WRITELN; WRITELN;
WRITELN(‘CODE NAME FINAL’:45);
FOR I:=1 TO 3 DO
BEGIN
WRITELN(CODE[I]:25,NAME[I]:10,FINAL[I]:10);
END;
WRITELN; WRITELN; WRITELN;
WRITELN(‘…PRESS ENDTER…’:45);READLN;
END;
‘4’ : CLRSCR;END;
END;
BEGIN
ENTERDATA;
MENU;
MENU;
MENU;
MENU;
END.
คำสั่ง GOTOXY
เป็นคำสั่งตั้ง cursor ที่ตำแหน่งบนหน้าจอ
รูปแบบ
GOTOXY(Row,Column)
ตัวอย่าง
PROGRAM EXAM19;
USES CRT;
VAR A,B,D:INTEGER;
BEGIN
CLRSCR;
GOTOXY(15,5);
WRITELN(‘ENTER TWO NUMBER’);
GOTOXY(15,7);
READ(A,B);
D:=A+B;
GOTOXY(15,10);
WRITELN(‘SUM OF A AND B = ‘,D);
END.
โกลบอลและโลคอล (Global and Local)
โกลบอล (Global) หมายถึง ค่าใด ๆ ที่เรากำหนดไว้ในส่วนข้อกำหนดของโปรแกรมหลัก คำใดก็ตามไม่ว่าจะเป็นตัวแปร ค่าคงที่ ชื่อแบบข้อมูล หรือโปรแกรมย่อย ที่กำหนดไว้ในส่วนของข้อกำหนดของโปรแกรมหลัก ถือเป็นส่วนกลาง นำไปใช้ได้ทั้งโปรแกรมหลักและโปรแกรมย่อย
โลคอล (Local) หมายถึง ค่าใด ๆ ที่เรากำหนดไว้ส่วนข้อกำหนดของโปรแกรมย่อย รวมทั้งที่กำหนดในส่วนหัว คือ จะใช้ได้ในโปรแกรมย่อยนั้นหรือโปรแกรมย่อยรองลงไปของโปรแกรมย่อยนั้นเท่านั้น ส่วนโปรแกรมหลักและโปรแกรมย่อยอื่นจะนำไปใช้ไม่ได้
ตัวอย่าง แสดงโกลบอลและโลคอล
PROGRAM AA;
VAR NUM:INTEGER;
PROCEDURE A;
BEGIN
NUM:=NUM*10;
WRITELN(‘NUM*10 = ‘,NUM);
END;
VAR ANY:INTEGER;
PROCEDURE B;
VAR NUM,CNTR:INTEGER;
BEGIN
NUM:=124;
WRITELN(‘NUM = ‘,NUM);
CNTR:=122;
WRITELN(‘CNTR =’,CNTR);
END;
BEGIN {MAIN PROGRAM}
NUM:=5;
WRITELN(‘IN MAIN’,’NUM = ‘,NUM);
A;
B;
WRITELN(‘BACK TO MAIN NUM = ‘,NUM);
END.
ผลที่ได้จาการ RUN
NUM*10 = 50
NUM = 124
CNTR = 122
BACK TO MAIN NUM = 50
อธิบาย
- NUM ที่กำหนดในโปรแกรมหลักเป็นโกบอล คือให้ค่าและ output ในโปรแกรมหลักและให้ค่าและ output ใน program ย่อย A
- NUM, cntr ที่กำหนดใน program ย่อย B เป็นโลคอล B ซึ่งโปรแกรมหลักหรือโปรแกรมย่อยอื่น ๆ จะนำไปใช้ไม่ได้ แต่ชื่อ NUM ซ้ำกับ NUM ในโปรแกรมหลัก จึงถือว่าเป็นคนละ NUM กัน ที่โปรแกรมหลัก NUM=5 แต่พอถึง A นำมาคูณ 10 ได้ 50 เมื่อถึง B ให้ค่าใหม่เป็น 124 เมื่อกลับมาโปรแกรมหลักก็เป็น 124 แต่ยังเป็น 50 เพราะเป็น NUM คนละตัวกัน
-ก่อน Procedure B ได้กำหนดตัวแปร ANY ซึ่งเป็นโกบอล แต่ใช้ใน procedure A ไม่ได้ใช้ได้ใน procedure B และโปรแกรมหลัก
- เพราะฉะนั้น B เรียกใช้ A แต่ A เรียกใช้ B ไม่ได้ และทั้ง A,B เรียกใช้ AA ไม่ได้ เพราะเป็นโปรแกรมหลัก
อาร์เรย์ (Array)
จากเนื้อหาที่ผ่านมาได้แนะนำการกำหนดตัวแปรเพื่อใช้ในการเก็บข้อมูล ซึ่งตัวแปรเหล่านั้นมีลักษณะเป็นข้อมูลเดียว (Simple data type) ซึ่งมีความหมายว่าตัวแปรหนึ่งตัวจะสามารถเก็บข้อมูลได้เพียงข้อมูลเดียว เช่น
VAR X : integer;
จะมีความหมายว่า ตัวแปร X เป็นตัวแปรที่เก็บข้อมูลเลขจำนวนเต็ม ซึ่ง X จะสามารถเก็บเลขจำนวนเต็มได้ค่าเดียว ถ้าหากเราต้องการที่จะเก็บ ข้อมูลที่เป็นชนิดเดียวกันหลายๆ จำนวน เราก็จำเป็นจะต้องจองตัวแปรชนิดเดียวกันเป็นจำนวนหลายๆ ตัวให้เท่ากับจำนวนที่ต้องการด้วย ซึ่งตัวแปรแต่ละตัวก็จำเป็นจะต้องมีชื่อที่แตกต่างกันด้วยเช่น ถ้าต้องการจองตัวแปรชนิด เลขจำนวนเต็มเป็นจำนวน 10 ตัว โดยใช้วิธีดังที่กล่าวมาจะต้องทำดังนี้
VAR X1, X2, X3, X4, X5, X6, X7, X8, X9, X10 : integer;
จะเห็นว่าว่าวิธีการจองตัวแปรแบบนี้เป็นวิธีที่ไม่สะดวก เพราะถ้าหากมีตัวแปรเพิ่มขึ้นมากๆ เช่น 100 ตัวก็จะต้องพิมพ์ชื่อตัวแปรไปเรื่อยๆ จนครบจำนวน 100 ตัวเช่นกัน และถ้าหากสังเกตให้ดีแล้วการจองตัวแปรในลักษณะนี้จะก่อให้เกิดความยุ่งยากในการเขียนโปรแกรมด้วย
ตัวแปรข้อมูลชนิดโครงสร้าง (Structured data type) ซึ่งลักษณะตัวแปรข้อมูลประเภทนี้เกิดจากการนำเอาข้อมูลชนิดพื้นฐานหลายตัวมาประกอบรวมกันตามแต่ที่ผู้ใช้จะกำหนด เช่น ข้อมูลชนิดอาร์เรย์ ข้อมูลชนิดเรคอร์ด ข้อมูลชนิดเซต และข้อมูลชนิดไฟล์ เป็นต้น ซึ่งการนำข้อมูลหลายๆตัวมารวมกันจะสามารถแก้ไขความยุ่งยากที่เกิดขึ้นจากการมีตัวแปรปริมาณมาก ๆ ได้ คือ มีตัวแปรทั้งสิ้น 100 ตัว และต้องการรวมตัวแปร 100 ตัวนี้เข้าด้วยกันเป็นตัวแปรข้อมูลชนิดโครงสร้างตัวเดียว เช่นนี้ สามารถทำได้โดยตัวแปรชนิดโครงสร้างที่เรียกว่า อาร์เรย์ (ARRAY)
อาร์เรย์ เป็นข้อมูลแบบโครงสร้างชนิดหนึ่ง ซึ่งประกอบขึ้นจากข้อมูลหลายๆ ตัวรวมเข้าด้วยกันเป็นกลุ่ม โดยข้อมูลแต่ละตัวในกลุ่มถูกเรียกว่าเอลิเมนต์ (Element) และแต่ละเอลิเมนต์จะต้องเป็นข้อมูลชนิดเดียวกัน การอ้างถึงข้อมูลจะใช้ตัวแปรชื่อเดียว ซึ่งจะหมายถึงชื่อของกลุ่ม และสามารถอ้างถึงข้อมูลแต่ละเอลิเมนต์ในกลุ่มได้โดยใช้ดัชนี (Index) ต่อท้ายหลังชื่อตัวแปรของกลุ่ม ดัชนีนี้จะเป็นตัวบ่งบอกถึงลำดับที่ของเอลิเมนต์ ลักษณะของดัชนีที่เราสามารถเข้าใจได้ง่ายที่สุดก็คือ ตัวเลข
การประกาศและอ้างถึงข้อมูลชนิดอาร์เรย์
จากส่วนประกาศตัวแปรในการจองตัวแปรจำนวน 10 ตัวเพื่อใช้ในการเก็บข้อมูลที่เป็นเลขจำนวนเต็ม ตามตัวอย่างที่ผ่านมานั้น เราจองตัวแปร X1,X2,X3,X4,X5,X6,X7,X8,X9,X10 เป็นตัวแปรชนิดจำนวนเต็ม ซึ่งถ้าหากเราเปลี่ยนมาใช้ตัวแปรชนิดโครงสร้างที่เป็นอาร์เรย์ก็สามารถทำได้ดังต่อไปนี้
VAR X : ARRAY [1..10] OF integer;
จากส่วนประกาศตัวแปรข้างบนพบว่าตัวแปร X เป็นตัวแปรแทนกลุ่มข้อมูลชนิดเลขจำนวนเต็ม โดยจำนวนของเอลิเมนต์ให้ดูจากดัชนี ซึ่งการกำหนดดัชนีของข้อมูลตามตัวอย่างถูกกำหนดให้อยู่ในรูปของช่วงย่อย (Subrange) โดยช่วงย่อยนี้ประกอบด้วย ค่าเริ่มต้น เครื่องหมาย ".." และค่าสิ้นสุด ทั้งหมดนี้จะอยู่ภายในเครื่องหมาย "[" และ "]" ในที่นี้คือ[1..10] ซึ่งมีความหมายว่า ดัชนีของตัวแปรอาร์เรย์ X เริ่มต้นจากเลข 1จนถึงเลข 10 รวมจำนวนทั้งสิ้น 10 ตัว และเราสามารถอ้างถึงข้อมูลแต่ละเอลิเมนต์ได้ดังนี้
X[1] ,X[2] ,X[3] ,X[4] ,X[5] ,X[6] ,X[7] ,X[8] ,X[9] ,X[10]
ภาพแสดงลักษณะโครงสร้างของตัวแปร X ซึ่งเป็น อาร์เรย์ ของเลขจำนวนเต็ม
VAR
X : ARRAY [0..99] OF real;
n : integer;
n : integer;
BEGIN {main program}
FOR n := 0 TO 99 DO
X[n] := n+1;
END.
จากตัวอย่างจะพบว่า X เป็นตัวแปรโครงสร้างชนิดอาร์เรย์ของ เลขจำนวนจริง โดยมี ดัชนีเริ่มต้นจาก 0 ถึง 99 รวมทั้งสิ้นเป็นเลขจำนวนเต็มทั้งหมด 100 จำนวน ซึ่งทำให้เราทราบว่าดัชนีของข้อมูลไม่จำเป็นที่จะต้องเริ่มต้นด้วย 1 ซึ่งในที่นี้เริ่มต้นด้วย 0 และจากส่วนของ main program ซึ่งทำการกำหนดค่าข้อมูล ตั้งแต่ 1 ถึง 100 ให้กับตัวแปร X ตั้งแต่ ดัชนี ที่ 0 ถึงดัชนีที่ 99 จะเห็นว่าเราสามารถใช้ตัวแปร n เป็นดัชนีเพื่อทำการชี้ตำแหน่งเอลิเมนต์ของตัวแปร X
TYPE lettertype = ARRAY ['A'..'Z'] OF Integer;
VAR
VAR
letter : lettertype;
index : 'A'..'Z';
index : 'A'..'Z';
BEGIN {main program}
FOR cindex := 'A' TO 'Z' DO letter[cindex] := 0;
END.
จากตัวอย่างทำให้เราทราบว่าดัชนีของอาร์เรย์อาจจะเป็นชนิดข้อมูลอิสระ ก็ได้ ซึ่งในที่นี้ดัชนีของตัวแปรอาร์เรย์ที่ชื่อว่า letter นี้ก็คือ ตัวอักษร 'A' ถึง 'Z'
TYPE
DayOfWeek = (sun, mon, tue, wed, thu, fri, sat);
day = ARRAY [DayOfWeek] OF integer;
day = ARRAY [DayOfWeek] OF integer;
VAR
day : Dday;
จากตัวอย่าง จากส่วนประกาศจะพบว่าเราสามารถกำหนดชนิดข้อมูล ขึ้นมาใหม่มีลักษณะเป็นแบบแจงนับ (enumerated data type) และใช้ชนิดของข้อมูลใหม่นี้เป็นดัชนีของอาร์เรย์ได้ ซึ่งจะทำให้เกิดเอลิเมนต์ดังต่อไปนี้
day[sun],day[mon],day[tue],day[wed], day[thu],day[fri],day[sat]
TYPE
ArrayOfChar = ARRAY [BYTE] OF char;
VAR
Message : ArrayOfChar;
ในตัวอย่างพบว่าสามารถใช้ชนิดของตัวแปร บางชนิดในการกำหนดดัชนีของตัวแปรอาร์เรย์ได้ชนิดข้อมูลที่ใช้กำหนดเป็น ดัชนีของข้อมูลชนิดอาร์เรย์ได้จะต้องเป็นข้อมูลแบบเรียงลำดับ (Ordinal Type) เท่านั้น จากตัวอย่าง เราได้ตัวแปรที่ชื่อ message เป็นอาร์เรย์ของตัวอักษร โดยมีจำนวนตัวอักษรหรือเอลิเมนต์ทั้งหมด 256 ตัวอักษร
ชนิดข้อมูลที่กำหนดให้กับเอลิเมนต์ในอาร์เรย์จะเป็นข้อมูลชนิดใดก็ได้เช่น ข้อมูลชนิดพื้นฐาน ข้อมูลชนิดโครงสร้างอื่นๆ รวมทั้งข้อมูลชนิดอาร์เรย์เอง แต่ทุกเอลิเมนต์ในอาร์เรย์เดียวกันจะต้องมีชนิดเหมือนกันเช่น
TYPE
Complex_number = RECORD
real_val : real;
imag_val : real;
imag_val : real;
END;
Sample = (HCL,CO1,SO2);
Sampling_result = ARRAY [ sample ] OF real;
Testing_mode =(burnt_test,shock_test,prev_maintenance,overall);
Testing_set = ARRAY [Testing_mode] OF Sampling_result;
Sample = (HCL,CO1,SO2);
Sampling_result = ARRAY [ sample ] OF real;
Testing_mode =(burnt_test,shock_test,prev_maintenance,overall);
Testing_set = ARRAY [Testing_mode] OF Sampling_result;
VAR
X : ARRAY [1..20} OF Complex_number;
Experiment_Result : ARRAY [1..10] OF Sampling_result;
Monthly_Operation : ARRAY [1..31] OF Testing_set;
Experiment_Result : ARRAY [1..10] OF Sampling_result;
Monthly_Operation : ARRAY [1..31] OF Testing_set;
การใช้ข้อมูลอาร์เรย์เบื้องต้น
ตัวแปรที่มีชนิดข้อมูลอาร์เรย์นั้น เมื่อเรานำมาใช้งานส่วนใหญ่แล้วผู้ใช้จะต้องการอ้างเข้าไปถึง เอลิเมนต์แต่ละตัวของอาร์เรย์ โดยใช้ดัชนีเป็นตัวช่วยอ้างถึงตำแหน่งเอลิเมนต์ที่ต้องการ หากต้องการใช้หรืออ้างถึงทุกๆ เอลิเมนต์ หรือช่วงใดช่วงหรือช่วงหนึ่งของอาร์เรย์ เราสามารถทำได้โดยใช้คำสั่งวนรอบเพื่อเข้าถึงเอลิเมนต์ทีละเอลิเมนต์จนครบทุกเอลิเมนต์ตามที่ต้องการ ในหัวข้อนี้จะกล่าวถึงวิธีการเขียนโปรแกรมเพื่อเข้าถึงเอลิเมนต์ต่างๆ ในตัวแปรอาร์เรย์
การตั้งค่าข้อมูลเริ่มต้นให้แก่ทุกเอลิเมนต์ให้มีข้อมูลค่าเดียวกันเขียนได้ดัง
CONST max_samp = 100;
VAR
VAR
Score : ARRAY [ 1.. max_samp] OF real;
IDX : integer;
IDX : integer;
BEGIN
FOR IDX := 1 TO max_samp DO
Score[IDX] := 0.0;
END.
การรับข้อมูลและแสดงผลตัวแปรชนิดอาร์เรย์
คำสั่ง READ, READLN, WRITE, WRITELN ซึ่งเป็นคำสั่งรับข้อมูล และแสดงผลของภาษาปาสคาล ไม่สามารถใช้รับข้อมูลหรือแสดงผลตัวแปรอาร์เรย์ได้ทั้งตัว ต้องสั่งให้แสดงผลทีละ เอลิเมนต์ไป ตัวอย่างในการรับข้อมูลและแสดงผลตัวแปรอาร์เรย์ แสดงในตัวอย่าง
PROGRAM Ex_Result (Input,Output);
CONST
CONST
Max_Samp = 100;
VAR
Exp_Result : ARRAY [1.. Max_Samp] OF real;
ExNo : integer;
Max_Exp : integer;
ExNo : integer;
Max_Exp : integer;
BEGIN
REPEAT
Write('Enter no. OF sampling : ');
Readln(Max_Exp);
Readln(Max_Exp);
UNTIL (Max_Exp <= max_samp) and (max_exp > 0);
FOR ExNo := 1 TO Max_Exp DO
BEGIN
FOR ExNo := 1 TO Max_Exp DO
BEGIN
Write('Result No.',ExNo:4':');
Readln('Exp_Result[ExNo]);
Readln('Exp_Result[ExNo]);
END;
FOR ExNo := 1 TO Max_Exp DO
FOR ExNo := 1 TO Max_Exp DO
Writeln('Result no.',ExNo:4,' :',Exp_Result[ExNo]);
END.
การอ้างถึงตัวแปรอาร์เรย์ในรูปแบบต่าง ๆ
การใช้ตัวแปรอาร์เรย์ในคำสั่งต่างๆ ต้องอ้างถึงเอลิเมนต์ของอาร์เรย์ โดยระบุดัชนี เช่น
RESULT[I] := SCORE [ I ] / 100;
SUMMARY[1] := SUM_SCORE / NUM_SCORE;
SUMMARY[2] := NUM_SCORE;
STEP_VALUE[STEP_NO+1] := STEP_VALUE[STEP_NO] + STEP_INC;
SUMMARY[1] := SUM_SCORE / NUM_SCORE;
SUMMARY[2] := NUM_SCORE;
STEP_VALUE[STEP_NO+1] := STEP_VALUE[STEP_NO] + STEP_INC;
การอ้างถึงตัวแปรอาร์เรย์ทั้งตัว ที่มีการใช้ในคำสั่งบางลักษณะ ได้แก่
1. คำสั่งกำหนดค่าตัวแปรให้อาร์เรย์ตัวหนึ่งๆ (ทุกๆ เอลิเมนต์) มีข้อมูลเหมือนตัวแปรอาร์เรย์อีกตัวหนึ่งมีข้อจำกัดว่า ตัวแปรอาร์เรย์ทั้งสองตัวจะต้องประกาศด้วยชนิดข้อมูลอาร์เรย์ที่เหมือนกันเท่านั้น ดังตัวอย่าง
TYPE
Result_Array = ARRAY [1..100] OF real;
VAR
First_result, Second_Result : Result_Array;
BEGIN
Second_Result := First_Result;
END.
2. เป็นพารามิเตอร์ของโพรซีเยอร์ หรือฟังก์ชันที่กำหนดชนิดพารามิเตอร์เป็นอาร์เรย์หากมี โพรซีเยอร์ หรือฟังก์ชันที่ต้องส่งผ่านอาร์เรย์ทั้งตัวเป็นพารามิเตอร์ ก็สามารถใช้ชนิดข้อมูลอาร์เรย์เป็นชนิดของพารามิเตอร์ได้แต่ต้องประกาศชนิดโดยใช้ส่วนประกาศชนิด (Type) สร้างชื่อชนิดใหม่ที่เป็นอาร์เรย์ที่มีจำนวน และชนิดของเอลิเมนต์ตามที่ต้องการ จึงนำชื่อชนิดนั้นไปใช้เป็นชื่อชนิดของพารามิเตอร์ได้ในการเรียกใช้โพรซีเยอร์หรือฟังก์ชัน ตัวแปรที่จะส่งไปเป็นพารามิเตอร์ก็ต้องใช้ชนิดเดียวกันกับชื่อชนิดของการกำหนดพารามิเตอร์ในการประกาศโพรซีเยอร์หรือฟังก์ชันด้วย ดังตัวอย่าง
TYPE
Result_Array = ARRAY [1..100] OF real;
VAR
First_Result : Result_Array;
Frist_count : integer;
First_arg : real;
Frist_count : integer;
First_arg : real;
FUNCTION Result_avg(Result_A:Result_Array;Res_no:INTEGER):real;
VAR
VAR
R_SUM : real;
IDX : integer;
IDX : integer;
BEGIN
R_SUM := 0.0;
FOR IDX := 1 TO Res_no DO
FOR IDX := 1 TO Res_no DO
R_SUM := R_SUM + Result_A[IDX];
Result_avg := R_Sum/Res_no;
END;
PROCEDURE Print_Result(Result_A:Result_Array; Res_no:integer);
VAR
VAR
IDX : integer;
BEGIN
FOR IDX := 1 TO Res_no DO
Writeln(LST,'Result no.',IDX:4':',Result_A[IDX]:10:4);
END;
BEGIN
First_avg := Result_avg(First_Result,First_count);
Print_Result(First_Result,First_count);
Print_Result(First_Result,First_count);
END.
ประโยชน์ของการใช้อาร์เรย์ มักใช้เก็บข้อมูลที่เป็นชุด ในบางครั้งอาจต้องมีการค้นหาข้อมูล ที่เก็บอยู่ในอาร์เรย์เพื่อให้ได้ข้อมูลที่ต้องการ เช่น ต้องการข้อมูลที่มีค่าสูงสุด ต่ำสุด ต้องการข้อมูลที่มีค่าต่ำกว่าตัวแรกที่พบในชุดข้อมูลที่มีข้อความนำหน้าด้วยอักษร "S" หรืออาจต้องการรับข้อมูลเข้าสู่ตัวแปรอาร์เรย์ แล้วนำไปจัดเรียงลำดับค่ามากน้อย หรือเรียงลำดับตัวอักษรของข้อความ เพื่อนำไปแสดงผล หรือเก็บบันทึกให้สามารถนำไปใช้ต่อ ในหัวข้อนี้จะยกตัวอย่างการเขียนโปรแกรมเพื่อค้นหา และจัดเรียงลำดับข้อมูลที่มีอยู่ในอาร์เรย์
โปรแกรมนี้จะทำการรับค่าจำนวนของนักเรียน และรับค่าคะแนนของนักเรียนแต่ละคน หลังจากนั้นจะทำการหาผลรวมของคะแนนทั้งหมด และหาค่าเฉลี่ยเลขคณิตของคะแนนทั้งหมด
PROGRAM LinAver;
USES CRT;
VAR
USES CRT;
VAR
score : ARRAY[1..100] OF real;
avg, sum : real;
i, num : integer;
avg, sum : real;
i, num : integer;
BEGIN
Clrscr;
REPEAT
REPEAT
Write('Enter number OF student: ');
Readln(num);
Readln(num);
UNTIL num in [1..100];
Writeln;
sum := 0;
FOR i := 1 TO num DO
BEGIN
Writeln;
sum := 0;
FOR i := 1 TO num DO
BEGIN
Write('Enter score OF student number ',i,' : ');
Readln(score[i]);
sum := sum + score[i];
Readln(score[i]);
sum := sum + score[i];
END;
avg := sum/num;
Writeln;
Writeln('Summation OF all scores is ',sum:0:2);
Writeln('The average OF all scores is ',avg:0:2);
Readln;
avg := sum/num;
Writeln;
Writeln('Summation OF all scores is ',sum:0:2);
Writeln('The average OF all scores is ',avg:0:2);
Readln;
END.
การประกาศและอ้างถึงชนิดข้อมูลอาร์เรย์
ในส่วนที่ผ่านมาเราได้แนะนำถึงอาร์เรย์ชนิดหนึ่งมิติ ซึ่งจะเห็นว่าในการกำหนดอาร์เรย์ชนิดนี้จะมีดัชนีซึ่งมีลักษณะเป็นช่วงเพียงชุดเดียว ข้อมูลที่เป็นอาร์เรย์หนึ่งมิติจะมีลักษณะเหมือนการนำเอาข้อมูลชนิดเดียวกันมาเรียงต่อกันเป็นเส้นตรงคล้ายกับการเข้าแถว
ในโปรแกรมภาษาปาสคาลสามารถสร้างและใช้อาร์เรย์หลายมิติได้สำหรับอาร์เรย์สองมิติเราสามารถเปรียบเทียบได้กับลักษณะของตารางซึ่งประกอบด้วยแกนแนวตั้งและแกนแนวนอน แกนแต่ละแกนนี้ก็คือดัชนีในแต่ละมิตินั้นเอง การประกาศอาร์เรย์หลายมิตินั้นสามารถทำได้โดยทำการกำหนดดัชนีซึ่งมีลักษณะเป็นช่วงเช่นเดียวกับดัชนีของอาร์เรย์หนึ่งมิติจำนวนหลายๆ ชุดโดยแต่ละตัวจะคั่นด้วยเครื่องหมาย ","
ตัวอย่าง เช่น
VAR M_array : ARRAY [1..10,1..3] OF char;
มีปัญหาอยู่หลายอย่างที่จำเป็นจะต้องเก็บข้อมูลให้อยู่ในรูปของตารางตัวอย่างเช่น ถ้าหากเราต้องการจดบันทึกค่าของแรงดันภายในท่อน้ำตามตำแหน่งต่างๆ ทั้งหมด 4 ตำแหน่งด้วยกันโดย ในหนึ่งวันจะทำการจดบันทึกทั้งหมด 5 ครั้ง ค่าของแรงดันที่อ่านได้สามารถบันทึกลงในตารางได้ดังนี้
ตารางแสดงตัวอย่างการการบันทึกข้อมูลในลักษณะตาราง
จากตารางที่สร้างขึ้นจะพบว่า ความดันในท่อน้ำ 4 ค่าที่อ่านได้ในหนึ่งครั้งนั้นอยู่ในแนวนอน และจำนวนครั้งที่อ่านทั้งหมด 5 ครั้งอยู่ในแนวตั้งรวมจำนวนข้อมูลทั้งหมด 20 ตัว เราสามารถกำหนดตัวแปรเพื่อสำหรับใช้ในการเก็บข้อมูลชุดนี้ได้ดังนี้
CONST
Times = 5; Locations = 4;
TYPE
PressureDataTable=ARRAY[1..Times,1..Locations] OF real;
VAR
PressureTable : PressureDataTable;
ในการอ้างถึงตัวข้อมูลนั้นสามารถอ้างได้ดังตัวอย่างเช่น ถ้าต้องการอ้างถึงข้อมูลของแรงดันที่วัดได้จากการอ่านครั้งที่ 5 ตำแหน่งที่ 2 จะเป็นดังนี้
PressureTable[5,2]
จากตัวอย่างในการกำหนดตัวแปรอาร์เรย์ที่เป็น 2 และ 3 มิติ ที่ผ่านมาคงพอจะทำให้เกิด ความเข้าใจในการกำหนดตัวแปรอาร์เรย์ชนิดหลายมิติได้ถ้าหากต้องการที่จะเพิ่มมิติให้กับตัวแปรอีกก็สามารถทำได้โดยเพิ่มจำนวนดัชนีดังตัวอย่างของอาร์เรย์ 2 และ 3 มิติ และจำนวนตัวแปรทั้งหมดที่
เกิดขึ้นจะเท่ากับผลคูณของจำนวนเอลิเมนต์ในแต่ละมิติ
เกิดขึ้นจะเท่ากับผลคูณของจำนวนเอลิเมนต์ในแต่ละมิติ
ใครเล่นบล๊อกนี้วะ ๆ
ตอบลบ