เมธอด และขอบเขตของตัวแปร
Download
1 / 79

????? ?????????????????? - PowerPoint PPT Presentation


  • 134 Views
  • Uploaded on

เมธอด และขอบเขตของตัวแปร. 01204111 คอมพิวเตอร์และการโปรแกรม. เนื้อหา. แนะนำเมธอด การประกาศและใช้งานเมธอด ขอบเขตของตัวแปร. แนะนำเมธอด. การแบ่งงานเป็นส่วน ๆ. ใน Python เราสามารถแบ่งโปรแกรมที่เขียนเป็นฟังก์ชันย่อย ๆ เพื่อลดทั้งความซ้ำซ้อนและความซับซ้อน

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about '????? ??????????????????' - nikita


An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript

เมธอด และขอบเขตของตัวแปร

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

  • สุดท้ายเราจะเขียนเมธอด 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

เมธอด Main

เมธอด PrintSquare


การประกาศและใช้งานเมธอดการประกาศและใช้งานเมธอด


รูปแบบการประกาศเมธอดการประกาศและใช้งานเมธอด

  • ไวยากรณ์ในการประกาศเมธอดเป็นดังนี้

static แบบชนิดข้อมูลที่คืนค่าชื่อเมธอด( รายการพารามิเตอร์)

{

// โปรแกรมของเมธอด

}

  • จากตัวอย่างที่ผ่านมา เราสามารถเขียนเมธอดที่คำนวณแล้วส่งค่ากลับมายังโปรแกรมส่วนที่เรียกใช้ได้ เราต้องระบุแบบชนิดของข้อมูลที่จะคืนค่ากลับนี้เมื่อประกาศเมธอดด้วย

  • เราจะส่งข้อมูลให้กับเมธอดผ่านทางพารามิเตอร์


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 doublePoly(double a, 

double b, 

double c,double x)    {     return a*x*x + b*x + c;    }public static void Main()    {    }  }}

  • ประกาศเมธอดภายในคลาส

  • ภายนอกเมธอด 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
ส่วนหัวของเมธอด การประกาศและใช้งานเมธอด(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
ส่วนตัวของเมธอดการประกาศและใช้งานเมธอด (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();    }


ความหมายของการเรียกใช้งานเมธอดความหมายของการเรียกใช้งานเมธอด

ข้อตกลงของเมธอด

การเรียกใช้งาน

double y = Poly(1,2,4,k);

เมธอด Poly(a, b, c, x) คำนวณค่าพนุนามกำลังสอง ax2 + bx + c

ให้ y มีค่าเท่ากับ "ผลการคำนวณค่าพนุนามกำลังสอง 1.k2 + 2.k + 4."

ความหมายของการเรียกใช้งานนี้


ตัวอย่างการเรียกใช้งานเมธอดตัวอย่างการเรียกใช้งานเมธอด (1)

โปรแกรมของเรามี 2 เมธอด คือ Poly ซึ่งเป็นเมธอดย่อย และ Main ซึ่งเป็นโปรแกรมหลัก

using System;namespacemet_examples{  class Program  {    static doublePoly(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;namespacemet_examples{  class Program  {    static doublePoly(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();    }  }}

ค่าของพารามิเตอร์จากจุดที่เรียก

ถูกส่งให้กับเมธอด

19

a

1

b

2

k

3

c

4

y

19

x

3

ผลลัพธ์:

19


การส่งพารามิเตอร์ ตัวอย่างการเรียกใช้งานเมธอด(1)

using System;namespacemet_examples{  class Program  {    static doublePoly(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 doublePoly(double a, double b, double c,double x)

double y = Poly(1,2,4,k);

  • ในขั้นตอนนี้ พารามิเตอร์ที่เราส่งให้กับเมธอด จะถูก "จับคู่" กับพารามิเตอร์ที่ประกาศไว้ในส่วนหัวของเมธอด


การส่งพารามิเตอร์ ตัวอย่างการเรียกใช้งานเมธอด(3)

    static doublePoly(double a, double b, double c,double x)

double y = Poly(1,2,4,k);

  • พารามิเตอร์ทางการ (Formal parameters)คือพารามิเตอร์ที่ประกาศไว้ที่ส่วนหัวของเมธอด

  • พารามิเตอร์จริง (Actual parameters)คือพารามิเตอร์ที่ส่งให้กับเมธอดจริง ๆ


การส่งพารามิเตอร์ ตัวอย่างการเรียกใช้งานเมธอด(4)

    static doublePoly(double a, double b, double c,double x)

double y = Poly(1,2,4,k);

  • ในตัวอย่างข้างต้นนี้ เมื่อมีการเรียกใช้เมธอด สิ่งที่เกิดขึ้นก็คือ ระบบจะคำนวณค่าของพารามิเตอร์จริงทุกตัวให้เสร็จสิ้น จากนั้นจะส่งค่าที่คำนวณได้ให้กับ พารามิเตอร์ทางการในเมธอด


การเรียกใช้งานเมธอดตัวอย่างการเรียกใช้งานเมธอด: แบบฝึกหัด 1

using System;namespacemet_examples{  class Program  {    static doublePoly(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;namespacemet_examples{  class Program  {    static doublePoly(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();    }  }}

2

3

6

2


Pass by value
การส่งพารามิเตอร์แบบ Pass by value

  • รูปแบบของการส่งพารามิเตอร์ในตัวอย่างข้างต้น ซึ่งเป็นรูปแบบมาตรฐานของ C# เรียกว่าการส่งค่าแบบ Pass by value

    • นั่นคือ เป็นการส่งพารามิเตอร์ที่ส่งเฉพาะค่า (value) ของพารามิเตอร์จริงให้กับเมธอด

  • ยังมีรูปแบบอื่น ๆ ในการส่งค่าอีก ซึ่งเราจะได้พิจารณาถัด ๆ ไป


การเรียกใช้งานเมธอด : แบบฝึกหัด 2

using System;namespacemet_examples{  class Program  {    static doublePoly(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);Console.WriteLine(y);Console.WriteLine(Poly(1,2,3,2));Console.ReadLine();    }  }}

ผลลัพธ์ของโปรแกรมนี้คืออะไร?

20111

11


Return 1
คำสั่ง 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
คำสั่ง return (2)

static int Min(int x, int y)

{

if(x < y)

return x;

return y;

}

  • คำสั่ง return จะคืนค่ากลับไปยังจุดที่เรียกทันที แม้ว่าจะไม่ใช่คำสั่งสุดท้ายก็ตาม

Console.WriteLine(

Min(100,15));

x

100

y

15

15


Return 3
คำสั่ง return (3)

static int Min(int x, int y)

{

if(x < y)

return x;

return y;

}

  • คำสั่ง return จะคืนค่ากลับไปยังจุดที่เรียกทันที แม้ว่าจะไม่ใช่คำสั่งสุดท้ายก็ตาม

Console.WriteLine(

Min(10,100));

x

10

y

100

10


เมธอดที่ไม่คืนค่า

  • ในการแบ่งงานเพื่อมาพัฒนาเป็นเมธอดนั้น หลาย ๆ ครั้งเราพบว่าเมธอดนั้นมีการทำงานที่เสร็จในตัวเอง เช่น พิมพ์ค่าผลลัพธ์

  • เมธอดเหล่านั้นมักไม่มีการคืนค่ากลับมายังโปรแกรมในส่วนที่เรียกใช้ ในการประกาศ เราจะระบุแบบชนิดข้อมูลที่เมธอดคืนกลับมาเป็นชนิด void

static void PrintLine(int n)

{

int i = 0;

while(i < n)

{

Console.Write("*");

i++;

}

Console.WriteLine();

}


Return
คำสั่ง return ในเมธอดที่ไม่คืนค่า

  • ในทำนองเดียวกับในเมธอดที่คืนค่า คำสั่ง return ในเมธอดที่ไม่คืนค่าทำให้เมธอดจบการทำงาน และคืนการทำงานกลับไปที่จุดที่เรียกเมธอดนั้น


ตัวอย่าง

ตัวอย่างการทำงาน

  class Program  {        static void Test(int n)    {int i = 0;while(true)      {Console.WriteLine(i);        i++;if(i > n)          return;      }    }public static void Main(string[] args)    {int a = int.Parse(Console.ReadLine());Test(a);Console.ReadLine();    }  }

3

0

1

2

3

  • พิจารณาเมธอด Test และคำสั่ง while

  • สังเกตว่าคำสั่ง while ดังกล่าวไม่มีทางหยุดการทำงานเอง เนื่องจากเงื่อนไขเป็นจริงตลอดเวลา

อย่างไรก็ตามคำสั่ง return ที่จะถูกทำงานเมื่อ i > n จะทำให้เมธอดหยุดทำงาน


ตัวอย่าง : เมธอดเพื่อลดความซ้ำซ้อน

  • มีโปรโมชั่นโทรศัพท์สองแบบ คือ

    • แบบ 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.");elseConsole.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 doubleCalculatePrice(doublemonthlyFee,doublefreeMinutes,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.");elseConsole.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

  • ในการทำงานของเมธอดที่ซับซ้อนมากขึ้น อาจมีความจำเป็นต้องใช้ตัวแปรในการเก็บค่าชั่วคราวระหว่างการทำงาน

การทำงานจริง ๆ ระบุที่ส่วนตัวของเมธอด

เรียกใช้งานตามที่ระบุไว้

ในส่วนหัวของเมธอด

สามารถประกาศตัวแปรในส่วนตัวเมธอดได้


ตัวอย่างส่วนของโปรแกรมที่คล้ายกัน

พิจารณาตัวอย่างจากการคำนวณค่าของฟังก์ชันที่ซับซ้อน

static doubleMyFunc(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 variables)

  • ตัวแปรที่เราประกาศภายในเมธอด ซึ่งรวมไปถึงตัวแปรในพารามิเตอร์ทางการด้วย จะรวมเรียกว่าตัวแปรท้องถิ่นของเมธอด(local variable)

static doubleMyFunc(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

t

a

n

MethodA

MethodC

t

b

a

sum

z

count

b

t

k

z


  class Programส่วนของโปรแกรมที่คล้ายกัน  {     static intC(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 intC(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

ตัวแปรท้องถิ่นของเมธอด C

คือ a, b, t, และ n

ตัวแปรท้องถิ่นของเมธอด Main คือ n, b, และ m

ตัวแปรท้องถิ่นของเมธอดทั้งสองคืออะไรบ้าง?


  class Programส่วนของโปรแกรมที่คล้ายกัน  {     static intC(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

ตัวแปร n ทั้งสอง

เป็นตัวแปรคนละตัวกัน

ตัวแปร b ทั้งสอง

เป็นตัวแปรคนละตัวกัน

แม้จะมีการส่งค่าไปให้กันก็ตาม


ข้อดีของความเป็นท้องถิ่นข้อดีของความเป็นท้องถิ่น

  • เนื่องจากตัวแปรท้องถิ่นของเมธอดไม่เกี่ยวข้องกัน ทำให้ในการพิจารณาการทำงานของเมธอดหนึ่ง ๆ ไม่ต้องคำนึงถึงเมธอดอื่น ๆ

  • นี่เป็นการลดความซับซ้อนของโปรแกรม


มุมนักคิดข้อดีของความเป็นท้องถิ่น

  • เมธอด C ทำอะไร?

    static intC(int a, int b)     {int t = 0;int n = b;while((n<=a) && (a % n == 0)) {         t++;  n *= b;       }       return t;    }


มุมนักคิดข้อดีของความเป็นท้องถิ่น: คำใบ้

  • เมธอด C ทำอะไร?

    static intC(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
การซ่อนรายละเอียดใน ข้อดีของความเป็นท้องถิ่นSharp Dev

  • ด้วยแนวคิดในการซ่อนรายละเอียดดังกล่าว ระบบพัฒนาโปรแกรมสมัยใหม่จึงมักสามารถทำให้เราซ่อนส่วนตัว (body) ของเมธอดได้ (ใน Sharp Dev ให้กดปุ่ม [–] ที่ต้นเมธอด)


  class Programข้อดีของความเป็นท้องถิ่น  {    static void SuperSum(int price)    {totalPrice += price;    }public static void Main(string[] args)    {inttotalPrice = 0;int p = int.Parse(Console.ReadLine());while(p!=0)      {SuperSum(p);          p = int.Parse(Console.ReadLine());      }Console.WriteLine(totalPrice);    }  }

ไม่มีตัวแปร (1)

  • พิจารณาโปรแกรมด้านซ้าย

  • ผลลัพธ์ของโปรแกรมดังกล่าวคือ?

  • โปรแกรมไม่ทำงาน

    • ทำไมถึงผิดพลาดดังกล่าว

The name 'totalPrice' does not exist in the current context.

ตัวแปร totalPriceไม่ถูกประกาศในเมธอด SuperSum


  class Programข้อดีของความเป็นท้องถิ่น  {    static void SuperSum(int price)    {inttotalPrice += price;    }public static void Main(string[] args)    {inttotalPrice = 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 inttotalPrice;    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
ตัวแปรครอบคลุม ข้อดีของความเป็นท้องถิ่น(global variable)

  • เป็นตัวแปรที่ประกาศภายในคลาส แต่ไม่อยู่ภายในเมธอด ทุก ๆ เมธอดภายในคลาสสามารถอ้างถึงตัวแปรครอบคลุมได้

  • รูปแบบการประกาศ: เหมือนกับการประกาศตัวแปรทั่วไป สำหรับในขั้นนี้ให้ใส่คำว่า static ไว้ด้วย

static แบบชนิดข้อมูลชื่อตัวแปร;

หรือ

static แบบชนิดข้อมูล ชื่อตัวแปร= ค่าเริ่มต้น;


ตัวอย่างข้อดีของความเป็นท้องถิ่น

  • ร้านขายของชำขายทั้งปากกาและข้าวกลางวัน

    • ปากกาแท่งละ 5 บาท

    • ข้าวกลางวันมีสองรายการคือ ข้าวไข่เจียว (10 บาท) และข้าวกระเพราไก่ (15 บาท)

  • เขียนโปรแกรมที่แสดงเมนูและคำนวณรายได้รวม


  class Programข้อดีของความเป็นท้องถิ่น  {    static inttotalIncome = 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();elseif(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;      }elseif(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;    static void Test(int y)    {int x;      x = y + 1;Console.WriteLine(x);    }public static void Main(string[] args)    {Console.WriteLine(x);Test(10);Console.WriteLine(x);          }  }

ผลลัพธ์โปรแกรม

0

11

0

ทำไมจึงได้ผลลัพธ์ดังกล่าว?

ตัวแปร x ในบรรทัดที่เพิ่มเข้าไป ทำให้คำสั่ง

x = y + 1

ไม่มีผลต่อตัวแปร 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();elseif(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 ที่ประกาศในเมธอด


สรุปการบดบังตัวแปรครอบคลุม


สรุปการบดบังตัวแปรครอบคลุม

  • เราสามารถใช้เมธอดในการ

    • ลดความซับซ้อนของโปรแกรม ทำให้เราสามารถพิจารณางานเป็นส่วนย่อย ๆ แยกจากกันได้

    • ลดความซ้ำซ้อนของโปรแกรม ทำให้เราสามารถรวบรวมโปรแกรมที่เหมือนกัน หรือคล้ายกันมาไว้ที่เมธอดเดียว เพื่อให้ง่ายต่อการแก้ไข

  • ตัวแปรมีขอบเขตการใช้งานที่เฉพาะเจาะจง ทำให้สามารถพิจารณาโปรแกรมแต่ละส่วนแยกจากกันได้


ad