ภาษาซี

**ภาษาซี** () เป็นภาษาโปรแกรมสำหรับวัตถุประสงค์ทั่วไป เริ่มพัฒนาขึ้นระหว่าง พ.ศ. 2512–2516 (ค.ศ. 1969–1973) โดยเดนนิส ริตชี (Dennis Ritchie) ที่เอทีแอนด์ทีเบลล์แล็บส์ (AT&T Bell Labs) ภาษาซีเป็นภาษาที่มีความยืดหยุ่นในการเขียนโปรแกรมและมีเครื่องมืออำนวยความสะดวกสำหรับการเขียนโปรแกรมเชิงโครงสร้างและอนุญาตให้มีขอบข่ายตัวแปร (scope) และการเรียกซ้ำ (recursion) ในขณะที่ระบบชนิดตัวแปรอพลวัตก็ช่วยป้องกันการดำเนินการที่ไม่ตั้งใจหลายอย่าง เหมือนกับภาษาโปรแกรมเชิงคำสั่งส่วนใหญ่ในแบบแผนของภาษาอัลกอล การออกแบบของภาษาซีมีคอนสตรักต์ (construct) ที่โยงกับชุดคำสั่งเครื่องทั่วไปได้อย่างพอเพียง จึงทำให้ยังมีการใช้ในโปรแกรมประยุกต์ซึ่งแต่ก่อนลงรหัสเป็นภาษาแอสเซมบลี คือซอฟต์แวร์ระบบอันโดดเด่นอย่างระบบปฏิบัติการคอมพิวเตอร์ ยูนิกซ์

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

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

ก่อนที่จะมีมาตรฐานภาษาซีอย่างเป็นทางการ ผู้ใช้และผู้พัฒนาต่างก็เชื่อถือในข้อกำหนดอย่างไม่เป็นทางการในหนังสือที่เขียนโดยเดนนิส ริตชี และไบรอัน เคอร์นิกัน (Brian Kernighan) ภาษาซีรุ่นนั้นจึงเรียกกันโดยทั่วไปว่า *ภาษาเคแอนด์อาร์ซี* (K&R C) ต่อมา พ.ศ. 2532 สถาบันมาตรฐานแห่งชาติของสหรัฐอเมริกา (ANSI) ได้ตีพิมพ์มาตรฐานสำหรับภาษาซีขึ้นมา เรียกกันว่า *[[ภาษาแอนซีซี]]* (ANSI C) หรือ *ภาษาซี89* (C89) ในปีถัดมา องค์การระหว่างประเทศว่าด้วยการมาตรฐาน (ISO) ได้อนุมัติให้ข้อกำหนดเดียวกันนี้เป็นมาตรฐานสากล เรียกกันว่า *ภาษาซี90* (C90) ในเวลาต่อมาอีก องค์การฯ ก็ได้เผยแพร่ส่วนขยายมาตรฐานเพื่อรองรับสากลวิวัตน์ (internationalization) เมื่อ พ.ศ. 2538 และมาตรฐานที่ตรวจชำระใหม่เมื่อ พ.ศ. 2542 เรียกกันว่า *[[ภาษาซี99]]* (C99) มาตรฐานรุ่นปัจจุบันก็ได้รับอนุมัติเมื่อเดือนธันวาคม พ.ศ. 2554 เรียกกันว่า *[[ภาษาซี11|ภาษาซี12]]* (C12)

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

ขณะทำงาน ภาษาซีจึงเป็นประโยชน์สำหรับหลายโปรแกรมที่ก่อนหน้านี้เคยเขียนในภาษาแอสเซมบลีมาก่อน

หากคำนึงถึงความสามารถในระดับล่าง ภาษานี้ถูกออกแบบขึ้นเพื่อส่งเสริมการเขียนโปรแกรมที่ขึ้นอยู่กับเครื่องใดเครื่องหนึ่ง (machine-independent) โปรแกรมภาษาซีที่เขียนขึ้นตามมาตรฐานและเคลื่อนย้ายได้ สามารถแปลได้บนแพลตฟอร์มคอมพิวเตอร์และระบบปฏิบัติการต่าง ๆ อย่างกว้างขวาง โดยแก้ไขรหัสต้นฉบับเพียงเล็กน้อยหรือไม่ต้องแก้ไขเลย ภาษานี้สามารถใช้ได้บนแพลตฟอร์มได้หลากหลายตั้งแต่ไมโครคอนโทรลเลอร์ฝังตัวไปจนถึงแฮรี่เคน

## ลักษณะเฉพาะ
ภาษาซีมีสิ่งอำนวยสำหรับการเขียนโปรแกรมเชิงโครงสร้าง และสามารถกำหนดขอบข่ายตัวแปรและเรียกซ้ำ เช่นเดียวกับภาษาโปรแกรมเชิงคำสั่งส่วนใหญ่ในสายตระกูลภาษาอัลกอล ในขณะที่ระบบชนิดตัวแปรแบบอพลวัตช่วยป้องกันการดำเนินการที่ไม่ได้ตั้งใจ รหัสที่ทำงานได้ทั้งหมดในภาษาซีถูกบรรจุอยู่ในฟังก์ชัน พารามิเตอร์ของฟังก์ชันส่งผ่านด้วยค่าของตัวแปรเสมอ ส่วนการส่งผ่านด้วยการอ้างอิงจะถูกจำลองขึ้นโดยการส่งผ่านค่าตัวชี้ ชนิดข้อมูลรวมแบบแตกต่าง (`[[สตรักต์|struct]]`) ช่วยให้สมาชิกข้อมูลที่เกี่ยวข้องกันสามารถรวมกันและจัดการได้ในหน่วยเดียว รหัสต้นฉบับของภาษาซีเป็นรูปแบบอิสระ ซึ่งใช้อัฒภาค (`;`) เป็นตัวจบคำสั่ง (มิใช่ตัวแบ่ง)

ภาษาซียังมีลักษณะเฉพาะต่อไปนี้เพิ่มเติม
* ตัวแปรอาจถูกซ่อนในบล็อกซ้อนใน
* ชนิดตัวแปรไม่เคร่งครัด เช่นข้อมูลตัวอักษรสามารถใช้เป็นจำนวนเต็ม
* เข้าถึงหน่วยความจำคอมพิวเตอร์ในระดับต่ำโดยแปลงที่อยู่ในเครื่องด้วยชนิดตัวแปรตัวชี้ (pointer)
* ฟังก์ชันและตัวชี้ข้อมูลรองรับการทำงานในภาวะหลายรูปแบบ (polymorphism)
* การกำหนดดัชนีแถวลำดับสามารถทำได้ด้วยวิธีรอง คือนิยามในพจน์ของเลขคณิตของตัวชี้
* ตัวประมวลผลก่อนสำหรับการนิยามแมโคร การรวมไฟล์รหัสต้นฉบับ และการแปลโปรแกรมแแบ
* ความสามารถที่ซับซ้อนเช่น ไอ/โอ การจัดการสายอักขระ และฟังก์ชันทางคณิตศาสตร์ รวมอยู่ในไลบรารี
* คำหลักที่สงวนไว้มีจำนวนค่อนข้างน้อย
* ตัวดำเนินการแบบประสมจำนวนมาก เช่น `+=`, `-=`, `*=`, `++` ฯลฯ

โครงสร้างการเขียน คล้ายภาษาบีมากกว่าภาษาอัลกอล ตัวอย่างเช่น
* ใช้วงเล็บปีกกา `{ ... }` แทนที่จะเป็น `begin ... end` ในภาษาอัลกอล 60 หรือวงเล็บโค้ง `( ... )` ในภาษาอัลกอล 68
* เท่ากับ `=` ใช้สำหรับกำหนดค่า (คัดลอกข้อมูล) เหมือนภาษาฟอร์แทรน แทนที่จะเป็น `:=` ในภาษาอัลกอล
* เท่ากับสองตัว `==` ใช้สำหรับเปรียบเทียบความเท่ากัน แทนที่จะเป็น `.EQ.` ในภาษาฟอร์แทรนหรือ `=` ในภาษาเบสิกและภาษาอัลกอล
* ตรรกะ "และ" กับ "หรือ" แทนด้วย `&&` กับ `||` ตามลำดับ แทนที่จะเป็นตัวดำเนินการ ∧ กับ ∨ ในภาษาอัลกอล แต่ตัวดำเนินการดังกล่าวจะไม่ประเมินค่าตัวถูกดำเนินการทางขวา ถ้าหากผลลัพธ์จากทางซ้ายสามารถพิจารณาได้แล้ว เหตุการณ์เช่นนี้เรียกว่าการประเมินค่าแบบลัดวงจร (short-circuit evaluation) และตัวดำเนินการดังกล่าวก็มีความหมายต่างจากตัวดำเนินการระดับบิต `&` กับ `|`

### คุณลักษณะที่ขาดไป
ธรรมชาติของภาษาในระดับต่ำช่วยให้โปรแกรมเมอร์ควบคุมสิ่งที่คอมพิวเตอร์กระทำได้อย่างใกล้ชิด ในขณะที่อนุญาตให้มีการปรับแต่งพิเศษและการทำให้เหมาะที่สุดสำหรับแพลตฟอร์มหนึ่งใดโดยเฉพาะ สิ่งนี้ทำให้รหัสสามารถทำงานได้อย่างมีประสิทธิภาพบนฮาร์ดแวร์ที่มีทรัพยากรจำกัดมาก ๆ ได้เช่นระบบฝังตัว

ภาษาซีไม่มีคุณลักษณะบางอย่างที่มีในภาษาอื่นอาทิ
* ไม่มีการนิยามฟังก์ชันซ้อนใน
* ไม่มีการกำหนดค่าแถวลำดับหรือสายอักขระโดยตรง (การคัดลอกข้อมูลจะกระทำผ่านฟังก์ชันมาตรฐาน แต่ก็รองรับการกำหนดค่าวัตถุที่มีชนิดเป็น `struct` หรือ `union`)
* ไม่มีการเก็บข้อมูลขยะโดยอัตโนมัติ
* ไม่มีข้อกำหนดเพื่อการตรวจสอบขอบเขตของแถวลำดับ
* ไม่มีการดำเนินการสำหรับแถวลำดับทั้งชุดในระดับตัวภาษา
* ไม่มีวากยสัมพันธ์สำหรับช่วงค่า (range) เช่น `A..B` ที่ใช้ในบางภาษา
* ก่อนถึงภาษาซี99 ไม่มีการแบ่งแยกชนิดข้อมูลแบบบูล (ค่าศูนย์หรือไม่ศูนย์ถูกนำมาใช้แทน) 
* ไม่มีส่วนปิดคลุมแบบรูปนัย (closure) หรือฟังก์ชันในรูปแบบพารามิเตอร์ (มีเพียงตัวชี้ของฟังก์ชันและตัวแปร)
* ไม่มีตัวสร้างและโครูทีน การควบคุมกระแสการทำงานภายในเทร็ดมีเพียงการเรียกใช้ฟังก์ชันซ้อนลงไป เว้นแต่การใช้ฟังก์ชัน `[[longjmp]]` หรือ `[[setcontext]]` จากไลบรารี
* ไม่มีการจัดกระทำสิ่งผิดปรกติ (exception handling) ฟังก์ชันไลบรารีมาตรฐานจะแสดงเงื่อนไขข้อผิดพลาดด้วยตัวแปรส่วนกลาง `[[errno]]` และ/หรือค่ากลับคืนพิเศษ และฟังก์ชันไลบรารีได้เตรียม `goto` แบบไม่ใช่เฉพาะที่ไว้ด้วย
* การเขียนโปรแกรมเชิงมอดูลรองรับแค่ระดับพื้นฐานเท่านั้น
* การโอเวอร์โหลดฟังก์ชันหรือตัวดำเนินการไม่รองรับภาวะหลายรูปแบบขณะแปลโปรแกรม
* การเขียนโปรแกรมเชิงวัตถุรองรับในระดับที่จำกัดมาก โดยพิจารณาจากภาวะหลายรูปแบบกับการรับทอด (inheritance)
* การซ่อนสารสนเทศ (encapsulation) รองรับในระดับที่จำกัด
* ไม่รองรับโดยพื้นฐานกับการทำงานแบบมัลติเทร็ดและเครือข่ายคอมพิวเตอร์
* ไม่มีไลบรารีมาตรฐานสำหรับคอมพิวเตอร์กราฟิกส์และความจำเป็นหลายอย่างในการเขียนโปรแกรมประยุกต์
คุณลักษณะเหล่านี้จำนวนหนึ่งมีให้ใช้ได้จากส่วนขยายในตัวแปลโปรแกรมบางตัว หรือจัดสรรไว้แล้วในสภาพแวดล้อมของระบบปฏิบัติการ (เช่นโพสซิกซ์) หรือจัดเตรียมโดยไลบรารีภายนอก หรือสามารถจำลองโดยดัดแปลงแก้ไขรหัสที่มีอยู่ หรือบางครั้งก็ถูกพิจารณาว่าไม่ใช่รูปแบบการเขียนโปรแกรมที่เหมาะสม

### พฤติกรรมไม่นิยาม
การดำเนินการหลายอย่างในภาษาซีมีพฤติกรรมไม่นิยามซึ่งไม่ถูกกำหนดว่าต้องตรวจสอบขณะแปลโปรแกรม ในกรณีของภาษาซี "พฤติกรรมไม่นิยาม" หมายถึงพฤติกรรมเฉพาะอย่างที่เกิดขึ้นโดยมาตรฐานมิได้ระบุไว้ และสิ่งที่จะเกิดขึ้นก็ไม่มีในเอกสารการใช้งานของภาษาซี หนึ่งในชุดคำสั่งที่มีชื่อเสียงและน่าขบขันจากกลุ่มข่าว [news:comp.std.c comp.std.c] และ [news:comp.lang.c comp.lang.c] นั้นทำให้โปรแกรมเกิดปัญหาที่เรียกว่า "ปิศาจที่ออกมาจากจมูกของคุณ" (demons to fly out of your nose)  บางครั้งสิ่งที่เกิดขึ้นในทางปฏิบัติอันเป็นผลมาจากพฤติกรรมไม่นิยามทำให้เกิดจุดบกพร่องที่ยากต่อการตรวจสอบและอาจทำให้ข้อมูลในหน่วยความจำผิดแปลกไป ตัวแปลโปรแกรมบางชนิดช่วยสร้างการดำเนินงานที่ทำให้พฤติกรรมนั้นดีขึ้นและมีเหตุผล ซึ่งแตกต่างจากการแปลโดยตัวแปลชนิดอื่นที่อาจดำเนินงานไม่เหมือนกัน สาเหตุที่พฤติกรรมบางอย่างยังคงไว้ว่าไม่นิยามก็เพื่อให้ตัวแปลโปรแกรมบนสถาปัตยกรรมชุดของคำสั่งเครื่องที่หลากหลาย สามารถสร้างรหัสที่ทำงานได้ในพฤติกรรมที่นิยามอย่างมีประสิทธิภาพมากขึ้น ซึ่งเชื่อว่าเป็นบทบาทหนึ่งที่สำคัญของภาษาซีในฐานะภาษาสำหรับสร้างระบบ ดังนั้นภาษาซีจึงส่งผลให้เกิดความรับผิดชอบของโปรแกรมเมอร์เพื่อหลีกเลี่ยงพฤติกรรมไม่นิยาม โดยอาจใช้เครื่องมือต่าง ๆ เพื่อค้นหาส่วนของโปรแกรมว่าพฤติกรรมใดบ้างที่ไม่นิยาม ตัวอย่างของพฤติกรรมไม่นิยามเช่น
* การเข้าถึงข้อมูลนอกขอบเขตของแถวลำดับ
* ข้อมูลล้น (overflow) ในตัวแปรจำนวนเต็มมีเครื่องหมาย 
* ฟังก์ชันที่กำหนดไว้ว่าต้องส่งค่ากลับ แต่ไม่มีคำสั่งส่งกลับ (return) ในฟังก์ชัน ในขณะเดียวกันค่าส่งกลับก็ถูกใช้งานด้วย
* การอ่านค่าตัวแปรโดยที่ยังไม่ได้กำหนดค่าเริ่มต้น
การดำเนินการเหล่านี้ทั้งหมดเป็นข้อผิดพลาดในการเขียนโปรแกรม ซึ่งสามารถปรากฏในการใช้ภาษาโปรแกรมอื่น ๆ จำนวนมาก ภาษาซีจึงถูกวิพากษ์วิจารณ์เพราะมาตรฐานของมันสามารถชี้ให้เห็นถึงพฤติกรรมไม่นิยามในหลายกรณีได้อย่างชัดเจน รวมไปถึงพฤติกรรมบางอย่างที่อาจนิยามไว้อย่างดีแล้ว และไม่มีการระบุกลไกการจัดกระทำต่อข้อผิดพลาดขณะทำงานเลย

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

## ประวัติ
### การพัฒนาช่วงแรก
การเริ่มต้นพัฒนาภาษาซีเกิดขึ้นที่เบลล์แล็บส์ของเอทีแอนด์ทีระหว่าง พ.ศ. 2512–2516  แต่ตามข้อมูลของริตชี ช่วงเวลาที่เกิดความสร้างสรรค์มากที่สุดคือ พ.ศ. 2515 ภาษานี้ถูกตั้งชื่อว่า "ซี" เพราะคุณลักษณะต่าง ๆ ต่อยอดมาจากภาษาก่อนหน้าคือ "บี" ซึ่งจากข้อมูลของเคน ทอมป์สัน (Ken Thompson) กล่าวว่าภาษาบีเป็นรุ่นที่แยกตัวออกจากภาษาบีซีพีแอลอีกทอดหนึ่ง

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

รุ่นดั้งเดิมของระบบยูนิกซ์บนพีดีพี-11ถูกพัฒนาขึ้นด้วยภาษาแอสเซมบลี เมื่อประมาณ พ.ศ. 2516 ภาษาซีเพิ่มชนิดข้อมูล `struct` ทำให้ภาษาซีเพียงพออย่างมีประสิทธิภาพ ซึ่งเคอร์เนลยูนิกซ์ส่วนใหญ่ถูกเขียนด้วยภาษาซี นี้ก็เป็นเคอร์เนลหนึ่งของระบบปฏิบัติการที่พัฒนาด้วยภาษาอื่นนอกเหนือจากภาษาแอสเซมบลี (ระบบอื่นเช่นมัลติกส์เขียนด้วยภาษาพีแอล/วัน เอ็มซีพีสำหรับเบอร์โรส์ บี5000เขียนด้วยภาษาอัลกอล ในปี พ.ศ. 2504)

### ภาษาเคแอนด์อาร์ซี
เมื่อ พ.ศ. 2521 ไบรอัน เคอร์นิกัน (Brian Kernighan) และเดนนิส ริตชี ได้ตีพิมพ์หนังสือเล่มแรกชื่อ *เดอะซีโปรแกรมมิงแลงกวิจ (The C Programming Language)*  ซึ่งเป็นที่รู้จักในกลุ่มโปรแกรมเมอร์ภาษาซีว่า "เคแอนด์อาร์" (K&R อักษรย่อของผู้แต่งทั้งสอง) หนังสือเล่มนี้ทำหน้าที่เป็นข้อกำหนดของภาษาอย่างไม่เป็นทางการมาหลายปี ภาษาซีรุ่นดังกล่าวจึงมักถูกอ้างถึงว่าเป็น **ภาษาเคแอนด์อาร์ซี** (K&R C) ส่วนหนังสือที่ปรับปรุงครั้งที่สองครอบคลุมมาตรฐานแอนซีซีที่มีขึ้นทีหลัง 

ภาษาเคแอนด์อาร์ซีได้แนะนำคุณลักษณะหลายประการเช่น
* ไลบรารีไอ/โอมาตรฐาน
* ชนิดข้อมูล `long int` (จำนวนเต็มขนาดยาว)
* ชนิดข้อมูล `unsigned int` (จำนวนเต็มไม่มีเครื่องหมาย)
* ตัวดำเนินการกำหนดค่าแบบประสมในรูปแบบ *=ตัวดำเนินการ* (เช่น `=-`) ถูกเปลี่ยนเป็น *ตัวดำเนินการ=* (เช่น `-=`) เพื่อลดปัญหาความกำกวมเชิงความหมาย อย่างเช่นกรณี `i=-10` ซึ่งจะถูกตีความว่า `i =- 10` แทนที่จะเป็นอย่างที่ตั้งใจคือ `i = -10`

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

ในภาษาซีรุ่นแรก ๆ เฉพาะฟังก์ชันที่คืนค่าไม่เป็นจำนวนเต็ม จำเป็นต้องประกาศไว้ก่อนการนิยามฟังก์ชันหากมีการเรียกใช้ อีกนัยหนึ่งคือ ฟังก์ชันที่ถูกเรียกใช้โดยไม่มีการประกาศมาก่อน ถือว่าฟังก์ชันนั้นจะคืนค่าเป็นจำนวนเต็มหากค่าของมันถูกใช้งาน ตัวอย่างเช่น


```text
long int SomeFunction();
/* int OtherFunction(); */

/* int */ CallingFunction()
{
    long int test1;
    register /* int */ test2;

    test1 = SomeFunction();
    if (test1 > 0)
        test2 = 0;
    else
        test2 = OtherFunction();

    return test2;
}
```

จากตัวอย่างข้างต้น การประกาศ `int` ที่ถูกคัดออก สามารถละเว้นได้ในภาษาเคแอนด์อาร์ซี แต่ `long int` จำเป็นต้องประกาศ

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

หลายปีถัดจากการเผยแพร่ภาษาเคแอนด์อาร์ซี คุณลักษณะที่ไม่เป็นทางการหลายอย่างก็ถูกเพิ่มเข้ามาในภาษา ซึ่งรองรับโดยตัวแปลโปรแกรมจากเอทีแอนด์ทีและผู้ผลิตรายอื่น คุณลักษณะที่เพิ่มเหล่านี้เช่น
* ฟังก์ชัน `[[วอยด์|void]]`
* ฟังก์ชันที่คืนค่าเป็นชนิดข้อมูล `struct` หรือ `[[ยูเนียน (วิทยาการคอมพิวเตอร์)|union]]` (แทนที่จะเป็นตัวชี้)
* การกำหนดค่าให้กับชนิดข้อมูล `struct`
* ชนิดข้อมูลแจงนับ (enumerated type)

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

### ภาษาแอนซีซีและภาษาไอโซซี

ช่วงพุทธทศวรรษ 2520 ภาษาซีหลายรุ่นถูกพัฒนาขึ้นสำหรับเมนเฟรมคอมพิวเตอร์ มินิคอมพิวเตอร์ และไมโครคอมพิวเตอร์อย่างกว้างขวางรวมทั้งไอบีเอ็มพีซี ซึ่งความนิยมของมันเริ่มเพิ่มขึ้นอย่างมีนัยสำคัญ

เมื่อ พ.ศ. 2526 สถาบันมาตรฐานแห่งชาติของสหรัฐอเมริกา (ANSI) ได้ก่อตั้งคณะกรรมการ *เอกซ์3เจ11* ขึ้นมาเพื่อกำหนดมาตรฐานของภาษาซี ต่อมา พ.ศ. 2532 มาตรฐานดังกล่าวได้รับการอนุมัติเป็น ANSI X3.159-1989 "Programming Language C" ซึ่งภาษารุ่นนี้มักถูกอ้างถึงว่าเป็นภาษาแอนซีซี (ANSI C) ภาษาซีมาตรฐาน หรือภาษาซี89 (C89) ในบางครั้ง

เมื่อ พ.ศ. 2533 องค์การระหว่างประเทศว่าด้วยการมาตรฐาน (ISO) ได้รับเอามาตรฐานแอนซีซี (พร้อมการเปลี่ยนแปลงการจัดรูปแบบ) มาเป็น ISO/IEC 9899:1990 ซึ่งบางครั้งก็ถูกเรียกว่าภาษาไอโซซี (ISO C) หรือภาษาซี90 (C90) ดังนั้นคำว่า "ซี89" กับ "ซี90" จึงหมายถึงภาษาโปรแกรมเดียวกัน

แอนซีไม่ได้พัฒนามาตรฐานภาษาซีโดยเอกเทศอีกต่อไปแล้ว เหมือนเช่นองค์กรมาตรฐานแห่งชาติอื่น ๆ แต่ก็คล้อยตามมาตรฐานไอโซซี การรับเอามาตรฐานระดับชาติมาปรับปรุงเป็นมาตรฐานระดับสากล เกิดขึ้นภายในปีเดียวกับที่เผยแพร่มาตรฐานไอโซ

จุดมุ่งหมายหนึ่งของกระบวนการสร้างมาตรฐานให้ภาษาซีคือเพื่อสร้างซูเปอร์เซตของภาษาเคแอนด์อาร์ซี ผสมผสานคุณลักษณะต่าง ๆ ที่ยังไม่เป็นทางการซึ่งแนะนำต่อกันมา คณะกรรมการมาตรฐานได้รวมคุณลักษณะหลายประการเพิ่มเข้ามาอาทิ ฟังก์ชันโพรโทไทป์ (ยืมมาจากภาษาซีพลัสพลัส), ตัวชี้ `void`, รองรับการจัดเรียงท้องถิ่น (locale) และชุดอักขระสากล, และการปรับปรุงตัวประมวลก่อนให้ดีขึ้น วากยสัมพันธ์สำหรับการประกาศพารามิเตอร์ถูกเพิ่มเข้ามาให้เหมือนกับรูปแบบที่ใช้ในภาษาซีพลัสพลัส แม้ว่าการเขียนแบบเคแอนด์อาร์ก็ยังสามารถใช้ได้เพื่อความเข้ากันได้กับรหัสต้นฉบับที่มีอยู่แล้ว

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

ในกรณีที่ต้องเลือกว่ารหัสต้องถูกแปลด้วยตัวแปลภาษาซีมาตรฐานหรือภาษาเคแอนด์อาร์ซีอย่างใดอย่างหนึ่ง การใช้แมโคร `__STDC__` สามารถช่วยให้แบ่งแยกรหัสส่วนมาตรฐานและส่วนเคแอนด์อาร์ออกจากกัน ซึ่งเป็นคุณลักษณะที่ได้เปรียบอีกอย่างหนึ่งที่มีเฉพาะในภาษาซีมาตรฐาน

### ภาษาซี99

หลังจากกระบวนการทำให้เป็นมาตรฐานของแอนซี/ไอโซแล้ว ข้อกำหนดภาษาซียังคงนิ่งอยู่ชั่วระยะเวลาหนึ่ง ในขณะที่ภาษาซีพลัสพลัสกำลังก่อตัวด้วยความพยายามทำให้เป็นมาตรฐานของมันเอง การเพิ่มเติมกฎเกณฑ์ครั้งที่ 1 สำหรับมาตรฐานภาษาซีเผยแพร่เมื่อ พ.ศ. 2538 เพื่อแก้ไขรายละเอียดบางจุดและเพิ่มการรองรับชุดอักขระสากลให้มากขึ้น ต่อมามาตรฐานภาษาซีถูกเรียบเรียงดัดแปลงใหม่และนำไปสู่การเผยแพร่ ISO/IEC 9899:1999 ออกสู่สาธารณชนใน พ.ศ. 2542 ซึ่งมักถูกอ้างถึงว่า "ซี99" (C99) มาตรฐานนี้มีการเพิ่มเติมกฎเกณฑ์แล้วสามครั้งโดย Technical Corrigenda ปัจจุบันมาตรฐานภาษาซีสากลดูแลและควบคุมโดยกลุ่ม ISO/IEC JTC1/SC22/WG14

ภาษาซี99ได้แนะนำคุณลักษณะใหม่หลายประการอาทิ ฟังก์ชันแบบแทรก (inline function) ชนิดข้อมูลใหม่หลายชนิด (เช่น `long long int` และ `complex` สำหรับจำนวนเชิงซ้อน) แถวลำดับความยาวแปรได้ (variable-length array) แมโครอาร์กิวเมนต์แปรได้ (variadic macro) และหมายเหตุในหนึ่งบรรทัดที่ขึ้นต้นด้วย `//` เหมือนภาษาบีซีพีแอลหรือภาษาซีพลัสพลัส ซึ่งคุณลักษณะส่วนใหญ่เคยพัฒนาไว้แล้วเป็นส่วนขยายของตัวแปลภาษาซีหลายโปรแกรม

ภาษาซี99สามารถเข้ากันได้แบบย้อนหลังกับภาษาซี90เป็นส่วนใหญ่ แต่ก็จำกัดมากขึ้นในบางแง่มุม โดยเฉพาะการประกาศโดยไม่ระบุชนิด จะไม่ถูกสมมติว่าเป็น `int` อีกต่อไป แมโครมาตรฐาน `__STDC_VERSION__` ถูกนิยามขึ้นด้วยค่า `199901L` เพื่อแสดงว่ารหัสนั้นรองรับภาษาซี99 ขณะนี้ จีซีซี ซันสตูดิโอ และตัวแปลโปรแกรมอื่น ๆ ก็รองรับคุณลักษณะใหม่ของภาษาซี99เป็นจำนวนมากหรือทั้งหมดแล้ว

### ภาษาซี1เอกซ์

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

## การใช้งาน
การเขียนโปรแกรมระบบเป็นการใช้งานหลักของภาษาซี ซึ่งรวมไปถึงการพัฒนาระบบปฏิบัติการและโปรแกรมประยุกต์ระบบฝังตัว เนื่องจากลักษณะเฉพาะอันเป็นที่ต้องการถูกรวมเข้าไว้ด้วยกัน อย่างเช่น ความสามารถในเคลื่อนย้ายได้กับประสิทธิภาพของรหัสต้นฉบับ ความสามารถในการเข้าถึงที่อยู่ของฮาร์ดแวร์ที่ระบุ ความสามารถเรื่อง type punning เพื่อให้เข้ากับความต้องการการเข้าถึงข้อมูลที่กำหนดไว้จากภายนอก และความต้องการทรัพยากรระบบขณะทำงานต่ำ ภาษาซีสามารถใช้เขียนโปรแกรมเว็บไซต์โดยใช้ซีจีไอเป็น "เกตเวย์" เพื่อแลกเปลี่ยนสารสนเทศระหว่างเว็บแอปพลิเคชัน เซิร์ฟเวอร์ และเบราว์เซอร์  ปัจจัยบางอย่างที่ทำให้เลือกภาษาซีแทนที่จะเป็นภาษาอินเทอร์พรีตเตอร์ คือความเร็ว เสถียรภาพ และความอ่อนไหวต่อการเปลี่ยนแปลงในสภาพแวดล้อมของการดำเนินงาน เนื่องจากเป็นธรรมชาติของภาษาคอมไพเลอร์ 

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

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

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

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

## วากยสัมพันธ์

รหัสต้นฉบับของภาษาซีมีรูปแบบอิสระ ซึ่งสามารถใช้อักขระช่องว่างเท่าใดก็ได้ในรหัส มากกว่าที่จะถูกจำกัดด้วยคอลัมน์หรือบรรทัดข้อความอย่างภาษาฟอร์แทรน 77 ข้อความหมายเหตุจะปรากฏระหว่างตัวคั่น `/*` และ `*/` (แบบดั้งเดิม) หรือตามหลัง `//` จนกว่าจะจบบรรทัด (ภาษาซี99 เป็นต้นไป)

รหัสต้นฉบับแต่ละไฟล์ประกอบด้วยการประกาศและการนิยามฟังก์ชันต่าง ๆ และการนิยามฟังก์ชันก็ประกอบด้วยการประกาศและข้อความสั่งต่าง ๆ ภายในอีกด้วย การประกาศอาจกำหนดชนิดข้อมูลใหม่โดยใช้คำหลักเช่น `struct`, `union` และ `enum` หรือกำหนดค่าของชนิดข้อมูลและอาจสงวนเนื้อที่สำรองให้กับตัวแปรใหม่ โดยการเขียนชื่อของชนิดข้อมูลตามด้วยชื่อตัวแปร คำหลักอาทิ `char` และ `int` เป็นชนิดข้อมูลพื้นฐานที่มากับภาษา ส่วนต่าง ๆ ของรหัสถูกคลุมด้วยวงเล็บปีกกา `{` กับ `}` เพื่อจำกัดขอบเขตของการประกาศ และเพื่อกระทำเสมือนข้อความสั่งเดียวสำหรับโครงสร้างการควบคุม

ภาษาซีใช้ *ข้อความสั่ง* (statement) ในการระบุการกระทำเช่นเดียวกับภาษาเชิงคำสั่งอื่น ข้อความสั่งที่สามัญที่สุดคือ *ข้อความสั่งนิพจน์* (expression statement) ซึ่งประกอบด้วยนิพจน์ที่จะถูกนำไปประเมินค่า ตามด้วยอัฒภาค `;` จากผลข้างเคียงของการประเมินค่า ฟังก์ชันหลายฟังก์ชันอาจถูกเรียกใช้และตัวแปรหลายตัวอาจถูกกำหนดค่าใหม่ ภาษาซีได้เตรียมข้อความสั่งสำหรับควบคุมการไหลของโปรแกรมไว้หลายข้อความซึ่งดูได้จากคำสงวนต่าง ๆ ตัวอย่างเช่น การใช้ `if`-`else` เพื่อการทำงานแบบมีเงื่อนไข และการใช้ `do`-`while`, `while` และ `for` เพื่อการทำงานแบบวนรอบ เพื่อปรับเปลี่ยนการทำงานอันเป็นลำดับปกติ เป็นสิ่งที่รองรับสำหรับการเขียนโปรแกรมเชิงโครงสร้าง สำหรับข้อความสั่ง `for` นั้นมีนิพจน์ของการกำหนดค่าเริ่มต้น การทดสอบเงื่อนไข และการกำหนดค่ารอบใหม่ทั้งสามอย่างในตัวเอง ซึ่งสามารถละเว้นนิพจน์ใดก็ได้ ข้อความสั่ง `break` และ `continue` สามารถใช้ภายในการทำงานแบบวนรอบ เพื่อหยุดการวนรอบ หรือข้ามไปยังการกำหนดค่ารอบใหม่ทันทีตามลำดับ นอกจากนี้ยังมีข้อความสั่งที่ไม่เป็นเชิงโครงสร้างคือ `[[goto]]` ซึ่งจะทำให้การไหลของโปรแกรมข้ามไปยังป้าย (label) ที่ตั้งชื่อไว้ทันทีภายในฟังก์ชัน ข้อความสั่ง `switch` และ `case` ใช้สำหรับพิจารณาทางเลือกของการทำงานโดยพิจารณานิพจน์ที่เป็นจำนวนเต็ม

นิพจน์ต่าง ๆ สามารถใช้ตัวดำเนินการที่มีมากับภาษาได้หลากหลาย (ดูด้านล่าง) และอาจมีการเรียกใช้ฟังก์ชัน อาร์กิวเมนต์ของฟังก์ชันและตัวถูกดำเนินการของตัวดำเนินการส่วนใหญ่ที่จะถูกประเมินค่านั้นไม่มีการระบุลำดับ การประเมินค่าจึงอาจแทรกซ้อนกันก็ได้ อย่างไรก็ตามผลกระทบที่เกิดขึ้นทั้งหมด (รวมทั้งที่เก็บข้อมูลตัวแปร) จะปรากฏก่อน *[[จุดลำดับ]]* (sequence point) ถัดไป จุดลำดับนั้นคือจุดสิ้นสุดของข้อความสั่งของแต่ละนิพจน์ และจุดที่เข้าและออกจากการเรียกใช้ฟังก์ชัน จุดลำดับก็ยังเกิดขึ้นระหว่างการประเมินค่านิพจน์ที่มีตัวดำเนินการบางชนิด (เช่น `&&`, `||`, `[[?:]]` และตัวดำเนินการจุลภาค) สิ่งนี้ทำให้การปรับแต่งรหัสจุดหมายให้เหมาะสมทำได้ในระดับสูง ซึ่งไม่จำเป็นต้องให้โปรแกรมเมอร์ภาษาซีใส่ใจมากนักเพื่อให้ได้ผลลัพธ์ที่เชื่อถือได้ ในขณะที่จำเป็นสำหรับภาษาโปรแกรมอื่น

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

ปัญหาเฉพาะบางอย่างที่ควรหมายเหตุไว้มีดังนี้
* ไม่มีการตรวจสอบจำนวนและชนิดของอาร์กิวเมนต์ เมื่อการประกาศฟังก์ชันมีรายการพารามิเตอร์ว่าง (สิ่งนี้เพื่อความเข้ากันได้ย้อนหลังกับภาษาเคแอนด์อาร์ซี ซึ่งไม่มีโพรโทไทป์)
* ทางเลือกที่น่าสงสัยของสิทธิการทำก่อนของตัวดำเนินการ ดังที่กล่าวถึงโดยเคอร์นิกันและริตชีข้างต้น เช่น `==` ที่วางอยู่ติดกับ `&` และ `|` ในนิพจน์ดังตัวอย่าง `x & 1 == 0` ตัวดำเนินการ `==` จะทำก่อนซึ่งไม่ใช่ผลที่คาดไว้ จำเป็นต้องใส่วงเล็บเพิ่ม `(x & 1) == 0` เพื่อให้ `&` ทำก่อนตามต้องการ
* ตัวดำเนินการ `=` ซึ่งใช้แสดงภาวะเท่ากันในคณิตศาสตร์ แต่ในภาษาซีใช้เพื่อการกำหนดค่าของตัวแปร โดยใช้ตามแบบที่มีอยู่ก่อนในภาษาฟอร์แทรน ภาษาพีแอล/วัน และภาษาเบสิก ไม่เหมือนภาษาอัลกอลและภาษาต่อยอดของมัน ริตชีตั้งใจเลือกรูปแบบนี้ด้วยเหตุผลหลักว่า อาร์กิวเมนต์ของการกำหนดค่าเกิดขึ้นบ่อยกว่าการเปรียบเทียบ
* ความคล้ายกันของตัวดำเนินการกำหนดค่าและการเปรียบเทียบภาวะเท่ากัน (`=` และ `==`) ทำให้เกิดความผิดพลาดจากการใช้เครื่องหมายผิดได้ง่าย ในหลายกรณีเครื่องหมายถูกใช้ในบริบทของอีกอันหนึ่งโดยไม่มีความผิดพลาดขณะแปล (แม้ว่าตัวแปลโปรแกรมปกติจะสร้างข้อความเตือนขึ้นมา) ตัวอย่างเช่น นิพจน์เงื่อนไขภายใน `if (a = b)` จะเป็นจริงถ้า `a` มีค่าไม่เป็นศูนย์หลังจากการกำหนดค่า  อย่างไรก็ตาม ข้อบกพร่องนี้อาจมีประโยชน์สำหรับการเขียนรหัสอย่างย่อในบางกรณี
* การขาดตัวดำเนินการเติมกลางสำหรับวัตถุซับซ้อนหลายชนิด โดยเฉพาะการดำเนินการสายอักขระ ทำให้โปรแกรมที่ขึ้นอยู่กับการดำเนินการเหล่านี้มีขนาดใหญ่กว่าที่ควรเป็น (เพราะต้องสร้างฟังก์ชันขึ้นเอง) และทำให้รหัสอ่านยากขึ้นด้วย
* รูปแบบของการประกาศที่บางครั้งไม่เป็นไปตามสามัญสำนึก โดยเฉพาะตัวชี้ฟังก์ชัน (แนวคิดของริตชีคือการประกาศตัวระบุในบริบทที่สัมพันธ์กับการใช้งานของมัน)

### ตัวดำเนินการ

ภาษาซีรองรับตัวดำเนินการหลายประเภท ซึ่งเป็นสัญลักษณ์ที่ใช้ในนิพจน์เพื่อระบุการจัดการที่จะถูกทำให้เกิดผล ระหว่างการประเมินค่าของนิพจน์นั้น ภาษาซีมีตัวดำเนินการต่อไปนี้
* พีชคณิต (`[[การบวก|+]]`, `[[การลบ|-]]`, `[[การคูณ|*]]`, `[[การหาร|/]]`, `[[มอดุโล|%]]`)
* การกำหนดค่า (`=`)
* การกำหนดค่าแต่งเติม (`+=`, `-=`, `*=`, `/=`, `%=`, `&=`, `|=`, `^=`, `<<=`, `>>=`)
* ตรรกะระดับบิต (`~`, `&`, `|`, `^`)
* การเลื่อนระดับบิต (`<<`, `>>`)
* ตรรกะแบบบูล (`!`, `&&`, `||`)
* การประเมินค่าเชิงเงื่อนไข (`?:`)
* การทดสอบภาวะเท่ากัน (`==`, `!=`)
* การรวมอาร์กิวเมนต์ฟังก์ชัน (`( )`)
* การเพิ่มค่าและการลดค่า (`++`, `--`)
* การเลือกสมาชิกในวัตถุ (`.`, `->`)
* ขนาดของวัตถุ (`[[sizeof]]`)
* ความสัมพันธ์เชิงอันดับ (`<`, `<=`, `>`, `>=`)
* การอ้างอิงและการถูกอ้างอิง (`&`, `*`, `[ ]`)
* การลำดับ (`,`)
* การจัดกลุ่มนิพจน์ย่อย (`( )`)
* การแปลงชนิดข้อมูล (`( )`)
ภาษาซีมีไวยากรณ์รูปนัยซึ่งระบุโดยมาตรฐานภาษาซี 

### การแปลงจำนวนเต็ม จำนวนจุดลอยตัว และการปัดเศษ
วากยสัมพันธ์ของการแปลงชนิดข้อมูลสามารถใช้แปลงค่าต่าง ๆ ระหว่างชนิดข้อมูลจำนวนเต็มและจำนวนจุดลอยตัว (จำนวนทศนิยม) หรือระหว่างจำนวนเต็มสองจำนวน หรือระหว่างจำนวนจุดลอยตัวสองจำนวนที่มีขนาดแตกต่างกัน ตัวอย่างเช่น `(long int)sqrt(1000.0)`, `(double)(256*256)` หรือ `(float)sqrt(1000.0)` เป็นต้น การแปลงชนิดข้อมูลเป็นภาวะปริยายในหลายบริบทอาทิ เมื่อกำหนดค่าให้กับตัวแปรหรือพารามิเตอร์ของฟังก์ชัน หรือเมื่อใช้จำนวนจุดลอยตัวเป็นดัชนีของเวกเตอร์ หรือในการดำเนินการทางเลขคณิตที่มีตัวถูกดำเนินการเป็นข้อมูลคนละชนิดกัน

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

ส่วนการแปลงชนิดข้อมูลจากจำนวนจุดลอยตัวไปเป็นจำนวนเต็มจะเกิดการตัดค่าหลังจุดทศนิยมอย่างหลีกเลี่ยงไม่ได้ (ค่าถูกปัดเศษเข้าหาศูนย์) สำหรับการปัดเศษชนิดอื่น ภาษซี99ได้ระบุไว้แล้วในฟังก์ชันดังนี้ (ใน `<[[math.h]]>`)
* `round()`: ปัดเศษไปยังจำนวนเต็มที่ใกล้สุด
* `rint()`, `nearbyint()`: ปัดเศษตามทิศทางของจำนวนจุดลอยตัวปัจจุบัน
* `ceil()`: ค่าจำนวนเต็มน้อยสุดที่ไม่น้อยกว่าอาร์กิวเมนต์ (ปัดขึ้น) ดูเพิ่มที่ฟังก์ชันเพดาน
* `floor()`: ค่าจำนวนเต็มมากสุดที่ไม่มากกว่าอาร์กิวเมนต์ (ปัดลง) ดูเพิ่มที่ฟังก์ชันพื้น
* `trunc()`: ปัดเศษเข้าหาศูนย์ (เหมือนกับการแปลงชนิดข้อมูลเป็นจำนวนเต็ม)
ฟังก์ชันทั้งหมดนี้รับอาร์กิวเมนต์ `double` และคืนค่าเป็น `double` ซึ่งต่อจากนี้ก็อาจแปลงชนิดข้อมูลเป็นจำนวนเต็มอีกทีหากจำเป็น

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

เครื่องที่ทำตามมาตรฐานจำนวนจุดลอยตัวของ IEEE เหตุการณ์การปัดเศษบางเหตุการณ์มีผลมาจากสถานะการปัดเศษปัจจุบัน (ได้แก่การปัดเศษเลขคู่ การปัดเศษขึ้น การปัดเศษลง และการปัดเศษเข้าหาศูนย์) ซึ่งอาจเรียกดูหรือตั้งค่าสถานะโดยใช้ฟังก์ชัน `fegetround()`/`fesetround()` ที่นิยามไว้ใน `<[[fenv.h]]>`

## ตัวอย่างโปรแกรม "Hello World"
ตัวอย่างโปรแกรม "เฮลโลเวิลด์" ซึ่งปรากฏอยู่ในหนังสือ *เดอะซีโปรแกรมมิงแลงกวิจ* ที่พิมพ์ครั้งแรก กลายมาเป็นตัวแบบของโปรแกรมเกริ่นนำในตำราการเขียนโปรแกรมส่วนใหญ่หากไม่คำนึงถึงภาษาที่ใช้เขียน โปรแกรมดังกล่าวจะแสดงผล "hello world" ทางอุปกรณ์ส่งออกมาตรฐาน ซึ่งมักจะเป็นเครื่องปลายทางหรือหน่วยแสดงผลจอภาพ

รหัสโปรแกรมรุ่นดั้งเดิมเป็นดังนี้


```text
main()
{
    printf("hello world\n");
}
```


และหลังจากการปรับเปลี่ยนรหัสให้เข้ากับมาตรฐาน รหัสจึงเป็นดังนี้ 


```text
#include <stdio.h>

int main(void)
{
    printf("hello world\n");
    return 0;
}
```


บรรทัดแรกของโปรแกรมเป็นคำสั่งชี้แนะตัวประมวลผลก่อน (preprocessing directive) แสดงไว้โดย `#include` ทำให้ตัวประมวลผลก่อน (อันเป็นเครื่องมืออย่างแรกที่พิจารณารหัสต้นฉบับขณะแปล) นำเนื้อหาข้อความทั้งหมดของไฟล์ส่วนหัวมาตรฐาน `[[stdio.h]]` เข้ามาแทนที่บรรทัดนั้น ซึ่งไฟล์ดังกล่าวมีการประกาศฟังก์ชันสำหรับอุปกรณ์นำเข้าและส่งออกมาตรฐานอาทิ `printf` วงเล็บแหลมที่คลุมชื่อไฟล์ `stdio.h` (ซึ่งความจริงคือเครื่องหมายน้อยกว่า-มากกว่า) เป็นการแสดงว่า `stdio.h` ถูกกำหนดที่ตั้งโดยใช้กลยุทธ์การค้นหาที่ให้ความสำคัญต่อไฟล์ส่วนหัวมาตรฐาน มากกว่าไฟล์ส่วนหัวอื่นที่มีชื่อเดียวกัน อัญประกาศคู่อาจใช้ได้ในกรณีที่ต้องการนำไฟล์ส่วนหัวที่อยู่ใกล้เคียงหรือเจาะจงโครงการเข้ามารวม

บรรทัดถัดมาเป็นการนิยามฟังก์ชันชื่อว่า `main` ฟังก์ชัน <code>main</code> เป็นฟังก์ชันที่มีจุดประสงค์พิเศษในโปรแกรมภาษาซี สภาพแวดล้อมขณะทำงานจะเรียกใช้ฟังก์ชัน `main` เพื่อเริ่มต้นการทำงานโปรแกรม ตัวระบุชนิด `int` เป็นตัวแสดงว่า *ค่าส่งคืน* ที่ถูกส่งคืนโดยตัวที่เรียกใช้ (กรณีนี้คือสภาพแวดล้อมขณะทำงาน) จะเป็นจำนวนเต็มค่าหนึ่ง อันเป็นผลจากการประเมินค่าของฟังก์ชัน `main` คำหลัก `void` ในรายการพารามิเตอร์แสดงว่าฟังก์ชัน `main` ไม่ต้องใช้อาร์กิวเมนต์ 

วงเล็บปีกกาเปิดหมายถึงจุดเริ่มต้นของการนิยามฟังก์ชัน `main`

บรรทัดถัดมาเป็นการ *เรียกใช้* ฟังก์ชันที่ชื่อว่า `[[printf]]` ซึ่งประกาศไว้ใน `stdio.h` และจัดเตรียมขึ้นจากไลบรารีของระบบ ในการเรียกใช้ครั้งนี้ ฟังก์ชัน `printf` จะถูก *ผ่านค่า* ด้วยอาร์กิวเมนต์หนึ่งตัวคือตำแหน่งหน่วยความจำของอักขระตัวแรกในสายอักขระ `"hello world\n"` สายอักขระดังกล่าวคือแถวลำดับที่ไม่มีชื่ออันประกอบด้วยชนิดข้อมูล `char` จะถูกสร้างขึ้นโดยอัตโนมัติโดยตัวแปลโปรแกรม และแถวลำดับจะมีอักขระค่าศูนย์ (null) เป็นสิ่งที่บ่งบอกจุดสิ้นสุดของสายอักขระ (`printf` จำเป็นต้องทราบสิ่งนี้) `\n` ที่ปรากฏในสายอักขระคือ *ลำดับการหลีก* (escape sequence) ภาษาซีจะตีความว่าเป็นอักขระขึ้นบรรทัดใหม่ (newline) ซึ่งจะทำให้อุปกรณ์ส่งออกทราบว่าถึงจุดสิ้นสุดของบรรทัดปัจจุบัน ค่าส่งคืนจากฟังก์ชัน `printf` คือชนิด `int` แต่มันถูกละทิ้งไปอย่างเงียบ ๆ เนื่องจากไม่มีการใช้ (โปรแกรมที่ระมัดระวังมากกว่าอาจทดสอบค่าส่งคืน เพื่อพิจารณาว่าผลจากการทำงานของฟังก์ชัน `printf` สำเร็จหรือไม่) อัฒภาค `;` เป็นจุดสิ้นสุดข้อความสั่ง

ข้อความสั่ง `return` เป็นการสิ้นสุดการทำงานของฟังก์ชัน `main` และทำให้ฟังก์ชันส่งกลับเป็นจำนวนเต็มค่า 0 ซึ่งสภาพแวดล้อมขณะทำงานจะตีความว่าเป็นรหัสออกจากโปรแกรมที่แสดงว่าการทำงานประสบผลสำเร็จ

วงเล็บปีกกาปิดหมายถึงจุดสิ้นสุดของการนิยามฟังก์ชัน `main`

## ชนิดข้อมูล

ภาษาซีมีระบบชนิดตัวแปรแบบไม่เคร่งครัด ซึ่งมีความคล้ายคลึงบางประการร่วมกับภาษาลูกของภาษาอัลกอล อาทิ ภาษาปาสกาล ภาษาซีมีชนิดตัวแปรที่เตรียมไว้แล้วสำหรับจำนวนเต็มหลายขนาด แบบทั้งมีเครื่องหมายและไม่มีเครื่องหมาย จำนวนจุดลอยตัว ตัวอักขระ และชนิดข้อมูลแจงนับ (`enum`) ในภาษาซี99 ได้เพิ่มชนิดตัวแปรแบบบูลเข้าไปด้วย ภาษาซีก็ยังมีชนิดตัวแปรที่รับทอดมาด้วยเช่นแถวลำดับ ตัวชี้ ระเบียน (`struct`) และยูเนียน (`union`)

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

### ตัวชี้
ภาษาซีรองรับการใช้งานตัวชี้ (pointer) ซึ่งเป็นชนิดข้อมูลสำหรับการอ้างอิงอย่างง่ายชนิดหนึ่ง ที่เก็บบันทึกที่อยู่หรือตำแหน่งของวัตถุหรือฟังก์ชันในหน่วยความจำ ตัวชี้สามารถ *อ้างอิงกลับ* (dereference) เพื่อเข้าถึงข้อมูลที่บันทึกในตำแหน่งที่ถูกชี้อยู่ หรือเพื่อเรียกใช้ฟังก์ชันที่ถูกชี้อยู่ ตัวชี้สามารถจัดดำเนินการกำหนดค่าและเลขคณิตของตัวชี้ได้ด้วย ค่าของตัวชี้ขณะโปรแกรมทำงาน มักจะเป็นตำแหน่งมูลฐานในหน่วยความจำ (ซึ่งอาจเสริมด้วยค่าออฟเซตในหน่วยเวิร์ด) แต่เนื่องจากตัวชี้มีการระบุชนิดตามข้อมูลที่ชี้ไป ตัวแปลโปรแกรมจึงสามารถตรวจสอบชนิดตัวแปรในนิพจน์ต่าง ๆ รวมทั้งตัวชี้ด้วยกันเองขณะแปลได้ เลขคณิตของตัวชี้จะแปรสัดส่วนของขนาดโดยอัตโนมัติตามชนิดข้อมูลที่ชี้ไป (ดูเพิ่มที่ส่วนความใช้แทนกันได้ระหว่างตัวชี้และแถวลำดับ) จุดประสงค์ของการใช้ตัวชี้มีหลากหลายในภาษาซีเช่น สายอักขระมักจัดดำเนินการโดยใช้ตัวชี้ไปยังแถวลำดับของตัวอักขระ การจัดสรรหน่วยความจำพลวัต (dynamic memory allocation) สามารถกระทำได้ด้วยตัวชี้ ชนิดข้อมูลชนิดอื่นเช่น ต้นไม้ ปกติจะถูกพัฒนาขึ้นโดยการจัดสรรวัตถุ `struct` โดยพลวัต ซึ่งเชื่อมโยงแต่ละหน่วยเข้ากันด้วยตัวชี้ ตัวชี้ของฟังก์ชันใช้เพื่อการเรียกกลับ (callback) สำหรับชุดคำสั่งจัดการเหตุการณ์ เป็นต้น

*[[ตัวชี้ว่าง]]* (null pointer) คือตัวชี้ที่ชี้ไปยังตำแหน่งที่ใช้งานไม่ได้ ซึ่งจะมีค่าเป็น 0  การอ้างอิงกลับของตัวชี้ว่างจึงไม่มีความหมาย และโดยทั่วไปให้ผลเป็นข้อผิดพลาดขณะทำงาน อย่างไรก็ตามตัวชี้ว่างก็มีประโยชน์สำหรับกรณีพิเศษเช่น ใช้เป็นจุดสิ้นสุดหน่วยสุดท้ายของรายการโยง ซึ่งหมายความว่าไม่มีตัวชี้ไปหน่วยอื่นแล้ว หรือใช้แจ้งข้อผิดพลาดจากฟังก์ชันที่คืนค่าเป็นตัวชี้ ตัวชี้ว่างในการลงรหัสมักจะนำเสนอด้วย `0` หรือ `NULL`

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

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

### แถวลำดับ

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

ถึงแม้ภาษาซีรองรับแถวลำดับแบบสถิต แต่ก็ไม่จำเป็นว่าดัชนีของแถวลำดับจะต้องมีผล (การตรวจสอบขอบเขต) ตัวอย่างเช่น เราสามารถลองบันทึกค่าสมาชิกตัวที่หกลงในแถวลำดับที่มีสมาชิกห้าตัวได้ ซึ่งจะทำให้เกิดผลที่ไม่คาดคิด ความผิดพลาดเช่นนี้เรียกว่า *[[บัฟเฟอร์ส่วนล้น]]* (buffer overflow/overrun) เป็นสาเหตุที่สำคัญอย่างหนึ่งของปัญหาด้านความปลอดภัย เนื่องจากเทคโนโลยีการกำจัดการตรวจสอบขอบเขต (bounds-checking elimination) ไม่มีอยู่เลยเมื่อภาษาซีถูกนิยามขึ้น การตรวจสอบขอบเขตจึงลดทอนประสิทธิภาพอย่างรุนแรง โดยเฉพาะกับการคำนวณเชิงจำนวน เมื่อสองสามปีก่อนหน้านั้น ตัวแปลภาษาฟอร์แทรนมีตัวเลือกให้เปิดหรือปิดการตรวจสอบขอบเขตได้ แต่ตัวเลือกเช่นนี้ไม่มีประโยชน์ต่อภาษาซี เพราะอาร์กิวเมนต์ของแถวลำดับถูกผ่านค่าด้วยตัวชี้ธรรมดา

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

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

ภาษาซี99 ได้แนะนำ "แถวลำดับความยาวแปรได้" เพิ่มเข้ามา แต่ก็ยังมีปัญหาบางประการที่เหมือนกับปัญหาแถวลำดับของภาษาซี

### ความใช้แทนกันได้ระหว่างตัวชี้และแถวลำดับ
คุณลักษณะเด่นชัดของภาษาซี (ซึ่งอาจทำให้สับสนด้วย) คือการปฏิบัติต่อแถวลำดับและตัวชี้ สัญกรณ์แถวลำดับ `x[i]` สามารถใช้กับตัวชี้ `x` ได้ โดยแปลความหมายว่าเป็นการเข้าถึงวัตถุตัวที่ `i + 1` ของวัตถุข้อมูลที่อยู่ติดกันถัดจากตำแหน่งที่ `x` ชี้อยู่ ซึ่งถือว่าเป็นสมาชิกตัวแรกของแถวลำดับ (`x[0]`)

`x[i]` มีความหมายเทียบเท่า `*(x + i)` ตามรูปแบบ และเนื่องจากชนิดตัวแปรของตัวชี้เป็นที่ทราบขณะแปล ตำแหน่ง `x + i` ที่ชี้ไปมิได้หมายความว่าจากตำแหน่ง `x` แล้วเพิ่มไปอีก `i` ไบต์ แต่หมายถึงเพิ่มไปอีก (`i` คูณด้วยขนาดของสมาชิกที่ตำแหน่ง `x`) ขนาดของสมาชิกนี้ได้มาจากการใช้ตัวดำเนินการ `sizeof` บนสมาชิกที่อ้างอิงกลับตัวใดตัวหนึ่งของ `x` ดังเช่น `n = sizeof *x` หรือ `n = sizeof x[0]`

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

จำนวนสมาชิกของแถวลำดับ `x` ที่ได้ประกาศไว้แล้ว สามารถคำนวณได้จาก `sizeof x / sizeof x[0]`

การสาธิตอย่างหนึ่งที่น่าสนใจต่อความใช้แทนกันได้ระหว่างตัวชี้และแถวลำดับแสดงไว้ด้านล่าง การกำหนดค่าทั้งสี่มีความหมายเทียบเท่ากันและเป็นรหัสที่ใช้งานได้ในภาษาซี

```text
/* x เป็นแถวลำดับหรือตัวชี้, i เป็นจำนวนเต็ม */

x[i] = 1;         /* เทียบเท่ากับ *(x + i) */
*(x + i) = 1;
*(i + x) = 1;
i[x] = 1;         /* เทียบเท่ากับ *(i + x) */
```

แม้ว่าการกำหนดค่าทั้งสี่เทียบเท่ากัน แต่มีเพียงแบบแรกเท่านั้นที่แสดงรูปแบบการลงรหัสที่ดี กรณีอื่นอาจพบได้ในรหัสภาษาซีที่ยุ่งเหยิง

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

## การจัดการหน่วยความจำ
ฟังก์ชันการทำงานหนึ่งที่สำคัญที่สุดของภาษาโปรแกรมคือ การให้บริการการจัดการหน่วยความจำและวัตถุที่บันทึกอยู่ในหน่วยความจำ ภาษาซีมีสามแนวทางที่ต่างกันเพื่อจัดสรรหน่วยความจำสำหรับวัตถุ
* การจัดสรรหน่วยความจำสถิต ที่ว่างสำหรับวัตถุในรหัสฐานสองซึ่งเว้นไว้ขณะแปลโปรแกรม วัตถุเหล่านี้มีอายุขัย (extent) ตราบเท่าที่รหัสฐานสองที่มีวัตถุนั้นบรรจุลงในหน่วยความจำ
* การจัดสรรหน่วยความจำอัตโนมัติ วัตถุชั่วคราวสามารถเก็บบันทึกในกองซ้อน (stack) และที่ว่างนี้จะถูกเรียกคืนและใช้ใหม่หลังจากวัตถุที่ประกาศเลิกการทำงานโดยอัตโนมัติ
* การจัดสรรหน่วยความจำพลวัต บล็อกต่าง ๆ ของหน่วยความจำในขนาดที่ต้องการสามารถร้องขอได้ขณะทำงาน โดยใช้ฟังก์ชันไลบรารีอาทิ `[[malloc]]` จองเนื้อที่หน่วยความจำที่เรียกว่าฮีป (heap) บล็อกเหล่านี้คงอยู่จนกว่าจะถูกเรียกคืนเพื่อใช้ใหม่โดยใช้ฟังก์ชัน `free` ในภายหลัง

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

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

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

ปัญหาอีกประการหนึ่งคือ การจัดสรรหน่วยความจำในฮีปจำเป็นต้องกระทำพร้อมกับการใช้งานจริงด้วยตนเองในโปรแกรมใด ๆ ก็ตาม เพื่อให้มันสามารถนำกลับมาใช้ใหม่มากที่สุดเท่าที่เป็นไปได้ ตัวอย่างเช่น ถ้ามีตัวชี้ไปยังฮีปที่ถูกจัดสรรนอกขอบเขต หรือค่าของตัวชี้ถูกเขียนทับก่อนเรียกใช้ `free` จะทำให้หน่วยความจำที่ตำแหน่งนั้นไม่สามารถเรียกคืนเพื่อใช้ใหม่ภายหลังและสูญเสียไปกับโปรแกรม อันเป็นปรากฏการณ์ที่เรียกว่า *[[หน่วยความจำรั่ว]]* (memory leak) ในทางกลับกัน การปลดปล่อยหน่วยความจำเร็วเกินไปแล้วยังคงใช้งานอยู่ซึ่งเป็นไปได้ แต่เนื่องจากระบบจัดสรรหน่วยความจำสามารถจัดสรรอีกครั้งหรือใช้หน่วยความจำที่ถูกทำให้ว่าง พฤติกรรมที่คาดเดาไม่ได้ก็อาจเกิดขึ้น โดยปกติอาการจะปรากฏในส่วนของโปรแกรมที่อยู่ไกลจากจุดที่ทำให้เกิดความผิดพลาดจริง ทำให้ตรวจแก้ปัญหาได้อย่างยากลำบาก ปัญหาเช่นนี้ได้รับการปรับปรุงแก้ไขในภาษาโปรแกรมที่มีการเก็บกวาดข้อมูลขยะอัตโนมัติ

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

ไลบรารีสามัญที่สุดคือไลบรารีมาตรฐานของภาษาซี ซึ่งระบุไว้โดยมาตรฐานไอโซและแอนซีซีและติดมากับทุกโปรแกรมที่พัฒนาด้วยภาษาซี (ส่วนการพัฒนาบนสภาพแวดล้อมแบบฝังตัวอาจมีไลบรารีมาตรฐานเพียงส่วนย่อยส่วนหนึ่ง) ไลบรารีนี้รองรับกระแสข้อมูลรับเข้าและส่งออก การจัดสรรหน่วยความจำ คณิตศาสตร์ สายอักขระ และค่าของเวลา

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

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

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

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

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

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

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

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

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

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

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

ภาษาลิมโบเป็นภาษาหนึ่งที่พัฒนาโดยทีมงานที่เบลล์แล็บส์ และในขณะที่ยังคงรักษาวากยสัมพันธ์และลักษณะทั่วไปบางอย่างของภาษาซี ก็ยังมีการเก็บกวาดข้อมูลขยะและภาวะพร้อมกันที่มีพื้นฐานบนกระบวนการสื่อสารแบบลำดับ (communicating sequential processes)

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

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

## อ้างอิง

## ดูเพิ่ม
* ตัวประมวลผลก่อนของภาษาซี
* ไลบรารีมาตรฐานของภาษาซี
* วากยสัมพันธ์ในภาษาซี
* การเปรียบเทียบระหว่างภาษาปาสกาลและภาษาซี
* การเปรียบเทียบระหว่างภาษาโปรแกรม
* การประกวดรหัสภาษาซียุ่งเหยิงนานาชาติ
* รายชื่อตัวแปลโปรแกรม
* รายชื่อภาษาโปรแกรมที่มีพื้นฐานจากภาษาซี

## หนังสืออ่านเพิ่มเติม
* 
* 
* 
* 

## แหล่งข้อมูลอื่น
* ISO C Working Group official website
* comp.lang.c Frequently Asked Questions
* ISO/IEC 9899. Official C99 documents.
* 
* ''ANSI C Standard'' (ANSI X3J11/88-090)  (Published May 13, 1988), Third Public Review
* ''ANSI C Rationale'' (ANSI X3J11/88-151) (Published Nov 18, 1988)


หมวดหมู่:ภาษาโปรแกรมเชิงกระบวนงาน
หมวดหมู่:สิ่งประดิษฐ์ของสหรัฐ
หมวดหมู่:ซอฟต์แวร์ข้ามแพลตฟอร์ม
หมวดหมู่:ภาษาโปรแกรมระบบ