วันเสาร์ที่ 29 สิงหาคม พ.ศ. 2552

เขียนฟังก์ชั่นภาษาซีขึ้นใช้เอง

ฟังก์ชันที่เขียนเอง (user defined functions)

ฟังก์ชันประเภทนี้เป็นฟังก์ชันที่คนเขียนโปรแกรมเขียนขึ้นเองเพื่อทำงานบางอย่างตามความต้องการ



โครงสร้างของฟังก์ชัน (Structure of Functions)

type function_name(type1 arg1,type2 arg2,...,typeN argN)

{

local varilabel declarations;

statement_1;

statement_2;

...

statement_N;

return(value)

}

โดย type คือ ชนิดของฟังก์ชัน หรือ ชนิดของข้อมูล เช่น int , float , char , double , void ที่ส่งไปให้ตำแหน่งที่เรียกใช้ ถ้าไม่มีการส่งค่ากลับไปให้ตำแหน่งที่เรียกใช้ จะใช้ void ถ้าไม่มีการกำหนด จะได้ข้อมูลที่ส่งกลับมาเป็น int เสมอ

Function_name คือ ชื่อของฟังก์ชัน ควรตั้งชื่อให้สื่อความหมายถึงการทำงานของฟังก์ชัน และต้องเป็นไปตามกฏเกณฑ์การตั้งชื่อตัวแปรในภาษาซี

type1 arg1,type2 arg2,...,typeN argN เป็นชนิดและชื่อของ argument หรือ parameter ค่าที่ 1 , 2 ถึง N ที่จะรับมาจากผู้เรียกใช้ฟังก์ชัน ถ้าเป็นฟังก์ชันที่ไม่มีการรับและส่งค่า parameter จะใช้คำว่า void

{ จุดเริ่มต้นของฟังก์ชัน

location variable declaration คือ ส่วนที่มีการประกาศชนิดและชื่อของตัวแปรที่จะใช้เฉพาะในฟังก์ชัน โดยส่วนที่อยู่ฟังก์ชัน จะไม่สามารถเรียกใช้ตัวแปรเหล่านี้ได้

statement_1; statement_2; ... statement_N เป็นคำสั่งที่ใช้งานในฟังก์ชัน

return(value); คือ คำสั่งที่ใช้ส่งข้อมูลหรือค่าที่เป็นผลลัพธ์จากการประมวลผลในฟังก์ชัน ไปให้ผู้เรียกใช้ฟังก์ชัน โดยชนิดของข้อมูลที่ส่งต้องเป็นชนิดเดียวกับชนิดของฟังก์ชันหรือชนิดของข้อมูลของฟังก์ชัน ถ้าเป็นฟังก์ชันที่ไม่มีการส่งค่า(void) จะไม่ต้องใช้คำสั่ง return

} ส่วนสิ้นสุดของฟังก์ชัน



ประเภทของฟังก์ชัน

ถ้าพิจารณาจากลักษณะการส่งการรับข้อมูลระหว่างฟังก์ชันกับตำแหน่งที่เรียกใช้ฟังก์ชัน จะแบ่งฟังก์ชัน เป็น 3 ประเภท คือ

1. ฟังก์ชันที่ไม่มีการรับการส่งค่าใด ๆ ในการเรียกใช้ฟังก์ชัน

2. ฟังก์ชันที่ต้องรับค่า parameter หรือ argument เข้าในการทำงานในฟังก์ชัน

3. ฟังก์ชันที่ต้องรับค่า parameter เข้ามาในการทำงานและส่งค่ากลับไปให้ตำแหน่งที่เรียกใช้



ฟังก์ชันที่ไม่มีการรับและส่งค่า

การเรียกใช้ฟังก์ชันประเภทนี้ ไม่ต้องส่งค่าอาร์กูเมนต์(argument) หรือ พารามิเตอร์(parameter) ใด ๆ ไปให้ฟังก์ชันและฟังก์ชันก็ไม่มีการส่งค่าใดกลับมาให้ ส่วนมากจะใช้แสดงรายละเอียดหรือข้อความที่ต้องแสดงบ่อย ๆ

โครงสร้างของฟังก์ชันที่ไม่มีการรับส่งค่า

void functionname(void)

{

local variable declaration;

statements;

}

หรือ functionname()

{ local variable declaration; statements; }

ฟังก์ชันประเภทนี้จะไม่มีฟังก์ชัน return () อยู่ในฟังก์ชัน



ตัวอย่าง ฟังก์ชันที่ไม่มีการรับส่งค่า เช่น

void starline() /* ฟังก์ชัน starline() ฟังก์ชันนี้ไม่มีการรับค่าและส่งค่ากลับ */

{ /* เริ่มต้นฟังก์ชัน */

int i,k=50;

for (i=1;i<=k;i++)

printf("*");

} /* จบฟังก์ชัน starline() */

void bodin(void) /* ฟังก์ชัน void bodin(void) ฟังก์ชันนี้ไม่มีการรับค่าและส่งค่ากลับ */

{ /* เริ่มต้นฟังก์ชัน */

printf("Bodindecha \(Sing Singhaseni\)\n");

} /* จบฟังก์ชัน bodin() */





ฟังก์ชันที่มีการรับค่าแต่ไม่มีการส่งค่ากลับ

เป็นฟังก์ชันที่เมื่อถูกเรียกใช้จะต้องได้รับค่าพารามิเตอร์หรืออาร์กูเมนต์(argument)มาพร้อมกับการเรียกใช้ โดยค่าพารามิเตอร์ที่ได้รับมาจะต้องมีชนิดของข้อมูลเป็นชนิดเดียวกับที่กำหนดไว้ในฟังก์ชัน ในการส่งค่าพารามิเตอร์ให้ฟังก์ชันนอกจากจะต้องคำนึงถึงชนิดของข้อมูลแล้วกรณีที่มีพารามิเตอร์หลายตัวจะต้องคำนึงถึงลำดับของพารามิเตอร์แต่ละค่าด้วย โดยฟังก์ชันประเภทนี้เมื่อมีการประมวลผลแล้วจะไม่มีการส่งค่าใดกลับไปยังตำแหน่งที่เรียกใช้ฟังก์ชัน

โครงสร้างของฟังก์ชัน ที่มีการรับค่าพาราเตอร์แต่ไม่มีการส่งค่ากลับ

void functionname(type arg1,type arg2,…,type argN)

{

local variable declaration;

statements;

} /* end function */

หรือ functionname(type arg1,type arg2,…,type argN)

{ local variable declaration; statements; }



ตัวอย่าง ฟังก์ชันที่มีการรับค่าแต่ไม่มีการส่งค่ากลับ

void score(char grade)

{ char g; g = toupper(grade);

switch(g) {

case ‘A’ :

printf(“You get score between 80 to 100%”); break;

case ‘B’ :

printf(“You get score between 70 to 79%”); break;

case ‘C’ :

printf(“You get score between 60 to 69%”); break;

case ‘D’ :

printf(“You get score between 0 to 59%”); break;

case ‘F’ :

printf(“You get score less than 50%”); break;

default :

printf(“You get some problem,please check.”); } /* end switch() */

} /* end function score() */



/* function triangle() */

triangle(float *arg1, float *arg2)

{

float x,y;

x = *arg1;

y = *arg2;

printf("Area of triangle = %f",x*y/2);

} /* จบฟังก์ชัน */

/* function average() */



average(float num[10])

float sum = 0;

int i;

for (i=0;i<10;i++)

{

sum+= num[i];

}

printf("Average = %f\n ",sum/10);

} /* จบฟังก์ชัน */



/* function divide() */

void divide(float p, int q)

{

float k;

k = p/q;

printf("\n p=%.2f q=%.2f k=%.2f \n",p,q,k);

}





ฟังก์ชันที่มีการรับค่าและส่งค่ากลับ

ฟังก์ชัน ประเภทนี้ ต้องมีทั้งชนิดของฟังก์ชัน และอาร์กูเมนต์ และในโครงสร้างต้องมีคำสั่ง return (value) เพื่อส่งค่ากลับ ยกเว้นกรณีที่ใช้ตัวแปรพอยน์เตอร์ มาเป็นตัวรับส่งค่า ก็อาจไม่ต้องมีคำสั่ง return



โครงสร้างของฟังก์ชัน

type functionname(type arg1,type arg2,...,type argN)

{

local variable declaration;

statements;

return(value);

}



ตัวอย่าง ฟังก์ชันที่มีการรับค่าและส่งค่ากลับ

int sqr(int x)

{

return (x * x);

} /* end function */

float change(float price,float money)

{

float z;

z = money - price; return(z);

} /* end function */

void addconst(int *xpt, int *ypt)

{

*xpt = *xpt +250; *ypt = *pt +750;

} /* end function */

int chan(int * ptr1,int *ptr2)

{

int temp;

temp = *ptr1 ;

*ptr1 = *ptr2;

*ptr2 = temp;

} /* end function */





การประกาศรูปแบบฟังก์ชัน (function prototype)

ฟังก์ชันที่ผู้ใช้สร้างขึ้นโดยเฉพาะฟังก์ชันที่มีการคืนค่ากลับนั้นจะต้องเขียนไว้ก่อนฟังก์ชัน main() โปรแกรมจึงจะใช้งานฟังก์ชันนั้นได้ แต่ถ้าไม่เขียนไว้ก่อนฟังก์ชัน main() จะต้องมีการประกาศรูปแบบของฟังก์ชันนั้นไว้ก่อนมีการเรียกใช้ฟังก์ชันในฟังก์ชัน main() ตำแหน่งที่จะใช้ในการประกาศรูปแบบของฟังก์ชัน ประกาศได้ 2 ตำแหน่ง ประกาศไว้ในตำแหน่งเริ่มต้นของโปรแกรมคือตำแหน่งที่ต่อจาก คำสั่ง preprocessor directive หรือตำแหน่งแรกในฟังก์ชัน main() แต่ควรประกาศไว้ในตำแหน่งเริ่มต้นของโปรแกรมคือตำแหน่งที่ต่อจาก คำสั่ง preprocessor directive เพื่อจะได้เรียกใช้ได้ในทุกตำแหน่งของโปรแกรม ทำนองเดียวกับตัวแปรที่ประกาศไว้ในตำแหน่งนี้ การประกาศรูปแบบของฟังก์ชัน มีรูปแบบโดยทั่วไป ดังนี้

type functionname(type arg1,type arg2,...,type argN) /* ลักษณะนี้เหมือนกับบรรทัดแรกในโครงสร้างของฟังก์ชัน */

หรือ type functionname(type1,type2,...,typeN) /* ประกาศแต่ชนิดของ อาร์กูเมนต์ไม่ต้องใส่ชื่ออาร์กูเมนต์ */

ความหมายของคำต่าง ๆ เป็นเช่นเดียวกับในหัวข้อโครงสร้างของฟังก์ชัน การประกาศรูปแบบนี้อาจพิจารณาตามประเภทของฟังก์ชัน ดังนี้

ฟังก์ชันที่ไม่มีการรับส่งค่าพารามิเตอร์ อาจประกาศรูปแบบของฟังก์ชัน ดังนี้

void functionname(void) หรือ void functionname()

ฟังก์ชันที่มีการรับค่าพารามิเตอร์แต่ไม่มีการส่งคืนค่า อาจประกาศรูปแบบของฟังก์ชัน ดังนี้

void functionname(type arg1,type arg2,...,type argN)

หรือ void functionname(type1,type2,...,typeN)

ฟังก์ชันที่มีการรับค่าพารามิเตอร์และมีการส่งคืนค่า อาจประกาศรูปแบบของฟังก์ชัน ดังนี้

type functionname(type arg1,type arg2,...,type argN)

หรือ type functionname(type1,type2,...,typeN)





การเรียกใช้ฟังก์ชันในโปรแกรม

การเรียกใช้ฟังก์ชัน ขึ้นกับประเภทของฟังก์ชัน เช่น

ฟังก์ชันที่ไม่มีการรับส่งค่าพารามิเตอร์ ทำดังนี้

functionname();

ฟังก์ชันที่มีการรับค่าพารามิเตอร์แต่ไม่มีการส่งคืนค่า มีการเรียกใช้ ดังนี้

functionname(argument list); หรือ functionname(arg1,arg2,...,argN);

โดย argument list คือ ตัวแปร หรือนิพจน์ที่ส่งไปให้ฟังก์ชัน ถ้ามีมากกว่า 1 ค่า ให้คั่นด้วยเครื่องหมาย คอมม่า (,)

ฟังก์ชันที่มีการรับและส่งคืนค่าพารามิเตอร์ มีการเรียกใช้ ดังนี้

variablename = functioname(arg1,arg2,...,argN);

โดย variablename คือ ชื่อของตัวแปรที่จะมารับค่าของพารามิเตอร์ที่ฟังก์ชันส่งคืนกับมา



การส่งค่าพารามิเตอร์หรืออาร์กูเมนต์ให้แก่ฟังก์ชัน

ฟังก์ชันที่มีการรับค่าพารามิเตอร์โดยไม่การส่งค่ากลับคืน และฟังก์ชันที่มีการรับค่าพารามิเตอร์และการส่งค่ากลับ ต้องการค่าของอาร์กูเมนต์หรือพารามิเตอร์ โดยพารามิเตอร์หรืออาร์กูเมนต์อาจมีเพียง 1 ค่าหรือมากกว่า การส่งค่าอาร์กูเมนต์ให้แก่ฟังก์ชัน โดยฟังก์ชันมีการรับค่าพารามิเตอร์ ได้หลายวิธีการ

1. การรับค่า(ข้อมูล)โดยตรง (call by value) เป็นการนำตัวแปร ค่าคงที่ หรือนิพจน์ซึ่งให้ผลมาเป็นค่าคงที่

2. การรับค่า เป็น ตำแหน่งหรือ address ของตัวแปรในหน่วยความจำ มาเป็นอาร์กูเมนต์ในการเรียกใช้ฟังก์ชัน ปกติจะต้องใช้ตัวแปรพอยน์เตอร์ มาเป็นตัวจัดเกี่ยวข้อมูลที่ฟังก์ชันรับเข้า (คือใช้เครื่องหมายของตัวแปรพอยน์เตอร์ คือ & และ * เป็นตัวช่วย

ในบางครั้งบางฟังก์ชัน ต้องการอาร์กูเมนต์หลายค่าและเป็นค่าชนิดเดียวกัน การเรียกใช้ฟังก์ชันพวกนี้อาจส่งค่าพารามิเตอร์ในรูปของอาร์เรย์ให้แก่ฟังก์ชัน



ตัวอย่าง การส่งค่าพารามิเตอร์ในรูปการรับค่าข้อมูลโดยตรง (ให้ตั้งชื่อโปรแกรมว่า sendargument1.c )

#include

#include

void divide(float , int );

main()

{

clrscr(); float x; int y;

printf("\n\tPlease type 1st number that you want to know the division :");

scanf("%f",&x);

printf("\n\tPlease type 2nd number that you want to know the division :");

scanf("%d",&y);

divide(x,y); /* ส่งค่า x,y ไปให้ ฟังก์ชัน divide(float p, int q) */

}

void divide(float p, int q)

{

float k;

k = p/q;

clrscr();

printf("\n\t p=%4.2f q=%d p/q =%4.2f \n",p,q,k);

}





การเรียกใช้ฟังก์ชันที่มีการรับค่า เป็น ตำแหน่งหรือ address ของตัวแปร



ตัวอย่าง การส่งค่าพารามิเตอร์ในรูปการรับค่าเป็นตำแหน่งหรือ address ของตัวแปร(ให้ศึกษาวิเคราะห์และทดลอง)

/* program name sentargument2.c */

#include

#include

void getpointer(int * , char *); /* ฟังก์ชันที่รับค่าเป็นตำแหน่งหรือ address การประกาศต้องใช้เครื่องหมาย * เพื่อระบุว่าเป็นพอยน์เตอร์ มิฉะนั้นต้องใช้ชื่อเต็ม */

main()

{ int i = 25; char a ='w'; printf("\n\tValue before send to getpointer i = %d a = %c ",i,a);

getpointer(&i,&a); */ การส่งค่าพารามิเตอร์แบบอ้างตำแหน่ง ให้แก่ตัวแปรพอยน์เตอร์ ในฟังก์ชัน */

} */ จบฟังก์ชัน main() */

void getpointer(int *pti, char *ptc)

{ int x; char y; x = *pti +30; y = *ptc;

printf("\n\tvalue of *pti = %d \n\tvalue of x or *pti + 30 =%d \n\tvalue of y = *ptc = %c ", *pti, x,y);

}



ตัวอย่าง การส่งค่าพารามิเตอร์ในรูปการรับค่าเป็นตำแหน่งหรือ address ของตัวแปร

/* sentargument3.c */

#include

#include

void addr(int *);

main()

{ int arr[6] = {10,25,45,65,75,95}; clrscr();

addr(arr); */ ส่งค่าพารามิเตอร์ในรูปการรับค่าเป็นตำแหน่งหรือ address ของตัวแปร */

} */ จบฟังก์ชัน main() */

void addr(int *pti)

{ int i=0;

while (i <=5) { printf("\n\tValue of i %d arr[%d] = %d ",i,i,*(pti+i)); i++; }

}





การส่งค่ากลับจากฟังก์ชัน

ปกติเมื่อเรียกใช้ฟังก์ชันแบบที่มีการคืนค่ากลับ ในกรณีที่ส่งค่าให้ฟังก์ชันโดยการส่งค่า(ข้อมูล)โดยตรง คือส่งค่าตัวแปร หรือ ค่าคงที่ให้ฟังก์ชัน ฟังก์ชันจะคืนค่าได้เพียง 1 ค่า โดยคืนมาในชื่อของฟังก์ชัน และในการเรียกใช้อาจใช้ตัวแปรมารับค่าที่คืนมา

ถ้าต้องการให้ฟังก์ชันสามารถคืนค่าอาร์กูเมนต์กลับคืนมาให้ได้หลายค่า ต้องใช้ตัวแปรพอยน์เตอร์มาช่วย โดยในเรียกใช้ฟังก์ชัน ค่าอาร์กูเมนต์ที่ใช้ในการเรียกใช้ต้องเป็นตำแหน่งของตัวแปร โดยใช้ เครื่องหมาย & และฟังก์ชันต้องมีอาร์กูเมนต์เป็นพอยน์เตอร์ คือ ตัวแปรที่เริ่มต้นชื่อด้วยเครื่องหมาย * โดยในกรณีนี้ฟังก์ชันนั้นอาจเป็นฟังก์ชันที่ไม่มีการส่งค่ากลับ(ฟังก์ชันที่ขึ้นต้นด้วย void)ก็สามารถใช้ส่งค่ากลับได้



ตัวอย่าง การส่งค่ากลับจากฟังก์ชัน เมื่อฟังก์ชันได้รับค่าแบบส่งค่า(ข้อมูล)ตรง ซึ่งฟังก์ชันจะคืนได้เพียงค่าเดียว

ให้นักเรียนศึกษา วิเคราะห์โปรแกรมแล้วทดสอบว่าตรงกับที่นักเรียนคิดหรือไม่

/* program return1.c */

#include

#include

int num1(int ,int ); /* ส่วนนี้เป็นการประกาศรูปแบบของฟังก์ชัน */

main()

{

clrscr();

int a,b,c;

a= 10; b=500;c=0;

printf("\nValue before send by use c = num1\(a,b\) a=%d b=%d c=%d ",a,b,c);

c= num1(a,b); */ ส่วนนี้เป็นการเรียกใช้ฟังก์ชัน โดยการให้ฟังก์ชันรับค่าโดยตรง และให้ตัวแปร c มารับค่าที่ฟังก์ชันคืนกลับมาให้ */

printf("\nValue after send by use c = num1\(a,b\) a=%d b=%d c=%d ",a,b,c); /* แสดงผลลัพธ์ */

printf("\nValue of num1\(a,b\) =%d ",num1(a,b)); */ แสดงผลลัพธ์ */

} /* จบฟังก์ชัน main() */

int num1(int x,int y) /* ฟังก์ชัน num1 */

{

int z;

z = x +y;

return (z);

}

ไม่มีความคิดเห็น:

แสดงความคิดเห็น

DEVELOPER ZOne