สารบัญ
หน้าที่ 5 - ฟังก์ชัน (Functions) และ โปรแกรมแยกเป็นโมดูล (Modular Programming)
4.ฟังก์ชัน และการเขียนโปรแกรมแยกเป็นโมดูล (Functions & Modular Programming)
สำหรับนักพัฒนา ที่ได้ทำการพัฒนาโปรแกรมมามากๆ บางครั้ง จำเป็นต้องเขียนโปรแกรมที่มีขนาดใหญ่และมีความสลับซับซ้อน จึงจำเป็นต้องหาวิธีในการพัฒนาโปรแกรมที่ดี ซึ่งสามารถทำได้ด้วยการ แตกปัญหาใหญ่ออกเป็นปัญหาย่อยๆ แล้วแก้ปัญหาย่อยออกไปที่ละส่วนจนกว่าจะหมด ซึ่งจะช่วยให้แก้ปัญหาใหญ่ๆ ได้สำเร็จนั่นเอง ซึ่งเราเรียกกันว่า วิธีแบ่งแยกแล้วพิชิต (Divide and Conquer) ซึ่งจะเป็นแนวการแก้ปัญหาแบบจากบนลงล่าง (Top down approach) ดังแสดงให้เห็นดังภาพที่ 4.1
การแตกปัญหาออกเป็นฟังก์ชันย่อยๆ มีข้อดีดังนี้
1) การแยกปัญหาที่จะใช้ในการเขียนโปรแกรมออกเป็นฟังก์ชันย่อยๆ จะช่วยให้เขียนโปรแกรมได้ง่ายขึ้นเพราะปัญหามีความซับซ้อนน้อยลง
2) การแยกปัญหาที่จะใช้ในการเขียนโปรแกรมออกเป็นฟังก์ชันย่อยๆ สามารถแก้ปัญหาตามที่โปรแกรมต้องทำ โดยมีโอกาสที่จะผิดพลาดน้อยลงเนื่องจากได้ทดสอบแก้ไขข้อผิดพลาดภายในฟังก์ชันย่อยๆ ก่อนรวมกันเป็นโปรแกรมใหญ่แล้ว
3) การแยกปัญหาออกเป็นฟังก์ชันย่อยนั้นมีประโยชน์ ที่ทำให้เราสามารถใช้ฟังกชันย่อยๆ เหล่านี้กลับไปใช้กับโปรแกรมอื่นๆ ได้ด้วย
4) การนำฟังกชันย่อยๆ เหล่านี้กลับมาใช้อีก จะช่วยลดขนาดของโปรแกรมลง และยังช่วยลดเวลาและค่าใช้จ่ายในการพัฒนาและการซ่อมบำรุงโปรแกรมได้อีกด้วย เพราะไม่ต้องเสียเวลาในการเขียนฟังก์ชันซ้ำ นอกจากฟังก์ชันย่อยที่ยังไม่ได้เขียนมาก่อน
ตัวอย่างการเขียนโปรแกรมออกเป็นโมดูลต่างๆ จะแสดงให้เป็นดังผังในภาพที่ 4.2 ซึ่งในภาพดังกล่าวได้แยกโปรแกรม Main ออกเป็นส่วนๆ คือ
1) ส่วนรับข้อมูล (Input) ซึ่งจะเป็นไปตามความต้องการของผู้ใช้ เช่นการป้อนข้อมุล หรือ การอ่านไฟล์ข้อมูล
2) ส่วนการคำนวณ (CAL) ซึ่งประกอบด้วยฟังก์ชันที่ใช้กับการคำนวณ ได้แก่
i. AVG สำหรับคำนวณค่าเกรดเฉลี่ยสำหรับเทอมปัจจุบัน
ii. GPA สำหรับคำนวณเกรดเฉลี่ยสะสม
3) ส่วนการแสดงผล (Display) ซึ่งเป็นการแสดงผลบนจอภาพ หรือจะพิมพ์ผลออกมาก็ได้ตามความต้องการของผู้ใช้โปรแกรม ที่กำหนดให้ผู้เขียนโปรแกรมทำให้สำเร็จตามเป้าหมาย
ภาพที่ 4.2: ตัวอย่างการเขียนโปรแกรมคำนวณค่าเกรดเฉลี่ย และ เกรดเฉลี่ยสะสมออกเป็นโมดูล
ส่วนในการตั้งชื่อฟังก์ชันนั้น ก็มีข้อกำหนดดังนี้
1) ห้ามขึ้นต้นด้วยตัวเลข
2) ห้ามเอาชื่อตารางอาเรย์ ชื่อตัวแปร หรือ คำสำคัญ (keywords) มาตั้งชื่อฟังก์ชันโดยเด็ดขาด
3) ในการใช้งานจริง นั้น ไม่ควรตั้งชื่อฟังก์ชันโดยไม่สื่อความหมายถึงการทำงานของฟังก์ชัน เพราะจะทำให้ลำบากในการซ่อมบำรุงโปรแกรม
โดยทั่วไปแล้วในการประกาศฟังก์ชันนั้น จะต้องมีการกำหนด type ให้ตัวแปรร่วมภายในฟังก์ชันด้วยเสมอ ดังตัวอย่างต่อไปนี้
ชนิดของฟังก์ชัน[function-type] ชื่อฟังก์ชัน [function-name] (บัญชีตัวแปรร่วม [parameter-list])
{
การประกาศตัวแปรเฉพาะที่; [local-definitions declaration;]
กลไกการทำงานของฟังก์ชัน; [function-implementation;]
การคืนค่าถ้าชนิดฟังก์ชันไม่เป็น void; [return statement if function type NOT void]
}
ยกตัวอย่างเช่น
float distance(float x, float y) // float คือ ชนิดของฟังก์ชัน ส่วน distance คือ ชื่อฟังก์ชัน
{ // float x, float y คือ บัญชีตัวแปรร่วม
float dist; // float dist คือ การประกาศตัวแปรเฉพาะที่;
dist = sqrt(x*x+y*y); // dist = ระยะห่างระหว่างพิกัด (x,y) ไป (0,0)
return dist ;
}
ก่อนจะทำการเรียกใช้ฟังก์ชัน จำเป็นต้องมี
การกำหนดฟังก์ชัน (function prototype)
ซึ่งเป็น copy ของ function heading และมีข้อกำหนดดังนี้
1) ตัวแปรร่วมในฟังก์ชัน ที่ประกาศไว้ และ ตัวแปรร่วมขณะเรียกใช้ฟังกชันนั้นต้องมีจำนวนเท่ากันและต้องมี type ตรงกัน มิฉะนั้นจะเกิด error ขึ้น
2) ต้องกำหนดการทำงานของฟังก์ชันก่อนการเรียกใช้ฟังก์ชัน ใน main function เพื่อให้ตัวแปรภาษารู้ว่าฟังก์ชันนี้ทำงานอย่างไร
3) แม้ฟังก์ชันที่ใช้จะไม่มีค่าตัวแปรร่วม ก็ต้องใส่วงเล็บ [ ( ) ] ไว้หลังชื่อฟังก์ชันเสมอ
4) การกำหนดฟังก์ชัน จะต้องกำหนดก่อนการใช้ Main function เพื่อให้ Main function ได้รับรู้ว่าฟังก์ชันดังกล่าวมีอะไรเป็นตัวแปรร่วม และ จะคืนค่าอะไรออกมา
5) กลไกการทำงานเต็มของฟังก์ชันย่อยจะแสดงหลังจากที่เรียก Main function แล้ว หรืออยู่ในไฟล์ที่แยกต่างหาก ซึ่งจะมีการแปรออกมาแล้วเชื่อมต่อกับ Main function
การกำหนดฟังก์ชันจะมีลักษณะดังนี้
float distance(float, float); // การกำหนดฟังก์ชัน [function prototype]
void main()
{
float x0 =
.,y0 =
;
float dist1 = distance(x0,y0);
}
float distance(float x, float y) // float คือ ชนิดของฟังก์ชัน distance คือ ชื่อฟังก์ชัน
{ // float x, float y คือ บัญชีตัวแปรร่วม
float dist; // float dist คือ การประกาศตัวแปรเฉพาะที่;
dist = sqrt(x*x+y*y);
return dist ;
}
ในการส่งผ่านตัวแปรเข้า ฟังก์ชัน (Passing argument)
นั้นมีการเรียกได้ 2 แบบ คือ
1) ส่งผ่านตามค่า (Pass by Value) ซึ่งส่งผ่านค่า ลงในตัวแปรร่วมของฟังก์ชันโดยตรง
2) ส่งผ่านตามการอ้างอิง (pass by Reference) ซึ่งส่งผ่านค่า address ในหน่วยความจำของตัวแปร ให้กับตัวแปรร่วมของฟังก์ชัน ถ้ามีการเปลี่ยนแปลงข้อมูล ณ ตำแหน่งหน่วยความจำดังกล่าว ค่าที่ส่งให้ตัวแปรร่วมของฟังก์ชันก็จะเปลี่ยนด้วย
ตัวแปรที่เกี่ยวข้องกับฟังก์ชันคือ
1) ตัวแปรเฉพาะที่ (Local variables) เป็นตัวแปรที่อยู่และเปลี่ยนแปลงเฉพาะภายในฟังก์ชันที่เรียกใช้ตัวแปรดังกล่าว การเปลี่ยนแปลงภายนอกฟังก์ชันที่เรียกใช้ตัวแปรเฉพาะที่จะไม่มีผลต่อตัวแปรเฉพาะที่ดังกล่าว ดังตัวอย่างต่อไปนี้
void test_locvar(int num)
{
int myvar; // Local variable fro this function
myvar = num;
}
void main()
{
int myvar, myvar_before, myvar_after; //Local variable for this function
myvar = 5;
myvar_before = myvar; // myvar_before = 5;
test_locvar(100); // call function
myvar_after = myvar; // myvar_after = 5;
}
2) ตัวแปรส่วนกลาง (Global variables) เป็นตัวแปรที่อยู่นอกฟังก์ชันซึ่งสามารถเปลี่ยนแปลงค่าภายในตัวแปรได้ตลอดเวลาเมื่อตัวแปรได้รับการเปลี่ยนแปลงโดยฟังก์ชัน ดังตัวอย่างต่อไปนี้
int myvar; // Global varible
void test_locvar(int num)
{
myvar = 20;
}
void main()
{
int myvar_before, myvar_after; //Local variable fro this function
myvar = 5;
myvar_before = myvar; // myvar_before == 5;
test_locvar(100); // call function
myvar_after = myvar; // myvar_after == 20;
}
ฟังก์ชันมีหลายประเภทได้แก่
1) ฟังก์ชันที่ไม่มี อาร์กิวเมนต์ และ ไม่คืนค่า เช่น ฟังก์ชัน void main()
2) ฟังก์ชันที่มี อาร์กิวเมนต์ แต่ ไม่คืนค่า เช่นฟังก์ชัน void do_something(float x, float y) ซึ่งจะทำงานตามที่ต้องการโดยอาศัยค่าอาร์กิวเมนต์ (ตัวแปร x,y) โดยไม่คืนค่าออกมา ฟังก์ชันดังกล่าวจะมีกลไกการับข้อมูลเข้าต่างหาก โดยไม่ต้องใช้ตัวแปรที่เป็น อาร์กิวเมนต์
3) ฟังก์ชันที่ไม่มี อาร์กิวเมนต์ แต่ก็คืนค่า เช่น ฟังก์ชัน float do_something2() ค่าที่คืนมาได้จาก ตัวแปรเฉพาะที่และกลไกการคำนวณภายในฟังก์ชันดังกล่าว
4) ฟังก์ชันที่มี อาร์กิวเมนต์ และ คืนค่า เช่นฟังก์ชัน float distance(float x, float y) ฟังก์ชันดังกล่าว สามารถคืนค่า โดยไม่จำเป็นต้องใช้ตัวแปรเฉพาะที่ทำหน้าที่เป็นตัวแปรชั่วคราวในการคืนค่า ตัวอย่างเช่น
float distance3D(float x, float y, float z)
{
return sqrt((x*x)+(y*y)+(z*z));
}
*หมายเหตุ
งานเขียนชิ้นนี้ ได้รับการคุ้มครองสิทธิตามพระราชบัญญัติคุ้มครองสิทธิทางปัญญา โดยลิขสิทธิเป็นของผู้เขียน ที่ให้เกียรตินำเผยแพร่ผ่าน วิชาการ.คอม เรามีความยินดีและอนุญาตให้ทำซ้ำหรือเผยแพร่ต่อเพื่อประโยชน์ทางการศึกษาเท่านั้น กรุณาให้เกียรติผู้เขียน โดยอ้างชื่อผู้เขียนและ วิชาการ.คอม (www.vcharkarn.com) ทุกครั้งที่ทำการเผยแพร่ต่อ ห้ามนำส่วนหนึ่งส่วนใดไปเผยแพร่ต่อในสื่อที่เอื้อประโยชน์ทางธุรกิจก่อนได้รับอนุญาต ขอขอบคุณที่ร่วมกันช่วยสร้างให้สังคมไทยเป็นสังคมแห่งปัญญา
จำนวน 36 ความเห็น, หน้า่ |
1| -
2-
ความเห็นเพิ่มเติมที่ 19 19 ธ.ค. 2550 (20:29) ตอบ ค.ห. ที่ 18 อ่ะคับ
ที่คอมไพล์ไม่ผ่านก็คงจะมาจากการเขียนรูปแบบของโปรแกรมผิด
ซึ่งอันที่จริงมันก็คงจะเป็นแค่เส้นผมบังภูเขาอยู่เท่านั้นแล
ค่อยๆหาจุดผิดพลาดนะคับ แล้วความผิดพลาดในคร้งนี้จะทำให้คุณจำมันจนขึ้นใจ
เป็นกำลังใจให้คับ
ความเห็นเพิ่มเติมที่ 20 22 ธ.ค. 2550 (12:17) ความเห็นที่ 18 นั้น ที่เขียนไม่ผ่าน อยู่บรรทัดแรกเลยครับ
#include
ตามจริงจะต้องเป็น
#include<ชื่อไดเรกทอรี่>
ชื่อไดเรกทอรี่ ก็มีเยอะ แต่ที่สำคัญที่สุดก็ stdio.h
ส่วนอื่นๆก็ยังมีอีกเยอะ ลองใช้ help ใน Turbo C ดูครับ (แบบDosนะ)
แบบDos จะใช้ง่ายที่สุดแล้ว ที่ผมเขียนมา
ความเห็นเพิ่มเติมที่ 21 24 ธ.ค. 2550 (23:19) เขียนโปรพอได้บ้างครับแต่ติดที่ภาษาแบบ งง ม๊ากมากทำงัยดี
ความเห็นเพิ่มเติมที่ 22 30 ธ.ค. 2550 (23:11) ขอบคุณมากๆครับ เพิ้งหัดศึกษา
ความเห็นเพิ่มเติมที่ 23 10 ม.ค. 2551 (04:00) คห ที่ 14
ใช้ software จาก หุ่นยนต์นั้นแหละ ง่ายที่สุด ครับ
เพราะผมก็ทำเหมือนกัน มันก็ละเอียดเช่นกันครับ
ปัญหาของหุ่นยนต์อยู่ที่ตัวแปรของอุปสรรคที่ไม่คงที่ครับเช่น
กำหนดให้ แสงน้อยเดินซ้าย ปรากฏว่า บริเวณนั้น มีหลอดไฟส่องอยู่ไม่ตรงตามที่กำหนดไว้
หุ่นยนต์ก็ผ่านไปครับ
เล็งแม่นๆ ตั้งค่าให้กว้างที่สุดเท่าที่จะทำได้
สำคัญอีกส่วนการออกแบบ ครับต้องให้เซ็นเซอร์ เสถียรไว้ก่อน ไม่โยกไปมา เพราะอ่านค่าแปลกไปครับ
ผมลองมาแล้ว ถ้าแสงบนสนามไม่เสถียรแล้วไม่แก้ไขหละก้อ
ดวงล้วนๆ ครับ
ความเห็นเพิ่มเติมที่ 24 21 ก.พ. 2551 (10:38) เติมตัวเลขเข้าไป ๒ จำนวน แล้วรายงานได้ว่าตัวเลขนั้นเท่ากันหรือไม่เท่ากัน
เขียนอย่างไรครับ
ความเห็นเพิ่มเติมที่ 25 16 มี.ค. 2551 (10:15)
ต้องขอขอบคุณเป็นอย่างมากเลยครับ ผมเคยเรียนมานานมากแล้ว ไม่รู้ว่าในสมองจะเหลือความจำบ้างหรือเปล่า ขอบคุณอีกครั้ง
ความเห็นเพิ่มเติมที่ 26 31 มี.ค. 2551 (15:56) ก็น่าสนใจน๊ะครับ แต่ถ้ายังไงผมแนะนำให้ไปดูเพิ่มเติมที่
citecclub.org แล้วจะได้อะไรเพิ่มขึ้นอีกมายมายมากกว่าที่คุณคิดน๊ะครับ
แค่คุณคิดจาสมัครก็ไม่ธรรมดาแล้ว แต่เนื้อหาแน่นน่าชมอย่างงมาก
เชื่อว่าคุณๆ จะต้องไม่ผิดหวังครับ
Os
ร่วมแบ่งปันความรู้และความเห็นแล้ว 1 ครั้ง - ได้รับดาวแล้ว 150 ดวง - โหวตเพิ่มดาว
ความเห็นเพิ่มเติมที่ 27 23 เม.ย. 2551 (15:21) ขอบคุณมากครับ
ความเห็นเพิ่มเติมที่ 28 15 พ.ค. 2551 (01:24) คุณ ช่วยแจ้งลบความเห็นนี้แล้ว ขอบคุณค่ะ ขอบคุณมากค่ะ ได้ความรู้มากเลย
ตอนนี้มีเรียนเรื่องนี้อยู่แต่เพิ่งเปิดเทอมยังไม่ได้ซื้อหนังสือเลยค่ะ ><"
ความเห็นเพิ่มเติมที่ 29 17 พ.ค. 2551 (13:08) ไม่เคยเข้าไปชมเว็บ ก็ดีครับ
ความเห็นเพิ่มเติมที่ 30 17 พ.ค. 2551 (13:26) ช่วยแนนำตัวprogram run ภาษา ซี
ความเห็นเพิ่มเติมที่ 31 20 พ.ค. 2551 (12:19) ตอบคำถาม นะครับ
คำถามที่ 16 ภาษา C เป็นภาษาโครงสร้างครับ แต่ java ถ้าจะให้ถูกหลักต้องเขียนเป็น OOP ครับ
คำถาม 17 ตัวแปรเกิดจากผู้เขียน สร้างขึ้นมาเองนะครับ ดังนั้น การสร้างขึ้นมาผู้เขียนโปรแกรมต้องจำได้สิครับ ที่คุณว่าหมายถึงคำสั่งป่ะครับ
คำถามที่ 18 คุณเขียนแค่นั้นไม่ได้หรอกครับ คุณต้องใช้ <Stdio.h> ตามหลัง include ด้วยครับ เพราะคุณมีการเรียกใช้ คำสั่งในการแสดงผล printf
คำถามที่ 30 ตัวโปรแกรม TC3 ครับ หรือ Turbo C++ ก็ได้ TC3 นี่ไม่ต้อง install Copy ลงไปแล้วเซ็ตาค่านิดหน่อยใช้ได้เลย ส่วน Turbo C++ install ใช้เหมือนโปรแกรมทั่วไป
goah
ร่วมแบ่งปันความรู้และความเห็นแล้ว 1 ครั้ง - ได้รับดาวแล้ว 50 ดวง - โหวตเพิ่มดาว
ความเห็นเพิ่มเติมที่ 32 4 มิ.ย. 2551 (10:19) การรัน คอมไพเลอร์ ระบบ boardland และระบบ turbo c อันไหนดีก่ากันคับ
ความเห็นเพิ่มเติมที่ 33 4 มิ.ย. 2551 (10:44) ผมก็เพิ่งเคยเขียนภาษา C
ผมจะลองเขียนให้ดูง่ายๆนะคับผิดตรงไหนก็ต้องขอโทษด้วยจริงๆ
#include<stdio.h>
void main()
{
int num1,num2,num3;
char[20] no1;
printf("\t\t\t\============\n");
printf("\t\t\t\t\TEST\n");
printf("\t\t\t\============\n");
printf("NUMBER 1 : ");
scanf("%d",num1);
printf("PLEASE + - * / ");
scanf("%d",no1);
printf("NUMBER 2 : ");
scanf("%d",num2);
{
if no1="+"
printf("ANSWER IS : ",num1+num2);
elseif no1="-"
printf("ANSWER IS : ",num1-num2);
elseif no1="*"
printf("ANSWER IS : ",num1*num2);
else
printf("ANSWER IS : ",num1/num2);
}
ผมว่าน่าจะผิดเยอะช่วยหาที่ผิดหน่อยนะคับ
ความเห็นเพิ่มเติมที่ 34 5 มิ.ย. 2551 (13:39)
ผมเด็กใหม่ แต่อยากเรียนภาษา c คับ ช่วยสอนผมหน่อยอยากเขียนโปรแกรมเป็นคับ "."
ความเห็นเพิ่มเติมที่ 35 9 มิ.ย. 2551 (16:34) กระผมขอขอบคุณเป็นอย่างมากๆๆๆๆๆๆๆๆๆๆๆๆๆๆๆๆๆๆๆๆๆ
ถ้ากระผมเข้าใจกระผมจะไม่ลืมพระคุณเลยขอรับ
ความเห็นเพิ่มเติมที่ 37 17 มิ.ย. 2551 (16:55) สวัสดีครับพี่ๆช่วยผมหน่อยนะครับ ผมอยากเขียนภาษา c
เป็นครับ audsadee@hotmail.com
ความเห็นเพิ่มเติมที่ 38 17 มิ.ย. 2551 (23:32) <P>#include<stdio.h></P>
<P>#include<conio.h></P>
<P>main(){</P>
<P> printf("Hello\nMy name is DotA.\n");</P>
<P> //printf();</P>
<P> printf("Good Bye");</P>
<P> getch();</P>
<P> }</P>
<P> </P>
<P>พอได้ป่าวคับ :)</P>