การออกแบบ
ภาษาซีเป็นภาษาที่ใช้ในการมีปฏิสัมพันธ์เช่น เชิงคำสั่ง (หรือ
เชิงกระบวนงาน) ถูกออกแบบขึ้นเพื่อใช้แปลด้วยตัวแปลโปรแกรม
แบบการเชื่อมโยงที่ตรงไปตรงมา สามารถเข้าถึงหน่วยความจำใน
ระดับล่าง เพื่อสร้างภาษาที่จับคู่อย่างมีประสิทธิภาพกับชุดคำสั่ง
เครื่อง และแทบไม่ต้องการสนับสนุนใด ๆ ขณะทำงาน ภาษาซีจึงเป็น
ประโยชน์สำหรับหลายโปรแกรมที่ก่อนหน้านี้เคยเขียนในภาษาแอส
เซมบลีมาก่อน
หากคำนึงถึงความสามารถในระดับล่าง ภาษานี้ถูกออกแบบขึ้นเพื่อส่ง
เสริมการเขียนโปรแกรมที่ขึ้นอยู่กับเครื่องใดเครื่องหนึ่ง (machine-
independent) โปรแกรมภาษาซีที่เขียนขึ้นตามมาตรฐานและเคลื่อน
ย้ายได้ สามารถแปลได้บนแพลตฟอร์มคอมพิวเตอร์และระบบปฏิบัติ
การต่าง ๆ อย่างกว้างขวาง โดยแก้ไขรหัสต้นฉบับเพียงเล็กน้อยหรือ
ไม่ต้องแก้ไขเลย ภาษานี้สามารถใช้ได้บนแพลตฟอร์มได้หลากหลาย
ลักษณะเฉพาะ
ภาษาซีมีสิ่งอำนวยสำหรับการเขียนโปรแกรมเชิงโครงสร้าง
และสามารถกำหนดขอบข่ายตัวแปรและเรียกซ้ำ เช่นเดียวกับภาษา
โปรแกรมเชิงคำสั่งส่วนใหญ่ในสายตระกูลภาษาอัลกอล ในขณะที่
ระบบชนิดตัวแปรแบบอพลวัตช่วยป้องกันการดำเนินการที่ไม่ได้
ตั้งใจ รหัสที่ทำงานได้ทั้งหมดในภาษาซีถูกบรรจุอยู่ในฟังก์ชัน
พารามิเตอร์ของฟังก์ชันส่งผ่านด้วยค่าของตัวแปรเสมอ ส่วนการส่ง
ผ่านด้วยการอ้างอิงจะถูกจำลองขึ้นโดยการส่งผ่านค่าตัวชี้ ชนิดข้อมูล
รวมแบบแตกต่าง (struct) ช่วยให้สมาชิกข้อมูลที่เกี่ยวข้องกัน
สามารถรวมกันและจัดการได้ในหน่วยเดียว รหัสต้นฉบับของภาษาซี
เป็นรูปแบบอิสระ ซึ่งใช้อัฒภาค (;) เป็นตัวจบคำสั่ง (มิใช่ตัวแบ่ง)
ภาษาซียังมีลักษณะเฉพาะต่อไปนี้เพิ่มเติมตัวแปรอาจถูกซ่อนใน
บล็อกซ้อนใน
ชนิดตัวแปรไม่เคร่งครัด เช่นข้อมูลตัวอักษรสามารถใช้เป็นจำนวนเต็ม
เข้าถึงหน่วยความจำคอมพิวเตอร์ในระดับต่ำโดยแปลงที่อยู่ในเครื่อง
ด้วยชนิดตัวแปรตัวชี้ (pointer)
ฟังก์ชันและตัวชี้ข้อมูลรองรับการทำงานในภาวะหลายรูปแบบ
(polymorphism)
การกำหนดดัชนีแถวลำดับสามารถทำได้ด้วยวิธีรอง คือนิยามในพจน์
ของเลขคณิตของตัวชี้
ตัวประมวลผลก่อนสำหรับการนิยามแมโคร การรวมไฟล์รหัสต้นฉบับ
และการแปลโปรแกรมแบบมีเงื่อนไข
ฟังก์ชันทางคณิตศาสตร์ รวมอยู่ในไลบรารี
คำหลักที่สงวนไว้มีจำนวนค่อนข้างน้อย
ตัวดำเนินการแบบประสมจำนวนมาก อาทิ +=, -=, *=, ++ ฯลฯ
โครงสร้างการเขียน คล้ายภาษาบีมากกว่าภาษาอัลกอล ตัวอย่างเช่น
ใช้วงเล็บปีกกา { ... } แทนที่จะเป็น begin ... end ในภาษาอัลกอล
60 หรือวงเล็บโค้ง ( ... ) ในภาษาอัลกอล 68 เท่ากับ = ใช้สำหรับ
ในภาษาอัลกอลเท่ากับสองตัว == ใช้สำหรับเปรียบเทียบความเท่า
กัน แทนที่จะเป็น .EQ. ในภาษาฟอร์แทรนหรือ = ในภาษาเบสิกและ
ภาษาอัลกอล
ตรรกะ "และ" กับ "หรือ" แทนด้วย && กับ || ตามลำดับ แทนที่จะเป็น
ตัวดำเนินการ ∧ กับ ∨ ในภาษาอัลกอล แต่ตัวดำเนินการดังกล่าวจะ
ไม่ประเมินค่าตัวถูกดำเนินการทางขวา ถ้าหากผลลัพธ์จากทางซ้าย
สามารถพิจารณาได้แล้ว เหตุการณ์เช่นนี้เรียกว่าการประเมินค่าแบบ
ลัดวงจร (short-circuit evaluation) และตัวดำเนินการดังกล่าวก็มี
ความหมายต่างจากตัวดำเนินการระดับบิต & กับ |
คุณลักษณะที่ขาดไป
ธรรมชาติของภาษาในระดับต่ำช่วยให้โปรแกรมเมอร์ควบคุม
สิ่งที่คอมพิวเตอร์กระทำได้อย่างใกล้ชิด ในขณะที่อนุญาตให้มีการ
ปรับแต่งพิเศษและการทำให้เหมาะที่สุดสำหรับแพลตฟอร์มหนึ่งใด
โดยเฉพาะ สิ่งนี้ทำให้รหัสสามารถทำงานได้อย่างมีประสิทธิภาพบน
ฮาร์ดแวร์ที่มีทรัพยากรจำกัดมาก ๆ ได้เช่นระบบฝังตัว
ภาษาซีไม่มีคุณลักษณะบางอย่างที่มีในภาษาอื่นอาทิ
ไม่มีการนิยามฟังก์ชันซ้อนใน
ไม่มีการกำหนดค่าแถวลำดับหรือสายอักขระโดยตรง (การคัดลอก
ข้อมูลจะกระทำผ่านฟังก์ชันมาตรฐาน แต่ก็รองรับการกำหนดค่าวัตถุ
ที่มีชนิดเป็น struct หรือ union)
ไม่มีการเก็บข้อมูลขยะโดยอัตโนมัติ
ไม่มีข้อกำหนดเพื่อการตรวจสอบขอบเขตของแถวลำดับ
ไม่มีการดำเนินการสำหรับแถวลำดับทั้งชุดในระดับตัวภาษา
ไม่มีวากยสัมพันธ์สำหรับช่วงค่า (range) เช่น A..B ที่ใช้ในบางภาษา
ก่อนถึงภาษาซี99 ไม่มีการแบ่งแยกชนิดข้อมูลแบบบูล (ค่าศูนย์หรือ
ไม่ศูนย์ถูกนำมาใช้แทน)
ไม่มีส่วนปิดคลุมแบบรูปนัย (closure) หรือฟังก์ชันในรูปแบบ
พารามิเตอร์ (มีเพียงตัวชี้ของฟังก์ชันและตัวแปร)
เพียงการเรียกใช้ฟังก์ชันซ้อนลงไป เว้นแต่การใช้ฟังก์ชันlongjmp
หรือ setcontext จากไลบรารี
ไม่มีการจัดกระทำสิ่งผิดปรกติ (exception handling) ฟังก์ชัน
ไลบรารีมาตรฐานจะแสดงเงื่อนไขข้อผิดพลาดด้วยตัวแปรส่วน
goto แบบไม่ใช่เฉพาะที่ไว้ด้วย
การเขียนโปรแกรมเชิงมอดูลรองรับแค่ระดับพื้นฐานเท่านั้น
การโอเวอร์โหลดฟังก์ชันหรือตัวดำเนินการไม่รองรับภาวะหลายรูป
แบบขณะแปลโปรแกรม
การเขียนโปรแกรมเชิงวัตถุรองรับในระดับที่จำกัดมาก โดยพิจารณา
จากภาวะหลายรูปแบบกับการรับทอด (inheritance)
การซ่อนสารสนเทศ (encapsulation) รองรับในระดับที่จำกัด
ไม่รองรับโดยพื้นฐานกับการทำงานแบบมัลติเทร็ดและเครือข่าย
ไม่มีไลบรารีมาตรฐานสำหรับคอมพิวเตอร์กราฟิกส์และความจำเป็น
หลายอย่างในการเขียนโปรแกรมประยุกต์
คุณลักษณะเหล่านี้จำนวนหนึ่งมีให้ใช้ได้จากส่วนขยายในตัวแปล
โปรแกรมบางตัว หรือจัดสรรไว้แล้วในสภาพแวดล้อมของระบบปฏิบัติ
การ (เช่นโพสซิกซ์) หรือจัดเตรียมโดยไลบรารีภายนอก หรือสามารถ
จำลองโดยดัดแปลงแก้ไขรหัสที่มีอยู่ หรือบางครั้งก็ถูกพิจารณาว่า
ไม่ใช่รูปแบบการเขียนโปรแกรมที่เหมาะสม
พฤติกรรมไม่นิยาม
ถูกกำหนดว่าต้องตรวจสอบขณะแปลโปรแกรม ในกรณีของภาษาซี
"พฤติกรรมไม่นิยาม" หมายถึงพฤติกรรมเฉพาะอย่างที่เกิดขึ้นโดย
มาตรฐานมิได้ระบุไว้ และสิ่งที่จะเกิดขึ้นก็ไม่มีในเอกสารการใช้งาน
ของภาษาซี หนึ่งในชุดคำสั่งที่มีชื่อเสียงและน่าขบขันจากกลุ่มข่าว
comp.std.c และ comp.lang.c นั้นทำให้โปรแกรมเกิดปัญหาที่เรียก
ว่า "ปิศาจที่ออกมาจากจมูกของคุณ" (demons to fly out of your
nose) บางครั้งสิ่งที่เกิดขึ้นในทางปฏิบัติอันเป็นผลมาจาก
พฤติกรรมไม่นิยามทำให้เกิดจุดบกพร่องที่ยากต่อการตรวจสอบและ
อาจทำให้ข้อมูลในหน่วยความจำผิดแปลกไป ตัวแปลโปรแกรมบาง
ชนิดช่วยสร้างการดำเนินงานที่ทำให้พฤติกรรมนั้นดีขึ้นและมีเหตุผล
ซึ่งแตกต่างจากการแปลโดยตัวแปลชนิดอื่นที่อาจดำเนินงานไม่
เหมือนกัน สาเหตุที่พฤติกรรมบางอย่างยังคงไว้ว่าไม่นิยามก็เพื่อให้
ตัวแปลโปรแกรมบนสถาปัตยกรรมชุดของคำสั่งเครื่องที่หลากหลาย
สามารถสร้างรหัสที่ทำงานได้ในพฤติกรรมที่นิยามอย่างมี
ประสิทธิภาพมากขึ้น ซึ่งเชื่อว่าเป็นบทบาทหนึ่งที่สำคัญของภาษาซี
ในฐานะภาษาสำหรับสร้างระบบ ดังนั้นภาษาซีจึงส่งผลให้เกิดความ
รับผิดชอบของโปรแกรมเมอร์เพื่อหลีกเลี่ยงพฤติกรรมไม่นิยาม โดย
อาจใช้เครื่องมือต่าง ๆ เพื่อค้นหาส่วนของโปรแกรมว่าพฤติกรรมใด
บ้างที่ไม่นิยาม ตัวอย่างของพฤติกรรมไม่นิยามเช่น
การเข้าถึงข้อมูลนอกขอบเขตของแถวลำดับ
ข้อมูลล้น (overflow) ในตัวแปรจำนวนเต็มมีเครื่องหมาย
ฟังก์ชันที่กำหนดไว้ว่าต้องส่งค่ากลับ แต่ไม่มีคำสั่งส่งกลับ (return)
ในฟังก์ชัน ในขณะเดียวกันค่าส่งกลับก็ถูกใช้งานด้วย
การอ่านค่าตัวแปรโดยที่ยังไม่ได้กำหนดค่าเริ่มต้น
การดำเนินการเหล่านี้ทั้งหมดเป็นข้อผิดพลาดในการเขียนโปรแกรม
ซึ่งสามารถปรากฏในการใช้ภาษาโปรแกรมอื่น ๆ จำนวนมาก ภาษาซี
จึงถูกวิพากษ์วิจารณ์เพราะมาตรฐานของมันสามารถชี้ให้เห็นถึง
พฤติกรรมไม่นิยามในหลายกรณีได้อย่างชัดเจน รวมไปถึงพฤติกรรม
บางอย่างที่อาจนิยามไว้อย่างดีแล้ว และไม่มีการระบุกลไกการจัด
กระทำต่อข้อผิดพลาดขณะทำงานเลย
ตัวอย่างหนึ่งของพฤติกรรมไม่นิยามเช่นการเรียกใช้ fflush() บน
กระแสข้อมูลป้อนเข้า ซึ่งไม่จำเป็นว่าจะทำให้โปรแกรมทำงานผิด
พลาด แต่ในบางกรณีที่การทำให้เกิดผลที่สอดคล้องกันได้นิยามไว้
แล้วอย่างดี มีความหมายซึ่งใช้ประโยชน์ได้ (จากตัวอย่างนี้คือการ
สมมติให้ข้อมูลที่ป้อนเข้าถูกละทิ้งทั้งหมดจนถึงอักขระขึ้นบรรทัดใหม่
ตัวถัดไป) เป็น ส่วนขยาย ที่อนุญาต ส่วนขยายที่ไม่เป็นมาตรฐานเช่น
นี้เป็นข้อจำกัดความสามารถในการเคลื่อนย้ายของซอฟต์แวร์
ไม่มีความคิดเห็น:
แสดงความคิดเห็น