260 likes | 365 Views
function. เนื้อหาที่สอนในวันนี้. ฟังก์ชันคืออะไร ? ส่วนประกอบของฟังก์ชัน โครงสร้างของการเขียนฟังก์ชัน Parameters (ตัวแปรที่รับมา) Return Value (ค่าที่ต้องส่งกลับ) function prototyping local variable & call by value. ฟังก์ชันคืออะไร ?.
E N D
เนื้อหาที่สอนในวันนี้เนื้อหาที่สอนในวันนี้ • ฟังก์ชันคืออะไร ? • ส่วนประกอบของฟังก์ชัน • โครงสร้างของการเขียนฟังก์ชัน • Parameters (ตัวแปรที่รับมา) • Return Value (ค่าที่ต้องส่งกลับ) • function prototyping • local variable & call by value #07 function
ฟังก์ชันคืออะไร ? • กลุ่มของคำสั่งที่ทำงานเป็นอิสระจากคำสั่งกลุ่มอื่นๆ • ตัวฟังก์ชันเขียนอยู่นอกบล็อกใดๆ • มีตัวแปรของตัวเอง (local variable) • รู้จักเฉพาะในฟังก์ชันนั้น • ติดต่อกับ main program , ฟังก์ชันอื่นผ่าน parameter • ทำไมต้องเขียนเป็นฟังก์ชัน • โปรแกรมขนาดใหญ่เกิดข้อผิดพลาดได้ง่าย • ง่ายในการเขียน, การตรวจสอบแก้ไข (debug) • นำกลับมาใช้ใหม่ได้ (reusable) #07 function
โปรแกรมปกติ เขียนเป็นฟังก์ชัน #include stdio.h void main() { … (บล็อกของ main) } #include stdio.h void fn1 ( int a ) { … (บล็อกของ fn1) } int fn2 ( void ) { … (บล็อกของ fn2) } void main() { … (บล็อกของ main) } #07 function
ขั้นตอนการเรียกใช้ฟังก์ชันขั้นตอนการเรียกใช้ฟังก์ชัน • เรียกใช้งานฟังก์ชัน พร้อมทั้งส่งค่าให้ฟังก์ชัน • ย้ายไปทำงานฟังก์ชันที่ถูกเรียกใช้จนจบ • ฟังก์ชันคืนค่าผลลัพธ์ให้ผู้ที่เรียกใช้ • Boss asks worker to complete task • Worker gets information, does task, returns result • Information hiding: boss does not know details • เช่น ฟังก์ชัน fabs() ใน math.h ซึ่งเป็นฟังก์ชันในการหาค่าสัมบูรณ์ของตัวเลขจำนวนจริง #07 function
ตัวอย่าง ฟังก์ชัน fabs() ใน math.h ซึ่งเป็นฟังก์ชันในการหาค่าสัมบูรณ์ของตัวเลขจำนวนจริง • เมื่อต้องการหาค่าสัมบูรณ์ : เรียกใช้งานฟังก์ชัน fabs() โดยส่งตัวเลขที่ต้องการหาค่าสัมบูรณ์ให้ฟังก์ชัน • ฟังก์ชัน fabs() รับตัวเลข , คำนวณค่าสัมบูรณ์ , ส่งผลลัพธ์กลับ • ได้ผลลัพธ์จากฟังก์ชันเป็นค่าสัมบูรณ์ของตัวเลขที่ส่งไป • ต้องการหาค่าสัมบูรณ์อีกครั้ง : เรียกใช้ฟังก์ชัน fabs()โดยส่งค่าใหม่ให้แก่ฟังก์ชัน ผลลัพธ์ที่ได้จะเปลี่ยนแปลงตามค่าที่ส่งไป #07 function
4.5 4.5 -3.1 3.1 ตัวอย่าง function main start … r1 = fabs(4.5) … r2 = fabs(-3.1) … stop function fabs() start คำนวณหาค่าสัมบูรณ์ stop #07 function
ส่วนประกอบของฟังก์ชันส่วนประกอบของฟังก์ชัน • function name : ชื่อของฟังก์ชันที่ส่วนอื่นๆ จะใช้ในการเรียกใช้งาน • function body : กลุ่มคำสั่งที่เขียนขึ้นเพื่อให้ฟังก์ชันทำงานตามที่ต้องการ • parameters : ค่าที่ส่งให้กับฟังก์ชัน • อาจไม่มีก็ได้ เช่น ฟังก์ชัน clrscr() • return value : ค่าที่ฟังก์ชันส่งกลับให้กับส่วนที่เรียกใช้ • อาจไม่มีก็ได้ เช่น ฟังก์ชัน clrscr() #07 function
ตัวอย่าง printf ( “You are %d years old” , year ) ; • function name : printf • function body : กลุ่มคำสั่งในการพิมพ์ตัวอักษรออกทางหน้าจอ (อยู่ในไฟล์ stdio.h) • parameters : format ในการพิมพ์ข้อความ (ข้อความภายใต้เครื่องหมายคำพูด) + ผลลัพธ์ของ expression ที่ต้องการพิมพ์ออกมา • parameters ที่ส่งให้ฟังก์ชันจะอยู่ภายใต้วงเล็บ • return value : ไม่มี (ความจริงมี แต่ไม่จำเป็นต้องใช้) #07 function
โครงสร้างของการเขียนฟังก์ชันโครงสร้างของการเขียนฟังก์ชัน int user_abs ( int n) { if ( n < 0) { n = -1 * n ; } return ( n ) ; } return-value-typefunction-name( parameter-list) { function-body ; return (expression); // ค่าที่ต้องการส่งกลับ } ตัวอย่าง #07 function
Parameters (ค่าที่ได้รับมา) • ส่วนที่กำหนดตัวแปรเพื่อรับค่าที่ส่งให้กับฟังก์ชัน โดยจะกำหนดในวงเล็บที่อยู่หลังจากชื่อของฟังก์ชัน • ชนิดของข้อมูลที่ผู้เรียกใช้จะส่งมาเมื่อเรียกใช้ฟังก์ชันนี้ ต้องเป็นชนิดเดียวกัน กับที่กำหนดไว้ในส่วน parameters • ฟังก์ชันรับค่าเพียงค่าเดียว หรือหลายค่าก็ได้ • ถ้าไม่ต้องการรับค่า : ใช้คำสั่ง void int single_para ( int n) intmulti_para ( float x , int a ) intno_para ( void ) #07 function
Return Value (ค่าที่ส่งกลับ) • ส่วนที่กำหนดค่าที่ฟังก์ชันจะส่งกลับให้ส่วนที่เรียกใช้ ต้องกำหนด 2 ตำแหน่งที่ สัมพันธ์กัน คือ • ส่วนที่อยู่หน้าชื่อฟังก์ชัน (return-value-type) ชนิดข้อมูลของค่าที่จะส่งกลับ เช่น int, float, long เป็นต้น • ส่วนที่อยู่หลังคำสั่ง return (ใน body of function) ตัวแปรหรือ expression ที่ต้องการส่งกลับ • ต้องมีผลลัพธ์เป็นข้อมูลชนิดเดียวกันกับชนิดของ return-value-type • ส่งค่ากลับจากฟังก์ชันได้ เพียง 1 ค่า เท่านั้น #07 function
ถ้าไม่ต้องการส่งค่ากลับ • ในส่วน return-value-type ใช้คำสั่ง void • ใน function body ไม่ต้องมีคำสั่ง return int return1 ( int n) { … … return ( n ) ; } float return2 ( int n) { float xxx; … return ( xxx ) ; } double return3 ( int n) { double yyy; … return ( yyy * 3.0 ) ; } void no_return (int n) { float xxx; … } #07 function
ฟังก์ชัน fac ใช้ในการคำนวณหา factorial ของค่าที่รับมา โดยรับค่าเป็นตัวแปรชนิด double และเมื่อคำนวณเสร็จจึงส่งผลลัพธ์กลับให้ส่วนที่เรียกใช้ โดยส่งค่ากลับเป็นตัวแปรชนิด double เช่นกัน เรียกใช้งานฟังก์ชัน fac โดยส่งค่าเป็นตัวแปรชนิด double และค่าที่รับกลับจากฟังก์ชันเป็นตัวแปรชนิด double ตัวอย่าง #1 #include <stdio.h> double fac(double x) { int i; double r=1; for (i=1;i<=x;i++) r=r*i; return r; } void main( ) { double x , r ; printf(“input number : ”) ; scanf(“ %f ”,&x) ; r = fac(x) ; printf(“ %.f! = %.f ”, x, r); } #07 function
ถ้าไม่มี return_type จะถือว่าเป็น int โดยปริยาย ชื่อตัวแปรที่รับไม่จำเป็นต้องเป็นชื่อเดียวกับตัวแปรที่ส่ง แต่ต้องเป็นข้อมูลชนิดเดียวกัน ค่าที่ส่งกลับโดยใช้คำสั่ง return จะเป็นตัวแปรหรือ expression ก็ได้ แต่จะต้องเป็นข้อมูลชนิดเดียวกับที่ตัวแปรใน main คอยรับอยู่ (x) การเรียกใช้ฟังก์ชันสามารถส่งค่า arguments เป็นค่าคงที่ , expression หรือตัวแปรก็ได้ แต่ค่าที่ส่งไปต้องเป็นข้อมูลชนิดเดียวกับที่เรากำหนดไว้ในฟังก์ชัน ตัวอย่าง #2 #include <stdio.h> #include <conio.h> sum (int a , int b) { return a + b ; } void main( ) { int x; clrscr( ); x = sum(5,sum(4,5)); printf(“x = %d“ , x); } #07 function
บางฟังก์ชันไม่จำเป็นต้องมีการรับค่าหรือส่งค่ากลับ ขึ้นอยู่กับจุดประสงค์ของแต่ละฟังก์ชัน เมื่อไม่มีการรับหรือส่งค่ากลับ เวลาเรียกใช้งานฟังก์ชันก็ไม่จำเป็นต้องมีส่วนที่ส่งค่าหรือตัวแปรเพื่อมารับค่ากลับ ตัวอย่าง #3 #include <stdio.h> #include <conio.h> void printMsg(void) { printf(“inside function \n”); } void main() { clrscr(); printf(“inside main \n”); printMsg(); printf(“inside main \n”); } #07 function
function prototyping • ชื่อของฟังก์ชันที่เราจะเรียกใช้ จะต้องถูกประกาศก่อนการใช้งานเสมอ ( อยู่บรรทัดบนของส่วนที่จะเรียกใช้ ) • การประกาศฟังก์ชัน เรียกว่า function prototyping • เหมือนกับการประกาศชื่อตัวแปรก่อนที่จะเรียกใช้งาน ตัวแปรนั้น • การเขียนฟังก์ชัน ที่สมบูรณ์ขึ้นมาถือว่าเป็นการทำ function prototyping ไปในตัว • แต่ถ้าเรายังไม่เขียนฟังก์ชัน เราจำเป็นต้องประกาศให้คนอื่นได้รับรู้ก่อน #07 function
#include <stdio.h> double fac(double x); void main( ) { float x , r ; printf(“input number : ”) ; scanf(“ %f ”,&x) ; r = fac(x) ; printf(“ %.f! = %.f ”, x, r); } double fac(double x) { int i; double r = 0 ; for (i=1;i<=x;i++) r = r * i ; return r; } #include <stdio.h> double fac(double x) { int i; double r = 0 ; for (i=1;i<=x;i++) r = r * i ; return r; } void main( ) { float x , r ; printf(“input number : ”) ; scanf(“ %f ”,&x) ; r = fac(x) ; printf(“ %.f! = %.f ”, x, r); } #07 function
#include <stdio.h> #include <conio.h> sum (int , int ); void main( ) { int x; clrscr( ); x = sum(5,sum(4,5)); printf(“x = %d“ , x); } sum (int a , int b) { return a + b ; } #include <stdio.h> #include <conio.h> sum (int a , int b) { return a + b ; } void main( ) { int x; clrscr( ); x = sum(5,sum(4,5)); printf(“x = %d“ , x); } #07 function
#include <stdio.h> #include <conio.h> void printMsg(void) { printf(“inside function\n”); } main() { clrscr(); printf(“inside main \n”); printMsg(); printf(“inside main \n”); } #include <stdio.h> #include <conio.h> void main() { void printMsg(void); clrscr(); printf(“inside main \n”); printMsg(); printf(“inside main \n”); } void printMsg(void) { printf(“inside function\n”); } #07 function
ex7_1.c • เขียนโปรแกรมเพื่อคำนวณหาผลลัพธ์ของเลขยกกำลัง xy • ผู้ใช้กรอกตัวเลขฐาน x และเลขชี้กำลัง y จากนั้นโปรแกรมจึงคำนวณ และแสดงผลลัพธ์ออกทางหน้าจอ • ในส่วนของการคำนวณ ให้เขียนเป็นฟังก์ชัน โดยมี function prototype ดังนี้ #07 function
#include <stdio.h> void test_var(int a) { a = 5 ; } main() { int a = 3 ; printf( “a = %d\n” , a ); test_var(a); printf( “a = %d\n” , a ); } ผลการรันโปรแกรม a = 3 a = 3 #07 function
local variable & call by value local variable • ตัวแปรที่ประกาศภายใต้ฟังก์ชันทุกฟังก์ชัน (รวมถึงฟังก์ชัน main) เป็นตัวแปรชนิด local variable • ตัวแปรจะรู้จักและใช้งานได้เฉพาะในฟังก์ชันที่ประกาศตัวแปรนั้นเท่านั้น ฟังก์ชันอื่นไม่สามารถรู้จักและใช้งานตัวแปรของอีกฟังก์ชันหนึ่งได้ • ตัวแปรที่มีชื่อซ้ำกันในคนละฟังก์ชัน จึงถือว่าเป็นตัวแปรคนละตัวกัน #07 function
call by value • ในการเรียกใช้งานฟังก์ชันในภาษาซี ปกติแล้วค่าที่ส่งให้กับฟังก์ชันจะใช้การส่งค่าแบบ call by value • คือ การ copy ค่าที่ผู้เรียกใช้ฟังก์ชันส่งให้กับฟังก์ชัน ไปยังตัวแปรแบบ local ในฟังก์ชัน • ส่วน parameter list ของฟังก์ชันจริงๆ แล้วก็คือการประกาศตัวแปรแบบ local สำหรับฟังก์ชันนั้น และนำตัวแปรแบบ local ที่ประกาศมา copy ค่าตัวแปรที่ส่งให้กับฟังก์ชัน #07 function
main a 3 test_var a 3 ผลการรันโปรแกรม a = 3 a = 3 #include <stdio.h> void test_var(int a) { a = 5 ; } main() { int a = 3 ; printf( “a = %d\n” , a ); test_var(a); printf( “a = %d\n” , a ); } 2 5 4 1 1 2 3 3 5 5 4 #07 function
main 1 x y 3 6 test_var x y 3 10 #include <stdio.h> inttest_var(int x) { int y = 10 ; x = 5 ; printf( “%d %d\n” , x , y ); return y ; } main() { int x = 3 , y = 6; printf( “%d %d\n” , x , y ); y = test_var(x); printf( “%d %d\n” , x , y ); } ผลการรันโปรแกรม 3 6 5 10 3 10 2 5 7 4 5 6 10 1 6 3 2 3 5 7 4 #07 function