1 บทที่ 5 โปรแกรมย่อย Part II Function
2 ฟังก์ชัน (Function) เป็นชุดคำสั่งย่อยที่มีหน้าที่เฉพาะอย่างใดอย่างหนึ่ง เหมือนกับ procedure สามารถมีการรับส่งค่าข้อมูล (parameter) ระหว่างฟังก์ชันกับ โปรแกรมส่วนอื่นๆที่เรียกใช้ฟังก์ชันหรือไม่ก็ได้ และการส่งผ่าน parameter ก็สามารถทำได้ทั้งแบบ pass by value และแบบ pass by variable เช่นเดียวกันกับ procedure ฟังก์ชันต่างจาก procedure ตรงที่ฟังก์ชันต้องมีการส่งค่าผลลัพธ์ ของการทำงาน 1 ค่ากลับไปยังคำสั่งที่เรียกใช้งานฟังก์ชันผ่านชื่อ ฟังก์ชันด้วย
3 ประเภทฟังก์ชัน Built-in function เป็นฟังก์ชันมาตรฐานที่ปาสคาลมีให้ เช่น sqrt( ), exp( ), round( ) เป็นต้น User defined function เป็นฟังก์ชันที่ผู้เขียนโปรแกรม ออกแบบเอง
4 Built-in procdure ClrScr - สำหรับลบภาพบนจอทั้งจอภาพ และให้เคอร์เซอร์ (cursor) ไปอยู่ที่มุมบนซ้าย (ตำแหน่งแถวที่ 1 และคอลัมน์ที่ 1) - เป็น procedure ที่ไม่มีการรับค่า paramter GotoXY(x,y) สำหรับย้ายเคอร์เซอร์ไปยังตำแหน่งแถว(row)ที่ y และคอลัมน์(column)ที่ x เช่น Gotoxy(1,1) จะทำให้ เคอร์เซอร์ย้ายไปอยู่ที่มุมบนซ้ายของจอภาพ และ Gotoxy(80,25) คือมุมล่างขวา - เป็น procedure ที่มีการรับค่า paramter เป็นเลขจำนวนเต็ม 2 ค่า
5 Built-in function upcase() ฟังก์ชันที่คืนค่าเป็นอักขระตัวพิมพ์ใหญ่ abs() ฟังก์ชันให้ค่าสัมบูรณ์ (Absolute value) ของ จำนวน n ที่เป็นไปได้ตามแบบข้อมูลของ n sqr() ฟังก์ชันยกกำลังสอง sqrt() ฟังก์ชันหาค่ารากที่สอง exp() ฟังก์ชันหาค่า exponential ln() ฟังก์ชันหาค่า log ธรรมชาติ sin() ฟังก์ชันหาค่าไซน์ โดยค่าที่ส่งไปหาค่าไซน์ต้อง เป็นค่าเรเดียน cos(), tan(), acos(),….
6 ตัวอย่างการใช้ built-in function Program mySecond_101; uses wincrt; var a : integer; x,y : real; ch : char; begin a := -9; x := 1.2; ch := 'a'; y := sqr(x); writeln('sqr(1.2) = ', y:1:3); writeln('sqr(-9) = ',sqr(-9)); writeln('sqrt(2) = ',sqrt(2) : 1:3); writeln('abs(-9) = ',abs(a)); writeln('pi/2 = ', Pi/2 : 1:3); writeln('sin(pi/2) = ', sin( Pi/2 ) :1:3); writeln('Uppercase (a) = ', upcase(ch) ); writeln('Uppercase (5) = ', upcase('5') ); end. ผลลัพธ์ของโปรแกรม นี้คือ sqr(1.2) = sqr(-9) = 81 sqrt(2) = abs(-9) = 9 Pi/2 = sin(pi/2) = Uppercase (a) = A Uppercase (5) = 5 หมายเหตุ Pi เป็นฟังก์ชันที่ไม่ต้องการ parameter
7 รูปแบบการเขียนฟังก์ชัน function ชื่อ( formal parameter list: ชนิดของข้อมูล): ชนิดของ function; เช่น function fnEllipseArea (a,b :real) : real; var area : real; begin area := *a*b; fnEllipseArea := area; end ; User defined function : การเขียนฟังก์ชัน ชนิดของ function real ดังนั้นคำสั่งการกำหนดค่าให้ ที่ชื่อฟังก์ชัน (เพื่อส่งค่ากลับ) ต้องมีชนิดเป็น real ด้วย formal parameter คือ a,b ซึ่งเป็น pass by value เพราะไม่มีคำว่า var นำหน้า a,b ประกาศตัวแปรสำหรับภายในฟังก์ชัน รับค่า parameter เข้าฟังก์ชัน ฟังก์ชัน ส่งค่ากลับ
8 program ExFunc1; uses wincrt; function fnEllipseArea (a,b :real) : real; var area : real; begin area := *a*b; fnEllipseArea := area; end; var a1,a2,x, y : real; begin x := 0.5; y := 20.0; a1 := fnEllipseArea(x,10); {First Calling} writeln(a1:5:2); a2 := fnEllipseArea(x,10); {Second Calling} writeln(a2:5:2); fnEllipseArea(x,y); {the last Calling} end. ตัวอย่างที่ 1 : รับค่า parameter รัศมีที่ยาวที่สุด และรัศมีที่สั้นที่สุดของวงรีจาก main เพื่อคำนวณพื้นที่ของวงรีในfunction และแสดงค่าพื้นที่ในส่วนของ main program เรียกใช้งาน function โดยไม่มี การรับค่าที่คืนมาจาก function แบบนี้ไม่ได้ ! สามารถเรียกใช้งาน function ได้ทั้ง 3 แบบ เป็น function -แบบ pass by value -ส่งค่ากลับเป็นชนิด real
9 program ExFunc1; uses wincrt; function fnEllipseArea (a, b :real) : real; var area : real; begin area := *a*b; fnEllipseArea := area; end; var a1,a2,x, y : real; begin x := 0.5; y := 20.0; a1 := fnEllipseArea (x,y); {First Calling} writeln(a1:5:2); a2 := fnEllipseArea (x,10); writeln(a2:5:2); end. ตัวอย่างที่ 1 : รับค่า parameter รัศมีที่ยาวที่สุด และรัศมีที่สั้นที่สุดของวงรีจาก main เพื่อคำนวณพื้นที่ของวงรีใน function และแสดงค่าพื้นที่ในส่วนของ main program จากคำสั่ง writeln(a1:5:2); ใน main program จะแสดงผลลัพธ์ค่า ซึ่งได้มาจาก 1)คำสั่ง a1 := fnEllipseArea (x,y); ใน main program จะมีการส่งค่า actual parameter x,y ( 0.5 และ 20) มา ให้ formatal parameter a และ b ของฟังก์ชัน 2)ในฟังก์ชันมีการคำนวณค่า area เท่ากับ *a*b ได้ และ คืนค่า area นี้ผ่านชื่อฟังก์ชัน 3)ใน main program จะรับค่าคืนมา จากฟังก์ชันเป็น และ กำหนดค่านี้ให้กับตัวแปร a1 เมื่อพิมพ์ค่า a1 (จากคำสั่ง writeln(a1:5:2); ใน main) จึงได้ ผลลัพธ์เป็น 31.42
10 program ExFunc1; uses wincrt; function fnEllipseArea (a, b :real) : real; var area : real; begin area := *a*b; fnEllipseArea := area; end; var a1,a2,x, y : real; begin x := 0.5; y := 20.0; a1 := fnEllipseArea (x,y); {First Calling} writeln(a1:5:2); a2 := a1+ fnEllipseArea (x,10); {Second Calling} writeln(a2:5:2); end. ตัวอย่างที่ 1 : รับค่า parameter รัศมีที่ยาวที่สุด และรัศมีที่สั้นที่สุดของวงรีจาก main เพื่อคำนวณพื้นที่ของวงรีใน function และแสดงค่าพื้นที่ในส่วนของ main program ผลรันของโปรแกรมนี้คือ
11 function factorial(n:integer):integer; var product, i :integer; begin product := 1; for i := 1 to n do product := product*i; factorial := product; end; ตัวอย่างที่ 2 : รับค่าเลขจำนวนเต็มจากผู้ใช้ แล้วส่งค่าให้ฟังก์ชันเพื่อ คำนวณค่า Factorial โดยให้แสดงผลลัพธ์ของค่า Factorial ที่ main program ออกแบบฟังก์ชัน Factorial คำนวณ ค่า n! (เก็บในตัวแปร product) และส่งคืนผลลัพธ์ค่า n! ที่คำนวณ ได้ผ่านชื่อฟังก์ชัน โดย ถ้ารับค่า formal parameter n เป็น 4 มีการทำงานของฟังก์ชัน ดังนี้ เริ่มต้น product = 1 เมื่อ i=1 product = 1 เมื่อ i=2 product = 1*2 เมื่อ i=3 product = 2*3 เมื่อ i=4 product = 6*4 ดังนั้นจะได้ค่า product = 24 แล้วส่งคืนกับไป ตัวแปร product เป็นเลขจำนวนเต็ม ดังนั้นชนิด function ก็เป็น integer
12 program ExFunc2; uses wincrt; function factorial(n:integer):integer; var product, i :integer; begin product := 1; for i := 1 to n do product := product*i; factorial := product; end; var number,result : integer; begin write('Input number : ' ); readln(number); result := factorial(number); writeln('Factorial is ',result ); end. ตัวอย่างที่ 2 : รับค่าเลขจำนวนเต็มจากผู้ใช้ แล้วส่งค่าให้ฟังก์ชันเพื่อ คำนวณค่า Factorial โดยให้แสดงผลลัพธ์ของค่า Factorial ที่ main program ตัวอย่างผลรัน ของโปรแกรม Input number : 5 Factorial is 120
13 function isEven(n : integer) : boolean; var temp :integer; result : boolean; begin temp := n mod 2; if temp = 0 then result := true else result := false; isEven := result; end; ออกแบบฟังก์ชัน isEven ทำหน้าที่ตรวจสอบว่าค่า n ว่าเป็นเลขคู่หรือไม่ -โดยถ้าค่า formal parameter n เป็นเลขคู่จริง (หาร 2 แล้วเหลือเศษศูนย์) ฟังก์ชันจะคืนค่า True - แต่ถ้า n ไม่ใช่เลขคู่ฟังก์ชันคะคืนค่า False ดังนั้นชนิดของ function ต้องเป็น boolean ตัวอย่างที่ 3: รับค่าเลขจำนวนเต็มจากผู้ใช้ แล้วส่งค่าให้ฟังก์ชันตรวจสอบ ว่าเป็นเลขคู่หรือเลขคี่ แล้วแสดงผลลัพธ์ที่ main program ว่าเป็น 'odd number' หรือ 'even number'
14 program ExFunc3; uses wincrt; function isEven(n : integer) : boolean; var temp :integer; result : boolean; begin temp := n mod 2; if temp = 0 then result := true else result := false; isEven := result; end; var number : integer; begin write('Input number : ' ); readln(number); if isEven(number) then writeln('Even number') else writeln('Odd number'); end. ตัวอย่างที่ 3: รับค่าเลขจำนวนเต็มจากผู้ใช้ แล้วส่งค่าให้ฟังก์ชันตรวจสอบ ว่าเป็นเลขคู่หรือเลขคี่ แล้วแสดงผลลัพธ์ที่ main program ว่าเป็น 'odd number' หรือ 'even number' ตัวอย่างผลรัน ของโปรแกรม Input number : 5 Odd number
15 1.ใน การเขียนฟังก์ชัน อย่าลืมกำหนดชนิดของ function function fnEllipseArea (a,b :real) : real; ต้องการคืนค่าไปเป็นตัวเลขชนิด real 2.ภายในฟังก์ชัน ต้องมีคำสั่งในการนำค่าที่ฟังก์ชันต้องการส่งคืน มา กำหนดให้กับชื่อ function และต้องมีชนิดแบบเดียวกันกับชนิดของ ฟังก์ชันด้วย fnEllpseArea := area; ต้องการส่งค่า area ที่คำนวณได้ภายในฟังก์ชันคืนกลับไป 3.ใน การเรียกใช้ฟังก์ชัน จะไม่เหมือน procedure เพราะ ควรมีตัวแปรมารับผลลัพธ์ที่คืนมาพร้อมกับชื่อฟังก์ชันที่เรียกใช้ เช่น x := fnEllipseArea(3.0,b); โดย x ต้องมีการประกาศชนิดตัวแปร เป็นชนิดเดียวกันกับชนิดของ ฟังก์ชันด้วย ข้อควรระวังเกี่ยวกับ function
16 procedure และ function การเรียกใช้ Procedure การรับค่าที่คำนวณจากโปรแกรม ย่อยต้องใช้การส่ง parameter power3proc(x,x3); การเรียกใช้ Function การรับค่าที่คำนวณจากโปรแกรมย่อยจะ รับผ่านชื่อฟังก์ชันได้ X3 := power3func(x); procedure power3proc(x:integer; var x3: integer ); begin x3 : = x*x*x; end; function power3function(x : integer) : integer; begin power3function : = x*x*x; end; โปรแกรมย่อย สำหรับคำนวณ ค่า x 3 จุดที่แตกต่าง
17 program Grading; Function ComputeGrade(score:real ) : char; Var grade : char; begin if score >= 80 then grade := 'A' else if score >= 65 then grade := 'B' else if score >= 50 then grade := 'C' else grade := 'F'; end; var score:real; grd:char; begin writeln('Input score : '); readln(score); grd := Grading(score); writeln('Your grade is ',grd); end. โปรแกรมย่อยคำนวณเกรด (แต่ไม่แสดงผล) แบบฝึกหัด โปรแกรม Grading สำหรับรับค่าคะแนนจากผู้ใช้ เพื่อคำนวณเกรดใน function แล้วส่งเกรดไปแสดงผลที่ main program แสดงผลที่ main program ข้อ 1. จากโปรแกรม Grading ใน ข้อ 1 พัฒนาเพิ่มเติมให้ สามารถรับคะแนนและคำนวณ ค่าเกรดของนักเรียน N คนได้
18 แบบฝึกหัด ข้อ 2. จงเขียนฟังก์ชันรับค่า parameter N เพื่อคำนวณผลรวมของเลขคี่ ทั้งหมดที่อยู่ในช่วง 1 ถึง N เช่น ถ้า N เป็น 20 ค่าที่ต้องคำนวณคือ … 19 = 100 ถ้า N เป็น 15 ค่าที่ต้องคำนวณคือ … 15 = 64 ข้อ 3. จงเขียนโปรแกรมรับจำนวนชั่วโมงทำงานต่อสัปดาห์ และอัตราค่าจ้าง เพื่อคำนวณค่าจ้างสุทธิหลังหักภาษี ณ ที่จ่ายให้กับลูกจ้าง ( 1 คน) โดย ในการคำนวณค่าจ้าง หากทำงานเกิน 40 ชั่วโมงต่อสัปดาห์ ชั่วโมงที่เกินจะ ได้ค่าล่วงเวลา 1.5 ของค่าจ้าง โดยการคำนวณภาษีใช้ตามเงื่อนไขต่อไปนี้ – บาท คิดภาษี 2% ของค่าจ้าง – บาท คิดภาษี 3%ของค่าจ้าง –เกิน 4000 เสีย 5% ภาษีของค่าจ้าง กำหนดให้โปรแกรมคำนวณค่าจ้างสุทธินี้ โดยมี 1)โมดูลคำนวณภาษี 2)โมดูลคำนวณค่าจ้างสุทธิหลังหักภาษี