23
..\PoP\sathit Edit 24062009 by Sathit Intajag 87 บทที5 ฟังก์ชัน วัตถุประสงค์ - ศึกษาการเรียกใช้ฟังก์ชันพื ้นฐานทางคณิตศาสตร์จากไลบรารีมาตรฐาน - สามารถเขียนฟังก์ชันขึ ้นมาใช้เองได้ - ให้เข้าใจกลไกการส่งผ่านข้อมูลระหว่างฟังก์ชัน - สามารถใช้ฟังก์ชันในการสร้างเลขสุ่มได้ - เข้าใจขอบเขตและอายุของไอเด็นติไฟเออร์ - เพื่อให้เข้าใจกลไกพื ้นฐานของฟังก์ชันเรียกตัวเอง - เพื่อให้เข้าใจการออกแบบโปรแกรมด้วยโมดูล 5.1 บทนํา หลักทั่วไปของการเขียนโปรแกรมคอมพิวเตอร์เพื่อแก้ปัญหาต่างๆ ส่วนใหญ่จะใช้วิธีการ แจกแจงปัญหาออกเป็นส่วนๆ ปัญหาแต่ละส่วนจะถูกแบ่งตามหน้าที่การทํางาน และส่วนต่างๆ เหล่านี ้สามารถพิจารณาเป็นเซตของสเตจเม็นต์ ซึ ่งเป็นเสมือนบล็อกในโปรแกรมโครงสร้างที่ถูก นํามาเชื่อมต่อกันอย่างที่ได้ศึกษามาแล้วจากบทที่สามและสีโปรแกรมที่เขียนขึ ้นมาแก้ปัญหาต่างๆจะ ประกอบไปด้วยสเตจเม็นต์จํานวนมาก คือจะมีสเตจเม็นต์มากกว่าตัวอย่างโปรแกรมเท่าที่ได้เคย ศึกษามาแล้วจากบทก่อนหน้านี เมื่อมีประสบการณ์ในการเขียนโปรแกรมมากขึ ้น ก็จะพบว่าวิธีที่ดี ที่สุดที่จะพัฒนาและดูแลโปรแกรมขนาดใหญ่ก็คือ การสร้างโปรแกรมให้ประกอบขึ ้นด้วยส่วนย่อย ต่างๆของโปรแกรมหรือที่เรียกว่าโปรแกรมย่อยที่มีหน้าที่ทํางานเฉพาะอย่าง ซึ ่งส่วนของโปรแกรม เหล่านี ้จะถูกเรียกว่า โมดูล (Modules) โมดูลที่สร้างขึ ้นในภาษาซีจะเรียกว่าฟังก์ชัน ในบทนี ้จะไดอธิบายคุณสมบัติของฟังก์ชัน ที่ทําให้โปรแกรมขนาดใหญ่มีความยืดหยุ่นต่อการออกแบบและดูแล รักษา 5.2 โปรแกรมโมดูล เราจะเริ่มศึกษาโมดูลจากภาษาคอมพิวเตอร์ที่พอจะคุ้นเคยกันบ้างแล้ว นั่นคือโปรแกรม ภาษาซีที่ประกอบขึ ้นด้วยโมดูลที่เรียกว่าฟังก์ชัน เนื่องจากโปรแกรมภาษาซีจะต้องมีอย่างน้อยที่สุด หนึ ่งฟังก์ชันคือฟังก์ชันหลักหรือฟังก์ชัน main แต่ถ้ามีฟังก์ชันอื่นๆอีกก็จะถูกเรียกใช้ผ่านทาง ฟังก์ชันหลัก โปรแกรมภาษาซีมีฟังก์ชันมีอยู ่สองชนิดคือ ฟังก์ชันที่ถูกเขียนขึ ้นมาใหม่กับฟังก์ชันใน ไลบรารีมาตรฐาน ไลบรารีมาตรฐานของภาษาซีประกอบด้วยกลุ่มฟังก์ชันที่ถูกจัดไว้เป็นหมวดหมู เฉพาะงาน เช่นการคํานวณทางคณิตศาสตร์ การจัดการกับตัวอักษรและสายอักษร อินพุต/เอาต์พุต และปฏิบัติการอื่นๆที่เอื ้อประโยชน์ต่อการเขียนโปรแกรม ซึ ่งฟังก์ชันต่างๆเหล่านี ้ช่วยผู ้เขียน

บทที่ 5 ฟังก์ชันstaff.cs.psu.ac.th/sathit/StructuredProgramming/ch5.pdf · บทที่ 5 ฟังก์ชัน วัตถุประสงค ์

  • Upload
    others

  • View
    3

  • Download
    0

Embed Size (px)

Citation preview

Page 1: บทที่ 5 ฟังก์ชันstaff.cs.psu.ac.th/sathit/StructuredProgramming/ch5.pdf · บทที่ 5 ฟังก์ชัน วัตถุประสงค ์

..\PoP\sathit Edit 24062009 by Sathit Intajag 87

บทท 5 ฟงกชน

วตถประสงค

- ศกษาการเรยกใชฟงกชนพนฐานทางคณตศาสตรจากไลบรารมาตรฐาน

- สามารถเขยนฟงกชนขนมาใชเองได

- ใหเขาใจกลไกการสงผานขอมลระหวางฟงกชน

- สามารถใชฟงกชนในการสรางเลขสมได

- เขาใจขอบเขตและอายของไอเดนตไฟเออร

- เพอใหเขาใจกลไกพนฐานของฟงกชนเรยกตวเอง - เพอใหเขาใจการออกแบบโปรแกรมดวยโมดล

5.1 บทนา

หลกทวไปของการเขยนโปรแกรมคอมพวเตอรเพอแกปญหาตางๆ สวนใหญจะใชวธการแจกแจงปญหาออกเปนสวนๆ ปญหาแตละสวนจะถกแบงตามหนาทการทางาน และสวนตางๆเหลานสามารถพจารณาเปนเซตของสเตจเมนต ซงเปนเสมอนบลอกในโปรแกรมโครงสรางทถกนามาเชอมตอกนอยางทไดศกษามาแลวจากบททสามและส โปรแกรมทเขยนขนมาแกปญหาตางๆจะประกอบไปดวยสเตจเมนตจานวนมาก คอจะมสเตจเมนตมากกวาตวอยางโปรแกรมเทาทไดเคยศกษามาแลวจากบทกอนหนาน เมอมประสบการณในการเขยนโปรแกรมมากขน กจะพบวาวธทดทสดทจะพฒนาและดแลโปรแกรมขนาดใหญกคอ การสรางโปรแกรมใหประกอบขนดวยสวนยอยตางๆของโปรแกรมหรอทเรยกวาโปรแกรมยอยทมหนาททางานเฉพาะอยาง ซงสวนของโปรแกรมเหลานจะถกเรยกวา โมดล (Modules) โมดลทสรางขนในภาษาซจะเรยกวาฟงกชน ในบทนจะไดอธบายคณสมบตของฟงกชน ททาใหโปรแกรมขนาดใหญมความยดหยนตอการออกแบบและดแลรกษา

5.2 โปรแกรมโมดล

เราจะเรมศกษาโมดลจากภาษาคอมพวเตอรทพอจะคนเคยกนบางแลว นนคอโปรแกรมภาษาซทประกอบขนดวยโมดลทเรยกวาฟงกชน เนองจากโปรแกรมภาษาซจะตองมอยางนอยทสดหนงฟงกชนคอฟงกชนหลกหรอฟงกชน main แตถามฟงกชนอนๆอกกจะถกเรยกใชผานทางฟงกชนหลก

โปรแกรมภาษาซมฟงกชนมอยสองชนดคอ ฟงกชนทถกเขยนขนมาใหมกบฟงกชนในไลบรารมาตรฐาน ไลบรารมาตรฐานของภาษาซประกอบดวยกลมฟงกชนทถกจดไวเปนหมวดหมเฉพาะงาน เชนการคานวณทางคณตศาสตร การจดการกบตวอกษรและสายอกษร อนพต/เอาตพต และปฏบตการอนๆทเออประโยชนตอการเขยนโปรแกรม ซงฟงกชนตางๆเหลานชวยผเขยน

Page 2: บทที่ 5 ฟังก์ชันstaff.cs.psu.ac.th/sathit/StructuredProgramming/ch5.pdf · บทที่ 5 ฟังก์ชัน วัตถุประสงค ์

..\PoP\sathit Edit 24062009 by Sathit Intajag 88

โปรแกรมใหทางานไดงายขน เพราะสามารถเลอกไดวาจะใชฟงกชนจากไลบรารมาตรฐานทประกอบดวยฟงกชนพนฐานทลวนจาเปนในการเขยนโปรแกรม หรอผเขยนโปรแกรมอาจจะเขยนฟงกชนขนมาเองตามความเหมาะสมของงาน และจะเรยกฟงกชนเหลานวา “ฟงกชนทเขยนขนโดยโปรแกรมเมอร (Programmer-defined function)”

โปรแกรมจะอางถงฟงกชนหรอเรยกใชฟงกชน (Function call) ดวยชอฟงกชนพรอมกบอากวเมนต โดยอากวเมนตจะตองกาหนดใหถกตองเหมาะสมตามทไดประกาศไว ถาเปรยบเทยบฟงกชนในภาษาซกบฟงกชนทางคณตศาสตรทเขยนอยในรป y = f(x) เมอ f กคอชอฟงกชน สวน x

เปนพารามเตอรหรออากวเมนตของฟงกชน และ y กคอคาทฟงกชน f กระทากบ x จนไดผลลพธแลวสงมาเกบไวท y

main

worker1 worker2 worker3

worker4 worker5

รปท 5.1 ความสมพนธของฟงกชนทเรยกและถกเรยกตามลาดบชน

การเรยกใชฟงกชนเปรยบเทยบไดกบการบรหารจดการอยางมลาดบชน นนคอเจานาย (ซงเปรยบไดกบฟงกชนทเรยกใชฟงกชนอน) จะเรยกใชผใตบงคบบญชาซงกคอฟงกชนทถกเรยกเพอใหทางานแลวใหรายงานกลบไปเมอทางานเสรจ (ดรปท 5.1) เชนฟงกชนทตองการแสดงขอมลไปทหนาจอกจะสงขอมลมาใหฟงกชน printf เมอ printf พมพขอความไปทหนาจอเรยบรอยแลวกจะรายงานกลบหรอสงคากลบโดยใชคยเวรด return เพอแจงใหฟงกชนทเรยกทราบวาไดทางานเสรจเรยบรอย ฟงกชนทเปนผเรยกจะไมทราบเลยวาฟงกชนทถกเรยกทางานอยางไร ฟงกชนทถกเรยกใชอาจจะไปเรยกใชฟงกชนอนตออกทอดหนง ซงฟงกชนทเปนเจานายกไมตองการทจะรบรในสวนน การเขยนโปรแกรมโดยการเรยกใชฟงกชนชวยใหสามารถซอนรายละเอยดการทางาน ซงเปนเทคนคอยางหนงทนยมนามาใชในวศวกรรมซอฟตแวร จากรปท 5.1 ฟงกชน main ทเปรยบเหมอนเจานายทเรยกใชกบฟงกชนอนตามลาดบชนหลายฟงกชนดวยกน สงเกตวาฟงกชน worker1 ทาหนาทเปนหวหนางานโดยไดแจกงานใหฟงกชน worker4 และ worker5

5.3 ฟงกชนไลบรารทางคณตศาสตร

หวขอนจะอธบายหลกการเบองตนของการเรยกใชฟงกชน โดยอาศยฟงกชนคณตศาสตรจากไลบารมาตรฐานเปนตวอยาง การเรยกใชฟงกชนในโปรแกรมทวไปจะเรยกชอของฟงกชน การเรยกจะอางถงชอตามดวยวงเลบ และถาฟงกชนนนมอากวเมนตกจะใสอากวเมนตไวในวงเลบ ใน

Page 3: บทที่ 5 ฟังก์ชันstaff.cs.psu.ac.th/sathit/StructuredProgramming/ch5.pdf · บทที่ 5 ฟังก์ชัน วัตถุประสงค ์

..\PoP\sathit Edit 24062009 by Sathit Intajag 89

กรณทฟงกชนมอากวเมนตหลายตวระหวางอากวเมนตแตละตวจะคนดวยคอมมา เชนเมอตองการคานวณและพมพคารากทสองของ 900.0 กสามารถเรยกใชฟงกชนไดดงน

printf(“%.2f”, sqrt(900.0)); เมอฟงกชน printf ถกประมวลผล ฟงกชน sqrt กจะถกเรยกใชเพอคานวณคารากทสองของอากวเมนตทอยในวงเลบคอ 900.0 และเมอฟงกชน sqrt คานวณคารากทสองของ 900.0 แลวกจะสงคารากกลบ นนคอฟงกชน sqrt จะสง 30. 00 กลบมาและคานกจะเปนอากวเมนตตวทสองของฟงกชน printf ซงอากวเมนตนกจะถกพมพไปทจอภาพ

อากวเมนตของ sqrt เปนขอมลชนด double และคาผลลพธทจะสงกลบมากเปนชนด double

เชนกน ทกฟงกชนทอยในไลบรารทางคณตศาสตรจะสงคากลบเปนชนด double สงเกตวาขอมลชนด double จะใชเกบเลขทศนยมเชนเดยวกบ float ซงสามารถใชขอกาหนดการแปลง %f ไดเหมอนกน การเรยกใชฟงกชนไลบรารทางคณตศาสตรจะตองใชตวกากบการประมวลผลกอน #include <math.h>

อากวเมนตของฟงกชนอาจจะเปนคาคงทอยางทเหนในตวอยางทแลว หรออาจจะเปนตวแปรหรอนพจนอยางเชน a = 13.0, b = 3.0 และ c = 4.0 ดงนนสเตจเมนต

printf(“%.2f”, sqrt(a+b*c)); เปนการเรยกฟงกชน sqrt ดวยนพจน a+b*c ซงกคอ 13.0+3.0*4.0 = 25.0 นนกคอฟงกชน sqrt จะรบคา 25.0 ไปคานวณคารากและจะไดผลลพธเทากบ 5.0 คานกจะถกพมพไปทหนาจอ

ตารางท 5.1 ไดสรปฟงกชนทางคณตศาสตรของภาษาซเอาไว โดยทตวแปร x, y เปนชนด double

5.4 ฟงกชน

ฟงกชนเปนกลไกหลกทชวยสนบสนนการเขยนโปรแกรมเชงโครงสราง เพราะสามารถแบงโปรแกรมออกเปนบลอกๆตามหนาทการทางาน และยงชวยซอนตวแปรและการทางานตางๆไวในฟงกชน ตวแปรตางๆทกาหนดขนในฟงกชนถกมองเหนหรอเรยกใชไดเฉพาะในฟงกชน ซงตวแปรทประกาศไวในฟงกชนจะถกเรยกวา “ตวแปรทองถน (local variable)” โดยทวไปแลวจะเรยกตวแปรทองถนวาตวแปรโลคอล นอกจากนตวแปรทใชสอสารกบฟงกชนอนหรออากวเมนตกเปนตวแปรโลคอลเชนกน

การออกแบบฟงกชนกจะเหมอนกบการสรางบลอก เพอนาบลอกไปเชอมตอกบบลอกอนๆในโปรแกรมไดอยางลงตว แตอยางลมวาฟงกชนเปนบลอกทบรรจบลอกอนไวขางใน ซงกคอบลอกทเปนโครงสรางดงทไดศกษามาแลวจากบททสามและส และฟงกชนเองกถกบรรจไวในบลอกทใหญกวาซงกคอฟงกชนทเปนผเรยก ดงทอธบายไวในรปท 5.1 ดงนนการออกแบบฟงกชนทเหมาะสมกจะทาใหลดความซ าซอนในโปรแกรมลงไดมาก

Page 4: บทที่ 5 ฟังก์ชันstaff.cs.psu.ac.th/sathit/StructuredProgramming/ch5.pdf · บทที่ 5 ฟังก์ชัน วัตถุประสงค ์

..\PoP\sathit Edit 24062009 by Sathit Intajag 90

ตารางท 5.1 ฟงกชนพนฐานทางคณตศาสตรของภาษาซ

ฟงกชน คณสมบต ตวอยางการเรยกใช sqrt(x) หาคารากของ x sqrt(256.0) ซงจะสงคา 16.0 กลบ

sqrt(9.0) ซงจะสงคา 3.0 กลบ exp(x) ฟงกชนเอกโพเนนเชยล ex exp(1.0) ผลทไดคอ 2.718282

exp(2.0) ผลทไดคอ 7.389056 log(x) ลอกการทมธรรมชาตของ x

หรอลอกกาธทมฐาน e log(2.718282) ผลทไดคอ 1.0 log(7.389056) ผลทไดคอ 2.0

log10(x) ลอกการทมฐานสบของ x log10(1.0) ผลลพธทไดกคอ 0.0 log10(10.0) ผลลพธทไดกคอ 1.0 log10(100.0) ผลลพธทไดกคอ 2.0

fabs(x) คาสมบรณของ x fabs(5.0) ผลลพธทไดกคอ 5.0 fabs(0.0) ผลลพธทไดกคอ 0.0 fabs(-5.0) ผลลพธทไดกคอ 5.0

ceil(x) ปดเศษของ x ขน เพอทาใหเปนเลขจานวนเตมทไมนอยกวา x

ceil(9.2) ผลลพธทไดกคอ 10.0 ceil(-9.8) ผลลพธทไดกคอ –9.0

floor(x) ปดเศษของ x ลง เพอทาใหเปนเลขจานวนเตมทไมมากกวา x

floor(9.2) ผลลพธทไดกคอ 9.0 floor(-9.8) ผลลพธทไดกคอ -10.0

pow(x,y) คานวณคา x ยกกาลง y pow(2.0, 7) ผลลพธทไดกคอ 128.0 pow(9.0, 0.5) ผลลพธทไดกคอ 3.0

fmod(x,y) หาคาเหลอเศษของ x/y fmod(13.657, 2.333) ผลลพธทไดคอ 1.992

sin(x) ตรโกณมตของไซน x sin(0.0) ผลลพธทไดกคอ 0.0

cos(x) ตรโกณมตของโคไซน x cos(0.0) ผลลพธทไดกคอ 1.0

tan(x) ตรโกณมตของแทนเจนต x tan(0.0) ผลลพธทไดกคอ 0.0

5.5 การนยามฟงกชน

จากโปรแกรมตางๆทไดเคยอธบายมาแลวจากตวอยางตางๆกอนหนาน เรมจากการเรยกฟงกชน main แลวฟงกชน main กจะเรยกใชฟงกชนไลบรารมาตรฐาน โปรแกรมตอไปนจะนยามฟงกชนขนมาใชเอง โดยมการสรางฟงกชน square ขนมาเพอคานวณกาลงสองของอากวเมนตทมคาเปนจานวนเตม 1 ถง 10 แลวสงผลลพธทไดไปพมพ 1. /* DefFunc.c: Creating and using a programmer-defined function */ 2. #include <stdio.h> 3. 4. int square(int y); /* Function prototype */ 5. 6. int main() 7. { 8. int x; 9. for(x=1; x<=10; x++) 10. printf("%d\t", square(x)); 11. 12. printf("\n\n"); 13. return 0;

Page 5: บทที่ 5 ฟังก์ชันstaff.cs.psu.ac.th/sathit/StructuredProgramming/ch5.pdf · บทที่ 5 ฟังก์ชัน วัตถุประสงค ์

..\PoP\sathit Edit 24062009 by Sathit Intajag 91

14. } 15. /* square function definition returns square of parameter */ 16. int square(int y) 17. { 18. return y*y; 19. }

ฟงกชน square ถกอางถงหรอถกเรยกในฟงกชน printf ในบรรทดท 10 ของฟงกชน main

นนคอ printf("%d\t", square(x));

เมอฟงกชน square ถกเรยก ตวแปร y ทบรรทด 16 จะไดรบสาเนาจากตวแปร x ซงเหมอนกบการกาหนดคา x ใหกบ y (y = x) เมอฟงกชน square คานวณ y*y ในบรรทดท 18 ผลการคานวณถกสงกลบไปใหฟงกชน printf ในฟงกชน main กระบวนการนถกกระทาซ า 10 รอบดวยสเตจเมนต for

บรรทดท 4 ของโปรแกรม DefFunc.c มการประกาศฟงกชนตนแบบหรอทเรยกวา โพรโตไทปของฟงกชน (Function prototype) ไวดงน

int square(int y); /* Function prototype */ คยเวรด int ทอยในวงเลบจะแจงใหคอมไพเลอรทราบวาฟงกชน square จะรบคาทเปนจานวนเตม สวน int ทอยซายสดกอนชอฟงกชน จะแจงใหคอมไพเลอรทราบวา square จะสงคาผลลพธกลบไปยงสวนทเรยกใชเปนจานวนเตม คอมไพเลอรจะใชฟงกชนตนแบบเพอตรวจสอบการเรยกใชในบรรทดท 10 วาไดสงคาอากวเมนตและตวแปรทใชรบคาผลลพธทถกสงกลบมาจากฟงกชน square ตรงกบฟงกชนตนแบบหรอไม นนคอคอมไพเลอรจะตรวจสอบวาตวแปร x ทจะสงไปให y นนเปนชนด int หรอไมและตวแปรทใชรบคาทสงกลบมาเปนชนด int ดวยหรอไม นอกจากนคอมไพเลอรยงใชฟงกชนตนแบบในการตรวจสอบจานวน ชนด และลาดบของอากวเมนต ซงรายละเอยดของเรองฟงกชนตนแบบจะอธบายอกครงในหวขอตอไป

การนยามฟงกชนมรปแบบดงน return-value-type function-name(parameter-list) { definitions; statements; }

เมอ function-name คอชอฟงกชนทตองการประกาศ

return-value-type คอชนดของขอมลของผลลพธทจะสงกลบไปใหกบฟงกชนทเรยก ถา return-value-type เปนชนด void แสดงวาฟงกชนไมมการสงคากลบหรออาจจะสงคากลบแตเปนชนด void (จะไดอธบาย void เพมเตมในหวขอตอไป)

แตถาไมไดระบวาเปนขอมลชนดใด return-value-type จะถกกาหนดโดยคอมไพเลอรวาเปนชนด int อยางไรกตามไมควรละเลยในสวนน ในบรรทดแรกของการนยามฟงกชนทประกอบดวย return-value-type, function-name,

Page 6: บทที่ 5 ฟังก์ชันstaff.cs.psu.ac.th/sathit/StructuredProgramming/ch5.pdf · บทที่ 5 ฟังก์ชัน วัตถุประสงค ์

..\PoP\sathit Edit 24062009 by Sathit Intajag 92

parameter-list บางครงจะเรยกทงหมดนวาหวของฟงกชนหรอฟงกชนเฮดเดอร (Function header)

parameter-list ถาสวนนประกอบดวยตวแปรหลายตว กจะคนแตละตวดวยคอมมา parameter-list หรอรายการอากวเมนตของฟงกชน จะตองมการประกาศชอและชนดของตวแปรทจะรบเขามาใชในฟงกชน ถาฟงกชนไมมการรบคาใดๆเขามา parameter-list กจะเปนชนด void หรออาจจะปลอยวางเอาไวอยางทเหนในฟงกชน main ของตวอยางโปรแกรม DefFunc.c ชนดของตวแปรจะตองประกาศไวกอนชอตวแปรแตละตว นอกเสยจากตวแปรนนเปนชนด int

เนองจากถาไมไดระบชนดเอาไวคอมไพเลอรจะกาหนดใหเปนชนด int

definitions และ statements ทอยภายในวงเลบปกกาของตวฟงกชน (function body)

จะมรปแบบเปนบลอก ตวแปรตางๆสามารถทจะกาหนดเปนบลอก และบลอกนกสามารถทจะนามาซอนกนได

definitions เปนสวนของการนยามตวแปรโลคอล เพอใชภายในฟงกชน

statements เปนสวนของคาสงตางๆ ทเกดจากการนาตวแปรโลคอลและขอมลทรบมาจากสวนของ parameter-list เพอทาใหฟงกชนไดผลลพธ

การควบคมการสงคากลบจากฟงกชนมอยสามวธดวยกนคอ - ถาฟงกชนไมมการสงคากลบ การควบคมจะถกสงกลบแบบงายๆ เมอตองการออกจาก

ฟงกชนทจดใดๆ กใหใสสเตจเมนต return; ทจดนน

- กรณจบฟงกชน การควบคมการสงกลบกจะทางานโดยอตโนมต ไมจาเปนจะตองใช return กได นนคอเมอโปรแกรมทางานไปถงวงเลบปกกาปดสาหรบจบฟงกชนทถกเรยก การทางานกจะกลบไปยงฟงกชนทเรยกใชโดยอตโนมต

- ฟงกชนทตองสงคากลบ รปแบบของสเตจเมนตการสงคากลบกคอ return

expression; ซงเปนการสงคาทอาจจะอยในรปของนพจน คาคงท หรอตวแปรกลบไปยงฟงกชนทเรยกใช

ตวอยางโปรแกรมตอไปเปนการหาคาสงสด โปรแกรมนไดนยามฟงกชน maximum

เพอใหหาคาสงสดและสงคานกลบ โปรแกรม MaxFunc.c จะอานคาจานวนเตมสามตวมาจากคยบอรดดวยฟงกชน scanf ในบรรทดท 11 และจานวนเตมทงสามนจะถกสงใหฟงกชน maximum ในบรรทดท 13 เพอหาคาสงสด เมอไดผลลพธแลวกจะถกสงกลบมายง main ดวยสเตจเมนต return ในบรรทดท 24 และคาทถกสงกลบมาจะถกแสดงไปทหนาจอดวยฟงกชน printf ในบรรทดท 19 1. /* MaxFunc.c: 2nd example of chapter 5 to find the maximum of three integers */ 2. #include <stdio.h>

Page 7: บทที่ 5 ฟังก์ชันstaff.cs.psu.ac.th/sathit/StructuredProgramming/ch5.pdf · บทที่ 5 ฟังก์ชัน วัตถุประสงค ์

..\PoP\sathit Edit 24062009 by Sathit Intajag 93

3. 4. int maximum(int x, int y, int z); 5. 6. int main() 7. { 8. int num1, num2, num3; 9. 10. printf("Enter three integers: "); 11. scanf("%d%d%d", &num1, &num2, &num3); 12. 13. printf("Maximum is: %d\n\n", maximum(num1, num2, num3)); 14. 15. return 0; 16. } 17. /*Function maximum definition */ 18. int maximum(int x, int y, int z) 19. { 20. int max = y>x? y: x; 21. 22. if(z>max) 23. max = z; 24. return max; 25. }

5.6 ตนแบบฟงกชน

ตนแบบฟงกชน1 ประกาศไวเพอใหคอมไพเลอรทราบถงขอกาหนดของฟงกชน ซงประกอบดวยชนดของขอมลทจะสงกลบ ชอฟงกชน จานวน ชนด และลาดบของตวแปรทฟงกชนจะรบเขามา คอมไพเลอรจะใชตนแบบของฟงกชนเพอตรวจสอบการเรยกฟงกชน ภาษาซในรนกอนๆทยงไมไดมการตรวจสอบตนแบบฟงกชน กอใหเกดปญหาการเรยกใชฟงกชนอยางไมถกตอง สงผลใหการเรยกใชฟงกชนเกดความผดพลาดรายแรงในขณะประมวลผลโปรแกรม หรอถาไมรายแรงกทาใหตรวจหาสาเหตของความผดพลาดไดยาก นอกจากนยงยากตอการตรวจหาความผดพลาดทางตรรก ดงนนตนแบบฟงกชนจงเขามามบทบาทในการแกไขความยงยากเหลาน พรโปรเซสเซอรทกาหนดโดย #include เปนการนาตนแบบฟงกชนจากไลบรารมาตรฐานเขามา เพอใหคอมไพเลอรไดตรวจสอบการเรยกใชฟงกชน

ตนแบบฟงกชน maximum ทบรรทด 4 ทประกาศไวในโปรแกรม MaxFunc.c คอ int maximum(int x, int y, int z);

ตนแบบฟงกชนไดบอกวาฟงกชนชอ maximum มอากวเมนตสามตวเปนชนดจานวนเตม และสงคากลบเปนจานวนเตมดวยเชนกน สงเกตวาตนแบบฟงกชนจะถกกาหนดเหมอนกบบรรทดแรกของการนยามฟงกชนเฮดเดอร maximun ในบรรทดท 18 แตทงสองสวนนจะแตกตางกนตรงทตนแบบฟงกชนจะจบสเตจเมนตดวยเซมโคลอนสวนการนยามจะไมมเซมโคลอน

1

คณสมบตทดอกอยางหนงของภาษาซคอการประกาศตนแบบของฟงกชน คณสมบตนถกนามาใชโดยคณะกรรมการมาตรฐานภาษาซทนามาจากภาษา C++

Page 8: บทที่ 5 ฟังก์ชันstaff.cs.psu.ac.th/sathit/StructuredProgramming/ch5.pdf · บทที่ 5 ฟังก์ชัน วัตถุประสงค ์

..\PoP\sathit Edit 24062009 by Sathit Intajag 94

การเรยกใชฟงกชนโดยไมกาหนดใหตรงตามฟงกชนตนแบบ คอมไพเลอรจะแจงเตอนใหทราบวามการเรยกฟงกชนไมถกตองและอาจจะเกดขอผดพลาดขนดวยเชนกน ถาตนแบบและการนยามฟงกชนไมตรงกน เชนจากโปรแกรม MaxFunc.c ถากาหนดตนแบบของฟงกชนเปน

void maximum(int x, int y, int z); คอมไพเลอรกจะแจงขอผดพลาด เนองจากคาทสงกลบเปนชนด void ในตนแบบฟงกชน แตการนยามฟงกชนปรากฏวามการสงคากลบเปนชนด int

คณลกษณะทสาคญอกอยางหนงของตนแบบฟงกชนคอ การควบคมอากวเมนตใหมชนดทเหมาะสม เชน การเรยกฟงกชน sqrt จากไลบรารคณตศาสตร สามารถเรยกใชไดดวยอากวเมนตชนดจานวนเตม แมวาฟงกชนตนแบบใน math.h ไดกาหนดไววาเปนชนด double แตฟงกชนกยงสามารถทางานไดอยางถกตอง ดงสเตจเมนตตอไปน

printf(“%.3f\n”, sqrt(4)); การเรยกฟงกชน sqrt(4) เมอ 4 เปนจานวนเตมแต sqrt กจะคานวณและสงคากลบมาพมพเปน 2.000 ซงเปนผลลพธทถกตอง ในกรณนตนแบบฟงกชนทาใหคอมไพเลอรแปลงจานวนเตม 4 ใหเปนชนด double คอมคาเทากบ 4.0 กอนทจะสงให sqrt

เมอเรยกฟงกชนโดยกาหนดอากวเมนตทไมตรงกบชนดของตวแปรในฟงกชนตนแบบ กจะถกแปลงเปนชนดทถกตองตามฟงกชนตนแบบกอนทจะสงไปใหฟงกชน การแปลงนสามารถกอใหเกดผลลพธทผดพลาดไดถาไมเปนไปตามกฎการแปลงของภาษาซ

กฎการแปลงของภาษาซไดกาหนดไววา ขอมลตางชนดกนสามารถทจะแปลงไปเปนชนดอนไดโดยไมผดพลาด ถาเปนการแปลงจากชนดทเลกกวาไปยงชนดทใหญกวา อยางในตวอยาง sqrt

ขางตน ขอมลชนด int จะถกแปลงไปเปน double อยางอตโนมตโดยไมมความผดพลาด อยางไรกตามการแปลงจาก double ไปส int กจะมการปดเศษทศนยมทงไป และการแปลงจากจานวนเตมทมขนาดใหญกวาไปสชนดทเลกกวา เชนการแปลง long ไปเปน short อาจจะกอใหเกดผดพลาดได ถาคาทเกบอยใน long มคาเกนขอบเขตของ short แตถาไมเกนขอบเขตกไมมความผดพลาดเกดขน

กฎการแปลง ถกนามาใชอยางอตโนมตกบนพจนทประกอบดวยตวแปรสองตวหรอมากกวา โดยตวแปรชนดทเลกกวาจะถกแปลงใหเปนชนดเดยวกบตวแปรชนดทใหญทสดอยางอตโนมต เชน x*sqrt(9) เมอ x เปนจานวนเตม ดงนน x จะถกแปลงใหเปนชนด double เปนตน ตารางท 5.2

แสดงรายการชนดขอมลตามลาดบ จากชนดทใหญทสดไปยงชนดทเลกทสดตามขอกาหนดการแปลงของฟงกชน printf และ scanf

โดยปกตการแปลงคาจากตวแปรชนดใหญกวาไปยงตวแปรชนดทเลกกวา จะทาใหเกดความผดพลาดขนมาได การแปลงไปสชนดทเลกกวาอาจจะกาหนดคาโดยตรงใหกบตวแปรหรอโดยใชตวดาเนนการแคสต สาหรบอากวเมนตฟงกชนจะถกแปลงตามชนดของตวแปรในตนแบบฟงกชน อยางฟงกชน square ทเขยนขนในโปรแกรม DefFunc.c จะรบตวแปรชนด int เมอเราเรยกใชโดย

Page 9: บทที่ 5 ฟังก์ชันstaff.cs.psu.ac.th/sathit/StructuredProgramming/ch5.pdf · บทที่ 5 ฟังก์ชัน วัตถุประสงค ์

..\PoP\sathit Edit 24062009 by Sathit Intajag 95

สงเลขทศนยมไปให ทาใหคาทสงไปถกแปลงเปน int ซงเปนตวแปรทมพสยเลกกวาเปนเหตใหฟงกชน square สงคาการคานวณทผดพลาดกลบมา เชน square(4.5) กจะสงคา 16 กลบมา แทนทจะเปน 20.25 เนองจาก 4.5 จะถกแปลงเปนจานวนเตมทเทากบ 4 ตารางท 5.2 ตวกาหนดการแปลงจากชนดขอมลทใหญทสดไปยงชนดทเลก

ชนดของขอมล ขอกาหนดการแปลงของ printf ขอกาหนดการแปลงของ scanf

long double %Lf %Lfdouble %f %f float %f %f unsigned long int %lu %lu long int %ld %ld unsigned int %u %u int %d %d short %hd %hd char %c %c

ถาตนแบบฟงกชนไมไดรวมหรอไมไดกาหนดไวในโปรแกรม คอมไพเลอรจะสรางตนแบบ

ของฟงกชนขนมาเองจากการบรรทดแรกทอางถงฟงกชน ไมวาจะเปนการนยามหรอการเรยกใช เมอคอมไพลเลอรสรางตนแบบขนมาเองจะทาใหคาทสงกลบจะถกกาหนดเปนชนด int โดยอตโนมต สวนอากวเมนตกจะถกกาหนดตามชนดของตวแปรทใชเรยกฟงกชน ในบางกรณทาใหอากวเมนตทสงไปยงฟงกชนไมถกตอง ความผดพลาดนจะไมถกรายงานโดยคอมไพเลอรอยางทเคยเหนมาแลวในบททผานมา

5.7 เฮดเดอรไฟล

ไลบรารมาตรฐานจะมไฟลทเรยกวาเฮดเดอรไฟล สาหรบประกาศตนแบบฟงกชน นอกจากนเฮดเดอรไฟลยงไดนยามตวแปรและคาคงทตามความเหมาะสม ตารางท 5.3 แสดงเฮดเดอรไฟลของไลบรารมาตรฐานบางสวนทมการนามาใชบอยๆในโปรแกรม

ผเขยนโปรแกรมสามารถสรางไฟลเฮดเดอรของตนเองได ไฟลเฮดเดอรทสรางขนเองควรตงชอและใชนามสกล .h ดวยเชนกน เวลานาไปใชกประกาศใชเชนเดยวกบเฮดเดอรมาตรฐานคอ ใชพรโปรเซสเซอร #include

5.8 การเรยกฟงกชน

การเรยกใชหรอการอางถงฟงกชนของภาษาคอมพวเตอรโดยทวไปมอยสองวธคอ การเรยกดวยคา (Call by value) และการเรยกไปทหนวยความจา (Call by reference) การเรยกใชฟงกชนทงสองวธนจะแบงตามวธการสงผานอากวเมนต เมอฟงกชนถกเรยกดวยคา ตวแปรทเปนอา-กวเมนตจะถกทาสาเนาขนแลวสงใหกบพารามเตอรของฟงกชนทถกเรยก เมอพารามเตอรถก

Page 10: บทที่ 5 ฟังก์ชันstaff.cs.psu.ac.th/sathit/StructuredProgramming/ch5.pdf · บทที่ 5 ฟังก์ชัน วัตถุประสงค ์

..\PoP\sathit Edit 24062009 by Sathit Intajag 96

นาไปใชโดยการเปลยนแปลงคากจะไมสงผลถงคาเดมของตวแปรทอยในฟงกชนผเรยก แตถาเรยกใชฟงกชนดวยการอางองถงหนวยความจา ฟงกชนผเรยกจะยอมใหฟงกชนทถกเรยกเขาไปเปลยนแปลงคาของตวแปรทถกสงไป ตารางท 5.3 เฮดเดอรไฟล

เฮดเดอร คาอธบาย <assert.h> มฟงกชนทชวยวนจฉยและการตรวจสอบโปรแกรม<ctype.h> บรรจไวซงฟงกชนตนแบบสาหรบฟงกชนตางๆ ททดสอบตวอกษรตางๆ สาหรบ

คณสมบตทแนนอน และฟงกชนตนแบบสาหรบฟงกชนตางๆ ทจะถกใชในการแปลงตวอกษรภาษาองกฤษจากตวพมพเลกไปเปนตวพมพใหญและสามารถแปลงในทางกลบกน

<errno.h> มแมกโครทนยามไวสาหรบใชประโยชนในการแจงเงอนไขของความผดพลาด <float.h> บรรจไวซงขดจากดของขนาดของจดทศนยมของระบบ<limits.h> บรรจไวซงคาขดจากดของขนาดจานวนเตมของระบบ<locale.h> ประกอบดวยตนแบบฟงกชนและขอมลอนๆ ทชวยในการเขยนโปรแกรมทจะแปลง

หนวยของเงนตราทใชอย โดยขนอยกบทตงของแตละประเทศทมขอมลของวนท เวลา <math.h> ประกอบดวยตนแบบฟงกชนสาหรบใชในทางคณตศาสตร<setjmp.h> ประกอบดวยตนแบบของฟงกชนสาหรบยอมใหเปนทางผานของการเรยกฟงกชนปกต

และสงคากลบเปนลาดบ <signal.h> ประกอบดวยตนแบบฟงกชนและแมกโครเพอทจะจดการกบเงอนไขตางๆ ทอาจจะ

เกดขนในระหวางการประมวลผลโปรแกรม <stdarg.h> มนยามของแมกโครทจะใชจดการกบลาดบของอากวเมนตของฟงกชนทไมทราบทง

จานวนและชนด <stddef.h> ประกอบดวยนยามทวไปของชนดขอมลทใชในภาษาซสาหรบการคานวณ <stdio.h> ประกอบดวยตนแบบฟงกชนสาหรบทจะจดการกบอนพต/เอาตพต<stdlib.h> มตนแบบของฟงกชนสาหรบการแปลงจานวนตวเลขไปเปนตวอกษรและจากตวอกษร

แปลงเปนตวเลข การจดหนวยความจา เลขสม และฟงกชนเออประโยชนอนๆ <string.h> มตนแบบฟงกชนสาหรบประมวลผลสายอกษร<time.h> มตนแบบฟงกชนและชนดสาหรบจดการเรองเวลาและวนท

การเรยกใชฟงกชนดวยคา ควรใชเมอฟงกชนทถกเรยกไมจาเปนตองเปลยนคาเดมของตวแปรในฟงกชนผเรยก ในกรณนเปนการปองกนความผดพลาดทเนองมาจากการเขาไปแกไขคาตวแปรของฟงกชนทเรยกใชโดยไมตงใจ ซงการเรยกฟงกชนดวยคาเพอสอสารกบฟงกชนอนจะชวยเพมความนาเชอถอใหกบระบบซอฟตแวรทตองการซอนขอมลไวในแตละฟงกชน สวนการเรยกฟงกชนแบบอางถงหนวยความจาควรใชเทาทจาเปน และตองแนใจวาฟงกชนผเรยกจาเปนตองเปลยนแปลงคาของตวแปร ซงรายละเอยดของการเรยกฟงกชนทงสองแบบนจะไดศกษากนอกครงในบทตอไป

5.9 การสรางเลขสม

หวขอนจะนาความรเรองฟงกชนทไดศกษา มาประยกตใชกบการจาลองเกมงายๆโดยนาเอาการพฒนาโปรแกรมโครงสรางทมการเชอมตอการทางานของฟงกชนตางๆ เชนเดยวกบการเชอมตอ

Page 11: บทที่ 5 ฟังก์ชันstaff.cs.psu.ac.th/sathit/StructuredProgramming/ch5.pdf · บทที่ 5 ฟังก์ชัน วัตถุประสงค ์

..\PoP\sathit Edit 24062009 by Sathit Intajag 97

บลอกของโฟลวชารต และตวอยางโปรแกรมในหวขอนจะใชโครงสรางการควบคมทงหมดทไดศกษามาแลว

พจารณาสเตจเมนตตอไปน i = rand();

ฟงกชน rand ถกเรยกเพอสรางเลขสมทอยระหวาง 0 ถง RAND_MAX (เปนสญลกษณแทนคาคงททถกนยามไวในเฮดเดอรไฟล <stdlib.h>) จากมาตรฐาน ANSI ทกลาวไววาคาของ RAND_MAX

จะตองไมนอยกวา 32767 ซงเปนคาสงสดของจานวนเตมขนาดสองไบต โปรแกรมนจะทดสอบเลขสม ถาฟงกชน rand มการสมอยางแทจรงทกจานวนระหวาง 0 ถง RAND_MAX จะมโอกาสทจะถกสมเทาๆกน

พสยของคาทสรางขนโดยตรงจากฟงกชน rand สวนใหญกจะแตกตางกนตามความจาเปนของแตละงาน เชนโปรแกรมทจาลองการโยนเหรยญอาจจะตองการเลขสมแค 0 กบ 1 คอ 0 แทนการออกหวสวน 1 แทนการออกกอย สาหรบโปรแกรมทจาลองการโยนลกเตา หกดานของลกเตากจะถกแทนดวยเลขสม 1 ถง 6

ตนแบบฟงกชน rand อยใน stdlib.h และจะใชตวดาเนนการหารเหลอเศษรวมกบ rand ดงน rand()%6 + 1

เพอสรางเลขสมจาก 1 ถง 6 ทแทนการโยนลกเตาในแตละครง เลข 6 ทใชเปนตวหารเหลอเศษในกระบวนการนเรยกวาสเกลลงแฟกเตอร (Scaling factor) เมอผลจากการสมของฟงกชน rand()

ถกหารเหลอเศษดวย 6 กจะไดคา 0 ถง 5 และจะบวกหนงเขาไปเพอใหไดคา 1 ถง 6 1. /* RandDice.c: Shifted, scaled integers produced by 1 + rand() % 6 */ 2. #include <stdio.h> 3. #include <stdlib.h> 4. 5. /* function main begins program execution */ 6. int main() 7. { 8. int i; /* counter */ 9. 10. /* loop 20 times */ 11. for ( i = 1; i <= 20; i++ ) 12. { 13. /* pick random number from 1 to 6 and output it */ 14. printf( "%10d", 1 + ( rand() % 6 ) ); 15. /* if counter is divisible by 5, begin new line of output */ 16. if ( i % 5 == 0 ) 17. printf( "\n" ); 18. } /* end for */ 19. 20. return 0; /* indicates successful termination */ 21. 22. } /* end main */

การทางานของโปรแกรม RandDice.c ไดแสดงไวในรปท 5.2 ซงเปนโปรแกรมโครงสรางทประกอบดวยสองบลอกซอนกนอยคอ บลอกของ if ถกซอนไวในบลอกของ for ทวนซ าเพอสม

Page 12: บทที่ 5 ฟังก์ชันstaff.cs.psu.ac.th/sathit/StructuredProgramming/ch5.pdf · บทที่ 5 ฟังก์ชัน วัตถุประสงค ์

..\PoP\sathit Edit 24062009 by Sathit Intajag 98

เลขแทนการโยนลกเตาหนงลก 20 ครง ผลการโยนแตละครงจะถกพมพไปทจอภาพ และเมอโยนลกเตาครบหาครงกจะขนบรรทดใหม ผลลพธของโปรแกรมนไดแสดงไวในรปท 5.3

START

i = 1;

i <= 20

printf( "%10d", 1 + ( rand() % 6 ) );

i %5 == 0

printf( "\n" );

STOP

Yes,

Yes,

i = i + 1;

No,

No,

บลอกของ if

บลอกของสเตจเมน for

รปท 5.2 การทางานของโปรแกรม RandDice.c

รปท 5.3 ผลลพธของการโยนลกเตาหนงลกยสบครงของโปรแกรม RandDice

เมอทดลองประมวลผลโปรแกรม RandDice หลายๆครง สงเกตดผลการโยนลกเตากจะ

พบวาผลลพธทไดในแตละครงจะไมแตกตางกน เพอใหไดเลขสมทไมซ ากนเมอประมวลผลโปรแกรมซ าๆ จะตองเรยกใช rand รวมกบฟงกชน srand ฟงกชนนมอากวเมนตเปนจานวนเตมบวก ฟงกชน srand จะตองถกเรยกกอนฟงกชน rand เมอนาโปรแกรม RandDice.c มาแกไขเสยใหมโดยการแทรกบรรทดตอไปนเขาไปตอจากบรรทดท 8 นนคอ

9. unsigned seed; /* จานวนทใชกาหนดเพอสรางเลขสม */ 10. printf(“Enter seed: ”); 11. scanf(“%u”, &seed); /*อานเลขจานวนเตมบวกเขามาสาหรบสรางเลขสม */ 12. srand(seed); /* ใช seed ทปอนเขามาเปนตวสรางเลขสม */

สวนบรรทดอนๆของโปรแกรมไมจาเปนตองแกไข เมอคอมไพลและประมวลผลโปรแกรมใหมกจะพบวาเลขสมของการโยนลกเตาแตละครงจะไมซ ากนดงทแสดงในรปท 5.4

Page 13: บทที่ 5 ฟังก์ชันstaff.cs.psu.ac.th/sathit/StructuredProgramming/ch5.pdf · บทที่ 5 ฟังก์ชัน วัตถุประสงค ์

..\PoP\sathit Edit 24062009 by Sathit Intajag 99

(ก) ประมวลผลครงแรกโดยปอน seed=50 เพอกาหนดคาให srand

(ข) ประมวลผลครงทสองโดยปอน seed=10 เพอกาหนดคาให srand

(ค) ประมวลผลครงทสามโดยปอน seed=5000 เพอกาหนดคาให srand

รปท 5.4 การประมวลผล RandDice ทแกไขใหมสามครง

5.10 ระดบของการประกาศตวแปร

ไอเดนตไฟเออร(Identifier) เปนสญลกษณทอยในรปของชอตางๆทถกกาหนดขนในภาษาคอมพวเตอร ซงประกอบดวยชอตวแปร ชนดขอมล ชอฟงกชนและปายชอ (Label) จากบททผานมาเราไดเรยนรปการตงชอตางๆเหลานมาแลว หวขอนจะศกษาคณสมบตของไอเดนตไฟเออร เชน ระดบของการเกบ ชวงเวลาในการเกบ ขอบเขตและการเชอมโยง

การประกาศตวแปรภาษาซประกอบดวยตวกาหนดระดบ auto, register, extern และ static

ระดบการประกาศไอเดนตไฟเออรใชสาหรบกาหนดชวงอายการเกบ(Storage duration) ขอบเขต(Scope) และการเชอมโยง (Linkage) ชวงอายการเกบของไอเดนตไฟเออร กคอชวงระยะเวลาทไอเดนตไฟเออรตวนนๆอยในหนวยความจา ไอเดนตไฟเออรบางตวจะอยในหนวยความจาเพยงระยะสนๆ บางตวกจะถกสรางและทาลายอยางซ าๆ แตบางตวกอยในหนวยความจาจนกระทงจบโปรแกรม

ขอบเขตของไอเดนตไฟเออร เปนตวกาหนดวามสวนใดบางในโปรแกรมทสามารถอางถงหรอเรยกใชไอเดนตไฟเออรนนๆได เนองจากไอเดนตไฟเออรบางตวสามารถอางถงหรอเรยกใชไดทวทงโปรแกรม แตบางตวกอางถงไดเฉพาะเพยงบางสวนของโปรแกรม

การเชอมโยงไอเดนตไฟเออรจะเกดขนเมอโปรแกรมประกอบดวยหลายไฟล ไอเดนตไฟเออรใดๆกตามจะมการรบรไดหรอมขอบเขตหรออางถงไดเฉพาะในไฟลนนๆ แตถาตองการใหมการเชอมโยงกนระหวางไฟลกจะตองมการกาหนดขนมา

Page 14: บทที่ 5 ฟังก์ชันstaff.cs.psu.ac.th/sathit/StructuredProgramming/ch5.pdf · บทที่ 5 ฟังก์ชัน วัตถุประสงค ์

..\PoP\sathit Edit 24062009 by Sathit Intajag 100

ตวกาหนดระดบการประกาศไอเดนตไฟเออรทงสชนด สามารถแบงตามลกษณะชวงเวลาการจดเกบไดเปนสองแบบคอ การจดเกบอตโนมต(Automatic storage duration) และการจดเกบแบบคงท (Static storage duration) คาสงวนหรอคยเวรด auto และ register ถกใชเพอกาหนดตวแปรแบบมระยะเวลาการจดเกบอตโนมต ตวแปรทกาหนดแบบมระยะเวลาเกบอตโนมตนจะถกสรางขนในบลอกทถกประกาศไว และยงคงอยในหนวยความจาตราบเทาทบลอกนนยงทางานอย ตวแปรเหลานจะถกทาลายเมอโปรแกรมออกจากบลอก

การประกาศตวแปรแบบมระยะเวลาการเกบอตโนมต เชนตวแปรทองถนทประกาศขนภายในฟงกชน (ไมวาจะถกกาหนดเปนรายการของพารามเตอรหรอทประกาศในตวฟงกชน) โดยปกตแลวจะเปนตวแปรแบบมระยะเวลาการจดเกบอตโนมต คยเวรด auto ใชแจงวาเปนตวแปรทมระยะเวลาการเกบอตโนมต ตวอยางการประกาศทแสดงใหเหนวาตวแปร x, y เปนชนด double ทเปนตวแปรทองถนแบบอตโนมต และจะอยในหนวยความจาตราบเทาทฟงกชนยงทางานอย

auto double x, y; ตวแปรทองถนจะเปนแบบมระยะเวลาการเกบแบบอตโนมตอยแลว ดงนนคยเวรด auto สวน

ใหญกไมมใครใชคานกนในการประกาศตวแปรทองถน นอกจากนตวแปรทเปนแบบมระยะเวลาการเกบอตโนมตมกจะเรยกสนๆ เพยงวา “ตวแปรอตโนมต (Automatic variable)” และการเกบแบบอตโนมต กจะหมายถงการจองหนวยความจาดวยตวแปรอยางอตโนมต ขอมลทกาหนดใหกบตวแปรกจะถกเกบไวในหนวยความจาระยะหนงตราบเทาทจาเปนตองใช โดยปกตแลวขอมลในโปรแกรมจะถกดงขนมาในหนวยความจาโดยเกบไวในรจสเตอร (Registers) เพอการคานวณและการประมวลผล

การประกาศตวแปรแบบรจสเตอรจะนาคยเวรด register มาวางไวกอนชอตวแปรอตโนมต เพอชนาใหคอมไพเลอรจดเกบตวแปรรจสเตอรไวในหนวยความจารจเตอรของคอมพวเตอร เชนกรณทตวแปรใดถกใชบอยๆ เชนตวแปรทเปนตวนบกสามารถทจะกาหนดเปนตวแปรรจสเตอรของฮารดแวรได เนองจากตวนบเปนตวแปรทตองทางานอยตลอดในวงวน ไมวาจะเปนการตรวจสอบเงอนไขเพอออกจากวงวน หรอการเพมคาของตวนบทเปนงานปกตของตวนบอยแลว จะเหนวาตวแปรทตองเรยกใชงานบอยๆเชนน ถาประกาศเปนตวแปรรจสเตอรกจะทาใหไมตองนาเขาหรอเอาออกจากรจสเตอรบอยๆ กจะลดเวลาการตดตอกบตวแปร

คอมไพเลอรอาจจะไมสนใจการประกาศตวแปรรจสเตอร เนองจากรจสเตอรของเครองคอมพวเตอรมอยอยางจากด เมอไมมรจสเตอรเพยงพอกบจานวนตวแปรทถกประกาศเปน register

ตวแปรเหลานกจะถกใชเหมอนกบตวแปรอตโนมตธรรมดา การประกาศตวแปรทใชในการนบตอไปนจะเปนการกาหนดตวแปรชอ counter เปนชนดจานวนเตมและถกใสเขาไปในรจสเตอรตวหนงของคอมพวเตอร โดยกาหนดคาเรมตนใหเทากบ 1

register int counter = 1;

Page 15: บทที่ 5 ฟังก์ชันstaff.cs.psu.ac.th/sathit/StructuredProgramming/ch5.pdf · บทที่ 5 ฟังก์ชัน วัตถุประสงค ์

..\PoP\sathit Edit 24062009 by Sathit Intajag 101

คยเวรด register ใชไดกบตวแปรทเปนแบบมระยะเวลาการเกบแบบอตโนมตเทานน คอมไพเลอรในปจจบนสามารถกาหนดภาษาเครองใหเปนแบบเหมาะสม (Optimizing compiler) โปรแกรมกจะมความสามารถทจะกาหนดตวแปร และสามารถทจะตดสนใจไดเองวาตวแปรใดควรถกกาหนดเปนตวแปรรจเตอรโดยทผเขยนโปรแกรมไมจาเปนตองประกาศเปนตวแปรรจสเตอร

คยเวรด extern และ static ใชเพอประกาศไอเดนตไฟเออรของตวแปรและฟงกชนทตองการใหมระยะเวลาการเกบแบบคงท ไอเดนตไฟเออรของการมระยะเวลาเกบแบบคงทจะเกดขนจากจดทถกประกาศ การประกาศตวแปรจะถกจดสรรและกาหนดคาเรมตนเมอโปรแกรมเรมประมวลผล สวนฟงกชนชอของฟงกชนจะปรากฏขนเมอโปรแกรมเรมประมวลผลเชนกน อยางไรกตามแมวาชอของตวแปรและชอฟงกชนปรากฏขนเมอโปรแกรมเรมประมวลผล แตไมไดหมายความวาไอเดนตไฟเออรเหลานสามารถเขาถงไดทวทงโปรแกรม ชวงเวลาการเกบและขอบเขตหรอชอใดๆทสามารถเรยกใชไดจะอธบายในเรองขอบเขตของไอเดนตไฟเออร

ไอเดนตไฟเออรแบบมระยะการเกบคงทมสองชนดคอ ไอเดนตไฟเออรทกาหนดไวขางนอกฟงกชนเชน ตวแปรภายนอก (Global variable) และชอฟงกชน สวนอกชนดหนงคอตวแปรทองถนทกาหนดไวภายในฟงกชนแตมการประกาศดวยตวกาหนดระดบการเกบ static

ตวแปรภายนอกจะถกประกาศไวนอกฟงกชน ตวแปรนจะมอายยนนานตราบเทาทโปรแกรมยงคงประมวลผลอย ตวแปรภายนอกและฟงกชนสามารถอางถงไดหลงจากประกาศไอเดนตไฟเออรนนๆไวแลวในไฟล นเปนเหตผลหนงของการใชตนแบบฟงกชนทจะเปนเสมอนการประกาศฟงกชนเปนตวแปรภายนอก เชนเมอเรารวมเอาเฮดเดอรไฟล stdio.h เขาไวในโปรแกรมกจะสามารถเรยกใชฟงกชน printf ได เนองจากมฟงกชนตนแบบทอยในเฮดเดอรไฟลถกวางไวตอนเรมตนของโปรแกรม ซงเปนการประกาศชอฟงกชน printf, scanf, และฟงกชนอนๆ ทอยใน stdio.h ใหโปรแกรมรบทราบวามการประกาศไวแลวสามารถเรยกใชไอเดนตไฟเออรตางๆจาก stdio.h ได

ตวแปรทองถนทประกาศดวยคยเวรด static เปนการแจงใหทราบเพยงวาตวแปรนจะเรยกใชไดเฉพาะในฟงกชนทประกาศ จะไมเหมอนกบตวแปรอตโนมตเสยทเดยว เนองจากตวแปรทองถนทประกาศเปนตวแปร static จะคงคาเอาไวตราบเทาทโปรแกรมยงคงประมวลผลอย โดยไมถกเอาออกจากหนวยความจา แตตวแปร static ทถกประกาศไวในฟงกชน ขอบเขตของมนกจะถกจากดอยเฉพาะในฟงกชนนนๆซงมขอบเขตเทากบตวแปรอตโนมต เพยงแตตวแปร static จะมอายยนกวาคอถกใสไวในหนวยความจาครงแรกทถกเรยกและจะอยไปตลอดจนจบโปรแกรม คาของตวแปร static จะไมสญหายเมอเรยกใชฟงกชนครงถดไป ในสเตจเมนตตอไปนเปนการกาหนดตวแปรทองถน count ทประกาศใหเปน static และมคาเรมตนเทากบหนง

static int count = 1; ตวแปรชนดทเปนตวเลขทงหมดของการประกาศดวย static จะถกกาหนดใหมคาเรมตนเทากบ 0

อยางอตโนมต ดงนนเมอเราตองการใหมคาเรมตนเปนคาอนกจะตองกาหนดคาขนมาเอง

Page 16: บทที่ 5 ฟังก์ชันstaff.cs.psu.ac.th/sathit/StructuredProgramming/ch5.pdf · บทที่ 5 ฟังก์ชัน วัตถุประสงค ์

..\PoP\sathit Edit 24062009 by Sathit Intajag 102

นอกจากนคยเวรด extern และ static จะมคณสมบตพเศษเมอถกใชเปนไอเดนตไฟเออรภายนอก ซงจะไดนาอธบายในหวขอตอๆ ไปทมเนองหาสอดคลองกน

5.11 กฎของขอบเขต

ขอบเขตทไอเดนตไฟเออรสามารถถกอางถงไดในแตละบลอกของโปรแกรม เชนเมอประกาศตวแปรทองถนขนมาใชในบลอกหนง มนสามารถทจะอางถงไดเฉพาะในบลอกทประกาศขนมาเทานน ขอบเขตของไอเดนตไฟเออรมอยสชนดคอขอบเขตของฟงกชน ขอบเขตของไฟล ขอบเขตของบลอกและขอบเขตของฟงกชนตนแบบ

ไอเดนตไฟเออรใดๆทประกาศนอกฟงกชนจะอยในขอบเขตของไฟล ไอเดนตไฟลเออรประเภทนสามารถอางถงไดในทกฟงกชนนบจากจดทไดประกาศเอาไวจนกระทงจบไฟล ซงไอเดนตไฟเออรในขอบเขตของไฟลประกอบดวย ตวแปรภายนอก นยามฟงกชน และตนแบบฟงกชนทกาหนดไวนอกฟงกชน

ไอเดนตไฟเออรตางๆทประกาศไวในบลอกจะอยในขอบเขตของบลอก ตวแปรทองถนทประกาศไวตอนเรมตนฟงกชนจะอยในขอบเขตของบลอก เชนเดยวกบพารามเตอรของฟงกชนซงถกจดเปนตวแปรทองถนของฟงกชนดวยเชนกน เมอมการสรางบลอกซอนกนไอเดนตไฟเออรของบลอกนอกทมชอเดยวกนกบไอเดนตไฟเออรทอยบลอกใน ไอเดนตไฟเออรทอยบลอกนอกจะถกซอนจนกระทงบลอกในจบการทางาน นหมายความวาในขณะทมการประมวลผลอยทบลอกใน บลอกในจะมองเหนคาของไอเดนตไฟเออรทองถน และไมเกยวของกบชอไอเดนตไฟเออรทเปนชอเดยวกนกบบลอกนอก ตวแปรทองถนทประกาศดวย static กยงคงอยในขอบเขตของบลอก ถงแมวาพวกมนจะคงคาเอาไวไดในขณะทโปรแกรมนนทางานอย ดงนนระยะเวลาการเกบจงไมสงผลกระทบกบขอบเขตของไอเดนตไฟเออร

ไอเดนตไฟเออรทประกาศในฟงกชนตนแบบ อยางทไดอธบายไวกอนหนานวาฟงกชนตนแบบไมจาเปนจะตองกาหนดชอตวแปรในรายการพารามเตอร โดยกาหนดเพยงชนดของตวแปรทจะอางถง เมอกาหนดชอตวแปรในรายการของพารามเตอรคอมไพเลอรกจะไมสนใจชอ นอกจากนไอเดนตไฟเออรทประกาศในตนแบบฟงกชน สามารถนากลบมาใชใหมในทใดๆของโปรแกรมกไดโดยไมกอใหเกดความสบสนตอการทางานของโปรแกรม เพอใหเขาใจเรองขอบเขตไอเดนตไฟเออรไดงายขน ใหศกษาขอบเขตของของตวแปรภายนอก ตวแปรอตโนมต และตวแปรอตโนมตทประกาศแบบ static ไดจากโปรแกรม Scope.c 1. /* Scope.c: To show Scope Rules of each identifier */ 2. #include <stdio.h> 3. void useLocal( void ); /* function prototype */ 4. void useStaticLocal( void ); /* function prototype */ 5. void useGlobal( void ); /* function prototype */ 6. 7. int x = 1; /* global variable */

Page 17: บทที่ 5 ฟังก์ชันstaff.cs.psu.ac.th/sathit/StructuredProgramming/ch5.pdf · บทที่ 5 ฟังก์ชัน วัตถุประสงค ์

..\PoP\sathit Edit 24062009 by Sathit Intajag 103

8. 9. /* function main begins program execution */ 10. int main() 11. { 12. int x = 5; /* local variable to main */ 13. 14. printf("local x in outer scope of main is %d\n", x ); 15. 16. { /* start new scope */ 17. int x = 7; /* local variable to new scope */ 18. 19. printf( "local x in inner scope of main is %d\n", x ); 20. } /* end new scope */ 21. 22. printf( "local x in outer scope of main is %d\n", x ); 23. useLocal(); /* useLocal has automatic local x */ 24. useStaticLocal(); /* useStaticLocal has static local x */ 25. useGlobal(); /* useGlobal uses global x */ 26. useLocal(); /* useLocal reinitializes automatic local x */ 27. useStaticLocal(); /* static local x retains its prior value */ 28. useGlobal(); /* global x also retains its value */ 29. 30. printf( "local x in main is %d\n", x ); 31. 32. return 0; /* indicates successful termination */ 33. } /* end main */ 34. 35. /* useLocal reinitializes local variable x during each call */ 36. void useLocal( void ) 37. { 38. int x = 25; /* initialized each time useLocal is called */ 39. 40. printf( "\nlocal x in a is %d after entering a\n", x ); 41. x++; 42. printf( "local x in a is %d before exiting a\n", x ); 43. } /* end function useLocal */ 44. 45. /* useStaticLocal initializes static local variable x only the first time 46. the function is called; value of x is saved between calls to this function */ 47. void useStaticLocal( void ) 48. { 49. /* initialized only first time useStaticLocal is called */ 50. static int x = 50; 51. 52. printf( "\nlocal static x is %d on entering b\n", x ); 53. x++; 54. printf( "local static x is %d on exiting b\n", x ); 55. } /* end function useStaticLocal */ 56. 57. /* function useGlobal modifies global variable x during each call */ 58. void useGlobal( void ) 59. { 60. printf( "\nglobal x is %d on entering c\n", x ); 61. x *= 10; 62. printf( "global x is %d on exiting c\n", x ); 63. } /* end function useGlobal */

ตวแปรโกลบอล(Global variable) x ในบรรทดท 7 ของโปรแกรม Scope.c ถกประกาศเปนชนดจานวนเตมและกาหนดคาเรมตนใหเทากบ 1 ตวแปรนถกประกาศอยนอกฟงกชน ทาใหทก

Page 18: บทที่ 5 ฟังก์ชันstaff.cs.psu.ac.th/sathit/StructuredProgramming/ch5.pdf · บทที่ 5 ฟังก์ชัน วัตถุประสงค ์

..\PoP\sathit Edit 24062009 by Sathit Intajag 104

ฟงกชนทนยามตอจากการประกาศ x สามารถอางถงตวแปรนได ยกเวนกรณทฟงกชนหรอบลอกใดๆประกาศตวแปรทองถนหรอตวแปรโลคอลชอ x ซ า ซงจะทาใหฟงกชนหรอบลอกนนมองไมเหนตวแปรโกลบอล x แตจะเหนตวแปรโลคอล x แทน ดงจะเหนไดจากฟงกชน main ทประกาศตวแปรโลคอล x ในบรรทดท 12 เปนชนดจานวนเตมและกาหนดคาเรมตนใหเทากบ 5 เมอพมพคาของ x ในบรรทดท 14 ตวแปรทถกพมพคอตวแปรโลคอลทมคาเทากบ 5 สวนตวแปรโกลบอล x ฟงกชน main จะมองไมเหน

เมอโปรแกรมทางานถงบรรทดท 16 ทมการสรางบลอกขนมาและบลอกนจบลงทบรรทด 20 ทบรรทด 17 มการประกาศตวแปรโลคอล x ในบลอกโดยกาหนดคาเรมตนใหเทากบ 7 ทาใหบลอกนมองไมเหนทงตวแปร x ทเปนโกลบอลและ x ทเปนตวแปรโลคอลของฟงกชน main เมอพมพคาตวแปร x ในบรรทดท 19 ฟงกชน printf กจะพมพคาของ x เทากบ 7 ไปทจอภาพ และตวแปร x ของบลอกนกหมดอายลงหลงจากบรรทดท 20 เนองจากขอบเขตของบลอกนจบลง ทาใหตวแปรโลคอลของบลอกถกเอาออกจากหนวยความจา ดงจะเหนไดจากการพมพในบรรทดท 22 ตวแปรโลคอล x ของฟงกชน main กกลบมาอกครง คอฟงกชน printf จะแสดงผลของ x มคาเทากบ 5

โปรแกรม Scope.c ประกาศฟงกชนตนแบบไวสามฟงกชนระหวางบรรทดท 3 ถง 5 การเรยกใชฟงกชน useLocal ทบรรทด 23 ทาใหตวแปรโลคอล x ของฟงกชน useLocal ทประกาศไวทบรรทด 38 ถกกาหนดขนในหนวยความจาพรอมกบคาเรมตนเทากบ 25 เมอประกาศชอตวแปรซ ากบตวแปรโกลบอล x ทาให useLocal เหมอนกบฟงกชน main คอมองไมเหนตวแปรโกลบอล x

เมอพมพคาทบรรทด 40 กจะแสดงคาเทากบ 25 ในบรรทดท 41 มการบวกคาตวแปรโลคอล x เขาไปอกหนง ทาใหการพมพคาทบรรทด 42 แสดงคา x เทากบ 26 และ useLocal จบลง ทาใหตวแปรโลคอล x ของฟงกชนนหมดอายหรอถกเอาออกจากหนวยความจาโดยอตโนมต

บรรทดท 24 มการเรยกฟงกชน useStaticLocal ทนยามไวในบรรทดท 47 ถง 55 ฟงกชนนไดประกาศตวแปรโลคอลแบบสแตตก x พรอมกบกาหนดคาเรมตนเทากบ 50 ไวทบรรทด 50 เมอประกาศชอตวแปรซ ากนทาใหฟงกชน useStaticLocal มองไมเหนตวแปรโกลบอล x เชนเดยวกบฟงกชน main และ useLocal เมอมการแสดงคาตวแปรสแตตก ฟงกชน printf แสดงคาของ x เทากบ 50 ไปทจอภาพ ในบรรทด 53 ตวแปรโลคอลแบบสแตตก x ถกบวกคาเพมเขาไปอกหนงทาให x มคาเทากบ 51 ดงทไดแสดงคาของ x ในบรรทด 54 เมอออกจากฟงกชน useStaticLocal แลวตวแปรโลคอลแบบสแตตกยงไมถกทาลาย แตฟงกชนอนจะมองไมเหนตวแปรน

บรรทดท 25 มการเรยกฟงกชน useGlobal ทนยามไวในบรรทดท 58 ถง 63 ฟงกชนนไมไดประกาศตวแปรใดๆ เมอมการเรยกใชตวแปร x เพอพมพคาในบรรทดท 60 ฟงกชน useGlobal จงมองเหนตวแปรโกลบอล x และแสดงคาของตวแปรนเทากบ 1 ไปทจอภาพ ทบรรทด 61 ไดนาตวแปรโกลบอล x มาคณดวย 10 แลวเกบคาไวในตวแปรน ทาให x ทถกแสดงคาใน

Page 19: บทที่ 5 ฟังก์ชันstaff.cs.psu.ac.th/sathit/StructuredProgramming/ch5.pdf · บทที่ 5 ฟังก์ชัน วัตถุประสงค ์

..\PoP\sathit Edit 24062009 by Sathit Intajag 105

บรรทด 62 พมพคา x เทากบ 10 ไปทจอภาพ เมอจบฟงกชน useGlobal ตวแปรโกลบอล x กยงไมถกทาลายเนองจากยงไมจบโปรแกรมและ x ยงเกบคา 10 เอาไว

รปท 5.5 ผลลพธของโปรแกรม Scope

บรรทดท 26 ถง 28 มการเรยกฟงกชนทงสามอกครง ในการเรยกฟงกชน useLocal ครงท

สองตวแปรโลคอล x มคาเหมอนเดมดงจะเหนไดจากรปท 5.5 เนองจากตวแปรโลคอลของฟงกชนจะถกประกาศขนมาใหมทกครงทมการเรยก ทาใหตวแปรโลคอล x ของฟงกชน useLocal มคาเรมตนเทากบ 25 ทกครงดวยเชนกน แตการเรยกฟงกชน useStaticLocal เปนครงทสองในบรรทด 27 ตวแปรโลคอลแบบสแตตกจะไมถกประกาศใหม เนองจากตวแปรนมอายตราบเทาทโปรแกรมยงประมวลผลอย ทาใหคาทแสดงไปทจอภาพเปนคาลาสดทตวแปรนเกบไว นนคอจะแสดงคาเทากบ 51 จากการเรยกฟงกชน printf ทบรรทด 52 และจากการเรยก printf ทบรรทด 54 ตวแปรโลคอลแบบสแตตกมคา 52 เมอออกจากฟงกชน useStaticLocal อกครง ตวแปรของฟงกชนนกยงไมถกทาลายแตมนมขอบเขตการเรยกใชอยเฉพาะในฟงกชนนเทานน

เมอมการเรยกฟงกชน useGlobal ทบรรทด 28 อกครงหนง ฟงกชน printf ทบรรทด 60 กจะพมพคาตวแปรโกลบอล x เทากบ 10 เมอแสดงคาตวแปรนอกครงในบรรทด 62 ตวแปรโกลบอล x กจะมคาเทากบ 100 ซงเปนผลจากการคณดวย 10 ทบรรทด 61 เมอออกจากฟงกชน useGlobal

ตวแปรโกลบอล x กยงคงมคาเทากบ 100 อย จะเหนวาตวแปรโกลบอลมอายเทากบตวแปรโลคอลแบบสแตตก แตตวแปรโกลบอลจะมขอบเขตทกวางกวา

บรรทดท 30 มการอางถงตวแปรโลคอล x ของฟงกชน main อกครงซงกยงคงมคาเทากบ 5

เชนเดม เมอโปรแกรม Scope.c ประมวลผลมาถงบรรทดท 32 มการประมวลผล return 0; ทาให

Page 20: บทที่ 5 ฟังก์ชันstaff.cs.psu.ac.th/sathit/StructuredProgramming/ch5.pdf · บทที่ 5 ฟังก์ชัน วัตถุประสงค ์

..\PoP\sathit Edit 24062009 by Sathit Intajag 106

ฟงกชน main สงคา 0 กลบไปแจงระบบปฏบตการวาโปรแกรมทางานเสรจสมบรณ ตวแปรทงหมดพรอมทงฟงกชนตางๆของโปรแกรมกจะถกเอาออกจากหนวยความจา

5.12 การเวยนบงเกด

โปรแกรมตางๆทไดอธบายไปแลวนน จะถกออกแบบใหประกอบดวยฟงกชนตางๆทเรยกฟงกชนอนเรยงตอกนเปนลาดบ แตมบางกรณทสามารถออกแบบใหฟงกชนเรยกตวเองแบบฟงกชนเวยนบงเกด (Recursive function) ฟงกชนนจะมการเรยกตวเองไมวาจะเปนการเรยกโดยตรงหรอเรยกโดยออมดวยการเรยกผานฟงกชนอน การออกแบบฟงกชนเวยนบงเกดเปนเรองทมความซบซอน แตในทนจะนาตวอยางงายๆของการเวยนบงเกดมาอธบาย เพอใหทราบถงพนฐานการทางาน

แนวคดของการแกปญหาแบบการเวยนบงเกด ลกษณะของปญหาจะมอยกรณหนงทเปนจดรวมและเปนสวนทนาไปสคาตอบ ซงจดรวมนจะถกเรยกวา “กรณพนฐาน(Base case)” ถาฟงกชนถกเรยกดวยกรณพนฐาน กจะเปนการเรยกครงสดทายหลงจากนนกจะไดคาตอบของปญหา แตถาฟงกชนถกเรยกดวยกรณอนทซบซอนกวา กจะมการแบงปญหาออกเปนสองสวน ปญหาในสวนแรกตองเปนสวนทนามาซงคาตอบหรอกรณพนฐาน และสวนทสองจะเปนทมาของการเวยนบงเกด โดยสวนนจะทาใหฟงกชนเรยกตวเองเพอใหปญหาลเขาสสวนแรก

เพอทาใหปญหาเวยนบงเกดงายขน สวนทสองของปญหาจะตองทาใหมรปแบบคลายกบปญหาเรมตนตอนทยงไมถกแบง อนทจรงจะไมเหมอนเสยทเดยวเพราะปญหาถกแบงออกไปแลว ดงนนสวนทคลายปญหาเรมตนคอรปแบบแตสารสนเทศภายในของปญหาจะเลกลง และปญหาในสวนทสองนจะเลกลงเรอยๆเนองจากกลไกการเรยกตวเองของฟงกชนเวยนบงเกด จงมกจะเรยกปญหาในสวนทสองนวา การเรยกแบบเวยนบงเกด (Recursive call) หรออยในขนของการเวยนบงเกด (Recursive step) การแกปญหาเวยนบงเกดดวยภาษาซ ขนของการเวยนบงเกดสวนใหญจะใชคยเวรด return เนองจากผลการเรยกตวเองในแตละครงจะถกนามารวมเขากบผลของกรณพนฐานของปญหาสวนแรก เพอคานวณคาตอบของฟงกชนเวยนบงเกดกอนทจะสงผลลพธกลบไปใหฟงกชนทเรยก

จากแนวคดของการแกปญหาเวยนบงเกดดวยฟงกชนเวยนบงเกด เมอฟงกชนเรยกตวเองในแตละครงดวยขนของการเวยนบงเกด กจะคลายกบลาดบในคณตศาสตร ดงนนเมอมการแบงปญหาออกเปนสองสวนคอ

1. สวนทเปนกรณพนฐาน จะเปนสวนของลาดบทกาหนดไดโดยตรงและ

2. ขนการเวยนบงเกด เปนลาดบใหมทจะถกกาหนดขนจากลาดบทเกดขนกอนหนาน

ปญหาทเปนกรณพนฐานจะใชกาหนดเงอนไขเรมตน สวนขนการเวยนบงเกดจะใชสรางลาดบถดไปจากเงอนไขเรมตน เมอสรางไดแลวกสามารถนาไปสรางลาดบถดไปไดอกตอไปเรอยๆ การเวยน

Page 21: บทที่ 5 ฟังก์ชันstaff.cs.psu.ac.th/sathit/StructuredProgramming/ch5.pdf · บทที่ 5 ฟังก์ชัน วัตถุประสงค ์

..\PoP\sathit Edit 24062009 by Sathit Intajag 107

บงเกดเปนแนวคดทสาคญทสามารถนาไปใชกาหนดลาดบของวตถ เซตของวตถทวไป และการดาเนนการกบวตถ

ลาดบเวยนบงเกด

ลาดบ S เปนรายการของวตถทถกระบอยางเปนอนดบ โดยมวตถชนทหนง ชนทสอง ทสามไปเรอยๆ เมอกาหนดให S(k) แทนวตถอนดบท k ทอยในลาดบ S ลาดบถกกาหนดแบบวนซ าโดยเรมจากคาแรกของลาดบ สวนคาทตามมาในลาดบจะถกกาหนดโดยอนดบกอนหนาน

ตวอยางท 1 ลาดบ S ถกกาหนดอยางวนซ าโดย

1. S(1) = 2

2. S(n) = 2S(n-1) สาหรบ n≥2

จากขอท 1 หรอ S(1) ไดกาหนดวตถชนแรกเทากบ 2 ซงขอท 1 นกคอคาเรมตนทเปนกรณพนฐานของปญหา สวนขอท 2 เปนวตถชนท n ใดๆ กคอขนของการเวยนบงเกด เชนเมอ n=2 กจะกาหนดไดวา S(2) = 2S(2-1) = 2S(1) เมอ S(1) = 2 กจะไดคา S(2) = 4 และจากขอท 2 เชนกน

(3) 2 (3 1) 2 (2) 2(4) 8S S S= − = = = สวนวตถในอนดบถดไปกสามารถคานวณไดในลกษณะเดยวกน เราจะเหนวาลาดบ S คอ 2, 4, 8, 16, 32, ... ในตวอยางท 1 เปนการกาหนดคาของลาดบดวยเทอมหรอพจนกอนหนา ซงถกเรยกวา “ความสมพนธเวยนบงเกด (Recurrence relation)”

อลกอรทมเวยนบงเกด

ในตวอยางท 1 ไดแสดงใหเหนการเวยนบงเกดของลาดบ S เมอตองการเขยนโปรแกรมคอมพวเตอรเพอหาคาตอบของลาดบ S(n) สาหรบจานวนเตมบวก n ใดๆ ซงมอยสองวธคอ

วธทหนง ถาเราตองการหา S(12) กสามารถเรมกบกรณพนฐาน S(1) = 2 และทาการคานวณ S(2) S(3) และคาอนๆ อยางเชนทไดอธบายในตวอยางท 1 จนกระทงสดทายเปนการคานวณ S(12) แนนอนวาวธนเปนการวนซ าในรปแบบของคาสงลปหรอวงวน อลกอรทมวงวนทถกเขยนดวยฟงกชนของภาษาซมดงน

อลกอรทม 1 การแทนลาดบดวยการวนซ า 1. int S(int n) /* เปนการคานวณแบบซาๆของจานวนเตม S(n) สาหรบลาดบ S ในตวอยางท 19 */ 2. { 3. int j; /* ดชนของวงวน */ 4. int CurrentValue; /* คาปจจบน */ 5. 6. if (n==1) 7. S = 2; 8. else 9. { 10. j = 2; 11. CurrentValue = 2; 12. while (j <= n) 13. { 14. CurrentValue = 2*CurrentValue; 15. j = j + 1; 16. }

Page 22: บทที่ 5 ฟังก์ชันstaff.cs.psu.ac.th/sathit/StructuredProgramming/ch5.pdf · บทที่ 5 ฟังก์ชัน วัตถุประสงค ์

..\PoP\sathit Edit 24062009 by Sathit Intajag 108

17. } 18. S = CurrentValue; 19. return S; 20. } เงอนไขพนฐานท n=1 ถกคานวณในสวนของเงอนไข if และสวนของ else จะถกคานวณเมอ n>1

โดยการกาหนดคาดชนเรมตน และคา CurrentValue เพอใชในการสะสมคาในขนของการวนซ า จะเหนวาในบรรทดท 13 กคอการคานวณ S(n) = 2S(n-1) ทถกวนซ าอยในวงวน while ซงจะวนจนกระทง j>n

วธทสองทใชคานวณ S(n) โดยใชนยามการเวยนบงเกดของลาดบ S โดยตรง อลกอรทมเวยนบงเกดทใชคานวณลาดบนสามารถเขยนดวยภาษาซไดดงตอไปน

อลกอรทม 2 การแทนลาดบดวยนยามการเวยนบงเกด 1. int S_recursive(int n) 2. { 3. int S; 4. 5. if (n == 1) 6. S = 2; 7. else 8. S = 2*S_recursive(n-1); 9. return S; 10. }

จะเหนวาอลกอรทม 2 เปนฟงกชนทประกอบดวยประพจนเงอนเดยวคอ if-else เพอทาความเขาใจการทางานของฟงกชนน ใหลองพจารณาการทางานของ S(3) ฟงกชนจะเรมจากรบคาขอมลทปอนเขาสฟงกชนหรออนพตของฟงกชน ซงพารามเตอรทรบคาของฟงกชนนคอ n = 3 ซงมการตรวจสอบเงอนไขในบรรทดท 5 แต n ไมไดเทากบ 1 ดงนนจงขามไปทางานทสวนของ else ในสวนนเองกจกรรมการคานวณ S(3) จะถกหยดหรอถกแขวนไวจนกระทงไดผลลพธของ S(2) สวน S(3) ทถกแขวนไวนนแททจรงคอมพวเตอรจะเกบ S(3) ไวในหนวยความจาแบบสแตก เมอ n = 3 ฟงกชนจะเกบ S(3) ซงในทนกคอ S_recursive(3) ดงนนในบรรทดท 8 ฟงกชนถกเรยกดวยตวแปร

n = 2 นนคอ S_recursive(3-1) หรอ S_recursive(2) กจะถกเกบไวในหนวยความจาสแตก และฟงกชนจะถกเรยกอกครงดวยตวแปร n = 1 หรอ S_recursive(2-1) ซงทาใหเงอนไข if เปนจรงเนองจาก n = 1 ทาใหมการกาหนดคา S = 2 และบรรทดท 9 เรมทางาน นนคอเอาคาทอยในสแตกออกมาคานวณคอ S_recursive(2) และ S_recursive(3) โดยลาดบ จงทาใหไดผลลพธ S(3)

เมอพจารณาสงทไดจากอลกอรทมท 1 และ 2 ทคานวณลาดบเดยวกน ในอลกอรทมท 2 ทเปนอลกอรทมการเวยนบงเกดจะมจานวนบรรทดหรอจานวนสเตจเมนตทนอยกวา เนองจากไมตองมวงวน while หรอ for ทใชคานวณลาดบ แตการประมวลผลอลกอรทมท 2 จะมความซบซอนมากกวาการใชวงวนในอลกอรทมท 1 เนองจากอลกอรทมเวยนบงเกดถกจดการดวยตวแปลภาษา ดงนนอลกอรทมท 2 สามารถนาไปใชไดกตอเมอภาษาคอมพวเตอรนนๆ รองรบการทางานแบบ

Page 23: บทที่ 5 ฟังก์ชันstaff.cs.psu.ac.th/sathit/StructuredProgramming/ch5.pdf · บทที่ 5 ฟังก์ชัน วัตถุประสงค ์

..\PoP\sathit Edit 24062009 by Sathit Intajag 109

เวยนบงเกดอยางภาษาซ ปาสคาล เปนตน แตเมอพจารณาถงหนวยความจาทใช อลกอรทมเวยนบงเกดจะใชหนวยความจาตามความยาวของลาดบ นนคอถา n มจานวนมากอลกอรทมนกจะใชหนวยความจามาก ถา n มากเกนไปจนหนวยความจาคอมพวเตอรรองรบไมไดกจะเกดสภาวะสแตกทวม (Stack overflow) เพราะหนวยความจาไมเพยงพอทจะประมวลผลตอไป แตถาอลกอรทมท 1 จะใชหนวยความจาคงทไมขนอยกบ n

อยางไรกตามการเวยนบงเกดรปแบบทเปนธรรมชาตมากกวาแบบวนซ า สาหรบการจดการกบปญหาทซบซอนมากๆ (เมอไมใชอลกอรทมเวยนบงเกด) อยางปญหาการคานวณคาสาหรบลาดบใดๆ ทตวลาดบเองถกนยามแบบเวยนบงเกดจะมความเหมาะสมมากทจะแทนลาดบเหลานนดวยอลกอรทมเวยนบงเกด

5.15 การเวยนบงเกดกบการวนซา

อลกอรทมของทงการวนซ าและการเวยนบงเกดตางกอาศยโครงสรางการควบคม ขอเสยของการเวยนบงเกดมหลายอยางดวยกน อนเนองมาจากกลไกการเรยกฟงกชนซ าๆ ทาใหเกดความซบซอนโดยไมจาเปน สนเปลองทงเวลาและหนวยความจา นนคอทงสองอยางนจะโตขนตามจานวนขอมล ในขณะทการวนซ ามเพยงเรองเวลาทใชหนวยประมวลผลกลางทโตตามจานวนขอมล แตจะใชหนวยความจาคงท การวนซ า การเวยนบงเกด

ใชโครงสรางแบบวนซ า ใชโครงสรางการเลอกเพอใหเกดการทาซ าโดยการเรยกฟงกชน

เงอนไขการหยดการทาซาเกดขนเมอเงอนไขความตอเนองของการวนซ าเปนเทจ

เงอนไขการหยดเกดจากเงอนไขของกรณพนฐานเปนจรง