540 likes | 718 Views
ฟังก์ชัน. อ.สุธน แซ่ว่อง ภาควิชาวิศวกรรมคอมพิวเตอร์. 1. function. ข้อมูล input. ผลลัพธ์ output. กล่องดำ. square root computation. ป้อนข้อมูล 16.0. ผลลัพธ์ที่ได้คือ 4.0. ฟังก์ชันคืออะไร. ฟังก์ชัน หรือ Procedure คือ ชุดของ statement ที่ทำงานอย่างใดอย่างหนึ่ง และมีชื่อเรียก
E N D
ฟังก์ชัน อ.สุธน แซ่ว่อง ภาควิชาวิศวกรรมคอมพิวเตอร์ 1
function ข้อมูล input ผลลัพธ์ output กล่องดำ square root computation ป้อนข้อมูล 16.0 ผลลัพธ์ที่ได้คือ 4.0 ฟังก์ชันคืออะไร ฟังก์ชัน หรือ Procedureคือ • ชุดของ statement ที่ทำงานอย่างใดอย่างหนึ่ง และมีชื่อเรียก • ส่วนอื่นของโปรแกรมสามารถเรียกใช้งานฟังก์ชันได้ เช่น
ฟังก์ชันในภาษา C • โปรแกรมภาษา C ประกอบไปด้วยหนึ่งฟังก์ชัน (main) หรือมากกว่า • แต่ละฟังก์ชันประกอบไปด้วยหนึ่ง statement หรือมากกว่า • ภาษา C แบ่งฟังก์ชันเป็น 2 แบบ • ฟังก์ชันมาตรฐานใน C • ฟังก์ชันที่สร้างโดยผู้เขียนโปรแกรม FUNCTIONS IN C C STANDARD LIBRARY PROGRAMMER DEFINED FUNCTION
เนื้อหา • การเรียกใช้งานฟังก์ชัน • การเขียนฟังก์ชันเอง • รายละเอียดเกี่ยวกับฟังก์ชัน • การส่งผ่านอาเรย์ไปยังฟังก์ชัน ภาควิชาวิศวกรรมคอมพิวเตอร์ มหาวิทยาลัยสงขลานครินทร์
นิพจน์ ฟังก์ชันมี Type เหมือนนิพจน์ เรียกใช้ฟังก์ชันอย่างถูกต้อง การเรียกใช้ฟังก์ชัน ภาควิชาวิศวกรรมคอมพิวเตอร์มหาวิทยาลัยสงขลานครินทร์
ฟังก์ชันมี Type (เหมือนนิพจน์ทั่วไป) • นิพจน์มี Type สามารถนำไปกำหนดค่าให้กับตัวแปร หรือ เขียนทิ้งไว้เฉยๆ • การเรียกใช้ฟังก์ชันแต่ละครั้งมี Type สามารถนำไปกำหนดค่าให้ตัวแปร หรือ เขียนทิ้งไว้เฉยๆ • x = 1; • 1; • a = f(1); • f(1); ข้อสังเกตุ: การเรียกใช้ฟังก์ชันจะขึ้นต้นด้วยชื่อของฟังก์ชันตามด้วย ( และ ) โดยภายในวงเล็บเป็น พารามิเตอร์ ประกอบการทำงานของฟังก์ชันนั้นๆ ภาควิชาวิศวกรรมคอมพิวเตอร์ มหาวิทยาลัยสงขลานครินทร์
การเรียกใช้ฟังก์ชัน • ต้องรู้ต้นแบบของฟังก์ชัน • การเรียกใช้ฟังก์ชันมี Type เป็น int • การเรียกใช้ฟังก์ชันมี Type เป็น double • เรียกใช้ด้วยชื่อ และตามด้วยพารามิเตอร์ที่มี Type ถูกต้อง • จำนวนพารามิเตอร์ และลำดับจะต้องถูกต้อง • ฟังก์ชันมักให้ผลลัพธ์ โดยนำผลลัพธ์มาใช้ โดยให้ดู Type ให้ถูกต้อง • /* prototype samples */ • int add(int, int); • double abs(double); • add(3, 2) • abs(2.0) • int x; • x = add(3,2); • printf("%.1f", abs(2.0)); ภาควิชาวิศวกรรมคอมพิวเตอร์ มหาวิทยาลัยสงขลานครินทร์
การเรียกใช้ฟังก์ชัน อันไหนถูกอันไหนผิด? /* given prototypes */ double foo(int); double a; int x; /* right or wrong? */ foo(3); foo(x); a = foo(2); a = foo(x) + 1 foo(3, 1) foo(3 + 1) • /* given prototypes */ • int foo(int); • int x; • /* right or wrong? */ • foo(3); • x = foo(3); • x + foo(3); • foo(foo(2)); • foo(foo + 2); • foo(2) = x; ภาควิชาวิศวกรรมคอมพิวเตอร์ มหาวิทยาลัยสงขลานครินทร์
C Standard Library • ฟังก์ชันพื้นฐานที่มีให้เรียกใช้อยู่แล้วในภาษา C • ประกอบด้วยฟังก์ชันเกี่ยวกับ • disk I/O (input/output) ex. printf(), scanf(), … • string manipulation ex. strlen(), strcpy(), … • mathematics ex. sqrt(), sin(), cos(), … • etc.. • สามารถเรียกใช้งานได้เลย แต่ต้องมีการ include header file ที่นิยามฟังก์ชันนั้นๆไว้เช่น จะใช้ printf(), scanf() ต้องเขียน #include "stdio.h" จะใช้ sqrt(), sin(), cos() ต้องเขียน #include "math.h" etc.
ตัวอย่างการหาค่ารากที่สองตัวอย่างการหาค่ารากที่สอง โปรแกรมหาค่ารากที่สอง โดยใช้ฟังก์ชัน sqrt() ใน math.h ต้นแบบ double sqrt(double num); ให้ค่า num #include <stdio.h> #include <math.h> int main() { printf("%f", sqrt(16.0)); }
ตัวอย่างการคำนวณเลขยกกำลังตัวอย่างการคำนวณเลขยกกำลัง โปรแกรมแสดง 10 ยกกำลัง 1 ถึง 5 โดยเรียกใช้ฟังก์ชัน pow() ใน math.h ต้นแบบ double pow(double base, double exp); ให้ค่า baseexp #include <stdio.h> #include <math.h> int main() { double x=10.0, y =1.0; do { printf("%f", pow(x,y)); y++; } while (y < 6); }
รู้หรือไม่ว่า … • ภาษา C สามารถแปลงข้อมูล Type ต่างๆ ไปมาได้ • ใช้อย่างระมัดระวังในกรณีที่แปลง Type ที่มีขนาดใหญ่กว่า เป็น Type ที่มีขนาดเล็กลง อาจมีปัญหา • ในกรณีที่แปลงจาก Type เล็กเป็น Type ใหญ่ สามารถทำได้ และมักจะไม่ก่อให้เกิดปัญหา • /* it’s work */ • /* but this is bad */ • float foo(int); • char c; • c = foo(10); • foo(10.0); • /* this is ok */ • foo('a'); • double d; • d = foo(10); ภาควิชาวิศวกรรมคอมพิวเตอร์ มหาวิทยาลัยสงขลานครินทร์
EXCERCISE ภาควิชาวิศวกรรมคอมพิวเตอร์ มหาวิทยาลัยสงขลานครินทร์
ไขคำถามในใจ ??? • ปกติเราจะเรียกใช้ฟังก์ชัน ต้องเขียนต้นแบบก่อนหรือไม่ • เราจะรู้ได้อย่างไร ว่า ต้นแบบของฟังก์ชัน เช่น printfเป็นอย่างไร • พารามิเตอร์ของฟังก์ชันเป็นอย่างอื่นได้อีกหรือไม่ นอกเหนือจาก char, int, long, float, double ภาควิชาวิศวกรรมคอมพิวเตอร์ มหาวิทยาลัยสงขลานครินทร์
สามส่วนของฟังก์ชัน นิยามฟังก์ชัน วงจรชีวิตของฟังก์ชัน การเขียนฟังก์ชันด้วยตนเอง ภาควิชาวิศวกรรมคอมพิวเตอร์มหาวิทยาลัยสงขลานครินทร์
3 ส่วนของฟังก์ชัน • ต้นแบบของฟังก์ชัน • ชื่อ • พารามิเตอร์ ตั้งแต่จำนวน ลำดับและชนิด • ชนิดของการเรียกใช้ฟังก์ชัน • นิยามของฟังก์ชัน • ส่วนหัวจะเหมือนต้นแบบของฟังก์ชัน แต่มีการระบุชื่อตัวแปรสำหรับพารามิเตอร์แต่ละตัว • หลังส่วนหัวจะตามด้วย { และ } โดยภายในบรรจุคำสั่งต่างๆ ไว้ • การเรียกใช้ฟังก์ชัน • int foo(int, int); • name => foo • parameters=> int, int • expression type => int • int foo(int a, int b){ • ...statments... • } • int x; • x = foo(2, 5); ภาควิชาวิศวกรรมคอมพิวเตอร์ มหาวิทยาลัยสงขลานครินทร์
ต้นแบบของฟังก์ชัน • รูปแบบ • return-typeหรือชนิดข้อมูลที่จะส่งค่ากลับได้แก่void, int, double, char, ... • function-nameชื่อของฟังก์ชัน • parameter-listจำนวนพารามิเตอร์ที่ฟังก์ชันต้องการ • แต่ละพารามิเตอร์ประกอบด้วย ชนิดตัวแปรและชื่อตัวแปร • แต่ละพารามิเตอร์แยกด้วยเครื่องหมาย" ," ตัวอย่างint add (int a, int b) ; return-typefunction-name (parameter-list) ;
นิยามของฟังก์ชัน • ส่วนหัวจะมีลักษณะคล้ายต้นแบบ เพียงแต่มีการระบุชื่อตัวแปรในพารามิเตอร์ • การระบุชื่อ จะกระทำตามไวยกรณ์ของการประกาศตัวแปร • พารามิเตอร์ทำตัวเหมือนตัวแปรที่ถูกแทนค่า เมื่อฟังก์ชันถูกเรียกใช้ • aแทนค่าด้วย 2 • aแทนค่าด้วย 7 • aแทนค่าด้วย 5 • ค่าของการเรียกใช้งานฟังก์ชัน คือค่าที่กำหนดไว้กับ return • int foo(int); • int foo(int a){ • int x; • x = a + 3; • return x; • } • int c; • c = foo(2); • c = foo(7); • c = foo(5); ภาควิชาวิศวกรรมคอมพิวเตอร์ มหาวิทยาลัยสงขลานครินทร์
นิยามของฟังก์ชัน • นิยามฟังก์ชันเป็นการเขียนรายละเอียดการทำงานของฟังก์ชันนั้นๆ • ประกอบด้วยส่วนของ header และalgorithm header จะมีการเขียนเหมือน ต้นแบบฟังก์ชัน แต่ไม่มี; algorithm เขียนอยู่ภายใน { } • รูปแบบ ถ้า return-typeไม่ใช่ voidต้องมีการส่งค่ากลับ โดยใช้คำสั่ง return ตามด้วยค่าที่จะส่งกลับ return-typefunction-name (parameter-list) { รายละเอียดการทำงาน }
คำสั่ง return • ใช้เพื่อสั่งให้ฟังก์ชันจบการทำงาน • หากคำสั่ง return อยู่ในบรรทัดสุดท้ายของฟังก์ชัน และไม่มีการกำหนดค่าให้กับการเรียกใช้ฟังก์ชัน คำสั่งนี้สามารถละได้ • หากการเรียกใช้ฟังก์ชันมีชนิด ค่าของการเรียกใช้จะเท่ากับ ค่าที่กำหนดไว้กับคำสั่ง return • ค่าที่กำหนดไว้กับคำสั่ง return สามารถเป็นนิพจน์แบบใดก็ได้ เพียงแต่มีชนิดตามที่กำหนดไว้ในส่วนหัวของฟังก์ชัน • void foo(){ • return; • } • int bar(){ • return 3; • } • int daa(){ • int x = 3; • return x; • } ภาควิชาวิศวกรรมคอมพิวเตอร์ มหาวิทยาลัยสงขลานครินทร์
ตัวอย่างฟังก์ชันที่ไม่มี return void check(int result) { if(result < 0) printf("negative"); else if(result == 0) printf("zero"); else printf("positive"); } • ตัวอย่างฟังก์ชันที่มี return int add (int a, int b) { int result; result = a + b; return result; }
การใช้งาน 3 ส่วนในโปรแกรม • ต้นแบบของฟังก์ชัน เขียนไว้ในส่วนหัวของโปรแกรม • อาจไม่ต้องเขียนต้นแบบของฟังก์ชัน หากเขียนนิยามของฟังก์ชันไว้ในส่วนหัว แต่จะทำให้โค้ดอ่านยาก • การเรียกใช้จะต้องกระทำหลังการเขียนต้นแบบหรือนิยามเท่านั้น • คอมไพเลอรจำเป็นต้องทราบข้อมูลเกี่ยวกับฟังก์ชันตามที่ได้ระบุไว้ในต้นแบบ เพื่อตรวจสอบความถูกต้องของการเรียกใช้ • #include<stdio.h> • //prototype • int add(int, int); • main(){ • int x; • //invoking • x = add(3, 2); • printf("%d\n", x); • } • //definition • int add(int a, int b){ • return a + b; • } ภาควิชาวิศวกรรมคอมพิวเตอร์ มหาวิทยาลัยสงขลานครินทร์
#include <stdio.h> int square(int x); int main() { int a=2,b; b = square(a); printf("b = %d \n",b); return 0; } int square(int x) { int y; y = x*x; return y; } ต้นแบบฟังก์ชัน function prototype อากิวเมนต์ เรียกใช้งานฟังก์ชัน call function พารามิเตอร์ นิยามฟังก์ชัน function definition ตัวอย่าง5.7 ชื่อต่างๆเกี่ยวกับฟังก์ชัน
I, R main get_volt V ตัวอย่าง จงเขียนโปรแกรมสำหรับหาค่าศักย์ไฟฟ้าซึ่งมีสมการดังนี้ V = I*R โดยที่ V คือ ค่าศักย์ไฟฟ้า , I คือ ค่ากระแสไฟฟ้า ส่วน R คือ ค่าความ ต้านทาน และทั้งสามค่านี้เป็นจำนวนจริง โดยกำหนดให้ส่วนที่คำนวณ ค่า V อยู่ในฟังก์ชัน get_volt สำหรับส่วนที่รับค่า I และ R จากผู้ใช้ รวม ทั้งส่วนที่แสดงผลลัพธ์ของค่า V ให้อยู่ในฟังก์ชัน main
#include <stdio.h> float get_volt(float i, float r); int main() { float i,r,v; printf("Enter I : "); scanf("%f", &i); printf("Enter R : "); scanf("%f", &r); printf("V = %.1f\n", get_volt(i, r)); return 0; } float get_volt(float i, float r) { float v = i * r; return v; }
วงจรชีวิตของฟังก์ชัน • นิยามของฟังก์ชันเป็นเหมือนพรหมลิขิตที่ถูกเขียนอยู่ในหนังสือ • เมื่อมีการเรียกใช้ฟังก์ชัน จะเกิดชีวิตใหม่ ที่จะดำเนินชีวิตตามพรหมลิขิต • เมื่อดำเนินไปถึงเป้าหมาย ชีวิตก็จะสิ้นสุดลง • ตัวอย่างด้านขวา มีฟังก์ชัน 3 ชีวิต • ชีวิตที่ 1 มี a=2, x=5 และจะสลายหายไป เมื่อชีวิตนี้จบสิ้น เหลือเพียงผลลัพธ์จากคำสั่ง return • int foo(int); • int foo(int a){ • int x; • x = a + 3; • return x; • } • int c; • c = foo(2); // born&die • c = foo(7); // born&die • c = foo(5); // born&die ภาควิชาวิศวกรรมคอมพิวเตอร์มหาวิทยาลัยสงขลานครินทร์
รู้หรือไม่ว่า … • ตัวแปรในภาษา C เมื่อถูกประกาศขึ้น จะมีการจองหน่วยความจำเพื่อเก็บข้อมูล ชื่อของตัวแปรเป็นเพียงชื่อเล่นเอาไว้อ้างอิงถึงหน่วยความจำที่ถูกจองเท่านั้น • ตัวแปรที่ถูกประกาศในฟังก์ชัน ชื่อของมันจะรู้จักเฉพาะในฟังก์ชันนั้นเท่านั้น • void foo(){ • int x; • } • void bar(){ • x = 3; //***wrong • } ภาควิชาวิศวกรรมคอมพิวเตอร์ มหาวิทยาลัยสงขลานครินทร์
EXCERCISE ภาควิชาวิศวกรรมคอมพิวเตอร์ มหาวิทยาลัยสงขลานครินทร์
ไขคำถามในใจ ??? • ตันแบบของฟังก์ชัน และส่วนหัวของนิยามของฟังก์ชันคล้ายกัน ทำไมต้องเขียนทั้งสองอย่าง • เราระบุชื่อตัวแปรของพารามิเตอร์ของฟังก์ชัน ที่ต้นแบบของฟังก์ชันได้หรือไม่ • ทำไมตัวแปรที่ประกาศในฟังก์ชัน ต้องรู้จักเพียงในฟังก์ชันนั้นเท่านั้น ภาควิชาวิศวกรรมคอมพิวเตอร์ มหาวิทยาลัยสงขลานครินทร์
ทำไมต้องเขียนฟังก์ชันทำไมต้องเขียนฟังก์ชัน Procedural Programming ขอบเขตของตัวแปร รายละเอียดเพิ่มเติมเกี่ยวกับฟังก์ชัน ภาควิชาวิศวกรรมคอมพิวเตอร์มหาวิทยาลัยสงขลานครินทร์
โปรแกรมที่ไม่มีการจัดระเบียบโครงสร้างโปรแกรมที่ไม่มีการจัดระเบียบโครงสร้าง #include <stdio.h> main() { int first, second, third; printf("\n f(X) = 3X + 10 if X > 0\n"); printf("\n f(X) = 10 if X = 0\n"); printf("\n Enter 3 values:"); scanf("%d %d %d", &first, &second, &third); if (first > 0) printf("f(%d) is %d", first, 3*first+10); else printf("f(%d) is 10", first); if (second > 0) printf("f(%d) is %d", second, 3*second + 10); else printf("f(%d) is 10", second); if (third > 0) printf("f(%d) is %d", third, 3*third + 10); else printf("f(%d) is 10", third); } Code programซ้ำซ้อน คำนวณ first คำนวณ second คำนวณ third
แนวคิดเพื่อปรับปรุง (แนวคิดเรื่องฟังก์ชัน): ชุด statement เดียวกันอาจมีการใช้งานหลายแห่งในโปรแกรม ทำให้ต้อง copy หลายครั้ง จึงเกิดแนวคิดที่จะรวบรวมชุด statement นี้เข้าไว้ที่เดียวกัน และมีการเรียกใช้งานเมื่อต้องการ เกิดเป็น Procedure
โปรแกรมที่จัดระเบียบโครงสร้างแล้วโปรแกรมที่จัดระเบียบโครงสร้างแล้ว #include <stdio.h> void fx(int x); main() { int first, second, third; printf("\n F(X) = 3X + 10 if X > 0\n"); printf("\n F(X) = 10 if X = 0\n"); printf("\n Enter 3 values:"); scanf("%d %d %d", &first, &second, &third); fx(first); fx(second); fx(third); } void fx(int x) { if (x > 0) printf("f(%d) is %d\n", x, (3*x) + 10); else printf("f(%d) is 10\n", x); } • รวมการทำงานแบบเดียวกันไว้ด้วยกัน • เปลี่ยนแปลงตัวแปร xในการเรียกใช้งานแต่ละครั้ง
โปรแกรมที่จัดระเบียบโครงสร้างอย่างดีแล้วโปรแกรมที่จัดระเบียบโครงสร้างอย่างดีแล้ว #include <stdio.h> void fx(int x); main() { int first, second, third; printf("\n F(X) = 3X + 10 if X > 0\n"); printf("\n F(X) = 10 if X = 0\n"); printf("\n Enter 3 values\n"); scanf("%d %d %d", &first, &second, &third); printf("f(%d) is %d\n", fx(first)); printf("f(%d) is %d\n", fx(second)); printf("f(%d) is %d\n", fx(third)); } void fx(int x) { if (x > 0) return (3*x) + 10; else return 10; } • โปรแกรมทำหน้าที่คำนวณ แยกออกจากการแสดงผล
Program main program procedure ลำดับการทำงาน จุดที่เรียกใช้งาน Procedural Programming รูปแบบ: ชุด statements สามารถรวมไว้ในที่ที่หนึ่งแยกจากส่วนของ main และมีการใช้ procedure call เพื่อเรียกใช้งาน ชุด statements นั้น ข้อดี : • ซ่อนรายละเอียดซับซ้อนไว้ในฟังก์ชัน ทำให้โปรแกรม main ง่ายในการทำความเข้าใจ • ลดความซ้ำซ้อนของส่วนโปรแกรมที่เหมือนๆกันไว้ในฟังก์ชัน • การหาข้อผิดพลาดของโปรแกรมง่ายขึ้น โดยแยกระหว่างส่วน main หรือว่า procedures ใด
ขอบเขตของตัวแปร ตัวแปรภายใน - ตัวแปรที่ประกาศในฟังก์ชันใด จะรู้จักเฉพาะในฟังก์ชันนั้นๆ ตัวแปรภายนอก - ตัวแปรที่ประกาศนอกฟังก์ชัน (รวมถึงฟังก์ชัน main) จะรู้จักในทุกฟังก์ชันที่เขียนถัดจากการประกาศตัวแปร
ขอบเขตของตัวแปรภายในฟังก์ชันขอบเขตของตัวแปรภายในฟังก์ชัน #include <stdio.h> void my_func(); int main() { double x = 1.1; my_func(); printf("In main, x = %d \n",x); return 0; } void my_func() { double x; x = 2.5; printf("In my_func, x = %d \n",x); } ผลลัพธ์ In my_func, x = 2.5 In main, x = 1.1
ขอบเขตของตัวแปรภายนอกฟังก์ชันขอบเขตของตัวแปรภายนอกฟังก์ชัน #include <stdio.h> double x; void my_func(); int main() { x = 1.1; my_func(); printf("In main, x = %d \n",x); return 0; } void my_func() { x = 2.5; printf("In main, x = %d \n",x); } ผลลัพธ์ In my_func, x = 2.5 In main, x = 2.5
สรุปขอบเขตของตัวแปร #define MAX 950 void one(intanarg, double second) { intonelocal; … } #define LIMIT 200 intfun_two(int one, char anarg) { intlocalvar; … } int main(void) { intlocalvar; … }
EXCERCISE ภาควิชาวิศวกรรมคอมพิวเตอร์ มหาวิทยาลัยสงขลานครินทร์
ไขคำถามในใจ ??? • ทำไม ฟังก์ชันที่เขียนขึ้น ต้องคืนค่ากลับมาพิมพ์ในฟังก์ชัน main ทั้งๆ ที่สามารถพิมพ์ในฟังก์ชันนั้นได้เลย • ถ้าเราใช้ตัวแปรภายนอกได้ ใช้แต่ตัวแปรภายนอกได้ไหม ง่ายดี ฟังก์ชันอื่นสามารถใช้งานได้เลย ไม่ต้อง return ให้ยุ่งยาก ภาควิชาวิศวกรรมคอมพิวเตอร์ มหาวิทยาลัยสงขลานครินทร์
การส่งอีลีเมนต์ของอาเรย์ไปยังฟังก์ชันการส่งอีลีเมนต์ของอาเรย์ไปยังฟังก์ชัน การส่งทั้งอาเรย์ไปยังฟังก์ชัน การส่งอาเรย์สองมิติ หรือมากกว่า ไปยังฟังก์ชัน การส่งอาเรย์ไปยังฟังก์ชัน ภาควิชาวิศวกรรมคอมพิวเตอร์มหาวิทยาลัยสงขลานครินทร์
การส่งอีลีเมนต์ของอาเรย์ไปยังฟังก์ชันการส่งอีลีเมนต์ของอาเรย์ไปยังฟังก์ชัน • อาร์กิวเมนต์ของฟังก์ชัน จะถูกหาค่า (evaluate) ก่อนที่จะส่งค่านั้นให้กับฟังก์ชัน • หากส่งค่าคงที่ เช่น 1 ซึ่งเราทราบค่าอยู่แล้ว ก็สามารถส่งค่านั้นไปยังฟังก์ชันได้เลย • หากส่งค่าเป็นตัวแปร เช่น x ค่าของ x จะถูก evaluate ก่อนส่ง • เช่นเดียวกันกับอีลีเมนต์ของอารย์ที่ต้องถูก evaluate ก่อน • ไม่มีอะไรพิเศษเกี่ยวกับการส่งอีลีเมนต์ของอาเรย์ไปยังฟังก์ชัน • void foo(int f); • main(){ • int x = 3; • int a[2] = {5, 7}; • foo(1); • //f = 1 • foo(x); • //f = 3, not f = x • foo(a[1]); • //f = 7, not f = a[1] • } ภาควิชาวิศวกรรมคอมพิวเตอร์ มหาวิทยาลัยสงขลานครินทร์
รู้หรือไม่ว่า … • เมื่อประกาศอาเรย์ขึ้นมาแล้ว สิ่งที่จะถูกจดจำไว้ จะมีเพียงจุดอ้างอิงของอาเรย์เท่านั้น • จุดอ้างอิงจะถูกจดจำไว้ผ่านตัวแปร • อีลีเมนต์ต่างๆ ของอาเรย์ จะถูกคำนวณจากจุดอ้างอิงเสมอ • #include<stdio.h> • main(){ • int d[3] = {0,2,8}; • int e[2] = {5,6}; • printf("%d\n", d[3]); • } • /* What is the output???? */ ภาควิชาวิศวกรรมคอมพิวเตอร์ มหาวิทยาลัยสงขลานครินทร์
การส่งทั้งอาเรย์ไปยังฟังก์ชันการส่งทั้งอาเรย์ไปยังฟังก์ชัน • เมื่อประกาศอาเรย์ขึ้น เราสามารถเข้าถึงอีลีเมนต์ต่างๆ ด้วยเครื่องหมาย [ ] • ถ้าไม่ใส่เครื่องหมาย [ ] จะหมายถึงตำแหน่งเริ่มต้น(reference) ของอาเรย์ • เราไม่สามารถส่งทุกอีลีเมนต์ไปยังฟังก์ชันพร้อมๆ กัน เราจึงต้องส่งตำแหน่งอ้างอิงไปแทน เพื่อให้ฟังก์ชันสามารถประมวลผลทุกอีลีเมนต์ในอาเรย์ได้ • int d[3] = {0, 2, 8}; • printf("%d\n", d[0]); • printf("%d\n", d[1]); • printf("%d\n", d[2]); • printf("%p\n", d); ภาควิชาวิศวกรรมคอมพิวเตอร์ มหาวิทยาลัยสงขลานครินทร์
การส่งตัวอ้างอิงของอาเรย์ไปยังฟังก์ชันการส่งตัวอ้างอิงของอาเรย์ไปยังฟังก์ชัน • การส่งทั้งอาเรย์ไปยังฟังก์ชัน จริงๆ คือ การส่งตัวอ้างอิงของอาเรย์ไปยังฟังก์ชัน • a เก็บตัวอ้างอิงของอาเรย์ที่มีสมาชิกสามตัว มีค่า 4, 7, 2 • เมื่อเรียกใช้ฟังก์ชัน poo โดยการส่งค่าของ a เป็นพารามิเตอร์ ตัวแปร d จึงเก็บตัวอ้างอิงของอาเรย์เดียวกัน • d[1] เป็นการหาสมาชิกตัวที่สองนับจากจุดอ้างอิง • main(){ • int a[3] = {4, 7, 2}; • poo(a); • } • int poo(int d[]){ • printf("%d\n", d[1]); • } ภาควิชาวิศวกรรมคอมพิวเตอร์ มหาวิทยาลัยสงขลานครินทร์
การเปลี่ยนแปลงค่าของตัวแปรในฟังก์ชันการเปลี่ยนแปลงค่าของตัวแปรในฟังก์ชัน • a เก็บจุดอ้างอิงของอาเรย์ที่เก็บข้อมูล 2 และ 7 • ในการเรียกใช้ฟังก์ชัน bar ได้ส่งจุดอ้างอิงของอาเรย์ไปให้กับการทำงานของฟังก์ชัน bar • b เก็บจุดอ้างอิงเดียวกับอาเรย์ของ a • การเปลี่ยนแปลงโดยใช้ b ในฟังก์ชัน bar ก็เหมือนกับการเปลี่ยนแปลงโดยใช้ a • ทั้ง a และ b อ้างอิงไปที่เดียวกัน • main(){ • int a[2] = {2, 7}; • bar(a); • printf("%d\n", a[0]); • } • void bar(int b[]){ • b[0] = 5; • } • ##OUTPUT## • 5 ภาควิชาวิศวกรรมคอมพิวเตอร์ มหาวิทยาลัยสงขลานครินทร์
การเปลี่ยนแปลงค่าของตัวแปรในฟังก์ชันการเปลี่ยนแปลงค่าของตัวแปรในฟังก์ชัน main(){ int a = 10; foo(a); printf("%d\n", a); } void foo(int b){ b = 11; } ##OUTPUT## 11 • main(){ • int a[2] = {2, 7}; • bar(a); • printf("%d\n", a[0]); • } • void bar(int b[]){ • b[0] = 5; • } • ##OUTPUT## • 5 ภาควิชาวิศวกรรมคอมพิวเตอร์ มหาวิทยาลัยสงขลานครินทร์
การเปลี่ยนแปลงค่าของตัวแปรในฟังก์ชันการเปลี่ยนแปลงค่าของตัวแปรในฟังก์ชัน a a 10 2 7 main main b 10 b foo bar ภาควิชาวิศวกรรมคอมพิวเตอร์ มหาวิทยาลัยสงขลานครินทร์
ตัวอย่างการหาค่าเฉลี่ยของสมาชิกในอาเรย์ตัวอย่างการหาค่าเฉลี่ยของสมาชิกในอาเรย์ #include<stdio.h> float avg(int[], int); main(){ int d[5] = {2, 3, 1, 5, 6}; printf("%.1f\n", avg(d, 5)); } float avg(int d[], int len){ int i; int toal = 0; for(i = 0; i < len; i++) total += d[i]; return (float)total/len; } ภาควิชาวิศวกรรมคอมพิวเตอร์ มหาวิทยาลัยสงขลานครินทร์