วันอังคารที่ 11 กันยายน พ.ศ. 2555

Java and C# for MiniCompiler part 16-2

ในขณะนี้ถือว่าเราผ่านกระบวนการตัวคำมาแล้ว (ด้วยดี) ต่อไปคือการอ่านคำเหล่านั้นเพื่อตรวจสอบกับ Grammar ด้านล่างนี้

A5 ::= B5 M5
M5 ::= "+" B5 M5 | empty
B5 ::= N5 C5
C5 ::= "*" N5 C5 | empty
N5 ::= N | "(" A5 ")"

กระบวนการดังกล่าวเรียกว่า 'การตรวจสอบ Syntax' พร้อมกันก็ทำ Semantic เพื่อผลิต Intermediate Code เป็นผลลัพธ์

Java and C# for MiniCompiler part 16-1

ในขณะนี้ถือว่าเราผ่านกระบวนการตัวคำมาแล้ว (ด้วยดี) ต่อไปคือการอ่านคำเหล่านั้นเพื่อตรวจสอบกับ Grammar ด้านล่างนี้

A5 ::= B5 M5
M5 ::= "+" B5 M5 | empty
B5 ::= N5 C5
C5 ::= "*" N5 C5 | empty
N5 ::= N | "(" A5 ")"

กระบวนการดังกล่าวเรียกว่า 'การตรวจสอบ Syntax' พร้อมกันก็ทำ Semantic เพื่อผลิต Intermediate Code เป็นผลลัพธ์

วันเสาร์ที่ 11 สิงหาคม พ.ศ. 2555

Java and C# for MiniCompiler part 13-2

Java and C# for MiniCompiler part 13-1

Java and C# for MiniCompiler part 12

Java and C# for MiniCompiler part 11

- ข้ามไปก่อนนะครับ

Java and C# for MiniCompiler part 10



- อธิบายเรื่อง Generic ของภาษาซีชาร์ป (ภาษาจาวาก็คล้ายกันนี่ล่ะครับ) หรือก็คือโครงสร้างข้อมูลที่ใช้ระบุตัวตนของข้อมูลที่ใช้ (มันคืออะไรเหรอ?)
       โครงสร้างข้อมูลที่ว่านี้ก็คือคลาสจำพวก ArrayList, LinkedList, Hashtable เป็นต้น ซึ่งโดยทั่วไปแล้วจะมีบริการเพื่อเพิ่ม (Add), ลบ (Remove), ขอจำนวน (Count, size), ขอข้อมูล ([ ], get) ฯลฯ

- เหตุใดต้องใช้ Generic ด้วยล่ะ (วีดีโอบอกไว้อยู่แล้ว)
       สมมติเราต้องการเขียนโปรแกรมจัดเก็บอะไรสักอย่างหนึ่ง (ไม่ระบุเจาะจง) และได้ออกแบบคลาสชื่อ MyArrayList ไว้ดังนี้

class MyArrayList
{
       private Object[] elements;
       private int count;

       public MyArrayList() : this(10) { }

       public MyArrayList(int size)
       {
              elements = new Object[size];
              count = 0;
       }

       public void Add(Object e)
       {
              elements[count++] = e;
       }

       public Object Get(int i)
       {
              return elements[i];
       }

       public int Count
       {
              get { return count; }
       }
}

       ทีนี้ก็นำไปเรียกใช้งานใน Main ดังนี้

MyArrayList ma = new MyArrayList();
ma.Add("Kittipong");
ma.Add(173);
ma.Add(65.5);
ma.Add('P');

for (int i = 0; i < ma.Count; i++)
{
              Console.WriteLine(ma.Get(i));
}

       โอโฮ้! โครงสร้างข้อมูล MyArrayList ของเราเก็บได้สารพัดนึกเลยครับ ไม่ว่าจะเป็น String, Integer, Floating-point หรือกระทั่ง Character นี่ก็คือสิ่งที่กล่าวว่า ไร้ Generic คือเป็นอะไรก็ได้ (มั่วกันไป) เหมือนจะดี แต่เขา (ใครก็ไม่รู้) มองว่ามันไม่ดีหรอก

       เปรียบเสมือน (เริ่มไร้สาระอีกแล้ว) หัวใจที่โลเลรักใครก็ได้ ไม่ว่าจะเป็นน้องเกต น้องอาร์ต น้องส้มโอ น้องแป้ง เจ้หมาน้อยหรือกระทั่งท่านต๋อง ชอบเขาไปหมด (ดีไหมล่ะแบบนี้) เมื่อมีการใช้ Generic คนหัวใจโลเลก็กลายเป็นคนซื่อสัตย์ ไม่ว่าจะกิน ไม่ว่าจะถ่าย ไม่ว่าจะมีความรักหรือนอน ต่างก็ระลึกถึงคนที่รักเพียงคนเดียว (รักเธอคนเดียวที่สุดในโลก) จะ Add จะ Remove จะ Get อย่างไรก็เธอคนเดียว อย่างนี้บ่งบอกว่าโครงสร้างข้อมูลนั้นใช้ Generic ด้วยครับผม และสัญลักษณ์ที่เห็นตั้งกะภาษา C++ ก็คือ <T> นั่นเอง (ย่อมาจาก Template และดูเหมือนจะนิยามการให้กำเนิดแตกต่างจาก Generic เล็กน้อย ต่างยังไงไม่ขอกล่าวถึงนะ อิอิ)

Java and C# for MiniCompiler part 9

- ข้ามไปก่อนนะครับ

วันอังคารที่ 17 กรกฎาคม พ.ศ. 2555

Java and C# for MiniCompiler part 7

       แนะนำตัวกันก่อน เริ่มจากสภาพแวดล้อมของ MS VS 2010 การแสดงหรือซ่อนหมายเลขบรรทัด ต่อจากนั้นคือโค้ดที่ MS VS 2010 เขียนให้ในไฟล์ Program.cs ครับ

วันพฤหัสบดีที่ 14 มิถุนายน พ.ศ. 2555

Java and C# for MiniCompiler part 6

ทุกครั้งที่สร้าง project ใหม่ เกิดอะไรขึ้นบ้าง Microsoft Visual Studio 2010 เตรียมอะไรไว้ให้ สำหรับภาษาซีชาร์ปดูกันก่อนเลย
- สร้าง project รูปแบบ Console Application ใหม่ชื่อว่า 'mainMethods'
- เน้นให้สร้าง Solution ด้วย ในที่นี้ชื่อว่า 'mainMethodsSolution' เท่ากับว่าบังคับให้เช็คถูก ณ ช่อง Create directory for solution โดยปริยาย
- แล้วคลิกปุ่ม 'ตกลง'

- ทีนี้ตามหา folder ของ project ที่เราได้บันทึกเอาไว้ ของผมคือที่ S:\mainMethodsSolution
- MS VS 2010 (เรียกย่อนะครับ) ได้สร้าง folder และไฟล์ที่มีนามสกุลลงท้ายด้วย .sln ซึ่งย่อมาจากคำว่า 'Solution' ไว้ภายใน
       หากคลิกที่ไฟล์ .sln ดังกล่าว project และส่วนประกอบทั้งหมดก็จะถูกเปิดโดย MS VS 2010 (ขณะนี้เปิดอยู่แล้วดังนั้นไม่ต้องดับเบิลคลิกเพื่อเปิดซ้ำ)

- ทีนี้เปิดเข้าไปใน folder ที่ชื่อเดียวกับ project ของเราที่ได้ตั้งชื่อไว้แต่แรก ในที่นี้คือ 'mainMethods'

ในเบื้องต้นอธิบายได้ว่า
- folder ชื่อ bin จะเก็บไฟล์ที่ผ่านการคอมไพล์เอาไว้ นั้นคือไฟล์สกุล .exe เราสามารถลบ folder นี้ทิ้งได้ เพราะเมื่อ project ถูกสั่งให้คอมไพล์ใหม่ folder ดังกล่าวนี้ก็จะถูกสร้างขึ้นอีก (ในบางครั้งหากสั่งคอมไพล์ project แล้วเกิด error ทั้งๆที่แน่ใจว่าโค้ดถูกต้อง ให้เพื่อนๆลองลบ folder ชื่อ bin นี้ก่อนแล้วค่อยสั่งคอมไพล์นะครับ)

- folder ชื่อ obj จะเก็บไฟล์และทรัพยากรอื่นๆที่จำเป็นต่อการคอมไพล์ในขั้นสุดท้าย คือก่อนที่ไฟล์และทรัพยากรเหล่านี้จะถูกจัดการ link จนกลายเป็นไฟล์สกุล .exe

- folder ชื่อ Properties จะมีไฟล์ AssemblyInfo.cs เพื่อบันทึกและกำหนดค่าเบื้องต้นให้กับ project ที่เราได้สร้างขึ้นมา ไฟล์นี้จะค่อยๆโตขึ้นเมื่อเราเพิ่มหรือเปลี่ยนแปลงการกำหนดค่าต่างๆใน project

- ไฟล์ชื่อ mainMethods.csproj คือไฟล์ project ของเรา ซึ่งเราสามารถคลิกเพื่อเปิด project เป็นการเฉพาะหากว่าไฟล์สกุล .sln ได้บรรจุ project ไว้มากกว่าหนึ่ง project

- ไฟล์ชื่อ Program.cs คือไฟล์ที่เขียนเมธอด Main ไว้ภายใน โดยตัวคอมไพล์จะมองหาไฟล์นี้เป็นไฟล์แรก (ตามค่าที่ถูกกำหนดมาในไฟล์ AssemblyInfo.cs) และเราจะศึกษาไฟล์นี้ต่อกันใน part หน้าครับ

วันอังคารที่ 12 มิถุนายน พ.ศ. 2555

Java and C# for MiniCompiler part 5

จาก part ที่แล้วที่ว่า คลาสใดๆจะใช้ public class และ Package กับ Name space คือสิ่งจำเป็นยิ่งที่จะใช้ระบุว่าคลาสหรือกลุ่มคลาสที่เราต้องการใช้งานนั้นอาศัยอยู่ ณ แห่งหนตำบลใด ใช่ครับ นั่นคือสามารถเรียกใช้คลาสหรือกลุ่มคลาสที่เตรียมไว้ให้ (ไลบรารี่มาตรฐาน) จากไลบรารี่ภาษาจาวาหรือภาษาซีชาร์ปก็ย่อมได้ หรือจะสร้างไลบรารี่ขึ้นมาเองก็ได้ ในขณะนี้ขอให้พิจารณาการเรียกใช้คลาสหรือกลุ่มคลาสจากไลบรารี่มาตรฐานก่อน ส่วนการสร้างเองนั้นหากมีโอกาสยัง part ต่อๆไปคงได้กล่าวถึง

กลับมาทบทวนฟังก์ชันหลักกันอีกสักครั้ง นั่นคือฟังก์ชัน main เราทราบแล้วว่า (คุยไปคุยมาจากคำว่า 'เพื่อนๆ' กลายเป็นคำว่า 'เรา' ไปซะได้ แฮ่ๆ) ภาษาจาวามีรูปแบบการเขียนฟังก์ชัน main ดังนี้
public static void main(String[] args)

ส่วนภาษาซีชาร์ปเขียนอย่างนี้
static void Main(String[] args)

อยากให้เราเข้าใจว่าเขากำหนดมันมาแบบนี้ก็เพื่อประโยชน์บางอย่าง เอาล่ะดูวีดีโอของคุณ Narinthone ต่อกันเลย


กล่าวโดยสรุปได้ว่า
- เขาเรียกฟังก์ชัน main ที่เราเข้าใจว่า 'เมธอด' (Method) ซึ่งตอนนี้ยังไม่ต้องสนใจว่าเหตุใดจึงเรียกแบบนั้น เอาเป็นว่าเรียกฟังก์ชันเป็นเมธอดตามเขาไปก่อนนะครับ
- เมธอดหลักนี้มีความสามารถที่จะทำงาน (ในที่นี้คือแสดงผลออกทางจอดำ) ด้วยตัวเอง (ที่จริงไม่ช่ายหรอกนะ ทำงานได้เพราะ Thread) และแต่ละคลาสมีเมธอดหลักได้หนึ่งเมธอดเท่านั้น
- เมธอดหลักที่ว่านี้เริ่มต้นจากคำว่า 'public' แล้วตามด้วยคำว่า 'static' ทั้งภาษาจาวาและซีชาร์ปต่างก็นิยามความหมายของสองคำนี้เหมือนกัน กล่าวคือ public เป็นสาธารณะ ใครก็สามารถมองเห็นแล้วนำไปใช้งานได้ ส่วน static หมายถึงทำให้มีอายุเท่ากับคลาส อั่นแน่ อายุเท่ากับคลาสอย่างนั้นเหรอ ? คืออะไรงะ ไว้ค่อยอธิบายใน part อื่นครับ
- พารามิเตอร์ของเมธอดหลักคือ String[] args โดยมีความหมายเดียวกับโค้ดด้านล่างนี้ของภาษาซี

จาวาและซีชาร์ป
ซี (รูปแบบที่ 1)
ซี (รูปแบบที่ 2)
String[] args
char** args
char* args[]

และเขาเรียกตัวแปรชื่อ args ว่าตัวแปรที่มีชนิดเป็น อาร์เรย์ของสตริง ซึ่งจะกล่าวอย่างละเอียดในภายหลัง (สำคัญมากเชียวล่ะ)

โอเค part นี้เนื้อหาเยอะเกินไปแล้ว มือใหม่อาจฉงนได้ ไว้เจอกันใหม่ครับเพื่อนๆ

วันจันทร์ที่ 11 มิถุนายน พ.ศ. 2555

Java and C# for MiniCompiler part 4

จาก part ที่แล้วๆมา ทบทวนอีกครั้ง เราจะสร้างคลาสขึ้นมาเพื่อบรรจุสิ่งที่มีความสัมพันธ์ต่อกันไว้ด้วยกัน สิ่งเหล่านั้นที่เรารู้จักคือ ตัวแปร และ ฟังก์ชัน สำคัญคือคลาสของเราจะเป็น public class (เอาแบบนี้ไปก่อน คือ เป็นคลาสที่อนุญาตให้ใครก็ได้นำไปใช้งาน) part นี้เราจะคุยกันเรื่อง Package และ Name space ของภาษาจาวาและซีชาร์ปตามลำดับครับ (สำคัญนะขอบอก!)


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

คือเล่าเป็นเรื่องเป็นราวได้

คราวนี้มาดูฝั่งภาษาซีชาร์ปบ้าง เราอาจเรียก Package สำหรับภาษาซีชาร์ปว่า Name space
- การสร้างที่เก็บคลาสหรือกลุ่มคลาส ภาษาซีชาร์ปเรียกว่า Name space
- เมื่อสร้าง Name space ใดๆ Name space เหล่านั้นจะห่อหุ้มลำดับของแต่ละ Name space ด้วยเครื่องหมาย { และ } และเข้าไปห่อหุ้มคลาสหรือกลุ่มคลาสอีกทีหนึ่ง
- แต่ละ Name space สามารถเข้าถึงด้วยเครื่องหมาย dot เช่นเดียวกับภาษาจาวา
- นิยามของ Name space คล้ายกับกล่องบรรจุของ คือในกล่องใบใหญ่ยังมีกล่องใบที่เล็กกว่า ในกล่องใบที่เล็กกว่ายังมีกล่องที่เล็กกว่าอีก และที่ว่าเล็กแล้วยังมีใบที่เล็กกว่านั้นอีก จวบกระทั่งพบคลาสหรือกลุ่มคลาสที่ต้องการ
ตัวอย่าง เมื่อเราต้องการเขียนโปรแกรมติดต่อฐานข้อมูล MS Office Access 2007 สิ่งที่เราควรคิดถึงคือ คลาสสำหรับติดต่อฐานข้อมูลดังกล่าวเก็บไว้ในกล่องใบไหน แน่นอนต้องเริ่มจากกล่องใบใหญ่ที่สุดก่อนแล้วไล่เปิดไปเรื่อยๆ ดังนี้
using System.Data.OleDb;

จากนั้นจึงจะใช้คลาส OleDbConnection, OleDbCommand, OleDbDataAdapter และอื่นๆที่เกี่ยวข้องได้

เอาละครับเบื้องต้นนี้ให้สนใจเพียงว่า Package และ Name space นั้นสำคัญมาก หากเรามีคลาสหรือกลุ่มคลาสแค่หยิบมือ (หนึ่งถึงสิบคลาสหรือมากกว่าอีกนิดหน่อย) เราอาจมองไม่เห็นว่าการสร้าง Package ในภาษาจาวาหรือ Name space ในภาษาซีชาร์ปนั้นมีประโยชน์อะไร ? ทว่าคลังของภาษาจาวาและซีชาร์ปในโลกสากลบรรจุคลาสไว้ภายในเป็นหมื่นถึงแสนคลาส แล้วจะจัดการคลาสมากมายปานนี้ได้อย่างไรล่ะ ? เพื่อให้ค้นหาง่าย แก้ไขง่าย ตลอดจนแบ่งจำพวกของมันออก เพราะเราไม่ต้องการโหลดหรือติดตั้งทั้งหมดนั่นลงในเครื่องคอมพิวเตอร์ของเราจริงไหม ? หรือเราต้องการทำแบบนั้นจริงๆ บ้า! เราคงไม่โง่พอจะเก็บทุกสิ่งไว้ในเป้แล้วแบกมันไว้บนหลังตลอดเวลาหรอก เชื่อสิ เราต้องการใช้งานเพียงไม่กี่คลาสเท่านั้นสำหรับงานของเรา รู้อย่างนี้แล้วสิ่งที่เราควรเร่งศึกษาก็คือ จะเลือกใช้คลาสที่มีเป็นกระบุงอย่างไรดี แต่ละคลาสทำอะไรได้บ้าง สร้างออบเจ็กต์ของคลาสอย่างไร เรียกใช้อย่างไรให้ได้ประสิทธิภาพเยี่ยมที่สุด เขียนโค้ดน้อยที่สุดทำนองนี้ เอาละครับไว้ part ต่อไปนะคนดี

วันพฤหัสบดีที่ 7 มิถุนายน พ.ศ. 2555

Java and C# for MiniCompiler part 3

ตามข้อตกลงจาก part ที่แล้วที่ว่า หนึ่งไฟล์ต่อจากนี้จะบรรจุเพียงหนึ่งคลาสเท่านั้น สำหรับ part นี้เรามาคุยกันสักนิดเกี่ยวกับการสร้างคลาสและนิยามการสร้างคลาสครับ (ก่อนที่จะมึนไปมากกว่านี้)

สร้างคลาสทำไม ? ภาษาซีไม่เห็นต้องสร้างเลย ?

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

ซี
#include <stdio.h>

void main() {
       printf("Hello World!");
}

โปรแกรมนี้ทำงานโดยนำเข้า (include) ไฟล์ไลบรารี่ที่ชื่อ stdio.h ซึ่งย่ามาจาก Standard Input Output ส่วน .h ย่อมากจาก header ซึ่งแปลว่า 'หัว'

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

แล้วฟังก์ชันคืออะไร ? มันก็คือส่วนหนึ่งของโปรแกรมที่เขียนขึ้นเพื่อลดทอนการเขียนโค้ดซ้ำซากหรือไม่ก็เป็นจุดเริ่มต้นการทำงานของโปรแกรม (อย่างฟังก์ชัน main นี่ไง)

อีกครั้งนะครับ โปรแกรมภาษาซีข้างต้นทำงานจากบนลงล่าง ดังนั้นพบ include ต่อไปก็พบฟังก์ชัน main หลังจากนั้นก็จะทำคำสั่งในฟังก์ชัน main คำสั่ง printf จะแสดงผลลัพธ์ออกทางจอดำ เป็นประโยคว่า "Hello World!" ก่อนจะจบฟังก์ชันและทำลายตัวเองทิ้ง (คืนหน่วยความจำ)

ตัวอย่างต่อไป

ซี
#include <stdio.h>

float summation(float x, float y) {
       return x + y;
}

void main() {
       printf("10 + 20 = %f", summation(10, 20));
}

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

float summation(float x, float y) ก็คือฟังก์ชันครับ (โปรแกรมนี้มีสองฟังก์ชันแล้วนะ คือ summation กับ main) ฟังก์ชัน summation ทำงานโดยรับค่าตัวเลขจำนวนจริงใดๆเข้ามาสองค่า ค่าแรกเก็บไว้ในตัวแปร x และค่าที่สองเก็บไว้ในตัวแปร y จากนั้นนำ x และ y มาบวกกัน ส่งผลลัพธ์ที่ได้ด้วยคำสั่ง return กลับไปยังจุดที่ฟังก์ชันนี้ถูกเรียกใช้งาน

ฟังก์ชัน summation นี้ถูกเขียนไว้ก่อนฟังก์ชัน main ไม่ได้หมายความว่าทำงานก่อน main นะครับ เพียงแต่เขียนเพื่อบอกเจ้าคอมไพล์เลอร์ว่ามี summation ที่ทำงานอย่างนี้อยู่ หากเรียกใช้ก็จะทำงานอย่างนี้ๆ ฉะนั้นที่บรรทัดที่เรียก summation ให้ทำงานอย่าง
printf("10 + 20 = %f", summation(10, 20));
เจ้าคอมไพล์เลอร์จึง อ๋อ ฉันรู้จักนะ ฉันรู้จัก summation นะ ใช่ๆ ก่อนที่จะพบฟังก์ชัน main ฉันเห็นและจดจำเขาไว้แล้ว ประโยคที่เขียนว่า summation(10, 20) ซึ่งอยู่ท้ายฟังก์ชัน printf จึงนำค่า 10 และ 20 ที่ระบุกำหนดให้กับตัวแปร x และ y ตามลำดับ จากนั้นบวกค่าของ x และ y แล้วส่งออกมาด้วยคำสั่ง return การกระทำเช่นนี้แหละครับเพื่อนๆที่เรียกว่า 'คืนค่า' มายังจุดที่ถูกเรียก ค่าที่ได้คือ 30 จึงถูกส่งออกมาแล้วนำไปวางไว้ตรงตำแหน่ง %f สุดท้ายได้ผลลัพธ์เป็น
10 + 20 = 30

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

กลับเข้าเรื่องดีกว่านะครับ ตัวอย่างภาษาซีข้างต้นไม่เห็นมีคำว่า class เลยจริงไหม แล้วภาษาจาวากับซีชาร์ปมี class ไว้เพื่ออะไรล่ะ ?

เหตุที่ต้องมี class ก็เพื่อจัดกลุ่มตัวแปร, ฟังก์ชัน และอะไรก็ตามเข้าไว้ด้วยกัน เพราะมันทำงานสัมพันธ์กันในทำนองว่าเป็นงานเดียวกัน หมวดหมู่เดียวกันประมาณนั้น

ตัวอย่างไฟล์ header หรือ 'หัว' ที่เรารู้จักชื่อ stdio.h ก็รวบรวมฟังก์ชันหรือค่าคงที่ที่เกี่ยวข้องกับการทำงานรับค่า (input) หรือแสดงค่า (output) เข้าไว้ด้วยกัน คำสั่ง printf จะไม่มีทางเรียกให้ทำงานได้หากปราศจากการนำเขาไฟล์ stdio.h ฉะนั้นภาษาใหม่ๆจึงพยายามรวบรวมเอาแนวทางการทำงานที่สอดคล้องกันหรืองานจำเพาะเข้าไว้ด้วยกัน ภายหลังเมื่อต้องการเรียกมาใช้งานก็จะง่ายขึ้น โดยการระบุชื่อหลังคำว่า class แล้วหุ้มด้วยเครื่องหมาย { } เพื่อบอกขอบเขตเริ่มต้นและสิ้นสุดของตัวมันเอง ลองดูนี่สิครับ

จาวา, ซีชาร์ป
class Calculator { }

ตามข้อตกลงใส่ 'public' ข้างหน้าคำว่า class จึงได้

จาวา, ซีชาร์ป
public class Calculator { }

ทีนี้เราก็ได้คลาสชื่อ Calculator หรือเครื่องคำนวณมาแล้ว อิอิ ง่ายชิมิ จากนั้นยกฟังก์ชัน summation ในภาษาซีใส่เข้าไป

จาวา, ซีชาร์ป
public class Calculator {
       float summation(float x, float y) {
              return x + y;
       }
}

ที่สุดเราก็ได้คลาสที่มีความสามารถในการคำนวณมาแล้ว พอประมาณก่อนครับ ไว้ต่อ part หน้านะเพื่อนๆที่รัก

วันอังคารที่ 5 มิถุนายน พ.ศ. 2555

Java and C# for MiniCompiler part 2

จาก part ที่ผ่านมาเพื่อนๆทราบแล้วว่าภาษาจาวาสามารถแสดงผลด้วยคำสั่ง println และภาษาซีชาร์ปแสดงผลด้วยคำสั่ง WriteLine ต่อไปเรามาทำความรู้จักกับคลาส (class) ของทั้งสองภาษากันดีกว่า


โดยสรุปปแล้วเขาพูดถึงเรื่อง
- การสร้างคลาสภาษาจาวาต้องประกอบด้วยคำว่า class แล้วตามด้วยชื่อ ในที่นี้มีสามคลาสสามชื่อคือ A, B และ JavaFile (เขียนสลับกันอย่างไรก็ได้นะ)
- ไฟล์ของภาษาจาวามีนามสกุล .java ในแต่ละไฟล์บรรจุได้มากกว่าหนึ่งคลาส
- และคลาสในไฟล์นั้นเป็น public class ได้เพียงคลาสเดียวเท่านั้น ซึ่งต้องมีชื่อเช่นเดียวกับไฟล์ดังกล่าว ตัวอย่าง ไฟล์ชื่อ JavaFile.java ดังนั้นคลาส JavaFile เพียงคลาสเดียวเท่านั้นที่มีสิทธิ์ใช้คำ 'public' นำหน้า คลาส A และ B ไม่มีสิทธิ์ (กลไกเช่นนี้คิดขึ้นเพื่ออะไร ?)

อธิบายเปรียบเทียบโค้ด

ถึงคราวภาษาซีชาร์ปแล้ว หนึ่งไฟล์มีได้กี่คลาส แต่ละคลาสเป็น public class ได้หรือไม่ มาดูกัน

จากโค้ดเราจะเห็นว่าชื่อไฟล์คือ Program.cs หมายความว่าไฟล์ภาษาซีชาร์ปมีนามสกุลเป็น .cs ภายในไฟล์นี้บรรจุคลาสไว้สามคลาสด้วยกัน ได้แก่ Program, A และ B เราจะเปรียบเทียบว่าคลาส Program ก็คือ JavaFile ในภาษาจาวา ซึ่งความคิดของทั้งสองภาษานี้แตกต่างกัน
- ภาษาจาวาคิดว่าหนึ่งไฟล์ควรมี public class เพียงคลาสเดียว (ซึ่งจะไม่มีเลยสักคลาสที่เป็น public class ก็ได้) ในเบื้องต้นนี้คำตอบคือให้สอดคล้องกับชื่อไฟล์และนิยามที่ว่า "หนึ่งไฟล์หนึ่งคลาส" กล่าวคือภาษาจาวานิยมให้สร้างหนึ่งไฟล์สำหรับบรรจุเพียงคลาสเดียว และให้คลาสนั้นใช้สิทธิ์ public class ได้อย่างเต็มที่ หากในเบื้องลึกคำตอบนี้จะเกี่ยวข้องกับโครงสร้างข้อมูลของคลาสย่อยที่ชื่อ Loader ที่มีหน้าที่โหลดคลาสเข้าสู่หน่วยความจำของเครื่องคอมพิวเตอร์เสมือน (Java Virtual Machine) ซึ่งจะไม่ขอกล่าวถึง (เรื่องมันยาว)
- ภาษาซีชาร์ปคิดว่าหนึ่งไฟล์ก็ควรมีเพียงหนึ่งคลาสเช่นกัน และไม่ได้ห้ามว่าต้องมี public class เพียงคลาสเดียว จะมีกี่ public class ก็ได้งานนี้ซีชาร์ปไม่แคร์สื่อค่ะ (แท้จริงเกี่ยวข้องกับตัวคอมไพล์ของภาษาซีชาร์ปเอง และมันเป็นเบื้องลึกเราจึงไม่ขอกล่าวถึงอีกเช่นเคย)

นอกประเด็นนิดหน่อยเกี่ยวกับเมธอดหลัก (main method) ของทั้งสองภาษา จากที่สังเกต

จาวาซีชาร์ป
public static void main(String[] args)static void Main(string[] args)

สำหรับภาษาซีชาร์ปเราสามารถเพิ่ม 'public' เข้าไปได้เช่นเดียวกับภาษาจาวา กลายเป็น
public static void Main(string[] args)

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

เอาล่ะแล้วฉันควรเขียนเป็น class เฉยๆหรือ public class ดีล่ะ คำตอบคือแล้วแต่งานและการออกแบบครับ การไม่เขียน public ให้คลาสในภาษาจาวาเท่ากับกำหนดขอบเขตเป็น default ต่างจากภาษาซีชาร์ปที่เป็น internal (อะไรคือ default และอะไรคือ internal ไม่เข้าใจ งง ? ไว้จะอธิบายอย่างละเอียดใน part อื่นซึ่งเป็นเรื่องของ access modifier) จากนี้ไปเราจะใช้ public class กับทุกๆคลาสที่สร้างขึ้นไปก่อน และแบ่งหนึ่งไฟล์สำหรับบรรจุเพียงหนึ่งคลาสเท่านั้น ประโยชน์คืออ่านชื่อไฟล์ก็ทราบชื่อคลาส ไม่ใช่อ่านชื่อไฟล์ยังต้องไปเปิดไฟล์ดูว่ามีคลาสอะไรบ้าง แบบหลังนี้ไม่เอานะเสียเวลา แล้วพบกันใน part หน้าเด้อ

วันจันทร์ที่ 4 มิถุนายน พ.ศ. 2555

Java and C# for MiniCompiler part 1

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

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


โดยสรุปแล้วเขาพูดถึงเรื่อง
- การโหลดและติดตั้ง Eclipse เพื่อใช้เป็นเครื่องมือสำหรับเขียนและแปลผลภาษาจาวา
- การสร้าง Package สำหรับระบุคลาสไว้ภายใน (ถาม : ไม่สร้าง Package ได้ไหม ?)
- คลาส HelloWorld กับการทักทายว่า "Hello World!"

ทีนี้มาติดตั้งเครื่องมือที่จะใช้เขียนและแปลภาษาซีชาร์ปกันบ้าง ปุ่มด้านล่างจะลิงค์ไปที่ Microsoft Visual Studio 2010 Express for C# ให้เพื่อนๆโหลดและติดตั้งไว้ในเครื่อง หากมีอยู่แล้วก็ให้ข้ามขั้นตอนเหล่านี้ไปได้เลยครับ


- เปิด Microsoft Visual Studio 2010 Express ขึ้นมา
- โดยเลือกไปที่ File >> New >> Project

- ในช่อง Installed Templates เลือก Visual C# >> Console Application

- ในส่วนล่างตั้งชื่อโปรเจ็กต์ว่า HelloWorldProject
- ในที่นี้ผมบันทึกไว้ ณ S:/ (แล้วแต่เพื่อนๆว่าจะเก็บไว้ที่ไหน)
- ตั้งชื่อ Solution ด้วย ในที่นี้ผมตั้งชื่อว่า HelloWorldProject_Solution (ตั้งชื่อ Solution เพื่ออะไร ?)
- ดูเครื่องหมายเช็คถูกในช่อง Create directory for solution ด้วยนะครับ (เช็คทำไม ?) แล้วกดปุ่ม OK

เราจะเห็นสภาพแวดล้อมที่ Microsoft Visual Studio จัดรูปแบบไว้ให้ ตอนนี้ให้สนใจไฟล์ที่ชื่อ Program.cs ซึ่งอยู่ในหน้าต่าง Solution Explorer ด้านขวาสุด (ไหน ? ไม่เห็นมีเลย)

- จากภาพ ณ บรรทัดที่ 12 (หาหมายเลขบรรทัดได้อย่างไร ?) เพิ่มโค้ดเข้าไปว่า
Console.WriteLine("Hello World!");


- สุดท้ายทดสอบ run โปรแกรม ด้วยการเลือกที่เมนูชื่อ Debug >> Start Without Debugging

ผลการ run


อธิบายเปรียบเทียบโค้ด

เพื่อนๆจะเห็นว่าโค้ดของจาวาและซีชาร์ปไม่ต่างกันมากนัก อาจมีข้อสงสัยเพียงเล็กน้อยเกี่ยวกับแนวคิดและไวยากรณ์ (syntax) ของแต่ละภาษา ตัวอย่างเช่น

จาวาซีชาร์ป
public class HelloWorldclass Program

ให้พิจารณาโดยการตัด public ของภาษาจาวาออกไปก่อน ก็จะได้โค้ดลักษณะคล้ายกันมากขึ้น

จาวาซีชาร์ป
class HelloWorldclass Program

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

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

เอาล่ะคิดมากไปใยในเมื่อภาษาซีชาร์ปเป็น class เฉยๆแต่แรกเริ่ม เราก็ยังสามารถบันดาลให้เขาเป็น public class ได้เฉกภาษาจาวา ด้วยการเติ่มคำว่า 'public' ไว้หน้าคำว่า 'class' ดังโค้ดด้านล่าง แล้วลอง run ดูสิครับ ผลก็เหมือนเดิมใช่ปะล่ะ
public class Program

ขอข้ามส่วนอื่นๆของโค้ดไปก่อน กระทั่งตรงนี้ครับ

จาวาซีชาร์ป
System.out.println("Hello World!");Console.WriteLine("Hello World!");

คำสั่ง println และ WriteLine ต่างก็ใช้สำหรับแสดงผลออกทางจอภาพนั่นเอง ส่วนจะเรียกมันได้อย่างไร หากเป็นภาษาจาวาต้องอ้างออบเจ็กต์ out จากคลาส System เสียก่อน ต่างจากภาษาซีชาร์ปที่สามารถเรียกจากคลาส Console ได้เลย (ง่ายกว่าปะล่ะ) จดจำการแสดงผลตรงนี้ไว้เพราะเราใช้บ่อยมาก ไว้เจอกัน part ต่อไปครับ