protect

ถ้าเอาบทความไปเผยแพร่แล้วไม่ให้เครดิต ดำเนินคดีด้วย พรบ. คอมพิวเตอร์ฉบับใหม่ ขั้นสูงสุดและไม่ยอมความครับ

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

Data Type ของ R


ก่อนอื่นออกตัวก่อนเลยนะครับ บทความนี้เขียนเพื่อตัวเอง เนื่องจากตอนนี้กำลังศึกษาเรื่อง R และ data structure ของ R เป็นเรื่องพื้นฐานที่สำคัญ ดังนั้นผมจึงทำสรุปเกี่ยวกับ data structure ของ R ไว้เพื่อที่ผมจะอ้างถึงในอนาคต

ใน R command มีกฏอยู่ 2 ข้อคือ

1) ทุกๆ อย่างที่อยู่ใน R command เป็น object
2) ทุกๆ อย่างที่เกิดขึ้นใน R command เกิดขึ้นจากการเรียกใช้ function.

โดยใน R command จะแบ่ง Type ออกได้เป็น 6 ชนิด (6 atomic class) ได้แก่
1 character - เป็น type ชนิด string หรือตัวหนังสือ ตัวอย่างดังรูปข้างล่างครับ



 คำสั่ง typeof เป็นคำสั่งที่ดูว่า type ที่ R กำลังใช้อยู่เป็น type ชนิดไหน


2 numeric หรือ double - เป็น type ชนิดตัวเลขทั่วๆ ไป สามารถเป็นได้ทั้งแบบมีทศนิยมและไม่มีทศนิยม  type นี้จะเป็นชนิด double ลองดูตัวอย่าง ดังรูปข้างล่างครับ



    ถ้าอยากรู้รายละเอียดของ numeric สามารถใช้คำสั่ง help(numeric) ที่ R command ได้เลยครับ

3 integer - เป็น type ชนิดตัวเลข โดยปกติ default type ของตัวเลขจะเป็น numeric ถ้าเราต้องการให้ type เป็น ชนิด integer ก็แค่ใส่ L ตามไปข้างหลัง ลองดูตัวอย่างตามรูปข้างล่างได้เลยครับ



   

     สิ่งหนึ่งที่สำคัญคือจำนวน maximum และ minimum ของ numeric กับ integer จะขึ้นอยู่กับชนิดของ CPU ว่าเป็น 32 bit หรือ 64 bit เราสามารถดู limit ของ type ได้ด้วยคำสั่ง .Machine  (มี dot หรือจุด นำหน้า Machine) ลองดูตัวอย่างข้างล่างน่ะครับ



4 logical - เป็น type ชนิด boolean คือมีแค่สองค่าคือ TRUE กับ FALSE ลองดูตัวอย่างวิธีใช้ข้างล่างครับ


     ข้อสังเกตุน่ะครับ true กับ TRUE ให้ผลไม่เหมือนกันน่ะครับ R ไม่รู้จัก true ครับ

5 complex - เป็น type ชนิด ซับซ้อนจะอยู่ในรูปแบบของสมการ ลองดูตัวอย่างข้างล่างครับ



     ในตัวอย่างผมเอา sqrt หรือ square root จะเห็นว่า ถ้า sqrt(-1) ค่าที่ return มาจะเป็น null แต่ ก็ยังเป็น double อยู่ดี ในขนาดที่ sqrt ของ complex จะได้ type ที่เป็น complex ด้วย
 
6 raw - ขอติดไว้ก่อนน่ะครับเดียวจะอธิบายอีกทีบทความหน้า เพราะต้องเข้าใจ Data structure ของ R ก่อน

บทความหน้าผมจะอธิบายในเรื่อง Data Structure ของ R พบกันใหม่ครับ

TuChay

วันจันทร์ที่ 30 พฤษภาคม พ.ศ. 2559

When I'm falling in love with BigData.

I had heard about BigData couple year ago. First time I heard about it, I was not quite sure what was the difference with database system. It looked very similar. Until last year, I started to take a look on BigData and went to the detail. Oh I found a lot of opportunity to improve the query data system and "data prediction".

Look back to 20 years ago, when I was a junior programmer. My job made software to create data summary report. I still remember, I needed to run my software more than a week to finish one summary report. That took time too long. I had talked to my older friend who is working on IT department for big company in Thailand. He explained to me, he has a lot of new technology to improve data query system to make more easier and faster for report (he mentioned on BI and quick view) but he still needs long time to finish the report, specially yearly report.

I am thinking, will it be better if he will create new BigData System (not replace with database) and copy the data transaction from database to Hadoop, then write the MapReduce software to generate the report. If you know how is Hadoop cluster system doing, you will understand how can be more faster. My friend mention to create new system is not easy because he needs to think about cost, time and maintain. I agreed on this but we need to trade off the benefit, how much money have to pay, how much time have gain. The Hadoop system does not require high performance. I tested with CubieTruck (ARM7 CPU), it works very well (base on not much big data :) )

One thing that I still do not understand, why the user (human) still be a person who generate the report. Why don't they have "a software bot" to auto collect data transaction, once time for create report was triggered. Just let the software bot does by itself, then send the final report to user automatic. This is a routine job that need to do everyday or every month or every year. The software bot should able to do it, no more user action. Do you think so?

A lot of more idea I can imagine what the BigData can do, like billing system, stock system. But I am interesting "data prediction" from BigData. Specially if you know machine learning, statistic or Six Sigma. You can predict data in the future from the history data.  Look interest??

TuChay

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

Assembly Module : ตอนที่ 6 manifest table


ก่อนอื่นขออนุญาติออกตัวก่อนน่ะครับ ช่วงนี้ที่ทำงานผมเริ่มกลับมามีงานแล้วครับ จากที่ สองสามเดือนก่อนหน้าไม่ค่อยมีงาน ตอนนี้เลยไม่ค่อยมีเวลาว่าง อาจจะออกบทความช้าหน่อยน่ะครับ

ใน header ของ metadata ตอนแรกผมตั้งใจจะเขียน definition table จากนั้นจะเขียนเรื่อง reference table แล้วค่อยเขียนเรื่อง manifest table หลังจากที่เริ่มเขียน reference table กลายเป็นว่ามันเกี่ยวเนื่องกันกับ manifest table คือต้องมีความเข้าใจในเรื่อง manifest table ก่อน จึงจะเข้าใจว่าอะไรคือ reference table ดังนั้นบทความนี้ผมจะอธิบาย manifest table น่ะครับ

โดยปกติโปรแกรมที่เราเขียนจึ้นมาทั้งหมดสามารถ execute ได้เพราะว่า มี manifest table และทำให้ execute file กลายเป็น Assembly module ขณะทำ runtime โดยทุกๆ code ที่ถูก compile ด้วย Visual Studio จะถูก compiler สร้าง manifest ไว้ที่ execute table ทุกครั้ง หมายความว่า code ที่ถูก compile ด้วย Visual Studio จะเป็น Assembly module เสมอ

ทุกๆ Assembly module ไม่ว่าจะเป็น static หรือ dynamic จะทำหน้าที่เก็บข้อมูลของ file ต่างๆ ที่ assembly เรียกใช้รวมถึงอธิบายวิธีการใช้ข้อมูลนั้น ข้อมูลของ file ในทีนี้สามารถเป็นได้ในรูปแบบของรูปภาพ (jpg หรือ gif), file library ที่มีนามสุล DLL และถูกเรียกใช้โดย module นอกจากจะเก็บข้อมูลของ file แล้วยังเก็บข้อมูล ดังต่อไปนี้

Assembly name - ชื่อของ assembly เก็บข้อความเป็นตัวหนังสือ
Version number - version ของ assembly
Culture -ข้อมูลเกี่ยวกับภาษาที่ assembly รองรับ
Strong name - หัวข้อนี้จะกล่าวในบทความถัดไปครับ
Type reference - ข้อมูลเกี่ยวกับ Type ที่ Assembly มีการไป reference มาจาก module อื่น ข้อมูลส่วนนี้ จะเชื่อมไปยัง table ModuleRef และ TypeRef (อยู่ในกลุ่มของ reference table ซึ่งจะกล่าวในหัวข้อถัดถัดไป)
Information on reference assemblies - ข้อมูลเกี่ยวกับ Assembly อื่นที่ Assembly นี้มีการไป reference โดยข้อมูลส่วนนี้จะมีการเชื่อมไปยัง table AssemblyRef (อยู่ในกลุ่มของ reference table ซึ่งจะกล่าวในหัวข้อถัดถัดไป)

โดยข้อมูลทั้งหมดที่ผมอธิบายจะเก็บในรูปแบบของ table เราเรียก table ในส่วนนี้ว่า manifest table

เมื่อโปรแกรมชนิด managed ถูกทำงาน สิ่งแรกที่ runtime ทำงานก่อนคือ อ่านข้อมูลของ manifest table เพื่อที่จะทราบรายละเอียดของ Type ที่ module เรียกใช้และจำขนาดของหน่วยความจำตามที่ข้อมูล manifest กำหนด ขนาดของหน่วยความจำนี้สำคัญมากตอน runtime ทำการ compile IL code ไปเป็น native code เพราะเป็นขั้นตอนที่จะจองหน่วยความจำของตัวเครื่องจริงๆ

ในตอนหน้าเราจะมาดูรายละเอียด table ของ manifest table กันครับ
พบกันใหม่บทความหน้า สวัสดีครับ
TuChay

วันศุกร์ที่ 30 ตุลาคม พ.ศ. 2558

Assembly Module : ตอนที่ 5 TypeDef table และสมาชิก (3)


เรามาต่อจาก บทความที่แล้วกันเลย ด้วยตัวอย่าง code จากบทความที่แล้ว ผมแสดงให้ดูถึงรายละเอียดของ Table TypeDef ไปแล้วในบทความนี้จะมาพูดถึงรายละเอียดของ table อื่นๆ ที่สัมพันธ์กับ table TypeDef กันครับ

จาก execute file ที่ได้จากตัวอย่างบทความที่แล้ว ถ้าเราเปิดด้วย ILDasm แล้วไปที่เมนู View -> MetaInfo -> Show!

ลองเลื่อนรายละเอียดของ metadata มาจนถึงรูปข้างล่างครับ



Method #1 (06000001)  จะเป็นสมาชิกของ table TypeDef
   #1 จะหมายถึง Index ของ method แล้วจะมีค่าบวกไปเรื่อยๆ สำหรับ method ถัดไป
   06000001 โดยที่ตัวเลข 06 ที่อยู่ข้างหน้า เป็น reference code สำหรับ runtime เพื่อให้ runtime ทราบขณะกำลัง compile ว่านี้คือ table MethodDef แน่นอนครับตัวเลขที่เป็นตัวเลขฐาน 16

ส่วนรายละเอียดข้างล่าง ของ Method #1 (06000001) ผมจะอธิบายเป็นบางส่วนก่อน ส่วนที่ยังไม่อธิบายจะไปอธิบายในบทความถัดๆ ไปน่ะครับ

MethodName 
จากตัวอย่างในรูปคือ .ctor หมายถึงเป็น constructor ก็คือมีชื่อเดียวกับชื่อของ TypeDef

Flags
บอกให้รู้ว่า method นี้มี flags อะไรบ้าง เช่น public (ส่วน flags ชนิดอื่น ผมจะอธิบายในส่วนถัดไปน่ะครับ)

RVA (Relative Virtual Address)
เป็น address ที่เก็บ IL code ของ method นี้ หมายความว่าเมื่อ runtime ทำงาน runtime จะไป compile IL code ของ method ที่ address 0x00002050 (ยังจำได้ไหมครับ managed execute file แบ่งออกเป็น 4 ส่วน สามารถย้อนไปอ่านได้ที่นี้ครับ)

ImplFlags
เป็น falgs ที่บอกว่า method นี้ถูก implement มาอย่างไร ในตัวอย่างหมายความว่า method นี้เป็นชนิด IL และสามารถ manage ได้

ReturnType
จากตัวอย่างเป็น Void คือ ไม่มีค่า return กลับ

No arguments
ไม่มีพารามิเตอร์สำหรับ method นี้ 

ที่นี้เราลองมาดู method Main กันบ้างน่ะครับ




 ใน method Main จะสังเกตุเห็นคำว่า [ENTRYPOINT] ซึ่งเป็นตัวบอก runtime ว่านี้เป็น method แรกเมื่อมีการ execute โปรแกรม 
RVA : 0x000020c2 บอกให้รู้ตำแหน่งของ IL code ของ entrypoint 
1 Arguments คือ method นี้ต้องการ 1 พารามิเตอร์ โดยมี Type SZArray ที่เก็บค่า string ของ Array
Signature : 00 01 01 1d 0e เป็น index ที่ชี้ไปที่ table ParamDef 
1 Parameters เป็นรายละเอียดของ table ParamDef ที่เกี่ยวกับ parameter นี้ จำนวน parameter จะเท่ากับจำนวน Arguments เสมอ

 พบกันใหม่บทความหน้าครับ
TuChay 

วันพฤหัสบดีที่ 29 ตุลาคม พ.ศ. 2558

Assembly Module : ตอนที่ 5 TypeDef table และสมาชิก (2)


ตอนที่แล้วผมแนะนำรายละเอียดของ table ต่างๆ ที่อยู่ในส่วนของ Definition table ไปแล้ว ที่นี้เราลองมาดูเนื้อหาของ table จากตัวอย่าง code C# ดูน่ะครับ

ลองดูตัวอย่าง code ง่ายๆ น่ะครับ

using System;

namespace CTS
{
    class Program
    {
        public int thisIsField;
        public event EventHandler thisIsEvent;
        public Program()
        {

        }

        ~Program()
        {

        }

        public string thisIsProperty
        {
            get { return ""; }
            set {}
        }


        public void thisIsMethod()
        {

        }

        public void thisIsMethod(int param)
        {

        }

        public string this[int inderxer]
        {
            get { return ""; }
            set { }
        }

        static void Main(string[] args)
        {
         
        }
    }

    public class ThisIsSecondType
    {
        public ThisIsSecondType()
        {

        }
    }
}


ตัวอย่าง code นี้มาจาก code ของ Common Type System (CTS) ตอนที่ 2  แต่ผมเพิ่มเข้าไปอีกหนึ่ง Type คือ ThisIsSecondType จากนั้น compile code เพื่อที่จะได้ execute file แล้วเปิด execute file ที่ได้ด้วย ILDasm น่ะครับ จากนั้นไปที่เมนู View -> MetaInfo -> Show!

เรามาดู information ของ table TypeDef ก่อน รูปข้างล่างเป็นตัวอย่างรายละเอียดของ table TypeDef




ที่บรรทัด TypeDef #1 (02000002)
   #1 จะเป็น index ของ Type โดยตัวเลขที่เพิ่มขึ้นไปทีล่ะหนึ่งสำหรับ Type ถัดไป
  02000002 ตัวเลข 02 ที่อยู่ข้างหน้า เป็น reference code สำหรับ runtime เพื่อให้ runtime ทราบขณะกำลัง compile ว่านี้คือ table TypeDef  โดย table TypeDef จะ start ที่ 0x02 ตัวแรก 0x หมายถึงเลขฐาน16 หมาความว่าตัวเลข 02000002 เป็นตัวเลขฐาน 16 น่ะครับ

ดังนั้นตัวเลข 02000010 ฐาน 10 จะมีค่าไม่เท่ากับ 02000010 ฐาน 16 

รายละเอียดข้างล่างอีก 3 บรรทัดจะเป็นรายละเอียดของ Type
    TypeDefName เป็นชื่อของ Type โดยชื่อของ Type จะรวม namespace หน้าชื่อของ Type ใน C# code
    Flags เป็นตัวบอกชนิดของ Type จะสังเกตุว่าใน 1 Type สามารถมีได้หลาย flag
    Extends เป็นตัวบอกให้รู้ว่า Type นี้มีการสืบถอดมาจาก Type ไหนบ้าง

อันนี้สำคัญน่ะครับ Type ทุก Type ที่เขียนขึ้นภายใต้ .Net Framework จะถูกสืบทอดมาจาก Type System.Object เสมอครับ นั้นคือเหตุผลว่าทำไม Type ทุก Type ที่เราสร้างขึ้นจึงมี method ToString() ทุกครั้ง

ที่นี้ลองมาดู Type ThisIsSecondType ใน code น่ะครับ จะเป็นได้ดังรูปข้างล่าง



สิ่งที่ต่างจาก Type Program (Type แรกของ table TypeDef) คือ Index ของ Type เป็นหมายเลข 2 และเลข reference เป็น 0x02000003 (จริงๆ ก็คือ 02000003 แหละครับ แต่ใส่ 0x เพื่อย้ำให้รู้ว่านี้เป็นเลขฐาน 16)

Flags ของ Type ThisIsSecondType เราระบุว่าเป็น public ในขณะที่ Type Program เราไม่ได้ระบุดังนั้น C# compiler จะให้ Type Program มี flag เป็น NotPublic เป็นค่า default

พบกันใหม่บทความหน้าครับ
TuChay




วันอังคารที่ 27 ตุลาคม พ.ศ. 2558

Assembly Module : ตอนที่ 5 TypeDef table และสมาชิก (1)


TypeDef table เป็น table ที่อยู่ในส่วนของ Definition table มี reference code 0x02 ตอนทำ runtime (reference code ผมจะอธิบายพร้อมยกตัวอย่างในตอนถัดไปครับ) ใน 1 Module จะมี TypeDef แค่ 1 table เท่านั้น ทำหน้าที่เก็บรายละเอียดของ Type ที่เป็นสมาชิกของ module โดยแต่ล่ะแถวของ table จะเก็บข้อมูลของ Type แต่ล่ะชนิด ข้อมูลในแถวจะเก็บรายละเอียดของข้อมูลดังนี้

1) ชื่อของ Type
2) base type ที่มีการสืบทอดมา
3) flags access modifiers ของ Type (เช่น public, private)
4) Index ของ method ที่ Type นี้เป็นเจ้าของ ข้อมูลของ method จะอยู่ใน table MethodDef โดยมี index นี้เป็นตัวเชื่อมระหว่าง TypeDef กับ MethodDef
5) Index ของ field ที่ Type นี้เป็นเจ้าของ ข้อมูลของ field จะอยู่ใน table FieldDef โดยมี index นี้เป็นตัวเชื่อมระหว่าง TypeDef กับ FieldDef
6) Index ของ property ที่ Type นี้เป็นเจ้าของ ข้อมูลของ property จะอยู่ใน table PropertyDef โดยมี index นี้เป็นตัวเชื่อมระหว่าง TypeDef กับ PropertyDef
7) Index ของ event ที่ Type นี้เป็นเจ้าของ ข้อมูลของ event จะอยู่ใน table EventDef โดยมี index นี้เป็นตัวเชื่อมระหว่าง TypeDef กับ EventDef

จากคำอธิบายข้างต้นเราจะเห็นความสัมพันธ์ของ database อย่างง่ายๆ โดยมี TypeDef เป็น table หลักและมี table อื่นๆ เป็นตัวเก็บรายละเอียดของ Type

เรามาดู table ย่อยที่มีความสัมพันธ์กับ TypeDef โดยมีรายละเอียดดังนี้

1) MethodDef
    เป็น table ที่เก็บรายละเอียดของ method ที่เป็นสมาชิกของ Type มี reference code 0x06 ตอนทำ runtime โดยรายละเอียดที่เก็บใน table มีดังนี้
   - ชื่อของ method
   - flags access modifiers ของ method (เช่น public, private)
   - Index ของ parameter ของ method (signature) ข้อมูลของ parameter จะอยู่ใน table ParamDef โดยมี index นี้เป็นตัวเชื่อมระหว่าง TypeDef กับ ParamDef

2) ParamDef
    เป็น table ที่เก็บรายละเอียดของ parameter ของ method  มี reference code 0x08 ตอนทำ runtime ใน 1 แถวจะเก็บรายละเอียดของ พารามิเตอร์ที่ถูกกำหนดใน method โดยข้อมูลในแต่ล่ะแถวจะเก็บรายละเอียดดังนี้
    - Type ของ parameter
    - ชื่อของ parameter
    - flag ของ parameter เช่น in, out, retval

2) FieldDef
  เป็น table ที่เก็บรายละเอียดของ filed ที่เป็นสมาชิกของ Type มี reference code 0x04 ตอนทำ runtime โดยรายละเอียดที่เก็บใน table มีดังนี้
    - Type ของ field
    - ชื่อของ field
    - flag ของ field เช่น private, public

3) PropertyDef
    เป็น table ที่เก็บรายละเอียดของ property ที่เป็นสมาชิกของ Type มี reference code 0x17 ตอนทำ runtime โดยรายละเอียดที่เก็บใน table มีดังนี้
    - Type ของ property
    - ชื่อของ property
    - flag ของ propertyเช่น private, public


4) EventDef

    เป็น table ที่เก็บรายละเอียดของ event ที่เป็นสมาชิกของ Type มี reference code 0x14 ตอนทำ runtime โดยรายละเอียดที่เก็บใน table มีดังนี้
    - Type ของ event
    - ชื่อของ event
    - flag ของ event เช่น private, public


ในตอนหน้าเราจะมาดูวิธีการอ่านรายละเอียดของ table TypeDef และ table อื่นๆ ที่ TypeDef มีการอ้างถึงกันครับ

พบกันใหม่บทความหน้าครับ
TuChay


วันจันทร์ที่ 19 ตุลาคม พ.ศ. 2558

Assembly Module : ตอนที่ 5 ModuleDef table


Table แรกและเป็น table ที่สำคัญในส่วนของ Definition table คือ ModuleDef เป็น table ที่เก็บรายละเอียดของ module ได้แก่

 1) ชื่อของ module และนามสกุลของ module
เราสามารถแก้ไขชื่อและนามสกุลในส่วนของ table ModuleDef ได้แต่เนื่องจากมีหลาย table ใน metadata ทำการ link ไปที่ข้อมูลของ ModuleDef เพื่อป้องกันความผิดพลาดในการทำ runtime จึงไม่ควรเปลี่ยนชื่อและนามสกุลใน ModuleDef โดยเด็ดขาด

2) MVID - Module Version Identifier
 จะเป็นค่า uniqe ที่จะไม่ซ้ำกันและค่าจะเปลี่ยนไปเรื่อยๆ ทุกๆ ครั้งที่มีการ compile code แม้แต่ code เดียวกันถ้า compile code 2 ครั้ง ค่า MVID ทั้งสองครั้งก็จะมีค่าไม่เหมือนกัน รูปแบบของ MVID จะเป็นรูปแบบเดียวกับ GUID โดยมีการ checksums เพื่อนำมาสร้างค่า MVID

ที่ .Net Framework มีเปลี่ยนแปลงค่า MVID ทุกครั้งที่มีการ compile code เป็นเพราะว่า โดยปกติบริษัทที่จำหน่าย software มักจะมีบริษัทที่สาม (Third party company) หรืออาจจะเป็นแผนกตรวจสอบคุณภาพ (QC) ภายในบริษัท จะทำหน้าที่ตรวจสอบคุณภาพและรับประกันคุณภาพของ software ก่อนที่ software จะถูกนำออกจำหน่าย หน้าที่นี้รวมถึงการตรวจสอบ source code ดังนั้นบริษัทที่สามต้องการยืนยันว่า code ที่ได้มาตรงกับ execute file ที่กำลังตรวจสอบ, ทดสอบ และ เตรียมตัวที่จะจำหน่าย ดังนั้นรหัส MVID จึงเป็นตัวช่วยในระบบการตรวจสอบได้ถูกต้องแม่นยำ

ในหนึ่ง module จะมี table นี้แค่เพียง table เดียวเท่านั้น

จากตัวอย่าง code  ของตอนที่ 2 เราสามารถดูข้อมูลของ ModuleDef ได้ด้วย ILDasm และเลือกที่เมนู View แล้วเลือก MetaInfo แล้วเลือก Show! จะได้ดังรูป




ข้อมูลในกรอบสีแดงคือข้อมูลใน table ModuleDef จริงๆ แล้ว metadata จะเก็บข้อมูลในรูปแบบ table แต่ข้อจำกัดในเรื่องการแสดงผลของ ILDasm จึงไม่สามารถแสดงผลในรูปแบบของตารางได้ ILDasm จึงแสดงข้อมูลในตารางทั้งหมดออกมาดังรูปข้างบน

นอกจากนี้เรายังสามารถดู MVID ผ่าน ทาง command ได้ด้วยคำสั่ง

    c:\>ildasm /all /text Program.exe | find /v "// Time-date stamp:" | find /v "// MVID" | find /v "//  Checksum:" > Program.txt


คำสั่งข้างบนจะเป็นการดึงข้อมูลของ header ใน manage file แล้วบันทึกลงใน text file จากตัวอย่าง text file ของเราคือ Program.txt ดังนั้นเราจึงสามารถ compare ข้อมูลใน header file ด้วยคำสั่ง fc ลองดูตัวอย่างวิธีการใช้ตามรูปข้างล่างน่ะครับ



บทความหน้าพบกับ table ที่ 2 ของ Definition table ครับ ซึ่งจะเป็น table อะไรนั้น .... พบกันใหม่บทความหน้าครับ
TuChay