Make your own free website on Tripod.com

บทที่ 7
โปรแกรมย่อย Procedure และฟังก์ชัน (Function)


     ภาษาปาสคาล เรียกโปรแกรมย่อยว่า Procedure ซึ่งเป็นโปรแกรมเล็ก ๆ ภายในโปรแกรมใหญ่ทั้งหมด แต่โปรแกรมหลักจะมีความเป็นอิสระในตัวเอง ส่วน Procedure จะเป็นอิสระและจบในตัวเอง แต่จะถูกเรียกใช้จากโปรแกรมหลัก หรือ Procedure อื่น ๆ

วัตถุประสงค์ของการสร้างโปรแกรมย่อย
1. เป็นส่วนโปรแกรมที่ใช้ซ้ำกันในหลาย ๆ แห่ง และจะแยกออกมาทำเป็นโปรแกรมย่อย
2. เป็นคำที่สร้างขึ้นใหม่ เพื่อเก็บไว้ใช้ต่อไป
3. เมื่อต้องการเขียนโปรแกรมเป็น Module จุดประสงค์ของการเขียนโปรแกรมเป็น Module ก็เพื่อตรวจหาที่ผิดได้ง่าย ดังนั้น โปรแกรมย่อยหนึ่ง ๆ ก็คือ Module ๆ หนึ่ง
4. เพื่อสนองความต้องการของการเขียนโปรแกรมจากบนลงล่าง

รูปแบบของ Procedure


PROCEDURE ชื่อ Procedure (อากิวเมนต์);
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 ไม่ได้ เพราะเป็นโปรแกรมหลัก


แบบฝึกหัด
เรื่อง โปรแกรมย่อย Procedure และฟังก์ชัน (Function)


1. procedure ต่างกับ function อย่างไรบ้าง

2. procedure ต่อไปนี้มีส่วนใดผิด

PROCEDURE T;
VAR I:INTEGER;
BEGIN
WHILE I>0 DO
BEGIN
I:=I-1;
WRITE(+,’ ‘);
END;
END;

3. โปรแกรมต่อไปนี้ ตัวแปรใดเป็นโกลบอล และตัวแปรใดเป็นโลคอลของ procedure xyz

PROGRAM ABC;
VAR M,N,P:REAL;
PROCEDURE XYZ(Q:REAL);
VAR UTV:BYTE;
BEGIN
.
.
.
.
.
END;
VAR R:BYTE;
BEGIN
.
.
.
.
.
END.

4. โปรแกรมต่อไปนี้ผลลัพธ์ที่ได้เป็นอย่างไร

PROGRAM P12(INPUT,OUTPUT);
VAR I:INTEGER;
PROCEDURE PN(X:INTEGER);
BEGIN
WRITELN(X+1);
END;
BEGIN
I:=5;
PN(I);
END.

5. จงเขียนโปรแกรมรับข้อมูลตัวเลข 25 จำนวน และนำตัวเลขนั้นมาเรียงลำดับจากมากไปหาน้อย