C# (ซีชาร์ป) เป็นภาษาโปรแกรมเชิงวัตถุที่พัฒนาโดยไมโครซอฟท์ มีการเปิดตัวครั้งแรกในปี 2000 ภายใต้โครงการ .NET Framework มีจุดเด่นคือ ออกแบบมาเพื่อเป็นภาษาการเขียนโปรแกรมที่ง่ายต่อการเรียนรู้ แต่มีความสามารถและประสิทธิภาพสูง พร้อมทั้งรองรับการพัฒนาแอปพลิเคชันในหลากหลายแพลตฟอร์ม ทำให้เป็นที่นิยมใช้ในการพัฒนาแอปพลิเคชันประเภทต่างๆ ทั้งแอปพลิเคชันเดสก์ท็อป แอปพลิเคชันเว็บ และแอปพลิเคชันมือถือ
C# ถูกพัฒนาขึ้นในช่วงปลายทศวรรษที่ 1990 โดยทีมงานของไมโครซอฟท์ นำโดย Anders Hejlsberg ซึ่งเป็นหนึ่งในผู้สร้างภาษา Turbo Pascal และ Delphi ก่อนหน้านั้น Microsoft ต้องการสร้างภาษาใหม่ที่มีความยืดหยุ่น และสามารถตอบสนองความต้องการของนักพัฒนาได้มากขึ้น โดยให้มีคุณสมบัติที่ดีจากภาษาอื่น ๆ เช่น Java และ C++ แต่ถูกปรับปรุงให้เหมาะสมกับการพัฒนาบนแพลตฟอร์ม Windows
จุดประสงค์หลักของการสร้าง C# คือการสร้างภาษาโปรแกรมที่ทันสมัย มีประสิทธิภาพสูง และใช้งานง่าย เพื่อแข่งขันกับภาษา Java ของ Sun Microsystems
.NET Framework
C# ถูกออกแบบมาให้ทำงานร่วมกับ .NET Framework ซึ่งเป็นแพลตฟอร์มสำหรับการพัฒนาแอปพลิเคชันของไมโครซอฟท์ ทำให้สามารถเข้าถึงไลบรารีและฟังก์ชันต่างๆ ของ .NET Framework ได้อย่างง่ายดาย
.NET Runtime เป็นสภาพแวดล้อมการทำงานที่จำเป็นสำหรับการรันแอปพลิเคชันที่พัฒนาขึ้นด้วยภาษา .NET เช่น C#, VB.NET หรือ F#. มันทำหน้าที่เป็นตัวกลางในการแปลโค้ดที่เขียนโดยนักพัฒนาให้เป็นภาษาที่คอมพิวเตอร์เข้าใจและสามารถประมวลผลได้
การรันแอปพลิเคชัน .NET บน Windows 64 บิต จะเกิดกระบวนการดังนี้
- การคอมไพล์: โค้ดที่เขียนด้วยภาษา .NET จะถูกคอมไพล์เป็น Intermediate Language (IL) ซึ่งเป็นภาษาที่เข้าใจได้โดย Common Language Runtime (CLR)
- Just-In-Time (JIT) Compilation: เมื่อแอปพลิเคชันเริ่มทำงาน CLR จะทำการแปล IL เป็นโค้ดเครื่อง (machine code) ที่เฉพาะเจาะจงสำหรับโปรเซสเซอร์ 64 บิต
- การบริหารจัดการหน่วยความจำ: CLR จะจัดการการจัดสรรและปล่อยหน่วยความจำให้กับแอปพลิเคชันโดยอัตโนมัติ
- การจัดการข้อยกเว้น: CLR จะจัดการกับข้อยกเว้นที่เกิดขึ้นในระหว่างการทำงานของแอปพลิเคชัน
- การรักษาความปลอดภัย: CLR จะมีคุณสมบัติความปลอดภัยที่หลากหลาย เช่น ความปลอดภัยประเภท ความปลอดภัยในการเข้าถึงรหัส และอื่นๆ เพื่อปกป้องแอปพลิเคชันและระบบ
C# 1.0: เวอร์ชันแรกของ C# ที่เปิดตัวพร้อมกับ .NET Framework 1.0 ในปี ค.ศ. 2002 โดยเป็นภาษาที่มีลักษณะเป็นแบบ Strongly Typed และ Object-Oriented มีคุณสมบัติพื้นฐานที่สนับสนุนการพัฒนาแอปพลิเคชันบน Windows เช่น การสนับสนุนคลาส, การจัดการหน่วยความจำแบบอัตโนมัติ (Garbage Collection), และ Exception Handling
C# 2.0: ในปี ค.ศ. 2005 C# 2.0 ได้ถูกเปิดตัวพร้อมกับ .NET Framework 2.0 การอัปเดตครั้งนี้มาพร้อมกับฟีเจอร์ใหม่ๆ ที่สำคัญ เช่น Generics, partial classes, Nullable Types, Anonymous Methods และ Iterators ทำให้การพัฒนาแอปพลิเคชันมีความยืดหยุ่นและประสิทธิภาพสูงขึ้น
C# 3.0: ในปี ค.ศ. 2007 C# 3.0 ถูกเปิดตัวพร้อมกับ .NET Framework 3.5 และมีการนำเสนอ LINQ (Language Integrated Query) ซึ่งเป็นฟีเจอร์ที่สำคัญที่ช่วยให้นักพัฒนาสามารถเขียนโค้ดในการจัดการข้อมูลได้ง่ายขึ้น ฟีเจอร์อื่น ๆ ที่มาพร้อมกับเวอร์ชันนี้ได้แก่ Lambda Expressions, Extension Methods, และ Anonymous Types
C# 4.0: เปิดตัวในปี ค.ศ. 2010 พร้อมกับ .NET Framework 4.0 การอัปเดตครั้งนี้มุ่งเน้นไปที่การเพิ่มความยืดหยุ่นในการเขียนโค้ด เช่น Dynamic Types, Named and Optional Arguments, และ Covariance & Contravariance
C# 5.0: เปิดตัวในปี ค.ศ. 2012 พร้อมกับ .NET Framework 4.5 โดยการอัปเดตครั้งนี้เน้นที่การปรับปรุง Asynchronous Programming โดยการนำเสนอคำสั่ง async และ await ซึ่งช่วยให้นักพัฒนาสามารถเขียนโค้ดที่รองรับการทำงานแบบขนาน (asynchronous) ได้ง่ายขึ้น
C# 6.0: ถูกเปิดตัวในปี ค.ศ. 2015 พร้อมกับ Visual Studio 2015 และ .NET Framework 4.6 ฟีเจอร์ใหม่ ๆ ที่มาพร้อมกับเวอร์ชันนี้มีวัตถุประสงค์เพื่อทำให้การเขียนโค้ดง่ายขึ้น เช่น Null-conditional Operators, Expression-bodied Members, และ String Interpolation
C# 7.0: C# 7.0 และ 7.x ถูกปล่อยออกมาในช่วงปี ค.ศ. 2017 และ ค.ศ. 2018 มีการเพิ่มฟีเจอร์เช่น Tuples, Pattern Matching, Local Functions, และ Value Tuples ซึ่งช่วยให้โค้ดมีความยืดหยุ่นและสามารถจัดการกับโครงสร้างข้อมูลที่ซับซ้อนได้ดีขึ้น
C# 8.0: เปิดตัวในปีค.ศ. 2019 พร้อมกับ .NET Core 3.0 การอัปเดตครั้งนี้มีการปรับปรุงฟีเจอร์ต่าง ๆ เช่น Nullable Reference Types, Asynchronous Streams, และ Default Interface Methods ซึ่งช่วยให้การพัฒนาบนแพลตฟอร์มที่ไม่ใช่ Windows สามารถทำได้ง่ายขึ้น พร้อมทั้งเน้นการสนับสนุนภาษา C# ให้เข้ากับ .NET Core และการพัฒนาแอปพลิเคชันแบบ cross-platform
C# 9.0: เปิดตัวในปี ค.ศ. 2020 พร้อมกับ .NET5 โดยเพิ่มฟีเจอร์ที่ช่วยให้เขียนโค้ดได้สั้นลงและอ่านง่ายขึ้น โดยมีการเพิ่มฟีเจอร์ที่ช่วยให้การพัฒนาแอปพลิเคชันรวดเร็วและมีประสิทธิภาพมากขึ้น เช่น Record Types, Init-only Properties, Top-level Statements, และการปรับปรุงใน Pattern Matching
C# 10.0: เปิดตัวปี ค.ศ. 2021 เน้นการปรับปรุงประสิทธิภาพและการสนับสนุนภาษา C# ให้เข้ากับ .NET 6
C#11.0: ถูกเปิดตัวในปี ค.ศ. 2022 พร้อมกับ .NET 7.0 มุ่งเน้นที่การปรับปรุงประสิทธิภาพและความสะดวกสบายในการพัฒนาแอปพลิเคชัน รวมถึงการสนับสนุนการพัฒนาบนแพลตฟอร์มที่หลากหลายมากยิ่งขึ้น อนาคตของ C# คาดว่าจะยังคงมุ่งเน้นที่การปรับปรุงความยืดหยุ่นและประสิทธิภาพให้สูงขึ้น รวมถึงการสนับสนุนเทคโนโลยีใหม่ๆ ที่กำลังพัฒนาอย่างต่อเนื่อง
C#12.0: เน้นการปรับปรุงด้านความสะดวกสบายและประสิทธิภาพในการพัฒนาโปรแกรมต่อไป โดยมุ่งเน้นไปที่การปรับปรุงฟีเจอร์ที่มีอยู่แล้วและการเพิ่มฟีเจอร์ใหม่ที่สอดคล้องกับความต้องการของนักพัฒนา เช่น การปรับปรุง Pattern Matching, การพัฒนาฟีเจอร์สำหรับ Data-Oriented Programming, และการปรับปรุงความยืดหยุ่นในการเขียนโค้ด โดยยังคงเน้นการสนับสนุนการพัฒนาแอปพลิเคชันในสภาพแวดล้อมที่หลากหลาย รวมถึงการพัฒนาบน .NET 8 และการสนับสนุนแอปพลิเคชันที่ใช้แพลตฟอร์มอื่นๆ นอกเหนือจาก Windows ดังตัวอย่างฟีเจอร์ต่อไปนี้
- Primary Constructors o ฟีเจอร์นี้อาจจะช่วยให้นักพัฒนาสามารถเขียนโค้ดที่เรียบง่ายและกระชับมากขึ้น โดยการกำหนดตัวแปรและการกำหนดค่าในตัวคอนสตรัคเตอร์หลักของคลาสได้โดยตรง
- Collection Literals o อาจเป็นฟีเจอร์ที่ช่วยให้การสร้างและใช้งาน Collection ต่างๆ เช่น List, Dictionary หรือ Array ง่ายและกระชับขึ้น โดยไม่จำเป็นต้องใช้วิธีการแบบเดิมในการกำหนดค่า
- Extended Pattern Matching o การปรับปรุงและขยายการใช้งาน Pattern Matching ซึ่งอาจเพิ่มฟีเจอร์ใหม่ เช่น List Patterns หรือการ Matching ที่ละเอียดขึ้นในสถานการณ์ต่าง ๆ
- Data-Oriented Programming Enhancements o ฟีเจอร์ที่จะสนับสนุนแนวทางการเขียนโปรแกรมแบบ Data-Oriented โดยอาจมีการเพิ่มฟีเจอร์สำหรับการจัดการข้อมูลขนาดใหญ่ หรือการจัดการหน่วยความจำที่มีประสิทธิภาพมากขึ้น
- Static Abstract Members in Interfaces o ฟีเจอร์นี้อาจช่วยให้นักพัฒนาสามารถกำหนดสมาชิกแบบ Abstract ที่เป็น Static ใน Interfaces ได้ ซึ่งช่วยให้สามารถสร้างพฤติกรรมที่เป็นลักษณะ Static ในคลาสที่นำ Interface นั้นไปใช้
- Default Values for Auto-Properties o ฟีเจอร์นี้อาจจะอนุญาตให้นักพัฒนากำหนดค่าเริ่มต้นสำหรับ Auto-Properties ได้โดยตรง ทำให้การเขียนโค้ดง่ายและกระชับมากขึ้น
- Language Support for Units of Measure o การสนับสนุนสำหรับการทำงานกับหน่วยวัดในตัวภาษา เช่น เมตร, วินาที, และหน่วยอื่นๆ ซึ่งจะช่วยเพิ่มความชัดเจนและความปลอดภัยในการคำนวณหรือการจัดการข้อมูลที่เกี่ยวข้องกับหน่วยวัด
ตัวเลขในภาษา C#
ตัวแปร ในภาษา C# คือ ชื่อที่ใช้ในการเก็บข้อมูลชั่วคราวภายในหน่วยความจำของคอมพิวเตอร์ เปรียบเสมือนกล่องที่เราใช้ใส่ของชิ้นต่างๆ โดยแต่ละกล่องจะมีขนาดและประเภทของสิ่งของที่ใส่ได้แตกต่างกันไป ตัวแปรใน C# ก็เช่นกัน จะมีชนิดข้อมูลที่กำหนดไว้ว่าจะเก็บข้อมูลประเภทใด เช่น จำนวนเต็ม ตัวเลขทศนิยม ตัวอักษร หรือข้อมูลอื่น ๆ
ชนิดข้อมูล ในภาษา C# คือ การกำหนดลักษณะของข้อมูลที่ตัวแปรหนึ่งๆ จะเก็บได้ เช่น เป็นจำนวนเต็ม จำนวนทศนิยม ตัวอักษร หรือข้อความ การกำหนดชนิดข้อมูลที่ถูกต้องจะช่วยให้โปรแกรมทำงานได้อย่างมีประสิทธิภาพและหลีกเลี่ยงข้อผิดพลาดในการคำนวณ
จำนวนที่ใช้กับ C# ประกอบด้วยจำนวนเต็มและทศนิยม โดยจำนวนมีขนาดแตกต่างกันตามตารางที่ 1 เพื่อให้ผู้เขียนโปรแกรมเลือกใช้ตามช่วงค่าที่ต้องการใช้ ทำให้ประหยัดปริมาณหน่วยความจำของคอมพิวเตอร์ หรืออุปกรณ์ที่รันโปรแกรม
ถ้าเป็นจำนวนเต็มให้ใช้ค่าตัวเลขระบุ เช่น 1, 5, -10, 0 หรือ -200 แต่ถ้าเป็นทศนิยมจะต้องใส่ค่าหลังเลขจำนวนเต็มประกอบ เช่น 1.0, 5.0, -10.0, 0.0 หรือ 200.0 โดยต้องกำหนดอักษร f ต่อท้ายตัวเลขเพื่อระบุประเภทของตัวเลขเป็นทศนิยมแบบ float แต่ถ้าไม่ระบุจำหมายถึง double เป็นต้น
ตัวเลขที่ถูกใช้ในภาษา C# มี 2 ประเภท คือ ตัวเลขที่เป็นค่าคงที่ และตัวเลขที่เก็บอยู่ในตัวแปร โดยในรูปแบบแรกนั้นเป็นการอ้างอิงชื่อเพื่อใช้แทนค่าตัวเลขทำให้สะดวกในการอ้างอิงหรือเปลี่ยนแปลงค่าแล้วส่งผลให้ทุกชื่อที่อ้างอิงนั้นเปลี่ยนเป็นค่าเดียวกันหมด ส่วนตัวแปรนั้นเป็นการจองหน่วยความจำของคอมพิวเตอร์เพื่อจัดเก็บตัวเลขลงในหน่วยความจำที่จองนั้น ดังนั้น ถ้าหน่วยความจำไม่เพียงพอจะส่งผลให้โปรแกรมไม่สามารถทำงานได้ และการจองหน่วยความจำที่ไม่เพียงพอต่อการเก็บส่งผลให้ค่านั้นเปลี่ยนแปลงไปเป็นค่าที่ไม่พึงประสงค์ได้ เช่น จองไว้ 1 ไบต์ ซึ่งเก็บค่าได้ -128 ถึง 127 (ดังตารางที่ 1-1) เมื่อใดที่มีค่าเป็น 127 แล้วเพิ่มค่าอีก 1 จะไม่ทำให้ค่าเป็น 128 แต่กลับกลายเป็น -128 เป้นต้น นอกจากนี้ในบางครั้งที่จองขนาดหน่วยความจำที่เกินกว่าจำเป็น เช่น ไม่ว่าอย่างไรค่าที่เก็บเป็นตัวเลขในช่วง 1 ถึง 8 แต่ผู้เขียนโปรแกรมจองหน่วยความจำเป็น UInt32 ซึ่งต้องการหน่วยความจำจำนวน 4 ไบต์ในการเก็บทั้งที่ใช้เพียง 1 ไบต์ก็เพียงพอ เป็นต้น
การประกาศตัวแปร
ตัวแปรนั้นเป็นการจองหน่วยความจำของคอมพิวเตอร์เพื่อจัดเก็บตัวเลขลงในหน่วยความจำที่จองไว้ แต่ถ้าหน่วยความจำไม่เพียงพอจะเกิดปัญหา not enough memory ทำให้โปรแกรมไม่สามารถทำงานต่อไปได้ โดยการประกาศตัวแปรมีรูปแบบดังนี้
ชนิดข้อมูล ชื่อตัวแปร;
หรือ
ชนิดข้อมูล ชื่อตัวแปร = ค่าตัวแปร;
โดยที่
- ชนิดข้อมูล: ระบุประเภทของข้อมูลที่ตัวแปรจะเก็บ
- ชื่อตัวแปร: ชื่อที่เราตั้งให้ตัวแปร โดยทั่วไปจะใช้ภาษาอังกฤษและมีความหมายสื่อถึงข้อมูลที่เก็บ
- ค่าตัวแปร: ค่าเริ่มต้นตามชนิดข้อมูลที่กำหนดให้กับตัวแปร
// ประกาศตัวแปร age ชนิด int และกำหนดค่าเป็น 25
int age = 25;
// ประกาศตัวแปร price ชนิด double และกำหนดค่าเป็น 99.99
double price = 99.99;
// ประกาศตัวแปร name ชนิด string และกำหนดค่าเป็น "John Doe"
string name = "John Doe";
// ประกาศตัวแปร pi ชนิด double
double pi = 3.14159;
// ประกาศตัวแปร initial ชนิด char
char initial = 'A';
// ประกาศตัวแปร isSunny ชนิด bool
bool isSunny = true;
// ประกาศตัวแปร name ชนิด string
string name = "John Doe";
การจองหน่วยความจำที่ไม่เพียงพอต่อการเก็บส่งผลให้ค่านั้นเปลี่ยนแปลงไปเป็นค่าที่ไม่พึงประสงค์ได้ เช่น จองไว้ 1 ไบต์ ซึ่งเก็บค่าได้ -128 ถึง 127 เมื่อใดที่มีค่าเป็น 127 แล้วเพิ่มค่าอีก 1 จะไม่ทำให้ค่าเป็น 128 แต่กลับกลายเป็น -128 เป็นต้น
นอกจากนี้ในบางครั้งที่จองขนาดหน่วยความจำที่เกินกว่าจำเป็น เช่น ไม่ว่าอย่างไรค่าที่เก็บเป็นตัวเลขในช่วง 1 ถึง 8 แต่ผู้เขียนโปรแกรมจองหน่วยความจำเป็น UInt32 ซึ่งต้องการหน่วยความจำจำนวน 4 ไบต์ในการเก็บทั้งที่ใช้เพียง 1 ไบต์ก็เพียงพอ เป็นต้น
กฎการตั้งชื่อตัวแปร
โดยปกติแล้วภาษาเขียนโปรแกรมจะต้องกำหนดชื่อสำหรับใช้ในภาษาของตน และเรียกคำเหล่านั้นว่าคำสงวน (Reserve word) หรือ คำสำคัญ (keyword) ทำให้การสร้างตัวแปรหรือค่าคงที่จะต้องไม้ซ้ำกับคำเหล่านั้น ดังนั้น จึงมีการกำหนดกฎของการตั้งชื่อของภาษา C# เอาไว้ดังนี้
- ต้องเริ่มด้วยอักษรหรือเครื่องหมาย underscore (_)
- สามารถประกอบด้วยอักษร ตัวเลข และ underscore
- ไม่สามารถใช้ keyword ของภาษา C# เป็นชื่อตัวแปร
- แนะนำให้ใช้ชื่อตัวแปรที่สื่อความหมาย
การกำหนดค่าให้ตัวแปร
การกำหนดค่าให้กับตัวแปรสามารถกระทำได้ 2 วิธี คือ กำหนดตั้งแต่ประกาศตัวแปรตามรูปแบบที่กล่าวถึงไปก่อนหน้านี้ กับการกำหนดภายหลังการประกาศตัวแปรที่ผู้เขียนโปรแกรมสามารถกำหนดค่าให้กับตัวแปรด้วยค่าตามประเภทข้อมูลของตัวแปร ดังรูปแบบต่อไปนี้
ชื่อตัวแปร = ค่าตัวแปร;
หรือ
L = R;
โดย
L คือ ตัวแปร
R คือ นิพจน์ (expression) อันจะเป็นตัวเลข ค่าคงที่ ตัวแปร หรือโปรแกรมย่อยที่จะถูกกระทำหรือทำงานจนได้คำตอบเพื่อนำไปเก็บใน L
นิพจน์เป็นการดำเนินการระหว่างตัวดำเนินการตามรูปแบบชองเครื่องหมายดำเนินการ อันได้แก่
1. เครื่องหมายดำเนินการ ตัวดำเนินการ
2. ตัวดำเนินการ1 เครื่องหมายดำเนินการ ตัวดำเนินการ2
ในรูปแบบที่ 1 จะเป็นเครื่องหมายดำเนินการประเภทเปลี่ยนแปลงค่าของตัวดำเนินการ อันได้แก่
-a หมายถึง การนำ -1 คูณกับ a
!a หมายถึง กลับค่าตรรกะของ a ถ้าเดิม a เป็น true จะได้ผลลัพธ์เป็น
false และ ในทางกลับกันเมื่อเดิม a เป็น false จะได้ผลลัพธ์
เป็น true
not a หมายถึง กลับค่าตรรกะของ a ซึ่งให้ผลลัพธ์เหมือนกับการใช้คำสั่ง !a
ในรูปแบบที่ 2 เป็นการกระทำระหว่างตัวดำเนินการ1 กับตัวดำเนินการ2 ซึ่งเครื่องหมายในกลุ่มนี้ได้แก่ การดำเนินการทางคณิตศาสตร์ เป็นตามตารางที่ 1-1 และการดำเนินการทางตรรกะ เป็นตามตารางที่ 1-2 (ให้ผลลัพธ์เป็น false หรือ true)
จากตาราง 1-2 จะพบว่าการประยุกต์ใช้เครื่องหมายสำหรับการย่อการเขียนในกรณีที่ตัวดำเนินการเป็นตัวเดียวกัน เช่น การเพิ่มค่าตัวแปร a ขึ้น 1 ค่า สามารถเขียนได้เป็น
a = a + 1
แต่สามารถเขียนแบบย่อเพื่อให้คำสั่งสั้นลงเป็นดังนี้
a += 1
ดังนั้น เครื่องหมายสำหรับการเขียนแบบย่อจึงมีด้วยกัน 5 แบบ คือ
ตัวแปร += ค่า หมายถึง ตัวแปร = ตัวแปร + ค่า
ตัวแปร -= ค่า หมายถึง ตัวแปร = ตัวแปร – ค่า
ตัวแปร *= ค่า หมายถึง ตัวแปร = ตัวแปร * ค่า
ตัวแปร /= ค่า หมายถึง ตัวแปร = ตัวแปร / ค่า
ตัวแปร %= ค่า หมายถึง ตัวแปร = ตัวแปร % ค่า
จากตารางที่ 1-3 จะได้ผลลัพธ์ของการดำเนินการทางตรรกะแบบ และ เป็นตามตารางที่ 1-4 และการดำเนินการทางตรรกะแบบ หรือ เป็นผลลัพธ์ตามตารางที่ 1-5
การกระทำระหว่างจำนวนในเชิงของระบบคอมพิวเตอร์นั้นมีเงื่อนไขดังนี้
1. การกระทำระหว่างตัวเลขจำนวนเต็มกับจำนวนเต็มจะได้ค่าเป็นจำนวนเต็ม
2. การกระทำระหว่างตัวเลขทศนิยมกับเลขทศนิยมจะได้ค่าเป็นทศนิยม
3. การกระทำระหว่างตัวเลขจำนวนเต็มกับตัวเลขทศนิยมจะได้เป็นทศนิยม
4. การหารด้วย 0 จะได้ค่าเป็นอนันต์ (infinity) ซึ่งไม่ถูกนิยามในทางคณิตศาสตร์แต่ในระบบคอมพิวเตอร์จะก่อเกิดปัญหาเรื่อง divide by zero อันทำให้โปรแกรมที่เขียนนั้นเกิดความผิดพลาดและส่งผลให้สิ้นสุดการทำงานแบบเกิดความผิดพลาด
5. ตัวเลข 0 หารด้วยค่าใด ๆ ได้ผลลัพธ์เป็น 0 เสมอ
ค่าคงที่ (constant)
ค่าคงที่เป็นการอ้างอิงชื่อเพื่อใช้แทนค่าตัวเลขทำให้สะดวกในการอ้างอิงหรือเปลี่ยนแปลงค่าแล้วส่งผลให้ทุกชื่อที่อ้างอิงนั้นเปลี่ยนเป็นค่าเดียวกันหมด ดังนั้น ค่าคงที่จึงเปรียบเสมือนเป็นเป็นตัวแปรที่มีค่าคงที่ตลอดการทำงานของโปรแกรม โดยการประกาศค่าคงที่จะคล้ายกับการประกาศตัวแปร แต่มีถ้อยแถลง const นำหน้า ดังนี้
const ชนิดข้อมูล ชื่อค่าคงที่ = ค่าของค่าคงที่;
ตัวอย่างการสร้างค่าคงที่ชื่อ MY_PI เพื่อเก็บเลขทศนิยมที่มีค่า 3.141592 สามรถเขียนได้ดังนี้
const double MY_PI = 3.141592;
การแปลงชนิดข้อมูล
การแปลงชนิดข้อมูลสามารถทำได้โดยตรงในบางกรณี หรือใช้การแปลงแบบขยาย (casting)
int num = 10;
// แปลง int เป็น double
double result = (double)num;
ข้อมูลทศนิยม
ในภาษา C# ใช้ตัวแปรประเภท float และ double เพื่อเก็บค่าทศนิยม โดยตัวแปรทั้งสองนี้ใช้มาตรฐาน IEEE 754 ในการแทนค่าทศนิยม ซึ่งเป็นมาตรฐานที่ใช้กันอย่างแพร่หลายในคอมพิวเตอร์ปัจจุบัน
- float: ใช้พื้นที่เก็บข้อมูล 32 บิต มีความแม่นยำน้อยกว่า double เหมาะสำหรับการคำนวณที่ไม่ต้องการความแม่นยำสูงมากนัก
- double: ใช้พื้นที่เก็บข้อมูล 64 บิต มีความแม่นยำสูงกว่า float เหมาะสำหรับการคำนวณที่ต้องการความแม่นยำสูง เช่น การคำนวณทางวิทยาศาสตร์
IEEE 754 เป็นมาตรฐานสากลที่กำหนดรูปแบบการแทนค่าจำนวนจุดลอยตัว (floating-point numbers) ในคอมพิวเตอร์ มาตรฐานนี้ถูกพัฒนาขึ้นโดยสถาบันวิศวกรไฟฟ้าและอิเล็กทรอนิกส์ (Institute of Electrical and Electronics Engineers หรือ IEEE) เพื่อให้คอมพิวเตอร์ต่างๆ ทั่วโลกสามารถแทนค่าทศนิยมได้อย่างสอดคล้องกันและแม่นยำ ทำให้โปรแกรมที่เขียนบนแพลตฟอร์มหนึ่งสามารถทำงานได้อย่างถูกต้องบนแพลตฟอร์มอื่น และสนับสนุนค่าพิเศษ เช่น อินฟินิตี้ (infinity), น็อต-อะ-นัมเบอร์ (NaN) เป็นต้น เพื่อจัดการกับสถานการณ์ที่ผิดปกติในการคำนวณ
โครงสร้างข้อมูลการจัดเก็บข้อมูลตัวเลขชนิดจำนวนทศนิยมตามมาตรฐาน IEEE 754 ประกอบด้วย 3 ส่วนหลักคือ
- เครื่องหมาย (sign): บิตแรกใช้แทนเครื่องหมายของจำนวน บิต 1 หมายถึงจำนวนเป็นลบ และบิต 0 หมายถึงจำนวนเป็นบวก
- เลขชี้กำลัง (exponent): เป็นจำนวนเต็มที่บ่งบอกถึงขนาดของจำนวน โดยใช้ในการเลื่อนจุดทศนิยม
- แมนทิสซา (mantissa): เป็นส่วนที่แทนค่าตัวเลขจริงของจำนวน โดยเป็นเศษส่วนที่อยู่ในช่วง 0 ถึง 1
แม้ว่ามาตรฐาน IEEE 754 จะช่วยให้เราสามารถแทนค่าทศนิยมได้อย่างแม่นยำ แต่ก็ยังมีข้อจำกัดบางประการที่เราควรทราบ
- ความแม่นยำจำกัด: เนื่องจากใช้บิตในการแทนค่าทศนิยมจำนวนจำกัด จึงทำให้ค่าทศนิยมบางค่าไม่สามารถแทนได้อย่างแม่นยำทั้งหมด โดยเฉพาะอย่างยิ่งค่าทศนิยมที่มีจำนวนตำแหน่งทศนิยมมาก
- ข้อผิดพลาดในการปัดเศษ: ในการคำนวณทางคณิตศาสตร์ อาจเกิดข้อผิดพลาดในการปัดเศษ เนื่องจากคอมพิวเตอร์ต้องตัดทอนค่าทศนิยมที่เกินออกมา
- ค่าอนันต์และค่าไม่นิยาม: IEEE 754 รองรับค่าอนันต์ (infinity) และค่าไม่นิยาม (NaN) ซึ่งเกิดขึ้นได้จากการหารด้วยศูนย์ หรือการดำเนินการทางคณิตศาสตร์ที่ไม่ถูกต้อง
- การเปรียบเทียบค่า: การเปรียบเทียบค่าทศนิยมโดยตรงอาจให้ผลลัพธ์ที่ไม่คาดคิด เนื่องจากข้อผิดพลาดในการปัดเศษ ควรใช้ช่วงความคลาดเคลื่อนในการเปรียบเทียบ
โค้ดโปรแกรมตัวอย่างข้อมูลทศนิยมต่อไปนี้จะแสดงผลลัพธ์ที่อาจไม่ตรงกับค่าที่เราคาดหวัง เนื่องจากค่า 0.1 ไม่สามารถแทนได้อย่างแม่นยำในระบบเลขฐานสอง
วิธีการแก้ไขปัญหาเรื่องความผิดพลาดในตัวเลขทศนิยมได้แก่
- ควรเลือกใช้ double แทน float
- ควรเปรียบเทียบค่าด้วยช่วงความคลาดเคลื่อนที่ยอมรับได้
- ใช้ไลบรารีสำหรับเลขทศนิยมที่มีความแม่นยำสูง เช่น GMP (GNU Multiple Precision Arithmetic Library)
float f = 0.1f;
double d = 0.1;
float f2 = 0.1f + 0.2f;
double d2 = 0.1 + 0.2;
Console.WriteLine($"f = {f}");
Console.WriteLine($"d = {d}");
Console.WriteLine($"0.1f + 0.2f = {f2}");
Console.WriteLine($"0.1 + 0.2 = {d2}");
if (f == 0.1f)
{
Console.WriteLine("f == 0.1f");
} else
{
Console.WriteLine("f != 0.1f");
}
if (d == 0.1)
{
Console.WriteLine("d == 0.1");
}
else
{
Console.WriteLine("d != 0.1");
}
ตัวอย่างผลลัพธ์ของการทำงานเป็นดังนี้
f = 0.1
d = 0.1
0.1f + 0.2f = 0.3
0.1 + 0.2 = 0.30000000000000004
f == 0.1f
d == 0.1
แถวลำดับ
แถวลำดับ หรืออาเรย์ (Array) เป็นโครงสร้างข้อมูลประเภทหนึ่งที่เกิดจากการจองข้อมูลประเภทเดียวกันเป็นจำนวน n ชุด ค่าในตัวแปรเดียว โดยแต่ละค่าจะมีดัชนี (index) ที่ใช้ในการระบุตำแหน่ง โดยข้อมูลอยู่ต่อเรียงกันไปเป็นลำดับที่ 0 ถึง n-1 อันทำให้สะดวกต่อการบริหารจัดการกับตัวแปร เช่น ต้องการสร้างตัวแปรเก็บพิกัดค่า x จำนวน 5 ชุด จะต้องสร้างตัวแปร 5 ตัว แต่ถ้าเป็นแถวลำดับจะใช้ตัวแปรตัวเดียว แต่อ้างอิงลำดับของข้อมูลเป็นข้อมูลลำดับที่ 0, 1, 2 ,3 และ 4 เป็นต้น
การสร้างตัวแปรประเภทแถวลำดับมีรูปแบบของการสร้างดังนี้
ชนิดตัวแปร[] ชื่อตัวแปร;
// สร้างอาเรย์จำนวนเต็มขนาด 5 องค์ประกอบ
int[] numbers = new int[5];
// สร้างอาเรย์สตริงและกำหนดค่าเริ่มต้น
string[] names = { "Alice", "Bob", "Charlie" };
การกำหนดค่าให้กับแถวลำดับมีรูปแบบการสั่งงานดังนี้
ชนิดตัวแปร[] ชื่อตัวแปร = new ชนิดตัวแปร[จำนวนสมาชิก];
ชนิดตัวแปร[จำนวนสมาชิก] ชื่อตัวแปร = {
ข้อมูล0, ข้อมูล1, ข้อมูล2, …, ข้อมูลจำนวนสมาชิก-1
};
ตัวอย่างการประยุกต์ใช้แถวลำดดับเพื่อเก็บค่าสถานะของตัวละคร เช่น ความแข็งแกร่ง (ST: Strength) ความแม่นยำ (AC: Accuracy) ความคล่องแคล่วว่องไว (DX: Dexterity) ความอดทน (RS: Resistance) แต้มชีวิต (HP: Hit Points) แต้มพลังเวทย์มนต์ (MP: Magic Points) และค่าประสบการณ์ ( EX: Experience ) โดยให้สมาชิกแต่ละตัวเก็บเป็นตัวเลขจำนวนเต็ม และค่าสูงสุดไม่เกิน 4000 พร้อมจัดเก็บแบบเรียงกันไปเป็นลำดับ 0,1,2,3,4 และ 5 สามารถเขียนได้ดังนี้
UIint16 [7] actor_stat;
การเข้าถึงสมาชิกของแถวลำดับจะต้องระบุตำแหน่งลำดับของสมาชิกนั้นดังรูปแบบการใช้งานด้านล่างนี้ โดยสมาชิกตัวแรกเป็นลำดับที่ 0 และลำดับสุดท้ายจะเท่ากับจำนวนสมาชิกลบด้วย 1
ชื่อตัวแปร[ ลำดับ ] = ค่า
สำหรับการอ้างอิงถึงค่าของข้อมูลในแถวลำดับให้ทำตามรูปแบบต่อไปนี้
ชื่อตัวแปร[ ลำดับ ]
การตรวจสอบจำนวนสมาชิกภายใแถวลำดับสามารถใช้คำสั่ง Length เพื่ออ่านค่าออกมาตามรูปแบบการใช้งานดังนี้
ชื่อตัวแปร.Length
กรณีที่กำหนดค่าของแต่ละคุณสมบัติให้มีค่าเรียงกันไปดังนี้ 5, 4, 5, 5, 10, 10 และ 0 หลังจากนั้นเขียนโปรแกรมเพื่อวนรอบเพื่อแสดงข้อมูลแต่ละรายการสามารถเขียนได้ดังตัวอย่างโปรแกรมต่อไปนี้
using System;
namespace array1
{
class Program
{
static UInt16[] actor_stat;
static void Main(string[] args)
{
actor_stat = new ushort[7];
String[] stat_info = {
"ST","AC","DX","RS","HP","MP","EX"
};
actor_stat[0] = 5; // ST
actor_stat[1] = 4; // AC
actor_stat[2] = 5; // DX
actor_stat[3] = 5; // RS
actor_stat[4] = 10; // HP
actor_stat[5] = 10; // MP
actor_stat[6] = 0; // EX
for (int idx=0; idx<actor_stat.Length; idx++)
{
Console.WriteLine(stat_info[idx].ToString() +
"="+ actor_stat[idx].ToString());
}
}
}
}
ตัวอย้างแถวลำดับเก็บสถานะของตัวละคร
int [] num = new int[5];
string [,] couples = new string[3,2];
int [] num2 = new int[5] {1,2,3,4,5};
num[0] = 1;
num[1] = 2;
num[2] = 3;
num[3] = 4;
num[4] = 5;
string [,] dict = new string[3,2]{
{“bat”,”ค้างคาว”},{“rat”,”หนู”},{“cat”,”แมว”}
}
Console.WriteLine(“{0} = {1}”, dict[0,0], dict[0,1]);
การแปลงข้อมูลตัวเลขให้เป็นข้อความมีรูปแบบการใช้งานดังนี้
ข้อมูลตัวอักษร = ตัวแปร.ToString()
โครงสร้างภาษา
โครงสร้างโปรแกรมพื้นฐานของ C# เป็นดังด้านล่างนี้ โดยจะพบว่า เมื่อใดที่วัตถุถูกเรียกขึ้นใช้งาน และพร้อมทำงานจะมีการเรียกใช้ฟังก์ชัน Main() ให้ทำงานเป็นฟังก์ชันแรกเสมอ และนามสกุลของโค้ดจะเป็น .cs
using System;
namespace ชื่อแอปพลิเคชัน
{
class ชื่อคลาส
{
static void Main( string[] args )
{
Console.WriteLine( “Hi, C#!” );
}
}
}
ภาษา C# เป็นภาษาแบบเชิงวัตถุ ที่กำหนดให้มีฟังก์ชันเริ่มต้นทำงานชื่อ main() โดยใช้เครื่องหมาย { แทนการเริ่มต้นบล็อกเขียนโค้ด (block coding) และปิดบล็อกด้วยเครื่องหมาย } ดังตัวอย่างต่อไปนี้
static void main()
{
var weAre = "GameDevPBRU";
var myFaculty = "IT@PBRU";
}
ตัวอย่างเช่น
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello, World!");
Console.ReadLine();
}
}
}
แต่ใน .NET รุ่นใหม่ได้ปรับปรุงเรื่องการเขียนที่ยืดเยื้อด้วยการเปิดให้ผู้เขียนโปรแกรมเขียนเฉพาะส่วนที่อยู่ภายใน Main() ได้โดยไม่ต้องประกาศคลาส หรือ namespace เพิ่มเติม ทำให้โค้ดเปลี่ยนเป็นดังนี้
Console.WriteLine("Hello, World!");
Console.ReadLine();
หรือ
var weAre = "GameDevPBRU";
var myFaculty = "IT@PBRU";
void SayHi( string name )
{
Console.WriteLine($"Hi {name}, I’m {weAre}.{myFacuulty}.");
}
SayHi("Jarut");
จากฟังก์ชันหรือเมธอด (method) ชื่อ main() ที่กำหนดให้เป็นฟังก์ชันหลักในการทำงาน และฟังก์ชัน SayHi() ที่เขียนขึ้น เป็นการสร้างพฤติกรรมการทำงานของโปรแกรมหรือวัตถุ
จากตัวอย่างข้างต้นนั้น ผู้อ่านจะพบว่า SayHi() มีการกำหนดพฤติกรรมการทำงานให้นำเข้าหรือรับค่าแบบสตริงโดยสมมติชื่อกล่องเก็บข้อมูลสตริงที่รับเข้ามาในชื่อ name ส่วนการทำงานจะเริ่มต้นหลังเครื่องหมาย { และสิ้นสุดเมื่อปิดด้วย } โดยสิ่งที่ทำหรือโค้ดโปรแกรมในพฤติกรรม SayHi() คือ แสดงข้อความ $”Hi {name}, I’m {weAre}.{myFaculty}.” ด้วยคำสั่ง WriteLine() อันเป็นคำสั่งที่อยู่ภายใต้คลังชุดคำสั่งที่ชื่อ Console ทำให้มีการนำค่าที่เก็บในตัวแปร (variable) หรือคุณสมบัติ (property) ที่ชื่อ name, weAre และ myFaculty มาแสดง
ตัวอย่างแสดงค่าจากตัวแปร x และ y กับค่าคงที่ MY_PI
var x = 100;
var y = -50.2;
const float my_pi = 3.1415f;
Console.WriteLine("x = " + x);
Console.WriteLine("y = " + y);
Console.WriteLine("my_pi = " + my_pi);
ตัวอย่างรับค่าชื่อกับนามสกุลเพื่อนำมาแสดงผล
string firstName, lastName;
Console.WriteLine("Enter your first name : ");
firstName = Console.ReadLine();
Console.WriteLine("Enter your last name : ");
lastName = Console.ReadLine();
Console.WriteLine( "Hello, " + firstName + " " + lastName + "!" );
Console.ReadLine();
สรุป
จากบทความในตอนที่ 1 จะพบว่าภาษา C# มีรากฐานที่ยาวนานและสร้างขึ้นมาเพื่อแก้ปัญหาในยุคต้นของปี ค.ศ. 2000 และมีการปรับเปลี่ยนตามความเปลี่ยนแปลงของการพัฒนาซอฟต์แวร์ และถูกนำมาใช้เป็นสคริปต์หลักของเครื่องมือพัฒนาเกมอย่าง Unity ทำให้การที่ผู้อ่านเข้าใจหลักภาษาได้ดีจึงเป็นผลให้สามารถพัฒนาเกมได้มีประสิทธิภาพมากขึ้น
ในบทความตอนหน้าจะเป็นเรื่องของการใช้คำสั่งกลุ่มของการควบคุม และการสร้างโปรแกรมย่อย อันเป็นพื้นฐานสำหรับการควบคุมและสั่งงานตามเงื่อนไขหรือทำซ้ำตามความต้องการของผู้พัฒนาโปรแกรม สุดท้ายนี้ขอให้สนุกกับการเขียนเกมครับ
(C) 2024, โดย จารุต บุศราทิจ
DcG.IT@PBRU