วันศุกร์ที่ 6 กันยายน พ.ศ. 2556

ใบความรู้ 7 การเขียนโปรแกรมด้วยภาษา C#

โครงสร้าง for ลูป

           ในใบความรู้ก่อนหน้านี้เราได้เห็นโครงสร้างของโปรแกรมแบบวนซ้ำที่ใช้คำสั่ง while และ
do..while เมื่อพิจารณาการใช้คำสั่งเหล่านี้ในการเขียนลูปแบบวนนับ (counting loop) เราจะพบว่า
โครงสร้างของลูปมักจะมีส่วนประกอบเหล่านี้เสมอ

   • ส่วนกำหนดค่าเริ่มต้นให้ตัวนับ – เป็นคำสั่งให้ค่าเริ่มต้นกับตัวแปรที่นำมาใช้เป็นตัวนับ คำสั่งนี้มัก
     ถูกเขียนไว้ทันทีก่อนที่โปรแกรมจะเข้าทำงานในโครงสร้าง while หรือ do..while

   • ส่วนคำสั่งที่ถูกทำซ้ำ – ส่วนหลักของลูปที่ประกอบด้วยคำสั่งที่ถูกเรียกทำงานในแต่ละรอบการวน
     ซ้ำ

   • ส่วนเงื่อนไข – ใช้สำหรับกำหนดเงื่อนไขว่าคำสั่งในลูปจะถูกเรียกทำต่อหรือไม่

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

         ตัวอย่างโปรแกรมต่อไปนี้แสดงให้เห็นส่วนประกอบต่าง ๆ ทั้งสี่ส่วน (แต่ละส่วนกำกับไว้ด้วยคอม
เมนต์ท้ายบรรทัด)

using System;
class CountDown {
  static void Main() {
    int i;
    i = 10;                  // (1) ส่วนกำหนดค่าเริ่มต้นให้ตัวนับ
    while (i >= 0) {         // (3) ส่วนเงื่อนไข
      Console.WriteLine(i);  // (2) ส่วนคำสั่งที่ถูกทำซ้ำ
      i--;                   // (4) ส่วนปรับค่าตัวนับ
    }
  }
}

            เนื่องจากลูปแบบวนนับมีการใช้งานบ่อยครั้งในโปรแกรมทั่ว ๆ ไป ภาษา C# (รวมถึงภาษา
โปรแกรมอื่น ๆ ด้วย) จึงได้เตรียมโครงสร้างพิเศษเพื่อใช้จัดการลูปประเภทนี้ได้โดยสะดวกยิ่งขึ้น
โครงสร้างนี้คือโครงสร้าง for ซึ่งมีรูปแบบการใช้งานดังนี้

for (init_stmt; condition; update_stmt) {
  statement1;
  statement2;
  :
  statementN;
}

           ผังงานด้านล่างแสดงขั้นตอนการทำงานของ for ลูป สังเกตว่าเงื่อนไขของลูปจะถูกตรวจสอบ
ก่อนที่คำสั่งวนซ้ำคำสั่งแรกจะถูกเรียกใช้ ดังนั้นโครงสร้าง for จึงมีการทำงานที่คล้ายคลึงกับโครงสร้าง
while มากกว่าโครงสร้าง do..while



ตัวอย่างที่ 4.5 โปรแกรมต่อไปนี้จะแสดงตัวเลข 1,2,3,...,20 บนหน้าจอ

using System;
class Counting {
  static void Main() {
    int i;
    for (i = 1; i <= 20; i++)
      Console.WriteLine(i);
  }
}

ตัวอย่างที่ 4.6 โปรแกรมต่อไปนี้รับตัวเลขอินพุท N จากผู้ใช้และแสดงตัวเลขทั้งหมดที่เป็นตัวประกอบของ N (นำไปหาร N แล้วลงตัว)

using System;
class Divisors {
  static void Main() {
    int i, N;
    Console.Write("Enter N: ");
    N = int.Parse(Console.ReadLine());
    for (i = 1; i <= N; i++) {
      if (N%i == 0) Console.WriteLine(i);
    }
  }
}

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

Enter N: 100
1
2
4
5
10
20
25
การประกาศและเรียกใช้เมท็อด

           ที่ผ่านมาเราได้เขียนโปรแกรมโดยใส่คำสั่งทั้งหมดไว้ในส่วนที่เรียกว่าเมท็อด Main อย่างไรก็ตามการเขียนโปรแกรมในลักษณะนี้จะเหมาะสำหรับโปรแกรมสั้น ๆ ที่ใช้แก้ปัญหาง่าย ๆ เท่านั้น แต่สำหรับปัญหาที่มีขนาดใหญ่และมีความซับซ้อนมากขึ้นการเขียนโปรแกรมแบบนี้นอกจากจะทำให้โปรแกรมดูเทอะทะไม่เป็นระเบียบแล้วยังทำให้เกิดความผิดพลาดภายในโปรแกรมได้ง่ายขึ้นอีกด้วย ดังนั้นนักเขียนโปรแกรมที่มีประสบการณ์จึงมักออกแบบโปรแกรมโดยการแบ่งปัญหาที่ต้องการแก้ออกเป็นงานย่อย ๆ หลาย ๆ งานจากนั้นจึงเขียนโปรแกรมเป็นส่วน ๆ เพื่อจัดการงานย่อยในแต่ละงาน เราเรียกส่วนของโปรแกรมเพื่อจัดการงานย่อยหนึ่ง ๆ ว่า ซับรูทีน (subroutine) นอกจากนี้ยังมีคำอีกหลายคำที่ให้ความหมายในทำนองเดียวกัน เช่น โปรแกรมย่อย (subprogram) และฟังก์ชัน (function) สำหรับภาษาที่สนับสนุนการเขียนโปรแกรมเชิงวัตถุเช่นภาษา C# นั้นส่วนของโปรแกรมดังกล่าวจะถูกเรียกว่า เมท็อด (method)

        การเขียนโปรแกรมเป็นส่วน ๆ โดยใช้เมท็อดมีข้อดีหลายประการ อาทิเช่น:
      • เป็นการมองงานที่ซับซ้อนเป็นงานย่อย ๆ ที่เล็กลงและเขียนโปรแกรมแก้ปัญหาได้ง่ายขึ้น
      • ช่วยลดการเขียนโค้ดที่ซ้ำซ้อน เช่นงานที่คล้ายคลึงกันที่ต้องถูกทำบ่อยครั้ง
      • ช่วยซ่อนรายละเอียดของโปรแกรมไว้ที่ส่วนอื่น แทนที่จะใส่ทั้งหมดไว้ที่ Main
      • ทำให้โปรแกรมดูมีระเบียบและง่ายต่อการเข้าใจ
      • รวมการคำนวณทางคณิตศาสตร์ที่ซับซ้อนไว้เป็นฟังก์ชันใหม่ให้เรียกใช้ได้โดยง่าย
      • เพิ่มความสะดวกในการดูแลและแก้ไขโปรแกรมในภายหลัง และลดความเสี่ยงในการเขียน
        โปรแกรมผิดพลาด
      • เพิ่มความสะดวกในการนำโค้ดที่เขียนไว้แล้วไปใช้ในโปรแกรมอื่น ๆ

           เราได้รู้จักวิธีการและได้เรียกใช้เมท็อดมาแล้วก่อนหน้านี้หลายครั้งเช่นการใช้งานเมท็อด
Console.WriteLine และ Math.Sqrt เมท็อดเหล่านี้เป็นเมท็อดที่ถูกสร้างมาให้พร้อมกับตัว
ภาษา C# ซึ่งเราสามารถเรียกใช้งานได้ทันที แต่ในปฏิบัติการครั้งนี้เราจะได้รู้จักวิธีการสร้างเมท็อดของเราขึ้นมาเอง

1. การประกาศเมท็อด
          ในความเป็นจริงเราเคยได้สร้างเมท็อดขึ้นมาเองมาก่อนหน้านี้แล้ว ยิ่งไปกว่านั้นเราได้สร้างเมท็อด
ลักษณะนี้เสมอในทุก ๆ โปรแกรมภาษา C# ที่เราเขียน เมท็อดดังกล่าวก็คือเมท็อด Main ที่ใช้สำหรับระบุ
จุดตั้งต้นของโปรแกรมนั่นเอง ลองพิจารณาโครงสร้างของโปรแกรมภาษา C# ที่เราคุ้นเคยมาก่อนแล้วดังนี้

namespace (มีหรือไม่มีก็ได้)
class
เมท็อด Main
statement;
...



           โครงสร้างโปรแกรมด้านบนเป็นโครงสร้างอย่างง่ายที่เราได้ใช้กันมาตั้งแต่แรกซึ่งประกอบด้วยเมท็
อด Main เพียงเมท็อดเดียว หากเราเขียนโปรแกรมที่ประกอบด้วยเมท็อดอื่น ๆ นอกเหนือจาก Main
โครงสร้างของโปรแกรมจะมีลักษณะดังนี้

namespace (มีหรือไม่มีก็ได้)
Class
เมท็อด Main
statement;
...

เมท็อด MyMethod_1
statement;
...

เมท็อด MyMethod_2
statement;
...

เมท็อด MyMethod_N
statement;
...



          สังเกตว่าเมท็อดแต่ละอันต้องถูกประกาศอยู่ภายนอกเมท็อดอื่น ๆ แต่อยู่ภายในคลาสเสมอ
   น      อ        ก       จ       า       ก         นั้         น
  เมท็อด Main ไม่จำเป็นต้องถูกประกาศเป็นเมท็อดแรกของโปรแกรม การประกาศเมท็อดจะมีรูปแบบดังนี้
static return_type method_name(parameter_list)
{
  statement1;
  statement2;
  :
}


          จะเห็นว่าเมท็อด Main ที่เราใช้กันมาตั้งแต่แรกก็มีการเขียนอยู่ในรูปแบบข้างต้นเช่นเดียวกัน เรา
สามารถแบ่งชนิดของเมท็อดเป็นสองประเภทคร่าว ๆ ได้แก่ เมท็อดแบบไม่คืนค่า (non-value returning
methods) และเมท็อดแบบคืนค่า (value-returning methods)

2. เมท็อดแบบไม่คืนค่า
         เมท็อดแบบไม่คืนค่า (บางครั้งเรียกว่า subroutine หรือ procedure) เป็นเมท็อดที่เขียนขึ้นมาเพื่อ
ปฏิบัติงานบางอย่างและจบงานนั้นในตัวมันเองโดยไม่ส่งค่าคืนกลับไปยังผู้เรียก การประกาศเมท็อด
ประเภทนี้ต้องมีการใช้คีย์เวิร์ด void ในตำแหน่ง return_type และการเรียกใช้เมท็อดประเภทนี้จะ
ปรากฏอยู่ในโปรแกรมเสมือนคำสั่งหนึ่งคำสั่ง

ตัวอย่างที่ 5.1 โปรแกรมต่อไปนี้ประกาศเมท็อดชื่อ PrintLine เพื่อทำหน้าที่พิมพ์ดาว (*) 10 ดวงออก
ทางหน้าจอ จากนั้นภายในเมท็อด Main จะเรียกใช้เมท็อด PrintLine สองครั้ง ดังนั้นผลลัพธ์ของ
โปรแกรมจะปรากฏเป็นดาวสองแถว แถวละ 10 ดวง

1:  using System;
2:  class MyClass {
3:    static void PrintLine() {
4:      for (int i = 0; i < 10; i++)
5:         Console.Write('*');
6:      Console.WriteLine();
7:    }
8:
9:    static void Main() {
10:      MyClass.PrintLine();
11:      MyClass.PrintLine();
12:   }
13: }

            จากการเรียกใช้งานเมท็อดในบรรทัดที่ 10--11 จะเห็นว่าการใช้งานเมท็อดนี้จะอยู่ในรูป
ClassName.MethodName โดย ClassName ในที่นี้คือ MyClass ซึ่งเป็นชื่อคลาสที่เราใช้ใน
โปรแกรมนี้ (บรรทัดที่ 2) และเป็นคลาสที่เมท็อด PrintLine ถูกนิยามไว้ ดังนั้นการใช้งานเมท็อดที่
สร้างขึ้นมาเองจึงเป็นลักษณะเดียวกันกับการใช้งานเมท็อดที่ภาษา C# เตรียมไว้ให้แล้ว เช่น
Console.WriteLine ซึ่ง WriteLine คือชื่อเมท็อดและ Console คือชื่อคลาสนั่นเอง

           อย่างไรก็ตามหากการเรียกใช้งานเมท็อดอยู่ภายในคลาสเดียวกันกับคลาสที่เมท็อดนั้น ๆ ถูก
ประกาศไว้ ภาษา C# อนุญาตให้เราละส่วนของชื่อคลาสออกไปได้ ดังนั้นเมท็อด Main ในตัวอย่างข้างต้น
จึงเขียนให้สั้นลงได้ดังนี้

static void Main() {
  PrintLine();
  PrintLine();
}

ไม่มีความคิดเห็น:

แสดงความคิดเห็น