วันศุกร์ที่ 26 พฤศจิกายน พ.ศ. 2553

โปรแกรมแบบโครงสร้างคืออะไร ?

โปรแกรมแบบโครงสร้างตามภาษาโปรแกรม (Structure Programming) หมายถึง โปรแกรมที่ถูกเขียนขึ้นอย่างมีเค้าโครง มีลำดับการทำงานเป็นขั้นตอน เช่น ทำงาน (ประมวลผล) จากโค้ดส่วนบนสุดไปยังโค้ดส่วนล่าง และจากซ้ายไปขวา แนวคิดของโปรแกรมโครงสร้างมักใช้สำหรับแก้ปัญหาอัลกอลิทึม (ระเบียบวิธีในการหาคำตอบ) ซึ่งไม่เน้นชนิดข้อมูล (Data Type)

ตัวอย่าง โปรแกรมแบบโครงสร้างที่เขียนด้วยภาษา C
ภาษา C เป็นภาษาระดับสูง (ทำความเข้าใจได้ง่ายกว่าเมื่อเทียบกับภาษาระดับต่ำหรือภาษาเครื่องที่มีแต่เลข 0 และ 1) โครงสร้างของภาษาอาจแบ่งออกเป็นหลายส่วน ซึ่งทำงานตามลำดับก่อน-หลัง ดังนี้
- ส่วนการประกาศฟังก์ชันและตัวแปร
- ส่วนฟังก์ชัน main
- ส่วน body ของฟังก์ชัน

ส่วนการประกาศฟังก์ชันและตัวแปร
ประกอบด้วย
- ส่วน Preprocessor หรือส่วนไฟล์เฮดเดอร์ เช่น
     #include <stdio.h>
- ส่วนการประกาศตัวแปรโกลบอล (global) หรือประกาศรูปแบบฟังก์ชันย่อย ส่วนนี้อาจมีหรือไม่ก็ได้ เช่น
     int x;
     void show(int);

ส่วนฟังก์ชัน main
- ประกอบด้วยฟังก์ชัน main มีรูปแบบอย่างง่าย (หนึ่งในหลายรูปแบบ) ดังนี้
     int main()
     {
          return 0;
     }

ส่วน body ของฟังก์ชัน
- ส่วนนี้จะมีก็ต่อเมื่อเขียนส่วนประกาศฟังก์ชัน เช่น
     void show(int number)
     {
          printf("Number is %d\n", number);
     }

รู้จักกับ C/C++

มาตฐาน
ภาษา C++ ถูกสร้างและเพิ่มเติมจากผู้พัฒนาจำนวนมาก เมื่อเราจะศึกษาภาษา C++ จึงควรยึดมาตรฐานสากลไว้ เพื่อให้โค้ดสำสั่งสามารถอ้างอิงได้ และแน่ใจว่าจะเกิดปัญหาน้อยที่สุดเมื่อนำมันมาแปลโปรแกรมพร้อมสั่งให้ทำงานในเครื่องคอมพิวเตอร์ต่างแพลตฟอร์มกัน (แพลตฟอร์ม หมายถึง ระบบปฏิบัติการ เช่น Windows, Mac, Ubuntu ฯลฯ)

บทความที่จะเขียนจากนี้จึงอ้างอิงมาตรฐาน ISO/IEC 98 เป็นหลัก เป็นมาตรฐานสากลแรกที่เผยแพร่สู่สารณชนอย่างเป็นทางการในปี ค.ศ. 1998 ครับ

ลักษณะของเนื้อหา
เพื่อไม่ให้เป็นบทความที่กล่าวอย่างเป็นทางการมากนัก เนื้อหาจึงประกอบด้วยข้อคิดเห็นส่วนตัว การตั้งคำถามโต้ตอบกับผู้อ่าน การชี้ประเด็นนอกเรื่องที่ชวนให้ขำขัน และสารพัดตามแต่อารมณ์ของผู้เขียนบทความเป็นหลัก (ซะงั้น)

เมื่อพยายามเข้าใจความคิดของผู้เขียนแล้ว (แม้ว่ายังไม่เข้าใจ) ผู้เขียนน้อมเล่าให้ฟัง

C++ มาจากไหน ?
เครื่องหมาย ++ นี้มีความหมายคือ +1 หรือเพิ่มความสามารถอีกระดับหนึ่ง ดังนั้นภาษา C++ คือภาษา C ที่เพิ่มความสามารถนั่นเอง (ถ้างั้นภาษา C# คงหมายถึง C++ เพิ่มเครื่องหมาย ++ อีกชั้นหนึ่งสินะ ?)

เดิมทีภาษา C คือการเขียนโปรแกรมแบบโครงสร้าง คือคิดถึงการแก้ปัญหา แล้วลำดับปัญหาออกเป็นขั้นตอนย่อยๆ (ใช้ฟังก์ชัน) ต่อมามีแนวคิดใหม่เกิดขึ้น เรียกว่า การเขียนโปรแกรมเชิงวัตถุ เริ่มตั้งแต่ปลายทศวรรษ 1960 โดยมีภาษาต้นแบบชื่อ Simula 67 มันประกอบด้วยคลาส (class) การสืบทอด (inheritance) และเวอร์ชวลฟังก์ชัน (virtual function) การทำงานของมันเป็นลักษณะ event-driven (ฟังก์ชันจะถูกเรียกเมื่อเกิดเหตุการณ์บางอย่างที่สัมพันธ์กัน)

หลังจากนั้นไม่นานจึงเกิดภาษา Small talk ซึ่งเป็นมาตรฐานภาษาเชิงวัตถุในวงการอุตสาหกรรมซอฟท์แวร์ กระทั่งนาย เบียร์นี สตาวร์สตุป (Bjarne Stroustrup) คิดค้นภาษา C++ ขึ้น ณ ห้องวิจัย Bell Lap ของบริษัท AT&T เขาได้สร้างคลาสให้กับภาษา C เพื่อช่วยสนับสนุนการซ่อนข้อมูล (data hiding) และทำให้ข้อมูลอยู่ในขอบเขตจำกัด (encapsulation) สุดท้ายตั้งชื่อว่า C++ ในปี ค.ศ. 1983
***อ้างอิงจาก ยุทธนา ลีลาศวัฒนกุล, "เริ่มต้นการเขียนโปรแกรมด้วยภาษา C++"

การโปรแกรมแบบโครงสร้าง VS การโปรแกรมแบบเชิงวัตถุ
- การโปรแกรมแบบโครงสร้าง หรือ Procedure Programming
- การโปรแกรมแบบเชิงวัตถุ หรือ Object-Oriented Programming

การโปรแกรมแบบโครงสร้างเน้นไปทางอัลกอริทึม (วิธีการคิด) การแก้ปัญหาโดยลำดับขั้นตอนจากบนลงล่าง โดยสนใจไทป์ข้อมูลน้อยมาก เหมาะสำหรับผู้เริ่มศึกษาการเขียนโปรแกรมและโปรแกรมขนาดเล็ก แต่ไม่เหมาะกับการพัฒนาโปรแกรมขนาดใหญ่ที่ประกอบด้วยโค้ดจำนวนมาก

การโปรแกรมแบบเชิงวัตถุ เน้นที่ไทป์ข้อมูล (Abstract data type และ User-defined type) และมองโปรแกรมจากล่างขึ้นบน
ล่างคือ การออกแบบชนิดข้อมูลใหม่ (นิยามคลาส) ที่สอดคล้องกับปัญหานั้น
บนคือ การมองภาพรวมที่จะประสานการทำงานชนิดข้อมูลใหม่เหล่านั้นเข้าด้วยกัน
ดังนั้นการโปรแกรมแบบเชิงวัตถุ จึงเหมาะกับการพัฒนาโปรแกรมขนาดใหญ่ที่ประกอบด้วยความซับซ้อนครับ (มึนเลย)

หาตัวแปลภาษาได้จากไหน ?
อ่านบทความ ใช้อะไรเขียนโปรแกรมภาษา C/C++ ดีละ ?
***หมายเหตุ บทความนี้ผมจัดอยู่ในหมวด "บทความเกี่ยวกับภาษา C++" แต่ว่าเนื้อหาเกี่ยวข้องกับบทความ "แนวคิดอัลกอริทึม" อย่าลงทางเชียวนะ!

ต่อจากนี้ไปอ่านหนังสือเอาเองนะ ก๊ากๆ (อะล้อเล่น)

อ่านเนื้อหาที่เกี่ยวข้อง ถัดไป

วันพฤหัสบดีที่ 25 พฤศจิกายน พ.ศ. 2553

สวัสดี Ruby

ภาษา Ruby คืออะไร ?
ภาษา Ruby คือภาษา script ภาษาหนึ่ง พัมนาขึ้นโดย Yukihiro Matsumoto ชาวญี่ปุ่น เป็นภาษาคอมพิวเตอร์ที่แปลภาษาโดยตัวแปลภาษาที่เรียกว่า interpreter กล่าวคือแปลและทำงานทีละประโยค (หนึ่ง statement)

อ่านเพิ่มเติมเกี่ยวกับ Ruby
- bkk-ruby.blogspot.com
- blogs.sun.com
- th.wikipedia.org

เหตุใด Ruby จึงน่าสนใจ ?
เมื่อผมต้องการศึกษาภาษาสคริปต์สำหรับพัฒนา web application จากทั้งหมดที่รู้จัก ผมเลือกสองภาษา ได้แก่
- java server pages (JSP)
- Ruby on Rails

ไวยากรของภาษา Ruby ง่ายต่อการศึกษาเป็นอย่างมาก (ลืม JSP ไปเลย ...แท้จริงก็ไม่ถึงขนาดนั้น) พร้อมกับ framework ที่ชื่อว่า Rails ความหวังที่จะพัฒนา web application โดยไม่ยุ่งกับการ config มากนักจึงไม่ไกลเกินเอื้อมอีกต่อไป ^^ (เหตุผลค้างๆคูๆนะ)

แล้ว framework คืออะไร ?
มันคือไลบรารีของคลาสจำนวนมากที่ถูกจัดหมวดหมูไว้เพื่อใช้พัฒนางานใดๆ และการใช้งาน framework เราจะต้องศึกษาวิธีการใช้ ซึ่งเรียกว่า Application Programming Interface (API) นั่นเอง

Ruby on Rails
เพื่อนๆบางคนสงสัยว่า เมื่อเริ่มต้นศึกษาภาษา Ruby เหตุใดต้องโหลด Rails framework มาด้วย ? เหตุเพราะเมื่อเราต้องการพัฒนา web application โดยใช้ภาษา Ruby มีเพียง framework ชื่อ Rails ที่ได้รับความนิยมอยู่ขณะนี้ (ผมตอบตรงคำถามหรือไม่นะ ?) ฉะนั้นหากเราต้องการศึกษาแต่เพียงภาษา Ruby ให้โหลด Ruby Installer มาใช้ ทว่าผมต้องการศึกษาเพื่อพัฒนา web application ไปด้วย จึงเลือก Instant Rails ครับ (แนะนำ)

- ดาวน์โหลด Instant Rails for Windows ได้จาก http://rubyforge.org
- ขณะนี้คือเวอร์ชัน 2.0 ดังนั้นผมเลือกลิงค์ที่ชื่อ InstantRails-2.0-win.zip

เตรียม InstantRails-2.0-win ให้พร้อมใช้งาน
- ผมขยายไฟล์ .zip ไว้ ณ disk D: ให้เพื่อนๆมองหาไฟล์ที่ชื่อ InstantRails.exe แล้วดับเบิลคลิกเพื่อเปิด

- InstantRails.exe จะถามแก้ไข path ของไฟล์ชื่อ use_ruby.cmd ให้ตอบตกลง ครู่หนึ่งจึงปิดโปรแกรมนี้โดยกด I แล้วเลือก Exit ดังรูป

- คัดลอกไฟล์ use_ruby.cmd ไปวางไว้ ณ C:\Windows เพราะทุกครั้งที่เรียก command prompt มันจะอ่านไฟล์นี้
- ทดลองโดยเรียก command prompt แล้วพิมพ์ use_ruby กด enter หากได้ผลลัพธ์เป็น path เหมือนกับด้านล่างนี้ แสดงว่าพร้อมใช้งานแล้วครับ
D:\InstantRails-2.0-win\rails_apps>

*** หมายเหตุ
- แต่ถ้ายังไม่ได้ path เหมือนกับข้างต้น ให้เปิดไฟล์ use_ruby.cmd ออกมาแก้ไข โดยเพิ่ม D: ตามบรรทัดในรูป บันทึกไฟล์แล้วคัดลอกไปวาง ณ C:\Windows อีกครั้ง (ทับไฟล์เดิมไปเลย)

อ่านเนื้อหาที่เกี่ยวข้อง ถัดไป

บทความที่เกี่ยวข้องกับภาษา Ruby

เรียนรู้ภาษา Ruby จากเพื่อนสู่เพื่อน
- สวัสดี Ruby
     ภาษา Ruby คืออะไร ?
     เหตุใด Ruby จึงน่าสนใจ ?
     ดาวน์โหลด Instant Rails for Windows
- สร้าง Web Application เบื้องต้น

วันอังคารที่ 23 พฤศจิกายน พ.ศ. 2553

Constructor และ Method

Product book = new Product();

เพื่อนๆทราบแล้วว่าคำสั่ง new Product(); จะสั่งให้สร้างออบเจกต์ในหน่วยความจำ เราเรียก Product() ที่ตามหลังคำสั่ง new นี้ว่าคอนสตรักเตอร์ครับ (constructor)

Constructor
คือเมธอดพิเศษ ทำหน้าที่กำหนดการทำงานต่างๆให้กับออบเจกต์ใหม่ที่เกิดขึ้นจากคำสั่ง new ทันทีโดยอัตโนมัติ หากไม่กำหนดคอนสตรักเตอร์ ตัวแปลภาษา C# จะสร้างคอนสตรักเตอร์พื้นฐาน (default constructor) ให้เอง

ตัวอย่างต่อไปนี้คือ คอนสตรักเตอร์พื้นฐาน ของคลาส Product
     public Product()
     {
     }

ตัวอย่างการเรียกใช้ default constructor จากแบบฝึกหัดที่ผ่านมา

รูปแบบการนิยามคอนสตรักเตอร์
[ access_modifiers ] identifier ( [ parameter_list ] )
{
     [ code_body ]
}
access_modifiers ได้อธิบายแล้ว ณ บทความก่อนหน้านี้
identifier หมายถึง ชื่อคอนสตรักเตอร์ ต้องเป็นชื่อเดียวกับคลาสเท่านั้น
parameter_list หมายถึง พารามิเตอร์จำนวนหนึ่ง เช่น char[ ] id, char[ ] name, float price เป็นต้น
code_body หมายถึง คำสั่งต่างๆภายในคอนสตรักเตอร์

ตัวอย่างการประกาศคอนสตรักเตอร์ในคลาส Product

รูปข้างต้นออกแบบให้รายการพารามิเตอร์ (parameter_list) มีจำนวนสามตัวเท่ากับจำนวนฟิวด์ (เพื่อนๆจะออกแบบรายการพารามิเตอร์อย่างไรก็ได้ โดยคำนึงถึงการนำเอาไปใช้มากที่สุด) และสำหรับ code_body นี้ประกอบด้วยสามคำสั่ง ได้แก่
this.id = id; หมายถึง นำค่าพารามิเตอร์ id ที่รับมาส่งให้ฟิวด์ทางซ้ายของเครื่องหมายเท่ากับ แต่เนื่องจากชื่อฟิวด์และชื่อพารามิเตอร์ id เหมือนกัน จึงต้องแยกแยะด้วยคำสั่ง this
name = newName; หมายถึง นำค่าพารามิเตอร์ newName ที่รับมาส่งให้ฟิวด์ชื่อ name แต่เนื่องจากชื่อฟิวด์และชื่อพารามิเตอร์ต่างกัน จะใช้หรือไม่ใช้คำสั่ง this ก็ได้
Price = price; หมายถึง นำค่าพารามิเตอร์ price ที่รับมาส่งให้พรอเพอร์ตี้ชื่อ Price ซึ่งเป็นรูปแบบที่ควรกระทำมากที่สุด

เมื่อสร้างคอนสตรักเตอร์แล้ว เป็นผลให้ default constructor ที่มีอยู่ต้องถูกยกเลิกไป

เมธอด
มีหน้าที่อธิบายพฤติกรรมของคลาส หรือกระทำกระบวนการบางอย่าง จากรูปข้างต้นเมธอดชื่อ ToCharArray ทำหน้าที่เปลี่ยน String ให้เป็น char[ ] แสดงว่าเมธอดนี้เป็นพฤติกรรมหนึ่งของคลาส String

รูปแบบการนิยามเมธอด
[ access_modifiers ] return_type identifier ( [ parameter_list ] )
{
     [ code_body ]
}
access_modifiers ได้อธิบายแล้ว ณ บทความก่อนหน้านี้
return_type หมายถึง ไทป์ที่จะถูกส่งออกจากเมธอด (ด้วยคำสั่ง return ที่อยู่ภายในเมธอด หากไทป์นั้นไม่ใช่ void) ไปยังโค้ดที่เรียกใช้
identifier หมายถึง ชื่อเมธอด
parameter_list หมายถึง พารามิเตอร์จำนวนหนึ่ง เช่น char[ ] id, char[ ] name, float price เป็นต้น
code_body หมายถึง คำสั่งต่างๆภายในเมธอด

อาร์กิวเมนต์ VS พารามิเตอร์
การส่งค่าใดๆให้กับเมธอดที่ถูกเรียก ผมเรียกว่า อาร์กิวเมนต์ (argument) ส่วนตัวแปรใดๆที่นิยามจาก parameter_list ที่รับค่าอาร์กิวเมนต์ ผมเรียกว่า พารามิเตอร์ (parameter)

พารามิเตอร์และ modifier
เมื่อเรานิยามเมธอดจะต้องกำหนดเครื่องหมาย ( และ ) ต่อท้ายชื่อเมธอดเสมอ โดยจะมีพารามิเตอร์หรือไม่ก็ได้ นอกจากนี้ยังสามารถระบุ modifier ให้แก่พารามิเตอร์แต่ละตัวด้วย สำหรับ modifier แบ่งออกเป็น 4 ประเภท ได้แก่
- value parameter หรือพารามิเตอร์ขาเข้า กล่าวคือ เมื่อเกิดการแก้ไขค่าของตัวแปรใดๆที่เป็นพารามิเตอร์ ค่าที่เปลี่ยนแปลงนั้นจะไม่ส่งผลกระทบต่อค่าเดิมที่ส่งมา เปรียบได้กับเอกสารที่ถ่ายสำเนาแล้ว แผ่นสำเนาจะนำไปขีดเขียนอย่างไร ก็ไม่กระทบต่อต้นฉบับเดิมของมัน พารามิเตอร์ประเภทนี้พบเห็นทั่วไป โดยไม่ต้องกำหนด modifier
- ref parameter หรือพารามิเตอร์ขาออก กล่าวคือ เมื่อเกิดการแก้ไขค่าของตัวแปรใดๆที่เป็นพารามิเตอร์ ค่าที่เปลี่ยนแปลงนั้นจะส่งผลกระทบต่อค่าเดิมที่ส่งมา เปรียบได้กับเอกสารต้นฉบับซึ่งเป็นของเรา แล้วถูกเพื่อนเราเอาไปขีดเขียน ภายหลังส่งกลับให้เรา อย่างไรมันก็ถูกขีดเขียน พารามิเตอร์ประเภทนี้จะต้องกำหนดคำสั่ง ref ไว้สองตำแหน่ง
     1. โค้ดที่ระบุอาร์กิวเมนต์จากการเรียกเมธอด เช่น Input(ref myName);
     2. โค้ดที่นิยามเมธอด เช่น public void Input(ref name) { ... }
     ***หมายเหตุ อาร์กิวเมนต์ชื่อ name นี้จะต้องถูกำหนดค่าเริ่มต้นก่อนส่งเสมอ
- out parameter หรือพารามิเตอร์ขาออก เช่นเดียวกับ ref parameter ต่างที่ไม่จำเป็นต้องกำหนดค่าเริ่มต้นให้กับอาร์กิวเมนต์ก่อนก็ได้ จากตัวอย่างคือ ไม่จำเป็นต้องกำหนดค่าเริ่มต้นให้กับ name
- params parameter หรือพารามิเตอร์อาร์เรย์ สำหรับการส่งแบบอาร์เรย์ พารามิเตอร์ประเภทนี้ระบุคำสั่ง params ไว้เพียงโค้ดที่นิยามเมธอดเท่านั้น ส่วนโค้ดเรียกเมธอดไม่ต้องระบุ
     โด้ดนิยามเมธอด เช่น public void Show(params int[ ] nameList) { ... }

***หมายเหตุ หากกำหนด params parameter ไว้กับพารามิเตอร์ประเภทอื่น จะต้องเขียน params parameter ไว้ลำดับสุดท้ายเท่านั้น

คอนสตรักเตอร์ VS เมธอด VS พรอเพอร์ตี้
เพื่อนๆที่เริ่มเขียนภาษา C# อย่าได้สบสนระหว่าง คอนสตรักเตอร์ กับ เมธอด หรือ เมธอด กับ พรอเพอร์ตี้ เพราะมันมีจุดสังเกตที่แต่งต่างกัน ดังนี้
- คอนสตรักเตอร์ไม่มี return _type เหมือนเมธอด (ดังที่กล่าวในหัวข้อ "รูปแบบการนิยามเมธอด")
- คอนสตรักเตอร์จะทำงานเพียงครั้งเดียว คือเมื่อมีการสร้างออบเจกต์ใหม่จากคำสั่ง new เท่านั้น
- เมธอดเรียกให้ทำงานได้หลายครั้งเช่นเดียวกับพรอเพอร์ตี้
- เมธอดจะมีเครื่องหมาย ( และ ) ตามหลังชื่อเสมอ ส่วนพรอเพอร์ตี้นั้นไม่มี
- เมธอดสามารถนิยามผลลัพธ์เหมือนพรอเพอร์ตี้ได้ แต่จะมุ่งไปที่กระบวนการภายใน มากกว่าการ ขอค่า หรือ กำหนดค่า แก่ฟิวด์เฉกเช่นพรอเพอร์ตี้
- พรอเพอร์ตี้ประเภท กำหนดค่า จะมีเครื่องหมาย = ตามท้ายชื่อ ส่วนเมธอดการ กำหนดค่า จะต้องผ่านทางอาร์กิวเมนต์เท่านั้น

แบบฝึกหัด
- ไม่มีครับ เรื่องนี้จะถูกประยุกต์ในตัวอย่างถัดไป

Class และ Properties

เพื่อนๆหลายคนคงรู้จักสตรัก (struct) ในภาษา C บ้างแล้ว เช่น
     struct product
     {
          char id[10];
          char name[30];
          float price;
     };

     product book, cup;

เมื่อเราทราบว่าข้อมูลจำนวนหนึ่งมีความสัมพันธ์ต่อกัน อาธิ รหัสสินค้า, ชื่อสินค้าและราคาสินค้า เราสามารถนิยามเป็นสตรักได้ กล่าวว่าเป็นการจัดกลุ่มของข้อมูลหรือนิยามชนิดข้อมูล (type) ใหม่นั่นเอง ตัวอย่างข้างต้นคือการประกาศสตรักที่มีชื่อว่า product ภายหลังได้นำสตรักนี้ไปสร้างเป็นออบเจกต์ (บางตำราเรียกว่า ตัวแปร) ชื่อ book และ cup

การนิยามคลาส
ความแตกต่างระหว่างภาษาแบบโครงสร้าง (Structural Programming) และภาษาแบบเชิงวัตถุ (Object-Oriented Programming) อยู่ที่ความสามารถในการกำหนดโครงสร้างของข้อมูลขึ้นใหม่ เพื่อใช้ในการแก้ปัญหา หากเทียบสตรักในภาษา C กับคลาสในภาษา C# คลาสยังสามารถกำหนดสภาพแวดล้อมของข้อมูลได้อีก (หลัก OOP) ซึ่งสตรักทำไม่ได้

แต่ภาษา C# สามารถนิยามสตรักแบบที่สามารถกำหนดสภาพแวดล้อมได้เช่นเดียวกับคลาส แต่เมื่อมันทั้งสองถูกสร้างเป็นออบเจกต์ หน่วยความจำจะถูกจัดการต่างกัน (จำไม่ได้ให้ย้อนกลับไปอ่านหัวข้อ สวัสดี Types)

โครงสร้างที่กำหนดสภาพแวดล้อมของข้อมูลได้ ตามนิยามของ OOP เรียกว่า "คลาส" ตัวอย่าง
     class Product
     {
          char[ ] id;
          char[ ] name;
          float price;
     }

การนิยามนี้ประกอบด้วยคำสั่ง class ตามด้วยชื่อของคลาสคือ Product และสมาชิกฟิวด์ของคลาสอีกจำนวนสามสมาชิก ได้แก่ id, name และ price

การนำคลาสไปใช้
คลาสจะถูกนำไปใช้ได้มีอยู่สองกรณีใหญ่ๆ คือ
- ถูกเรียกจากคลาสอื่น
- ถูกเรียกจาก Main ของคลาสอื่นหรือของตัวเอง
*** เพราะภาษา C# ต่างจากภาษา Java ที่มองว่า main เป็นเมธอดแบบพิเศษซึ่งเป็นสมาชิกหนึ่งของคลาส แต่ละคลาสจึงมี main เป็นของตัวเองได้ ทว่าภาษา C# ในหนึ่งงานหรือหนึ่งโปรเจกต์จะมี Main ได้เพียงเมธอดเดียว นั่นหมายความว่าจะมีเพียงคลาสเดียวเท่านั้นที่มี Main ได้

class Program
{
     static void Main(string[ ] args)
     {
          Product book = new Product();
     }
}

คลาส Program มีเมธอด Main และภายในได้สร้างออบเจกต์คลาส Product โดยมีอินสแตนท์ชื่อ book เป็นตัวรับ reference ออบเจกต์ที่เกิดขึ้น เราสามารถใช้เครื่องหมาย . (dot) ระบะต่อท้ายอินสแตนท์เพื่อเข้าถึงสมาชิกของคลาส Product ทว่าผลลัพธ์กลับเป็นดังนี้

เราไม่สามารถเข้าถึงสมาชิกฟิวด์ของคลาส Product ได้ เนื่องจากสมาชิกฟิวด์เหล่านั้น (id, name, price) ต่างถูกห่อหุ้ม (encapsulation) ไว้ ซึ่งเป็นคุณสมบัติอย่างหนึ่งของภาษาเชิงวัตถุ (OOP)

รูปแบบการนิยามคลาส

[ attributes ] [ access_modifiers ] class identifier [ : base_class ]
{
     class_body
}
attributes เราจะไม่กล่าวถึง (เพราะเป็นขั้นสูง เช่น [NoIDispatch] เป็นต้น) คนละความหมายกับแอตทริบิวต์ที่หมายถึงฟิวด์ซึ่งเป็นหนึ่งในสมาชิกของคลาส
access-modifiers หมายถึง ระดับอนุญาตการเข้าถึงสมาชิกของคลาส หากไม่ระบุจะเป็น private
identifier หมายถึง ชื่อคลาส
base_class หมายถึง ชื่อคลาสที่ต้องการสืบทอด (คลาสแม่)
class_body หมายถึง โค้ดภายในคลาส

access modifiers
การเขียนโปรแกรมเชิงวัตถุ สามารถกำหนดระดับการเข้าถึงสมาชิก (ฟิวด์, พรอเพอร์ตี้, เมธอด ฯลฯ) โดยอาจอนุญาตให้โค้ดภายในคลาสเดียวกันเท่านั้นที่เข้าถึงสมาชิกได้ หรืออาจยอมให้โค้ดภายนอกขอค่าของฟิวด์ (get) แต่ไม่ให้แก้ไขค่าของฟิวด์ (set) ทั้งนี้แล้วแต่เจตจำนงของผู้เขียนโปรแกรม การกำหนดระดับการเข้าถึงสมาชิกนี้เรียกว่า Access Modifier หรือต่อไปจะเรียกว่า ระดับอนุญาต ดังตาราง
- ที่มา msdn.microsoft.com

public หมายถึง ทุกคลาสสามารถเข้าถึงสามาชิกได้
protected หมายถึง โค้ดภายในคลาสและคลาสที่สืบทอดเท่านั้นสามารถเข้าถึงสมาชิกได้
internal หมายถึง โค้ดภายในแอสเซมบลี (assembly) เดียวกันสามารถเข้าถึงสมาชิกได้
protected internal หมายถึง โค้ดภายในคลาสและคลาสที่สืบทอดแต่ต่างแอสเซมบลี สามารถเข้าถึงสมาชิกได้
private หมายถึง โค้ดเฉพาะภายในคลาสเท่านั้นสามารถเข้าถึงสมาชิกได้

การกำหนดระดับอนุญาต
เมื่อรู้จัก access modifier แล้ว ทดลองเพิ่มโค้ดบรรทัดที่ 12 ดังนี้

จากรูปเราสามารถเข้าถึงสมาชิกฟิวด์ price ได้ เพราะมีระดับอนุญาตเป็น public แสดงว่าระดับอนุญาตก่อนขั้นตอนนี้ (default) ของทุกฟิวด์คือ private โปรดสังเกตตารางต่อไปนี้
- ที่มา msdn.microsoft.com

เช่นนั้นเมื่อต้องการเข้าถึงสมาชิกฟิวด์ทุกตัวของคลาส Product จึงควรเปลี่ยนระดับอนุญาตเป็น public ทั้งหมดใช่หรือไม่ ? คำตอบคือไม่ใช่ทั้งหมด

กลไกที่ช่วยทำให้ภาษาเชิงวัตถุสามารถประกันความปลอดภัยของสมาชิกได้ คือระดับอนุญาตที่เป็น private เราควรกำหนดระดับอนุญาตอย่างเหมาะสม โดยปกติสมาชิกฟิวด์มักกำหนดระดับอนุญาตเป็น private และใช้พรอเพอร์ตี้เป็นประตูทางออกเพื่อขอค่าหรือกำหนดค่าแทน ดังตัวอย่าง

รูปข้างต้น คำสั่ง get หมายถึง ขอค่า ส่วนคำสั่ง set หมายถึง กำหนดค่า โดยสมาชิกฟิวด์อาจมีทั้ง get และ set หรือมีอย่างใดอย่างหนึ่งก็เป็นได้

รูปแบบการนิยามพรอเพอร์ตี้
[ access-modifiers ] [ return_type ] identifier
{
     [ get_accessor ]
     [ set_accessor ]
}
return_type หมายถึง ไทป์ที่ถูกดำเนินการกับสมาชิกฟิวด์ ซึ่งมักเป็นไทป์เดียวกับสมาชิกฟิวด์
identifier หมายถึง ชื่อของพรอเพอร์ตี้ มักใช้ชื่อเดียวกับสมาชิกฟิวด์ เพียงแต่อักษรตัวแรกเป็นพิมพ์ใหญ่ เช่น Id, Name, Price เป็นต้น
get_accessor หมายถึง อนุญาตให้อ่าน (ขอ) ค่าสมาชิกฟิวด์ได้
set_accessor หมายถึง อนุญาตให้เขียน (กำหนด) ค่าสมาชิกฟิวด์ได้

     get accessor
     get
     {
          return expression
     }
expression หมายถึง นิพจน์คำนวณต่างๆรวมถึงชื่อสมาชิกฟิวด์ที่ต้องการอ้างถึง

     set accessor
     set
     {
          identifier = value
     }
identifier หมายถึง ชื่อสมาชิกฟิวด์ที่ต้องการอ้างถึง โดยมี value เป็นค่าใหม่ที่กำหนดมาให้
***หมายเหตุ คำสั่ง value จะมีไทป์เดียวกับ return_type เสมอ

P15_ClassAndProperties
- สร้างโปรเจกต์ใหม่เพิ่มเข้าไปยังโซลูชัน CsharpTutorialForFriends เหมือนเคย
- ตั้งชื่อมันว่า P15_ClassAndProperties
- โค้ดเพิ่มดังนี้

แบบฝึกหัด
- จงให้เหตุผลว่าเหตุใดคำสั่งภายในสี่เหลี่ยมสีส้ม ณ รูปข้างต้น จึงเกิดความผิดพลาด
- จงปรับปรุงพรอเพอร์ตี้ชื่อ Price ให้สามารถกำหนดค่าสมาชิกฟิวด์ชื่อ price ได้

วันจันทร์ที่ 22 พฤศจิกายน พ.ศ. 2553

บทความที่เกี่ยวข้องกับภาษา Objective-C

เกร็ดเล็กเกร็ดน้อย
- มาทำความรู้จักกับ Objective-C กันเถอะ
- เครื่องมือเขียนโค้ด Objective-C สำหรับ Windows
- Foundation.h อยู่ไหน ?
- ค้นหา NXConstantString ไม่พบ
- การ Compile ไฟล์ Interface, Implementation และ Main รวมกัน

เรียนรู้ภาษา Objective-C จากเพื่อนสู่เพื่อน
- Objective-C โปรแกรมแรก
- นิยามของคลาส, เมธอด และฟังก์ชัน
- การสร้างคลาสและนำไปใช้
- การสร้างเมธอดและนำไปใช้

Event

จากบทความที่ผ่านมา เมื่อเพื่อนๆคลิกที่ปุ่ม มันควรมีอะไรเกิดขึ้นบ้าง สิ่งที่จะเกิดขึ้นเมื่อคลิกที่ปุ่มนี้เราเรียกว่า เหตุการณ์ (event) ครับ
- สร้างโปรเจกต์ใหม่เพิ่มเข้าไปยังโซลูชัน CsharpTutorialForFriends เหมือนเคย
- ตั้งชื่อมันว่า P14_Event
- เพิ่ม References ชื่อ System.Windows.Forms และ System.Drawing
- คัดลอกโค้ดจากโปรเจกต์ที่แล้ว P13_ButtonAndTextBox มาเพิ่มคำสั่งใหม่ (ในกรอบสีส้ม)
- โค้ดทั้งหมดแสดงได้ดังนี้

- ผลลัพธ์

ออบเจกต์มีเหตุการณ์เป็นของตัวเอง
นอกจากแต่ละออบเจกต์จะมีพรอเพอร์ตี้และเมธอดแล้ว มันยังมีเหตุการณ์เป็นของตัวเอง โดยแสดงเป็นรูปฟ้าผ่า

การกำหนดเหตุการณ์
เมื่อ . (dot) ตามหลังอินสแตนท์แล้ว Visual Studio จะแสดง pop up รายการคำสั่งที่สัมพันธ์กับออบเจกต์ที่ถูกอ้างอิง
- ให้เลือกที่เป็นรูปฟ้าผ่า ตัวอย่างนี้เลือกคำสั่ง Click โดยอาจพิมพ์เป็นคำสั่ง หรือพิมพ์บางส่วนแล้วกดปุ่ม enter เลยก็ได้
- จากนั้นให้พิมพ์ต่อด้วยเครื่องหมาย += แล้วกดปุ่ม Tab ครับ Visual Studio จะสร้างโค้ดให้ (ส่วนที่ขีดเส้นใต้สีเขียว) ดังรูป

- แดร็กเม้าส์รวบข้อความ buttonClick แล้วคัดลอก (copy) ไว้ก่อน

สร้างเหตุการณ์
- สร้างเหตุการณ์โดยนำหน้าด้วยคำสั่ง static (เพื่อให้ Main มองเห็น) ตามด้วยคำสั่ง void (ระบุว่าไม่ส่งค่ากลับ)
- แล้ววาง (paste) ข้อความ buttonClick ที่คัดลอกไว้ต่อไปดังรูป
***โปรดสังเกต เหตุการณ์นี้มีชื่อว่า buttonClick หากเราต้องการเปลี่ยนเป็นชื่ออื่น จะต้องเปลี่ยนสองตำแหน่งด้วยกันคือ
     - หลังคำสั่ง EventHandler ในส่วนกำหนดเหตุการณ์ บรรทัดที่ 29
     - และ บรรทัดที่ 37 ในส่วนสร้างเหตุการณ์

- เราทราบว่าเหตุการณ์จะเกิดขึ้นต่อเมื่อผู้ใช้กระทำบางอย่างกับโปรแกรม กรณีนี้คือ คลิก ที่ปุ่ม
- ระบุพารามิเตอร์ตัวส่ง มีไทป์เป็น Object หรือ object แล้วตั้งชื่ออะไรก็ได้ ในที่นี้ชื่อ sender
- ระบุพารามิเตอร์ตัวรับ มีไทป์เป็น EventArgs แล้วตั้งชื่ออะไรก็ได้ ในที่นี้ชื่อ e ดังรูป

ทราบได้อย่างไรว่าตัวส่งต้องมีไทป์เป็น Object ตัวรับต้องเป็น EventArgs ?
- ผมก็ไม่แน่ใจนัก แต่ผมอาศัยการสังเกต จากตัวอย่างในหนังสือ หรืออ่านจากคู่มืออ้างอิง เพราะแต่ละออบเจ็กต์อาจมีเหตุการณ์ต่างกัน ส่งผลให้ตัวส่งและตัวรับอาจต่างกันด้วย แล้วแต่กรณีไป
- รูปด้านล่างนี้ มาจาก msdn.microsoft.com

แบบฝึกหัด
- จากโค้ด จงเปลียนจากเหตุการณ์ Click เป็น DoubleClick แล้วแสดงข้อความว่า "You Double Click!" ออกทาง Console (จอดำ)

ตัวแปรคืออะไร ? แล้ว x = x + 1 ยังไงนะ ?

ต้องมีตัวแปรเก็บค่าของข้อมูล ?
อะไรคือตัวแปร ? : ตัวแปรคือสัญลักษณ์ที่เรากำหนดขึ้นเพื่อใช้สื่อความหมายกับค่าใดๆที่ไม่รู้ค่าที่แท้จริงของมัน หรือกล่าวว่ามันอาจเป็นไปได้หลายค่า เช่น ตัวแปรตัวหนึ่งชื่อ x สามารถเป็นค่า -10, 0, 30, 400, 5000 หรือเท่าใดก็ได้

แล้วทำไมต้องชื่อ x ? : จะใช้ชื่ออะไรก็ได้ แต่คนส่วนมากนิยมตั้งชื่อว่า x, y หรือ z หรือ a, b หรือ c เพราะมันเป็นอักษรภาษาอังกฤษ และง่ายต่อการจดจำ อย่างไรก็ตามควรตั้งชื่อตัวแปรให้สื่อความหมายถึงค่าของมัน เช่น ตัวแปรชื่อ count ชื่อนี้สื่อถึงการนับจำนวน ค่าที่อาจเป็นไปได้ตั้งแต่ 1, 2, 3, 4, 5, ... ไปเรื่อยๆ เป็นต้น

x = 1 หมายถึงอะไร ? : หมายความว่าเอาค่า 1 ทางขวาของเครื่องหมายเท่ากับ ให้กับตัวแปรชื่อ x ที่อยู่ทางซ้ายของเครื่องหมายเท่ากับไง

แสดงว่า x กับ 1 มีค่าเท่ากันสิค่ะ ? : ใช่ครับ เก่งมากเลย

x = x + 1 ยังไงนะ ? : ให้พิจารณา x + 1 ที่อยู่ทางขวาของเครื่องหมายเท่ากับก่อนครับ มันหมายความว่า ตัวแปร x มีค่าเท่าใดก็ตาม ให้เอาค่านั้นมาบวกด้วย 1 แล้วนำผลบวกที่ได้ ให้กับตัวแปรชื่อ x ที่อยู่ทางซ้ายของเครื่องหมายเท่ากับครับ

ตัวอย่างเช่น
เดิมตัวแปรชื่อ x มีค่าเป็น 2 ดังนั้นจากประโยคที่ว่า x + 1 จึงได้ค่าเป็น 2 + 1 มีค่าเป็น 3 แล้วนำค่าผลบวก 3 นี้ให้กับตัวแปรชื่อ x ทางซ้ายของเครื่องหมายเท่ากับอีกที ถึงตอนนี้ถ้าถามว่า x = x + 1 มีค่าเท่าใด ให้ตอบว่ามีค่าเท่ากับ 3 ครับ

เหตุการณ์ตัวอย่างที่ผมสมมติข้างต้นนี้จะเป็นประโยชน์มากสำหรับผู้ที่ไม่รู้และเริ่มหัดเขียนโปรแกรมใหม่ๆ แต่ถ้าเพื่อนๆรู้อยู่แล้ว อาจคิดในใจว่า "แบบนี้ก็เอามาเขียนอธิบาย ปัญญา....ชัดๆ" อันนี้ก็ไม่สมควรนัก เสมือนกับคนที่ขับรถไม่เป็น ประเด็นมันไม่ได้อยู่ที่ปัญญา...หรือไม่ ? มันอยู่ที่หัดขับแล้วหรือไม่ได้หัด รู้หรือไม่รู้ ทำนองนี้ อย่าไปว่าเขาเลย ยังไงผมก็เป็นกำลังใจให้กับเพื่อนๆที่ฝึกเขียนโปรแกรมทุกคนนะ ^^

วันอาทิตย์ที่ 21 พฤศจิกายน พ.ศ. 2553

ใช้อะไรเขียนโปรแกรมภาษา C/C++ ดีละ ?

เพราะเริ่มต้นเขียนโปรแกรมอย่างจริงจังด้วยภาษา C (ผมไม่ได้ชอบหรือจะบอกว่าภาษานี้ดีอย่างไรนะครับ เพียงแต่อ่านจากหนังสือที่ซื้อมาแล้วมันพอจะจิตนาการได้บ้าง แบบงูๆปลาๆ) จึงต้องหาตัวแปลภาษาของภาษา C เสียก่อน เท่าที่ผมทราบมา ภาษา C++ คือภาษาที่พัฒนาจากภาษา C ดังนั้นตัวแปลภาษา C++ จึงใช้ได้กับภาษา C ด้วย ได้แก่
- Dev C++ (ฟรี)
- Turbo C++ (ฟรี)
- Borland C++ (ฟรี)
- MinGW or GNUstep (ฟรี)
- Visual C++ 6.0 (มีลิขสิทธิ์)
- Visual Studio Express (ฟรี)
- Visual Studio Ultimate (จำกัดอายุใช้งาน 30 วัน)

เลือกดาวน์โหลดมาสักตัวหนึ่ง แล้วติดตั้งลงเครื่องคอมพิวเตอร์ของเรา ส่วนตัวผมชอบ Visual Studio Express ทำไมหน่ะหรือ ? เพราะว่าฟรีและหน้าตามันสวยดีครับ

ใช้งานเครื่องมือ Visual Studio Express อย่างไร ?
- เปิดโปรแกรม Visual Studio Express แล้วเลือก File -> New -> Project...

- ทางซ้ายสุดเลือก Templates เป็น Visual C++
- ตรงกลาง เลือกรูปแบบ Win32 Console Application (รูปแบบหน้าจอดำๆ เหมือน DOS ไง)

- ตั้งชื่อโปรเจกต์ในช่อง Name ในที่นี้ผมตั้งชื่อว่า P01_HelloWorld
- ระบุที่อยู่ของโปรเจกต์ ในที่นี้ผมระบุเป็น D:\ หรือใช้ปุ่ม Browse
- ตั้งชื่อโซลูชันในช่อง Solution name ในที่นี้ผมตั้งชื่อว่า MyCpp
***สังเกต จะต้องคลิกให้เกิด เครื่องหมายถูก ในช่อง Create directory for solution เสียก่อนจึงจะตั้งชื่อโซลูชันได้ครับ
- เสร็จแล้วกดปุ่ม OK

- อย่าพึ่งกดปุ่ม Finish นะครับ กดปุ่ม Next ไปก่อน

- เลือกสร้างโปรเจกต์แบบ Emply project (ว่างเปล่า)
- กดปุ่ม Finish

- เลือกเมนู View -> Solution Explorer

- จะปรากฏหน้าต่าง Solution Explorer
- คลิกขวา ณ Folder ชื่อ Source Files -> Add -> New Item...

- เลือก C++ File
- ตั้งชื่อไฟล์ในช่อง Name ในที่นี้ผมตั้งว่า Main
- กดปุ่ม Add

- ทดสอบการรันโปรแกรม HelloWorld ให้เพื่อนๆพิมพ์โค้ดดังนี้ในไฟล์ที่สร้างขึ้น

- เลือกเมนู Debug -> Start Without Debugging

- ผลลัพธ์

จากขั้นตอนทั้งหมดที่ผ่านมา เพื่อนๆอาจสงสัยว่าโซลูชันคืออะไร ?, เหตุใดต้องสร้างโปรเจกต์ด้วย ?, อะไรคือไฟล์ทีมีสกุลเป็น .cpp ?, หน้าต่าง Solution Explorer คืออะไร ?, โค้ดที่เขียนหมายความว่าอย่างไร ? งืมงำๆ... ผมพอจะทราบคร่าวๆดังนี้ครับ

โซลูชันนั้นใหญ่กว่าโปรเจกต์
มันมีหน้าที่รวบรวมโปรเจกต์ อาจเพราะโปรเจกต์มีความสัมพันธ์ต่อกันหรือมีเนื้อหาเดียวกัน อย่างไรก็ตามเราไม่กำหนดโซลูชันก็ได้ โดยนำ เครื่องหมายถูก หน้าช่อง Create directory for solution ออกเสีย

เมื่อเพื่อนๆใช้โซลูชันรวบรวมโปรเจกต์ มันจะงายดายมากหากเพื่อนๆต้องการเปิดทุกโปรเจกต์เหล่านั้นพร้อมกันทั้งหมด (เหตุผลแล้วแต่เพื่อนๆ) เพียงดับเบิลคลิกที่ไฟล์ที่มีนามสกุลว่า .sln ครับ

มีโปรเจกต์เพื่อรวบรวมงาน
โปรเจกต์ที่สร้างขึ้นจะประกอบด้วยไฟล์จำนวนหนึ่ง มีทั้งไฟล์ที่ Visual Studio สร้างให้ และไฟล์ที่เพื่อนๆสร้างขึ้นเอง

ในโปรเจกต์หนึ่งจะอนุญาตให้มีไฟล์ที่ประกอบด้วยฟังก์ชันชื่อ mainเพียงไฟล์เดียวเท่านั้น เพื่อบอกให้ตัวแปลภาษา C เริ่มแปลภาษา C นับจากฟังก์ชันชื่อ main นี้เป็นต้นไป

หากเราไม่รวมไฟล์ไว้เป็นโปรเจกต์แล้ว ภายหลังอาจสับสนได้ๆว่าไฟล์ไหนควรใช้กับโปรเจกต์ไหน (หรือเพื่อนๆมีวิธีจัดการที่ดีกว่าก็เป็นได้)

ไฟล์ภาษา C มีนามสกุลคือ .c ส่วนไฟล์ภาษา C++ มีนามสกุลคือ .cpp
ขณะนี้เราสนใจภาษา C แล้วภาษา C++ มาอย่างไร ? ภาษา C++ คือภาษาต่อเติมจากภาษา C ให้มีความสามารถที่เก่งกว่าสำหรับจัดการกับงานที่มีปริมาณมากกว่า ทว่าภาษา C และ C++ เป็นตระกูลเดียวกัน ตัวแปลภาษาที่เราโหลดมาสามารถเข้าใจได้ทั้งสองภาษา ฉะนั้นแม้ว่าเพื่อนๆตั้งชื่อไฟล์แล้วระบุสกุลเป็น .c หรือ .cpp ก็ไม่เป็นปัญหาสำหรับมัน

หน้าต่าง Solution Explorer จะแสดงส่วนประกอบของโปรเจกต์
ส่วนประกอบในที่นี้คือไฟล์ต่างๆภายในโปรเจกต์ ซึ่ง Visual Studio จะจำลองสภาพแวดล้อมให้ระดับหนึ่ง กล่าวคือมันจะแยกแยะให้ว่าไฟล์ไหนมีประเภทเป็นอะไร เช่น ไฟล์ Main.cpp ตามตัวอย่างมีประเภทเป็น Source File เป็นต้น โดยสภาพแวดล้อมจำลองนี้ไม่มีผลต่อที่อยู่ของไฟล์ที่บันทึกไว้ในเครื่องคอมพิวเตอร์ของเรา

โค้ดที่เขียนมีความหมายว่าอย่างไร ?
มีความหมายว่าต้องการแสดงประโยคว่า Hello World ออกทางจอภาพ (ดำๆ) ส่วนรายละเอียดปลีกย่อยของภาษา C ผมกล่าวถึงใน หมวดภาษา C/C++ ครับ

เขียนโปรแกรมไม่เป็น คิดไม่ออก ?

พึ่งเริ่มหัดเขียน ไม่รู้เรื่องเลย
เพื่อนๆผมบางคนจำเป็นต้องเขียนโปรแกรม เขาถามผมว่าควรเริ่มต้นอย่างไรดี แหม! ผมเองยังไม่รู้ตัวเองเลยว่าที่เขียนอยู่ทุกวันนี้ เรียกว่าเขียนโปรแกรมเป็นหรือเปล่า ? (หัวเราะ)

แต่เอาหล่ะ มีคำตอบดีกว่าปล่อยให้ว่างเปล่าจริงไหม ? ผมเริ่มเขียนโปรแกรมจากภาษา pascal ครับ ชื่อหนังสือคือ "การเขียนโปรแกรมประมวลผลข้อมูลด้วย เทอร์โบปาสคาล"
แต่สุดท้ายก็ไปไม่รอด ไม่ใช่เพราะหนังสือเขาเขียนไม่ดีนะครับ แต่ผมไม่ใส่ใจ หมดความอดทนไปเสียก่อน สาเหตุที่ยอมแพ้เพราะพิมพ์ยังไม่คล่อง เกิดความรำคาญที่พิมพ์ผิดบ่อยๆ เมื่อรันโปรแกรมก็พบความผิดพลาด (error) บ่อย แก้ไขไม่เป็น เลยหันไปเล่นเกม, คุย msn, facebook หรือทำอย่างอื่นแทน หนักๆก็จะปิดเครื่องคอมพิวเตอร์ไปเลย เพื่อนๆเป็นเหมือนผมหรือเปล่าเอ่ย ?

แล้วใครล่ะ จะช่วยผม ?
ผมจำเป็นต้องเขียนโปรแกรมเพื่อใช้ในการสอบที่มหาวิทยาลัย ผมควรทำอย่างไรดี ? ...เช้าของวันใหม่ผมจึงไปมหาวิยาลัย ได้พบกับเพื่อนหลายคนที่คุยกันเรื่องโปรแกรมและวิชาที่ต้องสอบด้วยการเขียนโปรแกรม ผมดีใจมาก จึงตรงไปหาพวกเขา ถามหาวิธีการครับ

...ผมตามไม่ทัน คิดไม่ออก อะไรคืออัลกอริทึมที่พวกเขาพูดบ่อยๆ แล้ว flow chart ที่ขีดๆเขียนๆมันใช้อธิบายลำดับการทำงานของโปรแกรมอย่างไรกันนะ แม้เพื่อนจะพยายามอธิบายมากเท่าใด เปรียบประดุจบังคับให้ผมวิ่งทั้งที่ผมหมดแรงแล้ว สุดท้ายก็ได้แต่พยักหน้างกๆ จำๆไป ไม่รุสิครับ ด่าผมก็ได้ ยังไงผมก็ได้แต่จำ (หัวเราะ)

เย็นของวันนั้นผมไปร้านหนังสือ เพื่อนของผมเหล่านั้นพวกเขาก็มาด้วย พวกเขาแนะนำหนังสือเล่มโน้นเล่มนี้ ดีอย่างนั้น สุดยอดอย่างนี้ อื่ม... "ก็ดีนะ" เอ๋ "อย่างนั้นเหรอ" ได้แต่ตอบส่งๆไป... (อย่าแนะนำเลย ผมไม่เข้าใจเนื้อหามันสักนิด แล้วจะเอาความอยากอะไรไปซื้อ) สักพักจึงกลับห้อง ไม่ซื้อสักเล่ม

ไม่ได้การแล้ว เป็นแบบนี้แล้วเมื่อไหร่ผมจะเขียนโปรแกรมเป็น วันต่อมาจึงไปร้านหนังสืออีกครั้ง คราวนี้ไม่มีใครมาด้วย เลยยืนอ่านเล่มที่สนใจ อ่านเฉพาะคำนำไปก่อน เปิดดูสารบัญว่ามีเนื้อหาตามที่เพื่อนแนะนำว่าจะต้องใช้หรือไม่ สุดท้ายเลือกได้เล่มหนึ่งครับ ชื่อหนังสือว่า "คู่มือการเขียนโปรแกรมภาษา C ฉบับผู้เริ่มต้น"
เลือกหนังสือที่เพื่อนๆคิดว่าอ่านแล้วตัวเองเข้าใจ ใช้ภาษาง่ายๆ ไม่ทับศัพท์หรือลงรากศัพท์ภาษาไทยมากนัก และควรตระหนักว่าหนังสือหนึ่งเล่มไม่สามารถตอบสนองความต้องการทุกด้านของเราได้ เฉกเช่นร้าน seven eleven ที่ไม่มีคอมพิวเตอร์ขายนั่นละครับ (เกี่ยวยังไง หัวเราะ)

เอาล่ะ เราต้องเป็นเจ้านายตัวเอง ไม่ว่าจะเกิดอะไรขึ้น ทุนคือแรงกายของผม ผุ้สนับสนุนอย่างเป็นทางการคือสภาพจิตใจที่เข้มแข็ง กำไรคือความรู้ซึ่งมาพร้อมทักษะที่ค่อยๆพัฒนาอย่างไม่รู้ตัว... เป็นกำลังใจให้นะเพื่อนๆทุกคน (ยิ้ม)

วันพฤหัสบดีที่ 18 พฤศจิกายน พ.ศ. 2553

รวมคำถาม-คำตอบของเพื่อนๆ

- เขียนโปรแกรมไม่เป็น คิดไม่ออก ?
- ใช้อะไรเขียนโปรแกรมภาษา C/C++ ดีละ ?
- ตัวแปรคืออะไร ? แล้ว x = x + 1 ยังไงนะ ?
- โปรแกรมแบบโครงสร้างคืออะไร ?
- ความหมายและหน้าที่ของคำเหล่านี้ class, static, public, void ?
- ออกแบบ Grammar วิชา Compiler

Button และ TextBox

รู้จักกับคลาส, สตรักและอื่นๆ
จากรูปข้างต้นนี้ เพื่อนๆได้เขียนโค้ดเพื่อใช้งานคลาส, สตรัก, ออบเจกต์, พรอเพอร์ตี้, เมธอดและอื่นๆมาแล้ว โปรดสังเกตว่าชื่อ (อักษรนำ) ของมันเหล่านั้นขึ้นต้นด้วยพิมพ์ใหญ่ทั้งสิ้น และถูกระบายเป็นสีฟ้าโดย Visual Studio (เปลี่ยนสีได้ครับ) สำหรับคลาสและสตรัก นอกจากนั้นเป็นสีดำ

คลาส (class) คืออะไร ?
คลาสคือการนิยาม (สร้าง) ไทป์ใหม่ อาจเกิดขึ้นจากการประกอบไทป์เดิมที่มีอยู่แล้ว ภาษา Object Oriented Pogramming (OOP) อย่าง C++ และ Java ล้วนสนับสนุนให้นิยามไทป์ใหม่ทั้งสิ้น

ผมจะไม่เอ่ยถึงการนิยามคลาสตอนนี้นะครับ แต่จะกล่าวถึงการนำคลาสจาก .NET มาใช้งานที่เกี่ยวข้องกับการติดต่อฐานข้อมูล โดยทำเป็น application ตัวอย่างเล็กๆ

การนิยามคลาสภาษา C# จากเพื่อนคนอื่นๆ
- www.codetoday.net

สตรัก (struct) คืออะไร ?
สตรักคือการนิยาม (สร้าง) ไทป์ใหม่เช่นเดียวกับคลาส และคล้ายกับคลาสมาก แตกต่างกันเพียงสตรักเป็น value type ส่วนคลาสเป็น reference type

ผมจะไม่เอ่ยถึงการนิยามสตรักตอนนี้นะครับ หาก application ตัวอย่างอาจมีบางส่วนที่เรียกใช้งานสตรัก เมื่อถึงตอนนั้นจึงค่อยพูดถึงการนิยามสตรักก็แล้วกัน

พรอเพอร์ตี้ (properties) คืออะไร ?
คือคุณสมบัติ เป็นหนึ่งในสมาชิกของคลาสและสตรัก ซึ่งจะกำหนดให้มีหรือไม่ก็ได้ (เราเขียนเอง) พรอเพอร์ตี้มักเป็นสมาชิกแบบ public data (ถ้าไม่เข้าใจให้อ่านผ่านไปก่อนนะครับ) แต่แท้จริงแล้วมันคือเมธอดชนิดพิเศษที่เรียกว่า accessors (สำหรับกำหนดค่าหรือขอค่าของฟิวด์)

เมธอด (method) คืออะไร ?
คือพฤติกรรมหรือกระบวนการ เป็นหนึ่งในสมาชิกของคลาสและสตรัก ซึ่งจะกำหนดให้มีหรือไม่ก็ได้ (เราเขียนเอง) เมธอดเป็นบล็อกของโค้ดที่มีคำสั่งเรียงกัน บล็อกเริ่มต้นจากเครื่องหมาย { และจบที่เครื่องหมาย }

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

ออบเจกต์ (object) คืออะไร ?
ในที่นี้ออบเจกต์ หมายถึง พื้นที่ที่ถูกจองในหน่วยความจำหลัก (ซึ่งแบ่งออกเป็นสองส่วนคือ หน่วยความจำหลักส่วน stack และหน่วยความจำส่วน heap) โดยคำสั่ง new

ถ้าใช้คำสั่ง new กับสตรัก จะเกิดออบเจกต์ของกล่อง value ในหน่วยความจำหลักส่วน stack

ถ้าใช้คำสั่ง new กับคลาส จะเกิดออบเจกต์ของกล่อง reference ในหน่วยความจำหลักส่วน heap ครับ

อินสแตนท์ (instance) คืออะไร ?
ในที่นี้อินสแตนท์ หมายถึง ชื่อที่กำหนดเป็นตัวอ้างอิง reference ซึ่งเก็บ address ของออบเจกต์ที่เกิดขึ้นจากคำสั่ง new โดยอาจเป็นอินสแตนท์ของคลาสหรือสตรักก็ได้

เราอาจประกาศอินสแตนท์ไว้ก่อน แล้วค่อยให้ค่ากับมันในบรรทัดถัดไป ตัวอย่าง
     Form form; /*สร้างอินสแตนท์ชื่อ form มีไทป์เป็น Form*/
     form = new Form(); /*ให้ค่า reference กับ form*/

หรือประกาศและให้ค่าทันทีในบรรทัดเดียวกัน ตัวอย่าง
     Form form = new Form();

เมื่ออ้างถึงอินสแตนท์เราสามารถใช้เครื่องหมาย . (dot) เพื่อเข้าถึงสมาชิกพรอเพอร์ตี้หรือเมธอดของออบเจกต์ได้ ตัวอย่าง
     form.BackColor = Color.Pink; /*กำหนดค่าสีชมพูให้กับพรอเพอร์ตี้ BackColor*/
     form.Controls.Add(textBox); /*เพิ่มออบเจกต์ text box โดยเมธอด Add*/

บางครั้งการเรียกอินสแตนท์ว่าออบเจกต์ก็ไม่ผิด ถ้ามันอ้างอิง (reference) ไปยังออบเจกต์นั้นจริง

ตัวแปร (variable) คืออะไร ?
ในที่นี้ตัวแปร หมายถึง ชื่อที่ถูกกำหนดเพื่อใช้อ้างอิงหน่วยความจำหลักส่วน stack โดยค่า (value) ของมันไม่ได้มาจากคำสั่ง new กล่าวคือเป็นการกำหนดค่าคงที่ให้เสียมากกว่า ตัวอย่าง
     int a = 10; /*เรียก a ว่าตัวแปรของไทป์ int*/
แต่ถ้าเขียนเป็น
     int a = new int(); /*เรียก a ว่าอินสแตนท์ของออบเจกต์ int*/

และมักเรียกตัวแปรต่างจากฟิวด์ เนื่องจากมักนิยามให้มันเป็นตัวประเภท local variable ที่ประกาศขึ้นภายในพรอเพอร์ตี้, เมธอดหรือคอนสตรักเตอร์เท่านั้น

คำสั่ง new คืออะไร ?
คำสั่งเพื่อสั่งจองพื้นที่ในหน่วยความจำหลัก มักตามหลังคำสั่งนี้ด้วยคอนสตรักเตอร์

คำสั่ง static คืออะไร ?
คำสั่งเพื่อกำหนดให้ CLR จองหน่วยความจำให้กับสมาชิกที่กำหนด static ทันที แม้ว่าพื้นที่ดังกล่าวจะถูกเรียกไปใช้หรือไม่ก็ตาม เรียกอีกอย่างว่าสมาชิกแบบ global (ใช้ร่วมกัน)

ตัวอย่างการประกาศและใช้งานสมาชิก static จะกล่าวถึงในโอกาสต่อไปครับ

***หมายเหตุ
- ฟิวด์ (field) หมายถึง สมาชิกของคลาสหรือสตรัก (ภาษาจาวาเรียกว่า แอตทริบิวต์ (attribute)) สำหรับเก็บค่า (value) ข้อมูล ซึ่งเพื่อนๆจะเห็นชัดเมื่อกล่าวถึงเรื่องการนิยามคลาสหรือสตรัก
- คอนสตรักเตอร์ (constructor) หมายถึง เมธอดพิเศษในคลาสหรือสตรัก และจะทำงานอัตโนมัติเมื่อเราสร้างออบเจกต์ด้วยคำสั่ง new ซึ่งเพื่อนๆจะเห็นชัดเมื่อกล่าวถึงเรื่องการนิยามคลาสหรือสตรัก

รู้ได้อย่างไรว่าคำไหนเป็นคลาสหรือเป็นสตรัก ?
เมื่อใช้เครื่องมือเขียนโค้ดจาก Microsoft Visual Studio ให้ลองเอาเมาส์แตะที่ชื่อคลาสหรือสตรักที่สงสัย
รูปด้านล่าง เพื่อนๆจะเห็นว่า Form เป็นคลาส

รูปด้านล่าง เพื่อนๆจะเห็นว่า Color เป็นสตรัก


Visual Studio ใช้สัญลักษณ์ช่วยแยกแยะไทป์แต่ละประเภท
โปรดสังเกตรูปสัญลักษณ์ภายในวงกลม (หรือรี) เหล่านี้

เพราะในขณะที่เพื่อนๆเขียนคำสั่ง เจ้า pop up ช่วยเหลือนี้จะปรากฏขึ้นมาทุกครั้ง
หากไม่ปรากฏ ต้องแน่ใจว่า cursor อยู่ในตำแหน่งเหมาะสมแล้วกด Ctrl + Space bar

ขอแค่ส่งไทป์ให้ตรงกันก็ชนะไปกว่าครึ่งทางแล้ว!
อย่างที่เราทราบกันว่าไลบรารี .NET ประกอบด้วยไทป์ทั้งนั้น
ตัวอย่าง รูปด้านล่างนี้เลือกใช้เมธอด Run เพื่อสร้างชิวิต (กระตุ้น thread) ให้กับออบเจกต์ของคลาส Form

ดังนั้นเมื่อไทป์ของอินสแตนท์ form ตรงกับไทป์ของพารามิเตอร์ของเมธอด Run มันจึงยอมรับ
***สังเกต รูปด้านบนนี้เราสามารถใช้เมาส์คลิกที่สามเหลี่ยมในวงกลม เพื่อเลือกไทป์หรือลำดับไทป์ของพารามิเตอร์ของเมธอด Run ได้

P13_ButtonAndTextBox
- สร้างโปรเจ็กค์ใหม่เพิ่มเข้าไปยังโซลูชัน CsharpTutorialForFriends เหมือนเคย
- ตั้งชื่อมันว่า P13_ButtonAndTextBox
- เพิ่ม References ชื่อ System.Windows.Forms และ System.Drawing
- โค้ดเพิ่มดังนี้

- ผลลัพธ์

แบบฝึกหัด
- จากโค้ดจงแยกแยะคำสั่งออกเป็น
     คลาส ได้แก่ ?
     สตรัก ได้แก่ ?
     พรอเพอร์ตี้ ได้แก่ ?
     เมธอด ได้แก่ ?
     ออบเจกต์ ได้แก่ ?
     อินสแตนท์ ได้แก่ ?

วันพุธที่ 17 พฤศจิกายน พ.ศ. 2553

MSDN ช่วยฉันด้วย

ไทป์คือทุกอย่างของไลบรารี่ .NET
เมื่อเราต้องการพัฒนา application จาก .NET เวลาส่วนใหญ่หมดไปกับการออกแบบตัว application และการใช้งานไทป์ สำหรับการใช้งานไทป์ Microsoft แนะนำใหัใช้เอกสารอ้างอิงที่เรียกว่า Microsoft Development Network หรือ MSDN ซึ่งมีทั้งแบบ offline และ online ครับ

ตัวอย่างการใช้งาน MSDN online
- สมมติต้องการรู้จักกับคลาส Form
- ไปที่ MSDN online
- ให้พิมพ์คำว่า Form ลงไปดังรูป แล้วกดปุ่มค้นหาหรือกด Enter

- จะปรากฏหัวข้อเรื่องให้เลือกมากมาย อ่านรายละเอียดเล็กน้อย แล้วเลือกหัวข้อเรื่องที่ต้องการ จากรูปผมเลือกหัวข้อแรกครับ

- ให้สังเกตสามจุดในรูปด้านล่างที่ผม mark ไว้
- ในกรอบสีเหลี่ยมส้มนั้นสำคัญมาก มันบอกว่าคลาส Form นี้สืบเชื้อสายมาจากใครบ้าง
- ส่วนวงรีอีกสองวง เราก็เลือกเป็นภาษา C# และหากต้องการนำโค้ดไปใช้ก็ให้คลิกที่ Copy ง่ายดีใช่ไหมละ ?

- นอกจากนี้มันยังบอกเราด้วยว่าคลาส Form ประกอบด้วย constructors, properties, methods, evens และอื่นๆพร้อมรายละเอียดอีกเล็กน้อย

งานของเราคือพยายามใช้มันให้เกิดผล ถ้าถามผม ผมมักจะทำแบบนี้
- ผมจะจดจำว่าไทป์ (คลาส, สตรัก, primitive types) นั่นชื่อว่าอะไร
- นำไปค้นใน MSDN
- ตรวจดูว่า constructor ของมันรับไทป์หรือไม่ ถ้ารับมีอะไรบ้าง เคยรู้จักไทป์นั้นบ้างไหม
- ตรวจดูว่า properties หรือ method เหล่านั้นมีหน้าที่อะไร ตรงตามจุดประสงค์ของผมหรือไม่ ถ้าตรงจะต้องส่งไทป์อะไรให้มันบ้าง และมันคืนค่าอะไรออกมา
- ตรวจดูว่า even ของมันได้แก่อะไรบ้าง ตรงตามจุดประสงค์หรือไม่ ถ้าตรงมันตรวจจับคลาสอะไร เรารู้จักหรือยัง
- แล้วทดลองนำมาใช้ อะไรไม่รู้จักก็ไปค้นใน MSDN อีก ทำต่อไปจนกว่าจะใช้เป็น ไม่ก็โดดไปหาใน google

ฉันไม่เข้าใจ constructor, properties, method อะไรพวกนั้น มันคืออะไร ?
แท้จริงผมอยากอธิบายเสียตอนนี้ แต่เอาไว้บทความต่อไปแล้วกัน อยากให้ลองทำตามตัวอย่างต่อไปนี้

P12_MSDN_HelpMe
- สร้างโปรเจ็กค์ใหม่เพิ่มเข้าไปยังโซลูชัน CsharpTutorialForFriends เหมือนเคย
- ตั้งชื่อมันว่า P12_MSDN_HelpMe
- ณ หน้าต่าง Solution Explorer ของโปรเจ็กต์นี้ ให้เพิ่ม Reference โดยคลิกขวาที่ References -> Add Reference...

- เลือกแท็บไลบรารี่ .NET
- เลือก component ชื่อ System.Windows.Forms
- กด OK

- เขียนโค้ดดังรูปในบรรทัดที่ 6 เพื่อลดการอ้างถึงเนมสเปชที่ยาวมากไปในอนาคต

- บรรทัดที่ 14 ภายในรูปด้านล่าง เขียนโค้ดเพื่อสร้างออบเจ็กต์ของคลาส Form จากคำสั่ง new Form();
- บรรทัดที่ 16 ภายในรูปด้านล่าง เขียนโค้ดเพื่อให้ออบเจ็กต์ข้างต้นมีชีวิต (แท้จริงมีรายละเอียดมากมาย) ด้วยคำสั่ง Application.Run

- ผลลัพธ์

แบบฝึกคิด
- จงให้เหตุผลว่าเหตุใดจึงต้องเพิ่ม component ชื่อ System.Windows.Forms ?
- ไม่ใช้คำสั่ง using System.Windows.Forms; ได้หรือไม่ อย่างไร ?
- ผมทราบได้อย่างไรว่าคำสั่ง new Form(); สามารถถูกเรียกให้ทำงานได้ ?
- reference ของออบเจ็กต์ที่เกิดจากคำสั่ง new Form(); ถูกส่งให้กับตัวแปรชื่อ (โอกาสหน้าจะเรียกว่า อินสแตนท์) form และถูกจัดการแบบ value type ในหน่วยความจำใช่หรือไม่ เพราะเหตุใด ?

แบบฝึกหัด
- จากโปรเจ็กต์ชื่อ P12_MSDN_HelpMe เพิ่มโค้ดต่อไปนี้ไว้ ณ บรรทัดที่ 15 (หรือตามวิจารณญาณการจัดโค้ดของเพื่อนๆ) ดังรูป แล้วจงทำให้โปรแกรมนี้สามารถทำงานได้