Transcript double

เมธอด และขอบเขตของตัวแปร
01204111 คอมพิวเตอร์และการโปรแกรม
เนื้ อหา
• แนะนาเมธอด
• การประกาศและใช้งานเมธอด
• ขอบเขตของตัวแปร
แนะนาเมธอด
การแบ่งงานเป็ นส่วน ๆ
• ใน Python เราสามารถแบ่งโปรแกรมทีเ่ ขียนเป็ น
ฟงั ก์ชนั ย่อย ๆ เพือ่ ลดทัง้ ความซ้าซ้อนและความ
ซับซ้อน
• ใน C# เราก็ทาได้เช่นเดียวกัน โดยใช้เมธอด
ฟังก์ชนั vs เมธอด
• เมธอดกับฟงั ก์ชนั เป็ นชือ่ ทีใ่ ช้เรียกส่วนของโปรแกรมที่
เขียนเป็ นส่วนย่อย ๆ เช่นเดียวกัน
• อย่างไรก็ตาม เมธอด (method) นัน้ มีความหมายที่
เฉพาะเจาะจงกว่าในภาษาโปรแกรมเชิงวัตถุ
• อย่างไรก็ตาม ก่อนทีเ่ ราจะได้ศกึ ษาการโปรแกรมเชิง
วัตถุ เราจะใช้เมธอดในลักษณะเดียวกับฟงั ก์ชนั ใน
ภาษา Python
แนวคิด
• เราจะเริม่ โดยการยกตัวอย่างการใช้เมธอดในการ
ออกแบบโปรแกรม
• ในส่วนนี้จะคล้ายกับเนื้อหาทีเ่ คยพิจารณามาแล้วในส่วน
ของภาษาไพธอน แต่งานทีท่ าจะซับซ้อนขึน้
• ในตอนแรกนี้ นิสติ อาจจะยังไม่เข้าใจไวยากรณ์ในการ
นิยามเมธอด แต่ขอให้พยายามทาความเข้าใจกับ
ภาพรวมและการนาไปใช้ก่อน
ตัวอย่าง
จงเขียนโปรแกรมทีร่ บั จานวนเต็ม N จากผูใ้ ช้ แล้วพิมพ์รปู สีเ่ หลีย่ มขนาด N คอลัมน์
คูณ N บรรทัด ทีป่ ระกอบด้วยตัวอักขระ *
Enter N: 3
***
***
***
Enter N: 4
****
****
****
****
Enter N: 6
******
******
******
******
******
******
วางแผน: ขัน้ ตอนคร่าว ๆ
******
******
******
******
******
******
• รับค่า N
• พิมพ์ทลี ะบรรทัด จานวน N ครัง้
– แต่ละบรรทัด พิมพ์ * จานวน N ครัง้ แล้ว
ขึน้ บรรทัดใหม่
วางแผน: ภาพรวมของงานที่ต้องทา
โปรแกรมพิมพ์
สี่เหลี่ยม
รับค่า N
พิมพ์สี่เหลี่ยม
ขนาด N x N
พิมพ์ดาวเป็ นแถว
ความยาว N ตัวอักษร
เริ่มต้นเขียน: โปรแกรมหลัก
• สาหรับงานย่อย ๆ แต่ละงาน เรา
จะสมมติวา่ เรามีคาสังส
่ าหรับงาน
นัน้ อยูแ่ ล้ว (แต่จริง ๆ ยังไม่ม)ี
โปรแกรมพิมพ์
สี่เหลี่ยม
รับค่า N
พิมพ์สี่เหลี่ยม
ขนาด N x N
static void Main()
{
int n = int.Parse(Console.ReadLine());
PrintSquare(n);
Console.ReadLine();
}
คาสังนี
่ ้ ยงั ไม่มีจริง เราต้องเขียนขึน้ มาเอง
เมธอดแสดงสี่เหลี่ยม
• เมธอดดังกล่าวจะเรียกใช้เมธอด
PrintLine ทีย
่ งั ไม่มอี ยูจ่ ริงเช่นกัน
static void PrintSquare(int n)
{
int i = 0;
while(i < n)
{
PrintLine(n);
i++;
}
}
พิมพ์สี่เหลี่ยม
ขนาด N x N
พิมพ์ดาวเป็ น
แถว
ความยาว N
ตัวอักษร
คาสังนี
่ ้ ยงั ไม่มีจริง เราต้องเขียนขึน้ มาเองเช่นกัน
เมธอด PrintLine
• สุดท้ายเราจะเขียนเมธอด PrintLine ทีพ่ มิ พ์เส้นความ
ยาว n ด้วยดวงดาว
static void PrintLine(int n)
{
int i = 0;
while(i < n)
{
Console.Write("*");
i++;
}
Console.WriteLine();
}
โปรแกรมทัง้ หมด
using System;
namespace box1
{
class Program
{
static void PrintLine(int n)
{
int i = 0;
while(i < n)
{
Console.Write("*");
i++;
}
Console.WriteLine();
}
static void PrintSquare(int n)
{
int i = 0;
while(i < n)
{
PrintLine(n);
i++;
}
}
public static void Main(string[] args)
{
int n = int.Parse(Console.ReadLine());
PrintSquare(n);
Console.ReadLine();
}
}
}
• โปรแกรมทัง้ หมดดูยาว
เมธอด พอสมควร
PrintLine แต่ถา้ เรา
พิจารณาและทาความเข้าใจ
กับโปรแกรมเป็ นส่วนย่อย
ไปก่อน เราจะสามารถ
เมธอด ปะติ
PrintSquare
ดปะต่อการทางาน
ทัง้ หมดได้โดยไม่ยากนัก
เมธอด Main
การประกาศและใช้งานเมธอด
รูปแบบการประกาศเมธอด
• ไวยากรณ์ในการประกาศเมธอดเป็ นดังนี้
static แบบชนิดข้ อมูลทีค่ นื ค่ า ชื่อเมธอด( รายการพารามิเตอร์ )
{
// โปรแกรมของเมธอด
}
• จากตัวอย่างทีผ่ า่ นมา เราสามารถเขียนเมธอดทีค่ านวณแล้ว
ส่งค่ากลับมายังโปรแกรมส่วนทีเ่ รียกใช้ได้ เราต้องระบุแบบ
ชนิดของข้อมูลที่จะคืนค่ากลับนี้เมือ่ ประกาศเมธอดด้วย
• เราจะส่งข้อมูลให้กบั เมธอดผ่านทางพารามิเตอร์
คาหลัก static
• ในส่วนนี้เราจะเห็นคาว่า static เมือ่ ตอนทีเ่ ราประกาศ
เมธอด รวมถึงในตอนหลังทีใ่ ช้ในการประกาศตัวแปร
ครอบคลุม
• เราจะเข้าใจความหมายของคาหลักดังกล่าวมากขึน้ เมือ่
ได้ศกึ ษาการโปรแกรมเชิงวัตถุแล้ว ในขัน้ นี้ให้ใช้ตามที่
ระบุไปก่อน
ตัวอย่างการประกาศ
• เมธอดทีค่ านวณค่าของพหุนามกาลังสอง ax2 + bx + c
static double Poly(double a, double b, double c,
double x)
{
return a*x*x + b*x + c;
}
รับพารามิเตอร์ a, b, c และ x
คืนค่าเป็ น double
เมธอดชื่อ poly
ตาแหน่ งที่ประกาศ
using System;
namespace met_examples
{
class Program
{
static double Poly(double
double
double
double
{
return a*x*x + b*x + c;
}
public static void Main()
{
}
}
}
a,
b,
c,
x)
• ประกาศเมธอด
ภายในคลาส
• ภายนอกเมธอด
Main
–ไม่สามารถประกาศ
เมธอดภายในเมธอด
ได้
การประกาศเมธอด
• การประกาศเมธอดนัน้ มีสว่ นสาคัญสองส่วนคือ
1. ส่วนหัวของเมธอด (header)
static double Poly(double a, double b, double c,
double x)
{
return a*x*x + b*x + c;
}
2. ส่วนตัวของเมธอด (body)
ส่วนหัวของเมธอด (method header)
static double Poly(double a, double b,
double c, double x)
• ส่วนหัวของเมธอดเป็ นการประกาศต่อสาธารณะว่ารูปแบบใน
การใช้งานของเมธอดนี้เป็ นอย่างไร
• นอกจากนี้ยงั เป็ นการระบุอย่างไม่เป็ นทางการถึงข้อตกลงว่า
เมธอดนี้จะทางานอะไร เช่นในตัวอย่างนี้:
เมธอด Poly(double a, double b, double c, double x) คำนวณ
ค่ำพนุนำมกำลังสอง ax2 + bx + c
ส่วนตัวของเมธอด (method body)
• ส่วนหัวของเมธอดเป็ นการระบุสญ
ั ญาต่อสาธารณะ
• ส่วนตัว (body) ของเมธอดระบุโปรแกรมทีท่ างานตามที่
สัญญาไว้ --- เป็ นรายละเอียดภายในของเมธอด
เมธอด Poly
เมธอดอื่น ๆ
การทางานจริง ๆ ระบุที่
ส่วนตัวของเมธอด
เรียกใช้งาน
ตามที่ระบุไว้
ในส่วนหัว
การนาเมธอดไปใช้
• เราสามารถเรียกใช้เมธอดทีน่ ิยามได้จากเมธอดต่าง ๆ
ในคลาส
public static void Main(string[] args)
{
double k = 3;
double y = Poly(1,2,4,k);
Console.WriteLine(y);
Console.ReadLine();
}
ความหมายของการเรียกใช้งานเมธอด
ข้อตกลงของเมธอด
เมธอด Poly(a, b, c, x)
คำนวณค่ำพนุนำมกำลังสอง
ax2 + bx + c
การเรียกใช้งาน
double y = Poly(1,2,4,k);
ให้ y มีค่าเท่ากับ "ผลการคานวณค่าพนุนามกาลัง
สอง 1.k2 + 2.k + 4."
ความหมายของการเรียกใช้งานนี้
ตัวอย่างการเรียกใช้งานเมธอด (1)
โปรแกรมของเรามี 2 เมธอด คือ
using System;
namespace met_examples
Poly ซึ่งเป็ นเมธอดย่อย และ Main
{
class Program
ซึ่งเป็ นโปรแกรมหลัก
{
static double Poly(double a, double b, double c, double x)
{
return a*x*x + b*x + c;
}
public static void Main()
{
double k = 3;
double y = Poly(1,2,4,k);
Console.WriteLine(y);
Console.ReadLine();
}
}
}
โปรแกรมเริ่มทางานที่นี่
เรียกใช้เมธอด Poly ที่นี่
ตัวอย่างการเรียกใช้งานเมธอด (2)
using System;
namespace met_examples
{
class Program
{
static double Poly(double a, double b, double c, double x)
{
ค่าของพาราม
19
return
a*x*xิ เตอร์
+ b*x + c;
} จากจุดที่ เรียก
ถูกส่งstatic
ให้กบั เมธอด
public
void Main()
{
double k = 3;
double y = Poly(1,2,4,k);
Console.WriteLine(y);
Console.ReadLine();
}
}
}
19
k
y
ผลลัพธ์:
3
19
a
b
c
x
1
2
4
3
การส่งพารามิเตอร์ (1)
using System;
namespace met_examples
{
class Program
{
static double Poly(double a, double b, double c, double x)
{
return a*x*x + b*x + c;
}
public static void Main()
{
double k = 3;
double y = Poly(1,2,4,k);
Console.WriteLine(y);
Console.ReadLine();
}
}
}
ขัน้ ตอนที่สาคัญมากในการ
เรียกใช้งานเมธอด ก็คือ
ขัน้ ตอนการส่งพารามิเตอร์
การส่งพารามิเตอร์ (2)
static double Poly(double a, double b, double c, double x)
double y = Poly(1,2,4,k);
• ในขัน้ ตอนนี้ พารามิเตอร์ที่เราส่งให้กบั เมธอด จะถูก
"จับคู่" กับพารามิเตอร์ที่ประกาศไว้ในส่วนหัวของเมธอด
การส่งพารามิเตอร์ (3)
static double Poly(double a, double b, double c, double x)
double y = Poly(1,2,4,k);
• พารามิเตอร์ทางการ (Formal parameters) คือ
พารามิเตอร์ทป่ี ระกาศไว้ทส่ี ว่ นหัวของเมธอด
• พารามิเตอร์จริง (Actual parameters) คือพารามิเตอร์ทส่ี ง่
ให้กบั เมธอดจริง ๆ
การส่งพารามิเตอร์ (4)
static double Poly(double a, double b, double c, double x)
double y = Poly(1,2,4,k);
• ในตัวอย่างข้างต้นนี้ เมือ่ มีการเรียกใช้เมธอด สิง่ ทีเ่ กิดขึน้ ก็คอื
ระบบจะคานวณค่าของพารามิเตอร์จริงทุกตัวให้เสร็จสิน้
จากนัน้ จะส่งค่าทีค่ านวณได้ให้กบั พารามิเตอร์ทางการใน
เมธอด
การเรียกใช้งานเมธอด: แบบฝึ กหัด 1
using System;
namespace met_examples
{
class Program
{
static double Poly(double a, double b, double c, double x)
{
return a*x*x + b*x + c;
}
public static void Main()
{
double k = 3;
double y = Poly(2,k,k+3,2);
Console.WriteLine(y);
Console.ReadLine();
}
}
}
ผลลัพธ์ของโปรแกรมนี้
คืออะไร?
20
การส่งค่า: เฉลย
using System;
namespace met_examples
{
class Program
{
static double Poly(double a, double b, double c, double x)
{
return a*x*x + b*x + c;
}
2
public static void Main()
{
double k = 3;
double y = Poly(2,k,k+3,2);
Console.WriteLine(y);
Console.ReadLine();
}
}
}
3
6
2
การส่งพารามิเตอร์แบบ Pass by value
• รูปแบบของการส่งพารามิเตอร์ในตัวอย่างข้างต้น ซึง่
เป็ นรูปแบบมาตรฐานของ C# เรียกว่าการส่งค่าแบบ
Pass by value
–นันคื
่ อ เป็ นการส่งพารามิเตอร์ทส่ี ง่ เฉพาะค่า (value) ของ
พารามิเตอร์จริงให้กบั เมธอด
• ยังมีรปู แบบอื่น ๆ ในการส่งค่าอีก ซึง่ เราจะได้พจิ ารณา
ถัด ๆ ไป
การเรียกใช้งานเมธอด: แบบฝึ กหัด 2
using System;
namespace met_examples
{
class Program
{
static double Poly(double a, double b, double c, double x)
{ /* ละไว้ */ }
public static void Main()
{
ผลลัพธ์ของโปรแกรมนี้
double k = 3;
คืออะไร?
double y = Poly(2,k,k+3,2);
Console.WriteLine(y);
y = Poly(1,1,1,10);
20
Console.WriteLine(y);
Console.WriteLine(Poly(1,2,3,2));
111
Console.ReadLine();
11
}
}
}
คาสัง่ return (1)
static int Min(int x, int y)
{
if(x < y)
return x;
return y;
}
static void Main(string [] args)
{
int a = int.Parse(
Console.ReadLine());
int b = int.Parse(
Console.ReadLine());
Console.WriteLine(Min(a,b));
}
• รูปแบบ:
return ค่า;
• คาสัง่ return จะ
คืนค่ากลับไปยัง
จุดทีเ่ รียกทันที
แม้วา่ จะไม่ใช่คาสัง่
สุดท้ายก็ตาม
คาสัง่ return (2)
static int Min(int x, int y)
{
if(x < y)
x
100
return x;
y
15
return y;
}
Console.WriteLine(
Min(100,15));
15
• คาสัง่ return จะคืนค่ากลับไปยังจุดทีเ่ รียกทันที แม้วา่ จะ
ไม่ใช่คาสังสุ
่ ดท้ายก็ตาม
คาสัง่ return (3)
static int Min(int x, int y)
{
if(x < y)
x
10
return x;
y
100
return y;
}
Console.WriteLine(
Min(10,100));
10
• คาสัง่ return จะคืนค่ากลับไปยังจุดทีเ่ รียกทันที แม้วา่ จะ
ไม่ใช่คาสังสุ
่ ดท้ายก็ตาม
เมธอดที่ไม่คืนค่า
• ในการแบ่งงานเพือ่ มาพัฒนาเป็ นเมธอดนัน้ หลาย ๆ ครัง้ เราพบว่า
เมธอดนัน้ มีการทางานทีเ่ สร็จในตัวเอง เช่น พิมพ์คา่ ผลลัพธ์
• เมธอดเหล่านัน้ มักไม่มกี ารคืนค่ากลับมายังโปรแกรมในส่วนทีเ่ รียกใช้
ในการประกาศ เราจะระบุแบบชนิดข้อมูลทีเ่ มธอดคืนกลับมาเป็นชนิด
void
static void PrintLine(int n)
{
int i = 0;
while(i < n)
{
Console.Write("*");
i++;
}
Console.WriteLine();
}
คาสัง่ return ในเมธอดที่ไม่คืนค่า
• ในทานองเดียวกับในเมธอดทีค่ นื ค่า คาสัง่ return ใน
เมธอดทีไ่ ม่คนื ค่าทาให้เมธอดจบการทางาน และคืนการ
ทางานกลับไปทีจ่ ุดทีเ่ รียกเมธอดนัน้
ตัวอย่าง
ตัวอยางการท
างาน
class Program
่
{
3
static void Test(int n)
0
{
1
int i = 0;
2
while(true)
3
{
อย่างไรก็ตามคาสั ่ง return ที่จะถูกทางานเมื่อ
Console.WriteLine(i);
i++;
i > n จะทาให้เมธอดหยุดทางาน
if(i > n)
return;
}
}
public static void Main(string[] args)
{
int a = int.Parse(Console.ReadLine());
Test(a);
Console.ReadLine();
}
}
• พิจารณาเมธอด Test และ
คาสัง่ while
• สังเกตว่าคาสัง่ while
ดังกล่าวไม่มที างหยุดการ
ทางานเอง เนื่องจากเงือ่ นไข
เป็ นจริงตลอดเวลา
ตัวอย่าง: เมธอดเพื่อลดความซา้ ซ้อน
• มีโปรโมชันโทรศั
่
พท์สองแบบ คือ
–แบบ A: จ่ายรายเดือน 50 บาท โทรฟรี 50 นาที จากนัน้
คิดนาทีละ 1.5 บาท
–แบบ B: จ่ายรายเดือน 150 บาท โทรฟรี 100 นาที
หลังจากนัน้ คิดนาทีละ 1 บาท
• ให้เขียนโปรแกรมรับเวลาทีค่ าดว่าจะใช้โทรศัพท์
จากนัน้ ให้แนะนาว่าจะใช้โปรโมชันใด
่
public static void Main(string[] args)
{
Console.Write("Enter expected usage: ");
int u = int.Parse(Console.ReadLine());
double price1;
if(u <= 50)
price1 = 50;
else
price1 = 50 + (u - 50)*1.5;
double price2;
if(u <= 100)
price2 = 150;
else
price2 = 150 + (u - 100)*1.0;
if(price1 < price2)
Console.WriteLine("Plan A is better.");
else
Console.WriteLine("Plan B is better.");
Console.ReadLine();
}
โปรแกรมที่ไม่ใช้
เมธอด
• พิจารณาส่วนของ
โปรแกรมทีใ่ ช้
คานวณค่าใช้จา่ ย
• ส่วนของโปรแกรม
นัน้ คล้ายกันมาก
ส่วนของโปรแกรมที่คล้ายกัน
double price1;
if(u <= 50)
price1 = 50;
else
price1 = 50 + (u - 50)*1.5;
double price2;
if(u <= 100)
price2 = 150;
else
price2 = 150 + (u -100)*1.0;
จานวนนาที
ค่าใช้อจนาที
า่ ยรายเดื
ทในส่
โ่ี ทรฟรี
วอนที
น เ่ หลือ
• พิจารณาส่วนทีเ่ หมือนกัน และต่างกัน ราคาต่
• ส่วนทีต่ ่างกัน สามารถแยกออกมาเป็ นพารามิเตอร์ของ
เมธอดได้
เมธอดสาหรับคานวณ
static double CalculatePrice(double monthlyFee,
double freeMinutes,
double rate,
double usage)
{
if(usage <= freeMinutes)
return monthlyFee;
else
return monthlyFee + (usage - freeMinutes) * rate;
}
• เราแยกการคานวณทีเ่ หมือนกันออกมาเป็ นเมธอด
–สังเกตการตัง้ ชือ่ ตัวแปรทีส่ อ่ื ความหมาย
โปรแกรมหลัก
public static void Main(string[] args)
{
Console.Write("Enter expected usage: ");
int u = int.Parse(Console.ReadLine());
double price1 = CalculatePrice(50, 50, 1.5, u);
double price2 = CalculatePrice(150, 100, 1.0, u);
if(price1 < price2)
Console.WriteLine("Plan A is better.");
else
Console.WriteLine("Plan B is better.");
Console.ReadLine();
}
• โปรแกรมหลักก็สนั ้ ลง และอ่านเข้าใจได้งา่ ยขึน้
มุมนักคิด
จงเขียนโปรแกรมทีร่ บั จานวนเต็ม N จากผูใ้ ช้ แล้วพิมพ์รปู สามเหลีย่ ม
ขนาด N คอลัมน์ คูณ N บรรทัด ทีป่ ระกอบด้วยตัวอักขระ *
Enter N: 3
*
**
***
Enter N: 4
*
**
***
****
Enter N: 6
*
**
***
****
*****
******
หมายเหตุ: ให้เขียนเมธอด PrintTriangle(int n) ทีพ่ มิ พ์สามเหลีย่ ม
ดังกล่าว เมธอด PrintTriangle สามารถเรียกใช้เมธอด PrintLine ที่
เขียนไว้ก่อนได้
คาแนะนา
• ให้พจิ ารณาปรับแก้จากเมธอด PrintSquare
static void PrintSquare(int n)
{
int i = 0;
while(i < n)
{
PrintLine(n);
i++;
}
}
Enter N: 6
*
**
***
****
*****
******
ส่วนใดทีท
่ าให้ไมได
พธตามต
องการ?
่ ผลลั
้
้
์
ขอบเขตของตัวแปร
ตัวแปรของเมธอด
เมธอด Poly
เมธอดอื่น ๆ
•
การทางานจริง ๆ ระบุที่
ส่วนตัวของเมธอด
เรียกใช้งาน
ตามที่ระบุไว้
ในส่วนหัว
ของเมธอด
สามารถประกาศตัว
ในการทางานของเมธอดทีซ่ บั ซ้อนมากขึ
น้ อาจมี
วาม
แปรในส่
วนตัวคเมธอด
จาเป็ นต้องใช้ตวั แปรในการเก็บค่าชัวคราวระหว่
่
ได้ างการ
ทางาน
ตัวอย่าง
c
a b / c

e
b
2a
พิจารณาตัวอย่างจากการ
คานวณค่าของฟงั ก์ชนั ที่
ซับซ้อน
static double MyFunc(double a, double b, double c)
{
double x = 2 * Math.Pow(a,b);
double y = c / x;
double z = Math.Exp(a + b/c);
return y + z;
}
ตัวแปรท้องถิ่น (local variables)
• ตัวแปรทีเ่ ราประกาศภายในเมธอด ซึง่ รวมไปถึงตัวแปร
ในพารามิเตอร์ทางการด้วย จะรวมเรียกว่าตัวแปร
ท้องถิ่นของเมธอด (local variable)
static double MyFunc(double a, double b, double c)
{
double x = 2 * Math.Pow(a,b);
double y = c / x;
double z = Math.Exp(a + b/c);
return y + z;
}
ตัวแปรท้องถิ่นของเมธอด MyFunc คือ
a, b, c, x, y, และ z
ความเป็ น "ท้องถิ่น"
• ตัวแปรท้องถิน่ ของแต่ละเมธอดจะไม่เกี่ยวข้องกัน
แม้วา่ จะมีชอ่ื ซ้ากันก็ตาม
–การติดต่อรับ-ส่งค่าระหว่างตัวแปรเหล่านี้จะต้องทาผ่าน
ทางการส่งพารามิเตอร์เท่านัน้
MethodB
a
MethodA
a
b
z
sum
count
t
MethodC
k
b
z
t
n
t
class Program
{
static int C(int a, int b)
{
int t = 0;
int n = b;
while((n<=a) && (a % n == 0)) {
t++; n *= b;
}
return t;
}
public static void Main(string[] args)
{
int n = int.Parse(Console.ReadLine());
int b = int.Parse(Console.ReadLine());
int m = C(n,b);
Console.WriteLine("{0} is divisible by {1} ^ {2}.",
n,b,m);
Console.ReadLine();
}
}
ตัวอย่าง 1
พิจารณาโปรแกรม
ต่อไปนี้
ให้สนใจเฉพาะ
โครงสร้างของเมธอด
และตัวแปรท้องถิ่น ยัง
ไม่ต้องสนใจการ
ทางานของเมธอด
class Program
{
static int C(int a, int b)
{
int t = 0;
int n = b;
while((n<=a) && (a % n == 0)) {
t++; n *= b;
}
return t;
}
ตัวอย่าง 1
ตัวแปรท้องถิ่นของเมธอด C
คือ a, b, t, และ n
public static void Main(string[] args)
ตัวแปรท้องถิ่นของเมธอด
{
int n = int.Parse(Console.ReadLine()); Main คือ n, b, และ m
int b = int.Parse(Console.ReadLine());
int m = C(n,b);
Console.WriteLine("{0} is divisible by {1} ^ {2}.",
n,b,m);
Console.ReadLine(); ตัวแปรท้องถิ่นของเมธอดทัง้ สองคืออะไรบ้าง?
}
}
class Program
{
static int C(int a, int b)
{
int t = 0;
int n = b;
while((n<=a) && (a % n == 0)) {
t++; n *= b;
}
return t;
}
ตัวอย่าง 1
ตัวแปร n ทัง้ สอง
เป็ นตัวแปรคนละตัวกัน
public static void Main(string[] args)
{
int n = int.Parse(Console.ReadLine());
int b = int.Parse(Console.ReadLine());
ตัวแปร b ทัง้ สอง
int m = C(n,b);
เป็ นตัวแปรคนละตัวกัน
Console.WriteLine("{0} is divisible by {1} ^ {2}.",
n,b,m);
แม้จะมีการส่งค่าไปให้กนั ก็ตาม
Console.ReadLine();
}
}
ข้อดีของความเป็ นท้องถิ่น
• เนื่องจากตัวแปรท้องถิน่ ของเมธอดไม่เกีย่ วข้องกัน ทา
ให้ในการพิจารณาการทางานของเมธอดหนึ่ง ๆ ไม่ตอ้ ง
คานึงถึงเมธอดอื่น ๆ
• นี่เป็ นการลดความซับซ้อนของโปรแกรม
มุมนักคิด
• เมธอด C ทาอะไร?
static int C(int a, int b)
{
int t = 0;
int n = b;
while((n<=a) && (a % n == 0)) {
t++; n *= b;
}
return t;
}
มุมนักคิด: คาใบ้
• เมธอด C ทาอะไร?
static int C(int a, int b)
{
int t = 0;
int n = b;
while((n<=a) && (a % n == 0)) {
t++; n *= b;
}
return t;
}
ให้ทดลองคานวณ
• C(1100, 10)
• C(40, 2)
มุมนักคิด: เฉลย (1)
• เมธอด
C(int a, int b)
คานวณ กาลัง x ทีม่ ากทีส่ ดุ ของ b ทีท่ าให้ bx ยังหาร a
ลงตัว
(กดเพือ่ แสดง)
• ยกตัวอย่างเช่น C(m, 10) คานวณว่า m มีศนู ย์ลงท้ายกี่
ตัวเมือ่ เขียนเป็ นเลขฐานสิบ
มุมนักคิด: เฉลย (2)
เมธอด
C(int a, int b)
คานวณ กาลัง x ที่มากที่สดุ ของ b ที่ทาให้ bx ยังหาร a ลงตัว
• เมือ่ เราเข้าใจการทางานของเมธอดแล้ว ในการพิจารณา
ส่วนอื่น ๆ ของโปรแกรมต่อไป เราก็สามารถละทิ(กดเพื
ง้ อ่ แสดง)
รายละเอียดการทางานภายในของเมธอดนัน้ ได้
มุมนักคิด: หมายเหตุ
• เมือ่ เราเข้าใจเมธอดดังกล่าว เราจะพบว่าการตัง้ ชือ่
เมธอดว่า C นันไม่
่ ได้ชว่ ยในการเข้าใจอย่างใดเลย
• ในการเขียนโปรแกรมทีด่ นี นั ้ การตัง้ ชือ่ ควรจะสือ่
(กดเพือ่ ง้ แสดง)
ความหมายด้วย สาหรับเมธอดดังกล่าว เราอาจจะตั
ชือ่ เป็ น
FindMaxExp
ซึง่ น่าจะสือ่ ความหมายมากกว่า C
การซ่อนรายละเอียดใน Sharp Dev
• ด้วยแนวคิดในการซ่อนรายละเอียดดังกล่าว ระบบพัฒนา
โปรแกรมสมัยใหม่จงึ มักสามารถทาให้เราซ่อนส่วนตัว (body)
ของเมธอดได้ (ใน Sharp Dev ให้กดปุม่ [–] ทีต่ น้ เมธอด)
class Program
{
static void SuperSum(int price)
{
totalPrice += price;
}
ไม่มีตวั แปร (1)
The name 'totalPrice' does
not exist in the current
context.
public static void Main(string[] args)
{
int totalPrice = 0;
int p = int.Parse(Console.ReadLine());
while(p!=0)
{
SuperSum(p);
p = int.Parse(Console.ReadLine());
}
Console.WriteLine(totalPrice);
}
}
ตัวแปร totalPrice ไม่ถกู ประกาศในเมธอด SuperSum
• พิจารณาโปรแกรม
ด้านซ้าย
• ผลลัพธ์ของ
โปรแกรมดัง
กล่าวคือ?
• โปรแกรมไม่ทางาน
–ทาไมถึงผิดพลาด
ดังกล่าว
class Program
{
static void SuperSum(int price)
{
int totalPrice += price;
}
public static void Main(string[] args)
{
int totalPrice = 0;
int p = int.Parse(Console.ReadLine());
while(p!=0)
{
SuperSum(p);
p = int.Parse(Console.ReadLine());
}
Console.WriteLine(totalPrice);
}
ไม่มีตวั แปร (2)
• เพือ่ นของคุณแก้
โปรแกรมเป็ นดัง
ด้านซ้าย
• ผลลัพธ์ของโปรแกรม
ดังกล่าวคือ?
• โปรแกรมตอบ 0
เสมอ
}ตัวแปร totalPrice ในเมธอด SuperSum ไม่เกี่ยวข้องกับในเมธอด
– ทาไม?Main
ทาให้ค่าตัวแปร totalPrice ใน Main เป็ น 0 ตลอด
การใช้ตวั แปรร่วมกัน
• วิธหี นึ่งทีท่ าให้เมธอดสามารถใช้ตวั แปรร่วมกันได้คอื การ
ประกาศให้ตวั แปรนัน้ เป็ นตัวแปรครอบคลุม (Global variable)
totalPrice
Main
SuperSum
totalPrice
totalPrice
class Program
{
static int totalPrice;
static void SuperSum(int price)
{
totalPrice += price;
}
public static void Main(string[] args)
{
totalPrice = 0;
int p = int.Parse(Console.ReadLine());
while(p!=0)
{
SuperSum(p);
p = int.Parse(Console.ReadLine());
}
Console.WriteLine(totalPrice);
}
}
ตัวแปรครอบคลุม
• เราประกาศตัวแปร
totalPrice ไว้ภายนอก
เมธอด
• เราลบการประกาศตัวแปร
totalPrice ในสองเมธอดทิง้
• เมธอดทัง้ สองเมือ่ อ้างถึงตัว
แปร totalPrice จะหมายถึง
ตัวแปรทีป่ ระกาศในระดับ
คลาสนี้เหมือนกัน
ตัวแปรครอบคลุม (global variable)
• เป็ นตัวแปรทีป่ ระกาศภายในคลาส แต่ไม่อยูภ่ ายใน
เมธอด ทุก ๆ เมธอดภายในคลาสสามารถอ้างถึงตัว
แปรครอบคลุมได้
• รูปแบบการประกาศ: เหมือนกับการประกาศตัวแปร
ทัวไป
่ สาหรับในขัน้ นี้ให้ใส่คาว่า static ไว้ดว้ ย
หรือ
static แบบชนิดข้อมูล
ชือ่ ตัวแปร ;
static แบบชนิดข้อมูล
ชือ่ ตัวแปร = ค่าเริม่ ต้น ;
ตัวอย่าง
• ร้านขายของชาขายทัง้ ปากกาและข้าวกลางวัน
–ปากกาแท่งละ 5 บาท
–ข้าวกลางวันมีสองรายการคือ ข้าวไข่เจียว (10 บาท) และ
ข้าวกระเพราไก่ (15 บาท)
• เขียนโปรแกรมทีแ่ สดงเมนูและคานวณรายได้รวม
class Program
{
static int totalIncome = 0;
static void SaleFood() { /* ละไว้ */ }
static void SalePencil() { /* ละไว้ */ }
public static void Main(string[] args)
{
string ans;
do {
Console.Write("Eat, Write, or Quit (E/W/Q): ");
ans = Console.ReadLine();
if(ans == "E")
SaleFood();
else if(ans == "W")
SalePencil();
} while(ans != "Q");
Console.WriteLine("Total income = {0}",
totalIncome);
}
}
ภาพรวม
• เรามีตวั แปร
ครอบคลุม
totalIncome
สาหรับเก็บรายได้
ซึง่ เราจะแสดงผล
ตอนท้าย
• เราแบ่งงานเป็ นสอง
งาน คือส่วนขายของ
สองแบบ
เมธอดสาหรับขายอาหาร
static void SaleFood()
{
Console.Write("Omlet or Chicken Kraprao (O/C): ");
string ans = Console.ReadLine();
if(ans == "O")
{
Console.WriteLine("The price is 10 baht. Thanks");
totalIncome += 10;
}
else if(ans == "C")
{
Console.WriteLine("The price is 15 baht. Thanks");
totalIncome += 15;
}
}
• สังเกตว่าเมธอดใช้ตวั แปร totalIncome โดยไม่ตอ้ งประกาศ
เพราะว่าตัวแปรถูกประกาศไว้ในคลาสแล้ว
แบบฝึ กหัด
• พิจารณาโปรแกรมด้านล่าง
class Program
{
static int x = 0;
static void Test(int y)
{
x = y + 1;
Console.WriteLine(x);
}
public static void Main(string[] args)
{
Console.WriteLine(x);
Test(10);
Console.WriteLine(x);
}
}
ผลลัพธ์ของโปรแกรม
ดังกล่าวคืออะไร?
ผลลัพธโปรแกรม
์
0
11
11
ตัวแปรครอบคลุมและตัวแปรท้องถิ่น
• แก้โปรแกรมดังกล่าวโดยเพิม่ บรรทัด int x;
class Program
ผลลัพธโปรแกรม
์
{
static int x = 0;
0
static void Test(int y)
{
11
int x;
0
x = y + 1;
Console.WriteLine(x);
}
public static void Main(string[] args)
{
ตัวแปร x ในบรรทัดที่เพิ่มเข้าไป ทาให้คาสัง่
Console.WriteLine(x);
Test(10);
x=y+1
Console.WriteLine(x);
ไม่มีผลต่อตัวแปร x ที่เป็ นตัวแปรครอบคลุม
}
}
ทาไมจึงได้ผลลัพธ์
ดังกล่าว?
การบดบังตัวแปรครอบคลุม
• ถ้าภายในเมธอดมีตวั แปรท้องถิน่ ทีช่ อ่ื เดียวกันกับตัว
แปรครอบคลุม ตัวแปรท้องถิน่ นัน้ จะบดบัง (shadow)
ตัวแปรครอบคลุมไป
ตัวแปรในบล็อค (1)
int n = int.Parse(Console.ReadLine());
int i = 0;
while(i < n)
{
int a = 0;
int b = 0;
while(b < i)
{
a += b;
b++;
}
Console.WriteLine(a);
}
• นอกจากการประกาศ
ตัวแปรภายในเมธอด
แล้ว เรายังสามารถ
ประกาศตัวแปรท้องถิน่
ภายในบล็อคได้ดว้ ย
ตัวแปร a และ b เป็ นตัวแปร
ท้องถิ่นภายในบล็อค
ตัวแปรในบล็อค (2)
int n = int.Parse(Console.ReadLine());
int i = 0;
while(i < n)
{
int a = 0;
int b = 0;
while(b < i)
{
a += b;
b++;
}
Console.WriteLine(a);
}
Console.WriteLine(b);
• อย่างไรก็ตามตัวแปรที่
ประกาศจะสามารถ
ใช้ได้ภายในบล็อคนัน้
เท่านัน้
ตัวแปร a และ b เป็ นตัวแปร
ท้องถิ่นภายในบล็อค
ไม่สามารถเรียกใช้ได้หลังจาก
หมดขอบเขตของบล็อคแล้ว
ขอบเขตของตัวแปร
• ตาแหน่งในโปรแกรมทีต่ วั แปรหนึ่ง ๆ สามารถถูกอ้างถึง
ได้ จะเรียกว่าขอบเขตของตัวแปรนัน้ ๆ
• ตัวแปรทีป่ ระกาศในเมธอดมีกฎของขอบเขตดังนี้
–ตัวแปรจะเริม่ ปรากฏ (และอ้างถึงได้) ตัง้ แต่จุดทีถ่ กู
ประกาศ
–ตัวแปรจะอ้างถึงได้จนกระทังหมดขอบเขตของบล็
่
อคทีถ่ กู
ประกาศ
ตัวอย่าง
• โปรแกรมด้านล่างนี้ผดิ อย่างไร?
do {
Console.Write("Eat, write, or quit (E/W/Q): ");
string ans = Console.ReadLine();
if(ans == "E")
SaleFood();
else if(ans == "W")
SalePencil();
} while(ans != "Q");
เนื่ องจากตัวแปร ans ประกาศภายในบล็อค ทาให้มี
ขอบเขตแค่ภายในบล็อกเท่านัน้ และไม่สามารถใช้
ภายนอกบล็อค (ที่เงื่อนไข while)ได้
ข้อควรระวัง
static void Test(int a)
{
int x = a;
int j = 0;
while(x < a)
{
int j = x;
Console.WriteLine(j);
x--;
}
}
• ขอบเขตของตัวแปรท้องถิน่ ที่
ประกาศภายในบล็อกจะเป็ นไป
ตามกฎทัวไปของขอบเขตของตั
่
ว
แปร
• อย่างไรก็ตามตัวแปรท้องถิน่ ที่
ประกาศภายในบล็อคจะไม่
สามารถบดบังตัวแปรท้องถิน่ ที่
ประกาศในเมธอดได้
เกิดข้อผิดพลาดเนื่องจากตัวแปร j ทีป่ ระกาศในบล็อค
บดบังตัวแปร j ทีป่ ระกาศในเมธอด
สรุป
สรุป
• เราสามารถใช้เมธอดในการ
–ลดความซับซ้อนของโปรแกรม ทาให้เราสามารถ
พิจารณางานเป็ นส่วนย่อย ๆ แยกจากกันได้
–ลดความซา้ ซ้อนของโปรแกรม ทาให้เราสามารถ
รวบรวมโปรแกรมทีเ่ หมือนกัน หรือคล้ายกันมาไว้ทเ่ี มธอด
เดียว เพือ่ ให้งา่ ยต่อการแก้ไข
• ตัวแปรมีขอบเขตการใช้งานทีเ่ ฉพาะเจาะจง ทาให้
สามารถพิจารณาโปรแกรมแต่ละส่วนแยกจากกันได้